Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:32:47

0001 // system include files
0002 #include <memory>
0003 #include <sstream>
0004 
0005 // user include files
0006 #include "FWCore/Framework/interface/Frameworkfwd.h"
0007 #include "FWCore/Framework/interface/stream/EDProducer.h"
0008 
0009 #include "FWCore/Framework/interface/Event.h"
0010 #include "FWCore/Framework/interface/MakerMacros.h"
0011 
0012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0013 #include "FWCore/Utilities/interface/StreamID.h"
0014 
0015 #include "DataFormats/PatCandidates/interface/TriggerObjectStandAlone.h"
0016 #include "DataFormats/L1Trigger/interface/EGamma.h"
0017 #include "DataFormats/L1Trigger/interface/Tau.h"
0018 #include "DataFormats/L1Trigger/interface/Jet.h"
0019 #include "DataFormats/L1Trigger/interface/Muon.h"
0020 #include "DataFormats/L1Trigger/interface/EtSum.h"
0021 #include "DataFormats/HLTReco/interface/TriggerTypeDefs.h"
0022 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
0023 #include "CommonTools/Utils/interface/StringObjectFunction.h"
0024 #include "DataFormats/Math/interface/deltaR.h"
0025 #include "DataFormats/NanoAOD/interface/FlatTable.h"
0026 
0027 class TriggerObjectTableProducer : public edm::stream::EDProducer<> {
0028 public:
0029   explicit TriggerObjectTableProducer(const edm::ParameterSet &iConfig)
0030       : name_(iConfig.getParameter<std::string>("name")),
0031         src_(consumes<std::vector<pat::TriggerObjectStandAlone>>(iConfig.getParameter<edm::InputTag>("src"))),
0032         l1EG_(consumes<l1t::EGammaBxCollection>(iConfig.getParameter<edm::InputTag>("l1EG"))),
0033         l1Sum_(consumes<l1t::EtSumBxCollection>(iConfig.getParameter<edm::InputTag>("l1Sum"))),
0034         l1Jet_(consumes<l1t::JetBxCollection>(iConfig.getParameter<edm::InputTag>("l1Jet"))),
0035         l1Muon_(consumes<l1t::MuonBxCollection>(iConfig.getParameter<edm::InputTag>("l1Muon"))),
0036         l1Tau_(consumes<l1t::TauBxCollection>(iConfig.getParameter<edm::InputTag>("l1Tau"))) {
0037     std::vector<edm::ParameterSet> selPSets = iConfig.getParameter<std::vector<edm::ParameterSet>>("selections");
0038     sels_.reserve(selPSets.size());
0039     std::stringstream idstr, qualitystr;
0040     idstr << "ID of the object: ";
0041     for (auto &pset : selPSets) {
0042       sels_.emplace_back(pset);
0043       idstr << sels_.back().id << " = " << sels_.back().name;
0044       if (sels_.size() < selPSets.size())
0045         idstr << ", ";
0046       if (!sels_.back().qualityBitsDoc.empty()) {
0047         qualitystr << sels_.back().qualityBitsDoc << " for " << sels_.back().name << "; ";
0048       }
0049     }
0050     idDoc_ = idstr.str();
0051     bitsDoc_ = qualitystr.str();
0052 
0053     produces<nanoaod::FlatTable>();
0054   }
0055 
0056   ~TriggerObjectTableProducer() override {}
0057 
0058 private:
0059   void produce(edm::Event &, edm::EventSetup const &) override;
0060 
0061   std::string name_;
0062   edm::EDGetTokenT<std::vector<pat::TriggerObjectStandAlone>> src_;
0063   std::string idDoc_, bitsDoc_;
0064 
0065   edm::EDGetTokenT<l1t::EGammaBxCollection> l1EG_;
0066   edm::EDGetTokenT<l1t::EtSumBxCollection> l1Sum_;
0067   edm::EDGetTokenT<l1t::JetBxCollection> l1Jet_;
0068   edm::EDGetTokenT<l1t::MuonBxCollection> l1Muon_;
0069   edm::EDGetTokenT<l1t::TauBxCollection> l1Tau_;
0070 
0071   struct SelectedObject {
0072     std::string name;
0073     int id;
0074     StringCutObjectSelector<pat::TriggerObjectStandAlone> cut;
0075     StringCutObjectSelector<pat::TriggerObjectStandAlone> l1cut, l1cut_2, l2cut;
0076     float l1DR2, l1DR2_2, l2DR2;
0077     bool skipObjectsNotPassingQualityBits;
0078     StringObjectFunction<pat::TriggerObjectStandAlone> qualityBits;
0079     std::string qualityBitsDoc;
0080 
0081     SelectedObject(const edm::ParameterSet &pset)
0082         : name(pset.getParameter<std::string>("name")),
0083           id(pset.getParameter<int>("id")),
0084           cut(pset.getParameter<std::string>("sel")),
0085           l1cut(""),
0086           l1cut_2(""),
0087           l2cut(""),
0088           l1DR2(-1),
0089           l1DR2_2(-1),
0090           l2DR2(-1),
0091           skipObjectsNotPassingQualityBits(pset.getParameter<bool>("skipObjectsNotPassingQualityBits")),
0092           qualityBits(pset.getParameter<std::string>("qualityBits")),
0093           qualityBitsDoc(pset.getParameter<std::string>("qualityBitsDoc")) {
0094       if (pset.existsAs<std::string>("l1seed")) {
0095         l1cut = StringCutObjectSelector<pat::TriggerObjectStandAlone>(pset.getParameter<std::string>("l1seed"));
0096         l1DR2 = std::pow(pset.getParameter<double>("l1deltaR"), 2);
0097       }
0098       if (pset.existsAs<std::string>("l1seed_2")) {
0099         l1cut_2 = StringCutObjectSelector<pat::TriggerObjectStandAlone>(pset.getParameter<std::string>("l1seed_2"));
0100         l1DR2_2 = std::pow(pset.getParameter<double>("l1deltaR_2"), 2);
0101       }
0102       if (pset.existsAs<std::string>("l2seed")) {
0103         l2cut = StringCutObjectSelector<pat::TriggerObjectStandAlone>(pset.getParameter<std::string>("l2seed"));
0104         l2DR2 = std::pow(pset.getParameter<double>("l2deltaR"), 2);
0105       }
0106     }
0107 
0108     bool match(const pat::TriggerObjectStandAlone &obj) const { return cut(obj); }
0109   };
0110 
0111   std::vector<SelectedObject> sels_;
0112 };
0113 
0114 // ------------ method called to produce the data  ------------
0115 void TriggerObjectTableProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
0116   edm::Handle<std::vector<pat::TriggerObjectStandAlone>> src;
0117   iEvent.getByToken(src_, src);
0118 
0119   std::vector<std::pair<const pat::TriggerObjectStandAlone *, const SelectedObject *>> selected;
0120   for (const auto &obj : *src) {
0121     for (const auto &sel : sels_) {
0122       if (sel.match(obj) && (sel.skipObjectsNotPassingQualityBits ? (int(sel.qualityBits(obj)) > 0) : true)) {
0123         selected.emplace_back(&obj, &sel);
0124         break;
0125       }
0126     }
0127   }
0128 
0129   // Self-cleaning
0130   std::map<const pat::TriggerObjectStandAlone *, int> selected_bits;
0131   for (unsigned int i = 0; i < selected.size(); ++i) {
0132     const auto &obj = *selected[i].first;
0133     const auto &sel = *selected[i].second;
0134     selected_bits[&obj] = int(sel.qualityBits(obj));
0135 
0136     for (unsigned int j = 0; j < i; ++j) {
0137       const auto &obj2 = *selected[j].first;
0138       const auto &sel2 = *selected[j].second;
0139       if (sel.id == sel2.id && abs(obj.pt() - obj2.pt()) < 1e-6 && deltaR2(obj, obj2) < 1e-6) {
0140         selected_bits[&obj2] |= selected_bits[&obj];  //Keep filters from all the objects
0141         selected.erase(selected.begin() + i);
0142         i--;
0143       }
0144     }
0145   }
0146 
0147   edm::Handle<l1t::EGammaBxCollection> l1EG;
0148   edm::Handle<l1t::EtSumBxCollection> l1Sum;
0149   edm::Handle<l1t::JetBxCollection> l1Jet;
0150   edm::Handle<l1t::MuonBxCollection> l1Muon;
0151   edm::Handle<l1t::TauBxCollection> l1Tau;
0152   iEvent.getByToken(l1EG_, l1EG);
0153   iEvent.getByToken(l1Sum_, l1Sum);
0154   iEvent.getByToken(l1Jet_, l1Jet);
0155   iEvent.getByToken(l1Muon_, l1Muon);
0156   iEvent.getByToken(l1Tau_, l1Tau);
0157 
0158   std::vector<pair<pat::TriggerObjectStandAlone, int>> l1Objects;
0159 
0160   for (l1t::EGammaBxCollection::const_iterator it = l1EG->begin(0); it != l1EG->end(0); it++) {
0161     pat::TriggerObjectStandAlone l1obj(it->p4());
0162     l1obj.setCollection("L1EG");
0163     l1obj.addTriggerObjectType(trigger::TriggerL1EG);
0164     l1Objects.emplace_back(l1obj, it->hwIso());
0165   }
0166 
0167   for (l1t::EtSumBxCollection::const_iterator it = l1Sum->begin(0); it != l1Sum->end(0); it++) {
0168     pat::TriggerObjectStandAlone l1obj(it->p4());
0169 
0170     switch (it->getType()) {
0171       case l1t::EtSum::EtSumType::kMissingEt:
0172         l1obj.addTriggerObjectType(trigger::TriggerL1ETM);
0173         l1obj.setCollection("L1ETM");
0174         break;
0175 
0176       case l1t::EtSum::EtSumType::kMissingEtHF:
0177         l1obj.addTriggerObjectType(trigger::TriggerL1ETM);
0178         l1obj.setCollection("L1ETMHF");
0179         break;
0180 
0181       case l1t::EtSum::EtSumType::kTotalEt:
0182         l1obj.addTriggerObjectType(trigger::TriggerL1ETT);
0183         l1obj.setCollection("L1ETT");
0184         break;
0185 
0186       case l1t::EtSum::EtSumType::kTotalEtEm:
0187         l1obj.addTriggerObjectType(trigger::TriggerL1ETT);
0188         l1obj.setCollection("L1ETEm");
0189         break;
0190 
0191       case l1t::EtSum::EtSumType::kTotalHt:
0192         l1obj.addTriggerObjectType(trigger::TriggerL1HTT);
0193         l1obj.setCollection("L1HTT");
0194         break;
0195 
0196       case l1t::EtSum::EtSumType::kTotalHtHF:
0197         l1obj.addTriggerObjectType(trigger::TriggerL1HTT);
0198         l1obj.setCollection("L1HTTHF");
0199         break;
0200 
0201       case l1t::EtSum::EtSumType::kMissingHt:
0202         l1obj.addTriggerObjectType(trigger::TriggerL1HTM);
0203         l1obj.setCollection("L1HTM");
0204         break;
0205 
0206       case l1t::EtSum::EtSumType::kMissingHtHF:
0207         l1obj.addTriggerObjectType(trigger::TriggerL1HTM);
0208         l1obj.setCollection("L1HTMHF");
0209         break;
0210 
0211       default:
0212         continue;
0213     }
0214 
0215     l1Objects.emplace_back(l1obj, it->hwIso());
0216   }
0217 
0218   for (l1t::JetBxCollection::const_iterator it = l1Jet->begin(0); it != l1Jet->end(0); it++) {
0219     pat::TriggerObjectStandAlone l1obj(it->p4());
0220     l1obj.setCollection("L1Jet");
0221     l1obj.addTriggerObjectType(trigger::TriggerL1Jet);
0222     l1Objects.emplace_back(l1obj, it->hwIso());
0223   }
0224 
0225   for (l1t::MuonBxCollection::const_iterator it = l1Muon->begin(0); it != l1Muon->end(0); it++) {
0226     pat::TriggerObjectStandAlone l1obj(it->p4());
0227     l1obj.setCollection("L1Mu");
0228     l1obj.addTriggerObjectType(trigger::TriggerL1Mu);
0229     l1obj.setCharge(it->charge());
0230     l1Objects.emplace_back(l1obj, it->hwIso());
0231   }
0232 
0233   for (l1t::TauBxCollection::const_iterator it = l1Tau->begin(0); it != l1Tau->end(0); it++) {
0234     pat::TriggerObjectStandAlone l1obj(it->p4());
0235     l1obj.setCollection("L1Tau");
0236     l1obj.addTriggerObjectType(trigger::TriggerL1Tau);
0237     l1Objects.emplace_back(l1obj, it->hwIso());
0238   }
0239 
0240   unsigned int nobj = selected.size();
0241   std::vector<float> pt(nobj, 0), eta(nobj, 0), phi(nobj, 0), l1pt(nobj, 0), l1pt_2(nobj, 0), l2pt(nobj, 0);
0242   std::vector<int> id(nobj, 0), bits(nobj, 0), l1iso(nobj, 0), l1charge(nobj, 0);
0243   for (unsigned int i = 0; i < nobj; ++i) {
0244     const auto &obj = *selected[i].first;
0245     const auto &sel = *selected[i].second;
0246     pt[i] = obj.pt();
0247     eta[i] = obj.eta();
0248     phi[i] = obj.phi();
0249     id[i] = sel.id;
0250     bits[i] = selected_bits[&obj];
0251     if (sel.l1DR2 > 0) {
0252       float best = sel.l1DR2;
0253       for (const auto &l1obj : l1Objects) {
0254         const auto &seed = l1obj.first;
0255         float dr2 = deltaR2(seed, obj);
0256         if (dr2 < best && sel.l1cut(seed)) {
0257           l1pt[i] = seed.pt();
0258           l1iso[i] = l1obj.second;
0259           l1charge[i] = seed.charge();
0260         }
0261       }
0262     }
0263     if (sel.l1DR2_2 > 0) {
0264       float best = sel.l1DR2_2;
0265       for (const auto &l1obj : l1Objects) {
0266         const auto &seed = l1obj.first;
0267         float dr2 = deltaR2(seed, obj);
0268         if (dr2 < best && sel.l1cut_2(seed)) {
0269           l1pt_2[i] = seed.pt();
0270         }
0271       }
0272     }
0273     if (sel.l2DR2 > 0) {
0274       float best = sel.l2DR2;
0275       for (const auto &seed : *src) {
0276         float dr2 = deltaR2(seed, obj);
0277         if (dr2 < best && sel.l2cut(seed)) {
0278           l2pt[i] = seed.pt();
0279         }
0280       }
0281     }
0282   }
0283 
0284   auto tab = std::make_unique<nanoaod::FlatTable>(nobj, name_, false, false);
0285   tab->addColumn<int>("id", id, idDoc_);
0286   tab->addColumn<float>("pt", pt, "pt", 12);
0287   tab->addColumn<float>("eta", eta, "eta", 12);
0288   tab->addColumn<float>("phi", phi, "phi", 12);
0289   tab->addColumn<float>("l1pt", l1pt, "pt of associated L1 seed", 8);
0290   tab->addColumn<int>("l1iso", l1iso, "iso of associated L1 seed");
0291   tab->addColumn<int>("l1charge", l1charge, "charge of associated L1 seed");
0292   tab->addColumn<float>("l1pt_2", l1pt_2, "pt of associated secondary L1 seed", 8);
0293   tab->addColumn<float>("l2pt", l2pt, "pt of associated 'L2' seed (i.e. HLT before tracking/PF)", 10);
0294   tab->addColumn<int>("filterBits", bits, "extra bits of associated information: " + bitsDoc_);
0295   iEvent.put(std::move(tab));
0296 }
0297 
0298 //define this as a plug-in
0299 DEFINE_FWK_MODULE(TriggerObjectTableProducer);