File indexing completed on 2025-03-05 03:16:38
0001 #include "FWCore/Framework/interface/Event.h"
0002 #include "FWCore/Framework/interface/global/EDFilter.h"
0003 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0004 #include "DataFormats/L1Trigger/interface/P2GTCandidate.h"
0005 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0006
0007 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0008 #include "DataFormats/Common/interface/Handle.h"
0009 #include "FWCore/Utilities/interface/EDGetToken.h"
0010 #include "DataFormats/Common/interface/Ref.h"
0011 #include "FWCore/Framework/interface/MakerMacros.h"
0012
0013 #include "L1Trigger/Phase2L1GT/interface/L1GTScales.h"
0014 #include "L1GTSingleCollectionCut.h"
0015 #include "L1GTCorrelationalCut.h"
0016 #include "L1GT3BodyCut.h"
0017 #include "L1GTSingleInOutLUT.h"
0018 #include "L1GTOptionalParam.h"
0019
0020 #include <cinttypes>
0021 #include <memory>
0022 #include <vector>
0023 #include <set>
0024
0025 #include <ap_int.h>
0026
0027 using namespace l1t;
0028
0029 class L1GTQuadObjectCond : public edm::global::EDFilter<> {
0030 public:
0031 explicit L1GTQuadObjectCond(const edm::ParameterSet&);
0032 ~L1GTQuadObjectCond() override = default;
0033
0034 static void fillDescriptions(edm::ConfigurationDescriptions&);
0035
0036 private:
0037 bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override;
0038
0039 const L1GTScales scales_;
0040
0041 const L1GTSingleCollectionCut collection1Cuts_;
0042 const L1GTSingleCollectionCut collection2Cuts_;
0043 const L1GTSingleCollectionCut collection3Cuts_;
0044 const L1GTSingleCollectionCut collection4Cuts_;
0045
0046 const bool enable_sanity_checks_;
0047 const bool inv_mass_checks_;
0048
0049 const L1GTCorrelationalCut correl12Cuts_;
0050 const L1GTCorrelationalCut correl13Cuts_;
0051 const L1GTCorrelationalCut correl23Cuts_;
0052 const L1GTCorrelationalCut correl14Cuts_;
0053 const L1GTCorrelationalCut correl24Cuts_;
0054 const L1GTCorrelationalCut correl34Cuts_;
0055
0056 const L1GT3BodyCut correl123Cuts_;
0057 const L1GT3BodyCut correl124Cuts_;
0058 const L1GT3BodyCut correl134Cuts_;
0059 const L1GT3BodyCut correl234Cuts_;
0060
0061 const std::optional<unsigned int> minQualityScoreSum_;
0062 const std::optional<unsigned int> maxQualityScoreSum_;
0063
0064 const edm::EDGetTokenT<P2GTCandidateCollection> token1_;
0065 const edm::EDGetTokenT<P2GTCandidateCollection> token2_;
0066 const edm::EDGetTokenT<P2GTCandidateCollection> token3_;
0067 const edm::EDGetTokenT<P2GTCandidateCollection> token4_;
0068 const edm::EDGetTokenT<P2GTCandidateCollection> primVertToken_;
0069 };
0070
0071 L1GTQuadObjectCond::L1GTQuadObjectCond(const edm::ParameterSet& config)
0072 : scales_(config.getParameter<edm::ParameterSet>("scales")),
0073 collection1Cuts_(config.getParameter<edm::ParameterSet>("collection1"), config, scales_),
0074 collection2Cuts_(config.getParameter<edm::ParameterSet>("collection2"), config, scales_),
0075 collection3Cuts_(config.getParameter<edm::ParameterSet>("collection3"), config, scales_),
0076 collection4Cuts_(config.getParameter<edm::ParameterSet>("collection4"), config, scales_),
0077 enable_sanity_checks_(config.getUntrackedParameter<bool>("sanity_checks")),
0078 inv_mass_checks_(config.getUntrackedParameter<bool>("inv_mass_checks")),
0079 correl12Cuts_(
0080 config.getParameter<edm::ParameterSet>("correl12"), config, scales_, enable_sanity_checks_, inv_mass_checks_),
0081 correl13Cuts_(
0082 config.getParameter<edm::ParameterSet>("correl13"), config, scales_, enable_sanity_checks_, inv_mass_checks_),
0083 correl23Cuts_(
0084 config.getParameter<edm::ParameterSet>("correl23"), config, scales_, enable_sanity_checks_, inv_mass_checks_),
0085 correl14Cuts_(
0086 config.getParameter<edm::ParameterSet>("correl14"), config, scales_, enable_sanity_checks_, inv_mass_checks_),
0087 correl24Cuts_(
0088 config.getParameter<edm::ParameterSet>("correl24"), config, scales_, enable_sanity_checks_, inv_mass_checks_),
0089 correl34Cuts_(
0090 config.getParameter<edm::ParameterSet>("correl34"), config, scales_, enable_sanity_checks_, inv_mass_checks_),
0091 correl123Cuts_(config.getParameter<edm::ParameterSet>("correl123"), config, scales_, inv_mass_checks_),
0092 correl124Cuts_(config.getParameter<edm::ParameterSet>("correl124"), config, scales_, inv_mass_checks_),
0093 correl134Cuts_(config.getParameter<edm::ParameterSet>("correl134"), config, scales_, inv_mass_checks_),
0094 correl234Cuts_(config.getParameter<edm::ParameterSet>("correl234"), config, scales_, inv_mass_checks_),
0095 minQualityScoreSum_(getOptionalParam<unsigned int>("minQualityScoreSum", config)),
0096 maxQualityScoreSum_(getOptionalParam<unsigned int>("maxQualityScoreSum", config)),
0097 token1_(consumes<P2GTCandidateCollection>(collection1Cuts_.tag())),
0098 token2_(collection1Cuts_.tag() == collection2Cuts_.tag()
0099 ? token1_
0100 : consumes<P2GTCandidateCollection>(collection2Cuts_.tag())),
0101 token3_(collection1Cuts_.tag() == collection3Cuts_.tag()
0102 ? token1_
0103 : (collection2Cuts_.tag() == collection3Cuts_.tag()
0104 ? token2_
0105 : consumes<P2GTCandidateCollection>(collection3Cuts_.tag()))),
0106 token4_(collection1Cuts_.tag() == collection4Cuts_.tag()
0107 ? token1_
0108 : (collection2Cuts_.tag() == collection4Cuts_.tag()
0109 ? token2_
0110 : (collection3Cuts_.tag() == collection4Cuts_.tag()
0111 ? token3_
0112 : consumes<P2GTCandidateCollection>(collection4Cuts_.tag())))),
0113 primVertToken_(consumes<P2GTCandidateCollection>(config.getParameter<edm::InputTag>("primVertTag"))) {
0114 produces<P2GTCandidateVectorRef>(collection1Cuts_.tag().instance());
0115
0116 if (!(collection1Cuts_.tag() == collection2Cuts_.tag())) {
0117 produces<P2GTCandidateVectorRef>(collection2Cuts_.tag().instance());
0118 }
0119
0120 if (!(collection1Cuts_.tag() == collection3Cuts_.tag()) && !(collection2Cuts_.tag() == collection3Cuts_.tag())) {
0121 produces<P2GTCandidateVectorRef>(collection3Cuts_.tag().instance());
0122 }
0123
0124 if (!(collection1Cuts_.tag() == collection4Cuts_.tag()) && !(collection2Cuts_.tag() == collection4Cuts_.tag()) &&
0125 !(collection3Cuts_.tag() == collection4Cuts_.tag())) {
0126 produces<P2GTCandidateVectorRef>(collection4Cuts_.tag().instance());
0127 }
0128
0129 if (inv_mass_checks_) {
0130 produces<InvariantMassErrorCollection>();
0131 }
0132
0133 if ((minQualityScoreSum_ || maxQualityScoreSum_) &&
0134 !(collection1Cuts_.tag() == collection2Cuts_.tag() && collection2Cuts_.tag() == collection3Cuts_.tag() &&
0135 collection3Cuts_.tag() == collection4Cuts_.tag())) {
0136 throw cms::Exception("Configuration") << "A qualityScore sum can only be calculated within one collection.";
0137 }
0138 }
0139
0140 void L1GTQuadObjectCond::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0141 edm::ParameterSetDescription desc;
0142
0143 edm::ParameterSetDescription collection1Desc;
0144 L1GTSingleCollectionCut::fillPSetDescription(collection1Desc);
0145 desc.add<edm::ParameterSetDescription>("collection1", collection1Desc);
0146
0147 edm::ParameterSetDescription collection2Desc;
0148 L1GTSingleCollectionCut::fillPSetDescription(collection2Desc);
0149 desc.add<edm::ParameterSetDescription>("collection2", collection2Desc);
0150
0151 edm::ParameterSetDescription collection3Desc;
0152 L1GTSingleCollectionCut::fillPSetDescription(collection3Desc);
0153 desc.add<edm::ParameterSetDescription>("collection3", collection3Desc);
0154
0155 edm::ParameterSetDescription collection4Desc;
0156 L1GTSingleCollectionCut::fillPSetDescription(collection4Desc);
0157 desc.add<edm::ParameterSetDescription>("collection4", collection4Desc);
0158
0159 edm::ParameterSetDescription scalesDesc;
0160 L1GTScales::fillPSetDescription(scalesDesc);
0161 desc.add<edm::ParameterSetDescription>("scales", scalesDesc);
0162
0163 desc.add<edm::InputTag>("primVertTag");
0164
0165 desc.addUntracked<bool>("sanity_checks", false);
0166 desc.addUntracked<bool>("inv_mass_checks", false);
0167
0168 edm::ParameterSetDescription correl12Desc;
0169 L1GTCorrelationalCut::fillPSetDescription(correl12Desc);
0170 desc.add<edm::ParameterSetDescription>("correl12", correl12Desc);
0171
0172 edm::ParameterSetDescription correl13Desc;
0173 L1GTCorrelationalCut::fillPSetDescription(correl13Desc);
0174 desc.add<edm::ParameterSetDescription>("correl13", correl13Desc);
0175
0176 edm::ParameterSetDescription correl23Desc;
0177 L1GTCorrelationalCut::fillPSetDescription(correl23Desc);
0178 desc.add<edm::ParameterSetDescription>("correl23", correl23Desc);
0179
0180 edm::ParameterSetDescription correl14Desc;
0181 L1GTCorrelationalCut::fillPSetDescription(correl14Desc);
0182 desc.add<edm::ParameterSetDescription>("correl14", correl14Desc);
0183
0184 edm::ParameterSetDescription correl24Desc;
0185 L1GTCorrelationalCut::fillPSetDescription(correl24Desc);
0186 desc.add<edm::ParameterSetDescription>("correl24", correl24Desc);
0187
0188 edm::ParameterSetDescription correl34Desc;
0189 L1GTCorrelationalCut::fillPSetDescription(correl34Desc);
0190 desc.add<edm::ParameterSetDescription>("correl34", correl34Desc);
0191
0192 edm::ParameterSetDescription correl123Desc;
0193 L1GT3BodyCut::fillPSetDescription(correl123Desc);
0194 desc.add<edm::ParameterSetDescription>("correl123", correl123Desc);
0195
0196 edm::ParameterSetDescription correl124Desc;
0197 L1GT3BodyCut::fillPSetDescription(correl124Desc);
0198 desc.add<edm::ParameterSetDescription>("correl124", correl124Desc);
0199
0200 edm::ParameterSetDescription correl134Desc;
0201 L1GT3BodyCut::fillPSetDescription(correl134Desc);
0202 desc.add<edm::ParameterSetDescription>("correl134", correl134Desc);
0203
0204 edm::ParameterSetDescription correl234Desc;
0205 L1GT3BodyCut::fillPSetDescription(correl234Desc);
0206 desc.add<edm::ParameterSetDescription>("correl234", correl234Desc);
0207
0208 desc.addOptional<unsigned int>("minQualityScoreSum");
0209 desc.addOptional<unsigned int>("maxQualityScoreSum");
0210
0211 L1GTCorrelationalCut::fillLUTDescriptions(desc);
0212
0213 descriptions.addWithDefaultLabel(desc);
0214 }
0215
0216 bool L1GTQuadObjectCond::filter(edm::StreamID, edm::Event& event, const edm::EventSetup& setup) const {
0217 edm::Handle<P2GTCandidateCollection> col1 = event.getHandle(token1_);
0218 edm::Handle<P2GTCandidateCollection> col2 = event.getHandle(token2_);
0219 edm::Handle<P2GTCandidateCollection> col3 = event.getHandle(token3_);
0220 edm::Handle<P2GTCandidateCollection> col4 = event.getHandle(token4_);
0221 edm::Handle<P2GTCandidateCollection> primVertCol = event.getHandle(primVertToken_);
0222
0223 bool condition_result = false;
0224
0225 std::set<std::size_t> triggeredIdcs1;
0226 std::set<std::size_t> triggeredIdcs2;
0227 std::set<std::size_t> triggeredIdcs3;
0228 std::set<std::size_t> triggeredIdcs4;
0229
0230 InvariantMassErrorCollection massErrors;
0231
0232 for (std::size_t idx1 = 0; idx1 < col1->size(); ++idx1) {
0233 bool single1Pass = collection1Cuts_.checkObject(col1->at(idx1));
0234 single1Pass &= collection1Cuts_.checkPrimaryVertices(col1->at(idx1), *primVertCol);
0235
0236 for (std::size_t idx2 = 0; idx2 < col2->size(); ++idx2) {
0237 bool single2Pass = collection2Cuts_.checkObject(col2->at(idx2));
0238 single2Pass &= collection2Cuts_.checkPrimaryVertices(col2->at(idx2), *primVertCol);
0239
0240 for (std::size_t idx3 = 0; idx3 < col3->size(); ++idx3) {
0241 bool single3Pass = collection3Cuts_.checkObject(col3->at(idx3));
0242 single3Pass &= collection3Cuts_.checkPrimaryVertices(col3->at(idx3), *primVertCol);
0243
0244 for (std::size_t idx4 = 0; idx4 < col4->size(); ++idx4) {
0245
0246 if (col1.product() == col2.product() && idx1 == idx2) {
0247 continue;
0248 }
0249
0250 if (col2.product() == col3.product() && idx2 == idx3) {
0251 continue;
0252 }
0253
0254 if (col1.product() == col3.product() && idx1 == idx3) {
0255 continue;
0256 }
0257
0258 if (col1.product() == col4.product() && idx1 == idx4) {
0259 continue;
0260 }
0261
0262 if (col2.product() == col4.product() && idx2 == idx4) {
0263 continue;
0264 }
0265
0266 if (col3.product() == col4.product() && idx3 == idx4) {
0267 continue;
0268 }
0269
0270 bool pass = single1Pass & single2Pass & single3Pass;
0271
0272 pass &= collection4Cuts_.checkObject(col4->at(idx4));
0273 pass &= collection4Cuts_.checkPrimaryVertices(col4->at(idx4), *primVertCol);
0274 pass &= correl12Cuts_.checkObjects(col1->at(idx1), col2->at(idx2), massErrors);
0275 pass &= correl13Cuts_.checkObjects(col1->at(idx1), col3->at(idx3), massErrors);
0276 pass &= correl23Cuts_.checkObjects(col2->at(idx2), col3->at(idx3), massErrors);
0277 pass &= correl14Cuts_.checkObjects(col1->at(idx1), col4->at(idx4), massErrors);
0278 pass &= correl24Cuts_.checkObjects(col2->at(idx2), col4->at(idx4), massErrors);
0279 pass &= correl34Cuts_.checkObjects(col3->at(idx3), col4->at(idx4), massErrors);
0280 pass &= correl123Cuts_.checkObjects(col1->at(idx1), col2->at(idx2), col3->at(idx3), massErrors);
0281 pass &= correl124Cuts_.checkObjects(col1->at(idx1), col2->at(idx2), col4->at(idx4), massErrors);
0282 pass &= correl134Cuts_.checkObjects(col1->at(idx1), col3->at(idx3), col4->at(idx4), massErrors);
0283 pass &= correl234Cuts_.checkObjects(col2->at(idx2), col3->at(idx3), col4->at(idx4), massErrors);
0284
0285 if (minQualityScoreSum_ || maxQualityScoreSum_) {
0286 unsigned int qualityScoreSum =
0287 col1->at(idx1).hwQualityScore().to_uint() + col2->at(idx2).hwQualityScore().to_uint() +
0288 col3->at(idx3).hwQualityScore().to_uint() + col4->at(idx4).hwQualityScore().to_uint();
0289
0290 pass &= minQualityScoreSum_ ? qualityScoreSum > minQualityScoreSum_ : true;
0291 pass &= maxQualityScoreSum_ ? qualityScoreSum < maxQualityScoreSum_ : true;
0292 }
0293
0294 condition_result |= pass;
0295
0296 if (pass) {
0297 triggeredIdcs1.emplace(idx1);
0298
0299 if (col1.product() != col2.product()) {
0300 triggeredIdcs2.emplace(idx2);
0301 } else {
0302 triggeredIdcs1.emplace(idx2);
0303 }
0304
0305 if (col1.product() != col3.product() && col2.product() != col3.product()) {
0306 triggeredIdcs3.emplace(idx3);
0307 } else if (col1.product() == col3.product()) {
0308 triggeredIdcs1.emplace(idx3);
0309 } else {
0310 triggeredIdcs2.emplace(idx3);
0311 }
0312
0313 if (col1.product() != col4.product() && col2.product() != col4.product() &&
0314 col3.product() != col4.product()) {
0315 triggeredIdcs4.emplace(idx4);
0316 } else if (col1.product() == col4.product()) {
0317 triggeredIdcs1.emplace(idx4);
0318 } else if (col2.product() == col4.product()) {
0319 triggeredIdcs2.emplace(idx4);
0320 } else {
0321 triggeredIdcs3.emplace(idx4);
0322 }
0323 }
0324 }
0325 }
0326 }
0327 }
0328
0329 condition_result &= collection1Cuts_.checkCollection(*col1);
0330 condition_result &= collection2Cuts_.checkCollection(*col2);
0331 condition_result &= collection3Cuts_.checkCollection(*col3);
0332 condition_result &= collection4Cuts_.checkCollection(*col4);
0333
0334 if (condition_result) {
0335 std::unique_ptr<P2GTCandidateVectorRef> triggerCol1 = std::make_unique<P2GTCandidateVectorRef>();
0336
0337 for (std::size_t idx : triggeredIdcs1) {
0338 triggerCol1->push_back(P2GTCandidateRef(col1, idx));
0339 }
0340 event.put(std::move(triggerCol1), collection1Cuts_.tag().instance());
0341
0342 if (col1.product() != col2.product()) {
0343 std::unique_ptr<P2GTCandidateVectorRef> triggerCol2 = std::make_unique<P2GTCandidateVectorRef>();
0344
0345 for (std::size_t idx : triggeredIdcs2) {
0346 triggerCol2->push_back(P2GTCandidateRef(col2, idx));
0347 }
0348 event.put(std::move(triggerCol2), collection2Cuts_.tag().instance());
0349 }
0350
0351 if (col1.product() != col3.product() && col2.product() != col3.product()) {
0352 std::unique_ptr<P2GTCandidateVectorRef> triggerCol3 = std::make_unique<P2GTCandidateVectorRef>();
0353
0354 for (std::size_t idx : triggeredIdcs3) {
0355 triggerCol3->push_back(P2GTCandidateRef(col3, idx));
0356 }
0357 event.put(std::move(triggerCol3), collection3Cuts_.tag().instance());
0358 }
0359
0360 if (col1.product() != col4.product() && col2.product() != col4.product() && col3.product() != col4.product()) {
0361 std::unique_ptr<P2GTCandidateVectorRef> triggerCol4 = std::make_unique<P2GTCandidateVectorRef>();
0362
0363 for (std::size_t idx : triggeredIdcs4) {
0364 triggerCol4->push_back(P2GTCandidateRef(col4, idx));
0365 }
0366 event.put(std::move(triggerCol4), collection4Cuts_.tag().instance());
0367 }
0368 }
0369
0370 if (inv_mass_checks_) {
0371 event.put(std::make_unique<InvariantMassErrorCollection>(std::move(massErrors)), "");
0372 }
0373
0374 return condition_result;
0375 }
0376
0377 DEFINE_FWK_MODULE(L1GTQuadObjectCond);