ATLAS Offline Software
L1TopoLUT.cxx
Go to the documentation of this file.
1 /*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #define BOOST_BIND_GLOBAL_PLACEHOLDERS // silence Boost pragma message (fixed in Boost 1.76)
8 #include <boost/property_tree/json_parser.hpp>
9 
10 #include <fstream>
11 #include <map>
12 #include <iostream>
13 #include <sstream>
14 
15 namespace LVL1MUCTPIPHASE1
16 {
17  void L1TopoLUT::fillFromPtree(const boost::property_tree::ptree& node, std::map<unsigned short,std::vector<float>>& theLut) const
18  {
19  theLut.clear();
20  size_t outerIndex = 0;
21  for (const boost::property_tree::ptree::value_type& outer_elem : node){
22 
23  std::vector<float> buff(outer_elem.second.size());
24  size_t index = 0;
25  for (const boost::property_tree::ptree::value_type& inner_elem : outer_elem.second) {
26  buff[index] = inner_elem.second.get_value<float>();
27  ++index; //count index manually to avoid some stoi
28  }
29  //cannot get around stoi as outer layer may be non-continuous (some indices/keys are not present)
30  if (outer_elem.first.length() > 0) { //string type key
31  theLut[std::stoi(outer_elem.first)] = std::move(buff);
32  } else {
33  theLut[outerIndex] = std::move(buff);
34  ++outerIndex; //ok to only count in this case, mixed keys/indices at same depth are not valid
35  }
36  }
37  return;
38  }
39 
40  void L1TopoLUT::fillFromPtree(const boost::property_tree::ptree& node, std::map<unsigned short,std::map<unsigned short, std::pair<unsigned short, unsigned short>>>& theLut) const
41  {
42  theLut.clear();
43  for (const boost::property_tree::ptree::value_type& outer_elem : node){
44 
45  std::map<unsigned short,std::pair<unsigned short, unsigned short>> buff;
46  for (const boost::property_tree::ptree::value_type& inner_elem : outer_elem.second) {
47  std::vector<unsigned short> codeBuff;
48  for (const boost::property_tree::ptree::value_type& code_elem : inner_elem.second) {
49  codeBuff.push_back( code_elem.second.get_value<unsigned short>() );
50  }
51  if ( codeBuff.size() != 2 ) {
52  //stricter error checking/handling comes later
53  continue;
54  }
55  buff[std::stoi(inner_elem.first)] = { codeBuff[0], codeBuff[1] } ;
56  }
57  //cannot get around stoi as outer layer may be non-continuous (some indices/keys are not present)
58  theLut[std::stoi(outer_elem.first)] = std::move(buff);
59  }
60  return;
61  }
62 
63 
64  bool L1TopoLUT::initializeCompactedLUTs(const std::string& side0LUTFileName,
65  const std::string& side1LUTFileName) {
66  bool success = true;
68  boost::property_tree::read_json(side0LUTFileName.c_str(), root0);
70  boost::property_tree::read_json(side1LUTFileName.c_str(), root1);
71 
72  //Barrel encoding
73  fillFromPtree(root0.get_child("encode_lookup_barrel") , m_barrel_encoding0);
74  fillFromPtree(root1.get_child("encode_lookup_barrel") , m_barrel_encoding1);
75 
76  //Barrel, A-side
77  fillFromPtree(root0.get_child("lookup_barrel_eta") , m_barrel_eta_lookup0);
78  fillFromPtree(root0.get_child("lookup_barrel_phi") , m_barrel_phi_lookup0);
79  //Barrel, C-side
80  fillFromPtree(root1.get_child("lookup_barrel_eta") , m_barrel_eta_lookup1);
81  fillFromPtree(root1.get_child("lookup_barrel_phi") , m_barrel_phi_lookup1);
82  //Endcap, A-side
83  fillFromPtree(root0.get_child("lookup_endcap_eta") , m_endcap_eta_lookup0);
84  fillFromPtree(root0.get_child("lookup_endcap_phi") , m_endcap_phi_lookup0);
85  //Endcap, C-side
86  fillFromPtree(root1.get_child("lookup_endcap_eta") , m_endcap_eta_lookup1);
87  fillFromPtree(root1.get_child("lookup_endcap_phi") , m_endcap_phi_lookup1);
88  //Forward, A-side
89  fillFromPtree(root0.get_child("lookup_forward_eta") , m_forward_eta_lookup0);
90  fillFromPtree(root0.get_child("lookup_forward_phi") , m_forward_phi_lookup0);
91  //Forward, C-side
92  fillFromPtree(root1.get_child("lookup_forward_eta") , m_forward_eta_lookup1);
93  fillFromPtree(root1.get_child("lookup_forward_phi") , m_forward_phi_lookup1);
94 
95 
96  if (m_barrel_encoding1.size() && m_barrel_encoding1.size() &&
97  m_barrel_phi_lookup1.size() && m_barrel_phi_lookup0.size() &&
98  m_endcap_phi_lookup1.size() && m_endcap_phi_lookup0.size() &&
99  m_forward_phi_lookup1.size() && m_forward_phi_lookup0.size() ) {
100  return success;
101  }
102  return false;
103  }
104 
105  bool L1TopoLUT::initializeLUT(const std::string& barrelFileName,
106  const std::string& ecfFileName,
107  const std::string& side0LUTFileName,
108  const std::string& side1LUTFileName) {
109  m_encoding.clear();
110  m_errors.clear();
111 
112  bool success = true;
113 
114  // read the compacted LUTs containing the simplified eta/phi values
115  // used for encoding/decoding for/at L1Topo
116  success = success && initializeCompactedLUTs(side0LUTFileName, side1LUTFileName);
117 
118  //read remaining info from the json files
119  //(the input labels are swapped between A-side and C-side)
120  //success = success && initializeJSON(side1LUTFileName, 0);
121  //success = success && initializeJSON(side0LUTFileName, 1);
122 
123  //read the barrel file
124  success = success && initializeLUT(barrelFileName, true);
125 
126  //read the endcap+forward file
127  success = success && initializeLUT(ecfFileName, false);
128 
129  return success;
130  }
131 
132  bool L1TopoLUT::initializeLUT(const std::string& inFileName, const bool& isBarrel) {
133  //map between L1TopoLUTKey -> map between eta/phi -> index
134  std::unordered_map<L1TopoLUTKey, std::map<float, unsigned short>, L1TopoLUTKeyHasher> sector_eta_indices, sector_phi_indices;
135 
136  std::ifstream inFile(inFileName.c_str());
137  if (!inFile) return false;
138  while (!inFile.eof() && inFile.good()) {
139  unsigned short side;
140  unsigned short subsystem=0;
141  unsigned short sectorID;
142  unsigned short roi;
143  double eta_min, eta_max;
144  double phi_min, phi_max;
145 
146  inFile >> side;
147  if (inFile.eof()) { break; }
148 
149  if (!isBarrel) {
150  inFile >> subsystem;
151  //in the EC+FW file, EC=0 and FW=1, so increment to distinguish from barrel
152  subsystem++;
153  side = !side; //EC+FW file uses inverted side numbers w.r.t. Barrel...
154  }
155  //at this point the "side" convention is
156  // 0 -> C side
157  // 1 -> A side
158  // the LUT json file naming, however, if inverse (follows EC+FW file...)
159 
160  inFile >> sectorID;
161  inFile >> roi;
162  inFile >> eta_min;
163  inFile >> eta_max;
164  inFile >> phi_min;
165  inFile >> phi_max;
166 
167  double eta = getCompactedValue_eta(subsystem, side, sectorID, roi);
168  //coverity[tainted_data]
169  double phi = getCompactedValue_phi(subsystem, side, sectorID, roi);
170 
171  unsigned short ieta = 0;
172  unsigned short iphi = 0;
173  if (subsystem == 0) { //barrel
174  //note: interpretation of values 0/1 for side flipped on purpose here (different conventions)!
175  ieta = (side ? m_barrel_encoding0 : m_barrel_encoding1)[sectorID][roi].first;
176  iphi = (side ? m_barrel_encoding0 : m_barrel_encoding1)[sectorID][roi].second;
177  } else if (subsystem == 1) { //endcap
178  ieta = (roi>>2); //eta part of roi
179  ieta |= 1 << 6; //detector code
180  iphi = roi & 0x3; //phi part of roi
181  iphi |= (sectorID & 0x3F) << 2;
182  } else if (subsystem == 2) { //forward
183  ieta = (roi>>2); //eta part of roi
184  ieta |= 1 << 5; //detector code
185  iphi = (roi & 0x3) << 1; //phi part of roi
186  iphi |= (sectorID & 0x1F) << 3;
187  }
188  //truncate to 8bit values each:
189  ieta &= 0xFF;
190  iphi &= 0xFF;
191 
192  if (subsystem == 0) {
193  //populate reverse map for barrel
194  unsigned short etaPhiSubWord = ((ieta&0xF) << 9) | ((sectorID&0x1F) << 3) | (iphi&0x7);
195  if (side) {
196  m_barrel_reverse_encoding0[etaPhiSubWord] = roi;
197  } else {
198  m_barrel_reverse_encoding1[etaPhiSubWord] = roi;
199  }
200  }
201 
202  //reminder in case of debugging needs:
203  //compacted values should be close to these averages
204  //(albeit some are different enough to cause mismatches in Topo!)
205  //float avgEta = (eta_min+eta_max)/2.;
206  //float avgPhi = (phi_min+phi_max)/2.;
207 
208 
209  L1TopoLUTKey key = {side, subsystem, sectorID, roi};
210  L1TopoCoordinates value = {eta, phi, eta_min, eta_max, phi_min, phi_max, ieta, iphi};
211 
212  if (m_encoding.find(key) != m_encoding.end())
213  {
214  m_errors.push_back("Duplicate key found in L1TopoLUT: "+key.info());
215  return false;
216  }
217  m_encoding[key] = value;
218  }
219  return true;
220  }
221 
222 
224  const unsigned short& subsystem,
225  const unsigned short& sectorID,
226  const unsigned short& roi) const {
227  L1TopoLUTKey key = {side, subsystem, sectorID, roi};
228  auto itr = m_encoding.find(key);
229  if (itr == m_encoding.end())
230  {
231  L1TopoCoordinates null;
232  return null;
233  }
234  return itr->second;
235  }
236 
237  unsigned short L1TopoLUT::getBarrelROI(unsigned short side, unsigned short sector, unsigned short ieta, unsigned short iphi) const {
238  unsigned short etaPhiSubWord = ((ieta&0xF) << 9) | ((sector&0x1F) << 3) | (iphi&0x7);
239  unsigned short retval = 0;
240  if (side) {
241  retval = m_barrel_reverse_encoding0.at(etaPhiSubWord);
242  } else {
243  retval = m_barrel_reverse_encoding1.at(etaPhiSubWord);
244  }
245  return retval;
246  }
247 
248 
249  float L1TopoLUT::getCompactedValue_eta(unsigned short subsystem, unsigned short side, unsigned short sectorID, unsigned short roi) {
250  //note: scheme used for "side" argument here is
251  // 0 -> C side
252  // 1 -> A side
253  float retval = std::numeric_limits<float>::quiet_NaN();
254  try {
255  if (subsystem == 0) { //barrel
256  //barrel is very irregular, so need to retrieve indices for MUCTPI->L1Topo encoding scheme first
257  unsigned short lutCode = (side ? m_barrel_encoding0 : m_barrel_encoding1)[sectorID][roi].first;
258  retval = (side ? m_barrel_eta_lookup0 : m_barrel_eta_lookup1)[sectorID][lutCode];
259  } else if (subsystem == 1) { //endcap
260  retval = (side ? m_endcap_eta_lookup0 : m_endcap_eta_lookup1)[roi >> 2][sectorID & 0x1];
261  } else if (subsystem == 2) { //forward
262  retval = (side ? m_forward_eta_lookup0 : m_forward_eta_lookup1)[sectorID & 0x1][roi >> 2];
263  } else {
264  std::stringstream ess;
265  ess << "[TrigT1MuctpiPhase1/L1TopoLUT] Unknown muon subsystem value: " << subsystem;
266  throw std::out_of_range(ess.str());
267  }
268  } catch (const std::exception& e) {
269  std::stringstream ess;
270  ess << "[TrigT1MuctpiPhase1/L1TopoLUT] Failed to look up eta value for subsystem=" << subsystem
271  << ", side="<< (side?"A":"C")
272  << ", sectorID="<< sectorID
273  << ", roi="<< roi
274  << "\n (caught exception: " << e.what() <<")";
275  throw std::out_of_range(ess.str());
276  }
277  return retval;
278  }
279 
280  float L1TopoLUT::getCompactedValue_phi(unsigned short subsystem, unsigned short side, unsigned short sectorID, unsigned short roi) {
281  //note: scheme used for "side" argument here is
282  // 0 -> C side
283  // 1 -> A side
284  float retval = std::numeric_limits<float>::quiet_NaN();
285  try {
286  if (subsystem == 0) { //barrel
287  //barrel is very irregular, so need to retrieve indices for MUCTPI->L1Topo encoding scheme first
288  unsigned short lutCode = (side ? m_barrel_encoding0 : m_barrel_encoding1)[sectorID][roi].second;
289  retval = (side ? m_barrel_phi_lookup0 : m_barrel_phi_lookup1)[sectorID][lutCode];
290  } else if (subsystem == 1) { //endcap
291  retval = (side ? m_endcap_phi_lookup0 : m_endcap_phi_lookup1)[sectorID][roi & 0x3];
292  } else if (subsystem == 2) { //forward
293  retval = (side ? m_forward_phi_lookup0 : m_forward_phi_lookup1)[roi & 0x3][sectorID];
294  } else {
295  std::stringstream ess;
296  ess << "[TrigT1MuctpiPhase1/L1TopoLUT] Unknown muon subsystem value: " << subsystem;
297  throw std::out_of_range(ess.str());
298  }
299  } catch (const std::exception& e) {
300  std::stringstream ess;
301  ess << "[TrigT1MuctpiPhase1/L1TopoLUT] Failed to look up phi value for subsystem=" << subsystem
302  << ", side="<< (side?"A":"C")
303  << ", sectorID="<< sectorID
304  << ", roi="<< roi
305  << "\n (caught exception: " << e.what() <<")";
306  throw std::out_of_range(ess.str());
307  }
308  return retval;
309  }
310 
311 
312 }
LVL1MUCTPIPHASE1::L1TopoLUT::m_forward_eta_lookup1
std::map< unsigned short, std::vector< float > > m_forward_eta_lookup1
Definition: L1TopoLUT.h:125
LVL1MUCTPIPHASE1::L1TopoLUT::m_endcap_phi_lookup1
std::map< unsigned short, std::vector< float > > m_endcap_phi_lookup1
Definition: L1TopoLUT.h:123
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
get_hdefs.buff
buff
Definition: get_hdefs.py:61
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:215
LVL1MUCTPIPHASE1::L1TopoLUT::getBarrelROI
unsigned short getBarrelROI(unsigned short side, unsigned short sector, unsigned short ieta, unsigned short iphi) const
Definition: L1TopoLUT.cxx:237
LVL1MUCTPIPHASE1::L1TopoLUT::m_barrel_reverse_encoding0
std::map< unsigned short, unsigned short > m_barrel_reverse_encoding0
Definition: L1TopoLUT.h:133
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
index
Definition: index.py:1
makeTOC.inFile
string inFile
Definition: makeTOC.py:5
LVL1MUCTPIPHASE1::L1TopoLUT::fillFromPtree
void fillFromPtree(const boost::property_tree::ptree &node, std::map< unsigned short, std::vector< float >> &theLut) const
Definition: L1TopoLUT.cxx:17
python.SystemOfUnits.second
float second
Definition: SystemOfUnits.py:135
LVL1MUCTPIPHASE1::L1TopoLUT::m_encoding
std::unordered_map< L1TopoLUTKey, L1TopoCoordinates, L1TopoLUTKeyHasher > m_encoding
Definition: L1TopoLUT.h:136
LVL1MUCTPIPHASE1::L1TopoLUT::m_barrel_encoding1
std::map< unsigned short, std::map< unsigned short, std::pair< unsigned short, unsigned short > > > m_barrel_encoding1
Definition: L1TopoLUT.h:130
LVL1MUCTPIPHASE1::L1TopoLUT::m_errors
std::vector< std::string > m_errors
Definition: L1TopoLUT.h:137
athena.value
value
Definition: athena.py:124
LVL1MUCTPIPHASE1::L1TopoLUT::getCompactedValue_eta
float getCompactedValue_eta(unsigned short subsystem, unsigned short side, unsigned short sectorID, unsigned short roi)
Definition: L1TopoLUT.cxx:249
LVL1MUCTPIPHASE1::L1TopoCoordinates
Definition: L1TopoLUT.h:23
LVL1MUCTPIPHASE1::L1TopoLUT::m_barrel_phi_lookup1
std::map< unsigned short, std::vector< float > > m_barrel_phi_lookup1
Definition: L1TopoLUT.h:119
LVL1MUCTPIPHASE1::L1TopoLUT::m_endcap_phi_lookup0
std::map< unsigned short, std::vector< float > > m_endcap_phi_lookup0
Definition: L1TopoLUT.h:122
TRT::Hit::side
@ side
Definition: HitInfo.h:83
LArCellBinning_test.retval
def retval
Definition: LArCellBinning_test.py:112
LVL1MUCTPIPHASE1::L1TopoLUT::m_barrel_eta_lookup0
std::map< unsigned short, std::vector< float > > m_barrel_eta_lookup0
Definition: L1TopoLUT.h:116
L1TopoLUT.h
LVL1MUCTPIPHASE1::L1TopoLUT::m_barrel_eta_lookup1
std::map< unsigned short, std::vector< float > > m_barrel_eta_lookup1
Definition: L1TopoLUT.h:117
LVL1MUCTPIPHASE1
Definition: Configuration.h:11
LVL1MUCTPIPHASE1::L1TopoLUT::getCoordinates
L1TopoCoordinates getCoordinates(const unsigned short &side, const unsigned short &subsystem, const unsigned short &sectorID, const unsigned short &roi) const
Definition: L1TopoLUT.cxx:223
LVL1MUCTPIPHASE1::L1TopoLUT::L1TopoLUTKey
Definition: L1TopoLUT.h:85
calibdata.exception
exception
Definition: calibdata.py:495
LVL1MUCTPIPHASE1::L1TopoLUT::m_barrel_phi_lookup0
std::map< unsigned short, std::vector< float > > m_barrel_phi_lookup0
Definition: L1TopoLUT.h:118
IDTPMcnv.inFileName
inFileName
Definition: IDTPMcnv.py:17
LVL1MUCTPIPHASE1::L1TopoLUT::initializeCompactedLUTs
bool initializeCompactedLUTs(const std::string &side0LUTFileName, const std::string &side1LUTFileName)
Definition: L1TopoLUT.cxx:64
LVL1MUCTPIPHASE1::L1TopoLUT::m_barrel_encoding0
std::map< unsigned short, std::map< unsigned short, std::pair< unsigned short, unsigned short > > > m_barrel_encoding0
Definition: L1TopoLUT.h:129
ptree
boost::property_tree::ptree ptree
Definition: JsonFileLoader.cxx:16
LVL1MUCTPIPHASE1::L1TopoLUT::m_endcap_eta_lookup1
std::map< unsigned short, std::vector< float > > m_endcap_eta_lookup1
Definition: L1TopoLUT.h:121
LVL1MUCTPIPHASE1::L1TopoLUT::m_barrel_reverse_encoding1
std::map< unsigned short, unsigned short > m_barrel_reverse_encoding1
Definition: L1TopoLUT.h:134
DeMoScan.index
string index
Definition: DeMoScan.py:362
LVL1MUCTPIPHASE1::L1TopoLUT::L1TopoLUTKeyHasher
Definition: L1TopoLUT.h:110
LVL1MUCTPIPHASE1::L1TopoLUT::getCompactedValue_phi
float getCompactedValue_phi(unsigned short subsystem, unsigned short side, unsigned short sectorID, unsigned short roi)
Definition: L1TopoLUT.cxx:280
DeMoScan.first
bool first
Definition: DeMoScan.py:534
LVL1MUCTPIPHASE1::L1TopoLUT::initializeLUT
bool initializeLUT(const std::string &barrelFileName, const std::string &ecfFileName, const std::string &side0LUTFileName, const std::string &side1LUTFileName)
Definition: L1TopoLUT.cxx:105
python.LArCondContChannels.isBarrel
isBarrel
Definition: LArCondContChannels.py:659
LVL1MUCTPIPHASE1::L1TopoLUT::m_forward_phi_lookup0
std::map< unsigned short, std::vector< float > > m_forward_phi_lookup0
Definition: L1TopoLUT.h:126
LVL1MUCTPIPHASE1::L1TopoLUT::m_forward_phi_lookup1
std::map< unsigned short, std::vector< float > > m_forward_phi_lookup1
Definition: L1TopoLUT.h:127
LVL1MUCTPIPHASE1::L1TopoLUT::m_endcap_eta_lookup0
std::map< unsigned short, std::vector< float > > m_endcap_eta_lookup0
Definition: L1TopoLUT.h:120
L1TopoSimulationConfig.subsystem
subsystem
Definition: L1TopoSimulationConfig.py:297
LVL1MUCTPIPHASE1::L1TopoLUT::m_forward_eta_lookup0
std::map< unsigned short, std::vector< float > > m_forward_eta_lookup0
Definition: L1TopoLUT.h:124
node
Definition: node.h:21
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37