Skip to content

Commit 5cd2f2d

Browse files
authored
Merge pull request #47460 from p2l1-gtEmulator/add_cuts
Quality score sum cut + L1GTAcceptFilter + internal fixes
2 parents 6ebe601 + 4c19899 commit 5cd2f2d

File tree

10 files changed

+176
-133
lines changed

10 files changed

+176
-133
lines changed

L1Trigger/Phase2L1GT/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,15 @@ The following 3-body correlational cuts are available:
253253
| `minTransMass` | $\frac{m_{T,1,2}^2}{2} + \frac{m_{T,1,3}^2}{2} + \frac{m_{T,2,3}^2}{2} > \frac{X^2}{2}$ | `cms.double` | `floor(X**2 * LUT_Scale / (2 * pT_lsb**2))` |
254254
| `maxTransMass` | $\frac{m_{T,1,2}^2}{2} + \frac{m_{T,1,3}^2}{2} + \frac{m_{T,2,3}^2}{2} < \frac{X^2}{2}$ | `cms.double` | `ceil(X**2 * LUT_Scale / (2 * pT_lsb**2))` |
255255

256+
The following N-body correlational cuts are available (N = 2 for DoubleObjectCondition, N = 3 for TripleObjectCondition and N = 4 for the QuadObjectCondition):
257+
258+
| Name | Expression | Datatype | Hardware conversion |
259+
|:-----|:----------:|:-------------:|:--------:|
260+
| `minQualityScoreSum`* | $\sum^N_{i=1} \mathrm{qualityScore} > X$ | `cms.unit32` | `X` |
261+
| `maxQualityScoreSum`* | $\sum^N_{i=1} \mathrm{qualityScore} < X$ | `cms.unit32` | `X` |
262+
263+
\*: For N=4 the 4 objects should be from the same input collection to guarantee timing closure of the FPGA firmware.
264+
256265
## Algorithms
257266

258267
Conditions are combined to algorithms via the [`L1GTAlgoBlockProducer`](plugins/L1GTAlgoBlockProducer.cc). To configure this behavior, a `cms.PSet` algorithm configuration should be added to the `algorithms` `cms.VPset`, included via:
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#include "FWCore/Framework/interface/Event.h"
2+
#include "FWCore/Framework/interface/global/EDFilter.h"
3+
#include "FWCore/ParameterSet/interface/ParameterSet.h"
4+
#include "DataFormats/L1Trigger/interface/P2GTAlgoBlock.h"
5+
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
6+
7+
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
8+
#include "FWCore/ParameterSet/interface/allowedValues.h"
9+
#include "FWCore/Framework/interface/MakerMacros.h"
10+
#include "DataFormats/Common/interface/Handle.h"
11+
#include "FWCore/Utilities/interface/EDGetToken.h"
12+
13+
using namespace l1t;
14+
15+
class L1GTAcceptFilter : public edm::global::EDFilter<> {
16+
public:
17+
explicit L1GTAcceptFilter(const edm::ParameterSet&);
18+
~L1GTAcceptFilter() override = default;
19+
20+
static void fillDescriptions(edm::ConfigurationDescriptions&);
21+
22+
enum DecisionType { beforeBxMaskAndPrescale, beforePrescale, final };
23+
24+
private:
25+
bool filter(edm::StreamID, edm::Event&, edm::EventSetup const&) const override;
26+
27+
const edm::EDGetTokenT<P2GTAlgoBlockMap> algoBlocksToken_;
28+
const DecisionType decisionEnum_;
29+
int triggerType_;
30+
};
31+
32+
L1GTAcceptFilter::L1GTAcceptFilter(const edm::ParameterSet& config)
33+
: algoBlocksToken_(consumes<P2GTAlgoBlockMap>(config.getParameter<edm::InputTag>("algoBlocksTag"))),
34+
decisionEnum_(config.getParameter<std::string>("decision") == "beforeBxMaskAndPrescale" ? beforeBxMaskAndPrescale
35+
: config.getParameter<std::string>("decision") == "beforePrescale" ? beforePrescale
36+
: final),
37+
triggerType_(config.getParameter<int>("triggerType")) {}
38+
39+
bool L1GTAcceptFilter::filter(edm::StreamID, edm::Event& event, const edm::EventSetup& setup) const {
40+
const P2GTAlgoBlockMap& algoMap = event.get(algoBlocksToken_);
41+
bool decision = false;
42+
bool veto = false;
43+
for (const auto& [name, algoBlock] : algoMap) {
44+
if (algoBlock.isVeto()) {
45+
veto |= algoBlock.decisionFinal();
46+
} else if ((algoBlock.triggerTypes() & triggerType_) > 0) {
47+
if (decisionEnum_ == beforeBxMaskAndPrescale) {
48+
decision |= algoBlock.decisionBeforeBxMaskAndPrescale();
49+
} else if (decisionEnum_ == beforePrescale) {
50+
decision |= algoBlock.decisionBeforePrescale();
51+
} else {
52+
decision |= algoBlock.decisionFinal();
53+
}
54+
}
55+
}
56+
57+
return decision && !veto;
58+
}
59+
60+
void L1GTAcceptFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
61+
edm::ParameterSetDescription desc;
62+
desc.add<edm::InputTag>("algoBlocksTag");
63+
desc.add<int>("triggerType", 1);
64+
desc.ifValue(edm::ParameterDescription<std::string>("decision", "final", true),
65+
edm::allowedValues<std::string>("beforeBxMaskAndPrescale", "beforePrescale", "final"));
66+
67+
descriptions.addWithDefaultLabel(desc);
68+
}
69+
70+
DEFINE_FWK_MODULE(L1GTAcceptFilter);

