00001 #include "FastSimulation/ParamL3MuonProducer/interface/FML3PtSmearer.h" 00002 00003 #include <cmath> 00004 00005 #include "FastSimulation/Utilities/interface/RandomEngine.h" 00006 00007 // 00008 // Static data member definition 00009 // 00010 double FML3PtSmearer::MuonMassSquared_ = 0.10565837*0.10565837; 00011 00012 00013 FML3PtSmearer::FML3PtSmearer(const RandomEngine * engine) 00014 : random(engine) 00015 { } 00016 00017 FML3PtSmearer::~FML3PtSmearer(){} 00018 00019 math::XYZTLorentzVector FML3PtSmearer::smear(math::XYZTLorentzVector simP4 , math::XYZVector recP3) const { 00020 double ptSim = std::sqrt(simP4.perp2()); 00021 double invPtSim; 00022 if (ptSim>0.) invPtSim = 1./ptSim; 00023 else { 00024 // Better if we throw an exception here... 00025 simP4.SetPx(recP3.X()); 00026 simP4.SetPy(recP3.Y()); 00027 simP4.SetPz(recP3.Z()); 00028 double muonEnergy=std::sqrt(simP4.P()*simP4.P()+MuonMassSquared_); 00029 simP4.SetE(muonEnergy); 00030 return simP4; 00031 } 00032 double etaSim = simP4.eta(); 00033 double invPtNew = random->gaussShoot(invPtSim,error(ptSim,etaSim)); 00034 invPtNew /= ( 1. + shift(ptSim,etaSim)*invPtNew); 00035 if (invPtNew>0.) { 00036 double invPtRec = std::sqrt(recP3.perp2()); 00037 if (invPtRec>0) invPtRec = 1./invPtRec; else invPtRec=invPtSim; 00038 simP4.SetPx(recP3.x()*invPtRec/invPtNew); 00039 simP4.SetPy(recP3.y()*invPtRec/invPtNew); 00040 simP4.SetPz(recP3.z()*invPtRec/invPtNew); 00041 double muonEnergy=std::sqrt(simP4.P()*simP4.P()+MuonMassSquared_); 00042 simP4.SetE(muonEnergy); 00043 } 00044 else { 00045 simP4.SetPx(recP3.x()); 00046 simP4.SetPy(recP3.y()); 00047 simP4.SetPz(recP3.z()); 00048 double muonEnergy=std::sqrt(simP4.P()*simP4.P()+MuonMassSquared_); 00049 simP4.SetE(muonEnergy); 00050 } 00051 return simP4; 00052 } 00053 00054 double FML3PtSmearer::error(double thePt, double theEta) const { 00055 return funSigma(fabs(theEta),thePt)/thePt; 00056 } 00057 00058 double FML3PtSmearer::shift(double thePt, double theEta) const { 00059 return funShift(fabs(theEta)); 00060 } 00061 00062 double FML3PtSmearer::funShift(double x) const { 00063 if (x<1.305) return 7.90897e-04; 00064 else if (x<1.82 ) return 9.52662e-02-1.12262e-01*x+3.05410e-02*x*x; 00065 else return -7.9e-03; 00066 } 00067 00068 double FML3PtSmearer::funSigma(double eta , double pt) const { 00069 double sigma = funSigmaPt(pt) * funSigmaEta(eta); 00070 return sigma; 00071 } 00072 00073 double FML3PtSmearer::funSigmaPt(double x) const { 00074 if (x<444.) return 3.13349e-01+2.77853e-03*x+4.94289e-06*x*x-9.63359e-09*x*x*x; 00075 else return 9.26294e-01+1.64896e-03*x; 00076 } 00077 00078 double FML3PtSmearer::funSigmaEta(double x) const { 00079 if (x<0.94) return 2.27603e-02+1.23995e-06*exp(9.30755*x); 00080 else return 2.99467e-02+1.86770e-05*exp(3.52319*x); 00081 }