CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/RecoVertex/VertexTools/src/InvariantMassFromVertex.cc

Go to the documentation of this file.
00001 #include "RecoVertex/VertexTools/interface/InvariantMassFromVertex.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 
00004 
00005 InvariantMassFromVertex::LorentzVector InvariantMassFromVertex::p4 (const CachingVertex<5>& vertex,
00006                           const double mass) const
00007 {
00008   return p4(vertex, std::vector<double>(vertex.tracks().size(), mass));
00009 }
00010 
00011 InvariantMassFromVertex::LorentzVector InvariantMassFromVertex::p4 (const CachingVertex<5>& vertex,
00012                           const std::vector<double> & masses) const
00013 {
00014 
00015   LorentzVector totalP4;
00016 
00017   // Check that tkToTkCovarianceIsAvailable
00018   if (!vertex.tkToTkCovarianceIsAvailable()) {
00019     LogDebug("InvariantMassFromVertex")
00020         << "Fit failed: vertex has not been smoothed\n";
00021     return totalP4;
00022   }
00023 
00024   if (vertex.tracks().size() != masses.size()) {
00025     LogDebug("InvariantMassFromVertex")
00026         << "Vector of masses does not have the same size as tracks in vertex\n";
00027     return totalP4;
00028   }
00029 
00030 
00031   std::vector<RefCountedVertexTrack> refTracks = vertex.tracks();
00032   std::vector<RefCountedVertexTrack>::const_iterator i_s = refTracks.begin();
00033   std::vector<double>::const_iterator i_m = masses.begin();
00034 
00035   for( ;i_s !=refTracks.end(), i_m != masses.end(); ++i_s, ++i_m) {
00036     GlobalVector momentum = (**i_s).refittedState()->freeTrajectoryState().momentum();
00037     totalP4 += LorentzVector(momentum.x(), momentum.y(), momentum.z(), *i_m);
00038   } 
00039   return totalP4;
00040 }
00041 
00042 GlobalVector InvariantMassFromVertex::momentum(const CachingVertex<5>& vertex) const
00043 {
00044  GlobalVector momentum_;
00045 
00046   // Check that tkToTkCovarianceIsAvailable
00047   if (!vertex.tkToTkCovarianceIsAvailable()) {
00048     LogDebug("InvariantMassFromVertex")
00049         << "Fit failed: vertex has not been smoothed\n";
00050    return momentum_;
00051   }
00052 
00053   std::vector<RefCountedVertexTrack> refTracks = vertex.tracks();
00054   std::vector<RefCountedVertexTrack>::const_iterator i_s = refTracks.begin();
00055 
00056   for( ;i_s !=refTracks.end() ; ++i_s) {
00057     momentum_ += (**i_s).refittedState()->freeTrajectoryState().momentum();
00058   } 
00059   return momentum_;
00060 
00061 }
00062 
00063 
00064 Measurement1D InvariantMassFromVertex::invariantMass(const CachingVertex<5>& vertex,
00065                           const double mass) const
00066 {
00067   return invariantMass(vertex, std::vector<double>(vertex.tracks().size(), mass));
00068 }
00069 
00070 
00071 Measurement1D InvariantMassFromVertex::invariantMass(const CachingVertex<5>& vertex,
00072                           const std::vector<double> & masses) const
00073 {
00074 
00075   // Check that tkToTkCovarianceIsAvailable
00076   if (!vertex.tkToTkCovarianceIsAvailable()) {
00077     LogDebug("InvariantMassFromVertex")
00078         << "Fit failed: vertex has not been smoothed\n";
00079     return Measurement1D(0.,0.);
00080   }
00081   if (vertex.tracks().size() != masses.size()) {
00082     LogDebug("InvariantMassFromVertex")
00083         << "Vector of masses does not have the same size as tracks in vertex\n";
00084     return Measurement1D(0.,0.);
00085   }
00086 
00087   LorentzVector totalP4 = p4(vertex, masses);
00088   double u = uncertainty(totalP4, vertex, masses);
00089   // std::cout << u<<std::endl;
00090   return Measurement1D(totalP4.M(), u );
00091 
00092 }
00093 
00094 //method returning the full covariance matrix
00095 //of new born kinematic particle
00096 double InvariantMassFromVertex::uncertainty(const LorentzVector & totalP4, 
00097         const CachingVertex<5>& vertex, const std::vector<double> & masses) const
00098 {
00099   std::vector<RefCountedVertexTrack> refTracks = vertex.tracks();
00100   int size = refTracks.size();
00101   AlgebraicMatrix cov(3*size,3*size);
00102   AlgebraicMatrix jac(1,3*size);
00103 
00104   double energy_total = totalP4.E();
00105 
00106   std::vector<RefCountedVertexTrack>::const_iterator rt_i = refTracks.begin();
00107   std::vector<double>::const_iterator i_m = masses.begin();
00108 
00109   int i_int = 0;
00110   for( ;rt_i !=refTracks.end(), i_m != masses.end(); ++rt_i, ++i_m) {
00111 
00112     double a;
00113     AlgebraicVector5 param = (**rt_i).refittedState()->parameters(); // rho, theta, phi,tr_im, z_im
00114     double rho = param[0];
00115     double theta = param[1];
00116     double phi = param[2];
00117     double mass = *i_m;
00118 
00119     if ((**rt_i).linearizedTrack()->charge()!=0) {
00120       a = -(**rt_i).refittedState()->freeTrajectoryState().parameters().magneticFieldInInverseGeV(vertex.position()).z()
00121                 * (**rt_i).refittedState()->freeTrajectoryState().parameters ().charge();
00122       if (a==0.) throw cms::Exception("InvariantMassFromVertex", "Field is 0");
00123     } else {
00124       a = 1;
00125     }
00126 
00127     double energy_local  = sqrt(a*a/(rho*rho)*(1+1/(tan(theta)*tan(theta)))  + mass*mass);
00128 
00129     jac(1,i_int*3+1) = (-(energy_total/energy_local*a*a/(rho*rho*rho*sin(theta)*sin(theta)) )
00130                   + totalP4.X()*a/(rho*rho)*cos(phi) + totalP4.Y()*a/(rho*rho)*sin(phi)
00131                   + totalP4.Z()*a/(rho*rho*tan(theta)) )/totalP4.M();   //dm / drho
00132 
00133     jac(1,i_int*3+2) = (-(energy_total/energy_local*a*a/(rho*rho*sin(theta)*sin(theta)*tan(theta)) )
00134                   + totalP4.Z()*a/(rho*sin(theta)*sin(theta)) )/totalP4.M();//dm d theta
00135 
00136     jac(1,i_int*3+3) = ( totalP4.X()*sin(phi) - totalP4.Y()*cos(phi) )*a/(rho*totalP4.M());     //dm/dphi
00137 
00138     // momentum corellatons: diagonal elements of the matrix
00139     cov.sub(i_int*3 + 1, i_int*3 + 1,asHepMatrix<6>((**rt_i).fullCovariance()).sub(4,6));
00140 
00141     //off diagonal elements: track momentum - track momentum corellations
00142 
00143     int j_int = 0;
00144     for(std::vector<RefCountedVertexTrack>::const_iterator rt_j = refTracks.begin(); rt_j != refTracks.end(); rt_j++) {
00145       if(i_int < j_int) {
00146         AlgebraicMatrix i_k_cov_m = asHepMatrix<3,3>(vertex.tkToTkCovariance((*rt_i),(*rt_j)));
00147         cov.sub(i_int*3 + 1, j_int*3 + 1,i_k_cov_m);
00148         cov.sub(j_int*3 + 1, i_int*3 + 1,i_k_cov_m.T());
00149       }
00150       j_int++;
00151     }
00152     i_int++;
00153   }
00154 //   std::cout<<"jac"<<jac<<std::endl;
00155 //   std::cout<<"cov"<<cov<<std::endl;
00156 //   std::cout << "final result"<<(jac*cov*jac.T())<<std::endl;
00157 
00158   return sqrt((jac*cov*jac.T())(1,1));
00159 }