00001 00002 #include "Alignment/TwoBodyDecay/interface/TwoBodyDecayLinearizationPointFinder.h" 00003 #include "DataFormats/CLHEP/interface/AlgebraicObjects.h" 00004 #include "Alignment/TwoBodyDecay/interface/TwoBodyDecayModel.h" 00005 00006 const TwoBodyDecayParameters 00007 TwoBodyDecayLinearizationPointFinder::getLinearizationPoint( const std::vector< RefCountedLinearizedTrackState > & tracks, 00008 const double primaryMass, 00009 const double secondaryMass ) const 00010 { 00011 GlobalPoint linPoint = tracks[0]->linearizationPoint(); 00012 PerigeeLinearizedTrackState* linTrack1 = dynamic_cast<PerigeeLinearizedTrackState*>( tracks[0].get() ); 00013 GlobalVector firstMomentum = linTrack1->predictedState().momentum(); 00014 PerigeeLinearizedTrackState* linTrack2 = dynamic_cast<PerigeeLinearizedTrackState*>( tracks[1].get() ); 00015 GlobalVector secondMomentum = linTrack2->predictedState().momentum(); 00016 00017 AlgebraicVector secondaryMomentum1( 3 ); 00018 secondaryMomentum1[0] = firstMomentum.x(); 00019 secondaryMomentum1[1] = firstMomentum.y(); 00020 secondaryMomentum1[2] = firstMomentum.z(); 00021 00022 AlgebraicVector secondaryMomentum2( 3 ); 00023 secondaryMomentum2[0] = secondMomentum.x(); 00024 secondaryMomentum2[1] = secondMomentum.y(); 00025 secondaryMomentum2[2] = secondMomentum.z(); 00026 00027 AlgebraicVector primaryMomentum = secondaryMomentum1 + secondaryMomentum2; 00028 00029 TwoBodyDecayModel decayModel( primaryMass, secondaryMass ); 00030 AlgebraicMatrix rotMat = decayModel.rotationMatrix( primaryMomentum[0], primaryMomentum[1], primaryMomentum[2] ); 00031 AlgebraicMatrix invRotMat = rotMat.T(); 00032 00033 double p = primaryMomentum.norm(); 00034 double pSquared = p*p; 00035 double gamma = sqrt( pSquared + primaryMass*primaryMass )/primaryMass; 00036 double betaGamma = p/primaryMass; 00037 AlgebraicSymMatrix lorentzTransformation( 4, 1 ); 00038 lorentzTransformation[0][0] = gamma; 00039 lorentzTransformation[3][3] = gamma; 00040 lorentzTransformation[0][3] = -betaGamma; 00041 00042 double p1 = secondaryMomentum1.norm(); 00043 AlgebraicVector boostedLorentzMomentum1( 4 ); 00044 boostedLorentzMomentum1[0] = sqrt( p1*p1 + secondaryMass*secondaryMass ); 00045 boostedLorentzMomentum1.sub( 2, invRotMat*secondaryMomentum1 ); 00046 00047 AlgebraicVector restFrameLorentzMomentum1 = lorentzTransformation*boostedLorentzMomentum1; 00048 AlgebraicVector restFrameMomentum1 = restFrameLorentzMomentum1.sub( 2, 4 ); 00049 double perp1 = sqrt( restFrameMomentum1[0]*restFrameMomentum1[0] + restFrameMomentum1[1]*restFrameMomentum1[1] ); 00050 double theta1 = atan2( perp1, restFrameMomentum1[2] ); 00051 double phi1 = atan2( restFrameMomentum1[1], restFrameMomentum1[0] ); 00052 00053 double p2 = secondaryMomentum2.norm(); 00054 AlgebraicVector boostedLorentzMomentum2( 4 ); 00055 boostedLorentzMomentum2[0] = sqrt( p2*p2 + secondaryMass*secondaryMass ); 00056 boostedLorentzMomentum2.sub( 2, invRotMat*secondaryMomentum2 ); 00057 00058 AlgebraicVector restFrameLorentzMomentum2 = lorentzTransformation*boostedLorentzMomentum2; 00059 AlgebraicVector restFrameMomentum2 = restFrameLorentzMomentum2.sub( 2, 4 ); 00060 double perp2 = sqrt( restFrameMomentum2[0]*restFrameMomentum2[0] + restFrameMomentum2[1]*restFrameMomentum2[1] ); 00061 double theta2 = atan2( perp2, restFrameMomentum2[2] ); 00062 double phi2 = atan2( restFrameMomentum2[1], restFrameMomentum2[0] ); 00063 00064 double pi = 3.141592654; 00065 double relSign = -1.; 00066 00067 if ( phi1 < 0 ) phi1 += 2*pi; 00068 if ( phi2 < 0 ) phi2 += 2*pi; 00069 if ( phi1 > phi2 ) relSign = 1.; 00070 00071 double momentumSquared1 = secondaryMomentum1.normsq(); 00072 double energy1 = sqrt( secondaryMass*secondaryMass + momentumSquared1 ); 00073 double momentumSquared2 = secondaryMomentum2.normsq(); 00074 double energy2 = sqrt( secondaryMass*secondaryMass + momentumSquared2 ); 00075 double sumMomentaSquared = ( secondaryMomentum1 + secondaryMomentum2 ).normsq(); 00076 double sumEnergiesSquared = ( energy1 + energy2 )*( energy1 + energy2 ); 00077 double estimatedPrimaryMass = sqrt( sumEnergiesSquared - sumMomentaSquared ); 00078 00079 AlgebraicVector linParam( TwoBodyDecayParameters::dimension, 0 ); 00080 linParam[TwoBodyDecayParameters::x] = linPoint.x(); 00081 linParam[TwoBodyDecayParameters::y] = linPoint.y(); 00082 linParam[TwoBodyDecayParameters::z] = linPoint.z(); 00083 linParam[TwoBodyDecayParameters::px] = primaryMomentum[0]; 00084 linParam[TwoBodyDecayParameters::py] = primaryMomentum[1]; 00085 linParam[TwoBodyDecayParameters::pz] = primaryMomentum[2]; 00086 linParam[TwoBodyDecayParameters::theta] = 0.5*( theta1 - theta2 + pi ) ; 00087 linParam[TwoBodyDecayParameters::phi] = 0.5*( phi1 + phi2 + relSign*pi ); 00088 linParam[TwoBodyDecayParameters::mass] = estimatedPrimaryMass; 00089 00090 return TwoBodyDecayParameters( linParam ); 00091 }