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  std::vector<edm::ParameterSet> selPSets = iConfig.getParameter<std::vector<edm::ParameterSet>>("selections");
38  sels_.reserve(selPSets.size());
39  std::stringstream idstr, qualitystr;
40  idstr << "ID of the object: ";
41  for (auto &pset : selPSets) {
42  sels_.emplace_back(pset);
43  idstr << sels_.back().id << " = " << sels_.back().name;
44  if (sels_.size() < selPSets.size())
45  idstr << ", ";
46  if (!sels_.back().qualityBitsDoc.empty()) {
47  qualitystr << sels_.back().qualityBitsDoc << " for " << sels_.back().name << "; ";
48  }
49  }
50  idDoc_ = idstr.str();
51  bitsDoc_ = qualitystr.str();
52 
53  produces<nanoaod::FlatTable>();
54  }
55 
57 
58  static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
59 
60 private:
61  void produce(edm::Event &, edm::EventSetup const &) override;
62 
66 
72 
73  struct SelectedObject {
75  int id;
78  float l1DR2, l1DR2_2, l2DR2;
82 
84  : name(pset.getParameter<std::string>("name")),
85  id(pset.getParameter<int>("id")),
86  cut(pset.getParameter<std::string>("sel")),
87  l1cut(""),
88  l1cut_2(""),
89  l2cut(""),
90  l1DR2(-1),
91  l1DR2_2(-1),
92  l2DR2(-1),
93  skipObjectsNotPassingQualityBits(pset.getParameter<bool>("skipObjectsNotPassingQualityBits")),
94  qualityBits("0"), //will be overwritten from configuration
95  qualityBitsDoc("") //will be created from configuration
96  {
97  if (pset.existsAs<std::string>("qualityBits")) {
99  qualityBitsDoc = pset.getParameter<std::string>("qualityBitsDoc");
100  } else {
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  }
126  if (pset.existsAs<std::string>("l1seed")) {
128  l1DR2 = std::pow(pset.getParameter<double>("l1deltaR"), 2);
129  }
130  if (pset.existsAs<std::string>("l1seed_2")) {
132  l1DR2_2 = std::pow(pset.getParameter<double>("l1deltaR_2"), 2);
133  }
134  if (pset.existsAs<std::string>("l2seed")) {
136  l2DR2 = std::pow(pset.getParameter<double>("l2deltaR"), 2);
137  }
138  }
139 
140  bool match(const pat::TriggerObjectStandAlone &obj) const { return cut(obj); }
141  };
142 
143  std::vector<SelectedObject> sels_;
144 };
145 
146 // ------------ method called to produce the data ------------
148  const auto &trigObjs = iEvent.get(src_);
149 
150  std::vector<std::pair<const pat::TriggerObjectStandAlone *, const SelectedObject *>> selected;
151  std::map<int, std::map<const pat::TriggerObjectStandAlone *, int>> selected_bits;
152  for (const auto &obj : trigObjs) {
153  for (const auto &sel : sels_) {
154  if (sel.match(obj)) {
155  selected_bits[sel.id][&obj] = int(sel.qualityBits(obj));
156  if (sel.skipObjectsNotPassingQualityBits ? (selected_bits[sel.id][&obj] > 0) : true) {
157  selected.emplace_back(&obj, &sel);
158  }
159  }
160  }
161  }
162 
163  // Self-cleaning
164  for (unsigned int i = 0; i < selected.size(); ++i) {
165  const auto &obj = *selected[i].first;
166  const auto &sel = *selected[i].second;
167 
168  for (unsigned int j = 0; j < i; ++j) {
169  const auto &obj2 = *selected[j].first;
170  const auto &sel2 = *selected[j].second;
171  if (sel.id == sel2.id && abs(obj.pt() - obj2.pt()) < 1e-6 && deltaR2(obj, obj2) < 1e-6) {
172  selected_bits[sel.id][&obj2] |= selected_bits[sel.id][&obj]; //Keep filters from all the objects
173  selected.erase(selected.begin() + i);
174  i--;
175  }
176  }
177  }
178 
179  const auto &l1EG = iEvent.get(l1EG_);
180  const auto &l1Sum = iEvent.get(l1Sum_);
181  const auto &l1Jet = iEvent.get(l1Jet_);
182  const auto &l1Muon = iEvent.get(l1Muon_);
183  const auto &l1Tau = iEvent.get(l1Tau_);
184 
185  std::vector<pair<pat::TriggerObjectStandAlone, int>> l1Objects;
186  l1Objects.reserve(l1EG.size(0) + l1Sum.size(0) + l1Jet.size(0) + l1Muon.size(0) + l1Tau.size(0));
187 
188  // no range-based for because we want bx=0 only
189  for (l1t::EGammaBxCollection::const_iterator it = l1EG.begin(0); it != l1EG.end(0); it++) {
190  pat::TriggerObjectStandAlone l1obj(it->p4());
191  l1obj.setCollection("L1EG");
192  l1obj.addTriggerObjectType(trigger::TriggerL1EG);
193  l1Objects.emplace_back(l1obj, it->hwIso());
194  }
195 
196  for (l1t::EtSumBxCollection::const_iterator it = l1Sum.begin(0); it != l1Sum.end(0); it++) {
197  pat::TriggerObjectStandAlone l1obj(it->p4());
198 
199  switch (it->getType()) {
201  l1obj.addTriggerObjectType(trigger::TriggerL1ETM);
202  l1obj.setCollection("L1ETM");
203  break;
204 
206  l1obj.addTriggerObjectType(trigger::TriggerL1ETM);
207  l1obj.setCollection("L1ETMHF");
208  break;
209 
211  l1obj.addTriggerObjectType(trigger::TriggerL1ETT);
212  l1obj.setCollection("L1ETT");
213  break;
214 
216  l1obj.addTriggerObjectType(trigger::TriggerL1ETT);
217  l1obj.setCollection("L1ETEm");
218  break;
219 
221  l1obj.addTriggerObjectType(trigger::TriggerL1HTT);
222  l1obj.setCollection("L1HTT");
223  break;
224 
226  l1obj.addTriggerObjectType(trigger::TriggerL1HTT);
227  l1obj.setCollection("L1HTTHF");
228  break;
229 
231  l1obj.addTriggerObjectType(trigger::TriggerL1HTM);
232  l1obj.setCollection("L1HTM");
233  break;
234 
236  l1obj.addTriggerObjectType(trigger::TriggerL1HTM);
237  l1obj.setCollection("L1HTMHF");
238  break;
239 
240  default:
241  continue;
242  }
243 
244  l1Objects.emplace_back(l1obj, it->hwIso());
245  }
246 
247  for (l1t::JetBxCollection::const_iterator it = l1Jet.begin(0); it != l1Jet.end(0); it++) {
248  pat::TriggerObjectStandAlone l1obj(it->p4());
249  l1obj.setCollection("L1Jet");
250  l1obj.addTriggerObjectType(trigger::TriggerL1Jet);
251  l1Objects.emplace_back(l1obj, it->hwIso());
252  }
253 
254  for (l1t::MuonBxCollection::const_iterator it = l1Muon.begin(0); it != l1Muon.end(0); it++) {
255  pat::TriggerObjectStandAlone l1obj(it->p4());
256  l1obj.setCollection("L1Mu");
257  l1obj.addTriggerObjectType(trigger::TriggerL1Mu);
258  l1obj.setCharge(it->charge());
259  l1Objects.emplace_back(l1obj, it->hwIso());
260  }
261 
262  for (l1t::TauBxCollection::const_iterator it = l1Tau.begin(0); it != l1Tau.end(0); it++) {
263  pat::TriggerObjectStandAlone l1obj(it->p4());
264  l1obj.setCollection("L1Tau");
265  l1obj.addTriggerObjectType(trigger::TriggerL1Tau);
266  l1Objects.emplace_back(l1obj, it->hwIso());
267  }
268 
269  unsigned int nobj = selected.size();
270  std::vector<float> pt(nobj, 0), eta(nobj, 0), phi(nobj, 0), l1pt(nobj, 0), l1pt_2(nobj, 0), l2pt(nobj, 0);
271  std::vector<int> id(nobj, 0), bits(nobj, 0), l1iso(nobj, 0), l1charge(nobj, 0);
272  for (unsigned int i = 0; i < nobj; ++i) {
273  const auto &obj = *selected[i].first;
274  const auto &sel = *selected[i].second;
275  pt[i] = obj.pt();
276  eta[i] = obj.eta();
277  phi[i] = obj.phi();
278  id[i] = sel.id;
279  bits[i] = selected_bits[sel.id][&obj];
280  if (sel.l1DR2 > 0) {
281  float best = sel.l1DR2;
282  for (const auto &l1obj : l1Objects) {
283  const auto &seed = l1obj.first;
284  float dr2 = deltaR2(seed, obj);
285  if (dr2 < best && sel.l1cut(seed)) {
286  best = dr2;
287  l1pt[i] = seed.pt();
288  l1iso[i] = l1obj.second;
289  l1charge[i] = seed.charge();
290  }
291  }
292  }
293  if (sel.l1DR2_2 > 0) {
294  float best = sel.l1DR2_2;
295  for (const auto &l1obj : l1Objects) {
296  const auto &seed = l1obj.first;
297  float dr2 = deltaR2(seed, obj);
298  if (dr2 < best && sel.l1cut_2(seed)) {
299  best = dr2;
300  l1pt_2[i] = seed.pt();
301  }
302  }
303  }
304  if (sel.l2DR2 > 0) {
305  float best = sel.l2DR2;
306  for (const auto &seed : trigObjs) {
307  float dr2 = deltaR2(seed, obj);
308  if (dr2 < best && sel.l2cut(seed)) {
309  best = dr2;
310  l2pt[i] = seed.pt();
311  }
312  }
313  }
314  }
315 
316  auto tab = std::make_unique<nanoaod::FlatTable>(nobj, name_, false, false);
317  tab->addColumn<int>("id", id, idDoc_);
318  tab->addColumn<float>("pt", pt, "pt", 12);
319  tab->addColumn<float>("eta", eta, "eta", 12);
320  tab->addColumn<float>("phi", phi, "phi", 12);
321  tab->addColumn<float>("l1pt", l1pt, "pt of associated L1 seed", 8);
322  tab->addColumn<int>("l1iso", l1iso, "iso of associated L1 seed");
323  tab->addColumn<int>("l1charge", l1charge, "charge of associated L1 seed");
324  tab->addColumn<float>("l1pt_2", l1pt_2, "pt of associated secondary L1 seed", 8);
325  tab->addColumn<float>("l2pt", l2pt, "pt of associated 'L2' seed (i.e. HLT before tracking/PF)", 10);
326  tab->addColumn<int>("filterBits", bits, "extra bits of associated information: " + bitsDoc_);
327  iEvent.put(std::move(tab));
328 }
329 
332  desc.add<std::string>("name")->setComment("name of the flat table output");
333  desc.add<edm::InputTag>("src")->setComment("pat::TriggerObjectStandAlone input collection");
334  desc.add<edm::InputTag>("l1EG")->setComment("l1t::EGammaBxCollection input collection");
335  desc.add<edm::InputTag>("l1Sum")->setComment("l1t::EtSumBxCollection input collection");
336  desc.add<edm::InputTag>("l1Jet")->setComment("l1t::JetBxCollection input collection");
337  desc.add<edm::InputTag>("l1Muon")->setComment("l1t::MuonBxCollection input collection");
338  desc.add<edm::InputTag>("l1Tau")->setComment("l1t::TauBxCollection input collection");
339 
341  selection.setComment("a parameterset to define a trigger collection in flat table");
342  selection.add<std::string>("name")->setComment("name of the leaf in the flat table");
343  selection.add<int>("id")->setComment("identifier of the trigger collection in the flat table");
344  selection.add<std::string>("sel")->setComment("function to selection on pat::TriggerObjectStandAlone");
345  selection.add<bool>("skipObjectsNotPassingQualityBits")->setComment("flag to skip object on quality bit");
346 
348  "qualityBits", "0", true, edm::Comment("function on pat::TriggerObjectStandAlone to define quality bits"));
350  "qualityBitsDoc", "", true, edm::Comment("documentation of the quality bits"));
352  bit.add<std::string>("selection")->setComment("function on pat::TriggerObjectStandAlone to define quality bit");
353  bit.add<std::string>("doc")->setComment("definition of the quality bit");
354  bit.addOptional<uint>("bit")->setComment("value of the bit, if not the order in the VPset");
355  bit.setComment("parameter set to define quality bit of matching object");
356 
357  //selection.addVPSet("qualityBits", bit); // non-backqard compatible
359  "qualityBits", bit, true, std::vector<edm::ParameterSet>());
360  //allow for backward compatible configuration with qualityBits and qualityBitsDoc as strings
361  selection.addNode(bits xor (oldSelection and oldDoc));
362 
363  selection.ifExists(edm::ParameterDescription<std::string>("l1seed", "selection on pat::TriggerObjectStandAlone"),
365  "l1deltaR", "deltaR criteria to match pat::TriggerObjectStandAlone to L1 primitive"));
366  selection.ifExists(edm::ParameterDescription<std::string>("l1seed_2", "selection on pat::TriggerObjectStandAlone"),
368  "l1deltaR_2", "deltaR criteria to match pat::TriggerObjectStandAlone to L1 primitive"));
369  selection.ifExists(edm::ParameterDescription<std::string>("l2seed", "selection on pat::TriggerObjectStandAlone"),
371  "l2deltaR", "deltaR criteria to match pat::TriggerObjectStandAlone to 'L2' primitive"));
372  desc.addVPSet("selections", selection);
373 
374  descriptions.addWithDefaultLabel(desc);
375 }
376 
377 //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:303
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
constexpr uint32_t bits
Definition: gpuClustering.h:23
std::string to_string(const V &value)
Definition: OMSAccess.h:71
delete x;
Definition: CaloConfig.h:22
assert(be >=bs)
BXVector< Tau > TauBxCollection
Definition: Tau.h:10
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
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)