TMBVector3.hpp

Go to the documentation of this file.
00001 #ifndef INCLUDE_TMBVECTOR3
00002 #define INCLUDE_TMBVECTOR3
00003 
00004 #include "TMath.h"
00005 #include "TError.h"
00006 #include "TVector2.h"
00007 #include "TMatrix.h"
00008 #include "TRotation.h"
00009 
00163 class TMBVector3 : public TObject {
00164 public:
00165 
00166    TMBVector3(Double_t x = 0.0, Double_t y = 0.0, Double_t z = 0.0):
00167        fX(x), fY(y), fZ(z) {  
00168    }
00169 
00170    TMBVector3(const Double_t *a): fX(a[0]), fY(a[1]), fZ(a[2]) 
00171    { 
00172    }
00173 
00174    TMBVector3(const Float_t *a): fX(a[0]), fY(a[1]), fZ(a[2]) 
00175    { 
00176    }
00177 
00178    TMBVector3(const TMBVector3 &p): TObject(p),
00179       fX(p.fX), fY(p.fY), fZ(p.fZ)
00180    {  
00181    }
00182 
00183    TMBVector3(const TVector3& v): fX(v.X()), fY(v.Y()), fZ(v.Z())
00184    {
00186    }
00187 
00188   virtual ~TMBVector3() {}
00189   // Destructor
00190 
00191   Double_t operator () (int i) const {
00193      switch(i) {
00194      case 0: return fX;
00195      case 1: return fY;
00196      case 2: return fZ;
00197      default: Error("operator()(i)", "bad index (%d) returning &fX",i);
00198      }
00199      return 0.;
00200   }
00201      
00202   inline Double_t operator [] (int i) const { 
00203      return operator()(i); }
00204 
00205 
00206   Double_t & operator () (int i) {
00208 
00209      switch(i) {
00210      case 0: return fX;
00211      case 1: return fY;
00212      case 2: return fZ;
00213      default: Error("operator()(i)", "bad index (%d) returning &fX",i);
00214      }
00215      return fX;
00216   }
00217   inline Double_t & operator [] (int i) { 
00218      return operator()(i); }
00219 
00220    Double_t x() const { 
00221       return fX; }
00222    Double_t X() const { 
00223       return x(); }
00224    Double_t Px() const { 
00225       return x(); }
00226 
00227    Double_t y() const { 
00228       return fY; }
00229    Double_t Y() const { 
00230       return y(); }
00231    Double_t Py() const { 
00232       return y(); }
00233 
00234    Double_t z() const { 
00235       return fZ; }
00236    Double_t Z() const { 
00237       return z(); }
00238    Double_t Pz() const { 
00239       return z(); }
00240 
00241    void SetX(Double_t a) { 
00242       fX=a; }
00243    void SetPx(Double_t a) { 
00244       SetX(a); }
00245    void SetY(Double_t a) { 
00246       fY=a; }
00247    void SetPy(Double_t a) { 
00248       SetY(a); }
00249    void SetZ(Double_t a) { 
00250       fZ=a; }
00251    void SetPz(Double_t a) { 
00252       SetZ(a); }
00253    inline void SetXYZ(Double_t x, Double_t y, Double_t z) {
00255        fX=x; fY=y; fZ=z; }
00256     
00257    void SetPtEtaPhi(Double_t pt, Double_t eta, Double_t phi) {
00259       Double_t apt = TMath::Abs(pt);
00260       Double_t d=TMath::Tan(2.0*TMath::ATan(TMath::Exp(-eta)));
00261       if (d==0.) 
00262          Warning("SetPtEtaPhi", "tan(2*atan(exp(-eta)))==0.! Setting z=0.");
00263       SetXYZ(apt*TMath::Cos(phi), apt*TMath::Sin(phi), d==0.?0.:apt/d );
00264    }
00265    void SetPtThetaPhi(Double_t pt, Double_t theta, Double_t phi) {
00267       Double_t apt = TMath::Abs(pt);
00268       fX = apt * TMath::Cos(phi);
00269       fY = apt * TMath::Sin(phi); 
00270       Double_t tanTheta = TMath::Tan(theta);
00271       if (tanTheta==0.) 
00272          Warning("SetPtThetaPhi", "tan(theta)==0.! Setting z=0.");
00273       fZ = tanTheta ? apt / tanTheta : 0;
00274    }
00275    
00276    inline void GetXYZ(Double_t *carray) const {
00278       carray[0]=fX; carray[1]=fY; carray[2]=fZ; }
00279    inline void GetXYZ(Float_t *carray) const {
00281       carray[0]=fX; carray[1]=fY; carray[2]=fZ; }
00282 
00283    Double_t Eta() const { 
00284       return PseudoRapidity(); }
00285    Double_t Theta() const { 
00286       return fX==.0 && fY==.0 && fZ==.0 ? .0 : TMath::ATan2(Perp(),fZ); }
00287    Double_t CosTheta() const { 
00288       Double_t ptot = Mag3();
00289       return ptot == 0.0 ? 1.0 : fZ/ptot;
00290    }
00291    Double_t Phi() const { 
00292       return (fX==.0 && fY==.0 ? .0 : TVector2::Phi_0_2pi(TMath::ATan2(fY,fX))); }
00293 
00294    Double_t Rho() const { 
00295       return Mag3(); }
00296 
00297    virtual Double_t Mag32() const {
00299       return fX*fX + fY*fY + fZ*fZ; }
00300    virtual Double_t Mag3() const {
00302       return TMath::Sqrt(Mag32()); }
00303    Double_t P()  const { 
00304       return Mag3(); }
00305 
00306    Double_t DeltaPhi(const TMBVector3 &v) const { 
00308       return TVector2::Phi_mpi_pi(Phi()-v.Phi()); }
00309 
00310    Double_t DeltaR(const TMBVector3 &v) const {
00312       Double_t deta = Eta()-v.Eta();
00313       Double_t dphi = TVector2::Phi_mpi_pi(Phi()-v.Phi());
00314       return TMath::Sqrt( deta*deta+dphi*dphi );
00315    }
00316    Double_t DrEtaPhi(const TMBVector3 &lv) const {
00318       return DeltaR(lv); }
00319 
00320     //   TVector2 EtaPhiVector() { /// return TVector2(eta,phi)
00321     //      return TVector2 (Eta(),Phi()); }
00322 
00323    Double_t Angle(const TVector3 & q) const { 
00324       Double_t ptot2 = Mag32()*q.Mag2();
00325       if(ptot2 <= 0.) return .0;
00326       Double_t arg = Dot(q)/TMath::Sqrt(ptot2);
00327       if(arg >  1.0) arg =  1.0;
00328       if(arg < -1.0) arg = -1.0;
00329       return TMath::ACos(arg);
00330    }
00331 
00332    void SetPhi(Double_t ph) { 
00333       Double_t xy   = Perp();
00334       SetX(xy*TMath::Cos(ph));
00335       SetY(xy*TMath::Sin(ph));
00336    }
00337 
00338   inline void SetTheta(Double_t th) { 
00339      Double_t ma   = Mag3();
00340      Double_t ph   = Phi();
00341      SetX(ma*TMath::Sin(th)*TMath::Cos(ph));
00342      SetY(ma*TMath::Sin(th)*TMath::Sin(ph));
00343      SetZ(ma*TMath::Cos(th));
00344   }
00345 
00346   inline void SetMag3(Double_t ma) { 
00347      Double_t factor = Mag3();
00348      if (factor == 0) {
00349         Warning("SetMag3","zero vector can't be stretched");
00350      }else{
00351         factor = ma/factor;
00352         SetX(fX*factor);
00353         SetY(fY*factor);
00354         SetZ(fZ*factor);
00355      }
00356   }
00357   inline Double_t Perp2() const { 
00359      return fX*fX + fY*fY; }
00360   inline Double_t Pt() const { 
00362      return Perp(); }
00363   inline Double_t Perp() const { 
00365      return TMath::Sqrt(Perp2()); }
00366      
00367   inline void SetPerp(Double_t r) { 
00369      Double_t p = Perp();
00370      if (p != 0.0) {
00371         fX *= r/p;
00372         fY *= r/p;
00373      }
00374   }
00375 
00376   inline Double_t Perp2(const TMBVector3 &p) const { 
00378      Double_t tot = p.Mag32();
00379      Double_t ss  = Dot(p);
00380      return tot > 0.0 ? Mag32()-ss*ss/tot : Mag32();
00381   }
00382 
00383   inline Double_t Pt(const TMBVector3 &p) const {
00385      return Perp(p); }
00386   inline Double_t Perp(const TMBVector3 &p) const {
00388      return TMath::Sqrt(Perp2(p)); }
00389 
00390   inline void SetMag3ThetaPhi(Double_t mag, Double_t theta, Double_t phi) {
00392      Double_t amag = TMath::Abs(mag);
00393      fX = amag * TMath::Sin(theta) * TMath::Cos(phi);
00394      fY = amag * TMath::Sin(theta) * TMath::Sin(phi);
00395      fZ = amag * TMath::Cos(theta);
00396   }
00397 
00398   inline TMBVector3 & operator = (const TMBVector3 &p) {
00400      fX = p.fX; fY = p.fY; fZ = p.fZ;
00401      return *this;
00402   }
00403 
00404   inline Bool_t operator == (const TMBVector3 &v) const {
00406      return (v.fX==fX && v.fY==fY && v.fZ==fZ); }
00407   inline Bool_t operator != (const TMBVector3 &v) const {
00409      return (v.fX!=fX || v.fY!=fY || v.fZ!=fZ); }
00410 
00413   Bool_t is_equal (const TMBVector3 &v) const;
00414 
00415   inline TMBVector3 & operator += (const TMBVector3 &p) { 
00416      fX += p.fX; fY += p.fY; fZ += p.fZ;
00417      return *this;
00418   }
00419 
00420   inline TMBVector3 & operator -= (const TMBVector3 &p) { 
00421      fX -= p.fX; fY -= p.fY; fZ -= p.fZ;
00422      return *this;
00423   }
00424 
00425   inline TMBVector3 operator - () const { 
00426      return TMBVector3(-fX, -fY, -fZ); }
00427 
00428   inline TMBVector3 & operator *= (Double_t a) { 
00430      fX *= a; fY *= a; fZ *= a;
00431      return *this;
00432   }
00433 
00434   inline TMBVector3 Unit() const { 
00435      Double_t  tot = Mag32();
00436      TMBVector3 p(fX,fY,fZ);
00437      return tot>.0 ? p *= (1.0/TMath::Sqrt(tot)) : p;
00438   }
00439 
00440   inline TMBVector3 Orthogonal() const { 
00441      Double_t x = fX < 0.0 ? -fX : fX;
00442      Double_t y = fY < 0.0 ? -fY : fY;
00443      Double_t z = fZ < 0.0 ? -fZ : fZ;
00444      if (x < y)
00445         return x<z ? TMBVector3(0,fZ,-fY) : TMBVector3(fY,-fX,0);
00446      return y<z ? TMBVector3(-fZ,0,fX) : TMBVector3(fY,-fX,0);
00447   }
00448 
00449   Double_t Dot(const TMBVector3 &p) const { 
00450      return fX*p.fX + fY*p.fY + fZ*p.fZ; }
00451 
00452   inline TMBVector3 Cross(const TMBVector3 &p) const { 
00453      return TMBVector3(fY*p.fZ-p.fY*fZ, fZ*p.fX-p.fZ*fX, fX*p.fY-p.fX*fY);
00454   }
00455 
00456   Double_t PseudoRapidity() const {
00458      double cosTheta = CosTheta();
00459      if (cosTheta*cosTheta < 1) 
00460         return (-0.5* TMath::Log( (1.0-cosTheta)/(1.0+cosTheta) ));
00461      Warning("PseudoRapidity","transvers momentum = 0! return +/- 10e10");
00462      if (fZ > 0) return (10e10);
00463      else        return (-10e10);
00464   }
00465   void RotateX(Double_t angle) {
00467      Double_t s = TMath::Sin(angle);
00468      Double_t c = TMath::Cos(angle);
00469      Double_t yy = fY;
00470      fY = c*yy - s*fZ;
00471      fZ = s*yy + c*fZ;
00472   }
00473 
00474   void RotateY(Double_t angle) {
00476      Double_t s = TMath::Sin(angle);
00477      Double_t c = TMath::Cos(angle);
00478      Double_t zz = fZ;
00479      fZ = c*zz - s*fX;
00480      fX = s*zz + c*fX;
00481   }
00482 
00483   void RotateZ(Double_t angle) {
00485      Double_t s = TMath::Sin(angle);
00486      Double_t c = TMath::Cos(angle);
00487      Double_t xx = fX;
00488      fX = c*xx - s*fY;
00489      fY = s*xx + c*fY;
00490   }
00491 
00492   void RotateUz(const TMBVector3& NewUzVector) {
00494      Double_t u1 = NewUzVector.fX;
00495      Double_t u2 = NewUzVector.fY;
00496      Double_t u3 = NewUzVector.fZ;
00497      Double_t up = u1*u1 + u2*u2;
00498 
00499      if (up>0.) {
00500         up = TMath::Sqrt(up);
00501         Double_t px = fX,  py = fY,  pz = fZ;
00502         fX = (u1*u3*px - u2*py + u1*up*pz)/up;
00503         fY = (u2*u3*px + u1*py + u2*up*pz)/up;
00504         fZ = (u3*u3*px -    px + u3*up*pz)/up;
00505      }
00506      else if (u3 < 0.) { fX = -fX; fZ = -fZ; }      // phi=0  teta=pi
00507      else {};
00508   }
00509 
00510   void Rotate(Double_t angle, const TMBVector3 &axis) {
00512      TRotation trans;
00513      trans.Rotate(angle, (TVector3)axis);
00514      operator*=(trans);
00515   }
00516 
00517   TMBVector3 & operator *= (const TRotation &m) {
00519      return *this = m * (*this);
00520   }
00521   TMBVector3 & Transform(const TRotation &m) {
00523      return *this = m * (*this);
00524   }
00525 
00526    TVector2 XYvector() const {
00528      return TVector2(fX,fY); }
00529 
00530    operator TVector3() const { 
00532       return TVector3(X(),Y(),Z()); }
00533 
00534    void Print(Option_t* option="") const {
00536       Printf("%s %s (x,y,z)=(%f,%f,%f) (rho,theta,phi)=(%f,%f,%f)",
00537              GetName(),GetTitle(),X(),Y(),Z(),
00538              Mag3(),Theta()*TMath::RadToDeg(),Phi()*TMath::RadToDeg());
00539    }
00540 
00541    // Helper to test if two FP numbers are equivalent within machine precision.
00542    static bool is_equal (double x1, double x2);
00543 
00544 private:
00545    Double32_t fX; 
00546    Double32_t fY; 
00547    Double32_t fZ; 
00548 
00549    ClassDef(TMBVector3,1) // A 3D physics vector
00550 
00551 };
00552 
00553 inline
00554 TMBVector3 operator + (const TMBVector3 &a, const TMBVector3 &b) {
00556   return TVector3(a.X() + b.X(), a.Y() + b.Y(), a.Z() + b.Z()); }
00557 
00558 inline
00559 TMBVector3 operator - (const TMBVector3 &a, const TMBVector3 &b) {
00561    return TVector3(a.X() - b.X(), a.Y() - b.Y(), a.Z() - b.Z()); }
00562 
00563 inline
00564 Double_t operator * (const TMBVector3 &a, const TMBVector3 &b) {
00566    return a.Dot(b); }
00567 
00568 inline
00569 TMBVector3 operator * (const TMBVector3 &p, Double_t a) {
00571    return TVector3(a*p.X(), a*p.Y(), a*p.Z()); }
00572 
00573 inline
00574 TMBVector3 operator * (Double_t a, const TMBVector3 &p) {
00576    return TVector3(a*p.X(), a*p.Y(), a*p.Z()); }
00577 
00578 inline
00579 TMBVector3 operator * (const TMatrix &m, const TMBVector3 &v) {
00581   return TVector3( m(0,0)*v.X()+m(0,1)*v.Y()+m(0,2)*v.Z(),
00582                    m(1,0)*v.X()+m(1,1)*v.Y()+m(1,2)*v.Z(),
00583                    m(2,0)*v.X()+m(2,1)*v.Y()+m(2,2)*v.Z());
00584 }
00585 
00586 /*************************************************************************
00587  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00588  * All rights reserved.                                                  *
00589  *                                                                       *
00590  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00591  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00592  *************************************************************************/
00593 
00594 // Author: Pasha Murat, Peter Malzacher   12/02/99
00595 
00596 #endif // INCLUDE_TMBVECTOR3

Generated on Thu Apr 3 04:14:24 2008 for CAF by doxygen 1.3.4