CMS 3D CMS Logo

PATJetUpdater.cc
Go to the documentation of this file.
1 
30 
31 #include <algorithm>
32 #include <memory>
33 #include <vector>
34 
35 namespace pat {
36 
38  public:
39  explicit PATJetUpdater(const edm::ParameterSet& iConfig);
40  ~PATJetUpdater() override;
41 
42  void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
43 
44  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
45 
46  private:
47  // configurables
49  bool sort_;
51  std::vector<edm::EDGetTokenT<edm::ValueMap<JetCorrFactors>>> jetCorrFactorsTokens_;
52 
55  std::vector<edm::InputTag> discriminatorTags_;
56  std::vector<edm::EDGetTokenT<reco::JetFloatAssociation::Container>> discriminatorTokens_;
57  std::vector<std::string> discriminatorLabels_;
59  std::vector<edm::InputTag> tagInfoTags_;
60  std::vector<edm::EDGetTokenT<edm::View<reco::BaseTagInfo>>> tagInfoTokens_;
61  std::vector<std::string> tagInfoLabels_;
62 
64 
67  //
68  bool printWarning_; // this is introduced to issue warnings only once per job
69  };
70 
71 } // namespace pat
72 
73 using namespace pat;
74 
76  : useUserData_(iConfig.exists("userData")), printWarning_(iConfig.getParameter<bool>("printWarning")) {
77  // initialize configurables
78  jetsToken_ = consumes<edm::View<reco::Jet>>(iConfig.getParameter<edm::InputTag>("jetSource"));
79  sort_ = iConfig.getParameter<bool>("sort");
80  addJetCorrFactors_ = iConfig.getParameter<bool>("addJetCorrFactors");
81  if (addJetCorrFactors_) {
83  iConfig.getParameter<std::vector<edm::InputTag>>("jetCorrFactorsSource"),
84  [this](edm::InputTag const& tag) { return mayConsume<edm::ValueMap<JetCorrFactors>>(tag); });
85  }
86  addBTagInfo_ = iConfig.getParameter<bool>("addBTagInfo");
87  addDiscriminators_ = iConfig.getParameter<bool>("addDiscriminators");
88  discriminatorTags_ = iConfig.getParameter<std::vector<edm::InputTag>>("discriminatorSources");
90  return mayConsume<reco::JetFloatAssociation::Container>(tag);
91  });
92  addTagInfos_ = iConfig.getParameter<bool>("addTagInfos");
93  tagInfoTags_ = iConfig.getParameter<std::vector<edm::InputTag>>("tagInfoSources");
95  tagInfoTags_, [this](edm::InputTag const& tag) { return mayConsume<edm::View<reco::BaseTagInfo>>(tag); });
96  if (discriminatorTags_.empty()) {
97  addDiscriminators_ = false;
98  } else {
99  for (std::vector<edm::InputTag>::const_iterator it = discriminatorTags_.begin(), ed = discriminatorTags_.end();
100  it != ed;
101  ++it) {
102  std::string label = it->label();
103  std::string::size_type pos = label.find("JetTags");
104  if ((pos != std::string::npos) && (pos != label.length() - 7)) {
105  label.erase(pos + 7); // trim a tail after "JetTags"
106  }
107  if (!it->instance().empty()) {
108  label = (label + std::string(":") + it->instance());
109  }
110  discriminatorLabels_.push_back(label);
111  }
112  }
113  if (tagInfoTags_.empty()) {
114  addTagInfos_ = false;
115  } else {
116  for (std::vector<edm::InputTag>::const_iterator it = tagInfoTags_.begin(), ed = tagInfoTags_.end(); it != ed;
117  ++it) {
118  std::string label = it->label();
119  std::string::size_type pos = label.find("TagInfos");
120  if ((pos != std::string::npos) && (pos != label.length() - 8)) {
121  label.erase(pos + 8); // trim a tail after "TagInfos"
122  }
123  tagInfoLabels_.push_back(label);
124  }
125  }
126  if (!addBTagInfo_) {
127  addDiscriminators_ = false;
128  addTagInfos_ = false;
129  }
130  // Check to see if the user wants to add user data
131  if (useUserData_) {
132  userDataHelper_ = PATUserDataHelper<Jet>(iConfig.getParameter<edm::ParameterSet>("userData"), consumesCollector());
133  }
134  // produces vector of jets
135  produces<std::vector<Jet>>();
136  produces<edm::OwnVector<reco::BaseTagInfo>>("tagInfos");
137 }
138 
140 
142  // Get the vector of jets
144  iEvent.getByToken(jetsToken_, jets);
145 
146  // read in the jet correction factors ValueMap
147  std::vector<edm::ValueMap<JetCorrFactors>> jetCorrs;
148  if (addJetCorrFactors_) {
149  for (size_t i = 0; i < jetCorrFactorsTokens_.size(); ++i) {
151  iEvent.getByToken(jetCorrFactorsTokens_[i], jetCorr);
152  jetCorrs.push_back(*jetCorr);
153  }
154  }
155 
156  // Get the vector of jet tags with b-tagging info
157  std::vector<edm::Handle<reco::JetFloatAssociation::Container>> jetDiscriminators;
159  jetDiscriminators.resize(discriminatorTokens_.size());
160  for (size_t i = 0; i < discriminatorTokens_.size(); ++i) {
161  iEvent.getByToken(discriminatorTokens_[i], jetDiscriminators[i]);
162  }
163  }
164  std::vector<edm::Handle<edm::View<reco::BaseTagInfo>>> jetTagInfos;
165  if (addBTagInfo_ && addTagInfos_) {
166  jetTagInfos.resize(tagInfoTokens_.size());
167  for (size_t i = 0; i < tagInfoTokens_.size(); ++i) {
168  iEvent.getByToken(tagInfoTokens_[i], jetTagInfos[i]);
169  }
170  }
171 
172  // loop over jets
173  auto patJets = std::make_unique<std::vector<Jet>>();
174 
175  auto tagInfosOut = std::make_unique<edm::OwnVector<reco::BaseTagInfo>>();
176 
178  iEvent.getRefBeforePut<edm::OwnVector<reco::BaseTagInfo>>("tagInfos");
179 
180  for (edm::View<reco::Jet>::const_iterator itJet = jets->begin(); itJet != jets->end(); itJet++) {
181  // construct the Jet from the ref -> save ref to original object
182  unsigned int idx = itJet - jets->begin();
183  const edm::RefToBase<reco::Jet> jetRef = jets->refAt(idx);
184  const edm::RefToBase<Jet> patJetRef(jetRef.castTo<JetRef>());
185  Jet ajet(patJetRef);
186 
187  if (addJetCorrFactors_) {
188  // undo previous jet energy corrections
189  ajet.setP4(ajet.correctedP4(0));
190  // clear previous JetCorrFactors
191  ajet.jec_.clear();
192  // add additional JetCorrs to the jet
193  for (unsigned int i = 0; i < jetCorrFactorsTokens_.size(); ++i) {
194  const JetCorrFactors& jcf = jetCorrs[i][jetRef];
195  // uncomment for debugging
196  // jcf.print();
197  ajet.addJECFactors(jcf);
198  }
199  std::vector<std::string> levels = jetCorrs[0][jetRef].correctionLabels();
200  if (std::find(levels.begin(), levels.end(), "L2L3Residual") != levels.end()) {
201  ajet.initializeJEC(jetCorrs[0][jetRef].jecLevel("L2L3Residual"));
202  } else if (std::find(levels.begin(), levels.end(), "L3Absolute") != levels.end()) {
203  ajet.initializeJEC(jetCorrs[0][jetRef].jecLevel("L3Absolute"));
204  } else {
205  ajet.initializeJEC(jetCorrs[0][jetRef].jecLevel("Uncorrected"));
206  if (printWarning_) {
207  edm::LogWarning("L3Absolute not found")
208  << "L2L3Residual and L3Absolute are not part of the jetCorrFactors\n"
209  << "of module " << jetCorrs[0][jetRef].jecSet() << ". Jets will remain"
210  << " uncorrected.";
211  printWarning_ = false;
212  }
213  }
214  }
215 
216  // add b-tag info if available & required
217  if (addBTagInfo_) {
218  if (addDiscriminators_) {
219  for (size_t k = 0; k < jetDiscriminators.size(); ++k) {
220  float value = (*jetDiscriminators[k])[jetRef];
221  ajet.addBDiscriminatorPair(std::make_pair(discriminatorLabels_[k], value));
222  }
223  }
224  if (addTagInfos_) {
225  for (size_t k = 0; k < jetTagInfos.size(); ++k) {
226  const edm::View<reco::BaseTagInfo>& taginfos = *jetTagInfos[k];
227  // This is not associative, so we have to search the jet
229  // Try first by 'same index'
230  if ((idx < taginfos.size()) && (taginfos[idx].jet() == jetRef)) {
231  match = taginfos.ptrAt(idx);
232  } else {
233  // otherwise fail back to a simple search
234  for (edm::View<reco::BaseTagInfo>::const_iterator itTI = taginfos.begin(), edTI = taginfos.end();
235  itTI != edTI;
236  ++itTI) {
237  if (itTI->jet() == jetRef) {
238  match = taginfos.ptrAt(itTI - taginfos.begin());
239  break;
240  }
241  }
242  }
243  if (match.isNonnull()) {
244  tagInfosOut->push_back(match->clone());
245  // set the "forward" ptr to the thinned collection
246  edm::Ptr<reco::BaseTagInfo> tagInfoForwardPtr(
247  h_tagInfosOut.id(), &tagInfosOut->back(), tagInfosOut->size() - 1);
248  // set the "backward" ptr to the original collection for association
249  const edm::Ptr<reco::BaseTagInfo>& tagInfoBackPtr(match);
250  // make FwdPtr
251  TagInfoFwdPtrCollection::value_type tagInfoFwdPtr(tagInfoForwardPtr, tagInfoBackPtr);
252  ajet.addTagInfo(tagInfoLabels_[k], tagInfoFwdPtr);
253  }
254  }
255  }
256  }
257 
258  if (useUserData_) {
259  userDataHelper_.add(ajet, iEvent, iSetup);
260  }
261 
262  // reassign the original object reference to preserve reference to the original jet the input PAT jet was derived from
263  // (this needs to be done at the end since cloning the input PAT jet would interfere with adding UserData)
264  ajet.refToOrig_ = patJetRef->originalObjectRef();
265 
266  patJets->push_back(ajet);
267  }
268 
269  // sort jets in pt
270  if (sort_) {
271  std::sort(patJets->begin(), patJets->end(), pTComparator_);
272  }
273 
274  // put genEvt in Event
275  iEvent.put(std::move(patJets));
276 
277  iEvent.put(std::move(tagInfosOut), "tagInfos");
278 }
279 
280 // ParameterSet description for module
283  iDesc.setComment("PAT jet producer module");
284 
285  // input source
286  iDesc.add<edm::InputTag>("jetSource", edm::InputTag("no default"))->setComment("input collection");
287 
288  // sort inputs (by pt)
289  iDesc.add<bool>("sort", true);
290 
291  // tag info
292  iDesc.add<bool>("addTagInfos", true);
293  std::vector<edm::InputTag> emptyVInputTags;
294  iDesc.add<std::vector<edm::InputTag>>("tagInfoSources", emptyVInputTags);
295 
296  // jet energy corrections
297  iDesc.add<bool>("addJetCorrFactors", true);
298  iDesc.add<std::vector<edm::InputTag>>("jetCorrFactorsSource", emptyVInputTags);
299 
300  // btag discriminator tags
301  iDesc.add<bool>("addBTagInfo", true);
302  iDesc.add<bool>("addDiscriminators", true);
303  iDesc.add<std::vector<edm::InputTag>>("discriminatorSources", emptyVInputTags);
304 
305  // silent warning if false
306  iDesc.add<bool>("printWarning", true);
307 
308  // Check to see if the user wants to add user data
309  edm::ParameterSetDescription userDataPSet;
311  iDesc.addOptional("userData", userDataPSet);
312 
313  descriptions.add("PATJetUpdater", iDesc);
314 }
315 
317 
void initializeJEC(unsigned int level, const JetCorrFactors::Flavor &flavor=JetCorrFactors::NONE, unsigned int set=0)
initialize the jet to a given JEC level during creation starting from Uncorrected ...
GreaterByPt< Jet > pTComparator_
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
ParameterDescriptionBase * addOptional(U const &iLabel, T const &value)
void addJECFactors(const JetCorrFactors &jec)
add more sets of energy correction factors
Definition: Jet.h:191
Ptr< value_type > ptrAt(size_type i) const
REF castTo() const
Definition: RefToBase.h:257
~PATJetUpdater() override
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
edm::EDGetTokenT< edm::View< reco::Jet > > jetsToken_
std::vector< edm::InputTag > tagInfoTags_
PATJetUpdater(const edm::ParameterSet &iConfig)
auto vector_transform(std::vector< InputType > const &input, Function predicate) -> std::vector< typename std::remove_cv< typename std::remove_reference< decltype(predicate(input.front()))>::type >::type >
Definition: transform.h:11
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
void addBDiscriminatorPair(const std::pair< std::string, float > &thePair)
method to add a algolabel-discriminator pair
uint16_t size_type
size_type size() const
Definition: HeavyIon.h:7
static void fillDescription(edm::ParameterSetDescription &iDesc)
char const * label
std::vector< edm::EDGetTokenT< edm::View< reco::BaseTagInfo > > > tagInfoTokens_
void setComment(std::string const &value)
std::vector< edm::EDGetTokenT< reco::JetFloatAssociation::Container > > discriminatorTokens_
int iEvent
Definition: GenABIO.cc:224
Definition: Jet.py:1
Produces pat::Jet&#39;s.
Class for the storage of jet correction factors.
std::vector< edm::InputTag > discriminatorTags_
Definition: value.py:1
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
void add(ObjectType &patObject, edm::Event const &iEvent, edm::EventSetup const &iSetup)
std::vector< pat::JetCorrFactors > jec_
Definition: Jet.h:622
std::vector< std::string > discriminatorLabels_
void add(std::string const &label, ParameterSetDescription const &psetDescription)
boost::indirect_iterator< typename seq_t::const_iterator > const_iterator
Definition: View.h:86
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
pat::PATUserDataHelper< pat::Jet > userDataHelper_
const_iterator begin() const
Log< level::Warning, false > LogWarning
std::vector< std::string > tagInfoLabels_
const LorentzVector correctedP4(const std::string &level, const std::string &flavor="none", const std::string &set="") const
Definition: Jet.h:164
void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override
std::vector< edm::EDGetTokenT< edm::ValueMap< JetCorrFactors > > > jetCorrFactorsTokens_
const_iterator end() const
edm::Ptr< reco::Candidate > refToOrig_
Definition: PATObject.h:458
void setP4(const LorentzVector &p4) final
set 4-momentum
def move(src, dest)
Definition: eostools.py:511
void addTagInfo(const std::string &label, const TagInfoFwdPtrCollection::value_type &info)