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 "DataFormats/Common/interface/Ref.h"
0010 #include "FWCore/Utilities/interface/EDGetToken.h"
0011 
0012 #include "FWCore/Framework/interface/MakerMacros.h"
0013 
0014 #include "L1Trigger/Phase2L1GT/interface/L1GTScales.h"
0015 #include "L1GTSingleCollectionCut.h"
0016 #include "L1GTCorrelationalCut.h"
0017 #include "L1GT3BodyCut.h"
0018 #include "L1GTSingleInOutLUT.h"
0019 #include "L1GTOptionalParam.h"
0020 
0021 #include <set>
0022 
0023 #include <ap_int.h>
0024 
0025 using namespace l1t;
0026 
0027 class L1GTTripleObjectCond : public edm::global::EDFilter<> {
0028 public:
0029   explicit L1GTTripleObjectCond(const edm::ParameterSet&);
0030   ~L1GTTripleObjectCond() override = default;
0031 
0032   static void fillDescriptions(edm::ConfigurationDescriptions&);
0033 
0034 private:
0035   bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override;
0036 
0037   const L1GTScales scales_;
0038 
0039   const L1GTSingleCollectionCut collection1Cuts_;
0040   const L1GTSingleCollectionCut collection2Cuts_;
0041   const L1GTSingleCollectionCut collection3Cuts_;
0042 
0043   const bool enable_sanity_checks_;
0044   const bool inv_mass_checks_;
0045 
0046   const L1GTCorrelationalCut correl12Cuts_;
0047   const L1GTCorrelationalCut correl13Cuts_;
0048   const L1GTCorrelationalCut correl23Cuts_;
0049 
0050   const L1GT3BodyCut correl123Cuts_;
0051 
0052   const std::optional<unsigned int> minQualityScoreSum_;
0053   const std::optional<unsigned int> maxQualityScoreSum_;
0054 
0055   const edm::EDGetTokenT<P2GTCandidateCollection> token1_;
0056   const edm::EDGetTokenT<P2GTCandidateCollection> token2_;
0057   const edm::EDGetTokenT<P2GTCandidateCollection> token3_;
0058   const edm::EDGetTokenT<P2GTCandidateCollection> primVertToken_;
0059 };
0060 
0061 L1GTTripleObjectCond::L1GTTripleObjectCond(const edm::ParameterSet& config)
0062     : scales_(config.getParameter<edm::ParameterSet>("scales")),
0063       collection1Cuts_(config.getParameter<edm::ParameterSet>("collection1"), config, scales_),
0064       collection2Cuts_(config.getParameter<edm::ParameterSet>("collection2"), config, scales_),
0065       collection3Cuts_(config.getParameter<edm::ParameterSet>("collection3"), config, scales_),
0066       enable_sanity_checks_(config.getUntrackedParameter<bool>("sanity_checks")),
0067       inv_mass_checks_(config.getUntrackedParameter<bool>("inv_mass_checks")),
0068       correl12Cuts_(
0069           config.getParameter<edm::ParameterSet>("correl12"), config, scales_, enable_sanity_checks_, inv_mass_checks_),
0070       correl13Cuts_(
0071           config.getParameter<edm::ParameterSet>("correl13"), config, scales_, enable_sanity_checks_, inv_mass_checks_),
0072       correl23Cuts_(
0073           config.getParameter<edm::ParameterSet>("correl23"), config, scales_, enable_sanity_checks_, inv_mass_checks_),
0074       correl123Cuts_(config, config, scales_, inv_mass_checks_),
0075       minQualityScoreSum_(getOptionalParam<unsigned int>("minQualityScoreSum", config)),
0076       maxQualityScoreSum_(getOptionalParam<unsigned int>("maxQualityScoreSum", config)),
0077       token1_(consumes<P2GTCandidateCollection>(collection1Cuts_.tag())),
0078       token2_(collection1Cuts_.tag() == collection2Cuts_.tag()
0079                   ? token1_
0080                   : consumes<P2GTCandidateCollection>(collection2Cuts_.tag())),
0081       token3_(collection1Cuts_.tag() == collection3Cuts_.tag()
0082                   ? token1_
0083                   : (collection2Cuts_.tag() == collection3Cuts_.tag()
0084                          ? token2_
0085                          : consumes<P2GTCandidateCollection>(collection3Cuts_.tag()))),
0086       primVertToken_(consumes<P2GTCandidateCollection>(config.getParameter<edm::InputTag>("primVertTag"))) {
0087   produces<P2GTCandidateVectorRef>(collection1Cuts_.tag().instance());
0088 
0089   if (!(collection1Cuts_.tag() == collection2Cuts_.tag())) {
0090     produces<P2GTCandidateVectorRef>(collection2Cuts_.tag().instance());
0091   }
0092 
0093   if (!(collection1Cuts_.tag() == collection3Cuts_.tag()) && !(collection2Cuts_.tag() == collection3Cuts_.tag())) {
0094     produces<P2GTCandidateVectorRef>(collection3Cuts_.tag().instance());
0095   }
0096 
0097   if (inv_mass_checks_) {
0098     produces<InvariantMassErrorCollection>();
0099   }
0100 
0101   if ((minQualityScoreSum_ || maxQualityScoreSum_) &&
0102       !(collection1Cuts_.tag() == collection2Cuts_.tag() && collection2Cuts_.tag() == collection3Cuts_.tag())) {
0103     throw cms::Exception("Configuration") << "A qualityScore sum can only be calculated within one collection.";
0104   }
0105 }
0106 
0107 void L1GTTripleObjectCond::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0108   edm::ParameterSetDescription desc;
0109 
0110   edm::ParameterSetDescription collection1Desc;
0111   L1GTSingleCollectionCut::fillPSetDescription(collection1Desc);
0112   desc.add<edm::ParameterSetDescription>("collection1", collection1Desc);
0113 
0114   edm::ParameterSetDescription collection2Desc;
0115   L1GTSingleCollectionCut::fillPSetDescription(collection2Desc);
0116   desc.add<edm::ParameterSetDescription>("collection2", collection2Desc);
0117 
0118   edm::ParameterSetDescription collection3Desc;
0119   L1GTSingleCollectionCut::fillPSetDescription(collection3Desc);
0120   desc.add<edm::ParameterSetDescription>("collection3", collection3Desc);
0121 
0122   edm::ParameterSetDescription scalesDesc;
0123   L1GTScales::fillPSetDescription(scalesDesc);
0124   desc.add<edm::ParameterSetDescription>("scales", scalesDesc);
0125 
0126   desc.add<edm::InputTag>("primVertTag");
0127 
0128   desc.addUntracked<bool>("sanity_checks", false);
0129   desc.addUntracked<bool>("inv_mass_checks", false);
0130 
0131   edm::ParameterSetDescription correl12Desc;
0132   L1GTCorrelationalCut::fillPSetDescription(correl12Desc);
0133   desc.add<edm::ParameterSetDescription>("correl12", correl12Desc);
0134 
0135   edm::ParameterSetDescription correl13Desc;
0136   L1GTCorrelationalCut::fillPSetDescription(correl13Desc);
0137   desc.add<edm::ParameterSetDescription>("correl13", correl13Desc);
0138 
0139   edm::ParameterSetDescription correl23Desc;
0140   L1GTCorrelationalCut::fillPSetDescription(correl23Desc);
0141   desc.add<edm::ParameterSetDescription>("correl23", correl23Desc);
0142 
0143   L1GT3BodyCut::fillPSetDescription(desc);
0144 
0145   desc.addOptional<unsigned int>("minQualityScoreSum");
0146   desc.addOptional<unsigned int>("maxQualityScoreSum");
0147 
0148   L1GTCorrelationalCut::fillLUTDescriptions(desc);
0149 
0150   descriptions.addWithDefaultLabel(desc);
0151 }
0152 
0153 bool L1GTTripleObjectCond::filter(edm::StreamID, edm::Event& event, const edm::EventSetup& setup) const {
0154   edm::Handle<P2GTCandidateCollection> col1 = event.getHandle(token1_);
0155   edm::Handle<P2GTCandidateCollection> col2 = event.getHandle(token2_);
0156   edm::Handle<P2GTCandidateCollection> col3 = event.getHandle(token3_);
0157   edm::Handle<P2GTCandidateCollection> primVertCol = event.getHandle(primVertToken_);
0158 
0159   bool condition_result = false;
0160 
0161   std::set<std::size_t> triggeredIdcs1;
0162   std::set<std::size_t> triggeredIdcs2;
0163   std::set<std::size_t> triggeredIdcs3;
0164 
0165   InvariantMassErrorCollection massErrors;
0166 
0167   for (std::size_t idx1 = 0; idx1 < col1->size(); ++idx1) {
0168     bool single1Pass = collection1Cuts_.checkObject(col1->at(idx1));
0169     single1Pass &= collection1Cuts_.checkPrimaryVertices(col1->at(idx1), *primVertCol);
0170 
0171     for (std::size_t idx2 = 0; idx2 < col2->size(); ++idx2) {
0172       bool single2Pass = collection2Cuts_.checkObject(col2->at(idx2));
0173       single2Pass &= collection2Cuts_.checkPrimaryVertices(col2->at(idx2), *primVertCol);
0174 
0175       for (std::size_t idx3 = 0; idx3 < col3->size(); ++idx3) {
0176         // If we're looking at the same collection then we shouldn't use the same object in one comparison.
0177         if (col1.product() == col2.product() && idx1 == idx2) {
0178           continue;
0179         }
0180 
0181         if (col1.product() == col3.product() && idx1 == idx3) {
0182           continue;
0183         }
0184 
0185         if (col2.product() == col3.product() && idx2 == idx3) {
0186           continue;
0187         }
0188 
0189         bool pass = single1Pass & single2Pass;
0190 
0191         pass &= collection3Cuts_.checkObject(col3->at(idx3));
0192         pass &= collection3Cuts_.checkPrimaryVertices(col3->at(idx3), *primVertCol);
0193         pass &= correl12Cuts_.checkObjects(col1->at(idx1), col2->at(idx2), massErrors);
0194         pass &= correl13Cuts_.checkObjects(col1->at(idx1), col3->at(idx3), massErrors);
0195         pass &= correl23Cuts_.checkObjects(col2->at(idx2), col3->at(idx3), massErrors);
0196         pass &= correl123Cuts_.checkObjects(col1->at(idx1), col2->at(idx2), col3->at(idx3), massErrors);
0197 
0198         if (minQualityScoreSum_ || maxQualityScoreSum_) {
0199           unsigned int qualityScoreSum = col1->at(idx1).hwQualityScore().to_uint() +
0200                                          col2->at(idx2).hwQualityScore().to_uint() +
0201                                          col3->at(idx3).hwQualityScore().to_uint();
0202 
0203           pass &= minQualityScoreSum_ ? qualityScoreSum > minQualityScoreSum_ : true;
0204           pass &= maxQualityScoreSum_ ? qualityScoreSum < maxQualityScoreSum_ : true;
0205         }
0206 
0207         condition_result |= pass;
0208 
0209         if (pass) {
0210           triggeredIdcs1.emplace(idx1);
0211 
0212           if (col1.product() != col2.product()) {
0213             triggeredIdcs2.emplace(idx2);
0214           } else {
0215             triggeredIdcs1.emplace(idx2);
0216           }
0217 
0218           if (col1.product() != col3.product() && col2.product() != col3.product()) {
0219             triggeredIdcs3.emplace(idx3);
0220           } else if (col1.product() == col3.product()) {
0221             triggeredIdcs1.emplace(idx3);
0222           } else {
0223             triggeredIdcs2.emplace(idx3);
0224           }
0225         }
0226       }
0227     }
0228   }
0229 
0230   condition_result &= collection1Cuts_.checkCollection(*col1);
0231   condition_result &= collection2Cuts_.checkCollection(*col2);
0232   condition_result &= collection3Cuts_.checkCollection(*col3);
0233 
0234   if (condition_result) {
0235     std::unique_ptr<P2GTCandidateVectorRef> triggerCol1 = std::make_unique<P2GTCandidateVectorRef>();
0236 
0237     for (std::size_t idx : triggeredIdcs1) {
0238       triggerCol1->push_back(P2GTCandidateRef(col1, idx));
0239     }
0240     event.put(std::move(triggerCol1), collection1Cuts_.tag().instance());
0241 
0242     if (col1.product() != col2.product()) {
0243       std::unique_ptr<P2GTCandidateVectorRef> triggerCol2 = std::make_unique<P2GTCandidateVectorRef>();
0244 
0245       for (std::size_t idx : triggeredIdcs2) {
0246         triggerCol2->push_back(P2GTCandidateRef(col2, idx));
0247       }
0248       event.put(std::move(triggerCol2), collection2Cuts_.tag().instance());
0249     }
0250 
0251     if (col1.product() != col3.product() && col2.product() != col3.product()) {
0252       std::unique_ptr<P2GTCandidateVectorRef> triggerCol3 = std::make_unique<P2GTCandidateVectorRef>();
0253 
0254       for (std::size_t idx : triggeredIdcs3) {
0255         triggerCol3->push_back(P2GTCandidateRef(col3, idx));
0256       }
0257       event.put(std::move(triggerCol3), collection3Cuts_.tag().instance());
0258     }
0259   }
0260 
0261   if (inv_mass_checks_) {
0262     event.put(std::make_unique<InvariantMassErrorCollection>(std::move(massErrors)), "");
0263   }
0264 
0265   return condition_result;
0266 }
0267 
0268 DEFINE_FWK_MODULE(L1GTTripleObjectCond);