CMS 3D CMS Logo

JetCorrFactorsProducer.cc
Go to the documentation of this file.
1 #include <vector>
2 #include <string>
3 #include <iostream>
4 
14 
18 
19 using namespace pat;
20 
22  : emf_(cfg.getParameter<bool>("emf")),
23  srcToken_(consumes<edm::View<reco::Jet> >(cfg.getParameter<edm::InputTag>("src"))),
24  type_(cfg.getParameter<std::string>("flavorType")),
25  label_(cfg.getParameter<std::string>("@module_label")),
26  payload_(cfg.getParameter<std::string>("payload")),
27  useNPV_(cfg.getParameter<bool>("useNPV")),
28  useRho_(cfg.getParameter<bool>("useRho")),
29  cacheId_(0) {
30  std::vector<std::string> levels = cfg.getParameter<std::vector<std::string> >("levels");
31  // fill the std::map for levels_, which might be flavor dependent or not;
32  // flavor dependency is determined from the fact whether the std::string
33  // L5Flavor or L7Parton can be found in levels; if flavor dependent four
34  // vectors of strings will be filled into the map corresponding to GLUON,
35  // UDS, CHARM and BOTTOM (according to JetCorrFactors::Flavor), 'L5Flavor'
36  // and 'L7Parton' will be expanded accordingly; if not levels_ is filled
37  // with only one vector of strings according to NONE. This vector will be
38  // equivalent to the original vector of strings.
39  if (std::find(levels.begin(), levels.end(), "L5Flavor") != levels.end() ||
40  std::find(levels.begin(), levels.end(), "L7Parton") != levels.end()) {
45  } else {
47  }
48  // if the std::string L1JPTOffset can be found in levels an additional
49  // parameter extraJPTOffset is needed, which should pass on the the usual
50  // L1Offset correction, which is an additional input to the L1JPTOffset
51  // corrector
52  if (std::find(levels.begin(), levels.end(), "L1JPTOffset") != levels.end()) {
53  if (cfg.existsAs<std::string>("extraJPTOffset")) {
54  extraJPTOffset_.push_back(cfg.getParameter<std::string>("extraJPTOffset"));
55  } else {
56  throw cms::Exception("No parameter extraJPTOffset specified")
57  << "The configured correction levels contain a L1JPTOffset correction, which re- \n"
58  << "quires the additional parameter extraJPTOffset or type std::string. This \n"
59  << "string should correspond to the L1Offset corrections that should be applied \n"
60  << "together with the JPTL1Offset corrections. These corrections can be of type \n"
61  << "L1Offset or L1FastJet. \n";
62  }
63  }
64  // if the std::string L1Offset can be found in levels an additional para-
65  // meter primaryVertices is needed, which should pass on the offline pri-
66  // mary vertex collection. The size of this collection is needed for the
67  // L1Offset correction.
68  if (useNPV_) {
69  if (cfg.existsAs<edm::InputTag>("primaryVertices")) {
70  primaryVertices_ = cfg.getParameter<edm::InputTag>("primaryVertices");
71  primaryVerticesToken_ = mayConsume<std::vector<reco::Vertex> >(primaryVertices_);
72  } else {
73  throw cms::Exception("No primaryVertices specified")
74  << "The configured correction levels contain an L1Offset or L1FastJet correction, \n"
75  << "which requires the number of offlinePrimaryVertices. Please specify this col- \n"
76  << "lection as additional optional parameter primaryVertices of type edm::InputTag\n"
77  << "in the jetCorrFactors module. \n";
78  }
79  }
80  // if the std::string L1FastJet can be found in levels an additional
81  // parameter rho is needed, which should pass on the energy density
82  // parameter for the corresponding jet collection.
83  if (useRho_) {
84  if ((!extraJPTOffset_.empty() && extraJPTOffset_.front() == std::string("L1FastJet")) ||
85  std::find(levels.begin(), levels.end(), "L1FastJet") != levels.end()) {
86  if (cfg.existsAs<edm::InputTag>("rho")) {
87  rho_ = cfg.getParameter<edm::InputTag>("rho");
88  rhoToken_ = mayConsume<double>(rho_);
89  } else {
90  throw cms::Exception("No parameter rho specified")
91  << "The configured correction levels contain a L1FastJet correction, which re- \n"
92  << "quires the energy density parameter rho. Please specify this collection as \n"
93  << "additional optional parameter rho of type edm::InputTag in the jetCorrFac- \n"
94  << "tors module. \n";
95  }
96  } else {
97  edm::LogInfo message("Parameter rho not used");
98  message << "Module is configured to use the parameter rho, but rho is only used \n"
99  << "for L1FastJet corrections. The configuration of levels does not contain \n"
100  << "L1FastJet corrections though, so rho will not be used by this module. \n";
101  }
102  }
103  produces<JetCorrFactorsMap>();
104 }
105 
106 std::vector<std::string> JetCorrFactorsProducer::expand(const std::vector<std::string>& levels,
107  const JetCorrFactors::Flavor& flavor) {
108  std::vector<std::string> expand;
109  for (std::vector<std::string>::const_iterator level = levels.begin(); level != levels.end(); ++level) {
110  if ((*level) == "L5Flavor" || (*level) == "L7Parton") {
111  if (flavor == JetCorrFactors::GLUON) {
112  if (*level == "L7Parton" && type_ == "T") {
113  edm::LogWarning message("L7Parton::GLUON not available");
114  message << "Jet energy corrections requested for level: L7Parton and type: 'T'. \n"
115  << "For this combination there is no GLUON correction available. The \n"
116  << "correction for this flavor type will be taken from 'J'.";
117  }
118  expand.push_back(std::string(*level).append("_").append("g").append("J"));
119  }
120  if (flavor == JetCorrFactors::UDS)
121  expand.push_back(std::string(*level).append("_").append("q").append(type_));
122  if (flavor == JetCorrFactors::CHARM)
123  expand.push_back(std::string(*level).append("_").append("c").append(type_));
124  if (flavor == JetCorrFactors::BOTTOM)
125  expand.push_back(std::string(*level).append("_").append("b").append(type_));
126  } else {
127  expand.push_back(*level);
128  }
129  }
130  return expand;
131 }
132 
134  const std::vector<std::string>& levels) const {
135  std::vector<JetCorrectorParameters> params;
136  for (std::vector<std::string>::const_iterator level = levels.begin(); level != levels.end(); ++level) {
137  const JetCorrectorParameters& ip = parameters[*level]; //ip.printScreen();
138  params.push_back(ip);
139  }
140  return params;
141 }
142 
144  const JetCorrFactors::Flavor& flavor,
145  int level) {
146  std::unique_ptr<FactorizedJetCorrector>& corrector = correctors_.find(flavor)->second;
147  // add parameters for JPT corrections
148  const reco::JPTJet* jpt = dynamic_cast<reco::JPTJet const*>(&*jet);
149  if (jpt) {
150  TLorentzVector p4;
151  p4.SetPtEtaPhiE(jpt->getCaloJetRef()->pt(),
152  jpt->getCaloJetRef()->eta(),
153  jpt->getCaloJetRef()->phi(),
154  jpt->getCaloJetRef()->energy());
156  extraJPTOffsetCorrector_->setJPTrawP4(p4);
157  corrector->setJPTrawOff(extraJPTOffsetCorrector_->getSubCorrections()[0]);
158  }
159  corrector->setJPTrawP4(p4);
160  }
161  //For PAT jets undo previous jet energy corrections
162  const Jet* patjet = dynamic_cast<Jet const*>(&*jet);
163  if (patjet) {
164  corrector->setJetEta(patjet->correctedP4(0).eta());
165  corrector->setJetPt(patjet->correctedP4(0).pt());
166  corrector->setJetPhi(patjet->correctedP4(0).phi());
167  corrector->setJetE(patjet->correctedP4(0).energy());
168  } else {
169  corrector->setJetEta(jet->eta());
170  corrector->setJetPt(jet->pt());
171  corrector->setJetPhi(jet->phi());
172  corrector->setJetE(jet->energy());
173  }
174  if (emf_ && dynamic_cast<const reco::CaloJet*>(&*jet)) {
175  corrector->setJetEMF(dynamic_cast<const reco::CaloJet*>(&*jet)->emEnergyFraction());
176  }
177  return corrector->getSubCorrections()[level];
178 }
179 
181 
183  // get jet collection from the event
185  event.getByToken(srcToken_, jets);
186 
187  // get primary vertices for L1Offset correction level if needed
189  if (!primaryVertices_.label().empty())
190  event.getByToken(primaryVerticesToken_, primaryVertices);
191 
192  // get parameter rho for L1FastJet correction level if needed
194  if (!rho_.label().empty())
195  event.getByToken(rhoToken_, rho);
196 
197  auto const& rec = setup.get<JetCorrectionsRecord>();
198  if (cacheId_ != rec.cacheIdentifier()) {
199  // retreive parameters from the DB
201  setup.get<JetCorrectionsRecord>().get(payload(), parameters);
202  // initialize jet correctors
203  for (FlavorCorrLevelMap::const_iterator flavor = levels_.begin(); flavor != levels_.end(); ++flavor) {
204  correctors_[flavor->first].reset(new FactorizedJetCorrector(params(*parameters, flavor->second)));
205  }
206  // initialize extra jet corrector for jpt if needed
207  if (!extraJPTOffset_.empty()) {
209  }
210  cacheId_ = rec.cacheIdentifier();
211  }
212 
213  // fill the jetCorrFactors
214  std::vector<JetCorrFactors> jcfs;
215  for (edm::View<reco::Jet>::const_iterator jet = jets->begin(); jet != jets->end(); ++jet) {
216  // the JetCorrFactors::CorrectionFactor is a std::pair<std::string, std::vector<float> >
217  // the string corresponds to the label of the correction level, the vector contains four
218  // floats if flavor dependent and one float else. Per construction jet energy corrections
219  // will be flavor independent up to the first flavor dependent correction and flavor de-
220  // pendent afterwards. The first correction level is predefined with label 'Uncorrected'.
221  // Per definition it is flavor independent. The correction factor is 1.
222  std::vector<JetCorrFactors::CorrectionFactor> jec;
223  jec.push_back(
224  std::make_pair<std::string, std::vector<float> >(std::string("Uncorrected"), std::vector<float>(1, 1)));
225 
226  // pick the first element in the map (which could be the only one) and loop all jec
227  // levels listed for that element. If this is not the only element all jec levels, which
228  // are flavor independent will give the same correction factors until the first flavor
229  // dependent correction level is reached. So the first element is still a good choice.
230  FlavorCorrLevelMap::const_iterator corrLevel = levels_.begin();
231  if (corrLevel == levels_.end()) {
232  throw cms::Exception("No JECFactors")
233  << "You request to create a jetCorrFactors object with no JEC Levels indicated. \n"
234  << "This makes no sense, either you should correct this or drop the module from \n"
235  << "the sequence.";
236  }
237  for (unsigned int idx = 0; idx < corrLevel->second.size(); ++idx) {
238  std::vector<float> factors;
239  if (corrLevel->second[idx].find("L5Flavor") != std::string::npos ||
240  corrLevel->second[idx].find("L7Parton") != std::string::npos) {
241  for (FlavorCorrLevelMap::const_iterator flavor = corrLevel; flavor != levels_.end(); ++flavor) {
242  if (!primaryVertices_.label().empty()) {
243  // if primaryVerticesToken_ has a value the number of primary vertices needs to be
244  // specified
245  correctors_.find(flavor->first)->second->setNPV(numberOf(primaryVertices));
246  }
247  if (!rho_.label().empty()) {
248  // if rhoToken_ has a value the energy density parameter rho and the jet area need
249  // to be specified
250  correctors_.find(flavor->first)->second->setRho(*rho);
251  correctors_.find(flavor->first)->second->setJetA(jet->jetArea());
252  }
253  factors.push_back(evaluate(jet, flavor->first, idx));
254  }
255  } else {
256  if (!primaryVertices_.label().empty()) {
257  // if primaryVerticesToken_ has a value the number of primary vertices needs to be
258  // specified
259  correctors_.find(corrLevel->first)->second->setNPV(numberOf(primaryVertices));
260  }
261  if (!rho_.label().empty()) {
262  // if rhoToken_ has a value the energy density parameter rho and the jet area need
263  // to be specified
264  correctors_.find(corrLevel->first)->second->setRho(*rho);
265  correctors_.find(corrLevel->first)->second->setJetA(jet->jetArea());
266  }
267  factors.push_back(evaluate(jet, corrLevel->first, idx));
268  }
269  // push back the set of JetCorrFactors: the first entry corresponds to the label
270  // of the correction level, which is taken from the first element in levels_. For
271  // L5Flavor and L7Parton the part including the first '_' indicating the flavor
272  // of the first element in levels_ is chopped of from the label to avoid confusion
273  // of the correction levels. The second parameter corresponds to the set of jec
274  // factors, which might be flavor dependent or not. In the default configuration
275  // the CorrectionFactor will look like this: 'Uncorrected': 1 ; 'L2Relative': x ;
276  // 'L3Absolute': x ; 'L5Flavor': v, x, y, z ; 'L7Parton': v, x, y, z
277  jec.push_back(std::make_pair((corrLevel->second[idx]).substr(0, (corrLevel->second[idx]).find("_")), factors));
278  }
279  // create the actual object with the scale factors we want the valuemap to refer to
280  // label_ corresponds to the label of the module instance
281  JetCorrFactors corrFactors(label_, jec);
282  jcfs.push_back(corrFactors);
283  }
284  // build the value map
285  auto jetCorrsMap = std::make_unique<JetCorrFactorsMap>();
286  JetCorrFactorsMap::Filler filler(*jetCorrsMap);
287  // jets and jetCorrs have their indices aligned by construction
288  filler.insert(jets, jcfs.begin(), jcfs.end());
289  filler.fill(); // do the actual filling
290  // put our produced stuff in the event
291  event.put(std::move(jetCorrsMap));
292 }
293 
296  iDesc.add<bool>("emf", false);
297  iDesc.add<std::string>("flavorType", "J");
298  iDesc.add<edm::InputTag>("src", edm::InputTag("ak5CaloJets"));
299  iDesc.add<std::string>("payload", "AK5Calo");
300  iDesc.add<bool>("useNPV", true);
301  iDesc.add<edm::InputTag>("primaryVertices", edm::InputTag("offlinePrimaryVertices"));
302  iDesc.add<bool>("useRho", true);
303  iDesc.add<edm::InputTag>("rho", edm::InputTag("fixedGridRhoFastjetAllCalo"));
304  iDesc.add<std::string>("extraJPTOffset", "L1Offset");
305 
306  std::vector<std::string> levels;
307  levels.push_back(std::string("L1Offset"));
308  levels.push_back(std::string("L2Relative"));
309  levels.push_back(std::string("L3Absolute"));
310  levels.push_back(std::string("L2L3Residual"));
311  levels.push_back(std::string("L5Flavor"));
312  levels.push_back(std::string("L7Parton"));
313  iDesc.add<std::vector<std::string> >("levels", levels);
314  descriptions.add("JetCorrFactorsProducer", iDesc);
315 }
316 
318 
const LorentzVector correctedP4(const std::string &level, const std::string &flavor="none", const std::string &set="") const
Definition: Jet.h:158
T getParameter(std::string const &) const
edm::EDGetTokenT< double > rhoToken_
std::string payload()
map jet algorithm to payload in DB
double eta() const final
momentum pseudorapidity
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:161
std::string label_
label of jec factors
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
void push_back(key_type i, value_type const &j, label_type const &flav="")
def setup(process, global_tag, zero_tesla=False)
Definition: GeneralSetup.py:2
double pt() const final
transverse momentum
edm::EDGetTokenT< std::vector< reco::Vertex > > primaryVerticesToken_
const edm::RefToBase< reco::Jet > & getCaloJetRef() const
Definition: JPTJet.h:130
std::vector< std::string > extraJPTOffset_
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
bool emf_
use electromagnetic fraction for jet energy corrections or not (will only have an effect for jets Cal...
std::string payload_
label of payload
Definition: HeavyIon.h:7
JetCorrFactorsProducer(const edm::ParameterSet &cfg)
default constructor
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
Definition: Jet.py:1
double p4[4]
Definition: TauolaWrapper.h:92
void produce(edm::Event &event, const edm::EventSetup &setup) override
everything that needs to be done per event
Jets made from CaloJets corrected for ZSP and tracks.
Definition: JPTJet.h:29
int numberOf(const edm::Handle< std::vector< reco::Vertex > > &primaryVertices)
determines the number of valid primary vertices for the standard L1Offset correction of JetMET ...
Class for the storage of jet correction factors.
vector< PseudoJet > jets
double energy() const final
energy
ParameterDescriptionBase * add(U const &iLabel, T const &value)
Produces a ValueMap between JetCorrFactors and the to the originating reco jets.
std::vector< std::string > expand(const std::vector< std::string > &levels, const JetCorrFactors::Flavor &flavor)
primaryVertices
Definition: jets_cff.py:24
edm::EDGetTokenT< edm::View< reco::Jet > > srcToken_
input jet collection
std::vector< JetCorrectorParameters > params(const JetCorrectorParametersCollection &parameters, const std::vector< std::string > &levels) const
return the jec parameters as input to the FactorizedJetCorrector for different flavors ...
void add(std::string const &label, ParameterSetDescription const &psetDescription)
std::string const & label() const
Definition: InputTag.h:36
fixed size matrix
HLT enums.
boost::indirect_iterator< typename seq_t::const_iterator > const_iterator
Definition: View.h:86
T get() const
Definition: EventSetup.h:71
std::unique_ptr< FactorizedJetCorrector > extraJPTOffsetCorrector_
cache container for JPTOffset jet corrections
std::map< JetCorrFactors::Flavor, std::unique_ptr< FactorizedJetCorrector > > correctors_
cache container for jet corrections
edm::InputTag primaryVertices_
label for L1Offset primaryVertex collection
edm::InputTag rho_
label for L1FastJet energy density parameter rho
bool useNPV_
use the NPV and rho with the JEC? (used for L1Offset/L1FastJet and L1FastJet, resp.)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
description of configuration file parameters
std::string type_
type of flavor dependent JEC factors (only &#39;J&#39; and &#39;T&#39; are allowed)
float evaluate(edm::View< reco::Jet >::const_iterator &jet, const JetCorrFactors::Flavor &flavor, int level)
evaluate jet correction factor up to a given level
double phi() const final
momentum azimuthal angle
unsigned long long cacheId_
cache identifier for JetCorrectionsRecord
def move(src, dest)
Definition: eostools.py:511
Definition: event.py:1