L1Trigger/Phase2L1GT/plugins/L1GTDoubleObjectCond.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "L1GTSingleCollectionCut.h"
1919
#include "L1GTCorrelationalCut.h"
2020
#include "L1GTSingleInOutLUT.h"
21+
#include "L1GTOptionalParam.h"
2122

2223
#include <cinttypes>
2324
#include <memory>
@@ -48,6 +49,9 @@ class L1GTDoubleObjectCond : public edm::global::EDFilter<> {
4849

4950
const L1GTCorrelationalCut deltaCuts_;
5051

52+
const std::optional<unsigned int> minQualityScoreSum_;
53+
const std::optional<unsigned int> maxQualityScoreSum_;
54+
5155
const edm::EDGetTokenT<P2GTCandidateCollection> token1_;
5256
const edm::EDGetTokenT<P2GTCandidateCollection> token2_;
5357
const edm::EDGetTokenT<P2GTCandidateCollection> primVertToken_;
@@ -60,6 +64,8 @@ L1GTDoubleObjectCond::L1GTDoubleObjectCond(const edm::ParameterSet& config)
6064
enable_sanity_checks_(config.getUntrackedParameter<bool>("sanity_checks")),
6165
inv_mass_checks_(config.getUntrackedParameter<bool>("inv_mass_checks")),
6266
deltaCuts_(config, config, scales_, enable_sanity_checks_, inv_mass_checks_),
67+
minQualityScoreSum_(getOptionalParam<unsigned int>("minQualityScoreSum", config)),
68+
maxQualityScoreSum_(getOptionalParam<unsigned int>("maxQualityScoreSum", config)),
6369
token1_(consumes<P2GTCandidateCollection>(collection1Cuts_.tag())),
6470
token2_(collection1Cuts_.tag() == collection2Cuts_.tag()
6571
? token1_
@@ -74,6 +80,10 @@ L1GTDoubleObjectCond::L1GTDoubleObjectCond(const edm::ParameterSet& config)
7480
if (inv_mass_checks_) {
7581
produces<InvariantMassErrorCollection>();
7682
}
83+
84+
if ((minQualityScoreSum_ || maxQualityScoreSum_) && !(collection1Cuts_.tag() == collection2Cuts_.tag())) {
85+
throw cms::Exception("Configuration") << "A qualityScore sum can only be calculated within one collection.";
86+
}
7787
}
7888

7989
void L1GTDoubleObjectCond::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
@@ -95,6 +105,9 @@ void L1GTDoubleObjectCond::fillDescriptions(edm::ConfigurationDescriptions& desc
95105
L1GTCorrelationalCut::fillPSetDescription(desc);
96106
L1GTCorrelationalCut::fillLUTDescriptions(desc);
97107

108+
desc.addOptional<unsigned int>("minQualityScoreSum");
109+
desc.addOptional<unsigned int>("maxQualityScoreSum");
110+
98111
edm::ParameterSetDescription scalesDesc;
99112
L1GTScales::fillPSetDescription(scalesDesc);
100113
desc.add<edm::ParameterSetDescription>("scales", scalesDesc);
@@ -129,6 +142,14 @@ bool L1GTDoubleObjectCond::filter(edm::StreamID, edm::Event& event, const edm::E
129142
pass &= collection2Cuts_.checkPrimaryVertices(col2->at(idx2), *primVertCol);
130143
pass &= deltaCuts_.checkObjects(col1->at(idx1), col2->at(idx2), massErrors);
131144

145+
if (minQualityScoreSum_ || maxQualityScoreSum_) {
146+
unsigned int qualityScoreSum =
147+
col1->at(idx1).hwQualityScore().to_uint() + col2->at(idx2).hwQualityScore().to_uint();
148+
149+
pass &= minQualityScoreSum_ ? qualityScoreSum > minQualityScoreSum_ : true;
150+
pass &= maxQualityScoreSum_ ? qualityScoreSum < maxQualityScoreSum_ : true;
151+
}
152+
132153
condition_result |= pass;
133154

134155
if (pass) {

L1Trigger/Phase2L1GT/plugins/L1GTEvaluationInterface.h

Lines changed: 1 addition & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ namespace l1t {
5757

5858
ap_uint<N> pack() const override { return pack_common(); }
5959

60-
static L1TGT_Common3Vector from_GTObject(const P2GTCandidate& gtObject) {
61-
return L1TGT_Common3Vector(1, gtObject.hwPT(), gtObject.hwPhi(), gtObject.hwEta());
62-
}
63-
6460
P2GTCandidate to_GTObject() const override {
6561
P2GTCandidate gt_object;
6662
gt_object.setHwPT(pT);
@@ -84,10 +80,6 @@ namespace l1t {
8480

8581
ap_uint<64> pack() const override { return pack_common(); }
8682

87-
static L1TGT_CommonSum from_GTObject(const P2GTCandidate& gtObject) {
88-
return L1TGT_CommonSum(1, gtObject.hwPT(), gtObject.hwPhi(), gtObject.hwScalarSumPT());
89-
}
90-
9183
P2GTCandidate to_GTObject() const override {
9284
P2GTCandidate gt_object;
9385
gt_object.setHwPT(pT);
@@ -122,10 +114,6 @@ namespace l1t {
122114
return l1t_pack_int<ap_uint<WIDTH>>(L1TGT_Common3Vector::pack_common(), seed_pT);
123115
}
124116

125-
static L1TGT_GCT_tau6p6 from_GTObject(const P2GTCandidate& gtObject) {
126-
return L1TGT_GCT_tau6p6(1, gtObject.hwPT(), gtObject.hwPhi(), gtObject.hwEta(), gtObject.hwSeed_pT());
127-
}
128-
129117
P2GTCandidate to_GTObject() const override {
130118
P2GTCandidate gt_object(L1TGT_Common3Vector::to_GTObject());
131119
gt_object.setHwSeed_pT(seed_pT);
@@ -141,7 +129,7 @@ namespace l1t {
141129
// Global Muon Trigger
142130

143131
struct L1TGT_GMT_PromptDisplacedMuon : public L1TGT_Common3Vector<64> {
144-
ap_uint<5> z0;
132+
ap_int<5> z0;
145133
ap_int<7> d0;
146134
ap_uint<1> charge;
147135
ap_uint<4> qualityScore;
@@ -160,17 +148,6 @@ namespace l1t {
160148
return l1t_pack_int<ap_uint<WIDTH>>(L1TGT_Common3Vector::pack_common(), z0, d0, charge, qualityScore);
161149
}
162150

163-
static L1TGT_GMT_PromptDisplacedMuon from_GTObject(const P2GTCandidate& gtObject) {
164-
return L1TGT_GMT_PromptDisplacedMuon(1,
165-
gtObject.hwPT(),
166-
gtObject.hwPhi(),
167-
gtObject.hwEta(),
168-
gtObject.hwZ0() >> 12,
169-
gtObject.hwD0() >> 5,
170-
gtObject.hwCharge(),
171-
gtObject.hwQualityScore());
172-
}
173-
174151
P2GTCandidate to_GTObject() const override {
175152
P2GTCandidate gt_object(L1TGT_Common3Vector::to_GTObject());
176153
gt_object.setHwZ0(static_cast<int>(z0) << 12);
@@ -213,19 +190,6 @@ namespace l1t {
213190
L1TGT_Common3Vector::pack_common(), z0, d0, charge, qualityFlags, isolationPT, beta);
214191
}
215192

216-
static L1TGT_GMT_TrackMatchedmuon from_GTObject(const P2GTCandidate& gtObject) {
217-
return L1TGT_GMT_TrackMatchedmuon(1,
218-
gtObject.hwPT(),
219-
gtObject.hwPhi(),
220-
gtObject.hwEta(),
221-
gtObject.hwZ0() >> 7,
222-
gtObject.hwD0() >> 2,
223-
gtObject.hwCharge(),
224-
gtObject.hwQualityFlags(),
225-
gtObject.hwIsolationPT(),
226-
gtObject.hwBeta());
227-
}
228-
229193
P2GTCandidate to_GTObject() const override {
230194
P2GTCandidate gt_object(L1TGT_Common3Vector::to_GTObject());
231195
gt_object.setHwZ0(static_cast<int>(z0) << 7);
@@ -256,15 +220,6 @@ namespace l1t {
256220
return l1t_pack_int<ap_uint<WIDTH>>(valid, pT, eta, phi, mass, qualityFlags);
257221
}
258222

259-
static L1TGT_GMT_TopoObject from_GTObject(const P2GTCandidate& gtObject) {
260-
return L1TGT_GMT_TopoObject(1,
261-
gtObject.hwPT() / 5,
262-
gtObject.hwPhi() >> 5,
263-
gtObject.hwEta() >> 5,
264-
gtObject.hwMass(),
265-
gtObject.hwQualityFlags());
266-
}
267-
268223
P2GTCandidate to_GTObject() const override {
269224
P2GTCandidate gt_object;
270225
gt_object.setHwPT(static_cast<int>(pT) * 5); // TODO
@@ -301,16 +256,6 @@ namespace l1t {
301256
L1TGT_Common3Vector::pack_common(), z0, number_of_tracks, number_of_displaced_tracks);
302257
}
303258

304-
static L1TGT_GTT_PromptJet from_GTObject(const P2GTCandidate& gtObject) {
305-
return L1TGT_GTT_PromptJet(1,
306-
gtObject.hwPT(),
307-
gtObject.hwPhi(),
308-
gtObject.hwEta(),
309-
gtObject.hwZ0() >> 7,
310-
gtObject.hwNumber_of_tracks(),
311-
gtObject.hwNumber_of_displaced_tracks());
312-
}
313-
314259
P2GTCandidate to_GTObject() const override {
315260
P2GTCandidate gt_object(L1TGT_Common3Vector::to_GTObject());
316261
gt_object.setHwZ0(static_cast<int>(z0) << 7);
@@ -343,16 +288,6 @@ namespace l1t {
343288
L1TGT_Common3Vector::pack_common(), z0, number_of_tracks, number_of_displaced_tracks);
344289
}
345290

346-
static L1TGT_GTT_DisplacedJet from_GTObject(const P2GTCandidate& gtObject) {
347-
return L1TGT_GTT_DisplacedJet(1,
348-
gtObject.hwPT(),
349-
gtObject.hwPhi(),
350-
gtObject.hwEta(),
351-
gtObject.hwZ0() >> 7,
352-
gtObject.hwNumber_of_tracks(),
353-
gtObject.hwNumber_of_displaced_tracks());
354-
}
355-
356291
P2GTCandidate to_GTObject() const override {
357292
P2GTCandidate gt_object(L1TGT_Common3Vector::to_GTObject());
358293
gt_object.setHwZ0(static_cast<int>(z0) << 7);
@@ -387,17 +322,6 @@ namespace l1t {
387322
return l1t_pack_int<ap_uint<WIDTH>>(L1TGT_Common3Vector::pack_common(), seed_pT, seed_z0, charge, type);
388323
}
389324

390-
static L1TGT_GTT_HadronicTau from_GTObject(const P2GTCandidate& gtObject) {
391-
return L1TGT_GTT_HadronicTau(1,
392-
gtObject.hwPT(),
393-
gtObject.hwPhi(),
394-
gtObject.hwEta(),
395-
gtObject.hwSeed_pT(),
396-
gtObject.hwSeed_z0(),
397-
gtObject.hwCharge(),
398-
gtObject.hwType());
399-
}
400-
401325
P2GTCandidate to_GTObject() const override {
402326
P2GTCandidate gt_object(L1TGT_Common3Vector::to_GTObject());
403327
gt_object.setHwSeed_pT(seed_pT);
@@ -422,10 +346,6 @@ namespace l1t {
422346
return l1t_pack_int<ap_uint<WIDTH>>(L1TGT_Common3Vector::pack_common(), z0);
423347
}
424348

425-
static L1TGT_GTT_LightMeson from_GTObject(const P2GTCandidate& gtObject) {
426-
return L1TGT_GTT_LightMeson(1, gtObject.hwPT(), gtObject.hwPhi(), gtObject.hwEta(), gtObject.hwZ0() >> 7);
427-
}
428-
429349
P2GTCandidate to_GTObject() const override {
430350
P2GTCandidate gt_object(L1TGT_Common3Vector::to_GTObject());
431351
gt_object.setHwZ0(static_cast<int>(z0) << 7);
@@ -441,8 +361,6 @@ namespace l1t {
441361

442362
ap_uint<WIDTH> pack() const override { return ap_uint<WIDTH>(0); }
443363

444-
static L1TGT_GTT_Track from_GTObject(const P2GTCandidate& gtObject) { return L1TGT_GTT_Track(); }
445-
446364
P2GTCandidate to_GTObject() const override { return P2GTCandidate(); }
447365
};
448366

@@ -473,15 +391,6 @@ namespace l1t {
473391
valid, z0, number_of_tracks_in_pv, sum_pT_pv, qualityScore, number_of_tracks_not_in_pv);
474392
}
475393

476-
static L1TGT_GTT_PrimaryVert from_GTObject(const P2GTCandidate& gtObject) {
477-
return L1TGT_GTT_PrimaryVert(1,
478-
gtObject.hwZ0() / 5,
479-
gtObject.hwNumber_of_tracks_in_pv(),
480-
gtObject.hwSum_pT_pv(),
481-
gtObject.hwQualityScore(),
482-
gtObject.hwNumber_of_tracks_not_in_pv());
483-
}
484-
485394
P2GTCandidate to_GTObject() const override {
486395
P2GTCandidate gt_object;
487396
gt_object.setHwZ0(static_cast<int>(z0) * 5);
@@ -506,10 +415,6 @@ namespace l1t {
506415
return l1t_pack_int<ap_uint<WIDTH>>(L1TGT_Common3Vector::pack_common(), z0);
507416
}
508417

509-
static L1TGT_CL2_Jet from_GTObject(const P2GTCandidate& gtObject) {
510-
return L1TGT_CL2_Jet(1, gtObject.hwPT(), gtObject.hwPhi(), gtObject.hwEta(), gtObject.hwZ0() >> 7);
511-
}
512-
513418
P2GTCandidate to_GTObject() const override {
514419
P2GTCandidate gt_object(L1TGT_Common3Vector::to_GTObject());
515420
gt_object.setHwZ0(static_cast<int>(z0) << 7);
@@ -545,17 +450,6 @@ namespace l1t {
545450
return l1t_pack_int<ap_uint<WIDTH>>(L1TGT_Common3Vector::pack_common(), seed_pT, seed_z0, charge, type);
546451
}
547452

548-
static L1TGT_CL2_Tau from_GTObject(const P2GTCandidate& gtObject) {
549-
return L1TGT_CL2_Tau(1,
550-
gtObject.hwPT(),
551-
gtObject.hwPhi(),
552-
gtObject.hwEta(),
553-
gtObject.hwSeed_pT(),
554-
gtObject.hwSeed_z0(),
555-
gtObject.hwCharge(),
556-
gtObject.hwType());
557-
}
558-
559453
P2GTCandidate to_GTObject() const override {
560454
P2GTCandidate gt_object(L1TGT_Common3Vector::to_GTObject());
561455
gt_object.setHwSeed_pT(seed_pT);
@@ -591,17 +485,6 @@ namespace l1t {
591485
return l1t_pack_int<ap_uint<WIDTH>>(L1TGT_Common3Vector::pack_common(), qualityFlags, isolationPT, charge, z0);
592486
}
593487

594-
static L1TGT_CL2_Electron from_GTObject(const P2GTCandidate& gtObject) {
595-
return L1TGT_CL2_Electron(1,
596-
gtObject.hwPT(),
597-
gtObject.hwPhi(),
598-
gtObject.hwEta(),
599-
gtObject.hwQualityFlags(),
600-
gtObject.hwIsolationPT(),
601-
gtObject.hwCharge(),
602-
gtObject.hwZ0() >> 7);
603-
}
604-
605488
P2GTCandidate to_GTObject() const override {
606489
P2GTCandidate gt_object(L1TGT_Common3Vector::to_GTObject());
607490
gt_object.setHwQualityFlags(qualityFlags);
@@ -624,11 +507,6 @@ namespace l1t {
624507
return l1t_pack_int<ap_uint<WIDTH>>(L1TGT_Common3Vector::pack_common(), qualityFlags, isolationPT);
625508
}
626509

627-
static L1TGT_CL2_Photon from_GTObject(const P2GTCandidate& gtObject) {
628-
return L1TGT_CL2_Photon(
629-
1, gtObject.hwPT(), gtObject.hwPhi(), gtObject.hwEta(), gtObject.hwQualityFlags(), gtObject.hwIsolationPT());
630-
}
631-
632510
P2GTCandidate to_GTObject() const override {
633511
P2GTCandidate gt_object(L1TGT_Common3Vector::to_GTObject());
634512
gt_object.setHwQualityFlags(qualityFlags);

0 commit comments

Comments
 (0)