CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/TopQuarkAnalysis/TopTools/src/MEzCalculator.cc

Go to the documentation of this file.
00001 #include "TopQuarkAnalysis/TopTools/interface/MEzCalculator.h"
00002 #include "TMath.h"
00003 
00005 MEzCalculator::MEzCalculator() 
00006 {
00007   isComplex_ = false;
00008   isMuon_ = true;
00009 }
00010 
00012 MEzCalculator::~MEzCalculator() 
00013 {
00014 }
00015 
00017 double
00018 MEzCalculator::Calculate(int type) 
00019 {
00020   if(type<0 || type>3)
00021     throw cms::Exception("UnimplementedFeature") << "Type " << type << " not supported in MEzCalculator.\n";
00022 
00023   double M_W  = 80.4;
00024   double M_mu =  0.10566;
00025   double M_e = 0.511e-3;
00026   double M_lepton = M_mu;
00027   if (! isMuon_ ) M_lepton = M_e;
00028   
00029   double emu = lepton_.energy();
00030   double pxmu = lepton_.px();
00031   double pymu = lepton_.py();
00032   double pzmu = lepton_.pz();
00033   double pxnu = MET_.px();
00034   double pynu = MET_.py();
00035   double pznu = 0.;
00036 
00037   // use pznu = - B/2*A +/- sqrt(B*B-4*A*C)/(2*A)
00038   
00039   double a = M_W*M_W - M_lepton*M_lepton + 2.0*(pxmu*pxnu + pymu*pynu);
00040   double A = 4.0*(emu*emu - pzmu*pzmu);
00041   double B = -4.0*a*pzmu;
00042   double C = 4.0*emu*emu*(pxnu*pxnu + pynu*pynu) - a*a;
00043   
00044   double tmproot = B*B - 4.0*A*C;
00045   
00046   if (tmproot<0) {
00047     isComplex_= true;
00048     pznu = - B/(2*A); // take real part of complex roots
00049   }
00050   else {
00051     isComplex_ = false;
00052     double tmpsol1 = (-B + TMath::Sqrt(tmproot))/(2.0*A);
00053     double tmpsol2 = (-B - TMath::Sqrt(tmproot))/(2.0*A);
00054     
00055     if (type == 0 ) {
00056       // two real roots, pick the one closest to pz of muon
00057       if (TMath::Abs(tmpsol2-pzmu) < TMath::Abs(tmpsol1-pzmu)) { pznu = tmpsol2;}
00058       else pznu = tmpsol1;
00059       // if pznu is > 300 pick the most central root
00060       if ( pznu > 300. ) {
00061         if (TMath::Abs(tmpsol1)<TMath::Abs(tmpsol2) ) pznu = tmpsol1;
00062         else pznu = tmpsol2;
00063       }
00064     }
00065     if (type == 1 ) {
00066       // two real roots, pick the one closest to pz of muon
00067       if (TMath::Abs(tmpsol2-pzmu) < TMath::Abs(tmpsol1-pzmu)) { pznu = tmpsol2;}
00068       else pznu = tmpsol1;
00069     }
00070     if (type == 2 ) {
00071       // pick the most central root.
00072       if (TMath::Abs(tmpsol1)<TMath::Abs(tmpsol2) ) pznu = tmpsol1;
00073       else pznu = tmpsol2;
00074     }
00075     if (type == 3 ) {
00076       // pick the largest value of the cosine
00077       TVector3 p3w, p3mu;
00078       p3w.SetXYZ(pxmu+pxnu, pymu+pynu, pzmu+ tmpsol1);
00079       p3mu.SetXYZ(pxmu, pymu, pzmu );
00080       
00081       double sinthcm1 = 2.*(p3mu.Perp(p3w))/M_W;
00082       p3w.SetXYZ(pxmu+pxnu, pymu+pynu, pzmu+ tmpsol2);
00083       double sinthcm2 = 2.*(p3mu.Perp(p3w))/M_W;
00084       
00085       double costhcm1 = TMath::Sqrt(1. - sinthcm1*sinthcm1);
00086       double costhcm2 = TMath::Sqrt(1. - sinthcm2*sinthcm2);
00087       
00088       if ( costhcm1 > costhcm2 ) pznu = tmpsol1;
00089       else pznu = tmpsol2;
00090     }   
00091 
00092   }
00093   
00094   //Particle neutrino;
00095   //neutrino.setP4( LorentzVector(pxnu, pynu, pznu, TMath::Sqrt(pxnu*pxnu + pynu*pynu + pznu*pznu ))) ;
00096   
00097   return pznu;
00098 }