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
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);