ATLAS Offline Software
Loading...
Searching...
No Matches
FPGATrackSimRegionMap.cxx
Go to the documentation of this file.
1// Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2
11
14
15#include <cstdlib>
16#include <string>
17#include <iostream>
18#include <vector>
19
20using namespace std;
21using namespace asg::msgUserCode;
22
23
25// Constructor/Desctructor
27
28
29FPGATrackSimRegionMap::FPGATrackSimRegionMap(const std::vector<std::unique_ptr<FPGATrackSimPlaneMap>> & pmaps, std::string const & filepath, bool inclusive ) :
30 m_pmaps(pmaps),
31 m_inclusive(inclusive)
32{
33 // If the region map is loaded in "inclusive" mode, don't actually do anything.
34 if (m_inclusive) {
35 ANA_MSG_INFO("Region map set to inclusive mode; will always treat hits as being in region");
36 m_map.clear();
37 m_radii_map.clear();
38 // In inclusive mode assume there is one region.
39 m_nregions = 1;
40 m_map.resize(m_nregions);
41 m_radii_map.resize(m_nregions, std::vector<double>(m_pmaps.at(0)->getNLogiLayers()));
42 return;
43 }
44
45 // Open the file
46 ifstream fin(filepath);
47 if (!fin.is_open())
48 {
49 ANA_MSG_FATAL("Couldn't open " << filepath);
50 throw ("FPGATrackSimRegionMap Couldn't open " + filepath);
51 }
52 m_filepath=filepath;
53
54 // Reads the header of the file to resize all the vector members
55 allocateMap(fin);
56
57 // Read all the region data
58 for (int region = 0; region < m_nregions; region++){
59 readRegion(fin, region);
60 }
61
62 // Resize the radius structure appropriately.
63 m_radii_map.clear();
64 m_radii_map.resize(m_nregions, std::vector<double>(m_pmaps.at(0)->getNLogiLayers()));
65}
66
67// Reads the header of the file to resize all the vector members
69{
70 string line, towerKey;
71 bool ok = true;
72
73 ok = ok && getline(fin, line);
74 ANA_MSG_DEBUG(line << " < " << ok);
75
76 istringstream sline(line);
77 ok = ok && (sline >> towerKey >> m_nregions);
78 ok = ok && (towerKey == "towers");
79 if((m_filepath.size()-7)==m_filepath.find("subrmap")){
80 if(int(m_pmaps.size())!= m_nregions){
81 ANA_MSG_FATAL("Error Pmap slice size does not match Rmap: PMAP_SIZE:"<<m_pmaps.size()<<" RMAP_SIZE:"<<m_nregions);
82 throw ("Pmap slice size does not match Rmap:" );
83 }
84 }
85
86
87 if (!ok) ANA_MSG_FATAL("Error reading header");
88
89 m_map.resize(m_nregions);
90
91 for (int iRegion=0; iRegion<int(m_map.size()); iRegion++)
92 {
93 m_map.at(iRegion).resize(m_pmaps.at(0)->getNLogiLayers());
94 for (size_t l = 0; l < m_map.at(iRegion).size(); l++) m_map.at(iRegion).at(l).resize(m_pmaps.at(iRegion)->getNSections(l));
95 }
96}
97
98
99// Reads one region from file.
100void FPGATrackSimRegionMap::readRegion(ifstream & fin, int expected_region)
101{
102
103 string line, dummy;
104 bool ok = true;
105 int region = -1;
106 uint32_t linesRead = 0; // detLayer lines read
107
108 while (getline(fin, line))
109 {
110 if (line.empty() || line[0] == '#') continue;
111 istringstream sline(line);
112
113 if (region < 0) // Find the starting header of the next region
114 {
115 ok = ok && (sline >> region);// should check this is a sensible number
116 ok = ok && !(sline >> dummy); // No keyword to check that we're not reading a detector line, so make sure rest of string is empty
117 ok = ok && (region == expected_region);
118 if (!ok) break;
119 }
120 else // Detector layer line
121 {
122 int isPix{}, BEC{}, physLayer{}, phi_min{}, phi_max{}, phi_tot{}, eta_min{}, eta_max{}, eta_tot{};
123 //should check these are within sensible limits after they are read
124 ok = ok && (sline >> isPix >> BEC >> physLayer >> phi_min >> phi_max >> phi_tot >> eta_min >> eta_max >> eta_tot);
125 if (!ok) break;
126 //region WW
127 int logiLayer = m_pmaps.at(region)->getLayerSection(static_cast<SiliconTech>(isPix), static_cast<DetectorZone>(BEC), physLayer).layer;
128 int section = m_pmaps.at(region)->getLayerSection(static_cast<SiliconTech>(isPix), static_cast<DetectorZone>(BEC), physLayer).section;
129
130 if (logiLayer > -1)
131 m_map[region][logiLayer][section] = { phi_min, phi_max, eta_min, eta_max };
132
133 if (++linesRead == m_pmaps.at(region)->getNDetLayers()) break;
134 }
135 }
136
137 if (!ok)
138 {
139 ANA_MSG_FATAL("Found error reading file at line: " << line);
140 throw "FPGATrackSimRegionMap read error";
141 }
142}
143
144
145// Read module id LUT (defining global -> tower-local module IDs)
146void FPGATrackSimRegionMap::loadModuleIDLUT(std::string const & filepath)
147{
148 ANA_MSG_INFO("Reading module LUT" << filepath);
149 ifstream fin(filepath);
150 if (!fin.is_open())
151 {
152 ANA_MSG_ERROR("Couldn't open " << filepath);
153 throw ("FPGATrackSimRegionMap Couldn't open " + filepath);
154 }
155
156 m_global_local_map.clear();
157 m_global_local_map.resize(m_nregions, vector<map<uint32_t, uint32_t>>(m_pmaps.at(0)->getNLogiLayers()));
158
159 string line;
160 while (getline(fin, line))
161 {
162 uint32_t region, layer, globalID, localID;
163 istringstream sline(line);
164
165 if (!(sline >> region >> layer >> globalID >> localID))
166 ANA_MSG_WARNING("Error reading module LUT");
167 else if (region >= m_global_local_map.size() || layer >= m_pmaps.at(0)->getNLogiLayers())
168 ANA_MSG_WARNING("loadModuleIDLUT() bad region=" << region << " or layer=" << layer);
169 else
170 m_global_local_map[region][layer][globalID] = localID;
171 }
172}
173
174// Copied from the 1D Hough bitstream tool.
175void FPGATrackSimRegionMap::loadRadiiFile(std::string const & filepath, unsigned layer_offset = 0, unsigned layer_max = 0)
176{
177
178 // If layer_max is 0, then set it equal to the number of layers in the configured plane map, minus the offset.
179 layer_max = (layer_max == 0) ? m_pmaps.at(0)->getNLogiLayers() - layer_offset: layer_max - layer_offset;
180
181 // Open the file
182 std::ifstream fin(filepath);
183 if (!fin.is_open())
184 {
185 ANA_MSG_FATAL("Couldn't open radius file " << filepath);
186 }
187
188 // Variables to fill
189 std::string line;
190 bool ok = true;
191 double r = 0.0;
192
193 // Parse the file
194 while (getline(fin, line))
195 {
196 if (line.empty() || line[0] == '#') continue;
197 std::istringstream sline(line);
198 std::vector<int> shifts;
199
200 int subregion{-1};
201 ok = ok && (sline >> subregion);
202
203 // The radii file contains an "inclusive" line and then one for each subregion.
204 // If we only have one region (because we are the rmap or because we are a subrmap
205 // with one z-slice) then we only want to read the inclusive line.
206 // Otherwise we want to read everything BUT the inclusive line.
207 if (m_nregions == 1 && subregion != -1) {
208 continue;
209 }
210 if (m_nregions > 1 && subregion == -1) {
211 continue;
212 }
213
214 // Read up to layer_max layers out of the radii file. This is set by the mapping service when loading these files.
215 for (unsigned layer = 0; layer < layer_max; layer++) {
216 ok = ok && (sline >> r);
217 if (!ok) break;
218 unsigned eff_layer = layer + layer_offset;
219 ANA_MSG_DEBUG("Reading average radius at effective (actual) layer = " << eff_layer << " (" << layer << ") = " << r);
220 if (r<=0) {
221 ANA_MSG_WARNING("Radius in radiiFile is "<< r <<" for layer: " << eff_layer << " setting to dummy value!");
222 r = 500.0; // dummy value that won't cause a crash, but won't work anywhere.
223 }
224 if (subregion == -1) {
225 m_radii_map[0][eff_layer] = r;
226 } else {
227 m_radii_map[subregion][eff_layer] = r;
228 }
229 }
230
231 if (!ok) break;
232 }
233
234 if (!ok)
235 {
236 ANA_MSG_FATAL("Found error reading file at line: " << line);
237 }
238}
239
240
242// Interface Functions
244
245bool FPGATrackSimRegionMap::isInRegion(uint32_t region, const FPGATrackSimHit &hit) const
246{
247 // In inclusive mode, always return true.
248 if (m_inclusive) return true;
249
250 // Always assume that the hit's "layer" might not correspond to what's in the pmap
251 // Also, to avoid confusion and double-counting, by convention, always use the coordinates of the inner hit
252 // when testing if a spacepoint is in a (sub)region.
253 uint32_t layer;
254 uint32_t section;
255
256 LayerSection ls;
257 if (hit.getHitType() == HitType::spacepoint) {
258 ls = m_pmaps.at(region)->getLayerSection(hit.getPairedDetType(), hit.getPairedDetZone(), hit.getPairedPhysLayer());
259 } else {
260 ls = m_pmaps.at(region)->getLayerSection(hit.getDetType(), hit.getDetectorZone(), hit.getPhysLayer());
261 }
262 if (ls.layer<0) return false;
263 layer = static_cast<uint32_t>(ls.layer); //explicit cast to unsigned
264 section = ls.section;
265
266 int etamod = (hit.getHitType() == HitType::spacepoint) ? hit.getPairedEtaModule() : hit.getEtaModule();
267 unsigned phimod = (hit.getHitType() == HitType::spacepoint) ? hit.getPairedPhiModule() : hit.getPhiModule();
268 return isInRegion(region, layer, section, etamod, phimod);
269}
270
271
272bool FPGATrackSimRegionMap::isInRegion(uint32_t region, uint32_t layer, uint32_t section, int eta, int phi) const
273{
274 // In inclusive mode, always return true.
275 if (m_inclusive) return true;
276
277 if ( region >= m_map.size()
278 || layer >= m_map[region].size()
279 || section >= m_map[region][layer].size() )
280 {
281 return false;
282 }
283
284 int eta_min = m_map[region][layer][section].eta_min;
285 int eta_max = m_map[region][layer][section].eta_max;
286
287 if (eta < eta_min || eta > eta_max) return false;
288
289 int phi_min = m_map[region][layer][section].phi_min;
290 int phi_max = m_map[region][layer][section].phi_max;
291
292 // Need special cases for phi because it can go from 2pi to 0.
293 if (phi_min <= phi_max) // Region does not cross phi = 0
294 {
295 if (phi < phi_min || phi > phi_max) return false;
296 }
297 else // Region crosses phi = 0
298 {
299 if (phi < phi_min && phi > phi_max) return false;
300 }
301
302 return true;
303}
304
305std::vector<uint32_t> FPGATrackSimRegionMap::getRegions(const FPGATrackSimHit &hit) const
306{
307 std::vector<uint32_t> regions;
308 for (uint32_t region = 0; region < m_map.size(); region++) {
309 if (isInRegion(region, hit))
310 regions.push_back(region);
311 }
312 return regions;
313}
314
315uint32_t FPGATrackSimRegionMap::getUnmappedID(uint32_t region, const FPGATrackSimHit &hit) const
316{
317 /*
318 Todo: Does this handle EC hits correctly?
319
320 error code key:
321 6 digit number. 1 = ok. 2 = not ok
322
323 1st digit - Endcap Check
324 2nd - region
325 3rd - layer
326 4th - section
327 5th - eta
328 6th - phi
329 */
330
331 uint32_t layer = hit.getLayer();
332 uint32_t section = hit.getSection();
333 int eta = hit.getEtaModule();
334 int phi = hit.getPhiModule();
335
336 int anyerr = 0;
337 int err[] = {1,1,1,1,1,1};
338
339 if (region >= m_map.size()) anyerr = err[1] = 2;
340
341 if (!anyerr && layer >= m_map[region].size()) anyerr = err[2] = 2;
342
343 if (!anyerr && section >= m_map[region][layer].size()) anyerr = err[3] = 2;
344
345 if (!anyerr) {
346 int eta_min = m_map[region][layer][section].eta_min;
347 int eta_max = m_map[region][layer][section].eta_max;
348
349 if (eta < eta_min) err[4] = 3;
350 if (eta > eta_max) err[4] = 2;
351
352 int phi_min = m_map[region][layer][section].phi_min;
353 int phi_max = m_map[region][layer][section].phi_max;
354
355 // Need special cases for phi berrause it can go from 2pi to 0.
356 if (phi_min <= phi_max) // Region does not cross phi = 0
357 {
358 if (phi < phi_min || phi > phi_max) err[5] = 2;
359 }
360 else // Region crosses phi = 0
361 {
362 if (phi < phi_min && phi > phi_max) err[5] = 3;
363 }
364 }
365
366 int error_code = 100000*err[0] + 10000*err[1] + 1000*err[2] + 100*err[3] + 10*err[4] + err[5];
367
368 return error_code;
369}
370
371
372uint32_t FPGATrackSimRegionMap::getLocalID(uint32_t region, uint32_t layer, uint32_t globalModuleID) const
373{
374 // TEMPORARY UNTIL WE HAVE A MODULE LUT
375 (void) region;
376 (void) layer;
377 return globalModuleID & 0x3ff;
378}
379
380
381uint32_t FPGATrackSimRegionMap::getGlobalID(uint32_t region, uint32_t layer, uint32_t localModuleID) const
382{
383 if (region >= m_global_local_map.size() || layer >= m_pmaps.at(0)->getNLogiLayers())
384 {
385 ANA_MSG_ERROR("getGlobalID() bad region=" << region << " or layer=" << layer);
386 return -1;
387 }
388
389 for (auto const & g_l : m_global_local_map[region][layer])
390 if (g_l.second == localModuleID) return g_l.first;
391
392 ANA_MSG_ERROR("getGlobalID() Did not find global id for region " << region << ", layer " << layer << ", localID " << localModuleID);
393 return -1;
394}
395
396double FPGATrackSimRegionMap::getAvgRadius(unsigned region, unsigned layer) const {
397
398 if (region >= m_radii_map.size() || layer >= m_pmaps.at(0)->getNLogiLayers())
399 {
400 ANA_MSG_ERROR("getAvgRadius() bad region=" << region << " or layer=" << layer);
401 return -1;
402 }
403
404 // Return the radius we loaded for this region.
405 return m_radii_map[region][layer];
406}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
macros for messaging and checking status codes
#define ANA_MSG_INFO(xmsg)
Macro printing info messages.
#define ANA_MSG_ERROR(xmsg)
Macro printing error messages.
#define ANA_MSG_WARNING(xmsg)
Macro printing warning messages.
#define ANA_MSG_DEBUG(xmsg)
Macro printing debug messages.
#define ANA_MSG_FATAL(xmsg)
Macro printing fatal messages.
Maps ITK module indices to FPGATrackSim regions.
SiliconTech
DetectorZone
static const std::vector< std::string > regions
void section(const std::string &sec)
int getPairedEtaModule() const
unsigned getPairedPhysLayer() const
unsigned getPairedPhiModule() const
int getEtaModule(bool old=false) const
DetectorZone getPairedDetZone() const
unsigned getPhiModule() const
SiliconTech getPairedDetType() const
unsigned getPhysLayer(bool old=false) const
SiliconTech getDetType() const
DetectorZone getDetectorZone() const
unsigned getSection() const
HitType getHitType() const
double getAvgRadius(unsigned region, unsigned layer) const
std::vector< std::vector< std::vector< FPGATrackSimRegionBoundaries > > > m_map
std::vector< std::unique_ptr< FPGATrackSimPlaneMap > > const & m_pmaps
std::vector< std::vector< double > > m_radii_map
uint32_t getLocalID(uint32_t region, uint32_t layer, uint32_t globalModuleID) const
uint32_t getUnmappedID(uint32_t region, const FPGATrackSimHit &hit) const
void loadRadiiFile(std::string const &radii_file, unsigned layer_offset, unsigned layer_max)
void allocateMap(std::ifstream &fin)
uint32_t getGlobalID(uint32_t region, uint32_t layer, uint32_t localModuleID) const
FPGATrackSimRegionMap(const std::vector< std::unique_ptr< FPGATrackSimPlaneMap > > &pmaps, std::string const &filepath, bool m_inclusive)
std::vector< uint32_t > getRegions(const FPGATrackSimHit &hit) const
void readRegion(std::ifstream &fin, int expected_region)
bool isInRegion(uint32_t region, const FPGATrackSimHit &hit) const
void loadModuleIDLUT(std::string const &filepath)
std::vector< std::vector< std::map< uint32_t, uint32_t > > > m_global_local_map
int r
Definition globals.cxx:22
STL namespace.