CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/PhysicsTools/PatAlgos/plugins/JetCorrFactorsProducer.cc

Go to the documentation of this file.
00001 #include <memory>
00002 #include <vector>
00003 #include <string>
00004 #include <iostream>
00005 
00006 #include "FWCore/Framework/interface/ESHandle.h"
00007 #include "FWCore/Framework/interface/EventSetup.h"
00008 #include "DataFormats/JetReco/interface/CaloJet.h"
00009 #include "DataFormats/VertexReco/interface/Vertex.h"
00010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00011 #include "PhysicsTools/PatAlgos/plugins/JetCorrFactorsProducer.h"
00012 #include "JetMETCorrections/Objects/interface/JetCorrectionsRecord.h"
00013 
00014 #include "FWCore/ParameterSet/interface/ParameterDescription.h"
00015 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
00016 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
00017 
00018 
00019 using namespace pat;
00020 
00021 JetCorrFactorsProducer::JetCorrFactorsProducer(const edm::ParameterSet& cfg):
00022   emf_(cfg.getParameter<bool>( "emf" )), 
00023   src_(cfg.getParameter<edm::InputTag>( "src" )),
00024   type_ (cfg.getParameter<std::string>("flavorType")),
00025   label_(cfg.getParameter<std::string>( "@module_label" )),
00026   payload_( cfg.getParameter<std::string>("payload") ),
00027   useNPV_(cfg.getParameter<bool>("useNPV")),
00028   useRho_(cfg.getParameter<bool>("useRho"))
00029 {
00030 
00031   std::vector<std::string> levels = cfg.getParameter<std::vector<std::string> >("levels"); 
00032   // fill the std::map for levels_, which might be flavor dependent or not; 
00033   // flavor dependency is determined from the fact whether the std::string 
00034   // L5Flavor or L7Parton can be found in levels; if flavor dependent four
00035   // vectors of strings will be filled into the map corresponding to GLUON, 
00036   // UDS, CHARM and BOTTOM (according to JetCorrFactors::Flavor), 'L5Flavor'
00037   // and 'L7Parton' will be expanded accordingly; if not levels_ is filled 
00038   // with only one vector of strings according to NONE. This vector will be 
00039   // equivalent to the original vector of strings.
00040   if(std::find(levels.begin(), levels.end(), "L5Flavor")!=levels.end() || std::find(levels.begin(), levels.end(), "L7Parton")!=levels.end()){
00041     levels_[JetCorrFactors::GLUON ] = expand(levels, JetCorrFactors::GLUON );
00042     levels_[JetCorrFactors::UDS   ] = expand(levels, JetCorrFactors::UDS   );
00043     levels_[JetCorrFactors::CHARM ] = expand(levels, JetCorrFactors::CHARM );
00044     levels_[JetCorrFactors::BOTTOM] = expand(levels, JetCorrFactors::BOTTOM);
00045   }
00046   else{
00047     levels_[JetCorrFactors::NONE  ] = levels;
00048   }
00049   // if the std::string L1Offset can be found in levels an additional para-
00050   // meter primaryVertices is needed, which should pass on the offline pri-
00051   // mary vertex collection. The size of this collection is needed for the 
00052   // L1Offset correction.
00053   if(useNPV_){
00054     if(cfg.existsAs<edm::InputTag>("primaryVertices")){
00055       primaryVertices_=cfg.getParameter<edm::InputTag>("primaryVertices");
00056     }
00057     else{
00058       throw cms::Exception("No primaryVertices specified") 
00059         << "The configured correction levels contain an L1Offset or L1FastJet correction, \n"
00060         << "which requires the number of offlinePrimaryVertices. Please specify this col- \n"
00061         << "lection as additional optional parameter primaryVertices in the jetCorrFactors\n"
00062         << "module. \n";
00063     }
00064   }
00065   // if the std::string L1FastJet can be found in levels an additional
00066   // parameter rho is needed, which should pass on the energy density 
00067   // parameter for the corresponding jet collection.
00068   if(useRho_){
00069     if(std::find(levels.begin(), levels.end(), "L1FastJet")!=levels.end()){
00070       if(cfg.existsAs<edm::InputTag>("rho")){
00071         rho_=cfg.getParameter<edm::InputTag>("rho");
00072       }
00073       else{
00074         throw cms::Exception("No parameter rho specified") 
00075           << "The configured correction levels contain a L1FastJet correction, which re- \n"
00076           << "quires the energy density parameter rho. Please specify this collection as \n"
00077           << "additional optional parameter rho in the jetCorrFactors module. \n";
00078       }
00079     }
00080     else{
00081       edm::LogWarning message( "Parameter rho not used" );
00082       message << "Module is configured to use the parameter rho, but but rho is only used \n"
00083               << "for L1FastJet corrections at the moment. The configuration of levels    \n"
00084               << "does not contain L1FastJet corrections though, so rho will not be used  \n"
00085               << "throughout this module. \n";
00086     }
00087   }
00088   produces<JetCorrFactorsMap>();
00089 }
00090 
00091 std::vector<std::string>
00092 JetCorrFactorsProducer::expand(const std::vector<std::string>& levels, const JetCorrFactors::Flavor& flavor)
00093 {
00094   std::vector<std::string> expand;
00095   for(std::vector<std::string>::const_iterator level=levels.begin(); level!=levels.end(); ++level){
00096     if((*level)=="L5Flavor" || (*level)=="L7Parton"){
00097       if(flavor==JetCorrFactors::GLUON ){
00098         if(*level=="L7Parton" && type_=="T"){
00099           edm::LogWarning message( "L7Parton::GLUON not available" );
00100           message << "Jet energy corrections requested for level: L7Parton and type: 'T'. \n"
00101                   << "For this combination there is no GLUON correction available. The    \n"
00102                   << "correction for this flavor type will be taken from 'J'.";
00103         }
00104         expand.push_back(std::string(*level).append("_").append("g").append("J"));      
00105       }
00106       if(flavor==JetCorrFactors::UDS   ) expand.push_back(std::string(*level).append("_").append("q").append(type_));   
00107       if(flavor==JetCorrFactors::CHARM ) expand.push_back(std::string(*level).append("_").append("c").append(type_));   
00108       if(flavor==JetCorrFactors::BOTTOM) expand.push_back(std::string(*level).append("_").append("b").append(type_));
00109     }
00110     else{
00111       expand.push_back(*level); 
00112     }
00113   }
00114   return expand;
00115 }
00116 
00117 std::vector<JetCorrectorParameters>
00118 JetCorrFactorsProducer::params(const JetCorrectorParametersCollection& parameters, const std::vector<std::string>& levels) const 
00119 {
00120   std::vector<JetCorrectorParameters> params;
00121   for(std::vector<std::string>::const_iterator level=levels.begin(); level!=levels.end(); ++level){ 
00122     const JetCorrectorParameters& ip = parameters[*level]; //ip.printScreen();
00123     params.push_back(ip); 
00124   } 
00125   return params;
00126 }
00127 
00128 float
00129 JetCorrFactorsProducer::evaluate(edm::View<reco::Jet>::const_iterator& jet, boost::shared_ptr<FactorizedJetCorrector>& corrector, int level)
00130 {
00131   corrector->setJetEta(jet->eta()); corrector->setJetPt(jet->pt()); corrector->setJetE(jet->energy()); 
00132   if( emf_ && dynamic_cast<const reco::CaloJet*>(&*jet)){ 
00133     corrector->setJetEMF(dynamic_cast<const reco::CaloJet*>(&*jet)->emEnergyFraction()); 
00134   }
00135   return corrector->getSubCorrections()[level];
00136 }
00137 
00138 std::string
00139 JetCorrFactorsProducer::payload()
00140 {
00141   return payload_;
00142 }
00143 
00144 void 
00145 JetCorrFactorsProducer::produce(edm::Event& event, const edm::EventSetup& setup) 
00146 {
00147   // get jet collection from the event
00148   edm::Handle<edm::View<reco::Jet> > jets;
00149   event.getByLabel(src_, jets);
00150 
00151   // get primary vertices for L1Offset correction level if needed
00152   edm::Handle<std::vector<reco::Vertex> > primaryVertices;
00153   if(!primaryVertices_.label().empty()) event.getByLabel(primaryVertices_, primaryVertices);
00154 
00155   // get parameter rho for L1FastJet correction level if needed
00156   
00157   edm::Handle<double> rho;
00158   if(!rho_.label().empty()) event.getByLabel(rho_, rho);
00159 
00160   // retreive parameters from the DB 
00161   edm::ESHandle<JetCorrectorParametersCollection> parameters;
00162   setup.get<JetCorrectionsRecord>().get(payload(), parameters); 
00163 
00164   // initialize jet correctors
00165   std::map<JetCorrFactors::Flavor, boost::shared_ptr<FactorizedJetCorrector> > corrector;
00166   for(FlavorCorrLevelMap::const_iterator flavor=levels_.begin(); flavor!=levels_.end(); ++flavor){
00167     corrector[flavor->first] = boost::shared_ptr<FactorizedJetCorrector>( new FactorizedJetCorrector(params(*parameters, flavor->second)) );
00168   }
00169 
00170   // fill the jetCorrFactors
00171   std::vector<JetCorrFactors> jcfs;
00172   for(edm::View<reco::Jet>::const_iterator jet = jets->begin(); jet!=jets->end(); ++jet){
00173     // the JetCorrFactors::CorrectionFactor is a std::pair<std::string, std::vector<float> >
00174     // the string corresponds to the label of the correction level, the vector contains four 
00175     // floats if flavor dependent and one float else. Per construction jet energy corrections
00176     // will be flavor independent up to the first flavor dependent correction and flavor de-
00177     // pendent afterwards. The first correction level is predefined with label 'Uncorrected'. 
00178     // Per definition it is flavor independent. The correction factor is 1.
00179     std::vector<JetCorrFactors::CorrectionFactor> jec;
00180     jec.push_back(std::make_pair<std::string, std::vector<float> >(std::string("Uncorrected"), std::vector<float>(1, 1)));
00181 
00182     // pick the first element in the map (which could be the only one) and loop all jec 
00183     // levels listed for that element. If this is not the only element all jec levels, which 
00184     // are flavor independent will give the same correction factors until the first flavor
00185     // dependent correction level is reached. So the first element is still a good choice.
00186     FlavorCorrLevelMap::const_iterator corrLevel=levels_.begin();
00187     if(corrLevel==levels_.end()){
00188       throw cms::Exception("No JECFactors") << "You request to create a jetCorrFactors object with no JEC Levels indicated. \n"
00189                                             << "This makes no sense, either you should correct this or drop the module from \n"
00190                                             << "the sequence."; 
00191     }
00192     for(unsigned int idx=0; idx<corrLevel->second.size(); ++idx){
00193       bool flavorDependent=false;
00194       std::vector<float> factors;
00195       if(flavorDependent || 
00196          corrLevel->second[idx].find("L5Flavor")!=std::string::npos || 
00197          corrLevel->second[idx].find("L7Parton")!=std::string::npos){
00198         flavorDependent=true;
00199         // after the first encounter all subsequent correction levels are flavor dependent
00200         for(FlavorCorrLevelMap::const_iterator flavor=corrLevel; flavor!=levels_.end(); ++flavor){
00201           if(!primaryVertices_.label().empty()){
00202             // if primaryVertices_ has a value the number of primary vertices needs to be 
00203             // specified
00204             corrector.find(flavor->first)->second->setNPV(numberOf(primaryVertices));
00205           }
00206           if(!rho_.label().empty()){
00207             // if rho_ has a value the energy density parameter rho and the jet area need
00208             //  to be specified
00209             corrector.find(flavor->first)->second->setRho(*rho);
00210             corrector.find(flavor->first)->second->setJetA(jet->jetArea());
00211           }
00212           factors.push_back(evaluate(jet, corrector.find(flavor->first)->second, idx)); 
00213         }
00214       }
00215       else{
00216         if(!primaryVertices_.label().empty()){
00217           // if primaryVertices_ has a value the number of primary vertices needs to be 
00218           // specified
00219           corrector.find(corrLevel->first)->second->setNPV(numberOf(primaryVertices));
00220         }
00221         if(!rho_.label().empty()){
00222           // if rho_ has a value the energy density parameter rho and the jet area need
00223           //  to be specified
00224           corrector.find(corrLevel->first)->second->setRho(*rho);
00225           corrector.find(corrLevel->first)->second->setJetA(jet->jetArea());
00226         }
00227         factors.push_back(evaluate(jet, corrector.find(corrLevel->first)->second, idx));
00228       }
00229       // push back the set of JetCorrFactors: the first entry corresponds to the label 
00230       // of the correction level, which is taken from the first element in levels_. For
00231       // L5Flavor and L7Parton the part including the first '_' indicating the flavor
00232       // of the first element in levels_ is chopped of from the label to avoid confusion 
00233       // of the correction levels. The second parameter corresponds to the set of jec 
00234       // factors, which might be flavor dependent or not. In the default configuration 
00235       // the CorrectionFactor will look like this: 'Uncorrected': 1 ; 'L2Relative': x ; 
00236       // 'L3Absolute': x ; 'L5Flavor': v, x, y, z ; 'L7Parton': v, x, y, z 
00237       jec.push_back(std::make_pair((corrLevel->second[idx]).substr(0, (corrLevel->second[idx]).find("_")), factors));
00238     }
00239     // create the actual object with the scale factors we want the valuemap to refer to
00240     // label_ corresponds to the label of the module instance
00241     JetCorrFactors corrFactors(label_, jec);
00242     jcfs.push_back(corrFactors);
00243   }
00244   // build the value map
00245   std::auto_ptr<JetCorrFactorsMap> jetCorrsMap(new JetCorrFactorsMap());
00246   JetCorrFactorsMap::Filler filler(*jetCorrsMap);
00247   // jets and jetCorrs have their indices aligned by construction
00248   filler.insert(jets, jcfs.begin(), jcfs.end());
00249   filler.fill(); // do the actual filling
00250   // put our produced stuff in the event
00251   event.put(jetCorrsMap);
00252 }
00253 
00254 void
00255 JetCorrFactorsProducer::fillDescriptions(edm::ConfigurationDescriptions & descriptions)
00256 {
00257   edm::ParameterSetDescription iDesc;
00258   iDesc.add<bool>("emf", false);
00259   iDesc.add<std::string>("flavorType", "J");
00260   iDesc.add<edm::InputTag>("src", edm::InputTag("ak5CaloJets"));
00261   iDesc.add<std::string>("payload", "AK5Calo");
00262   iDesc.add<bool>("useNPV", true);
00263   iDesc.add<edm::InputTag>("primaryVertices", edm::InputTag("offlinePrimaryVertices"));
00264   iDesc.add<bool>("useRho", false);
00265   iDesc.add<edm::InputTag>("rho", edm::InputTag("kt6PFJets", "rho"));
00266 
00267   std::vector<std::string> levels;
00268   levels.push_back(std::string("L1Offset"  )); 
00269   levels.push_back(std::string("L2Relative")); 
00270   levels.push_back(std::string("L3Absolute")); 
00271   levels.push_back(std::string("L5Flavor"  )); 
00272   levels.push_back(std::string("L7Parton"  )); 
00273   iDesc.add<std::vector<std::string> >("levels", levels);
00274   descriptions.add("JetCorrFactorsProducer", iDesc);
00275 }
00276 
00277 #include "FWCore/Framework/interface/MakerMacros.h"
00278 
00279 DEFINE_FWK_MODULE(JetCorrFactorsProducer);