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 Lorentz 4-vectors in various reference frames.
27 // This class is meant to serve as a base class for ALICE objects
28 // that have Lorentz 4-vector characteristics.
29 // Error propagation is performed automatically.
31 // All 4-vectors are treated in the contravariant form and the convention
32 // for the metric and the 4-vector components is according to the one
33 // used in the book "Classical Electrodynamics" by J.D. Jackson.
35 // A 4-vector is said to have a scalar part and a 3-vector part,
36 // which is indicated by the notation
38 // x^i = (x^0,x^1,x^2,x^3)
40 // The scalar part = x^0
41 // The 3-vector part = (x^1,x^2,x^3)
43 // In view of accuracy and the fact that e.g. particle identity (mass)
44 // is preserved in many physics processes, the Lorentz invariant
45 // (x^i*x_i) is internally saved together with the scalar part.
47 // This allows the following two modes of functionality :
49 // Scalar mode : The scalar part and the 3-vector part are considered
50 // as basic quantities and the invariant with its error
51 // is derived from these.
52 // Invariant mode : The invariant and the 3-vector part are considered
53 // as basic quantities and the scalar with its error
54 // is derived from these.
56 // The philosophy followed here is the following :
57 // ===============================================
59 // 1) Invokation of SetVector() sets the scalar and 3-vector parts
60 // and the invariant is calculated from these.
61 // Automatically the scalar mode is selected and invokation of
62 // SetErrors() will calculate the error on the invariant.
64 // 2) In case the scalar part is modified via SetScalar(), scalar mode is
65 // automatically selected and the Lorentz invariant (x^i*x_i) and its
66 // error are updated accordingly.
67 // The 3-vector part is NOT modified.
68 // This situation arises when one e.g. precisely determines the time
71 // 3) In case the Lorentz invariant (x^i*x_i) is modified via SetInvariant(),
72 // invariant mode is selected automatically and the scalar part and its
73 // error are updated accordingly.
74 // The 3-vector part is NOT modified.
75 // This situation arises when one e.g. precisely determines the mass.
77 // 4) In case the vector part is modified via Set3Vector(), then the
78 // current mode determines whether the scalar or the invariant is updated.
79 // Scalar mode : The Lorentz invariant (x^i*x_i) and its error are updated;
80 // the scalar part and its error are NOT modified.
81 // This situation arises when one e.g. improves the 3-position
82 // vector for a particle with a very precise timing.
83 // Invariant mode : The scalar part and its error are updated;
84 // the Lorentz invariant (x^i*x_i) and its error are NOT modified.
85 // This situation arises when one e.g. improves the 3-momentum
86 // vector for a particle with known mass.
88 // The dotproduct is defined such that p.Dot(p) yields the Lorentz invariant
89 // scalar of the 4-vector p (i.e. m**2 in case p is a 4-momentum).
93 // Vectors (v), Errors (e) and reference frames (f) are specified via
94 // SetVector(Float_t* v,TString f)
95 // SetErrors(Float_t* e,TString f)
96 // under the following conventions :
98 // f="car" ==> 3-vector part of v in Cartesian coordinates (x,y,z)
99 // f="sph" ==> 3-vector part of v in Spherical coordinates (r,theta,phi)
100 // f="cyl" ==> 3-vector part of v in Cylindrical coordinates (rho,phi,z)
102 // All angles are in radians.
109 // Float_t v[4]={25,-1,3,7};
110 // a.SetVector(v,"car");
113 // a.GetVector(vec,"sph");
116 // Float_t v2[4]={33,6,-18,2};
117 // b.SetVector(v2,"car");
119 // Float_t dotpro=a.Dot(b);
123 // Float_t vec2[3]={1,2,3};
124 // x.SetVector(vec2,"car");
127 // c.SetVector(x0,x);
128 // c.GetVector(vec,"car");
134 //--- Author: Nick van Eijndhoven 01-apr-1999 UU-SAP Utrecht
135 //- Modified: NvE 15-oct-1999 UU-SAP Utrecht
136 ///////////////////////////////////////////////////////////////////////////
138 #include "Ali4Vector.h"
140 ClassImp(Ali4Vector) // Class implementation to enable ROOT I/O
142 Ali4Vector::Ali4Vector()
144 // Creation of a contravariant 4-vector and initialisation of parameters.
145 // All values are initialised to 0.
146 // Scalar mode is initially selected.
153 Double_t a[3]={0,0,0};
154 fV.SetVector(a,"sph");
156 ///////////////////////////////////////////////////////////////////////////
157 Ali4Vector::~Ali4Vector()
159 // Destructor to delete dynamically allocated memory
161 ///////////////////////////////////////////////////////////////////////////
162 void Ali4Vector::SetVector(Double_t v0,Ali3Vector v)
164 // Store contravariant vector.
165 // The error on the scalar part is initialised to 0.
166 // The errors on the vector part are taken from the input Ali3Vector.
167 // Scalar mode is automatically selected.
168 // The error on scalar result operations is reset to 0.
172 fV2=pow(v0,2)-fV.Dot(fV);
175 ///////////////////////////////////////////////////////////////////////////
176 void Ali4Vector::SetVector(Double_t* v,TString f)
178 // Store vector according to reference frame f.
179 // All errors are initialised to 0.
180 // Scalar mode is automatically selected.
181 // The error on scalar result operations is reset to 0.
184 for (Int_t i=0; i<3; i++)
190 fV2=pow(fV0,2)-fV.Dot(fV);
195 ///////////////////////////////////////////////////////////////////////////
196 void Ali4Vector::GetVector(Double_t* v,TString f)
198 // Provide 4-vector components according to reference frame f
199 // and according to the current mode.
200 // Scalar mode : The scalar part is directly returned via v[0].
201 // Invariant mode : The scalar part is re-calculated via the value
202 // of the Lorentz invariant and then returned via v[0].
209 v[0]=sqrt(fV.Dot(fV)+fV2);
213 for (Int_t i=0; i<3; i++)
218 ///////////////////////////////////////////////////////////////////////////
219 void Ali4Vector::SetVector(Float_t* v,TString f)
221 // Store vector according to reference frame f.
222 // All errors are initialised to 0.
223 // Scalar mode is automatically selected.
224 // The error on scalar result operations is reset to 0.
226 for (Int_t i=0; i<4; i++)
232 ///////////////////////////////////////////////////////////////////////////
233 void Ali4Vector::GetVector(Float_t* v,TString f)
235 // Provide 4-vector components according to reference frame f
236 // and according to the current mode.
237 // Scalar mode : The scalar part is directly returned via v[0].
238 // Invariant mode : The scalar part is re-calculated via the value
239 // of the Lorentz invariant and then returned via v[0].
242 for (Int_t i=0; i<4; i++)
247 ///////////////////////////////////////////////////////////////////////////
248 Double_t Ali4Vector::GetScalar()
250 // Provide the scalar part.
251 // The error on the scalar value is available via GetResultError()
252 // after invokation of GetScalar().
260 Double_t dot=fV.Dot(fV);
261 Double_t ddot=fV.GetResultError();
262 Double_t v02=dot+fV2;
263 Double_t dv02=sqrt(pow(ddot,2)+pow(fDv2,2));
264 Double_t v0=sqrt(fabs(v02));
266 if (v0) dv0=dv02/(2.*v0);
271 ///////////////////////////////////////////////////////////////////////////
272 Double_t Ali4Vector::GetResultError()
274 // Provide the error on the result of an operation yielding a scalar
275 // E.g. GetScalar(), GetInvariant() or Dot()
278 ///////////////////////////////////////////////////////////////////////////
279 void Ali4Vector::SetScalar(Double_t v0,Double_t dv0)
281 // Modify the scalar part (v0) and its error (dv0).
282 // The default value for dv0 is 0.
283 // The vector part is not modified.
284 // Scalar mode is automatically selected
285 // ==> Lorentz invariant and its error are updated.
286 // The error on scalar result operations is reset to 0.
289 fV2=pow(v0,2)-fV.Dot(fV);
292 ///////////////////////////////////////////////////////////////////////////
293 void Ali4Vector::SetScalarError(Double_t dv0)
295 // Set the error on the scalar part.
296 // If in scalar mode, update error on the invariant accordingly.
297 // The error on scalar result operations is reset to 0.
301 Double_t norm=fV.GetNorm();
302 Double_t dnorm=fV.GetResultError();
303 fDv2=sqrt(pow(2.*fV0*fDv0,2)+pow(2.*norm*dnorm,2));
307 ///////////////////////////////////////////////////////////////////////////
308 void Ali4Vector::Set3Vector(Ali3Vector v)
310 // Set the 3-vector part, the errors are taken from the input Ali3Vector
311 // Scalar mode : The scalar part and its error are not modified,
312 // the Lorentz invariantand its error are re-calculated.
313 // Invariant mode : The Lorentz invariant and its error are not modified,
314 // the scalar part and its error are re-calculated.
315 // The error on scalar result operations is reset to 0.
323 SetInvariant(fV2,fDv2);
326 ///////////////////////////////////////////////////////////////////////////
327 void Ali4Vector::Set3Vector(Double_t* v,TString f)
329 // Set the 3-vector part according to reference frame f
330 // The errors on the vector part are initialised to 0
331 // Scalar mode : The scalar part and its error are not modified,
332 // the Lorentz invariantand its error are re-calculated.
333 // Invariant mode : The Lorentz invariant and its error are not modified,
334 // the scalar part and its error are re-calculated.
335 // The error on scalar result operations is reset to 0.
337 for (Int_t i=0; i<3; i++)
349 SetInvariant(fV2,fDv2);
352 ///////////////////////////////////////////////////////////////////////////
353 void Ali4Vector::Set3Vector(Float_t* v,TString f)
355 // Set the 3-vector part according to reference frame f
356 // The errors on the vector part are initialised to 0
357 // The Lorentz invariant is not modified
358 // The error on scalar result operations is reset to 0.
360 for (Int_t i=0; i<3; i++)
366 ///////////////////////////////////////////////////////////////////////////
367 void Ali4Vector::SetInvariant(Double_t v2,Double_t dv2)
369 // Modify the Lorentz invariant (v2) quantity v^i*v_i and its error (dv2).
370 // The default value for the error dv2 is 0.
371 // The vector part is not modified.
372 // Invariant mode is automatically selected
373 // ==> the scalar part and its error are updated.
374 // The error on scalar result operations is reset to 0.
380 fDv0=GetResultError();
383 ///////////////////////////////////////////////////////////////////////////
384 void Ali4Vector::SetInvariantError(Double_t dv2)
386 // Set the error on the Lorentz invariant.
387 // If in invariant mode, update error on the scalar part accordingly.
388 // The error on scalar result operations is reset to 0.
392 fDv0=GetResultError();
396 ///////////////////////////////////////////////////////////////////////////
397 Double_t Ali4Vector::GetInvariant()
399 // Provide the Lorentz invariant v^i*v_i.
400 // The error on the Lorentz invariant is available via GetResultError()
401 // after invokation of GetInvariant().
409 Double_t inv=Dot(*this);
413 ///////////////////////////////////////////////////////////////////////////
414 Ali3Vector Ali4Vector::Get3Vector()
416 // Provide the 3-vector part
419 ///////////////////////////////////////////////////////////////////////////
420 void Ali4Vector::SetErrors(Double_t* e,TString f)
422 // Store errors for vector v^i according to reference frame f
423 // If in scalar mode, update error on the invariant accordingly.
424 // The error on scalar result operations is reset to 0.
426 for (Int_t i=0; i<3; i++)
430 SetScalarError(e[0]);
433 ///////////////////////////////////////////////////////////////////////////
434 void Ali4Vector::SetErrors(Float_t* e,TString f)
436 // Store errors for vector v^i according to reference frame f
437 // If in scalar mode, update error on the invariant accordingly.
438 // The error on scalar result operations is reset to 0.
440 for (Int_t i=0; i<4; i++)
446 ///////////////////////////////////////////////////////////////////////////
447 void Ali4Vector::GetErrors(Double_t* e,TString f)
449 // Provide errors for vector v^i according to reference frame f
450 // and according to the current mode.
451 // Scalar mode : The error on the scalar part is directly returned via e[0].
452 // Invariant mode : The error on the scalar part is re-calculated via the error
453 // value on the Lorentz invariant and then returned via e[0].
457 e[0]=GetResultError();
458 for (Int_t i=0; i<3; i++)
463 ///////////////////////////////////////////////////////////////////////////
464 void Ali4Vector::GetErrors(Float_t* e,TString f)
466 // Provide errors for vector v^i according to reference frame f
467 // and according to the current mode.
468 // Scalar mode : The error on the scalar part is directly returned via e[0].
469 // Invariant mode : The error on the scalar part is re-calculated via the error
470 // value on the Lorentz invariant and then returned via e[0].
473 for (Int_t i=0; i<4; i++)
478 ///////////////////////////////////////////////////////////////////////////
479 void Ali4Vector::Info(TString f)
481 // Print contravariant vector components and errors according to
482 // reference frame f and according to the current mode.
483 // Scalar mode : The scalar part and its error are directly returned.
484 // Invariant mode : The scalar part and its error are re-calculated via the
485 // value (and error) of the Lorentz invariant.
487 if (f=="car" || f=="sph" || f=="cyl")
489 Double_t vec[4],err[4];
492 Double_t inv=GetInvariant();
493 Double_t dinv=GetResultError();
494 cout << " Contravariant vector in " << f << " coordinates : "
495 << vec[0] << " " << vec[1] << " " << vec[2] << " " << vec[3] << endl;
496 cout << " ------------- Errors in " << f << " coordinates : "
497 << err[0] << " " << err[1] << " " << err[2] << " " << err[3] << endl;
498 cout << " --- Lorentz invariant (v^i*v_i) : " << inv << " error : " << dinv << endl;
502 cout << " *Ali4Vector::Info* Unsupported frame : " << f << endl
503 << " Possible frames are 'car', 'sph' and 'cyl'." << endl;
506 ///////////////////////////////////////////////////////////////////////////
507 Double_t Ali4Vector::Dot(Ali4Vector& q)
509 // Provide the dot product of the current vector with vector q
511 Double_t a0=GetScalar();
512 Double_t da0=GetResultError();
513 if ((this) == &q) // Check for special case v.Dot(v)
515 Double_t norm=fV.GetNorm();
516 Double_t dnorm=fV.GetResultError();
517 dotpro=pow(a0,2)-pow(norm,2);
518 fDresult=sqrt(pow(2.*a0*da0,2)+pow(2.*norm*dnorm,2));
522 Double_t b0=q.GetScalar();
523 Double_t db0=q.GetResultError();
524 Ali3Vector b=q.Get3Vector();
526 Double_t dot=fV.Dot(b);
527 Double_t ddot=fV.GetResultError();
531 fDresult=sqrt(pow(b0*da0,2)+pow(a0*db0,2)+pow(ddot,2));
536 ///////////////////////////////////////////////////////////////////////////
537 Ali4Vector Ali4Vector::operator+(Ali4Vector& q)
539 // Add 4-vector q to the current 4-vector
540 // Error propagation is performed automatically
541 Double_t a0=GetScalar();
542 Double_t da0=GetResultError();
543 Ali3Vector a=Get3Vector();
544 Double_t b0=q.GetScalar();
545 Double_t db0=q.GetResultError();
546 Ali3Vector b=q.Get3Vector();
550 Double_t dc0=sqrt(pow(da0,2)+pow(db0,2));
554 v.SetScalarError(dc0);
557 ///////////////////////////////////////////////////////////////////////////
558 Ali4Vector Ali4Vector::operator-(Ali4Vector& q)
560 // Subtract 4-vector q from the current 4-vector
561 // Error propagation is performed automatically
562 Double_t a0=GetScalar();
563 Double_t da0=GetResultError();
564 Ali3Vector a=Get3Vector();
565 Double_t b0=q.GetScalar();
566 Double_t db0=q.GetResultError();
567 Ali3Vector b=q.Get3Vector();
571 Double_t dc0=sqrt(pow(da0,2)+pow(db0,2));
575 v.SetScalarError(dc0);
578 ///////////////////////////////////////////////////////////////////////////
579 Ali4Vector Ali4Vector::operator*(Double_t s)
581 // Multiply the current 4-vector with a scalar s
582 // Error propagation is performed automatically
583 Double_t a0=GetScalar();
584 Double_t da0=GetResultError();
585 Ali3Vector a=Get3Vector();
593 v.SetScalarError(da0);
597 ///////////////////////////////////////////////////////////////////////////
598 Ali4Vector Ali4Vector::operator/(Double_t s)
600 // Divide the current vector by a scalar s
601 // Error propagation is performed automatically
603 if (fabs(s)<1.e-20) // Protect against division by 0
605 cout << " *Ali4Vector::/* Division by 0 detected. No action taken." << endl;
610 Double_t a0=GetScalar();
611 Double_t da0=GetResultError();
612 Ali3Vector a=Get3Vector();
620 v.SetScalarError(da0);
625 ///////////////////////////////////////////////////////////////////////////
626 Ali4Vector& Ali4Vector::operator+=(Ali4Vector& q)
628 // Add 4-vector q to the current 4-vector
629 // Error propagation is performed automatically
630 Double_t a0=GetScalar();
631 Double_t da0=GetResultError();
632 Ali3Vector a=Get3Vector();
633 Double_t b0=q.GetScalar();
634 Double_t db0=q.GetResultError();
635 Ali3Vector b=q.Get3Vector();
639 Double_t dc0=sqrt(pow(da0,2)+pow(db0,2));
646 ///////////////////////////////////////////////////////////////////////////
647 Ali4Vector& Ali4Vector::operator-=(Ali4Vector& q)
649 // Subtract 4-vector q from the current 4-vector
650 // Error propagation is performed automatically
651 Double_t a0=GetScalar();
652 Double_t da0=GetResultError();
653 Ali3Vector a=Get3Vector();
654 Double_t b0=q.GetScalar();
655 Double_t db0=q.GetResultError();
656 Ali3Vector b=q.Get3Vector();
660 Double_t dc0=sqrt(pow(da0,2)+pow(db0,2));
667 ///////////////////////////////////////////////////////////////////////////
668 Ali4Vector& Ali4Vector::operator*=(Double_t s)
670 // Multiply the current 4-vector with a scalar s
671 // Error propagation is performed automatically
672 Double_t a0=GetScalar();
673 Double_t da0=GetResultError();
674 Ali3Vector a=Get3Vector();
685 ///////////////////////////////////////////////////////////////////////////
686 Ali4Vector& Ali4Vector::operator/=(Double_t s)
688 // Divide the current vector by a scalar s
689 // Error propagation is performed automatically
691 if (fabs(s)<1.e-20) // Protect against division by 0
693 cout << " *Ali4Vector::/* Division by 0 detected. No action taken." << endl;
698 Double_t a0=GetScalar();
699 Double_t da0=GetResultError();
700 Ali3Vector a=Get3Vector();
712 ///////////////////////////////////////////////////////////////////////////
713 Int_t Ali4Vector::GetScalarFlag()
715 // Provide the value of the fScalar flag (for internal use only).
718 ///////////////////////////////////////////////////////////////////////////