]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGCF/FEMTOSCOPY/AliFemto/AliFmLorentzVector.h
Merge branch 'feature-movesplit'
[u/mrichter/AliRoot.git] / PWGCF / FEMTOSCOPY / AliFemto / AliFmLorentzVector.h
1 /***************************************************************************
2  *
3  * $Id$
4  *
5  * Author: Brian Lasiuk, Thomas Ullrich, April 1998
6  ***************************************************************************
7  *
8  * Description:
9  *
10  * Remarks:   Since not all compilers support member templates
11  *            we have to specialize the templated member on these
12  *            platforms. If member templates are not supported the
13  *            ST_NO_MEMBER_TEMPLATES flag has to be set. tu.
14  *
15  *            In the near future when all compilers can handle member
16  *            templates this class should be cleaned up. A lot of
17  *            redundant code can be removed as soon as the compilers
18  *            are up-to-date. tu
19  *
20  ***************************************************************************
21  *
22  * $Log$
23  * Revision 1.1.1.1  2007/04/25 15:38:41  panos
24  * Importing the HBT code dir
25  *
26  * Revision 1.1.1.1  2007/03/07 10:14:49  mchojnacki
27  * First version on CVS
28  *
29  * Revision 1.11  2005/09/22 20:09:20  fisyak
30  * Make AliFmLorentzVector persistent
31  *
32  * Revision 1.10  2005/07/06 18:49:56  fisyak
33  * Replace AliFmHelixD, AliFmLorentzVectorD,AliFmLorentzVectorF,AliFmMatrixD,AliFmMatrixF,AliFmPhysicalHelixD,AliFmThreeVectorD,AliFmThreeVectorF by templated version
34  *
35  * Revision 1.9  2005/03/28 06:02:45  perev
36  * Defence FPE added
37  *
38  * Revision 1.8  2003/09/02 17:59:35  perev
39  * gcc 3.2 updates + WarnOff
40  *
41  * Revision 1.7  2003/05/01 19:24:31  ullrich
42  * Corrected problem in boost().
43  *
44  * Revision 1.6  1999/10/15 15:56:36  ullrich
45  * Changed output format in operator<<, added operator>>
46  *
47  * Revision 1.5  1999/06/04 18:01:36  ullrich
48  * New operators operator() and operator[] which can be used
49  * as lvalues.
50  *
51  * Revision 1.4  1999/04/14 23:12:07  fisyak
52  * Add __CINT__ to handle references
53  *
54  * Revision 1.3  1999/02/17 11:38:36  ullrich
55  * Removed specialization for 'long double'.
56  *
57  * Revision 1.2  1999/02/14 23:11:42  fisyak
58  * Fixes for Rootcint
59  *
60  * Revision 1.1  1999/01/30 03:59:02  fisyak
61  * Root Version of AliFmarClassLibrary
62  *
63  * Revision 1.1  1999/01/23 00:27:52  ullrich
64  * Initial Revision
65  *
66  **************************************************************************/
67 /*//
68 //// General class for a Lorentz four-vector
69 ///*/
70 #ifndef ST_LORENTZ_VECTOR_HH
71 #define ST_LORENTZ_VECTOR_HH
72
73 #include "AliFmThreeVector.h"
74 template<class T> class AliFmLorentzVector {
75 public:
76     AliFmLorentzVector(T = 0, T = 0, T = 0, T = 0);
77     virtual ~AliFmLorentzVector();
78     
79 #ifndef ST_NO_MEMBER_TEMPLATES
80     template<class X> AliFmLorentzVector(const AliFmThreeVector<X>&, T);
81     template<class X> AliFmLorentzVector(T, const AliFmThreeVector<X>&);   
82
83     template<class X> AliFmLorentzVector(const AliFmLorentzVector<X>&);
84     template<class X> AliFmLorentzVector<T>& operator=(const AliFmLorentzVector<X>&);
85     // AliFmLorentzVector(const AliFmLorentzVector<T>&);                use default
86     // AliFmLorentzVector<T>& operator=(const AliFmLorentzVector<T>&);  use default
87 #else
88     AliFmLorentzVector(const AliFmThreeVector<float>&, T);
89     AliFmLorentzVector(T, const AliFmThreeVector<float>&);   
90     AliFmLorentzVector(const AliFmLorentzVector<float>&);
91     
92     AliFmLorentzVector(const AliFmThreeVector<double>&, T);
93     AliFmLorentzVector(T, const AliFmThreeVector<double>&);   
94     AliFmLorentzVector(const AliFmLorentzVector<double>&);
95         
96     AliFmLorentzVector<T>& operator=(const AliFmLorentzVector<float>&);
97     AliFmLorentzVector<T>& operator=(const AliFmLorentzVector<double>&);
98 #endif
99     
100     T x()                     const;
101     T y()                     const;
102     T z()                     const;
103     T t()                     const;
104     T px()                    const;
105     T py()                    const;
106     T pz()                    const;
107     T e()                     const;
108     T operator()  (size_t)    const;
109     T operator[]  (size_t)    const;
110     
111     T& operator()  (size_t);
112     T& operator[]  (size_t);
113
114     const AliFmThreeVector<T>& vect() const;    
115     
116     void SetX(T);
117     void SetY(T);
118     void SetZ(T);
119     void SetPx(T);
120     void SetPy(T);
121     void SetPz(T);
122     void SetE(T);
123     void SetT(T);
124     
125 #ifndef ST_NO_MEMBER_TEMPLATES
126     template <class X> void SetVect(const AliFmThreeVector<X>&);
127 #else
128     void SetVect(const AliFmThreeVector<float>&);
129     void SetVect(const AliFmThreeVector<double>&);
130 #endif   
131
132     T Perp()               const;
133     T Perp2()              const;
134     T PseudoRapidity()     const;
135     T Phi()                const;
136     T Theta()              const;
137     T CosTheta()           const;
138     
139     T Plus()               const;
140     T Minus()              const;
141     
142     T m()                  const; 
143     T m2()                 const; 
144     T mt()                 const;
145     T mt2()                const;
146     T Rapidity()           const;
147     
148 #ifndef ST_NO_MEMBER_TEMPLATES
149     template<class X> AliFmLorentzVector<T> boost(const AliFmLorentzVector<X>&) const;
150 #else
151     AliFmLorentzVector<T> boost(const AliFmLorentzVector<float>&) const;
152     AliFmLorentzVector<T> boost(const AliFmLorentzVector<double>&) const;
153 #endif   
154     
155     AliFmLorentzVector<T>  operator- ();
156     AliFmLorentzVector<T>  operator+ ();
157     AliFmLorentzVector<T>& operator*= (double);
158     AliFmLorentzVector<T>& operator/= (double);
159
160 #ifndef ST_NO_MEMBER_TEMPLATES
161     template<class X> bool operator == (const AliFmLorentzVector<X>&) const;
162     template<class X> bool operator != (const AliFmLorentzVector<X>&) const;
163     template<class X> AliFmLorentzVector<T>& operator+= (const AliFmLorentzVector<X>&);
164     template<class X> AliFmLorentzVector<T>& operator-= (const AliFmLorentzVector<X>&);
165 #else    
166     bool operator == (const AliFmLorentzVector<float>&) const;
167     bool operator != (const AliFmLorentzVector<float>&) const;
168     bool operator == (const AliFmLorentzVector<double>&) const;
169     bool operator != (const AliFmLorentzVector<double>&) const;
170
171     AliFmLorentzVector<T>& operator+= (const AliFmLorentzVector<float>&);
172     AliFmLorentzVector<T>& operator-= (const AliFmLorentzVector<float>&);
173     AliFmLorentzVector<T>& operator+= (const AliFmLorentzVector<double>&);
174     AliFmLorentzVector<T>& operator-= (const AliFmLorentzVector<double>&);
175 #endif
176
177 protected:
178     AliFmThreeVector<T> fThreeVector; // The spatial three-vector
179     T                fX4;             // The fourth components
180 #ifdef __ROOT__
181   ClassDef(AliFmLorentzVector,3)
182 #endif
183 };
184 #ifndef __CINT__
185 //
186 //        Implementation of member functions
187 //
188 template<class T>
189 AliFmLorentzVector<T>::AliFmLorentzVector(T ax, T ay, T az, T at)
190     : fThreeVector(ax, ay, az), fX4(at) { /* nop */ }
191
192 template<class T>
193 AliFmLorentzVector<T>::~AliFmLorentzVector() { /* nopt */ }    
194
195 template<class T>
196 const AliFmThreeVector<T>& AliFmLorentzVector<T>::vect() const 
197 {
198     return fThreeVector;
199 }
200
201 template<class T>
202 T AliFmLorentzVector<T>::m2() const
203 {
204     return (fX4*fX4 - fThreeVector*fThreeVector);    
205 }
206
207 template<class T>
208 T AliFmLorentzVector<T>::Plus() const { return (e() + pz()); }
209
210 template<class T>
211 T AliFmLorentzVector<T>::Minus() const { return (e() - pz()); }
212
213 template<class T>
214 T AliFmLorentzVector<T>::m() const
215 {
216     T mass2 = m2();
217     if (mass2 < 0)
218         return -::sqrt(-mass2);
219     else
220         return ::sqrt(mass2);
221 }
222
223 template<class T>
224 T AliFmLorentzVector<T>::mt2() const
225 {
226     return this->Perp2() + m2();
227 }
228
229 template<class T>
230 T AliFmLorentzVector<T>::mt() const
231 {
232     //
233     // change to more optimal code ?
234     // return e()*e() - pz()*pz();
235     T massPerp2 = mt2();
236     if (massPerp2 < 0)
237         return -::sqrt(-massPerp2);
238     else
239         return ::sqrt(massPerp2);
240 }
241
242 template<class T>
243 void AliFmLorentzVector<T>::SetPx(T ax) {fThreeVector.SetX(ax);}
244
245 template<class T>
246 void AliFmLorentzVector<T>::SetPy(T ay) {fThreeVector.SetY(ay);}
247
248 template<class T>
249 void AliFmLorentzVector<T>::SetPz(T az) {fThreeVector.SetZ(az);}
250
251 template<class T>
252 void AliFmLorentzVector<T>::SetX(T ax) {fThreeVector.SetX(ax);}
253
254 template<class T>
255 void AliFmLorentzVector<T>::SetY(T ay) {fThreeVector.SetY(ay);}
256
257 template<class T>
258 void AliFmLorentzVector<T>::SetZ(T az) {fThreeVector.SetZ(az);}
259
260 template<class T>
261 void AliFmLorentzVector<T>::SetT(T at) {fX4 = at;}
262
263 template<class T>
264 void AliFmLorentzVector<T>::SetE(T ae) {fX4 = ae;}
265
266 template<class T>
267 T AliFmLorentzVector<T>::x() const {return fThreeVector.x();}
268
269 template<class T>
270 T AliFmLorentzVector<T>::y() const {return fThreeVector.y();}
271
272 template<class T>
273 T AliFmLorentzVector<T>::z() const {return fThreeVector.z();}
274
275 template<class T>
276 T AliFmLorentzVector<T>::px() const {return fThreeVector.x();}
277
278 template<class T>
279 T AliFmLorentzVector<T>::py() const {return fThreeVector.y();}
280
281 template<class T>
282 T AliFmLorentzVector<T>::pz() const {return fThreeVector.z();}
283
284 template<class T>
285 T AliFmLorentzVector<T>::e() const {return fX4;}
286
287 template<class T>
288 T AliFmLorentzVector<T>::t() const {return fX4;}
289
290 template<class T>
291 T AliFmLorentzVector<T>::Perp() const {return fThreeVector.Perp();}
292
293 template<class T>
294 T AliFmLorentzVector<T>::Perp2() const {return fThreeVector.Perp2();}
295
296 template<class T>
297 T AliFmLorentzVector<T>::PseudoRapidity() const {return fThreeVector.PseudoRapidity();}
298
299 template<class T>
300 T AliFmLorentzVector<T>::Phi() const {return fThreeVector.Phi();}
301
302 template<class T>
303 T AliFmLorentzVector<T>::Theta() const {return fThreeVector.Theta();}
304
305 template<class T>
306 T AliFmLorentzVector<T>::CosTheta() const {return fThreeVector.CosTheta();}
307
308 template<class T>
309 T AliFmLorentzVector<T>::operator() (size_t i) const
310 {
311     if (i < 3)
312         return fThreeVector(i);
313     else if (i == 3)
314         return fX4;
315     else {
316 #ifndef ST_NO_EXCEPTIONS
317       throw out_of_range("AliFmLorentzVector<T>::operator(): bad index");  
318 #else
319       cerr << "AliFmLorentzVector<T>::operator(): bad index." << endl;
320 #endif
321       return 0;
322     }
323 }
324
325 template<class T>
326 T& AliFmLorentzVector<T>::operator() (size_t i)
327 {
328     if (i < 3)
329         return fThreeVector(i);
330     else if (i == 3)
331         return fX4;
332     else {
333 #ifndef ST_NO_EXCEPTIONS
334       throw out_of_range("AliFmLorentzVector<T>::operator(): bad index");  
335 #else
336       cerr << "AliFmLorentzVector<T>::operator(): bad index." << endl;
337       return fX4;
338 #endif
339     }
340 }
341
342 template<class T>
343 T AliFmLorentzVector<T>::operator[] (size_t i) const
344 {
345     if (i < 3)
346         return fThreeVector[i];
347     else if (i == 3)
348         return fX4;
349     else {
350 #ifndef ST_NO_EXCEPTIONS
351       throw out_of_range("AliFmLorentzVector<T>::operator[]: bad index"); 
352 #else
353       cerr << "AliFmLorentzVector<T>::operator[]: bad index." << endl;
354       return 0;
355 #endif
356     }
357 }
358
359 template<class T>
360 T& AliFmLorentzVector<T>::operator[] (size_t i)
361 {
362     if (i < 3)
363         return fThreeVector[i];
364     else if (i == 3)
365         return fX4;
366     else {
367 #ifndef ST_NO_EXCEPTIONS
368       throw out_of_range("AliFmLorentzVector<T>::operator[]: bad index"); 
369 #else
370       cerr << "AliFmLorentzVector<T>::operator[]: bad index." << endl;
371       return fX4;
372 #endif
373     }
374 }
375
376 template<class T>
377 T AliFmLorentzVector<T>::Rapidity() const
378 {
379     return 0.5*::log((fX4+fThreeVector.z())/(fX4-fThreeVector.z())+1e-20);
380 }
381
382 template<class T>
383 AliFmLorentzVector<T> AliFmLorentzVector<T>::operator- ()
384 {
385     return AliFmLorentzVector<T>(-fX4,-fThreeVector);
386 }
387
388 template<class T>
389 AliFmLorentzVector<T> AliFmLorentzVector<T>::operator+ ()
390 {
391     return *this;
392 }
393
394 template<class T>
395 AliFmLorentzVector<T>& AliFmLorentzVector<T>::operator*= (double c)
396 {
397     fThreeVector *= c;
398     fX4 *= c;
399     return *this;
400 }
401
402 template<class T>
403 AliFmLorentzVector<T>& AliFmLorentzVector<T>::operator/= (double c)
404 {
405     fThreeVector /= c;
406     fX4 /= c;
407     return *this;
408 }
409
410 #ifndef ST_NO_MEMBER_TEMPLATES
411 #ifndef WIN32
412
413 template<class T>
414 template<class X>
415 AliFmLorentzVector<T>::AliFmLorentzVector(const AliFmThreeVector<X> &vec, T at)
416         : fThreeVector(vec), fX4(at) { /* nop */ }
417
418 template<class T>
419 template<class X>
420 AliFmLorentzVector<T>::AliFmLorentzVector(T at, const AliFmThreeVector<X> &vec)
421         : fThreeVector(vec), fX4(at) { /* nop */ }
422
423 template<class T>
424 template<class X>
425 AliFmLorentzVector<T>::AliFmLorentzVector(const AliFmLorentzVector<X> &vec)
426         : fThreeVector(vec.vect()), fX4(vec.t()) { /* nop */ }
427
428 template<class T>
429 template<class X>
430 AliFmLorentzVector<T>
431 AliFmLorentzVector<T>::boost(const AliFmLorentzVector<X>& pframe) const
432 {
433     T mass               = abs(pframe);
434     AliFmThreeVector<T> eta = (-1./mass)*pframe.vect();            // gamma*beta
435     T gamma              = fabs(pframe.e())/mass;
436     AliFmThreeVector<T> pl  = ((this->vect()*eta)/(eta*eta))*eta;  // longitudinal momentum
437     return AliFmLorentzVector<T>(gamma*this->e() - this->vect()*eta,
438                               this->vect() + (gamma-1.)*pl - this->e()*eta);
439 }
440
441 template<class T>
442 template<class X>
443 void AliFmLorentzVector<T>::SetVect(const AliFmThreeVector<X>& v)
444 {
445     fThreeVector = v;
446 }
447
448 template<class T>
449 template<class X>
450 AliFmLorentzVector<T>&
451 AliFmLorentzVector<T>::operator=(const AliFmLorentzVector<X>& vec)
452 {
453     fThreeVector = vec.vect();
454     fX4 = vec.t();
455     return *this;
456 }
457
458 template<class T>
459 template<class X>
460 bool
461 AliFmLorentzVector<T>::operator== (const AliFmLorentzVector<X>& v) const
462 {
463     return (fThreeVector == v.vect()) && (fX4 == v.t());
464 }
465
466 template<class T>
467 template<class X>
468 bool
469 AliFmLorentzVector<T>::operator!= (const AliFmLorentzVector<X>& v) const
470 {
471     return !(*this == v);
472 }
473
474 template<class T>
475 template<class X>
476 AliFmLorentzVector<T>&
477 AliFmLorentzVector<T>::operator+= (const AliFmLorentzVector<X>& v)
478 {
479     fThreeVector += v.vect();
480     fX4 += v.t();
481     return *this;
482 }
483
484 template<class T>
485 template<class X>
486 AliFmLorentzVector<T>&
487 AliFmLorentzVector<T>::operator-= (const AliFmLorentzVector<X>& v)
488 {
489     fThreeVector -= v.vect();
490     fX4 -= v.t();
491     return *this;
492 }
493
494 #endif 
495 #else
496
497 template<class T>
498 AliFmLorentzVector<T>::AliFmLorentzVector(const AliFmThreeVector<float> &vec, T t)
499         : fThreeVector(vec), fX4(t) { /* nop */ }
500
501 template<class T>
502 AliFmLorentzVector<T>::AliFmLorentzVector(const AliFmThreeVector<double> &vec, T t)
503         : fThreeVector(vec), fX4(t) { /* nop */ }
504
505 template<class T>
506 AliFmLorentzVector<T>::AliFmLorentzVector(T t, const AliFmThreeVector<float> &vec)
507         : fThreeVector(vec), fX4(t) { /* nop */ }
508
509 template<class T>
510 AliFmLorentzVector<T>::AliFmLorentzVector(T t, const AliFmThreeVector<double> &vec)
511         : fThreeVector(vec), fX4(t) { /* nop */ }
512
513 template<class T>
514 AliFmLorentzVector<T>::AliFmLorentzVector(const AliFmLorentzVector<float> &vec)
515         : fThreeVector(vec.vect()), fX4(vec.t()) { /* nop */ }
516     
517 template<class T>
518 AliFmLorentzVector<T>::AliFmLorentzVector(const AliFmLorentzVector<double> &vec)
519         : fThreeVector(vec.vect()), fX4(vec.t()) { /* nop */ }
520     
521 template<class T>
522 AliFmLorentzVector<T>
523 AliFmLorentzVector<T>::boost(const AliFmLorentzVector<float>& pframe) const
524 {
525     T mass               = abs(pframe);
526     AliFmThreeVector<T> eta = (-1./mass)*pframe.vect();            // gamma*beta
527     T gamma              = fabs(pframe.e())/mass;
528     AliFmThreeVector<T> pl  = ((this->vect()*eta)/(eta*eta))*eta;  // longitudinal momentum
529     return AliFmLorentzVector<T>(gamma*this->e() - this->vect()*eta,
530                               this->vect() + (gamma-1.)*pl - this->e()*eta);
531 }
532
533 template<class T>
534 AliFmLorentzVector<T>
535 AliFmLorentzVector<T>::boost(const AliFmLorentzVector<double>& pframe) const
536 {
537     T mass               = abs(pframe);
538     AliFmThreeVector<T> eta = (-1./mass)*pframe.vect();            // gamma*beta
539     T gamma              = fabs(pframe.e())/mass;
540     AliFmThreeVector<T> pl  = ((this->vect()*eta)/(eta*eta))*eta;  // longitudinal momentum
541     return AliFmLorentzVector<T>(gamma*this->e() - this->vect()*eta,
542                               this->vect() + (gamma-1.)*pl - this->e()*eta);
543 }
544
545 template<class T>
546 void AliFmLorentzVector<T>::SetVect(const AliFmThreeVector<float>& v)
547 {
548     fThreeVector = v;
549 }
550
551 template<class T>
552 void AliFmLorentzVector<T>::SetVect(const AliFmThreeVector<double>& v)
553 {
554     fThreeVector = v;
555 }
556
557 template<class T>
558 AliFmLorentzVector<T>&
559 AliFmLorentzVector<T>::operator=(const AliFmLorentzVector<float>& vec)
560 {
561     fThreeVector = vec.vect();
562     fX4 = vec.t();
563     return *this;
564 }
565
566 template<class T>
567 AliFmLorentzVector<T>&
568 AliFmLorentzVector<T>::operator=(const AliFmLorentzVector<double>& vec)
569 {
570     fThreeVector = vec.vect();
571     fX4 = vec.t();
572     return *this;
573 }
574
575 template<class T>
576 bool
577 AliFmLorentzVector<T>::operator== (const AliFmLorentzVector<float>& v) const
578 {
579     return (this->vect() == v.vect()) && (fX4 == v.t());
580 }
581
582 template<class T>
583 bool
584 AliFmLorentzVector<T>::operator== (const AliFmLorentzVector<double>& v) const
585 {
586     return (fThreeVector == v.vect()) && (fX4 == v.t());
587 }
588
589 template<class T>
590 bool
591 AliFmLorentzVector<T>::operator!= (const AliFmLorentzVector<float>& v) const
592 {
593     return !(*this == v);
594 }
595
596 template<class T>
597 bool
598 AliFmLorentzVector<T>::operator!= (const AliFmLorentzVector<double>& v) const
599 {
600     return !(*this == v);
601 }
602
603 template<class T>
604 AliFmLorentzVector<T>&
605 AliFmLorentzVector<T>::operator+= (const AliFmLorentzVector<float>& v)
606 {
607     fThreeVector += v.vect();
608     fX4 += v.t();
609     return *this;
610 }
611
612 template<class T>
613 AliFmLorentzVector<T>&
614 AliFmLorentzVector<T>::operator+= (const AliFmLorentzVector<double>& v)
615 {
616     fThreeVector += v.vect();
617     fX4 += v.t();
618     return *this;
619 }
620
621 template<class T>
622 AliFmLorentzVector<T>&
623 AliFmLorentzVector<T>::operator-= (const AliFmLorentzVector<float>& v)
624 {
625     fThreeVector -= v.vect();
626     fX4 -= v.t();
627     return *this;
628 }
629
630 template<class T>
631 AliFmLorentzVector<T>&
632 AliFmLorentzVector<T>::operator-= (const AliFmLorentzVector<double>& v)
633 {
634     fThreeVector -= v.vect();
635     fX4 -= v.t();
636     return *this;
637 }
638
639 #endif // ST_NO_MEMBER_TEMPLATES
640 #endif /* ! __CINT__ */
641 #ifdef __CINT__
642 template<> AliFmLorentzVector<double> operator+ (const AliFmLorentzVector<double>& v1, const AliFmLorentzVector<double>& v2);
643 template<> AliFmLorentzVector<double> operator+ (const AliFmLorentzVector<double>& v1, const AliFmLorentzVector<float>& v2);
644 template<> AliFmLorentzVector<double> operator+ (const AliFmLorentzVector<float>&  v1, const AliFmLorentzVector<double>& v2);
645 template<> AliFmLorentzVector<float>  operator+ (const AliFmLorentzVector<float>&  v1, const AliFmLorentzVector<float>& v2);
646 template<> AliFmLorentzVector<double> operator- (const AliFmLorentzVector<double>& v1, const AliFmLorentzVector<double>& v2);
647 template<> AliFmLorentzVector<double> operator- (const AliFmLorentzVector<double>& v1, const AliFmLorentzVector<float>& v2);
648 template<> AliFmLorentzVector<double> operator- (const AliFmLorentzVector<float>&  v1, const AliFmLorentzVector<double>& v2);
649 template<> AliFmLorentzVector<float>  operator- (const AliFmLorentzVector<float>&  v1, const AliFmLorentzVector<float>& v2);
650 template<> AliFmLorentzVector<double> operator* (const AliFmLorentzVector<double>& v1, const AliFmLorentzVector<double>& v2);
651 template<> AliFmLorentzVector<double> operator* (const AliFmLorentzVector<double>& v1, const AliFmLorentzVector<float>& v2);
652 template<> AliFmLorentzVector<double> operator* (const AliFmLorentzVector<float>&  v1, const AliFmLorentzVector<double>& v2);
653 template<> AliFmLorentzVector<float>  operator* (const AliFmLorentzVector<float>&  v1, const AliFmLorentzVector<float>& v2);
654 template<> AliFmLorentzVector<double> operator* (const              double v1, const AliFmLorentzVector<double>& v2);
655 template<> AliFmLorentzVector<double> operator* (const              double v1, const AliFmLorentzVector<float>&  v2);
656 template<> AliFmLorentzVector<double> operator* (const AliFmLorentzVector<double>& v1, const double              v2);
657 template<> AliFmLorentzVector<double> operator* (const AliFmLorentzVector<float>&  v1, const double              v2);
658 template<> AliFmLorentzVector<double> operator/ (const AliFmLorentzVector<double>& v1, const AliFmLorentzVector<double>& v2);
659 template<> AliFmLorentzVector<double> operator/ (const AliFmLorentzVector<double>& v1, const AliFmLorentzVector<float>& v2);
660 template<> AliFmLorentzVector<double> operator/ (const AliFmLorentzVector<float>&  v1, const AliFmLorentzVector<double>& v2);
661 template<> AliFmLorentzVector<float>  operator/ (const AliFmLorentzVector<float>&  v1, const AliFmLorentzVector<float>& v2);
662 template<> AliFmLorentzVector<double> operator/ (const              double v1, const AliFmLorentzVector<double>& v2);
663 template<> AliFmLorentzVector<double> operator/ (const              double v1, const AliFmLorentzVector<float>&  v2);
664 template<> AliFmLorentzVector<double> operator/ (const AliFmLorentzVector<double>& v1, const double              v2);
665 template<> AliFmLorentzVector<double> operator/ (const AliFmLorentzVector<float>&  v1, const double              v2);
666 template<> istream& operator>> (istream& is, const AliFmLorentzVector<double>& v);
667 template<> ostream& operator<< (ostream& os, const AliFmLorentzVector<double>& v);
668 template<> istream& operator>> (istream& is, const AliFmLorentzVector<float>& v);
669 template<> ostream& operator<< (ostream& os, const AliFmLorentzVector<float>& v);
670 template<> double abs(const AliFmLorentzVector<double>& v);
671 template<> float  abs(const AliFmLorentzVector<float>& v);
672 #else
673 //
674 //   Non-member operators
675 //
676 template<class T, class X>
677 AliFmLorentzVector<T>
678 operator+ (const AliFmLorentzVector<T>& v1, const AliFmLorentzVector<X>& v2)
679 {
680     return AliFmLorentzVector<T>(v1) += v2;
681 }
682
683 template<class T, class X>
684 AliFmLorentzVector<T>
685 operator- (const AliFmLorentzVector<T>& v1, const AliFmLorentzVector<X>& v2)
686 {
687     return AliFmLorentzVector<T>(v1) -= v2;
688 }
689
690 template<class T, class X>
691 T
692 operator* (const AliFmLorentzVector<T>& v1, const AliFmLorentzVector<X>& v2)
693 {
694     return v1.t()*v2.t() - v1.vect()*v2.vect();
695 }
696
697 template<class T>
698 AliFmLorentzVector<T>
699 operator* (const AliFmLorentzVector<T>& v, double c)
700 {
701     return AliFmLorentzVector<T>(v) *= c;
702 }
703
704 template<class T>
705 AliFmLorentzVector<T> operator* (double c, const AliFmLorentzVector<T>& v)
706 {
707     return AliFmLorentzVector<T>(v) *= c;
708 }
709
710 template<class T, class X>
711 AliFmLorentzVector<T> operator/ (const AliFmLorentzVector<T>& v, X c)
712 {
713     return AliFmLorentzVector<T>(v) /= c;
714 }
715
716 template<class T>
717 ostream& operator<< (ostream& os, const AliFmLorentzVector<T>& v)
718 {
719     return os << v.vect() << "\t\t" << v.t();
720 }
721
722 template<class T>
723 istream&  operator>>(istream& is, AliFmLorentzVector<T>& v)
724 {
725     T  x, y, z, t;
726     is >> x >> y >> z >> t;
727     v.SetX(x);
728     v.SetY(y);
729     v.SetZ(z);
730     v.SetT(t);
731     return is;
732 }
733
734 //
735 //        Non-member functions
736 //
737 template<class T>
738 T abs(const AliFmLorentzVector<T>& v) {return v.m();}
739
740 #endif /*  __CINT__ */
741 #endif