CMS 3D CMS Logo

TriggerObjectTableProducer.cc
Go to the documentation of this file.
1 // system include files
2 #include <memory>
3 #include <sstream>
4 
5 // user include files
8 
11 
14 
26 
28 public:
30  : name_(iConfig.getParameter<std::string>("name")),
31  src_(consumes<std::vector<pat::TriggerObjectStandAlone>>(iConfig.getParameter<edm::InputTag>("src"))),
32  l1EG_(consumes<l1t::EGammaBxCollection>(iConfig.getParameter<edm::InputTag>("l1EG"))),
33  l1Sum_(consumes<l1t::EtSumBxCollection>(iConfig.getParameter<edm::InputTag>("l1Sum"))),
34  l1Jet_(consumes<l1t::JetBxCollection>(iConfig.getParameter<edm::InputTag>("l1Jet"))),
35  l1Muon_(consumes<l1t::MuonBxCollection>(iConfig.getParameter<edm::InputTag>("l1Muon"))),
36  l1Tau_(consumes<l1t::TauBxCollection>(iConfig.getParameter<edm::InputTag>("l1Tau"))) {
37  edm::ParameterSet selPSet = iConfig.getParameter<edm::ParameterSet>("selections");
38  const auto selNames = selPSet.getParameterNames();
39  std::stringstream idstr, qualitystr;
40  idstr << "ID of the object: ";
41  for (const auto &name : selNames) {
42  sels_.emplace_back(selPSet.getParameter<edm::ParameterSet>(name));
43  const auto &sel = sels_.back();
44  idstr << sel.id << " = " << name + sel.doc;
45  if (sels_.size() < selNames.size())
46  idstr << ", ";
47  if (!sel.qualityBitsDoc.empty()) {
48  qualitystr << sel.qualityBitsDoc << " for " << name << "; ";
49  }
50  }
51  idDoc_ = idstr.str();
52  bitsDoc_ = qualitystr.str();
53 
54  produces<nanoaod::FlatTable>();
55  }
56 
58 
59  static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
60 
61 private:
62  void produce(edm::Event &, edm::EventSetup const &) override;
63 
67 
73 
74  struct SelectedObject {
76  int id;
79  float l1DR2, l1DR2_2, l2DR2;
83 
85  : doc(pset.getParameter<std::string>("doc")),
86  id(pset.getParameter<int>("id")),
87  cut(pset.getParameter<std::string>("sel")),
88  l1cut(""),
89  l1cut_2(""),
90  l2cut(""),
91  l1DR2(-1),
92  l1DR2_2(-1),
93  l2DR2(-1),
94  skipObjectsNotPassingQualityBits(pset.getParameter<bool>("skipObjectsNotPassingQualityBits")),
95  qualityBits("0"), //will be overwritten from configuration
96  qualityBitsDoc("") //will be created from configuration
97  {
98  if (!doc.empty()) {
99  doc = "(" + doc + ")";
100  }
101  std::vector<edm::ParameterSet> qualityBitsConfig =
102  pset.getParameter<std::vector<edm::ParameterSet>>("qualityBits");
103  std::stringstream qualityBitsFunc;
104  std::vector<bool> bits(qualityBitsConfig.size(), false);
105  for (size_t i = 0; i != qualityBitsConfig.size(); ++i) {
106  if (i != 0) {
107  qualityBitsFunc << " + ";
108  qualityBitsDoc += ", ";
109  }
110  unsigned int bit = i;
111  if (qualityBitsConfig[i].existsAs<unsigned int>("bit"))
112  bit = qualityBitsConfig[i].getParameter<unsigned int>("bit");
113  assert(!bits[bit] && "a quality bit was inserted twice"); // the bit should not have been set already
114  assert(bit < 31 && "quality bits are store on 32 bit");
115  bits[bit] = true;
116  qualityBitsFunc << std::to_string(int(pow(2, bit))) << "*("
117  << qualityBitsConfig[i].getParameter<std::string>("selection") << ")";
118  qualityBitsDoc += std::to_string(bit) + " => " + qualityBitsConfig[i].getParameter<std::string>("doc");
119  }
120  if (!qualityBitsFunc.str().empty()) {
121  //std::cout << "The quality bit string is :" << qualityBitsFunc.str() << std::endl;
122  //std::cout << "The quality bit documentation is :" << qualityBitsDoc << std::endl;
124  }
125  if (pset.existsAs<std::string>("l1seed")) {
127  l1DR2 = std::pow(pset.getParameter<double>("l1deltaR"), 2);
128  }
129  if (pset.existsAs<std::string>("l1seed_2")) {
131  l1DR2_2 = std::pow(pset.getParameter<double>("l1deltaR_2"), 2);
132  }
133  if (pset.existsAs<std::string>("l2seed")) {
135  l2DR2 = std::pow(pset.getParameter<double>("l2deltaR"), 2);
136  }
137  }
138 
139  bool match(const pat::TriggerObjectStandAlone &obj) const { return cut(obj); }
140  };
141 
142  std::vector<SelectedObject> sels_;
143 };
144 
145 // ------------ method called to produce the data ------------
147  const auto &trigObjs = iEvent.get(src_);
148 
149  std::vector<std::pair<const pat::TriggerObjectStandAlone *, const SelectedObject *>> selected;
150  std::map<int, std::map<const pat::TriggerObjectStandAlone *, int>> selected_bits;
151  for (const auto &obj : trigObjs) {
152  for (const auto &sel : sels_) {
153  if (sel.match(obj)) {
154  selected_bits[sel.id][&obj] = int(sel.qualityBits(obj));
155  if (sel.skipObjectsNotPassingQualityBits ? (selected_bits[sel.id][&obj] > 0) : true) {
156  selected.emplace_back(&obj, &sel);
157  }
158  }
159  }
160  }
161 
162  // Self-cleaning
163  for (unsigned int i = 0; i < selected.size(); ++i) {
164  const auto &obj = *selected[i].first;
165  const auto &sel = *selected[i].second;
166 
167  for (unsigned int j = 0; j < i; ++j) {
168  const auto &obj2 = *selected[j].first;
169  const auto &sel2 = *selected[j].second;
170  if (sel.id == sel2.id && abs(obj.pt() - obj2.pt()) < 1e-6 && deltaR2(obj, obj2) < 1e-6) {
171  selected_bits[sel.id][&obj2] |= selected_bits[sel.id][&obj]; //Keep filters from all the objects
172  selected.erase(selected.begin() + i);
173  i--;
174  }
175  }
176  }
177 
178  const auto &l1EG = iEvent.get(l1EG_);
179  const auto &l1Sum = iEvent.get(l1Sum_);
180  const auto &l1Jet = iEvent.get(l1Jet_);
181  const auto &l1Muon = iEvent.get(l1Muon_);
182  const auto &l1Tau = iEvent.get(l1Tau_);
183 
184  std::vector<pair<pat::TriggerObjectStandAlone, int>> l1Objects;
185  l1Objects.reserve(l1EG.size(0) + l1Sum.size(0) + l1Jet.size(0) + l1Muon.size(0) + l1Tau.size(0));
186 
187  // no range-based for because we want bx=0 only
188  for (l1t::EGammaBxCollection::const_iterator it = l1EG.begin(0); it != l1EG.end(0); it++) {
189  pat::TriggerObjectStandAlone l1obj(it->p4());
190  l1obj.setCollection("L1EG");
191  l1obj.addTriggerObjectType(trigger::TriggerL1EG);
192  l1Objects.emplace_back(l1obj, it->hwIso());
193  }
194 
195  for (l1t::EtSumBxCollection::const_iterator it = l1Sum.begin(0); it != l1Sum.end(0); it++) {
196  pat::TriggerObjectStandAlone l1obj(it->p4());
197 
198  switch (it->getType()) {
200  l1obj.addTriggerObjectType(trigger::TriggerL1ETM);
201  l1obj.setCollection("L1ETM");
202  break;
203 
205  l1obj.addTriggerObjectType(trigger::TriggerL1ETM);
206  l1obj.setCollection("L1ETMHF");
207  break;
208 
210  l1obj.addTriggerObjectType(trigger::TriggerL1ETT);
211  l1obj.setCollection("L1ETT");
212  break;
213 
215  l1obj.addTriggerObjectType(trigger::TriggerL1ETT);
216  l1obj.setCollection("L1ETEm");
217  break;
218 
220  l1obj.addTriggerObjectType(trigger::TriggerL1HTT);
221  l1obj.setCollection("L1HTT");
222  break;
223 
225  l1obj.addTriggerObjectType(trigger::TriggerL1HTT);
226  l1obj.setCollection("L1HTTHF");
227  break;
228 
230  l1obj.addTriggerObjectType(trigger::TriggerL1HTM);
231  l1obj.setCollection("L1HTM");
232  break;
233 
235  l1obj.addTriggerObjectType(trigger::TriggerL1HTM);
236  l1obj.setCollection("L1HTMHF");
237  break;
238 
239  default:
240  continue;
241  }
242 
243  l1Objects.emplace_back(l1obj, it->hwIso());
244  }
245 
246  for (l1t::JetBxCollection::const_iterator it = l1Jet.begin(0); it != l1Jet.end(0); it++) {
247  pat::TriggerObjectStandAlone l1obj(it->p4());
248  l1obj.setCollection("L1Jet");
249  l1obj.addTriggerObjectType(trigger::TriggerL1Jet);
250  l1Objects.emplace_back(l1obj, it->hwIso());
251  }
252 
253  for (l1t::MuonBxCollection::const_iterator it = l1Muon.begin(0); it != l1Muon.end(0); it++) {
254  pat::TriggerObjectStandAlone l1obj(it->p4());
255  l1obj.setCollection("L1Mu");
256  l1obj.addTriggerObjectType(trigger::TriggerL1Mu);
257  l1obj.setCharge(it->charge());
258  l1Objects.emplace_back(l1obj, it->hwIso());
259  }
260 
261  for (l1t::TauBxCollection::const_iterator it = l1Tau.begin(0); it != l1Tau.end(0); it++) {
262  pat::TriggerObjectStandAlone l1obj(it->p4());
263  l1obj.setCollection("L1Tau");
264  l1obj.addTriggerObjectType(trigger::TriggerL1Tau);
265  l1Objects.emplace_back(l1obj, it->hwIso());
266  }
267 
268  unsigned int nobj = selected.size();
269  std::vector<float> pt(nobj, 0), eta(nobj, 0), phi(nobj, 0), l1pt(nobj, 0), l1pt_2(nobj, 0), l2pt(nobj, 0);
270  std::vector<int16_t> l1charge(nobj, 0);
271  std::vector<uint16_t> id(nobj, 0);
272  std::vector<int> bits(nobj, 0), l1iso(nobj, 0);
273  for (unsigned int i = 0; i < nobj; ++i) {
274  const auto &obj = *selected[i].first;
275  const auto &sel = *selected[i].second;
276  pt[i] = obj.pt();
277  eta[i] = obj.eta();
278  phi[i] = obj.phi();
279  id[i] = sel.id;
280  bits[i] = selected_bits[sel.id][&obj];
281  if (sel.l1DR2 > 0) {
282  float best = sel.l1DR2;
283  for (const auto &l1obj : l1Objects) {
284  const auto &seed = l1obj.first;
285  float dr2 = deltaR2(seed, obj);
286  if (dr2 < best && sel.l1cut(seed)) {
287  best = dr2;
288  l1pt[i] = seed.pt();
289  l1iso[i] = l1obj.second;
290  l1charge[i] = seed.charge();
291  }
292  }
293  }
294  if (sel.l1DR2_2 > 0) {
295  float best = sel.l1DR2_2;
296  for (const auto &l1obj : l1Objects) {
297  const auto &seed = l1obj.first;
298  float dr2 = deltaR2(seed, obj);
299  if (dr2 < best && sel.l1cut_2(seed)) {
300  best = dr2;
301  l1pt_2[i] = seed.pt();
302  }
303  }
304  }
305  if (sel.l2DR2 > 0) {
306  float best = sel.l2DR2;
307  for (const auto &seed : trigObjs) {
308  float dr2 = deltaR2(seed, obj);
309  if (dr2 < best && sel.l2cut(seed)) {
310  best = dr2;
311  l2pt[i] = seed.pt();
312  }
313  }
314  }
315  }
316 
317  auto tab = std::make_unique<nanoaod::FlatTable>(nobj, name_, false, false);
318  tab->addColumn<uint16_t>("id", id, idDoc_);
319  tab->addColumn<float>("pt", pt, "pt", 12);
320  tab->addColumn<float>("eta", eta, "eta", 12);
321  tab->addColumn<float>("phi", phi, "phi", 12);
322  tab->addColumn<float>("l1pt", l1pt, "pt of associated L1 seed", 8);
323  tab->addColumn<int>("l1iso", l1iso, "iso of associated L1 seed");
324  tab->addColumn<int16_t>("l1charge", l1charge, "charge of associated L1 seed");
325  tab->addColumn<float>("l1pt_2", l1pt_2, "pt of associated secondary L1 seed", 8);
326  tab->addColumn<float>("l2pt", l2pt, "pt of associated 'L2' seed (i.e. HLT before tracking/PF)", 10);
327  tab->addColumn<int>("filterBits", bits, "extra bits of associated information: " + bitsDoc_);
328  iEvent.put(std::move(tab));
329 }
330 
333  desc.add<std::string>("name")->setComment("name of the flat table output");
334  desc.add<edm::InputTag>("src")->setComment("pat::TriggerObjectStandAlone input collection");
335  desc.add<edm::InputTag>("l1EG")->setComment("l1t::EGammaBxCollection input collection");
336  desc.add<edm::InputTag>("l1Sum")->setComment("l1t::EtSumBxCollection input collection");
337  desc.add<edm::InputTag>("l1Jet")->setComment("l1t::JetBxCollection input collection");
338  desc.add<edm::InputTag>("l1Muon")->setComment("l1t::MuonBxCollection input collection");
339  desc.add<edm::InputTag>("l1Tau")->setComment("l1t::TauBxCollection input collection");
340 
342  selection.setComment("a parameterset to define a trigger collection in flat table");
343  selection.add<std::string>("doc", "")->setComment(
344  "optional additional info to be added to the table doc for that object");
345  selection.add<int>("id")->setComment("identifier of the trigger collection in the flat table");
346  selection.add<std::string>("sel")->setComment("function to selection on pat::TriggerObjectStandAlone");
347  selection.add<bool>("skipObjectsNotPassingQualityBits")->setComment("flag to skip object on quality bit");
348 
350  bit.add<std::string>("selection")->setComment("function on pat::TriggerObjectStandAlone to define quality bit");
351  bit.add<std::string>("doc")->setComment("definition of the quality bit");
352  bit.addOptional<uint>("bit")->setComment("value of the bit, if not the order in the VPset");
353  bit.setComment("parameter set to define quality bit of matching object");
354  selection.addVPSet("qualityBits", bit);
355 
356  selection.ifExists(edm::ParameterDescription<std::string>("l1seed", "selection on pat::TriggerObjectStandAlone"),
358  "l1deltaR", "deltaR criteria to match pat::TriggerObjectStandAlone to L1 primitive"));
359  selection.ifExists(edm::ParameterDescription<std::string>("l1seed_2", "selection on pat::TriggerObjectStandAlone"),
361  "l1deltaR_2", "deltaR criteria to match pat::TriggerObjectStandAlone to L1 primitive"));
362  selection.ifExists(edm::ParameterDescription<std::string>("l2seed", "selection on pat::TriggerObjectStandAlone"),
364  "l2deltaR", "deltaR criteria to match pat::TriggerObjectStandAlone to 'L2' primitive"));
365 
368  selections.addNode(selectionsNode);
369  desc.add<edm::ParameterSetDescription>("selections", selections);
370 
371  descriptions.addWithDefaultLabel(desc);
372 }
373 
374 //define this as a plug-in
BXVector< EGamma > EGammaBxCollection
Definition: EGamma.h:10
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
enum start value shifted to 81 so as to avoid clashes with PDG codes
selection
main part
Definition: corrVsCorr.py:100
delete x;
Definition: CaloConfig.h:22
assert(be >=bs)
BXVector< Tau > TauBxCollection
Definition: Tau.h:10
static std::string to_string(const XMLCh *ch)
StringCutObjectSelector< pat::TriggerObjectStandAlone > l1cut
Definition: HeavyIon.h:7
edm::EDGetTokenT< l1t::JetBxCollection > l1Jet_
std::vector< T >::const_iterator const_iterator
Definition: BXVector.h:18
BXVector< EtSum > EtSumBxCollection
Definition: EtSum.h:10
TriggerObjectTableProducer(const edm::ParameterSet &iConfig)
int iEvent
Definition: GenABIO.cc:224
edm::EDGetTokenT< std::vector< pat::TriggerObjectStandAlone > > src_
void setCollection(const std::string &collName)
Methods.
Definition: TriggerObject.h:79
StringObjectFunction< pat::TriggerObjectStandAlone > qualityBits
edm::EDGetTokenT< l1t::MuonBxCollection > l1Muon_
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
bool match(const pat::TriggerObjectStandAlone &obj) const
BXVector< Muon > MuonBxCollection
Definition: Muon.h:11
BXVector< Jet > JetBxCollection
Definition: Jet.h:10
StringCutObjectSelector< pat::TriggerObjectStandAlone > l1cut_2
HLT enums.
edm::EDGetTokenT< l1t::TauBxCollection > l1Tau_
StringCutObjectSelector< pat::TriggerObjectStandAlone > cut
std::vector< SelectedObject > sels_
edm::EDGetTokenT< l1t::EGammaBxCollection > l1EG_
edm::EDGetTokenT< l1t::EtSumBxCollection > l1Sum_
void produce(edm::Event &, edm::EventSetup const &) override
std::vector< std::string > getParameterNames() const
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
def move(src, dest)
Definition: eostools.py:511
StringCutObjectSelector< pat::TriggerObjectStandAlone > l2cut
Analysis-level trigger object class (stand-alone)