File indexing completed on 2021-02-14 13:32:47
0001
0002 #include <memory>
0003 #include <sstream>
0004
0005
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
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
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];
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
0299 DEFINE_FWK_MODULE(TriggerObjectTableProducer);