File indexing completed on 2025-01-18 10:10:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef ROOT_Math_GenVector_VectorUtil
0019 #define ROOT_Math_GenVector_VectorUtil 1
0020
0021 #include "Math/Math.h"
0022
0023
0024 #include "Math/GenVector/Boost.h"
0025
0026 namespace ROOT {
0027
0028 namespace Math {
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 namespace VectorUtil {
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 template <class Vector1, class Vector2>
0061 inline typename Vector1::Scalar DeltaPhi( const Vector1 & v1, const Vector2 & v2) {
0062 typename Vector1::Scalar dphi = v2.Phi() - v1.Phi();
0063 if ( dphi > M_PI ) {
0064 dphi -= 2.0*M_PI;
0065 } else if ( dphi <= -M_PI ) {
0066 dphi += 2.0*M_PI;
0067 }
0068 return dphi;
0069 }
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 template <class Vector1, class Vector2>
0082 inline typename Vector1::Scalar DeltaR2( const Vector1 & v1, const Vector2 & v2) {
0083 typename Vector1::Scalar dphi = DeltaPhi(v1,v2);
0084 typename Vector1::Scalar deta = v2.Eta() - v1.Eta();
0085 return dphi*dphi + deta*deta;
0086 }
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 template <class Vector1, class Vector2>
0097 inline typename Vector1::Scalar DeltaR2RapidityPhi( const Vector1 & v1, const Vector2 & v2) {
0098 typename Vector1::Scalar dphi = DeltaPhi(v1,v2);
0099 typename Vector1::Scalar drap = v2.Rapidity() - v1.Rapidity();
0100 return dphi*dphi + drap*drap;
0101 }
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 template <class Vector1, class Vector2>
0112 inline typename Vector1::Scalar DeltaR( const Vector1 & v1, const Vector2 & v2) {
0113 using std::sqrt;
0114 return sqrt( DeltaR2(v1,v2) );
0115 }
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125 template <class Vector1, class Vector2>
0126 inline typename Vector1::Scalar DeltaRapidityPhi( const Vector1 & v1, const Vector2 & v2) {
0127 using std::sqrt;
0128 return sqrt( DeltaR2RapidityPhi(v1,v2) );
0129 }
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141 template <class Vector1, class Vector2>
0142 double CosTheta( const Vector1 & v1, const Vector2 & v2) {
0143 double arg;
0144 double v1_r2 = v1.X()*v1.X() + v1.Y()*v1.Y() + v1.Z()*v1.Z();
0145 double v2_r2 = v2.X()*v2.X() + v2.Y()*v2.Y() + v2.Z()*v2.Z();
0146 double ptot2 = v1_r2*v2_r2;
0147 if(ptot2 <= 0) {
0148 arg = 0.0;
0149 }else{
0150 double pdot = v1.X()*v2.X() + v1.Y()*v2.Y() + v1.Z()*v2.Z();
0151 using std::sqrt;
0152 arg = pdot/sqrt(ptot2);
0153 if(arg > 1.0) arg = 1.0;
0154 if(arg < -1.0) arg = -1.0;
0155 }
0156 return arg;
0157 }
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168 template <class Vector1, class Vector2>
0169 inline double Angle( const Vector1 & v1, const Vector2 & v2) {
0170 using std::acos;
0171 return acos( CosTheta(v1, v2) );
0172 }
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 template <class Vector1, class Vector2>
0183 Vector1 ProjVector( const Vector1 & v, const Vector2 & u) {
0184 double magU2 = u.X()*u.X() + u.Y()*u.Y() + u.Z()*u.Z();
0185 if (magU2 == 0) return Vector1(0,0,0);
0186 double d = v.Dot(u)/magU2;
0187 return Vector1( u.X() * d, u.Y() * d, u.Z() * d);
0188 }
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198 template <class Vector1, class Vector2>
0199 inline Vector1 PerpVector( const Vector1 & v, const Vector2 & u) {
0200 return v - ProjVector(v,u);
0201 }
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211 template <class Vector1, class Vector2>
0212 inline double Perp2( const Vector1 & v, const Vector2 & u) {
0213 double magU2 = u.X()*u.X() + u.Y()*u.Y() + u.Z()*u.Z();
0214 double prjvu = v.Dot(u);
0215 double magV2 = v.Dot(v);
0216 return magU2 > 0.0 ? magV2-prjvu*prjvu/magU2 : magV2;
0217 }
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227 template <class Vector1, class Vector2>
0228 inline double Perp( const Vector1 & v, const Vector2 & u) {
0229 using std::sqrt;
0230 return sqrt(Perp2(v,u) );
0231 }
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 template <class Vector1, class Vector2>
0248 inline typename Vector1::Scalar InvariantMass( const Vector1 & v1, const Vector2 & v2) {
0249 typedef typename Vector1::Scalar Scalar;
0250 Scalar ee = (v1.E() + v2.E() );
0251 Scalar xx = (v1.X() + v2.X() );
0252 Scalar yy = (v1.Y() + v2.Y() );
0253 Scalar zz = (v1.Z() + v2.Z() );
0254 Scalar mm2 = ee*ee - xx*xx - yy*yy - zz*zz;
0255 using std::sqrt;
0256 return mm2 < 0.0 ? -sqrt(-mm2) : sqrt(mm2);
0257
0258
0259
0260 }
0261
0262 template <class Vector1, class Vector2>
0263 inline typename Vector1::Scalar InvariantMass2( const Vector1 & v1, const Vector2 & v2) {
0264 typedef typename Vector1::Scalar Scalar;
0265 Scalar ee = (v1.E() + v2.E() );
0266 Scalar xx = (v1.X() + v2.X() );
0267 Scalar yy = (v1.Y() + v2.Y() );
0268 Scalar zz = (v1.Z() + v2.Z() );
0269 Scalar mm2 = ee*ee - xx*xx - yy*yy - zz*zz;
0270 return mm2 ;
0271
0272
0273
0274 }
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285 template <class Vector>
0286 Vector RotateX(const Vector & v, double alpha) {
0287 using std::sin;
0288 double sina = sin(alpha);
0289 using std::cos;
0290 double cosa = cos(alpha);
0291 double y2 = v.Y() * cosa - v.Z()*sina;
0292 double z2 = v.Z() * cosa + v.Y() * sina;
0293 Vector vrot;
0294 vrot.SetXYZ(v.X(), y2, z2);
0295 return vrot;
0296 }
0297
0298
0299
0300
0301
0302
0303
0304 template <class Vector>
0305 Vector RotateY(const Vector & v, double alpha) {
0306 using std::sin;
0307 double sina = sin(alpha);
0308 using std::cos;
0309 double cosa = cos(alpha);
0310 double x2 = v.X() * cosa + v.Z() * sina;
0311 double z2 = v.Z() * cosa - v.X() * sina;
0312 Vector vrot;
0313 vrot.SetXYZ(x2, v.Y(), z2);
0314 return vrot;
0315 }
0316
0317
0318
0319
0320
0321
0322
0323 template <class Vector>
0324 Vector RotateZ(const Vector & v, double alpha) {
0325 using std::sin;
0326 double sina = sin(alpha);
0327 using std::cos;
0328 double cosa = cos(alpha);
0329 double x2 = v.X() * cosa - v.Y() * sina;
0330 double y2 = v.Y() * cosa + v.X() * sina;
0331 Vector vrot;
0332 vrot.SetXYZ(x2, y2, v.Z());
0333 return vrot;
0334 }
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344 template<class Vector, class RotationMatrix>
0345 Vector Rotate(const Vector &v, const RotationMatrix & rot) {
0346 double xX = v.X();
0347 double yY = v.Y();
0348 double zZ = v.Z();
0349 double x2 = rot(0,0)*xX + rot(0,1)*yY + rot(0,2)*zZ;
0350 double y2 = rot(1,0)*xX + rot(1,1)*yY + rot(1,2)*zZ;
0351 double z2 = rot(2,0)*xX + rot(2,1)*yY + rot(2,2)*zZ;
0352 Vector vrot;
0353 vrot.SetXYZ(x2,y2,z2);
0354 return vrot;
0355 }
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365 template <class LVector, class BoostVector>
0366 LVector boost(const LVector & v, const BoostVector & b) {
0367 double bx = b.X();
0368 double by = b.Y();
0369 double bz = b.Z();
0370 double b2 = bx*bx + by*by + bz*bz;
0371 if (b2 >= 1) {
0372 GenVector::Throw ( "Beta Vector supplied to set Boost represents speed >= c");
0373 return LVector();
0374 }
0375 using std::sqrt;
0376 double gamma = 1.0 / sqrt(1.0 - b2);
0377 double bp = bx*v.X() + by*v.Y() + bz*v.Z();
0378 double gamma2 = b2 > 0 ? (gamma - 1.0)/b2 : 0.0;
0379 double x2 = v.X() + gamma2*bp*bx + gamma*bx*v.T();
0380 double y2 = v.Y() + gamma2*bp*by + gamma*by*v.T();
0381 double z2 = v.Z() + gamma2*bp*bz + gamma*bz*v.T();
0382 double t2 = gamma*(v.T() + bp);
0383 LVector lv;
0384 lv.SetXYZT(x2,y2,z2,t2);
0385 return lv;
0386 }
0387
0388
0389
0390
0391
0392
0393
0394
0395 template <class LVector, class T>
0396 LVector boostX(const LVector & v, T beta) {
0397 if (beta >= 1) {
0398 GenVector::Throw ("Beta Vector supplied to set Boost represents speed >= c");
0399 return LVector();
0400 }
0401 using std::sqrt;
0402 T gamma = 1.0/ sqrt(1.0 - beta*beta);
0403 typename LVector::Scalar x2 = gamma * v.X() + gamma * beta * v.T();
0404 typename LVector::Scalar t2 = gamma * beta * v.X() + gamma * v.T();
0405
0406 LVector lv;
0407 lv.SetXYZT(x2,v.Y(),v.Z(),t2);
0408 return lv;
0409 }
0410
0411
0412
0413
0414
0415
0416
0417 template <class LVector>
0418 LVector boostY(const LVector & v, double beta) {
0419 if (beta >= 1) {
0420 GenVector::Throw ("Beta Vector supplied to set Boost represents speed >= c");
0421 return LVector();
0422 }
0423 using std::sqrt;
0424 double gamma = 1.0/ sqrt(1.0 - beta*beta);
0425 double y2 = gamma * v.Y() + gamma * beta * v.T();
0426 double t2 = gamma * beta * v.Y() + gamma * v.T();
0427 LVector lv;
0428 lv.SetXYZT(v.X(),y2,v.Z(),t2);
0429 return lv;
0430 }
0431
0432
0433
0434
0435
0436
0437
0438 template <class LVector>
0439 LVector boostZ(const LVector & v, double beta) {
0440 if (beta >= 1) {
0441 GenVector::Throw ( "Beta Vector supplied to set Boost represents speed >= c");
0442 return LVector();
0443 }
0444 using std::sqrt;
0445 double gamma = 1.0/ sqrt(1.0 - beta*beta);
0446 double z2 = gamma * v.Z() + gamma * beta * v.T();
0447 double t2 = gamma * beta * v.Z() + gamma * v.T();
0448 LVector lv;
0449 lv.SetXYZT(v.X(),v.Y(),z2,t2);
0450 return lv;
0451 }
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461 template<class Matrix, class CoordSystem, class U>
0462 inline
0463 DisplacementVector3D<CoordSystem,U> Mult (const Matrix & m, const DisplacementVector3D<CoordSystem,U> & v) {
0464 DisplacementVector3D<CoordSystem,U> vret;
0465 vret.SetXYZ( m(0,0) * v.x() + m(0,1) * v.y() + m(0,2) * v.z() ,
0466 m(1,0) * v.x() + m(1,1) * v.y() + m(1,2) * v.z() ,
0467 m(2,0) * v.x() + m(2,1) * v.y() + m(2,2) * v.z() );
0468 return vret;
0469 }
0470
0471
0472
0473
0474
0475
0476 template<class Matrix, class CoordSystem, class U>
0477 inline
0478 PositionVector3D<CoordSystem,U> Mult (const Matrix & m, const PositionVector3D<CoordSystem,U> & p) {
0479 DisplacementVector3D<CoordSystem,U> pret;
0480 pret.SetXYZ( m(0,0) * p.x() + m(0,1) * p.y() + m(0,2) * p.z() ,
0481 m(1,0) * p.x() + m(1,1) * p.y() + m(1,2) * p.z() ,
0482 m(2,0) * p.x() + m(2,1) * p.y() + m(2,2) * p.z() );
0483 return pret;
0484 }
0485
0486
0487
0488
0489
0490
0491
0492
0493 template<class CoordSystem, class Matrix>
0494 inline
0495 LorentzVector<CoordSystem> Mult (const Matrix & m, const LorentzVector<CoordSystem> & v) {
0496 LorentzVector<CoordSystem> vret;
0497 vret.SetXYZT( m(0,0)*v.x() + m(0,1)*v.y() + m(0,2)*v.z() + m(0,3)* v.t() ,
0498 m(1,0)*v.x() + m(1,1)*v.y() + m(1,2)*v.z() + m(1,3)* v.t() ,
0499 m(2,0)*v.x() + m(2,1)*v.y() + m(2,2)*v.z() + m(2,3)* v.t() ,
0500 m(3,0)*v.x() + m(3,1)*v.y() + m(3,2)*v.z() + m(3,3)* v.t() );
0501 return vret;
0502 }
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512 double Phi_0_2pi(double phi);
0513
0514
0515
0516 double Phi_mpi_pi(double phi);
0517
0518
0519
0520 }
0521
0522
0523
0524 }
0525
0526 }
0527
0528
0529 #endif