Back to home page

Project CMSSW displayed by LXR

 
 

    


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           // If we're looking at the same collection then we shouldn't use the same object in one comparison.
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);