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
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
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
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
00090 return Measurement1D(totalP4.M(), u );
00091
00092 }
00093
00094
00095
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();
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();
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();
00135
00136 jac(1,i_int*3+3) = ( totalP4.X()*sin(phi) - totalP4.Y()*cos(phi) )*a/(rho*totalP4.M());
00137
00138
00139 cov.sub(i_int*3 + 1, i_int*3 + 1,asHepMatrix<6>((**rt_i).fullCovariance()).sub(4,6));
00140
00141
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
00155
00156
00157
00158 return sqrt((jac*cov*jac.T())(1,1));
00159 }