CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoMET/METAlgorithms/src/SignAlgoResolutions.cc

Go to the documentation of this file.
00001 #include "RecoMET/METAlgorithms/interface/SignAlgoResolutions.h"
00002 // -*- C++ -*-
00003 //
00004 // Package:    METAlgorithms
00005 // Class:      SignAlgoResolutions
00006 // 
00014 //
00015 // Original Author:  Kyle Story, Freya Blekman (Cornell University)
00016 //         Created:  Fri Apr 18 11:58:33 CEST 2008
00017 // $Id: SignAlgoResolutions.cc,v 1.11 2013/05/06 17:56:45 sakuma Exp $
00018 //
00019 //
00020 #include "FWCore/Framework/interface/EventSetup.h"
00021 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00022 #include "DataFormats/TrackReco/interface/Track.h"
00023 #include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
00024 #include "DataFormats/ParticleFlowReco/interface/PFBlockElement.h"
00025 
00026 
00027 #include <math.h>
00028 
00029 #include <cstdlib>
00030 #include <iostream>
00031 #include <sstream>
00032 #include <string>
00033 #include <sys/stat.h>
00034 
00035 metsig::SignAlgoResolutions::SignAlgoResolutions(const edm::ParameterSet &iConfig):
00036     functionmap_(),
00037     ptResol_(0),
00038     phiResol_(0)
00039 {
00040   addResolutions(iConfig);
00041 }
00042 
00043 
00044 
00045 double metsig::SignAlgoResolutions::eval(const resolutionType & type, const resolutionFunc & func, const double & et, const double & phi, const double & eta) const {
00046   // derive p from et and eta;
00047   double theta = 2*atan(exp(-eta));
00048   double p = et / sin(theta); // rough assumption: take e and p equivalent...
00049   return eval(type,func,et,phi,eta,p);
00050 
00051 }
00052 
00053 double metsig::SignAlgoResolutions::eval(const resolutionType & type, const resolutionFunc & func, const double & et, const double & phi, const double & eta, const double &p) const {
00054 
00055   functionPars x(4);
00056   x[0]=et;
00057   x[1]=phi;
00058   x[2]=eta;
00059   x[3]=p;
00060   //  std::cout << "getting function of type " << type << " " << func << " " << x[0] << " " << x[1] << " " << x[2] << " " << x[3] << std::endl;
00061   return getfunc(type,func,x);
00062 
00063 }
00064 
00065 metsig::SigInputObj  metsig::SignAlgoResolutions::evalPF(const reco::PFCandidate *candidate) const {
00066   double eta = candidate->eta();
00067   double phi = candidate->phi();
00068   double et = candidate->energy()*sin(candidate->theta());
00069   resolutionType thetype;
00070   std::string name;
00071   int type = candidate->particleId();
00072   switch (type) 
00073     {
00074     case 1: 
00075       thetype=PFtype1;name="PFChargedHadron"; break;
00076     case 2: 
00077       thetype=PFtype2;name="PFChargedEM"; break;
00078     case 3: 
00079       thetype=PFtype3;name="PFMuon"; break;
00080     case 4: 
00081       thetype=PFtype4;name="PFNeutralEM"; break;
00082     case 5: 
00083       thetype=PFtype5;name="PFNeutralHadron"; break;
00084     case 6: 
00085       thetype=PFtype6;name="PFtype6"; break;
00086     case 7:
00087       thetype=PFtype7;name="PFtype7"; break;
00088     default:
00089       thetype=PFtype7;name="PFunknown"; break;
00090   }
00091 
00092   double d_et=0, d_phi=0; //d_phi here is the error on phi component of the et
00093   reco::TrackRef trackRef = candidate->trackRef();
00094   if(!trackRef.isNull()){
00095     d_phi = et*trackRef->phiError();
00096     d_et  = (type==2) ?  ElectronPtResolution(candidate) : trackRef->ptError();
00097     //if(type==2) std::cout << eval(thetype,ET,et,phi,eta) << "    " << trackRef->ptError() << "    "<< ElectronPtResolution(candidate) << std::endl;
00098   }
00099   else{
00100     d_et = eval(thetype,ET,et,phi,eta);
00101     d_phi = eval(thetype,PHI,et,phi,eta);
00102   }
00103 
00104   metsig::SigInputObj resultingobj(name,et,phi,d_et,d_phi);
00105   return resultingobj;
00106 }
00107 
00108 
00109 metsig::SigInputObj
00110 metsig::SignAlgoResolutions::evalPFJet(const reco::PFJet *jet) const{
00111 
00112     double jpt  = jet->pt();
00113     double jphi = jet->phi();
00114     double jeta = jet->eta();
00115     double jdeltapt = 999.;
00116     double jdeltapphi = 999.;
00117 
00118     if(jpt<ptResolThreshold_ && jpt<20.){ //use temporary fix for low pT jets
00119         double feta = TMath::Abs(jeta);
00120         int ieta = feta<5.? int(feta/0.5) : 9; //bin size = 0.5 
00121         int ipt  = jpt>3. ? int(jpt-3./2) : 0; //bin size =2, starting from ptmin=3GeV
00122         jdeltapt   = jdpt[ieta][ipt];
00123         jdeltapphi = jpt*jdphi[ieta][ipt];
00124     }
00125     else{
00126         //use the resolution functions at |eta|=5 to avoid crash for jets with large eta.
00127         if(jeta>5) jeta=5;
00128         if(jeta<-5) jeta=-5;
00129         double jptForEval = jpt>ptResolThreshold_ ? jpt : ptResolThreshold_;
00130         jdeltapt   = jpt*ptResol_->parameterEtaEval("sigma",jeta,jptForEval);
00131         jdeltapphi = jpt*phiResol_->parameterEtaEval("sigma",jeta,jptForEval);
00132     }
00133 
00134     std::string inputtype = "jet";
00135     metsig::SigInputObj obj_jet(inputtype,jpt,jphi,jdeltapt,jdeltapphi);
00136     //std::cout << "RESOLUTIONS JET: " << jpt << "   " << jphi<< "   " <<jdeltapt << "   " << jdeltapphi << std::endl;
00137     return obj_jet;
00138 }
00139 
00140 
00141 void metsig::SignAlgoResolutions::addResolutions(const edm::ParameterSet &iConfig){
00142     using namespace std;
00143 
00144   // Jet Resolutions - for now load from the files. Migrate to EventSetup asap.
00145   metsig::SignAlgoResolutions::initializeJetResolutions( iConfig );
00146   
00147   ptResolThreshold_ = iConfig.getParameter<double>("ptresolthreshold");
00148 
00149 
00150     //get temporary low pT pfjet resolutions
00151     for (int ieta=0; ieta<10; ieta++){
00152       jdpt[ieta] = iConfig.getParameter<std::vector<double> >(Form("jdpt%d", ieta));
00153       jdphi[ieta] = iConfig.getParameter<std::vector<double> >(Form("jdphi%d", ieta));
00154     }
00155 
00156 
00157   // for now: do this by hand - this can obviously also be done via ESSource etc.
00158   functionPars etparameters(3,0);
00159   functionPars phiparameters(1,0);
00160   // set the parameters per function:
00161   // ECAL, BARREL:
00162   std::vector<double> ebet = iConfig.getParameter<std::vector<double> >("EB_EtResPar");
00163   std::vector<double> ebphi = iConfig.getParameter<std::vector<double> >("EB_PhiResPar");
00164 
00165   etparameters[0]=ebet[0];
00166   etparameters[1]=ebet[1];
00167   etparameters[2]=ebet[2];
00168   phiparameters[0]=ebphi[0];
00169   addfunction(caloEB,ET,etparameters);
00170   addfunction(caloEB,PHI,phiparameters);
00171  // ECAL, ENDCAP:
00172   std::vector<double> eeet = iConfig.getParameter<std::vector<double> >("EE_EtResPar");
00173   std::vector<double> eephi = iConfig.getParameter<std::vector<double> >("EE_PhiResPar");
00174 
00175   etparameters[0]=eeet[0];
00176   etparameters[1]=eeet[1];
00177   etparameters[2]=eeet[2];
00178   phiparameters[0]=eephi[0];
00179   addfunction(caloEE,ET,etparameters);
00180   addfunction(caloEE,PHI,phiparameters);
00181  // HCAL, BARREL:
00182   std::vector<double> hbet = iConfig.getParameter<std::vector<double> >("HB_EtResPar");
00183   std::vector<double> hbphi = iConfig.getParameter<std::vector<double> >("HB_PhiResPar");
00184 
00185   etparameters[0]=hbet[0];
00186   etparameters[1]=hbet[1];
00187   etparameters[2]=hbet[2];
00188   phiparameters[0]=hbphi[0];
00189   addfunction(caloHB,ET,etparameters);
00190   addfunction(caloHB,PHI,phiparameters);
00191  // HCAL, ENDCAP:
00192   std::vector<double> heet = iConfig.getParameter<std::vector<double> >("HE_EtResPar");
00193   std::vector<double> hephi = iConfig.getParameter<std::vector<double> >("HE_PhiResPar");
00194 
00195   etparameters[0]=heet[0];
00196   etparameters[1]=heet[1];
00197   etparameters[2]=heet[2];
00198   phiparameters[0]=hephi[0];
00199   addfunction(caloHE,ET,etparameters);
00200   addfunction(caloHE,PHI,phiparameters);
00201  // HCAL, Outer
00202   std::vector<double> hoet = iConfig.getParameter<std::vector<double> >("HO_EtResPar");
00203   std::vector<double> hophi = iConfig.getParameter<std::vector<double> >("HO_PhiResPar");
00204 
00205 
00206   etparameters[0]=hoet[0];
00207   etparameters[1]=hoet[1];
00208   etparameters[2]=hoet[2];
00209   phiparameters[0]=hophi[0];
00210   addfunction(caloHO,ET,etparameters);
00211   addfunction(caloHO,PHI,phiparameters);
00212  // HCAL, Forward
00213   std::vector<double> hfet = iConfig.getParameter<std::vector<double> >("HF_EtResPar");
00214   std::vector<double> hfphi = iConfig.getParameter<std::vector<double> >("HF_PhiResPar");
00215 
00216   etparameters[0]=hfet[0];
00217   etparameters[1]=hfet[1];
00218   etparameters[2]=hfet[2];
00219   phiparameters[0]=hfphi[0];
00220   addfunction(caloHF,ET,etparameters);
00221   addfunction(caloHF,PHI,phiparameters);
00222 
00223 
00224   // PF objects:
00225   // type 1:
00226   std::vector<double> pf1et = iConfig.getParameter<std::vector<double> >("PF_EtResType1");
00227   std::vector<double> pf1phi = iConfig.getParameter<std::vector<double> >("PF_PhiResType1");
00228   etparameters[0]=pf1et[0];
00229   etparameters[1]=pf1et[1];
00230   etparameters[2]=pf1et[2];
00231   phiparameters[0]=pf1phi[0];
00232   addfunction(PFtype1,ET,etparameters);
00233   addfunction(PFtype1,PHI,phiparameters);
00234 
00235   // PF objects:
00236   // type 2:
00237   std::vector<double> pf2et = iConfig.getParameter<std::vector<double> >("PF_EtResType2");
00238   std::vector<double> pf2phi = iConfig.getParameter<std::vector<double> >("PF_PhiResType2");
00239   etparameters[0]=pf2et[0];
00240   etparameters[1]=pf2et[1];
00241   etparameters[2]=pf2et[2];
00242   phiparameters[0]=pf2phi[0];
00243   addfunction(PFtype2,ET,etparameters);
00244   addfunction(PFtype2,PHI,phiparameters);
00245 
00246   // PF objects:
00247   // type 3:
00248   std::vector<double> pf3et = iConfig.getParameter<std::vector<double> >("PF_EtResType3");
00249   std::vector<double> pf3phi = iConfig.getParameter<std::vector<double> >("PF_PhiResType3");
00250   etparameters[0]=pf3et[0];
00251   etparameters[1]=pf3et[1];
00252   etparameters[2]=pf3et[2];
00253   phiparameters[0]=pf3phi[0];
00254   addfunction(PFtype3,ET,etparameters);
00255   addfunction(PFtype3,PHI,phiparameters);
00256 
00257   // PF objects:
00258   // type 4:
00259   std::vector<double> pf4et = iConfig.getParameter<std::vector<double> >("PF_EtResType4");
00260   std::vector<double> pf4phi = iConfig.getParameter<std::vector<double> >("PF_PhiResType4");
00261   etparameters[0]=pf4et[0];
00262   etparameters[1]=pf4et[1];
00263   etparameters[2]=pf4et[2];
00264   //phiparameters[0]=pf4phi[0];
00265   addfunction(PFtype4,ET,etparameters);
00266   addfunction(PFtype4,PHI,pf4phi); //use the same functional form for photon phi error as for pT, pass whole vector
00267 
00268   // PF objects:
00269   // type 5:
00270   std::vector<double> pf5et = iConfig.getParameter<std::vector<double> >("PF_EtResType5");
00271   std::vector<double> pf5phi = iConfig.getParameter<std::vector<double> >("PF_PhiResType5");
00272   etparameters[0]=pf5et[0];
00273   etparameters[1]=pf5et[1];
00274   etparameters[2]=pf5et[2];
00275   phiparameters[0]=pf5phi[0];
00276   addfunction(PFtype5,ET,etparameters);
00277   addfunction(PFtype5,PHI,pf5phi);
00278 
00279   // PF objects:
00280   // type 6:
00281   std::vector<double> pf6et = iConfig.getParameter<std::vector<double> >("PF_EtResType6");
00282   std::vector<double> pf6phi = iConfig.getParameter<std::vector<double> >("PF_PhiResType6");
00283   etparameters[0]=pf6et[0];
00284   etparameters[1]=pf6et[1];
00285   etparameters[2]=pf6et[2];
00286   phiparameters[0]=pf6phi[0];
00287   addfunction(PFtype6,ET,etparameters);
00288   addfunction(PFtype6,PHI,phiparameters);
00289 
00290   
00291   // PF objects:
00292   // type 7:
00293   std::vector<double> pf7et = iConfig.getParameter<std::vector<double> >("PF_EtResType7");
00294   std::vector<double> pf7phi = iConfig.getParameter<std::vector<double> >("PF_PhiResType7");
00295   etparameters[0]=pf7et[0];
00296   etparameters[1]=pf7et[1];
00297   etparameters[2]=pf7et[2];
00298   phiparameters[0]=pf7phi[0];
00299   addfunction(PFtype7,ET,etparameters);
00300   addfunction(PFtype7,PHI,phiparameters);
00301 
00302   return;
00303 }
00304 
00305 void metsig::SignAlgoResolutions::addfunction(resolutionType type, resolutionFunc func, functionPars parameters){
00306 
00307   functionCombo mypair(type,func);
00308   functionmap_[mypair]=parameters;
00309 
00310 }
00311 
00312 double metsig::SignAlgoResolutions::getfunc(const metsig::resolutionType & type,const metsig::resolutionFunc & func, functionPars & x) const{
00313   
00314   double result=0;
00315   functionCombo mypair(type,func);
00316 
00317   if(functionmap_.count(mypair)==0){
00318         return result;
00319   }
00320   
00321   functionPars values = (functionmap_.find(mypair))->second;
00322   switch ( func ){
00323   case metsig::ET :
00324     return EtFunction(x,values);
00325   case metsig::PHI :
00326     return PhiFunction(x,values);
00327   case metsig::TRACKP :
00328     return PFunction(x,values);
00329   case metsig::CONSTPHI :
00330     return PhiConstFunction(x,values);
00331   }
00332   
00333   //  std::cout << "returning function " << type << " " << func << " " << result << " " << x[0] << std::endl; 
00334 
00335   return result;
00336 }
00337 
00338 double metsig::SignAlgoResolutions::EtFunction( const functionPars &x, const functionPars & par) const
00339 {
00340   if(par.size()<3)
00341     return 0.;
00342   if(x.size()<1)
00343     return 0.;
00344   double et=x[0];
00345   if(et<=0.)
00346     return 0.;
00347   double result = et*sqrt((par[2]*par[2])+(par[1]*par[1]/et)+(par[0]*par[0]/(et*et)));
00348   return result;
00349 }
00350 
00351 
00352 double metsig::SignAlgoResolutions::PhiFunction(const functionPars &x,const  functionPars & par) const
00353 {
00354   double et=x[0];
00355   if(et<=0.){
00356     return 0.;
00357   }
00358 
00359   //if 1 parameter is C provided, returns C*pT, if three parameters N, S, C are provided, it returns the usual resolution value, as for sigmaPt
00360   if(par.size()!=1 && par.size()!=3){//only 1 or 3 parameters supported for phi function
00361       return 0.;
00362   }
00363   else if(par.size()==1){
00364     return par[0]*et;
00365   }
00366   else{
00367     return et*sqrt((par[2]*par[2])+(par[1]*par[1]/et)+(par[0]*par[0]/(et*et)));
00368   }
00369 
00370 }
00371 double metsig::SignAlgoResolutions::PFunction(const functionPars &x, const functionPars & par) const
00372 {
00373   // not currently implemented
00374   return 0;
00375 }
00376 
00377 double metsig::SignAlgoResolutions::PhiConstFunction(const functionPars& x, const functionPars &par) const
00378 {
00379   return par[0];
00380 }
00381 
00382 void
00383 metsig::SignAlgoResolutions::initializeJetResolutions( const edm::ParameterSet &iConfig ) {
00384   
00385   using namespace std;
00386   
00387   // only reinitialize the resolutsion if the pointers are zero
00388   if ( ptResol_ == 0 ) {
00389     string resolutionsAlgo  = iConfig.getParameter<std::string>("resolutionsAlgo");     
00390     string resolutionsEra   = iConfig.getParameter<std::string>("resolutionsEra");     
00391 
00392     string cmssw_base(getenv("CMSSW_BASE"));
00393     string cmssw_release_base(getenv("CMSSW_RELEASE_BASE"));
00394     string path = cmssw_base + "/src/CondFormats/JetMETObjects/data";
00395     struct stat st;
00396     if (stat(path.c_str(),&st)!=0) {
00397       path = cmssw_release_base + "/src/CondFormats/JetMETObjects/data";
00398     }
00399     if (stat(path.c_str(),&st)!=0) {
00400       cerr<<"ERROR: tried to set path but failed, abort."<<endl;
00401     }    
00402     string era(resolutionsEra);
00403     string alg(resolutionsAlgo);
00404     string ptFileName  = path + "/" + era + "_PtResolution_" +alg+".txt";
00405     string phiFileName = path + "/" + era + "_PhiResolution_"+alg+".txt";
00406     
00407     ptResol_ = new JetResolution(ptFileName,false);
00408     phiResol_ = new JetResolution(phiFileName,false);
00409   }
00410 }
00411 
00412 double 
00413 metsig::SignAlgoResolutions::ElectronPtResolution(const reco::PFCandidate *c) const{
00414 
00415     double eta = c->eta();
00416     double energy = c->energy();
00417     double dEnergy = pfresol_->getEnergyResolutionEm(energy, eta);
00418 
00419     return dEnergy/cosh(eta);
00420 }
00421