1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////
20 // Handling of 3-vectors in various reference frames.
22 // This class is meant to serve as a base class for ALICE objects
23 // that have 3-dimensional vector characteristics.
24 // Error propagation is performed automatically.
28 // Vectors (v), Errors (e), reference frames (f) and angular units (u)
30 // SetVector(Float_t* v,TString f,TString u)
31 // SetErrors(Float_t* e,TString f,TString u)
32 // under the following conventions :
34 // f="car" ==> v in Cartesian coordinates (x,y,z)
35 // f="sph" ==> v in Spherical coordinates (r,theta,phi)
36 // f="cyl" ==> v in Cylindrical coordinates (rho,phi,z)
38 // u="rad" ==> angles in radians
39 // u="deg" ==> angles in degrees
41 // The "f" and "u" facilities only serve as a convenient user interface.
42 // Internally the actual storage of the various components is performed
43 // in a unique way. This allows setting/retrieval of vector components in a
44 // user selected frame/unit convention at any time.
50 // Float_t v[3]={-1,25,7};
51 // Float_t e[3]={0.03,0.5,0.21};
52 // a.SetVector(v,"car");
53 // a.SetErrors(e,"car");
58 // a.GetVector(vec,"sph","deg");
59 // a.GetErrors(vec,"sph","deg");
62 // Float_t v2[3]={6,-18,33};
63 // Float_t e2[3]={0.19,0.45,0.93};
64 // b.SetVector(v2,"car");
65 // b.SetErrors(e2,"car");
67 // Float_t dotpro=a.Dot(b);
68 // Float_t doterror=a.GetResultError();
70 // Ali3Vector c=a.Cross(b);
72 // c.GetVector(vec,"cyl");
73 // c.GetErrors(err,"cyl");
75 // Float_t norm=c.GetNorm();
76 // Float_t normerror=c.GetResultError();
82 //--- Author: Nick van Eijndhoven 30-mar-1999 UU-SAP Utrecht
83 //- Modified: NvE $Date$ UU-SAP Utrecht
84 ///////////////////////////////////////////////////////////////////////////
86 #include "Ali3Vector.h"
87 #include "Riostream.h"
89 ClassImp(Ali3Vector) // Class implementation to enable ROOT I/O
91 Ali3Vector::Ali3Vector()
93 // Creation of an Ali3Vector object and initialisation of parameters
94 // All attributes initialised to 0
97 ///////////////////////////////////////////////////////////////////////////
98 Ali3Vector::~Ali3Vector()
100 // Destructor to delete dynamically allocated memory
102 ///////////////////////////////////////////////////////////////////////////
103 Ali3Vector::Ali3Vector(const Ali3Vector& v)
114 ///////////////////////////////////////////////////////////////////////////
115 void Ali3Vector::Load(Ali3Vector& q)
117 // Load all attributes of the input Ali3Vector into this Ali3Vector object.
118 Double_t temp=q.GetResultError();
120 q.GetVector(a,"sph");
122 q.GetErrors(a,"car");
126 ///////////////////////////////////////////////////////////////////////////
127 void Ali3Vector::SetZero()
129 // (Re)set all attributes to zero.
138 ///////////////////////////////////////////////////////////////////////////
139 void Ali3Vector::SetVector(Double_t* v,TString f,TString u)
141 // Store vector according to reference frame f
143 // The string argument "u" allows to choose between different angular units
144 // in case e.g. a spherical frame is selected.
145 // u = "rad" : angles provided in radians
146 // "deg" : angles provided in degrees
148 // The default is u="rad".
150 // All errors will be reset to 0
157 Double_t pi=acos(-1.);
160 if (u == "deg") fu=pi/180.;
163 if (f == "car") frame=1;
164 if (f == "sph") frame=2;
165 if (f == "cyl") frame=3;
167 Double_t x,y,z,rho,phi;
171 case 1: // Cartesian coordinates
175 fV=sqrt(x*x+y*y+z*z);
177 if (fV && fabs(z/fV)<=1.)
185 if (fTheta<0.) fTheta+=2.*pi;
187 if (x || y) fPhi=atan2(y,x);
188 if (fPhi<0.) fPhi+=2.*pi;
191 case 2: // Spherical coordinates
197 case 3: // Cylindrical coordinates
201 fV=sqrt(rho*rho+z*z);
203 if (fPhi<0.) fPhi+=2.*pi;
205 if (fV && fabs(z/fV)<=1.)
213 if (fTheta<0.) fTheta+=2.*pi;
216 default: // Unsupported reference frame
217 cout << "*Ali3Vector::SetVector* Unsupported frame : " << f.Data() << endl
218 << " Possible frames are 'car', 'sph' and 'cyl'." << endl;
225 ///////////////////////////////////////////////////////////////////////////
226 void Ali3Vector::GetVector(Double_t* v,TString f,TString u) const
228 // Provide vector according to reference frame f
230 // The string argument "u" allows to choose between different angular units
231 // in case e.g. a spherical frame is selected.
232 // u = "rad" : angles provided in radians
233 // "deg" : angles provided in degrees
235 // The default is u="rad".
237 Double_t pi=acos(-1.);
240 if (u == "deg") fu=180./pi;
243 if (f == "car") frame=1;
244 if (f == "sph") frame=2;
245 if (f == "cyl") frame=3;
249 case 1: // Cartesian coordinates
250 v[0]=fV*sin(fTheta)*cos(fPhi);
251 v[1]=fV*sin(fTheta)*sin(fPhi);
255 case 2: // Spherical coordinates
261 case 3: // Cylindrical coordinates
267 default: // Unsupported reference frame
268 cout << "*Ali3Vector::GetVector* Unsupported frame : " << f.Data() << endl
269 << " Possible frames are 'car', 'sph' and 'cyl'." << endl;
270 for (Int_t i=0; i<3; i++)
277 ///////////////////////////////////////////////////////////////////////////
278 void Ali3Vector::SetVector(Float_t* v,TString f,TString u)
280 // Store vector according to reference frame f
282 // The string argument "u" allows to choose between different angular units
283 // in case e.g. a spherical frame is selected.
284 // u = "rad" : angles provided in radians
285 // "deg" : angles provided in degrees
287 // The default is u="rad".
289 // All errors will be reset to 0
292 for (Int_t i=0; i<3; i++)
298 ///////////////////////////////////////////////////////////////////////////
299 void Ali3Vector::GetVector(Float_t* v,TString f,TString u) const
301 // Provide vector according to reference frame f
303 // The string argument "u" allows to choose between different angular units
304 // in case e.g. a spherical frame is selected.
305 // u = "rad" : angles provided in radians
306 // "deg" : angles provided in degrees
308 // The default is u="rad".
312 for (Int_t i=0; i<3; i++)
317 ///////////////////////////////////////////////////////////////////////////
318 void Ali3Vector::SetErrors(Double_t* e,TString f,TString u)
320 // Store errors according to reference frame f
322 // The string argument "u" allows to choose between different angular units
323 // in case e.g. a spherical frame is selected.
324 // u = "rad" : angles provided in radians
325 // "deg" : angles provided in degrees
327 // The default is u="rad".
329 // The error on scalar results is reset to 0
331 Double_t pi=acos(-1.);
334 if (u == "deg") fu=pi/180.;
339 if (f == "car") frame=1;
340 if (f == "sph") frame=2;
341 if (f == "cyl") frame=3;
343 Double_t dx2,dy2,dz2,rho;
347 case 1: // Cartesian coordinates
353 case 2: // Spherical coordinates
354 dx2=pow((cos(fPhi)*sin(fTheta)*e[0]),2)+pow((fV*cos(fTheta)*cos(fPhi)*e[1]*fu),2)
355 +pow((fV*sin(fTheta)*sin(fPhi)*e[2]*fu),2);
356 dy2=pow((sin(fPhi)*sin(fTheta)*e[0]),2)+pow((fV*cos(fTheta)*sin(fPhi)*e[1]*fu),2)
357 +pow((fV*sin(fTheta)*cos(fPhi)*e[2]*fu),2);
358 dz2=pow((cos(fTheta)*e[0]),2)+pow((fV*sin(fTheta)*e[1]*fu),2);
364 case 3: // Cylindrical coordinates
366 dx2=pow((cos(fPhi)*e[0]),2)+pow((rho*sin(fPhi)*e[1]*fu),2);
367 dy2=pow((sin(fPhi)*e[0]),2)+pow((rho*cos(fPhi)*e[1]*fu),2);
373 default: // Unsupported reference frame
374 cout << "*Ali3Vector::SetErrors* Unsupported frame : " << f.Data() << endl
375 << " Possible frames are 'car', 'sph' and 'cyl'." << endl;
382 ///////////////////////////////////////////////////////////////////////////
383 void Ali3Vector::GetErrors(Double_t* e,TString f,TString u) const
385 // Provide errors according to reference frame f
387 // The string argument "u" allows to choose between different angular units
388 // in case e.g. a spherical frame is selected.
389 // u = "rad" : angles provided in radians
390 // "deg" : angles provided in degrees
392 // The default is u="rad".
394 Double_t pi=acos(-1.);
397 if (u == "deg") fu=180./pi;
400 if (f == "car") frame=1;
401 if (f == "sph") frame=2;
402 if (f == "cyl") frame=3;
404 Double_t dr2,dtheta2,dphi2,rho,drho2;
406 Double_t rxy2; // Shorthand for (x*x+y*y)
410 case 1: // Cartesian coordinates
416 case 2: // Spherical coordinates
418 rxy2=pow(v[0],2)+pow(v[1],2);
419 if (sqrt(rxy2)<(fV*1e-10)) rxy2=0;
422 dr2=(pow((v[0]*fDx),2)+pow((v[1]*fDy),2)+pow((v[2]*fDz),2))/(fV*fV);
430 dtheta2=rxy2*pow(fDz,2)/pow(fV,4);
433 dtheta2+=rxy2*pow(v[2],2)*(pow((v[0]*fDx),2)+pow((v[1]*fDy),2)) /
434 pow(((pow(v[2],2)*rxy2)+pow(rxy2,2)),2);
443 dphi2=(pow((v[1]*fDx),2)+pow((v[0]*fDy),2))/(pow(rxy2,2));
451 if (e[1]>pi) e[1]=pi;
453 if (e[2]>(2.*pi)) e[2]=2.*pi;
458 case 3: // Cylindrical coordinates
460 rho=fabs(fV*sin(fTheta));
461 if (rho<(fV*1e-10)) rho=0;
464 drho2=(pow((v[0]*fDx),2)+pow((v[1]*fDy),2))/(rho*rho);
472 dphi2=(pow((v[1]*fDx),2)+pow((v[0]*fDy),2))/(pow(rho,4));
480 if (e[1]>(2.*pi)) e[1]=2.*pi;
485 default: // Unsupported reference frame
486 cout << "*Ali3Vector::GetErrors* Unsupported frame : " << f.Data() << endl
487 << " Possible frames are 'car', 'sph' and 'cyl'." << endl;
488 for (Int_t i=0; i<3; i++)
495 ///////////////////////////////////////////////////////////////////////////
496 void Ali3Vector::SetErrors(Float_t* e,TString f,TString u)
498 // Store errors according to reference frame f
500 // The string argument "u" allows to choose between different angular units
501 // in case e.g. a spherical frame is selected.
502 // u = "rad" : angles provided in radians
503 // "deg" : angles provided in degrees
505 // The default is u="rad".
507 // The error on scalar results is reset to 0
510 for (Int_t i=0; i<3; i++)
516 ///////////////////////////////////////////////////////////////////////////
517 void Ali3Vector::GetErrors(Float_t* e,TString f,TString u) const
519 // Provide errors according to reference frame f
521 // The string argument "u" allows to choose between different angular units
522 // in case e.g. a spherical frame is selected.
523 // u = "rad" : angles provided in radians
524 // "deg" : angles provided in degrees
526 // The default is u="rad".
530 for (Int_t i=0; i<3; i++)
535 ///////////////////////////////////////////////////////////////////////////
536 void Ali3Vector::Data(TString f,TString u) const
538 // Print vector components according to reference frame f
540 // The string argument "u" allows to choose between different angular units
541 // in case e.g. a spherical frame is selected.
542 // u = "rad" : angles provided in radians
543 // "deg" : angles provided in degrees
545 // The defaults are f="car" and u="rad".
547 if (f=="car" || f=="sph" || f=="cyl")
549 Double_t vec[3],err[3];
552 cout << " Vector in " << f.Data() << " (" << u.Data() << ") coordinates : "
553 << vec[0] << " " << vec[1] << " " << vec[2] << endl;
554 cout << " Err. in " << f.Data() << " (" << u.Data() << ") coordinates : "
555 << err[0] << " " << err[1] << " " << err[2] << endl;
559 cout << " *Ali3Vector::Data* Unsupported frame : " << f.Data() << endl
560 << " Possible frames are 'car', 'sph' and 'cyl'." << endl;
563 ///////////////////////////////////////////////////////////////////////////
564 Double_t Ali3Vector::GetNorm()
566 // Provide the norm of the current vector
567 // The error on the scalar result (norm) is updated accordingly
573 ///////////////////////////////////////////////////////////////////////////
574 Double_t Ali3Vector::GetPseudoRapidity()
576 // Provide the pseudo-rapidity w.r.t. the z-axis.
577 // In other words : eta=-log(tan(theta/2))
578 // The error on the scalar result (pseudo-rap.) is updated accordingly
579 Double_t pi=acos(-1.);
582 Double_t thetahalf=v[1]/2.;
584 if (v[1]<pi) arg=tan(thetahalf);
586 if (arg>0) eta=-log(arg);
589 Double_t prod=cos(thetahalf)*sin(thetahalf);
591 if (prod) fDresult=fabs(e[1]/2.*prod);
594 ///////////////////////////////////////////////////////////////////////////
595 Double_t Ali3Vector::Dot(Ali3Vector& q)
597 // Provide the dot product of the current vector with vector q
598 // The error on the scalar result (dotproduct) is updated accordingly
602 if ((this) == &q) // Check for special case v.Dot(v)
604 Double_t norm=GetNorm();
605 Double_t dnorm=GetResultError();
607 fDresult=2.*norm*dnorm;
612 Double_t ea[3],eb[3];
617 q.GetVector(b,"car");
618 q.GetErrors(eb,"car");
619 for (Int_t i=0; i<3; i++)
622 d2+=pow(b[i]*ea[i],2)+pow(a[i]*eb[i],2);
629 ///////////////////////////////////////////////////////////////////////////
630 Double_t Ali3Vector::GetResultError() const
632 // Provide the error on the result of an operation yielding a scalar
633 // E.g. GetNorm() or Dot()
636 ///////////////////////////////////////////////////////////////////////////
637 Ali3Vector Ali3Vector::Cross(Ali3Vector& q) const
639 // Provide the cross product of the current vector with vector q
640 // Error propagation is performed automatically
641 Double_t a[3],b[3],c[3];
642 Double_t ea[3],eb[3],ec[3],d2;
646 q.GetVector(b,"car");
647 q.GetErrors(eb,"car");
649 c[0]=a[1]*b[2]-a[2]*b[1];
650 c[1]=a[2]*b[0]-a[0]*b[2];
651 c[2]=a[0]*b[1]-a[1]*b[0];
653 d2=pow(b[2]*ea[1],2)+pow(a[1]*eb[2],2)
654 +pow(b[1]*ea[2],2)+pow(a[2]*eb[1],2);
657 d2=pow(b[0]*ea[2],2)+pow(a[2]*eb[0],2)
658 +pow(b[2]*ea[0],2)+pow(a[0]*eb[2],2);
661 d2=pow(b[1]*ea[0],2)+pow(a[0]*eb[1],2)
662 +pow(b[0]*ea[1],2)+pow(a[1]*eb[0],2);
666 v.SetVector(c,"car");
667 v.SetErrors(ec,"car");
671 ///////////////////////////////////////////////////////////////////////////
672 Ali3Vector Ali3Vector::operator+(Ali3Vector& q) const
674 // Add vector q to the current vector
675 // Error propagation is performed automatically
676 Double_t a[3],b[3],ea[3],eb[3];
680 q.GetVector(b,"car");
681 q.GetErrors(eb,"car");
683 for (Int_t i=0; i<3; i++)
686 ea[i]=sqrt(pow(ea[i],2)+pow(eb[i],2));
690 v.SetVector(a,"car");
691 v.SetErrors(ea,"car");
695 ///////////////////////////////////////////////////////////////////////////
696 Ali3Vector Ali3Vector::operator-(Ali3Vector& q) const
698 // Subtract vector q from the current vector
699 // Error propagation is performed automatically
700 Double_t a[3],b[3],ea[3],eb[3];
704 q.GetVector(b,"car");
705 q.GetErrors(eb,"car");
707 for (Int_t i=0; i<3; i++)
710 ea[i]=sqrt(pow(ea[i],2)+pow(eb[i],2));
714 v.SetVector(a,"car");
715 v.SetErrors(ea,"car");
719 ///////////////////////////////////////////////////////////////////////////
720 Ali3Vector Ali3Vector::operator*(Double_t s) const
722 // Multiply the current vector with a scalar s.
723 // Error propagation is performed automatically.
729 for (Int_t i=0; i<3; i++)
736 v.SetVector(a,"car");
737 v.SetErrors(ea,"car");
741 ///////////////////////////////////////////////////////////////////////////
742 Ali3Vector Ali3Vector::operator/(Double_t s) const
744 // Divide the current vector by a scalar s
745 // Error propagation is performed automatically
747 if (fabs(s)<1.e-20) // Protect against division by 0
749 cout << " *Ali3Vector::/* Division by 0 detected. No action taken." << endl;
759 for (Int_t i=0; i<3; i++)
766 v.SetVector(a,"car");
767 v.SetErrors(ea,"car");
772 ///////////////////////////////////////////////////////////////////////////
773 Ali3Vector& Ali3Vector::operator+=(Ali3Vector& q)
775 // Add vector q to the current vector
776 // Error propagation is performed automatically
777 Double_t a[3],b[3],ea[3],eb[3];
781 q.GetVector(b,"car");
782 q.GetErrors(eb,"car");
784 for (Int_t i=0; i<3; i++)
787 ea[i]=sqrt(pow(ea[i],2)+pow(eb[i],2));
795 ///////////////////////////////////////////////////////////////////////////
796 Ali3Vector& Ali3Vector::operator-=(Ali3Vector& q)
798 // Subtract vector q from the current vector
799 // Error propagation is performed automatically
800 Double_t a[3],b[3],ea[3],eb[3];
804 q.GetVector(b,"car");
805 q.GetErrors(eb,"car");
807 for (Int_t i=0; i<3; i++)
810 ea[i]=sqrt(pow(ea[i],2)+pow(eb[i],2));
818 ///////////////////////////////////////////////////////////////////////////
819 Ali3Vector& Ali3Vector::operator*=(Double_t s)
821 // Multiply the current vector with a scalar s
822 // Error propagation is performed automatically
828 for (Int_t i=0; i<3; i++)
839 ///////////////////////////////////////////////////////////////////////////
840 Ali3Vector& Ali3Vector::operator/=(Double_t s)
842 // Divide the current vector by a scalar s
843 // Error propagation is performed automatically
845 if (fabs(s)<1.e-20) // Protect against division by 0
847 cout << " *Ali3Vector::/=* Division by 0 detected. No action taken." << endl;
857 for (Int_t i=0; i<3; i++)
869 ///////////////////////////////////////////////////////////////////////////
870 Ali3Vector Ali3Vector::GetVecTrans() const
872 // Provide the transverse vector w.r.t. z-axis.
873 // Error propagation is performed automatically
874 Double_t pi=acos(-1.);
882 dvt2=pow((sin(a[1])*ea[0]),2)+pow((a[0]*cos(a[1])*ea[1]),2);
891 v.SetVector(a,"sph");
892 v.SetErrors(ea,"sph");
896 ///////////////////////////////////////////////////////////////////////////
897 Ali3Vector Ali3Vector::GetVecLong() const
899 // Provide the longitudinal vector w.r.t. z-axis.
900 // Error propagation is performed automatically
901 Double_t pi=acos(-1.);
909 dvl2=pow((cos(a[1])*ea[0]),2)+pow((a[0]*sin(a[1])*ea[1]),2);
921 v.SetVector(a,"sph");
922 v.SetErrors(ea,"sph");
926 ///////////////////////////////////////////////////////////////////////////
927 Ali3Vector Ali3Vector::GetPrimed(TRotMatrix* m) const
929 // Provide vector components (and errors) in a rotated frame.
930 // The orientation of the rotated frame is described by the TRotMatrix
935 Double_t* mat=m->GetMatrix();
937 Double_t a[3],aprim[3];
940 aprim[0]=a[0]*mat[0]+a[1]*mat[1]+a[2]*mat[2];
941 aprim[1]=a[0]*mat[3]+a[1]*mat[4]+a[2]*mat[5];
942 aprim[2]=a[0]*mat[6]+a[1]*mat[7]+a[2]*mat[8];
943 v.SetVector(aprim,"car");
946 aprim[0]=sqrt(pow(a[0]*mat[0],2)+pow(a[1]*mat[1],2)+pow(a[2]*mat[2],2));
947 aprim[1]=sqrt(pow(a[0]*mat[3],2)+pow(a[1]*mat[4],2)+pow(a[2]*mat[5],2));
948 aprim[2]=sqrt(pow(a[0]*mat[6],2)+pow(a[1]*mat[7],2)+pow(a[2]*mat[8],2));
949 v.SetErrors(aprim,"car");
953 ///////////////////////////////////////////////////////////////////////////
954 Ali3Vector Ali3Vector::GetUnprimed(TRotMatrix* m) const
956 // Provide original vector components (and errors) from the rotated ones.
957 // The orientation of the rotated frame is described by the TRotMatrix
959 // So, this is the inverse of the GetPrimed() memberfunction.
960 // This memberfunction makes use of the fact that the inverse of a certain
961 // TRotMatrix is given by its transposed matrix.
965 Double_t* mat=m->GetMatrix();
967 Double_t a[3],aprim[3];
969 GetVector(aprim,"car");
970 a[0]=aprim[0]*mat[0]+aprim[1]*mat[3]+aprim[2]*mat[6];
971 a[1]=aprim[0]*mat[1]+aprim[1]*mat[4]+aprim[2]*mat[7];
972 a[2]=aprim[0]*mat[2]+aprim[1]*mat[5]+aprim[2]*mat[8];
973 v.SetVector(a,"car");
975 GetErrors(aprim,"car");
976 a[0]=sqrt(pow(aprim[0]*mat[0],2)+pow(aprim[1]*mat[3],2)+pow(aprim[2]*mat[6],2));
977 a[1]=sqrt(pow(aprim[0]*mat[1],2)+pow(aprim[1]*mat[4],2)+pow(aprim[2]*mat[7],2));
978 a[2]=sqrt(pow(aprim[0]*mat[2],2)+pow(aprim[1]*mat[5],2)+pow(aprim[2]*mat[8],2));
979 v.SetErrors(a,"car");
983 ///////////////////////////////////////////////////////////////////////////
984 Double_t Ali3Vector::GetX(Int_t i,TString f,TString u)
986 // Provide i-th vector component according to reference frame f.
988 // The string argument "u" allows to choose between different angular units
989 // in case e.g. a spherical frame is selected.
990 // u = "rad" : angles provided in radians
991 // "deg" : angles provided in degrees
993 // The default is u="rad".
995 // The vector components are addressed via the generic x1,x2,x3 notation.
996 // So, i=1 denotes the first vector component.
997 // The error on the selected component can be obtained via the
998 // usual GetResultError() facility.
1002 if (i<1 || i>3) return 0;
1013 ///////////////////////////////////////////////////////////////////////////
1014 Double_t Ali3Vector::GetOpeningAngle(Ali3Vector& q,TString u)
1016 // Provide the opening angle with vector q.
1017 // The string argument "u" allows to choose between different output units.
1018 // u = "rad" : opening angle provided in radians
1019 // "deg" : opening angle provided in degrees
1021 // The default is u="rad".
1025 if (GetNorm()<=0. || q.GetNorm()<=0.) return ang;
1031 GetVector(vec,"sph");
1032 GetErrors(err,"sph");
1035 v1.SetVector(vec,"sph");
1036 v1.SetErrors(err,"sph");
1039 q.GetVector(vec,"sph");
1040 q.GetErrors(err,"sph");
1043 v2.SetVector(vec,"sph");
1044 v2.SetErrors(err,"sph");
1046 Double_t x=v1.Dot(v2);
1047 Double_t dx=fDresult;
1052 if (fabs(x)<1.-dx) fDresult=dx/sqrt(1.-x*x);
1056 Double_t pi=acos(-1.);
1063 ///////////////////////////////////////////////////////////////////////////