1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
#ifndef DataFormats_L1TCalorimeterPhase2_DigitizedTowerCorrelator_h
#define DataFormats_L1TCalorimeterPhase2_DigitizedTowerCorrelator_h
#include <ap_int.h>
#include <vector>
namespace l1tp2 {
class DigitizedTowerCorrelator {
private:
// Data
unsigned int towerData;
unsigned int idxCard; // 0, 1, or 2 (there are three GCT cards)
unsigned int idxFiber; // 0 to 47 (there are 48 fibers in one GCT card)
unsigned int idxTower; // 0 to 16 (there are 17 towers in one fiber)
// Constants
static constexpr float LSB_ET = 0.5; // 0.5 GeV, so max value is (2^10 - 1) * 0.5 = 511.5 GeV
static constexpr unsigned int n_bits_pt = 10;
static constexpr unsigned int n_towers_in_fiber = 17;
static constexpr unsigned int n_fibers_in_card = 48;
static constexpr unsigned int n_cards = 3;
// Private member functions to perform digitization
ap_uint<10> digitizeEt(float et_f) {
float maxEt_f = (std::pow(2, n_bits_pt) - 1) * LSB_ET;
// If pT exceeds the maximum, saturate the value
if (et_f >= maxEt_f) {
return (ap_uint<10>)0x3FF;
}
return (ap_uint<10>)(et_f / LSB_ET);
}
ap_uint<4> digitizeHoE(ap_uint<4> hoe) { return (ap_uint<4>)hoe; }
// To-do: FB not implemented yet
ap_uint<2> digitizeFB(ap_uint<2> fb) { return (ap_uint<2>)fb; }
public:
DigitizedTowerCorrelator() { towerData = 0x0; }
DigitizedTowerCorrelator(ap_uint<16> data) { towerData = data; }
// Constructor from digitized inputs
DigitizedTowerCorrelator(ap_uint<10> et,
ap_uint<4> hoe,
ap_uint<2> fb,
unsigned int indexCard,
unsigned int indexFiber,
unsigned int indexTower,
bool fullyDigitizedInputs) {
(void)fullyDigitizedInputs;
towerData = ((ap_uint<16>)et) | (((ap_uint<16>)hoe) << 10) | (((ap_uint<16>)fb) << 14);
idxCard = indexCard;
idxFiber = indexFiber;
idxTower = indexTower;
assert(hasValidIndices());
}
// Constructor from float inputs
DigitizedTowerCorrelator(float et_f,
ap_uint<4> hoe,
ap_uint<2> fb,
unsigned int indexCard,
unsigned int indexFiber,
unsigned int indexTower) {
towerData = ((ap_uint<16>)digitizeEt(et_f)) | (((ap_uint<16>)hoe) << 10) | (((ap_uint<16>)fb) << 14);
idxCard = indexCard;
idxFiber = indexFiber;
idxTower = indexTower;
assert(hasValidIndices());
}
ap_uint<16> data() const { return towerData; }
// Other getters
float etLSB() const { return LSB_ET; }
ap_uint<10> et() const { return (towerData & 0x3FF); } // ten 1's = 0x3FF
ap_uint<4> hoe() const { return ((towerData >> 10) & 0xF); } // four 1's= 0xF
ap_uint<2> fb() const { return ((towerData >> 14) & 0x3); } // two 1's = 0x3
float etFloat() const { return et() * etLSB(); }
unsigned int cardNumber() const { return idxCard; } // GCT card number
unsigned int fiberNumber() const { return idxFiber; } // fiber number in card (hardware convention)
unsigned int towerNumber() const { return idxTower; } // tower number in fiber (hardware convention)
// Other checks
bool hasValidIndices(void) const {
return (idxTower < n_towers_in_fiber) && (idxFiber < n_fibers_in_card) && (idxCard < n_cards);
}
};
// Collection typedef
typedef std::vector<l1tp2::DigitizedTowerCorrelator> DigitizedTowerCorrelatorCollection;
} // namespace l1tp2
#endif
|