Skip to content

Commit 97dff05

Browse files
authored
Merge pull request #47193 from skkwan/add-phase2-gct-interface-to-correlator-pr
update GCT eg and hadronic cluster interface to Correlator
2 parents 538ac87 + 413761f commit 97dff05

File tree

9 files changed

+796
-24
lines changed

9 files changed

+796
-24
lines changed

DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ namespace l1tp2 {
118118
// Other getters
119119
float ptLSB() const { return LSB_PT; }
120120
ap_uint<12> pt() const { return (clusterData & 0xFFF); }
121+
float ptFloat() const { return (pt() * ptLSB()); }
121122

122123
// crystal eta in the correlator region (LSB: 2.8/170)
123124
ap_uint<8> eta() const { return ((clusterData >> 12) & 0xFF); } // (eight 1's) 0b11111111 = 0xFF
@@ -161,7 +162,8 @@ namespace l1tp2 {
161162
bool passNullBitsCheck(void) const { return ((data() >> unusedBitsStart()) == 0x0); }
162163

163164
// Get real eta (does not depend on card number). crystal iEta = 0 starts at real eta -1.4841.
164-
float realEta() const { return (float)((-1 * ETA_RANGE_ONE_SIDE) + (eta() * LSB_ETA)); }
165+
// LSB_ETA/2 is to add half a crystal width to get the center of the crystal in eta
166+
float realEta() const { return (float)((-1 * ETA_RANGE_ONE_SIDE) + (eta() * LSB_ETA) + (LSB_ETA / 2)); }
165167

166168
// Get real phi (uses card number).
167169
float realPhi() const {
@@ -176,7 +178,8 @@ namespace l1tp2 {
176178
}
177179
int thisPhi = (phi() + (offset_tower * n_crystals_in_tower));
178180
// crystal iPhi = 0 starts at real phi = -180 degrees
179-
return (float)((-1 * M_PI) + (thisPhi * LSB_PHI));
181+
// LSB_PHI/2 is to add half a crystal width to get the center of the crystal in phi
182+
return (float)((-1 * M_PI) + (thisPhi * LSB_PHI) + (LSB_PHI / 2));
180183
}
181184
};
182185

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#ifndef DataFormats_L1TCalorimeterPhase2_GCTEmDigiCluster_h
2+
#define DataFormats_L1TCalorimeterPhase2_GCTEmDigiCluster_h
3+
4+
#include <ap_int.h>
5+
#include <vector>
6+
7+
#include "DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h"
8+
#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h"
9+
10+
namespace l1tp2 {
11+
12+
class GCTEmDigiCluster {
13+
private:
14+
// Data
15+
unsigned long long int clusterData;
16+
17+
// Constants
18+
static constexpr float LSB_PT = 0.5; // 0.5 GeV
19+
20+
// start of the unused bits
21+
static constexpr int n_bits_unused_start = 52;
22+
23+
// Reference to the original float cluster
24+
edm::Ref<l1tp2::CaloCrystalClusterCollection> clusterRef_;
25+
26+
// reference to the original digitized cluster (before duplication in the output links)
27+
edm::Ref<l1tp2::DigitizedClusterCorrelatorCollection> digiClusterRef_;
28+
29+
public:
30+
GCTEmDigiCluster() { clusterData = 0; }
31+
32+
GCTEmDigiCluster(ap_uint<64> data) { clusterData = data; }
33+
34+
GCTEmDigiCluster(ap_uint<12> pt,
35+
int etaCr,
36+
int phiCr,
37+
ap_uint<4> hoe,
38+
ap_uint<2> hoeFlag,
39+
ap_uint<3> iso,
40+
ap_uint<2> isoFlag,
41+
ap_uint<6> fb,
42+
ap_uint<5> timing,
43+
ap_uint<2> shapeFlag,
44+
ap_uint<2> brems) {
45+
// To use .range() we need an ap class member
46+
ap_uint<64> temp_data;
47+
ap_uint<7> etaCrDigitized = abs(etaCr);
48+
ap_int<7> phiCrDigitized = phiCr;
49+
50+
temp_data.range(11, 0) = pt.range();
51+
temp_data.range(18, 12) = etaCrDigitized.range();
52+
temp_data.range(25, 19) = phiCrDigitized.range();
53+
temp_data.range(29, 26) = hoe.range();
54+
temp_data.range(31, 30) = hoeFlag.range();
55+
temp_data.range(34, 32) = iso.range();
56+
temp_data.range(36, 35) = isoFlag.range();
57+
temp_data.range(42, 37) = fb.range();
58+
temp_data.range(47, 43) = timing.range();
59+
temp_data.range(49, 48) = shapeFlag.range();
60+
temp_data.range(51, 50) = brems.range();
61+
62+
clusterData = temp_data;
63+
}
64+
65+
// Setters
66+
void setRef(const edm::Ref<l1tp2::CaloCrystalClusterCollection>& clusterRef) { clusterRef_ = clusterRef; }
67+
68+
void setDigiRef(const edm::Ref<l1tp2::DigitizedClusterCorrelatorCollection>& digiClusterRef) {
69+
digiClusterRef_ = digiClusterRef;
70+
}
71+
72+
// Getters
73+
ap_uint<64> data() const { return clusterData; }
74+
75+
// Other getters
76+
float ptLSB() const { return LSB_PT; }
77+
ap_uint<12> pt() const { return data().range(11, 0); }
78+
float ptFloat() const { return pt() * ptLSB(); }
79+
80+
// crystal eta (unsigned, 7 bits), starting at 0 at real eta = 0, and increasing in the direction of larger abs(real eta)
81+
// to convert to real eta, need to know which link this cluster is in
82+
int eta() const { return (ap_uint<7>)data().range(18, 12); }
83+
84+
// crystal phi (signed, 7 bits), relative to center of the SLR
85+
// to convert to real phi, need to know which SLR this cluster is in
86+
int phi() const { return (ap_int<7>)data().range(25, 19); }
87+
88+
// HoE value and flag: not defined yet in the emulator
89+
ap_uint<4> hoe() const { return data().range(29, 26); }
90+
ap_uint<2> hoeFlag() const { return data().range(31, 30); }
91+
92+
// Raw isolation sum: not saved in the emulator
93+
ap_uint<3> iso() const { return data().range(34, 32); }
94+
95+
// iso flag: two bits, least significant bit is the standalone WP (true or false), second bit is the looseTk WP (true or false)
96+
// e.g. 0b01 : standalone iso flag passed, loose Tk iso flag did not pass
97+
ap_uint<2> isoFlags() const { return data().range(36, 35); }
98+
bool passes_iso() const { return (isoFlags() & 0x1); } // standalone iso WP
99+
bool passes_looseTkiso() const { return (isoFlags() & 0x2); } // loose Tk iso WP
100+
101+
// fb and timing: not saved in the current emulator
102+
ap_uint<6> fb() const { return data().range(42, 37); }
103+
ap_uint<5> timing() const { return data().range(47, 43); }
104+
105+
// shower shape shape flag: two bits, least significant bit is the standalone WP, second bit is the looseTk WP
106+
// e.g. 0b01 : standalone shower shape flag passed, loose Tk shower shape flag did not pass
107+
ap_uint<2> shapeFlags() const { return data().range(49, 48); }
108+
109+
bool passes_ss() const { return (shapeFlags() & 0x1); } // standalone shower shape WP
110+
bool passes_looseTkss() const { return (shapeFlags() & 0x2); } // loose Tk shower shape WP
111+
112+
// brems: not saved in the current emulator
113+
ap_uint<2> brems() const { return data().range(51, 50); }
114+
115+
// Check that unused bits are zero
116+
const int unusedBitsStart() const { return n_bits_unused_start; }
117+
bool passNullBitsCheck(void) const { return ((data() >> unusedBitsStart()) == 0); }
118+
119+
// Get the underlying float cluster
120+
const edm::Ref<l1tp2::CaloCrystalClusterCollection>& clusterRef() const { return clusterRef_; }
121+
// Get the underlying digitized cluster (before duplication and zero-padding)
122+
const edm::Ref<l1tp2::DigitizedClusterCorrelatorCollection>& digiClusterRef() const { return digiClusterRef_; }
123+
};
124+
125+
// Collection typedefs
126+
127+
// This represents the 36 GCTEmDigiClusters in one link (one link spans 4 RCT cards, each RCT card sends 9 clusters (zero-padded and sorted by decreasing pT))
128+
// The ordering of the 4 RCT cards in the link is, e.g. for GCT1.SLR3, real phi -50 to -20 degrees, then real phi -20 to 10 degrees, then real phi 10 to 40 degrees, and lastly real phi 40 to 70 degrees
129+
typedef std::vector<l1tp2::GCTEmDigiCluster> GCTEmDigiClusterLink;
130+
131+
// This represents the 12 links sending GCTEmDigiClusters in the full barrel: there are 12 links = (3 GCT cards) * (two SLRs per GCT) * (one positive eta link and one negative eta link)
132+
// The ordering of the links in this std::vector is (GCT1.SLR1 negEta, GCT.SLR1 posEta, GCT1.SLR3 negEta, GCT1.SLR3 posEta, then analogously for GCT2 and GCT3)
133+
typedef std::vector<l1tp2::GCTEmDigiClusterLink> GCTEmDigiClusterCollection;
134+
135+
} // namespace l1tp2
136+
137+
#endif
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#ifndef DataFormats_L1TCalorimeterPhase2_GCTHadDigiCluster_h
2+
#define DataFormats_L1TCalorimeterPhase2_GCTHadDigiCluster_h
3+
4+
#include <ap_int.h>
5+
#include <vector>
6+
7+
#include "DataFormats/L1TCalorimeterPhase2/interface/CaloPFCluster.h"
8+
9+
namespace l1tp2 {
10+
11+
class GCTHadDigiCluster {
12+
private:
13+
// Data
14+
unsigned long long int clusterData;
15+
16+
// Constants
17+
static constexpr float LSB_PT = 0.5; // 0.5 GeV
18+
19+
// start of the unused bits
20+
static constexpr int n_bits_unused_start = 31;
21+
22+
// reference to corresponding float cluster
23+
edm::Ref<l1tp2::CaloPFClusterCollection> clusterRef_;
24+
25+
public:
26+
GCTHadDigiCluster() { clusterData = 0; }
27+
28+
GCTHadDigiCluster(ap_uint<64> data) { clusterData = data; }
29+
30+
// Note types of the constructor
31+
GCTHadDigiCluster(ap_uint<12> pt, int etaCr, int phiCr, ap_uint<4> hoe) {
32+
// To use .range() we need an ap class member
33+
ap_uint<64> temp_data;
34+
35+
ap_uint<7> etaCrDigitized = abs(etaCr);
36+
ap_int<7> phiCrDigitized = phiCr;
37+
38+
temp_data.range(11, 0) = pt.range();
39+
temp_data.range(18, 12) = etaCrDigitized.range();
40+
temp_data.range(25, 19) = phiCrDigitized.range();
41+
42+
clusterData = temp_data;
43+
}
44+
45+
// Setters
46+
void setRef(const edm::Ref<l1tp2::CaloPFClusterCollection> &clusterRef) { clusterRef_ = clusterRef; }
47+
// Getters
48+
ap_uint<64> data() const { return clusterData; }
49+
50+
// Other getters
51+
float ptLSB() const { return LSB_PT; }
52+
ap_uint<12> pt() const { return data().range(11, 0); }
53+
float ptFloat() const { return pt() * ptLSB(); }
54+
55+
// crystal eta (unsigned 7 bits)
56+
int eta() const { return (ap_uint<7>)data().range(18, 12); }
57+
58+
// crystal phi (signed 7 bits)
59+
int phi() const { return (ap_int<7>)data().range(25, 19); }
60+
61+
// HoE value
62+
ap_uint<4> hoe() const { return data().range(30, 26); }
63+
64+
// Check that unused bits are zero
65+
const int unusedBitsStart() const { return n_bits_unused_start; }
66+
bool passNullBitsCheck(void) const { return ((data() >> unusedBitsStart()) == 0); }
67+
68+
// Get the underlying ref
69+
edm::Ref<l1tp2::CaloPFClusterCollection> clusterRef() const { return clusterRef_; }
70+
};
71+
72+
// Collection typedefs
73+
74+
// This represents the 36 GCTHadDigiClusters in one link (one link spans 4 RCT cards, each RCT card sends 9 clusters (zero-padded and sorted by decreasing pT)
75+
// The ordering of the 4 RCT cards in this std::vector is, e.g. for GCT1.SLR3, real phi -50 to -20 degrees, then real phi -20 to 10 degrees, then real phi 10 to 40 degrees, and lastly real phi 40 to 70 degrees
76+
typedef std::vector<l1tp2::GCTHadDigiCluster> GCTHadDigiClusterLink;
77+
78+
// This represents the 12 links sending GCTHadDigiClusters in the full barrel: there are 12 links = (3 GCT cards) * (two SLRs per GCT) * (one positive eta link and one negative eta link)
79+
// The ordering of the links in this std::vector is (GCT1.SLR1 negEta, GCT.SLR1 posEta, GCT1.SLR3 negEta, GCT1.SLR3 posEta, then analogously for GCT2 and GCT3)
80+
typedef std::vector<l1tp2::GCTHadDigiClusterLink> GCTHadDigiClusterCollection;
81+
82+
} // namespace l1tp2
83+
84+
#endif

DataFormats/L1TCalorimeterPhase2/src/classes.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
/*********************/
1010

1111
#include "DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h"
12-
#include "DataFormats/L1TCalorimeterPhase2/interface/CaloTower.h"
12+
#include "DataFormats/L1TCalorimeterPhase2/interface/CaloPFCluster.h"
1313
#include "DataFormats/L1TCalorimeterPhase2/interface/CaloJet.h"
14+
#include "DataFormats/L1TCalorimeterPhase2/interface/CaloTower.h"
1415
#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h"
15-
#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedTowerCorrelator.h"
1616
#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterGT.h"
17-
#include "DataFormats/L1TCalorimeterPhase2/interface/CaloPFCluster.h"
17+
#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedTowerCorrelator.h"
18+
#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h"
19+
#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h"
1820
#include "DataFormats/L1TCalorimeterPhase2/interface/Phase2L1CaloJet.h"

DataFormats/L1TCalorimeterPhase2/src/classes_def.xml

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,7 @@
1010
<class name="std::vector<l1tp2::CaloCrystalCluster>" />
1111
<class name="l1tp2::CaloCrystalClusterCollection" />
1212
<class name="edm::Wrapper<l1tp2::CaloCrystalClusterCollection>" />
13-
14-
<class name="l1tp2::CaloTower" ClassVersion="3">
15-
<version ClassVersion="3" checksum="2608605419"/>
16-
</class>
17-
<class name="std::vector<l1tp2::CaloTower>" />
18-
<class name="l1tp2::CaloTowerCollection" />
19-
<class name="edm::Wrapper<l1tp2::CaloTowerCollection>" />
13+
<class name="edm::Ref<l1tp2::CaloCrystalClusterCollection>" />
2014

2115
<class name="l1tp2::CaloJet" ClassVersion="3">
2216
<version ClassVersion="3" checksum="2520028496"/>
@@ -25,19 +19,35 @@
2519
<class name="l1tp2::CaloJetsCollection" />
2620
<class name="edm::Wrapper<l1tp2::CaloJetsCollection>" />
2721

22+
<class name="l1tp2::CaloPFCluster" ClassVersion="3">
23+
<version ClassVersion="3" checksum="4176166177"/>
24+
</class>
25+
<class name="std::vector<l1tp2::CaloPFCluster>" />
26+
<class name="l1tp2::CaloPFClusterCollection" />
27+
<class name="edm::Wrapper<l1tp2::CaloPFClusterCollection>" />
28+
<class name="edm::Ref<l1tp2::CaloPFClusterCollection>" />
29+
30+
<class name="l1tp2::GCTHadDigiCluster" />
31+
<class name="std::vector<l1tp2::GCTHadDigiCluster>" />
32+
<class name="l1tp2::GCTHadDigiClusterLink" />
33+
<class name="edm::Wrapper<l1tp2::GCTHadDigiClusterLink>" />
34+
<class name="l1tp2::GCTHadDigiClusterCollection" />
35+
<class name="edm::Wrapper<std::vector<std::vector<l1tp2::GCTHadDigiCluster> > >" />
36+
37+
<class name="l1tp2::CaloTower" ClassVersion="3">
38+
<version ClassVersion="3" checksum="2608605419"/>
39+
</class>
40+
<class name="std::vector<l1tp2::CaloTower>" />
41+
<class name="l1tp2::CaloTowerCollection" />
42+
<class name="edm::Wrapper<l1tp2::CaloTowerCollection>" />
43+
2844
<class name="l1tp2::DigitizedClusterCorrelator" ClassVersion="4">
2945
<version ClassVersion="4" checksum="838642806"/>
3046
<version ClassVersion="3" checksum="1943292648"/>
3147
</class>
3248
<class name="l1tp2::DigitizedClusterCorrelatorCollection" />
3349
<class name="edm::Wrapper<l1tp2::DigitizedClusterCorrelatorCollection>" />
34-
35-
<class name="l1tp2::DigitizedTowerCorrelator" ClassVersion="4">
36-
<version ClassVersion="4" checksum="1597735835"/>
37-
<version ClassVersion="3" checksum="3734711406"/>
38-
</class>
39-
<class name="l1tp2::DigitizedTowerCorrelatorCollection" />
40-
<class name="edm::Wrapper<l1tp2::DigitizedTowerCorrelatorCollection>" />
50+
<class name="edm::Ref<l1tp2::DigitizedClusterCorrelatorCollection>" />
4151

4252
<class name="l1tp2::DigitizedClusterGT" ClassVersion="4">
4353
<version ClassVersion="4" checksum="2603854524"/>
@@ -46,12 +56,19 @@
4656
<class name="l1tp2::DigitizedClusterGTCollection" />
4757
<class name="edm::Wrapper<l1tp2::DigitizedClusterGTCollection>" />
4858

49-
<class name="l1tp2::CaloPFCluster" ClassVersion="3">
50-
<version ClassVersion="3" checksum="4176166177"/>
59+
60+
<class name="l1tp2::DigitizedTowerCorrelator" ClassVersion="4">
61+
<version ClassVersion="4" checksum="1597735835"/>
62+
<version ClassVersion="3" checksum="3734711406"/>
5163
</class>
52-
<class name="std::vector<l1tp2::CaloPFCluster>" />
53-
<class name="l1tp2::CaloPFClusterCollection" />
54-
<class name="edm::Wrapper<l1tp2::CaloPFClusterCollection>" />
64+
<class name="l1tp2::DigitizedTowerCorrelatorCollection" />
65+
<class name="edm::Wrapper<l1tp2::DigitizedTowerCorrelatorCollection>" />
66+
67+
<class name="l1tp2::GCTEmDigiCluster" />
68+
<class name="std::vector<l1tp2::GCTEmDigiCluster>" />
69+
<class name="l1tp2::GCTEmDigiClusterLink" />
70+
<class name="std::vector<l1tp2::GCTEmDigiClusterLink>" />
71+
<class name="edm::Wrapper<std::vector<std::vector<l1tp2::GCTEmDigiCluster> > >" />
5572

5673
<class name="l1tp2::Phase2L1CaloJet" ClassVersion="3">
5774
<version ClassVersion="3" checksum="289384850"/>
@@ -60,5 +77,6 @@
6077
<class name="l1tp2::Phase2L1CaloJetCollection" />
6178
<class name="edm::Wrapper<l1tp2::Phase2L1CaloJetCollection>" />
6279

80+
6381
</lcgdict>
6482

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#ifndef PHASE_2_L1_CALO_BARREL_TO_CORRELATOR
2+
#define PHASE_2_L1_CALO_BARREL_TO_CORRELATOR
3+
4+
#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h"
5+
#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h"
6+
7+
#include "L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h"
8+
9+
/*
10+
* Returns the difference in the azimuth coordinates of phi1 and phi2 (all in degrees not radians), taking the wrap-around at 180 degrees into account
11+
*/
12+
inline float p2eg::deltaPhiInDegrees(float phi1, float phi2, const float c = 180) {
13+
float r = std::fmod(phi1 - phi2, 2.0 * c);
14+
if (r < -c) {
15+
r += 2.0 * c;
16+
} else if (r > c) {
17+
r -= 2.0 * c;
18+
}
19+
return r;
20+
}
21+
22+
/*
23+
* For a given phi in degrees (e.g. computed from some difference), return the phi (in degrees) which takes the wrap-around at 180 degrees into account
24+
*/
25+
inline float p2eg::wrappedPhiInDegrees(float phi) { return p2eg::deltaPhiInDegrees(phi, 0); }
26+
27+
#endif

0 commit comments

Comments
 (0)