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
00033
00034
00035
00036
00037
00038
00039
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
00050
00051
00052
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
00066
00067
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];
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
00148 edm::Handle<edm::View<reco::Jet> > jets;
00149 event.getByLabel(src_, jets);
00150
00151
00152 edm::Handle<std::vector<reco::Vertex> > primaryVertices;
00153 if(!primaryVertices_.label().empty()) event.getByLabel(primaryVertices_, primaryVertices);
00154
00155
00156
00157 edm::Handle<double> rho;
00158 if(!rho_.label().empty()) event.getByLabel(rho_, rho);
00159
00160
00161 edm::ESHandle<JetCorrectorParametersCollection> parameters;
00162 setup.get<JetCorrectionsRecord>().get(payload(), parameters);
00163
00164
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
00171 std::vector<JetCorrFactors> jcfs;
00172 for(edm::View<reco::Jet>::const_iterator jet = jets->begin(); jet!=jets->end(); ++jet){
00173
00174
00175
00176
00177
00178
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
00183
00184
00185
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
00200 for(FlavorCorrLevelMap::const_iterator flavor=corrLevel; flavor!=levels_.end(); ++flavor){
00201 if(!primaryVertices_.label().empty()){
00202
00203
00204 corrector.find(flavor->first)->second->setNPV(numberOf(primaryVertices));
00205 }
00206 if(!rho_.label().empty()){
00207
00208
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
00218
00219 corrector.find(corrLevel->first)->second->setNPV(numberOf(primaryVertices));
00220 }
00221 if(!rho_.label().empty()){
00222
00223
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
00230
00231
00232
00233
00234
00235
00236
00237 jec.push_back(std::make_pair((corrLevel->second[idx]).substr(0, (corrLevel->second[idx]).find("_")), factors));
00238 }
00239
00240
00241 JetCorrFactors corrFactors(label_, jec);
00242 jcfs.push_back(corrFactors);
00243 }
00244
00245 std::auto_ptr<JetCorrFactorsMap> jetCorrsMap(new JetCorrFactorsMap());
00246 JetCorrFactorsMap::Filler filler(*jetCorrsMap);
00247
00248 filler.insert(jets, jcfs.begin(), jcfs.end());
00249 filler.fill();
00250
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);