ATLAS Offline Software
Loading...
Searching...
No Matches
TrigT1NSWSimExtras.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4#ifndef TRIGT1NSWSIMEXTRAS_H
5#define TRIGT1NSWSIMEXTRAS_H
6
7#include <algorithm>
8#include <array>
9#include <cstdint>
10#include <unordered_map>
11#include <iomanip>
12#include <cmath>
13#include <set>
14#include <sstream>
15#include <string>
16#include <vector>
18
26
27namespace NSWL1 {
28 // Space
29 const std::string SPACE{" "};
30
31 // Underscore
32 const std::string UNDERSCORE{"_"};
33
34 // Comma
35 const std::string COMMA{","};
36
37 // Semicolon
38 const std::string SEMICOLON{";"};
39
40 // VHDL comment
41 const std::string VHDLCOMMENT{"--"};
42
43 // Wheels
44 const std::vector<std::string> WHEELS{"A", "C"};
45
46 // Number of layers/sectors per wheel
47 constexpr uint32_t NLAYERS{8};
48 constexpr uint32_t NSECTORS{16};
49
50 // Sector name
51 inline std::string sectorName(const std::string& wheel, const uint32_t sec) {
52 std::stringstream ss;
53 ss << wheel;
54 ss << std::setfill('0') << std::setw(2) << (sec + 1);
55 return ss.str();
56 }
57
58 // Switch to int phiID
59 inline int getSignedPhiID(const uint32_t phiid) {
60 // 1 bit of sign (0 = positive) followed by 5 bits of phiid
61 constexpr size_t nbitsPhi{5};
62 constexpr size_t mask{(1 << nbitsPhi) - 1};
63 return std::pow(-1, phiid >> nbitsPhi) * (phiid & mask);
64 }
65
66 // Pad specific conventions
67 namespace PAD {
68 // Large - Small
69 const std::string LARGE{"large"};
70 const std::string SMALL{"small"};
71
72 // Allowed layers
73 constexpr std::array<uint32_t, NLAYERS> LAYERS{0, 1, 2, 3, 4, 5, 6, 7};
74
75 // Number of sectors
76 constexpr std::array<uint32_t, NSECTORS> SECTORS{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
77
78 // Unpacking pad patterns from vhd file (start)
79 const std::string PATTERN_TAG{"pad_trigger_pattern_array :="};
80
81 // Unpacking pad patterns from vhd file (our signal that all the useful blocks are done)
82 const std::string PATTERN_END{"bandid_tds_numbers"};
83
84 // Expected length of 1 line of pattern info: pfeb0, chan0, ..., pfeb7, chan7, phiid
85 constexpr size_t PATTERNLEN{17};
86
87 // Source ID from wheel + sector
88 inline uint32_t wheelSectorToSourceID(const char wheel, const uint32_t sector) {
89 uint32_t prefix = 0x6d0020;
90 if(wheel == 'C') prefix += (1<<16);
91 return prefix+sector;
92 }
93
94 // Calculate pFEB
95 inline uint32_t getpFEBAthena(const int gas_gap, const int multiplet, const int stationEta) {
96 const auto layer = (multiplet-1)*4 + (gas_gap-1);
97 uint32_t pfeb = (std::abs(stationEta)-1)*8 + layer;
98 return pfeb;
99 }
100
101 inline std::pair<int,int> getNrowsNcols(const int pfeb, const bool isLarge) {
102 if (isLarge) {
103 if(pfeb == 0) return std::make_pair(17, 6);
104 if(pfeb == 1) return std::make_pair(17, 6);
105 if(pfeb == 2) return std::make_pair(16, 7);
106 if(pfeb == 3) return std::make_pair(16, 7);
107 if(pfeb == 4) return std::make_pair(16, 6);
108 if(pfeb == 5) return std::make_pair(16, 6);
109 if(pfeb == 6) return std::make_pair(16, 6);
110 if(pfeb == 7) return std::make_pair(16, 6);
111 if(pfeb == 8) return std::make_pair(14, 4);
112 if(pfeb == 9) return std::make_pair(14, 4);
113 if(pfeb == 10) return std::make_pair(15, 5);
114 if(pfeb == 11) return std::make_pair(15, 5);
115 if(pfeb == 12) return std::make_pair(14, 4);
116 if(pfeb == 13) return std::make_pair(14, 4);
117 if(pfeb == 14) return std::make_pair(14, 4);
118 if(pfeb == 15) return std::make_pair(14, 4);
119 if(pfeb == 16) return std::make_pair(15, 4);
120 if(pfeb == 17) return std::make_pair(15, 4);
121 if(pfeb == 18) return std::make_pair(14, 5);
122 if(pfeb == 19) return std::make_pair(14, 5);
123 if(pfeb == 20) return std::make_pair(13, 4);
124 if(pfeb == 21) return std::make_pair(13, 4);
125 if(pfeb == 22) return std::make_pair(14, 4);
126 if(pfeb == 23) return std::make_pair(14, 4);
127 }
128 else {
129 if(pfeb == 0) return std::make_pair(17, 4);
130 if(pfeb == 1) return std::make_pair(17, 4);
131 if(pfeb == 2) return std::make_pair(18, 4);
132 if(pfeb == 3) return std::make_pair(18, 4);
133 if(pfeb == 4) return std::make_pair(17, 4);
134 if(pfeb == 5) return std::make_pair(17, 4);
135 if(pfeb == 6) return std::make_pair(17, 3);
136 if(pfeb == 7) return std::make_pair(17, 3);
137 if(pfeb == 8) return std::make_pair(16, 3);
138 if(pfeb == 9) return std::make_pair(16, 3);
139 if(pfeb == 10) return std::make_pair(15, 3);
140 if(pfeb == 11) return std::make_pair(15, 3);
141 if(pfeb == 12) return std::make_pair(15, 2);
142 if(pfeb == 13) return std::make_pair(15, 2);
143 if(pfeb == 14) return std::make_pair(15, 3);
144 if(pfeb == 15) return std::make_pair(15, 3);
145 if(pfeb == 16) return std::make_pair(13, 3);
146 if(pfeb == 17) return std::make_pair(13, 3);
147 if(pfeb == 18) return std::make_pair(14, 3);
148 if(pfeb == 19) return std::make_pair(14, 3);
149 if(pfeb == 20) return std::make_pair(12, 2);
150 if(pfeb == 21) return std::make_pair(12, 2);
151 if(pfeb == 22) return std::make_pair(13, 3);
152 if(pfeb == 23) return std::make_pair(13, 3);
153 }
154 return std::make_pair(0,0);
155 }
156
157 inline std::pair<int,int> getRowColAthena(const int athenaCh) {
158 const int arow = (athenaCh-1)%18;
159 const int acol = int((athenaCh-1)/18);
160 return std::make_pair(arow, acol);
161 }
162
163 inline uint32_t getPadchAthena(const int athCh, const int pfeb, const int sector, int gasGap) {
164 bool isLarge = (sector % 2 == 0);
165 const auto [Nrows, Ncols] = getNrowsNcols(pfeb, isLarge);
166 const auto [arow, acol] = getRowColAthena(athCh);
167 //row and column counting all begin at 0
168 const int ABrow = Nrows -1 -arow;
169 const int ABcol = ((gasGap-1)%2 ==0) ? (Ncols-1)-acol : acol;
170 return ABrow*Ncols + ABcol;
171 }
172
173 // Dummy bandid
174 constexpr uint32_t DUMMY_BANDID{0xff};
175
177 constexpr std::array<uint32_t,8> DUMMYPADS{104,105,110,111,112,113,114,115};
178
179 // Pad trigger ID
180 constexpr uint32_t PAD_TRIGGER_ROB{0x20};
181
182 // Pad trigger N(BC) in readout
183 constexpr uint32_t PAD_TRIGGER_READOUT_NBC{7};
184
185 // Wheels
186 constexpr uint32_t MUON_STGC_ENDCAP_A_SIDE{0x6D};
187 constexpr uint32_t MUON_STGC_ENDCAP_C_SIDE{0x6E};
188
189 // Number of pfeb per radius
190 constexpr uint32_t NPFEB_PER_RADIUS{NLAYERS};
191
192 // Unpacking a line of pattern info
193 constexpr size_t I_PFEB0 = 0;
194 constexpr size_t I_PADCHAN0 = 1;
195 constexpr size_t I_PFEB1 = 2;
196 constexpr size_t I_PADCHAN1 = 3;
197 constexpr size_t I_PFEB2 = 4;
198 constexpr size_t I_PADCHAN2 = 5;
199 constexpr size_t I_PFEB3 = 6;
200 constexpr size_t I_PADCHAN3 = 7;
201 constexpr size_t I_PFEB4 = 8;
202 constexpr size_t I_PADCHAN4 = 9;
203 constexpr size_t I_PFEB5 = 10;
204 constexpr size_t I_PADCHAN5 = 11;
205 constexpr size_t I_PFEB6 = 12;
206 constexpr size_t I_PADCHAN6 = 13;
207 constexpr size_t I_PFEB7 = 14;
208 constexpr size_t I_PADCHAN7 = 15;
209 constexpr size_t I_PHIID = 16;
210
211 /*
212 * The PriorityEncoder deals with the cases where we have more than one trigger segment in the same BC.
213 * The stripTDS can only deal with one request per BC, so if two triggers have bandIDs that require strips from the same stripTDS, we can only send one of the triggers.
214 * The trigger with highest BandID is given priority.
215 * This function defines for each BandID a range of forbidden bandIDs. It returns the lower bound of the forbidden range.
216 *
217 * Ex: {94,84} means if we have a trigger with bandID 94, the forbidden range is 84-94.
218 * Any additional trigger with BandID in that range will be ignored.
219 *
220 * So it would be something like map<triggered bandID, lower bound of the forbidden BandID range>
221 */
222 inline uint32_t priorityEncoderL(uint32_t bandid) {
223 static const std::unordered_map<uint32_t,uint32_t> bandids = {
224 {94,84}, {93,84}, {92,84}, {91,84}, {90,82},
225 {89,80}, {88,80}, {87,77}, {86,76}, {85,76}, {84,74}, {83,74}, {82,72}, {81,72}, {80,70},
226 {79,70}, {78,70}, {77,67}, {76,66}, {75,66}, {74,66}, {73,62}, {72,62}, {71,62}, {70,62},
227 {69,62}, {68,62}, {67,62}, {66,62}, {65,54}, {64,54}, {63,54}, {62,54}, {61,51}, {60,51},
228 {59,51}, {58,51}, {57,51}, {56,46}, {55,45}, {54,44}, {53,44}, {52,43}, {51,41}, {50,41},
229 {49,41}, {48,41}, {47,41}, {46,36}, {45,35}, {44,35}, {43,33}, {42,32}, {41,32}, {40,32},
230 {39,32}, {38,32}, {37,32}, {36,32}, {35,24}, {34,24}, {33,24}, {32,22}, {31,22}, {30,22},
231 {29,22}, {28,22}, {27,22}, {26,22}, {25,22}, {24,14}, {23,14}, {22,12}, {21,12}, {20,12},
232 {19,12}, {18,12}, {17,12}, {16,12}, {15,12}, {14, 6}, {13, 6}, {12, 6}, {11, 6}, {10, 6},
233 { 9, 6}, { 8, 6}, { 7, 6}, { 6, 6}};
234 auto it = bandids.find(bandid);
235 if(it == bandids.end()) return bandid;
236 else return it->second;
237 }
238 inline uint32_t priorityEncoderS(uint32_t bandid) {
239 static const std::unordered_map<uint32_t,uint32_t> bandids = {
240 {94,85}, {93,85}, {92,85}, {91,80}, {90,80},
241 {89,80}, {88,80}, {87,80}, {86,76}, {85,74}, {84,74}, {83,74}, {82,74}, {81,69}, {80,69},
242 {79,69}, {78,69}, {77,69}, {76,64}, {75,64}, {74,64}, {73,64}, {72,64}, {71,64}, {70,64},
243 {69,64}, {68,57}, {67,57}, {66,57}, {65,57}, {64,53}, {63,53}, {62,53}, {61,53}, {60,53},
244 {59,53}, {58,47}, {57,46}, {56,46}, {55,44}, {54,44}, {53,43}, {52,43}, {51,43}, {50,43},
245 {49,43}, {48,37}, {47,37}, {46,37}, {45,37}, {44,33}, {43,33}, {42,33}, {41,33}, {40,33},
246 {39,33}, {38,33}, {37,33}, {36,25}, {35,25}, {34,25}, {33,22}, {32,22}, {31,22}, {30,22},
247 {29,22}, {28,22}, {27,22}, {26,22}, {25,14}, {24,14}, {23,12}, {22,12}, {21,12}, {20,12},
248 {19,12}, {18,12}, {17,12}, {16,12}, {15,12}, {14, 6}, {13, 6}, {12, 5}, {11, 5}, {10, 5},
249 { 9, 5}, { 8, 5}, { 7, 5}, { 6, 2}, { 5, 2}, { 4, 2}, { 3, 2}, { 2, 2}};
250 auto it = bandids.find(bandid);
251 if(it == bandids.end()) return bandid;
252 else return it->second;
253 }
254
255 inline bool isDummyPad(const uint32_t padchan) {
256 return std::count(DUMMYPADS.begin(), DUMMYPADS.end(), padchan);
257 }
258
259 // Helper functions: contains
260 inline bool contains(const std::string& str, const std::string& substr) {
261 return str.find(substr) != std::string::npos;
262 }
263 inline bool contains(const std::vector<std::string>& cont, const std::string& val) {
264 return std::count(cont.begin(), cont.end(), val);
265 }
266 inline bool contains(const std::vector<uint32_t>& cont, const uint32_t val) {
267 return std::count(cont.begin(), cont.end(), val);
268 }
269 inline bool contains(const std::set<uint32_t>& cont, const uint32_t val) {
270 return cont.contains(val);
271 }
272
273 // Helper functions: replacement
274 inline std::string replace(std::string subject, const std::string& search, const std::string& replace) {
275 if (subject.empty() or search.empty()) return subject;
276
277 size_t pos = 0;
278 while((pos = subject.find(search, pos)) != std::string::npos) {
279 subject.replace(pos, search.length(), replace);
280 pos += replace.length();
281 }
282 return subject;
283 }
284
285 /* Helper function: parsing line
286 * - take a line like this and return the BandID as an integer, i.e.: "constant bandid_91_small_patterns : pad_trigger_pattern_array := ("
287 * - Retrieve first object: bandid_91_small_patterns
288 * - Split the object in its components: bandid, 91, small, patterns
289 * - Now save the number: 91
290 */
291 inline uint32_t parseLineForBandid(const std::string& line) {
292 const auto split = CxxUtils::tokenize(line, SPACE);
293 const auto word = split.at(1);
294 const auto word_split = CxxUtils::tokenize(line, UNDERSCORE);
295 return static_cast<uint32_t>(std::stoul(word_split.at(1)));
296 }
297 }
298
299 // MM specific conventions
300 namespace MM {
301 // Wheels
302 constexpr uint32_t MUON_MM_ENDCAP_A_SIDE{0x6B};
303 constexpr uint32_t MUON_MM_ENDCAP_C_SIDE{0x6C};
304 }
305
306 // Find side by source ID
307 inline bool isA(const uint32_t sourceid) {
308 return ( ((sourceid >> 16) & 0xff) == PAD::MUON_STGC_ENDCAP_A_SIDE || ((sourceid >> 16) & 0xff) == MM::MUON_MM_ENDCAP_A_SIDE );
309 }
310}
311#endif
static Double_t ss
void search(TDirectory *td, const std::string &s, std::string cwd, node *n)
recursive directory search for TH1 and TH2 and TProfiles
Definition hcg.cxx:739
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177
std::vector< std::string > tokenize(const std::string &the_str, std::string_view delimiters)
Splits the string into smaller substrings.
constexpr uint32_t MUON_MM_ENDCAP_A_SIDE
constexpr uint32_t MUON_MM_ENDCAP_C_SIDE
constexpr size_t I_PADCHAN1
const std::string SMALL
constexpr size_t I_PFEB7
uint32_t priorityEncoderS(uint32_t bandid)
constexpr size_t I_PADCHAN0
constexpr size_t I_PADCHAN2
constexpr size_t I_PADCHAN7
constexpr std::array< uint32_t, 8 > DUMMYPADS
Dummy pads.
constexpr uint32_t NPFEB_PER_RADIUS
constexpr size_t I_PHIID
constexpr std::array< uint32_t, NLAYERS > LAYERS
constexpr size_t I_PFEB2
uint32_t priorityEncoderL(uint32_t bandid)
const std::string PATTERN_END
constexpr uint32_t PAD_TRIGGER_READOUT_NBC
uint32_t getPadchAthena(const int athCh, const int pfeb, const int sector, int gasGap)
bool contains(const std::string &str, const std::string &substr)
constexpr size_t I_PADCHAN6
bool isDummyPad(const uint32_t padchan)
constexpr size_t I_PFEB3
constexpr size_t I_PADCHAN3
constexpr size_t I_PFEB5
std::pair< int, int > getRowColAthena(const int athenaCh)
constexpr size_t I_PADCHAN4
const std::string PATTERN_TAG
const std::string LARGE
constexpr size_t I_PFEB1
uint32_t parseLineForBandid(const std::string &line)
uint32_t wheelSectorToSourceID(const char wheel, const uint32_t sector)
constexpr std::array< uint32_t, NSECTORS > SECTORS
constexpr size_t PATTERNLEN
constexpr uint32_t MUON_STGC_ENDCAP_A_SIDE
constexpr size_t I_PFEB0
constexpr size_t I_PFEB6
constexpr size_t I_PFEB4
constexpr uint32_t PAD_TRIGGER_ROB
uint32_t getpFEBAthena(const int gas_gap, const int multiplet, const int stationEta)
constexpr uint32_t DUMMY_BANDID
constexpr size_t I_PADCHAN5
std::pair< int, int > getNrowsNcols(const int pfeb, const bool isLarge)
std::string replace(std::string subject, const std::string &search, const std::string &replace)
constexpr uint32_t MUON_STGC_ENDCAP_C_SIDE
PadEmulatorCoincidences.
bool isA(const uint32_t sourceid)
const std::vector< std::string > WHEELS
const std::string COMMA
std::string sectorName(const std::string &wheel, const uint32_t sec)
const std::string SEMICOLON
constexpr uint32_t NLAYERS
const std::string UNDERSCORE
int getSignedPhiID(const uint32_t phiid)
constexpr uint32_t NSECTORS
const std::string SPACE
const std::string VHDLCOMMENT