Skip to content

Commit c9fa672

Browse files
authored
Merge pull request #47792 from lrobertshaw/CMSSW_15_1_X
[L1T] PR containing simulation and emulation related to jet mass reconstruction (Phase-2)
2 parents 336fa9c + 9daabf3 commit c9fa672

File tree

10 files changed

+318
-51
lines changed

10 files changed

+318
-51
lines changed

DataFormats/L1TParticleFlow/interface/PFJet.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace l1t {
1515
typedef std::vector<edm::Ptr<l1t::PFCandidate>> Constituents;
1616

1717
PFJet() {}
18-
PFJet(float pt, float eta, float phi, float mass = 0, int hwpt = 0, int hweta = 0, int hwphi = 0)
18+
PFJet(float pt, float eta, float phi, float mass, int hwpt = 0, int hweta = 0, int hwphi = 0)
1919
: L1Candidate(PolarLorentzVector(pt, eta, phi, mass), hwpt, hweta, hwphi, /*hwQuality=*/0), rawPt_(pt) {}
2020

2121
PFJet(const LorentzVector& p4, int hwpt = 0, int hweta = 0, int hwphi = 0)
@@ -67,7 +67,7 @@ namespace l1t {
6767

6868
// Get and set the encodedJet_ bits. The Jet is encoded in 128 bits as a 2-element array of uint64_t
6969
// We store encodings both for Correlator internal usage and for Global Trigger
70-
enum class HWEncoding { CT, GT };
70+
enum class HWEncoding { CT, GT, GTWide };
7171
typedef std::array<uint64_t, 2> PackedJet;
7272
const PackedJet& encodedJet(const HWEncoding encoding = HWEncoding::GT) const {
7373
return encodedJet_[static_cast<int>(encoding)];
@@ -78,6 +78,7 @@ namespace l1t {
7878

7979
// Accessors to HW objects with ap_* types from encoded words
8080
const PackedJet& getHWJetGT() const { return encodedJet(HWEncoding::GT); }
81+
const PackedJet& getHWJetGTWide() const { return encodedJet(HWEncoding::GTWide); }
8182
const PackedJet& getHWJetCT() const { return encodedJet(HWEncoding::CT); }
8283

8384
private:
@@ -86,7 +87,7 @@ namespace l1t {
8687
std::vector<l1ct::JetTagClass> tagClasses_;
8788
std::vector<float> tagScores_;
8889
float ptCorrection_;
89-
std::array<PackedJet, 2> encodedJet_ = {{{{0, 0}}, {{0, 0}}}};
90+
std::array<PackedJet, 3> encodedJet_ = {{{{0, 0}}, {{0, 0}}, {{0, 0}}}};
9091
};
9192

9293
typedef std::vector<l1t::PFJet> PFJetCollection;

DataFormats/L1TParticleFlow/interface/datatypes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace l1ct {
99

1010
typedef ap_ufixed<14, 12, AP_TRN, AP_SAT> pt_t;
11+
typedef ap_ufixed<17, 15, AP_TRN, AP_SAT> mass2_t; // can store up to 256 GeV with 0.5 GeV precision
1112
typedef ap_ufixed<10, 8, AP_TRN, AP_SAT> pt10_t;
1213
typedef ap_fixed<16, 14, AP_TRN, AP_SAT> dpt_t;
1314
typedef ap_ufixed<28, 24, AP_TRN, AP_SAT> pt2_t;
@@ -177,6 +178,7 @@ namespace l1ct {
177178
inline float floatMeanZ(meanz_t meanz) { return meanz + MEANZ_OFFSET; };
178179
inline float floatHoe(hoe_t hoe) { return hoe.to_float(); };
179180
inline float floatIDScore(id_score_t score) { return score.to_float(); };
181+
inline float floatMass(mass2_t mass) { return mass.to_float(); }
180182

181183
inline pt_t makePt(int pt) { return ap_ufixed<16, 14>(pt) >> 2; }
182184
inline dpt_t makeDPt(int dpt) { return ap_fixed<18, 16>(dpt) >> 2; }

DataFormats/L1TParticleFlow/interface/gt_datatypes.h

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ namespace l1gt {
2727
// While bitwise identical to the l1ct::z0_t value, we store z0 in mm to profit of ap_fixed goodies
2828
typedef ap_fixed<10, 9, AP_RND_CONV, AP_SAT> z0_t; // NOTE: mm instead of cm!!!
2929
typedef ap_ufixed<8, 1, AP_RND, AP_SAT> id_proba_t; // for IDs bounded in range [0-1]
30+
typedef ap_ufixed<10, 1, AP_RND, AP_SAT> n_prong_score_t;
31+
typedef ap_ufixed<17, 15, AP_RND_CONV, AP_SAT> mass2_t;
3032
typedef ap_uint<1> valid_t;
3133

3234
// E/gamma fields
@@ -48,6 +50,7 @@ namespace l1gt {
4850
inline float floatEta(eta_t eta) { return eta.to_float() * ETAPHI_LSB; }
4951
inline float floatPhi(phi_t phi) { return phi.to_float() * ETAPHI_LSB; }
5052
inline float floatZ0(z0_t z0) { return z0.to_float() * Z0_UNITS; }
53+
inline float floatMassSq(mass2_t massSq) { return massSq.to_float(); }
5154
} // namespace Scales
5255

5356
struct ThreeVector {
@@ -151,8 +154,90 @@ namespace l1gt {
151154
return unpack_ap(bits);
152155
}
153156

157+
inline static Jet unpack(const std::array<long long unsigned int, 2> &src) {
158+
// unpack from two 64b ints
159+
ap_uint<BITWIDTH> bits;
160+
bits(63, 0) = src[0];
161+
bits(127, 64) = src[1];
162+
return unpack_ap(bits);
163+
}
164+
154165
}; // struct Jet
155166

167+
struct WideJet {
168+
valid_t valid;
169+
ThreeVector v3;
170+
z0_t z0;
171+
n_prong_score_t hwNProngScore;
172+
mass2_t hwMassSq;
173+
174+
inline bool operator==(const WideJet &other) const {
175+
return valid == other.valid && z0 == other.z0 && hwNProngScore == other.hwNProngScore &&
176+
hwMassSq == other.hwMassSq && v3 == other.v3;
177+
}
178+
179+
static const int BITWIDTH = 128;
180+
inline ap_uint<BITWIDTH> pack_ap() const {
181+
ap_uint<BITWIDTH> ret = 0;
182+
unsigned int start = 0;
183+
pack_into_bits(ret, start, valid);
184+
pack_into_bits(ret, start, v3.pack());
185+
pack_into_bits(ret, start, z0);
186+
pack_into_bits(ret, start, hwNProngScore);
187+
start = 64; // Start second word
188+
pack_into_bits(ret, start, hwMassSq);
189+
return ret;
190+
}
191+
192+
inline std::array<uint64_t, 2> pack() const {
193+
std::array<uint64_t, 2> packed;
194+
ap_uint<BITWIDTH> bits = this->pack_ap();
195+
packed[0] = bits(63, 0);
196+
packed[1] = bits(127, 64);
197+
return packed;
198+
}
199+
200+
inline static WideJet unpack_ap(const ap_uint<BITWIDTH> &src) {
201+
WideJet ret;
202+
ret.initFromBits(src);
203+
return ret;
204+
}
205+
206+
inline void initFromBits(const ap_uint<BITWIDTH> &src) {
207+
unsigned int start = 0;
208+
unpack_from_bits(src, start, valid);
209+
unpack_from_bits(src, start, v3.pt);
210+
unpack_from_bits(src, start, v3.phi);
211+
unpack_from_bits(src, start, v3.eta);
212+
unpack_from_bits(src, start, z0);
213+
unpack_from_bits(src, start, hwNProngScore);
214+
start = 64; // Start second word
215+
unpack_from_bits(src, start, hwMassSq);
216+
}
217+
218+
inline static WideJet unpack(const std::array<uint64_t, 2> &src) {
219+
ap_uint<BITWIDTH> bits;
220+
bits(63, 0) = src[0];
221+
bits(127, 64) = src[1];
222+
return unpack_ap(bits);
223+
}
224+
225+
inline static WideJet unpack(long long unsigned int &src) {
226+
// unpack from single 64b int
227+
ap_uint<BITWIDTH> bits = src;
228+
return unpack_ap(bits);
229+
}
230+
231+
inline static WideJet unpack(const std::array<long long unsigned int, 2> &src) {
232+
// unpack from two 64b ints
233+
ap_uint<BITWIDTH> bits;
234+
bits(63, 0) = src[0];
235+
bits(127, 64) = src[1];
236+
return unpack_ap(bits);
237+
}
238+
239+
}; // struct WideJet
240+
156241
struct Sum {
157242
valid_t valid;
158243
pt_t vector_pt;
@@ -394,6 +479,8 @@ namespace l1ct {
394479
return x * Scales::ETAPHI_CTtoGT_SCALE;
395480
}
396481

482+
inline l1gt::mass2_t CTtoGT_massSq(mass2_t x) { return (l1gt::mass2_t)x; }
483+
397484
} // namespace l1ct
398485

399486
#endif

DataFormats/L1TParticleFlow/interface/jets.h

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,11 @@ namespace l1ct {
5858

5959
static const unsigned NTagFields = 8;
6060
jet_tag_score_t hwTagScores[NTagFields];
61+
mass2_t hwMassSq;
6162

6263
inline bool operator==(const Jet &other) const {
63-
bool eq = hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwZ0 == other.hwZ0;
64+
bool eq = hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwMassSq == other.hwMassSq &&
65+
hwZ0 == other.hwZ0;
6466
for (unsigned i = 0; i < NTagFields; i++) {
6567
eq = eq && hwTagScores[i] == other.hwTagScores[i];
6668
}
@@ -74,6 +76,7 @@ namespace l1ct {
7476
hwPt = 0;
7577
hwEta = 0;
7678
hwPhi = 0;
79+
hwMassSq = 0;
7780
hwZ0 = 0;
7881
for (unsigned i = 0; i < NTagFields; i++) {
7982
hwTagScores[i] = 0;
@@ -87,6 +90,7 @@ namespace l1ct {
8790
float floatEta() const { return Scales::floatEta(hwEta); }
8891
float floatPhi() const { return Scales::floatPhi(hwPhi); }
8992
float floatZ0() const { return Scales::floatZ0(hwZ0); }
93+
float floatMass() const { return Scales::floatMass(hwMassSq); }
9094
std::vector<float> floatIDScores() const {
9195
std::vector<float> scores(NTagFields);
9296
for (unsigned i = 0; i < NTagFields; i++) {
@@ -96,13 +100,15 @@ namespace l1ct {
96100
}
97101

98102
static const int BITWIDTH =
99-
pt_t::width + glbeta_t::width + glbphi_t::width + z0_t::width + NTagFields * id_score_t::width;
103+
pt_t::width + glbeta_t::width + glbphi_t::width + mass2_t::width + z0_t::width + NTagFields * id_score_t::width;
104+
100105
inline ap_uint<BITWIDTH> pack_ap() const {
101106
ap_uint<BITWIDTH> ret;
102107
unsigned int start = 0;
103108
pack_into_bits(ret, start, hwPt);
104109
pack_into_bits(ret, start, hwEta);
105110
pack_into_bits(ret, start, hwPhi);
111+
pack_into_bits(ret, start, hwMassSq);
106112
pack_into_bits(ret, start, hwZ0);
107113
for (unsigned i = 0; i < NTagFields; i++) {
108114
pack_into_bits(ret, start, hwTagScores[i]);
@@ -130,6 +136,7 @@ namespace l1ct {
130136
unpack_from_bits(src, start, hwEta);
131137
unpack_from_bits(src, start, hwPhi);
132138
unpack_from_bits(src, start, hwZ0);
139+
unpack_from_bits(src, start, hwMassSq);
133140
for (unsigned i = 0; i < NTagFields; i++) {
134141
unpack_from_bits(src, start, hwTagScores[i]);
135142
}
@@ -149,6 +156,14 @@ namespace l1ct {
149156
return unpack_ap(bits);
150157
}
151158

159+
inline static Jet unpack(const std::array<long long unsigned int, 2> &src) {
160+
// unpack from two 64b ints
161+
ap_uint<BITWIDTH> bits;
162+
bits(63, 0) = src[0];
163+
// bits(127, 64) = src[1];
164+
return unpack_ap(bits);
165+
}
166+
152167
l1gt::Jet toGT() const {
153168
l1gt::Jet j;
154169
j.valid = hwPt != 0;
@@ -161,6 +176,19 @@ namespace l1ct {
161176
}
162177
return j;
163178
}
179+
180+
l1gt::WideJet toGTWide() const {
181+
l1gt::WideJet j;
182+
j.valid = hwPt != 0;
183+
j.v3.pt = CTtoGT_pt(hwPt);
184+
j.v3.phi = CTtoGT_phi(hwPhi);
185+
j.v3.eta = CTtoGT_eta(hwEta);
186+
j.z0(l1ct::z0_t::width - 1, 0) = hwZ0(l1ct::z0_t::width - 1, 0);
187+
j.hwNProngScore = 0;
188+
j.hwMassSq = CTtoGT_massSq(hwMassSq);
189+
190+
return j;
191+
}
164192
};
165193

166194
inline void clear(Jet &c) { c.clear(); }

DataFormats/L1TParticleFlow/src/classes_def.xml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@
3535
<class name="l1t::RegionalOutput<l1t::PFCandidateCollection>" />
3636
<class name="edm::Wrapper<l1t::RegionalOutput<l1t::PFCandidateCollection>>" />
3737

38-
<class name="l1t::PFJet" ClassVersion="7">
39-
<version ClassVersion="7" checksum="2216717791"/>
38+
<class name="l1t::PFJet" ClassVersion="8">
39+
<version ClassVersion="8" checksum="2216717794"/>
40+
<version ClassVersion="7" checksum="2216717791"/>
4041
<version ClassVersion="6" checksum="2599349078"/>
4142
<version ClassVersion="5" checksum="2270932343"/>
4243
<version ClassVersion="4" checksum="1424452548"/>

L1Trigger/Configuration/python/SimL1Emulator_cff.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@
253253
# PF MET
254254
# ########################################################################
255255
from L1Trigger.Phase2L1ParticleFlow.l1pfJetMet_cff import *
256+
_phase2_siml1emulator.add(L1TPFJetsTask)
256257
_phase2_siml1emulator.add(L1TPFJetsEmulationTask)
257258

258259
from L1Trigger.Phase2L1ParticleFlow.l1tMETPFProducer_cfi import *

L1Trigger/Phase2L1ParticleFlow/interface/jetmet/L1SeedConePFJetEmulator.h

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef L1Trigger_Phase2L1ParticleFlow_L1SeedConePFJetEmulator_h
22
#define L1Trigger_Phase2L1ParticleFlow_L1SeedConePFJetEmulator_h
33

4+
#define NCONSTITSFW 32 // DEFINE THE MAXIMUM NUMBER OF CONSTITUENTS USED TO CALCULATE THE JET MASS
5+
46
#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h"
57
#include "DataFormats/L1TParticleFlow/interface/jets.h"
68

@@ -21,6 +23,18 @@ class L1SCJetEmu {
2123
typedef ap_int<13> detaphi_t; // Type for deta & dphi
2224
typedef ap_fixed<18, 23> detaphi2_t; // Type for deta^2 & dphi^2
2325
typedef ap_fixed<22, 22> pt_etaphi_t; // Type for product of pt with deta & dphi
26+
27+
typedef ap_ufixed<13, 1, AP_RND, AP_SAT>
28+
eventrig_t; // stores values between 0 and 2, - 0 bit for sign, - 1 bit for integer, leaves 12 for frac
29+
typedef ap_fixed<13, 1, AP_RND, AP_SAT>
30+
oddtrig_t; // stores values between -1 and 1, 13 - 1 bit for sign, - 0 bits for integer, leaves 12 for frac
31+
32+
// typedef l1ct::mass_t mass_t; // stores values up to ~1 TeV, 18 bits - 0 for sign, - 10 for integer, 14 total bits improves performance
33+
typedef l1ct::mass2_t mass2_t;
34+
35+
typedef ap_ufixed<20, 12, AP_TRN, AP_SAT> ppt_t; // stores values between -1 and 1
36+
typedef ap_fixed<22, 14, AP_TRN, AP_SAT> npt_t; // stores values between -1 and 1 JUST REDUCED BY 2
37+
2438
typedef l1ct::PuppiObjEmu Particle;
2539

2640
class Jet : public l1ct::Jet {
@@ -43,6 +57,7 @@ class L1SCJetEmu {
4357
typedef ap_ufixed<18, -2> inv_pt_t;
4458
static constexpr int N_table_inv_pt = 1024;
4559
inv_pt_t inv_pt_table_[N_table_inv_pt];
60+
static constexpr int hwEtaPhi_steps = 185; // corresponds to eta/phi range of 0 to 0.8
4661

4762
static constexpr int ceillog2(int x) { return (x <= 2) ? 1 : 1 + ceillog2((x + 1) / 2); }
4863

@@ -142,10 +157,20 @@ class L1SCJetEmu {
142157
return out;
143158
}
144159

160+
template <typename lut_T, int N>
161+
static std::array<lut_T, N> init_trig_lut(lut_T (*func)(float)) {
162+
std::array<lut_T, N> lut;
163+
for (int hwEtaPhi = 0; hwEtaPhi < N; hwEtaPhi++) {
164+
lut[hwEtaPhi] = func(hwEtaPhi * l1ct::Scales::ETAPHI_LSB);
165+
}
166+
return lut;
167+
}
168+
145169
static detaphi_t deltaPhi(Particle a, Particle b);
146170
bool inCone(Particle seed, Particle part) const;
147-
Jet makeJet_HW(const std::vector<Particle>& parts) const;
148-
171+
std::vector<Particle> sortConstituents(const std::vector<Particle>& parts, const Particle seed) const;
172+
mass2_t jetMass_HW(const std::vector<Particle>& parts) const;
173+
Jet makeJet_HW(const std::vector<Particle>& parts, const Particle seed) const;
149174
}; // class L1SCJetEmu
150175

151176
#endif

0 commit comments

Comments
 (0)