00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 #ifndef ST_THREE_VECTOR_HH
00094 #define ST_THREE_VECTOR_HH
00095 #ifdef __ROOT__
00096 #include "Rtypes.h"
00097 #endif
00098 #ifndef __CINT__
00099 #include <Stiostream.h>
00100 #include <math.h>
00101 #ifdef GNU_GCC
00102 # include <stddef.h>
00103 #endif
00104 #if defined (__SUNPRO_CC) && __SUNPRO_CC < 0x500
00105 # include <stdcomp.h>
00106 #endif
00107 #ifndef ST_NO_EXCEPTIONS
00108 # include <stdexcept>
00109 # if !defined(ST_NO_NAMESPACES)
00110 using std::out_of_range;
00111 # endif
00112 #endif
00113 #endif // __CINT__
00114
00115 template<class T> class StThreeVector {
00116 public:
00117 StThreeVector();
00118 StThreeVector(T, T, T);
00119
00120 #if ROOT_VERSION_CODE >= 328449
00121 StThreeVector(TRootIOCtor*) : mX1(0), mX2(0), mX3(0) {}
00122 #endif
00123 virtual ~StThreeVector();
00124
00125 #if !defined(ST_NO_MEMBER_TEMPLATES) && !defined(__CINT__)
00126 template<class X> StThreeVector(const StThreeVector<X>&);
00127 template<class X> StThreeVector(const X*);
00128 template<class X> StThreeVector<T>& operator=(const StThreeVector<X>&);
00129
00130
00131 #else
00132 StThreeVector(const StThreeVector<float>&);
00133 StThreeVector(const StThreeVector<double>&);
00134
00135 StThreeVector(const float*);
00136 StThreeVector(const double*);
00137
00138 StThreeVector<T>& operator=(const StThreeVector<float>&);
00139 StThreeVector<T>& operator=(const StThreeVector<double>&);
00140 #endif
00141
00142 void setX(T);
00143 void setY(T);
00144 void setZ(T);
00145 void set(T X,T Y, T Z) {mX1=X;mX2=Y;mX3=Z;}
00146
00147 void setPhi(T);
00148 void setTheta(T);
00149 void setMag(T);
00150 void setMagnitude(T);
00151
00152 const T& x() const;
00153 const T& y() const;
00154 const T& z() const;
00155 const T* xyz() const;
00156 T* xyz();
00157 T theta() const;
00158 T cosTheta() const;
00159 T phi() const;
00160 T perp() const;
00161 T perp2() const;
00162 T magnitude() const;
00163 T mag() const;
00164 T mag2() const;
00165 T pseudoRapidity() const;
00166 T operator() (size_t) const;
00167 T operator[] (size_t) const;
00168
00169 T& operator() (size_t);
00170 T& operator[] (size_t);
00171
00172 T massHypothesis(T mass) const;
00173
00174 StThreeVector<T> unit() const;
00175 StThreeVector<T> orthogonal() const;
00176
00177 void rotateX(T);
00178 void rotateY(T);
00179 void rotateZ(T);
00180
00181 StThreeVector<T> operator- ();
00182 StThreeVector<T> operator+ ();
00183 StThreeVector<T>& operator*= (double);
00184 StThreeVector<T>& operator/= (double);
00185 StThreeVector<T> pseudoProduct(double,double,double) const;
00186
00187 #if !defined(ST_NO_MEMBER_TEMPLATES) && !defined(__CINT__)
00188 template<class X> T angle(const StThreeVector<X>&) const;
00189 template<class X> StThreeVector<T> cross(const StThreeVector<X>&) const;
00190 template<class X> T dot (const StThreeVector<X>&) const;
00191 template<class X> StThreeVector<T> pseudoProduct(const StThreeVector<X>&) const;
00192
00193 template<class X> bool operator == (const StThreeVector<X>& v) const;
00194 template<class X> bool operator != (const StThreeVector<X>& v) const;
00195
00196 template<class X> StThreeVector<T>& operator+= (const StThreeVector<X>&);
00197 template<class X> StThreeVector<T>& operator-= (const StThreeVector<X>&);
00198 #else
00199 T angle(const StThreeVector<float>&) const;
00200 StThreeVector<T> cross(const StThreeVector<float>&) const;
00201 T dot (const StThreeVector<float>&) const;
00202 StThreeVector<T> pseudoProduct(const StThreeVector<float>&) const;
00203
00204 T angle(const StThreeVector<double>&) const;
00205 T dot (const StThreeVector<double>&) const;
00206 StThreeVector<T> cross(const StThreeVector<double>&) const;
00207 StThreeVector<T> pseudoProduct(const StThreeVector<double>&) const;
00208
00209 bool operator == (const StThreeVector<float>& v) const;
00210 bool operator != (const StThreeVector<float>& v) const;
00211 StThreeVector<T>& operator+= (const StThreeVector<float>&);
00212 StThreeVector<T>& operator-= (const StThreeVector<float>&);
00213
00214 bool operator == (const StThreeVector<double>& v) const;
00215 bool operator != (const StThreeVector<double>& v) const;
00216 StThreeVector<T>& operator+= (const StThreeVector<double>&);
00217 StThreeVector<T>& operator-= (const StThreeVector<double>&);
00218 #endif
00219 int valid(double world = 1.e+5) const;
00220 int bad(double world = 1.e+5) const;
00221 protected:
00222 T mX1, mX2, mX3;
00223 #ifdef __ROOT__
00224 ClassDef(StThreeVector,3)
00225 #endif
00226 };
00227
00228
00229
00230
00231 template<class T>
00232 inline StThreeVector<T>::StThreeVector()
00233 : mX1(0), mX2(0), mX3(0) {}
00234
00235 template<class T>
00236 inline StThreeVector<T>::StThreeVector(T X, T Y, T Z)
00237 : mX1(X), mX2(Y), mX3(Z) {}
00238 template<class T>
00239 inline StThreeVector<T>::~StThreeVector() {}
00240
00241 template<class T>
00242 inline void StThreeVector<T>::setX(T X) {mX1 = X;}
00243
00244 template<class T>
00245 inline void StThreeVector<T>::setY(T Y) {mX2 = Y;}
00246
00247 template<class T>
00248 inline void StThreeVector<T>::setZ(T Z) {mX3 = Z;}
00249
00250 template<class T>
00251 void StThreeVector<T>::setPhi(T Angle)
00252 {
00253 double r = magnitude();
00254 double th = theta();
00255
00256 mX1 = r*sin(th)*cos(Angle);
00257 mX2 = r*sin(th)*sin(Angle);
00258 }
00259
00260 template <class T>
00261 void StThreeVector<T>::setTheta(T Angle)
00262 {
00263 double r = magnitude();
00264 double ph = phi();
00265
00266 mX1 = r*sin(Angle)*cos(ph);
00267 mX2 = r*sin(Angle)*sin(ph);
00268 mX3 = r*cos(Angle);
00269 }
00270
00271 template <class T>
00272 void StThreeVector<T>::setMagnitude(T r)
00273 {
00274 double th = theta();
00275 double ph = phi();
00276
00277 mX1 = r*sin(th)*cos(ph);
00278 mX2 = r*sin(th)*sin(ph);
00279 mX3 = r*cos(th);
00280 }
00281
00282 template <class T>
00283 void StThreeVector<T>::setMag(T Mag)
00284 {
00285 setMagnitude(Mag);
00286 }
00287
00288 template<class T>
00289 inline const T& StThreeVector<T>::x() const {return mX1;}
00290
00291 template<class T>
00292 inline const T& StThreeVector<T>::y() const {return mX2;}
00293
00294 template<class T>
00295 inline const T& StThreeVector<T>::z() const {return mX3;}
00296
00297 template<class T>
00298 inline const T* StThreeVector<T>::xyz() const {return &mX1;}
00299
00300 template<class T>
00301 inline T* StThreeVector<T>::xyz() {return &mX1;}
00302
00303 template<class T>
00304 inline T StThreeVector<T>::theta() const
00305 {
00306 return acos(cosTheta());
00307 }
00308
00309 template<class T>
00310 inline T StThreeVector<T>::cosTheta() const
00311 {
00312 return mX3/(mag()+1e-20);
00313 }
00314
00315 template<class T>
00316 inline T StThreeVector<T>::phi() const
00317 {
00318 return atan2(mX2,mX1);
00319 }
00320
00321 template<class T>
00322 inline T StThreeVector<T>::pseudoRapidity() const
00323 {
00324
00325
00326
00327
00328 double tmp = tan(theta()/2.); if (tmp <=0.) return 1e20;
00329 return -::log(tmp);
00330 }
00331
00332 template<class T>
00333 inline StThreeVector<T> StThreeVector<T>::unit() const
00334 {
00335 double tmp = mag(); if (tmp<=0.) tmp = 1e-20;
00336 return *this/tmp;
00337 }
00338
00339 template <class T>
00340 T StThreeVector<T>::massHypothesis(T mass) const
00341 {
00342 return ::sqrt((*this)*(*this) + mass*mass);
00343 }
00344
00345 template <class T>
00346 StThreeVector<T> StThreeVector<T>::orthogonal() const
00347 {
00348
00349
00350 double X = (mX1 < 0.0) ? -mX1 : mX1;
00351 double Y = (mX2 < 0.0) ? -mX2 : mX2;
00352 double Z = (mX3 < 0.0) ? -mX3 : mX3;
00353
00354 if(X<Y)
00355 return X < Z ? StThreeVector<T>(0,mX3,-mX2) : StThreeVector<T>(mX2,-mX1,0);
00356 else
00357 return mX2 < mX3 ? StThreeVector<T>(-mX3,0,mX1) : StThreeVector<T>(mX2,-mX1,0);
00358 }
00359
00360 template <class T>
00361 void StThreeVector<T>::rotateX(T Angle)
00362 {
00363
00364 double yPrime = cos(Angle)*mX2 - sin(Angle)*mX3;
00365 double zPrime = sin(Angle)*mX2 + cos(Angle)*mX3;
00366
00367 mX2 = yPrime;
00368 mX3 = zPrime;
00369 }
00370
00371 template <class T>
00372 void StThreeVector<T>::rotateY(T Angle)
00373 {
00374
00375 double zPrime = cos(Angle)*mX3 - sin(Angle)*mX1;
00376 double xPrime = sin(Angle)*mX3 + cos(Angle)*mX1;
00377
00378 mX1 = xPrime;
00379 mX3 = zPrime;
00380 }
00381
00382 template <class T>
00383 void StThreeVector<T>::rotateZ(T Angle)
00384 {
00385
00386 double xPrime = cos(Angle)*mX1 - sin(Angle)*mX2;
00387 double yPrime = sin(Angle)*mX1 + cos(Angle)*mX2;
00388
00389 mX1 = xPrime;
00390 mX2 = yPrime;
00391 }
00392
00393 template<class T>
00394 inline T StThreeVector<T>::perp() const
00395 {
00396 return ::sqrt(mX1*mX1+mX2*mX2);
00397 }
00398
00399 template<class T>
00400 inline T StThreeVector<T>::perp2() const
00401 {
00402 return mX1*mX1+mX2*mX2;
00403 }
00404
00405 template<class T>
00406 inline T StThreeVector<T>::magnitude() const
00407 {
00408 return mag();
00409 }
00410
00411 template<class T>
00412 inline T StThreeVector<T>::mag() const
00413 {
00414 return ::sqrt(mX1*mX1+mX2*mX2+mX3*mX3);
00415 }
00416
00417 template<class T>
00418 inline T StThreeVector<T>::mag2() const
00419 {
00420 return mX1*mX1+mX2*mX2+mX3*mX3;
00421 }
00422
00423 template<class T>
00424 inline T StThreeVector<T>::operator() (size_t i) const
00425 {
00426 if (i <= 2) return (&mX1)[i];
00427 #ifndef ST_NO_EXCEPTIONS
00428 throw out_of_range("StThreeVector<T>::operator(): bad index");
00429 #else
00430 cerr << "StThreeVector<T>::operator(): bad index" << endl;
00431 #endif
00432 return 0;
00433 }
00434
00435 template<class T>
00436 inline T& StThreeVector<T>::operator() (size_t i)
00437 {
00438 if (i <= 2) return (&mX1)[i];
00439 #ifndef ST_NO_EXCEPTIONS
00440 throw out_of_range("StThreeVector<T>::operator(): bad index");
00441 #else
00442 cerr << "StThreeVector<T>::operator(): bad index" << endl;
00443 #endif
00444 return mX1;
00445 }
00446
00447 template<class T>
00448 inline T StThreeVector<T>::operator[] (size_t i) const
00449 {
00450 if (i <= 2) return (&mX1)[i];
00451 #ifndef ST_NO_EXCEPTIONS
00452 throw out_of_range("StThreeVector<T>::operator[]: bad index");
00453 #else
00454 cerr << "StThreeVector<T>::operator[]: bad index" << endl;
00455 #endif
00456 return 0;
00457 }
00458
00459 template<class T>
00460 inline T &StThreeVector<T>::operator[] (size_t i)
00461 {
00462 if (i <= 2) return (&mX1)[i];
00463 #ifndef ST_NO_EXCEPTIONS
00464 throw out_of_range("StThreeVector<T>::operator[]: bad index");
00465 #else
00466 cerr << "StThreeVector<T>::operator[]: bad index" << endl;
00467 #endif
00468 return mX1;
00469 }
00470 #ifndef __CINT__
00471 template<class T>
00472 inline StThreeVector<T>& StThreeVector<T>::operator*= (double c)
00473 {
00474 mX1 *= c; mX2 *= c; mX3 *= c;
00475 return *this;
00476 }
00477 #else
00478 template <> StThreeVector<double>& StThreeVector<double>::operator*= (double c);
00479 template <> StThreeVector<float>& StThreeVector<float>::operator*= (double c);
00480 #endif
00481 template<class T>
00482 inline StThreeVector<T>& StThreeVector<T>::operator/= (double c)
00483 {
00484 mX1 /= c; mX2 /= c; mX3 /= c;
00485 return *this;
00486 }
00487
00488 template<class T>
00489 inline StThreeVector<T>
00490 StThreeVector<T>::pseudoProduct(double X,double Y,double Z) const
00491 {
00492 return StThreeVector<T>(mX1*X,mX2*Y,mX3*Z);
00493 }
00494
00495 template<class T>
00496 StThreeVector<T> StThreeVector<T>::operator- ()
00497 {
00498 return StThreeVector<T>(-mX1, -mX2, -mX3);
00499 }
00500
00501 template<class T>
00502 StThreeVector<T> StThreeVector<T>::operator+ ()
00503 {
00504 return *this;
00505 }
00506
00507 #if !defined(ST_NO_MEMBER_TEMPLATES) && !defined(__CINT__)
00508
00509 template<class T>
00510 template<class X>
00511 inline StThreeVector<T>::StThreeVector(const StThreeVector<X>& v)
00512 : mX1(v.x()), mX2(v.y()), mX3(v.z()) {}
00513
00514 template<class T>
00515 template<class X>
00516 inline StThreeVector<T>::StThreeVector(const X *a)
00517 {
00518 mX1 = a[0];
00519 mX2 = a[1];
00520 mX3 = a[2];
00521 }
00522
00523 template<class T>
00524 template<class X>
00525 inline StThreeVector<T>&
00526 StThreeVector<T>::operator=(const StThreeVector<X>& v)
00527 {
00528 mX1 = v.x(); mX2 = v.y(); mX3 = v.z();
00529 return *this;
00530 }
00531
00532 template<class T>
00533 template<class X>
00534 inline bool StThreeVector<T>::operator== (const StThreeVector<X>& v) const
00535 {
00536 return mX1 == v.x() && mX2 == v.y() && mX3 == v.z();
00537 }
00538
00539 template<class T>
00540 template<class X>
00541 inline bool StThreeVector<T>::operator!= (const StThreeVector<X>& v) const
00542 {
00543 return !(*this == v);
00544 }
00545
00546 template<class T>
00547 template<class X>
00548 inline StThreeVector<T>&
00549 StThreeVector<T>::operator+= (const StThreeVector<X>& v)
00550 {
00551 mX1 += v.x(); mX2 += v.y(); mX3 += v.z();
00552 return *this;
00553 }
00554
00555 template<class T>
00556 template<class X>
00557 inline StThreeVector<T>&
00558 StThreeVector<T>::operator-= (const StThreeVector<X>& v)
00559 {
00560 mX1 -= v.x(); mX2 -= v.y(); mX3 -= v.z();
00561 return *this;
00562 }
00563
00564 template<class T>
00565 template<class X>
00566 inline T StThreeVector<T>::dot(const StThreeVector<X>& v) const
00567 {
00568 return mX1*v.x() + mX2*v.y() + mX3*v.z();
00569 }
00570
00571 template<class T>
00572 template<class X>
00573 inline StThreeVector<T>
00574 StThreeVector<T>::cross(const StThreeVector<X>& v) const
00575 {
00576 return StThreeVector<T>(mX2*v.z() - mX3*v.y(),
00577 mX3*v.x() - mX1*v.z(),
00578 mX1*v.y() - mX2*v.x());
00579 }
00580
00581 template<class T>
00582 template<class X>
00583 inline T StThreeVector<T>::angle(const StThreeVector<X>& vec) const
00584 {
00585 double norm = this->mag2()*vec.mag2();
00586
00587 return norm > 0 ? acos(this->dot(vec)/(::sqrt(norm))) : 0;
00588 }
00589
00590 template<class T>
00591 template<class X>
00592 inline StThreeVector<T>
00593 StThreeVector<T>::pseudoProduct(const StThreeVector<X>& v) const
00594 {
00595 return this->pseudoProduct(v.x(),v.y(),v.z());
00596 }
00597
00598 #else
00599
00600 template<class T>
00601 inline StThreeVector<T>::StThreeVector(const StThreeVector<float>& v)
00602 : mX1(v.x()), mX2(v.y()), mX3(v.z()) {}
00603
00604 template<class T>
00605 inline StThreeVector<T>::StThreeVector(const StThreeVector<double>& v)
00606 : mX1(v.x()), mX2(v.y()), mX3(v.z()) {}
00607
00608 template<class T>
00609 inline StThreeVector<T>::StThreeVector(const float *a)
00610 {
00611 mX1 = a[0];
00612 mX2 = a[1];
00613 mX3 = a[2];
00614 }
00615
00616 template<class T>
00617 inline StThreeVector<T>::StThreeVector(const double *a)
00618 {
00619 mX1 = a[0];
00620 mX2 = a[1];
00621 mX3 = a[2];
00622 }
00623
00624 template<class T>
00625 inline StThreeVector<T>&
00626 StThreeVector<T>::operator=(const StThreeVector<float>& v)
00627 {
00628 mX1 = v.x(); mX2 = v.y(); mX3 = v.z();
00629 return *this;
00630 }
00631
00632 template<class T>
00633 inline StThreeVector<T>&
00634 StThreeVector<T>::operator=(const StThreeVector<double>& v)
00635 {
00636 mX1 = v.x(); mX2 = v.y(); mX3 = v.z();
00637 return *this;
00638 }
00639
00640 template<class T>
00641 inline bool
00642 StThreeVector<T>::operator== (const StThreeVector<float>& v) const
00643 {
00644 return mX1 == v.x() && mX2 == v.y() && mX3 == v.z();
00645 }
00646
00647 template<class T>
00648 inline bool
00649 StThreeVector<T>::operator== (const StThreeVector<double>& v) const
00650 {
00651 return mX1 == v.x() && mX2 == v.y() && mX3 == v.z();
00652 }
00653
00654 template<class T>
00655 inline bool
00656 StThreeVector<T>::operator!= (const StThreeVector<float>& v) const
00657 {
00658 return !(*this == v);
00659 }
00660
00661 template<class T>
00662 inline bool
00663 StThreeVector<T>::operator!= (const StThreeVector<double>& v) const
00664 {
00665 return !(*this == v);
00666 }
00667
00668 template<class T>
00669 inline StThreeVector<T>&
00670 StThreeVector<T>::operator+= (const StThreeVector<float>& v)
00671 {
00672 mX1 += v.x(); mX2 += v.y(); mX3 += v.z();
00673 return *this;
00674 }
00675
00676 template<class T>
00677 inline StThreeVector<T>&
00678 StThreeVector<T>::operator+= (const StThreeVector<double>& v)
00679 {
00680 mX1 += v.x(); mX2 += v.y(); mX3 += v.z();
00681 return *this;
00682 }
00683
00684 template<class T>
00685 inline StThreeVector<T>&
00686 StThreeVector<T>::operator-= (const StThreeVector<float>& v)
00687 {
00688 mX1 -= v.x(); mX2 -= v.y(); mX3 -= v.z();
00689 return *this;
00690 }
00691
00692 template<class T>
00693 inline StThreeVector<T>&
00694 StThreeVector<T>::operator-= (const StThreeVector<double>& v)
00695 {
00696 mX1 -= v.x(); mX2 -= v.y(); mX3 -= v.z();
00697 return *this;
00698 }
00699
00700 template<class T>
00701 inline T StThreeVector<T>::dot(const StThreeVector<float>& v) const
00702 {
00703 return mX1*v.x() + mX2*v.y() + mX3*v.z();
00704 }
00705
00706 template<class T>
00707 inline T StThreeVector<T>::dot(const StThreeVector<double>& v) const
00708 {
00709 return mX1*v.x() + mX2*v.y() + mX3*v.z();
00710 }
00711
00712 template<class T>
00713 inline StThreeVector<T>
00714 StThreeVector<T>::cross(const StThreeVector<float>& v) const
00715 {
00716 return StThreeVector<T>(mX2*v.z() - mX3*v.y(),
00717 mX3*v.x() - mX1*v.z(),
00718 mX1*v.y() - mX2*v.x());
00719 }
00720
00721 template<class T>
00722 inline StThreeVector<T>
00723 StThreeVector<T>::cross(const StThreeVector<double>& v) const
00724 {
00725 return StThreeVector<T>(mX2*v.z() - mX3*v.y(),
00726 mX3*v.x() - mX1*v.z(),
00727 mX1*v.y() - mX2*v.x());
00728 }
00729
00730 template<class T>
00731 inline T StThreeVector<T>::angle(const StThreeVector<float>& v) const
00732 {
00733 double tmp = mag()*v.mag(); if (tmp <=0) tmp = 1e-20;
00734 return acos(this->dot(v)/tmp);
00735 }
00736
00737 template<class T>
00738 inline T StThreeVector<T>::angle(const StThreeVector<double>& v) const
00739 {
00740 double tmp = mag()*v.mag(); if (tmp <=0) tmp = 1e-20;
00741 return acos(this->dot(v)/tmp);
00742 }
00743
00744 template<class T>
00745 inline StThreeVector<T>
00746 StThreeVector<T>::pseudoProduct(const StThreeVector<float>& v) const
00747 {
00748 return this->pseudoProduct(v.x(),v.y(),v.z());
00749 }
00750
00751 template<class T>
00752 inline StThreeVector<T>
00753 StThreeVector<T>::pseudoProduct(const StThreeVector<double>& v) const
00754 {
00755 return this->pseudoProduct(v.x(),v.y(),v.z());
00756 }
00757 #endif // ST_NO_MEMBER_TEMPLATES
00758 template<class T>
00759 inline int
00760 StThreeVector<T>::valid(double world) const {return !bad(world);}
00761
00762 template<class T>
00763 inline int
00764 StThreeVector<T>::bad(double world) const
00765 {
00766 for (int i=0;i<3;i++) {
00767 if (!::finite((&mX1)[i]) ) return 10+i;
00768 if ( ::fabs ((&mX1)[i])>world) return 20+i;
00769 }
00770 return 0;
00771 }
00772
00773
00774
00775 #if !defined(ST_NO_MEMBER_TEMPLATES) && !defined(__CINT__)
00776 template<class T>
00777 inline T abs(const StThreeVector<T>& v) {return v.mag();}
00778 template<class T, class X>
00779 inline StThreeVector<T>
00780 cross_product(const StThreeVector<T>& v1, const StThreeVector<X>& v2)
00781 {
00782 return v1.cross(v2);
00783 }
00784 template<class T, class X>
00785 inline StThreeVector<T>
00786 operator+ (const StThreeVector<T>& v1, const StThreeVector<X>& v2)
00787 {
00788 return StThreeVector<T>(v1) += v2;
00789 }
00790
00791 template<class T, class X>
00792 inline StThreeVector<T>
00793 operator- (const StThreeVector<T>& v1, const StThreeVector<X>& v2)
00794 {
00795 return StThreeVector<T>(v1) -= v2;
00796 }
00797
00798 template<class T, class X>
00799 inline T operator* (const StThreeVector<T>& v1, const StThreeVector<X>& v2)
00800 {
00801 return StThreeVector<T>(v1).dot(v2);
00802 }
00803 #else
00804 template<>
00805 inline double abs(const StThreeVector<double>& v) {return v.mag();}
00806
00807 template<>
00808 inline float abs(const StThreeVector<float>& v) {return v.mag();}
00809
00810 template<class T>
00811 inline StThreeVector<T>
00812 cross_product(const StThreeVector<T>& v1, const StThreeVector<double>& v2)
00813 {
00814 return v1.cross(v2);
00815 }
00816 template<class T>
00817 inline StThreeVector<T>
00818 cross_product(const StThreeVector<T>& v1, const StThreeVector<float>& v2)
00819 {
00820 return v1.cross(v2);
00821 }
00822
00823
00824
00825
00826
00827 template<class T>
00828 inline StThreeVector<T>
00829 operator+ (const StThreeVector<T>& v1, const StThreeVector<double>& v2)
00830 {
00831 return StThreeVector<T>(v1) += v2;
00832 }
00833
00834 template<class T>
00835 inline StThreeVector<T>
00836 operator- (const StThreeVector<T>& v1, const StThreeVector<double>& v2)
00837 {
00838 return StThreeVector<T>(v1) -= v2;
00839 }
00840 #ifndef __CINT__
00841 template<class T>
00842 inline T operator* (const StThreeVector<T>& v1, const StThreeVector<double>& v2)
00843 {
00844 return StThreeVector<T>(v1).dot(v2);
00845 }
00846 template<class T>
00847 inline T operator* (const StThreeVector<T>& v1, const StThreeVector<float>& v2)
00848 {
00849 return StThreeVector<T>(v1).dot(v2);
00850 }
00851 #else
00852 template<> double operator* (const StThreeVector<double>& v1, const StThreeVector<double>& v2);
00853 template<> double operator* (const StThreeVector<double>& v1, const StThreeVector<float>& v2);
00854 template<> double operator* (const StThreeVector<float>& v1, const StThreeVector<double>& v2);
00855 template<> float operator* (const StThreeVector<float>& v1, const StThreeVector<float>& v2);
00856 #endif
00857 template<class T>
00858 inline StThreeVector<T>
00859 operator+ (const StThreeVector<T>& v1, const StThreeVector<float>& v2)
00860 {
00861 return StThreeVector<T>(v1) += v2;
00862 }
00863
00864 template<class T>
00865 inline StThreeVector<T>
00866 operator- (const StThreeVector<T>& v1, const StThreeVector<float>& v2)
00867 {
00868 return StThreeVector<T>(v1) -= v2;
00869 }
00870
00871 #endif
00872 template<class T>
00873 inline StThreeVector<T> operator* (const StThreeVector<T>& v, double c)
00874 {
00875 return StThreeVector<T>(v) *= c;
00876 }
00877
00878 template<class T>
00879 inline StThreeVector<T> operator* (double c, const StThreeVector<T>& v)
00880 {
00881 return StThreeVector<T>(v) *= c;
00882 }
00883
00884 template<class T>
00885 inline StThreeVector<T> operator/ (const StThreeVector<T>& v,double c)
00886 {
00887 return StThreeVector<T>(v) /= c;
00888 }
00889 #ifndef __CINT__
00890 template<class T>
00891 ostream& operator<<(ostream& os, const StThreeVector<T>& v)
00892 {
00893 return os << v.x() << '\t' << v.y() << '\t' << v.z();
00894 }
00895 #else
00896 template<> ostream& operator<<(ostream& os, const StThreeVector<double>& v);
00897 template<> ostream& operator<<(ostream& os, const StThreeVector<float>& v);
00898 #endif
00899 template<class T>
00900 istream& operator>>(istream& is, StThreeVector<T>& v)
00901 {
00902 T x, y, z;
00903 is >> x >> y >> z;
00904 v.setX(x);
00905 v.setY(y);
00906 v.setZ(z);
00907 return is;
00908 }
00909 #endif