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
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
00321
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; }
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
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)
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
00588
00589
00590
00591
00592
00593
00594
00595
00596 #endif // INCLUDE_TMBVECTOR3