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 Revision 1.2 1999/09/29 09:24:28 fca
19 Introduction of the Copyright and cvs Log
23 ///////////////////////////////////////////////////////////////////////////
25 // Handling of 3-vectors in various reference frames.
27 // This class is meant to serve as a base class for ALICE objects
28 // that have 3-dimensional vector characteristics.
29 // Error propagation is performed automatically.
33 // Vectors (v), Errors (e) and reference frames (f) are specified via
34 // SetVector(Float_t* v,TString f)
35 // SetErrors(Float_t* e,TString f)
36 // under the following conventions :
38 // f="car" ==> v in Cartesian coordinates (x,y,z)
39 // f="sph" ==> v in Spherical coordinates (r,theta,phi)
40 // f="cyl" ==> v in Cylindrical coordinates (rho,phi,z)
42 // All angles are in radians.
48 // Float_t v[3]={-1,25,7};
49 // Float_t e[3]={0.03,0.5,0.21};
50 // a.SetVector(v,"car");
51 // a.SetErrors(e,"car");
56 // a.GetVector(vec,"sph");
57 // a.GetErrors(vec,"sph");
60 // Float_t v2[3]={6,-18,33};
61 // Float_t e2[3]={0.19,0.45,0.93};
62 // b.SetVector(v2,"car");
63 // b.SetErrors(e2,"car");
65 // Float_t dotpro=a.Dot(b);
66 // Float_t doterror=a.GetResultError();
68 // Ali3Vector c=a.Cross(b);
70 // c.GetVector(vec,"cyl");
71 // c.GetErrors(err,"cyl");
73 // Float_t norm=c.GetNorm();
74 // Float_t normerror=c.GetResultError();
80 //--- Author: Nick van Eijndhoven 30-mar-1999 UU-SAP Utrecht
81 //- Modified: NvE 25-oct-1999 UU-SAP Utrecht
82 ///////////////////////////////////////////////////////////////////////////
84 #include "Ali3Vector.h"
86 ClassImp(Ali3Vector) // Class implementation to enable ROOT I/O
88 Ali3Vector::Ali3Vector()
90 // Creation of an Ali3Vector object and initialisation of parameters
91 // All attributes initialised to 0
100 ///////////////////////////////////////////////////////////////////////////
101 Ali3Vector::~Ali3Vector()
103 // Destructor to delete dynamically allocated memory
105 ///////////////////////////////////////////////////////////////////////////
106 void Ali3Vector::SetVector(Double_t* v,TString f)
108 // Store vector according to reference frame f
109 // All errors will be reset to 0
115 Double_t pi=acos(-1.);
118 if (f == "car") frame=1;
119 if (f == "sph") frame=2;
120 if (f == "cyl") frame=3;
122 Double_t x,y,z,rho,phi;
126 case 1: // Cartesian coordinates
130 fV=sqrt(x*x+y*y+z*z);
132 if (fV && fabs(z/fV)<=1.)
140 if (fTheta<0.) fTheta+=2.*pi;
142 if (x || y) fPhi=atan2(y,x);
143 if (fPhi<0.) fPhi+=2.*pi;
146 case 2: // Spherical coordinates
152 case 3: // Cylindrical coordinates
156 fV=sqrt(rho*rho+z*z);
158 if (fPhi<0.) fPhi+=2.*pi;
160 if (fV && fabs(z/fV)<=1.)
168 if (fTheta<0.) fTheta+=2.*pi;
171 default: // Unsupported reference frame
172 cout << "*Ali3Vector::SetVector* Unsupported frame : " << f << endl
173 << " Possible frames are 'car', 'sph' and 'cyl'." << endl;
180 ///////////////////////////////////////////////////////////////////////////
181 void Ali3Vector::GetVector(Double_t* v,TString f)
183 // Provide vector according to reference frame f
185 if (f == "car") frame=1;
186 if (f == "sph") frame=2;
187 if (f == "cyl") frame=3;
191 case 1: // Cartesian coordinates
192 v[0]=fV*sin(fTheta)*cos(fPhi);
193 v[1]=fV*sin(fTheta)*sin(fPhi);
197 case 2: // Spherical coordinates
203 case 3: // Cylindrical coordinates
209 default: // Unsupported reference frame
210 cout << "*Ali3Vector::GetVector* Unsupported frame : " << f << endl
211 << " Possible frames are 'car', 'sph' and 'cyl'." << endl;
212 for (Int_t i=0; i<3; i++)
219 ///////////////////////////////////////////////////////////////////////////
220 void Ali3Vector::SetVector(Float_t* v,TString f)
222 // Store vector according to reference frame f
223 // All errors will be reset to 0
225 for (Int_t i=0; i<3; i++)
231 ///////////////////////////////////////////////////////////////////////////
232 void Ali3Vector::GetVector(Float_t* v,TString f)
234 // Provide vector according to reference frame f
237 for (Int_t i=0; i<3; i++)
242 ///////////////////////////////////////////////////////////////////////////
243 void Ali3Vector::SetErrors(Double_t* e,TString f)
245 // Store errors according to reference frame f
246 // The error on scalar results is reset to 0
250 if (f == "car") frame=1;
251 if (f == "sph") frame=2;
252 if (f == "cyl") frame=3;
254 Double_t dx2,dy2,dz2,rho;
258 case 1: // Cartesian coordinates
264 case 2: // Spherical coordinates
265 dx2=pow((cos(fPhi)*sin(fTheta)*e[0]),2)+pow((fV*cos(fTheta)*cos(fPhi)*e[1]),2)
266 +pow((fV*sin(fTheta)*sin(fPhi)*e[2]),2);
267 dy2=pow((sin(fPhi)*sin(fTheta)*e[0]),2)+pow((fV*cos(fTheta)*sin(fPhi)*e[1]),2)
268 +pow((fV*sin(fTheta)*cos(fPhi)*e[2]),2);
269 dz2=pow((cos(fTheta)*e[0]),2)+pow((fV*sin(fTheta)*e[1]),2);
275 case 3: // Cylindrical coordinates
277 dx2=pow((cos(fPhi)*e[0]),2)+pow((rho*sin(fPhi)*e[1]),2);
278 dy2=pow((sin(fPhi)*e[0]),2)+pow((rho*cos(fPhi)*e[1]),2);
284 default: // Unsupported reference frame
285 cout << "*Ali3Vector::SetErrors* Unsupported frame : " << f << endl
286 << " Possible frames are 'car', 'sph' and 'cyl'." << endl;
293 ///////////////////////////////////////////////////////////////////////////
294 void Ali3Vector::GetErrors(Double_t* e,TString f)
296 // Provide errors according to reference frame f
298 if (f == "car") frame=1;
299 if (f == "sph") frame=2;
300 if (f == "cyl") frame=3;
302 Double_t dr2,dtheta2,dphi2,rho,drho2;
307 case 1: // Cartesian coordinates
313 case 2: // Spherical coordinates
317 dr2=(pow((v[0]*fDx),2)+pow((v[1]*fDy),2)+pow((v[2]*fDz),2))/(fV*fV);
325 dtheta2=(v[2]*v[2]/(pow(fV,4)-pow(v[2],2)*pow(fV,2)))*dr2
326 +pow(fDz,2)/(pow(fV,2)-pow(v[2],2));
335 dphi2=(pow((v[1]*fDx),2)+pow((v[0]*fDy),2))/(pow(v[0],2)+pow(v[1],2));
346 case 3: // Cylindrical coordinates
351 drho2=(pow((v[0]*fDx),2)+pow((v[1]*fDy),2))/(rho*rho);
359 dphi2=(pow((v[1]*fDx),2)+pow((v[0]*fDy),2))/(pow(v[0],2)+pow(v[1],2));
370 default: // Unsupported reference frame
371 cout << "*Ali3Vector::GetErrors* Unsupported frame : " << f << endl
372 << " Possible frames are 'car', 'sph' and 'cyl'." << endl;
373 for (Int_t i=0; i<3; i++)
380 ///////////////////////////////////////////////////////////////////////////
381 void Ali3Vector::SetErrors(Float_t* e,TString f)
383 // Store errors according to reference frame f
384 // The error on scalar results is reset to 0
386 for (Int_t i=0; i<3; i++)
392 ///////////////////////////////////////////////////////////////////////////
393 void Ali3Vector::GetErrors(Float_t* e,TString f)
395 // Provide errors according to reference frame f
398 for (Int_t i=0; i<3; i++)
403 ///////////////////////////////////////////////////////////////////////////
404 void Ali3Vector::Info(TString f)
406 // Print vector components according to reference frame f
407 if (f=="car" || f=="sph" || f=="cyl")
409 Double_t vec[3],err[3];
412 cout << " Vector in " << f << " coordinates : "
413 << vec[0] << " " << vec[1] << " " << vec[2] << endl;
414 cout << " Err. in " << f << " coordinates : "
415 << err[0] << " " << err[1] << " " << err[2] << endl;
419 cout << " *Ali3Vector::Info* Unsupported frame : " << f << endl
420 << " Possible frames are 'car', 'sph' and 'cyl'." << endl;
423 ///////////////////////////////////////////////////////////////////////////
424 Double_t Ali3Vector::GetNorm()
426 // Provide the norm of the current vector
427 // The error on the scalar result (norm) is updated accordingly
433 ///////////////////////////////////////////////////////////////////////////
434 Double_t Ali3Vector::GetPseudoRapidity()
436 // Provide the pseudo-rapidity w.r.t. the z-axis.
437 // In other words : eta=-log(tan(theta/2))
438 // The error on the scalar result (pseudo-rap.) is updated accordingly
441 Double_t thetahalf=v[1]/2.;
442 Double_t arg=tan(thetahalf);
444 if (arg>0) eta=-log(arg);
447 Double_t prod=cos(thetahalf)*sin(thetahalf);
449 if (prod) fDresult=fabs(e[1]/2.*prod);
452 ///////////////////////////////////////////////////////////////////////////
453 Double_t Ali3Vector::Dot(Ali3Vector& q)
455 // Provide the dot product of the current vector with vector q
456 // The error on the scalar result (dotproduct) is updated accordingly
460 if ((this) == &q) // Check for special case v.Dot(v)
462 Double_t norm=GetNorm();
463 Double_t dnorm=GetResultError();
465 fDresult=2.*norm*dnorm;
470 Double_t ea[3],eb[3];
475 q.GetVector(b,"car");
476 q.GetErrors(eb,"car");
477 for (Int_t i=0; i<3; i++)
480 d2+=pow(b[i]*ea[i],2)+pow(a[i]*eb[i],2);
487 ///////////////////////////////////////////////////////////////////////////
488 Double_t Ali3Vector::GetResultError()
490 // Provide the error on the result of an operation yielding a scalar
491 // E.g. GetNorm() or Dot()
494 ///////////////////////////////////////////////////////////////////////////
495 Ali3Vector Ali3Vector::Cross(Ali3Vector& q)
497 // Provide the cross product of the current vector with vector q
498 // Error propagation is performed automatically
499 Double_t a[3],b[3],c[3];
500 Double_t ea[3],eb[3],ec[3],d2;
504 q.GetVector(b,"car");
505 q.GetErrors(eb,"car");
507 c[0]=a[1]*b[2]-a[2]*b[1];
508 c[1]=a[2]*b[0]-a[0]*b[2];
509 c[2]=a[0]*b[1]-a[1]*b[0];
511 d2=pow(b[2]*ea[1],2)+pow(a[1]*eb[2],2)
512 +pow(b[1]*ea[2],2)+pow(a[2]*eb[1],2);
515 d2=pow(b[0]*ea[2],2)+pow(a[2]*eb[0],2)
516 +pow(b[2]*ea[0],2)+pow(a[0]*eb[2],2);
519 d2=pow(b[1]*ea[0],2)+pow(a[0]*eb[1],2)
520 +pow(b[0]*ea[1],2)+pow(a[1]*eb[0],2);
524 v.SetVector(c,"car");
525 v.SetErrors(ec,"car");
529 ///////////////////////////////////////////////////////////////////////////
530 Ali3Vector Ali3Vector::operator+(Ali3Vector& q)
532 // Add vector q to the current vector
533 // Error propagation is performed automatically
534 Double_t a[3],b[3],ea[3],eb[3];
538 q.GetVector(b,"car");
539 q.GetErrors(eb,"car");
541 for (Int_t i=0; i<3; i++)
544 ea[i]=sqrt(pow(ea[i],2)+pow(eb[i],2));
548 v.SetVector(a,"car");
549 v.SetErrors(ea,"car");
553 ///////////////////////////////////////////////////////////////////////////
554 Ali3Vector Ali3Vector::operator-(Ali3Vector& q)
556 // Subtract vector q from the current vector
557 // Error propagation is performed automatically
558 Double_t a[3],b[3],ea[3],eb[3];
562 q.GetVector(b,"car");
563 q.GetErrors(eb,"car");
565 for (Int_t i=0; i<3; i++)
568 ea[i]=sqrt(pow(ea[i],2)+pow(eb[i],2));
572 v.SetVector(a,"car");
573 v.SetErrors(ea,"car");
577 ///////////////////////////////////////////////////////////////////////////
578 Ali3Vector Ali3Vector::operator*(Double_t s)
580 // Multiply the current vector with a scalar s.
581 // Error propagation is performed automatically.
587 for (Int_t i=0; i<3; i++)
594 v.SetVector(a,"car");
595 v.SetErrors(ea,"car");
599 ///////////////////////////////////////////////////////////////////////////
600 Ali3Vector Ali3Vector::operator/(Double_t s)
602 // Divide the current vector by a scalar s
603 // Error propagation is performed automatically
605 if (fabs(s)<1.e-20) // Protect against division by 0
607 cout << " *Ali3Vector::/* Division by 0 detected. No action taken." << endl;
617 for (Int_t i=0; i<3; i++)
624 v.SetVector(a,"car");
625 v.SetErrors(ea,"car");
630 ///////////////////////////////////////////////////////////////////////////
631 Ali3Vector& Ali3Vector::operator+=(Ali3Vector& q)
633 // Add vector q to the current vector
634 // Error propagation is performed automatically
635 Double_t a[3],b[3],ea[3],eb[3];
639 q.GetVector(b,"car");
640 q.GetErrors(eb,"car");
642 for (Int_t i=0; i<3; i++)
645 ea[i]=sqrt(pow(ea[i],2)+pow(eb[i],2));
653 ///////////////////////////////////////////////////////////////////////////
654 Ali3Vector& Ali3Vector::operator-=(Ali3Vector& q)
656 // Subtract vector q from the current vector
657 // Error propagation is performed automatically
658 Double_t a[3],b[3],ea[3],eb[3];
662 q.GetVector(b,"car");
663 q.GetErrors(eb,"car");
665 for (Int_t i=0; i<3; i++)
668 ea[i]=sqrt(pow(ea[i],2)+pow(eb[i],2));
676 ///////////////////////////////////////////////////////////////////////////
677 Ali3Vector& Ali3Vector::operator*=(Double_t s)
679 // Multiply the current vector with a scalar s
680 // Error propagation is performed automatically
686 for (Int_t i=0; i<3; i++)
697 ///////////////////////////////////////////////////////////////////////////
698 Ali3Vector& Ali3Vector::operator/=(Double_t s)
700 // Divide the current vector by a scalar s
701 // Error propagation is performed automatically
703 if (fabs(s)<1.e-20) // Protect against division by 0
705 cout << " *Ali3Vector::/=* Division by 0 detected. No action taken." << endl;
715 for (Int_t i=0; i<3; i++)
727 ///////////////////////////////////////////////////////////////////////////