ATLAS Offline Software
eFEXtauBDT.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 //*************************************************************************
6 // eFEXtauBDT - description
7 // --------------------
8 // begin : 15 09 2022
9 // email : david.reikher@gmail.com
10 //*************************************************************************
11 
13 #include <string>
14 
15 #define ENERGY_WIDTH 16
16 #define PARAM_WIDTH 8
17 
18 // default constructor for persistency
19 LVL1::eFEXtauBDT::eFEXtauBDT(AthAlgTool *log, std::string config_path)
20  : m_bdt(config_path), m_log(log) {
21  m_log->msg(MSG::DEBUG) << "Configured BDT with this file: " << config_path
22  << endmsg;
23  m_bdtVars.resize(m_bdt.getVariables().size());
24  m_towers.resize(m_bdt.getNTowers());
25  int n_multipliers = sizeof(m_fracMultipliers) / sizeof(m_fracMultipliers[0]);
26  m_emEtXMultiplier.resize(n_multipliers);
27  m_emEtXMultiplierOverflow.resize(n_multipliers);
28 }
29 
32 
33 void LVL1::eFEXtauBDT::setPointerToSCell(int eta, int phi, int layer,
34  unsigned int *sCellPtr) {
35  switch (layer) {
36  case 0:
37  m_em0cells[eta][phi] = sCellPtr;
38  break;
39  case 1:
40  m_em1cells[eta][phi] = sCellPtr;
41  break;
42  case 2:
43  m_em2cells[eta][phi] = sCellPtr;
44  break;
45  case 3:
46  m_em3cells[eta][phi] = sCellPtr;
47  break;
48  case 4:
49  m_hadcells[eta][phi] = sCellPtr;
50  break;
51  }
52 }
53 
55  int index, unsigned int *fracMultiplierPtr) {
56  m_fracMultipliers[index] = fracMultiplierPtr;
57 }
58 
60  int index, unsigned int *bdtThresholdPtr) {
61  m_bdtThresholds[index] = bdtThresholdPtr;
62 }
63 
64 void LVL1::eFEXtauBDT::setPointerToETThresholdParam(unsigned int *etThreshold) {
65  m_etThreshold = etThreshold;
66 }
67 
69  unsigned int *maxEtThreshold) {
70  m_maxEtThreshold = maxEtThreshold;
71 }
72 
74  unsigned int *bdtMinEtThreshold) {
75  m_bdtMinEtThreshold = bdtMinEtThreshold;
76 }
77 
78 unsigned int *LVL1::eFEXtauBDT::superCellToPtr(int eta, int phi, int layer) {
79  unsigned int *ptr = 0;
80  switch (layer) {
81  case 0:
82  ptr = m_em0cells[eta][phi];
83  break;
84  case 1:
85  ptr = m_em1cells[eta][phi];
86  break;
87  case 2:
88  ptr = m_em2cells[eta][phi];
89  break;
90  case 3:
91  ptr = m_em3cells[eta][phi];
92  break;
93  case 4:
94  ptr = m_hadcells[eta][phi];
95  break;
96  }
97  return ptr;
98 }
99 
101  initPointers(m_bdt.getETSCells(), m_eTComputeSCellPointers);
102 }
103 
105  initPointers(m_bdt.getEMETSCells(), m_EM_eTComputeSCellPointers);
106 }
107 
109  initPointers(m_bdt.getHADETSCells(), m_HAD_eTComputeSCellPointers);
110 }
111 
112 void LVL1::eFEXtauBDT::initPointers(const std::vector<std::vector<int>> &scells,
113  std::vector<unsigned int *> &ptr_list) {
114  m_log->msg(MSG::DEBUG) << "Will use sum of supercells: " << endmsg;
115  for (auto scell : scells) {
116  int eta = scell[0];
117  int phi = scell[1];
118  int layer = scell[2];
119  m_log->msg(MSG::DEBUG) << "\teta=" << eta << "\tphi=" << phi
120  << "\tlayer=" << layer << endmsg;
121  unsigned int *ptr = superCellToPtr(eta, phi, layer);
122  if (ptr == 0) {
123  m_log->msg(MSG::DEBUG)
124  << "Could not convert eta=" << eta << " phi=" << phi
125  << " layer=" << layer
126  << " to a pointer to supercell. Are they within range?" << endmsg;
127  throw std::domain_error(
128  std::string("Could not convert eta=") + std::to_string(eta) +
129  " phi=" + std::to_string(phi) + " layer=" + std::to_string(layer) +
130  " to a pointer to supercell. Are they within range?");
131  }
132  ptr_list.push_back(ptr);
133  }
134 }
135 
137  m_towersComputeSCellPointers.resize(m_bdt.getNTowers());
138  for (size_t i = 0; i < m_towers.size(); i++) {
139  m_log->msg(MSG::DEBUG) << "Tower " << i << endmsg;
140  initPointers(m_bdt.getTowerSCells(i), m_towersComputeSCellPointers[i]);
141  }
142 }
143 
145  for (size_t i = 0; i < m_bdt.getVariables().size(); i++) {
146  BDTVariable var = m_bdt.getVariables()[i];
147 
148  m_log->msg(MSG::DEBUG) << i << " is " << var.m_name << ", sum of supercells"
149  << endmsg;
150  std::vector<unsigned int *> pointersToSCells;
151  for (size_t j = 0; j < var.m_scells.size(); j++) {
152  int eta = var.m_scells[j][0];
153  int phi = var.m_scells[j][1];
154  int layer = var.m_scells[j][2];
155  m_log->msg(MSG::DEBUG) << "\teta=" << eta << "\tphi=" << phi
156  << "\tlayer=" << layer << endmsg;
157  unsigned int *ptr = superCellToPtr(eta, phi, layer);
158  if (ptr == 0) {
159  m_log->msg(MSG::DEBUG)
160  << "Could not convert eta=" << eta << " phi=" << phi
161  << " layer=" << layer
162  << " to a pointer to supercell. Are they within range?" << endmsg;
163  throw std::domain_error(
164  std::string("Could not convert eta=") + std::to_string(eta) +
165  " phi=" + std::to_string(phi) + " layer=" + std::to_string(layer) +
166  " to a pointer to supercell. Are they within range?");
167  }
168  pointersToSCells.push_back(ptr);
169  }
170 
171  m_bdtVarComputeSCellPointers.push_back(pointersToSCells);
172  }
173 }
174 
176  buildBDTVariables();
177  computeTowers();
178  computeETEstimate();
179  computeHADETEstimate();
180  computeEMETEstimate();
181  computeBDTCondition();
182  computeFracCondition();
183  computeIsCentralTowerSeed();
184 }
185 
187  std::string bdtVariables = "";
188  for (size_t i = 0; i < m_bdtVars.size(); i++) {
189  bdtVariables += std::to_string(m_bdtVars[i]) + " ";
190  }
191 
192  m_log->msg(MSG::DEBUG) << "BDT Variables: " << bdtVariables << endmsg;
193 }
194 
195 // Build BDT Variables
197  for (size_t i = 0; i < m_bdtVarComputeSCellPointers.size(); i++) {
198  bool overflow;
199  m_bdtVars[i] = computeEstimate(m_bdtVarComputeSCellPointers[i], overflow,
200  ENERGY_WIDTH);
201  if (overflow) {
202  m_bdtVars[i] = (1 << ENERGY_WIDTH) - 1;
203  }
204  }
205  debugPrintBDTVariables();
206  m_bdtVarsComputed = true;
207 }
208 
210  // Need BDT variables to be computed
211  if (m_bdtVarsComputed == false) {
212  m_log->msg(MSG::DEBUG)
213  << "BDT Variables not computed. BDT score will be garbage." << endmsg;
214  }
215 
216  m_bdtScore = m_bdt.getBDT().decision_function(m_bdtVars)[0];
217  m_log->msg(MSG::DEBUG) << "BDT Score: " << m_bdtScore << endmsg;
218 }
219 
221  m_eTEstimate = computeEstimate(m_eTComputeSCellPointers, m_eTEstimateOverflow,
222  ENERGY_WIDTH);
223  m_log->msg(MSG::DEBUG) << "ET Estimate: " << m_eTEstimate << endmsg;
224 }
225 
227  m_EM_eTEstimate = computeEstimate(m_EM_eTComputeSCellPointers,
228  m_EM_eTEstimateOverflow, ENERGY_WIDTH);
229  m_log->msg(MSG::DEBUG) << "EM ET Estimate: " << m_EM_eTEstimate << endmsg;
230 }
231 
233  m_HAD_eTEstimate = computeEstimate(m_HAD_eTComputeSCellPointers,
234  m_HAD_eTEstimateOverflow, ENERGY_WIDTH);
235  m_log->msg(MSG::DEBUG) << "HAD ET Estimate: " << m_HAD_eTEstimate << endmsg;
236 }
237 
239  m_log->msg(MSG::DEBUG) << "Towers Estimate: " << endmsg;
240  for (int eta = 0; eta < 3; eta++) {
241  for (int phi = 0; phi < 3; phi++) {
242  int flatIndex = flatTowerIndex(eta, phi);
243  m_log->msg(MSG::DEBUG)
244  << "Tower " << flatIndex << " ET (eta=" << eta << ", phi=" << phi
245  << "): " << m_towers[flatIndex] << endmsg;
246  }
247  }
248 }
249 
250 int LVL1::eFEXtauBDT::flatTowerIndex(int eta, int phi) { return 3 * phi + eta; }
251 
253  for (size_t i = 0; i < m_towers.size(); i++) {
254  bool overflow;
255  m_towers[i] = computeEstimate(m_towersComputeSCellPointers[i], overflow,
256  ENERGY_WIDTH);
257  if (overflow) {
258  m_towers[i] = (1 << ENERGY_WIDTH) - 1;
259  }
260  }
261 
262  debugPrintTowers();
263 }
264 
265 bool LVL1::eFEXtauBDT::isOverflow(unsigned int number, int nBits) {
266  if ((number >> nBits) != 0) {
267  return true;
268  }
269  return false;
270 }
271 
272 unsigned int
273 LVL1::eFEXtauBDT::computeEstimate(std::vector<unsigned int *> &ptr_list,
274  bool &overflow, int resultNBits) {
275  unsigned int estimate = 0;
276  overflow = false;
277  for (unsigned int *it : ptr_list) {
278  estimate += *it;
279  if (isOverflow(estimate, resultNBits)) {
280  overflow = true;
281  }
282  }
283  return estimate;
284 }
285 
286 unsigned int LVL1::eFEXtauBDT::multWithOverflow(unsigned int a, unsigned int b,
287  bool &overflow,
288  int resultNBits) {
289  overflow = false;
290  if (b == 0) {
291  return 0;
292  }
293  unsigned int result = a * b;
294  if (a != result / b) {
295  // This shouldn't happen (a and b are in reality 16 bit numbers), but just
296  // in case.
297  overflow = true;
298  }
299 
300  overflow = isOverflow(result, resultNBits);
301 
302  return result;
303 }
304 
305 unsigned int LVL1::eFEXtauBDT::BitLeftShift(unsigned int number, int by,
306  int totalNBits) {
307  if ((number >> (totalNBits - by)) != 0) {
308  return (1 << totalNBits) - 1;
309  }
310  return number << by;
311 }
312 
314  int n_multipliers = sizeof(m_fracMultipliers) / sizeof(m_fracMultipliers[0]);
315 
316  if ((m_eTEstimate >= *m_maxEtThreshold) or m_eTEstimateOverflow or
317  m_HAD_eTEstimateOverflow) {
318 
319  m_fracCondition = (1 << (n_multipliers - 1)) - 1;
320  return;
321  }
322 
323  if (m_EM_eTEstimateOverflow) {
324  m_fracCondition = 0;
325  return;
326  }
327 
328  m_hadEstimateShifted = BitLeftShift(m_HAD_eTEstimate, 3, ENERGY_WIDTH);
329  int i = 0;
330  for (; i < n_multipliers; i++) {
331 
332  bool overflow;
333  m_emEtXMultiplier[i] = multWithOverflow(
334  *(m_fracMultipliers[i]), m_EM_eTEstimate, overflow, ENERGY_WIDTH);
335  m_emEtXMultiplierOverflow[i] = (int)overflow;
336 
337  if ((m_hadEstimateShifted < m_emEtXMultiplier[i]) or
338  m_emEtXMultiplierOverflow[i]) {
339  break;
340  }
341  }
342  m_fracCondition = i;
343 }
344 
346  computeBDTScore();
347  int n_thresholds = sizeof(m_bdtThresholds) / sizeof(m_bdtThresholds[0]);
348 
349  int toShiftRight = m_bdt.getScorePrecision() - PARAM_WIDTH;
350  // Only compare the MSB bits of the BDT score to the thresholds provided in
351  // the parameters
352  m_bdtScoreShifted = (m_bdtScore >> toShiftRight);
353 
354  if ((m_eTEstimate >= *m_maxEtThreshold) or m_eTEstimateOverflow or
355  m_eTEstimate < *m_bdtMinEtThreshold) {
356 
357  m_bdtCondition = (1 << (n_thresholds - 1)) - 1;
358  return;
359  }
360 
361  int i = 0;
362  for (; i < n_thresholds; i++) {
363  if (m_bdtScoreShifted < *(m_bdtThresholds[i])) {
364  break;
365  }
366  }
367  m_bdtCondition = i;
368 }
369 
370 // Check if central tower qualifies as a seed tower for the tau algorithm
371 // Bitwise computation (as opposed to implementation in eFEXtauBDTAlgo.cxx)
373  m_isSeeded = true;
374 
375  // Get central tower ET
376  unsigned int centralET = m_towers[4];
377 
378  // Loop over all cells and check that the central tower is a local maximum
379  for (unsigned int beta = 0; beta < 3; beta++) {
380  for (unsigned int bphi = 0; bphi < 3; bphi++) {
381  int flatIndex = flatTowerIndex(beta, bphi);
382  // Don't need to compare central cell with itself
383  if ((beta == 1) && (bphi == 1)) {
384  continue;
385  }
386 
387  // Cells to the up and right must have strictly lesser ET
388  if (beta == 2 || (beta == 1 && bphi == 2)) {
389  if (centralET <= m_towers[flatIndex]) {
390  m_isSeeded = false;
391  }
392  }
393  // Cells down and to the left must have lesser or equal ET. If strictly
394  // lesser would create zero TOB if two adjacent cells had equal energy
395  else if (beta == 0 || (beta == 1 && bphi == 0)) {
396  if (centralET < m_towers[flatIndex]) {
397  m_isSeeded = false;
398  }
399  }
400  }
401  }
402 
403  if (m_eTEstimate < *m_etThreshold) {
404  m_isSeeded = false;
405  }
406 
407  m_log->msg(MSG::DEBUG) << "Seeded: " << (int)m_isSeeded << endmsg;
408 }
409 
410 unsigned int LVL1::eFEXtauBDT::getET() const {
411  if (m_eTEstimateOverflow) {
412  return (1 << ENERGY_WIDTH) - 1;
413  }
414  if (m_eTEstimate < *m_etThreshold) {
415  return 0;
416  }
417  return m_eTEstimate;
418 }
LVL1::eFEXtauBDT::computeBDTCondition
void computeBDTCondition()
Definition: eFEXtauBDT.cxx:345
LVL1::eFEXtauBDT::m_towers
std::vector< unsigned int > m_towers
Definition: eFEXtauBDT.h:129
beamspotnt.var
var
Definition: bin/beamspotnt.py:1394
LVL1::eFEXtauBDT::m_bdt
eFEXBDT m_bdt
Definition: eFEXtauBDT.h:147
LVL1::eFEXtauBDT::flatTowerIndex
int flatTowerIndex(int eta, int phi)
Definition: eFEXtauBDT.cxx:250
get_generator_info.result
result
Definition: get_generator_info.py:21
LVL1::eFEXtauBDT::setPointerToMaxETParam
void setPointerToMaxETParam(unsigned int *maxEtThreshold)
Definition: eFEXtauBDT.cxx:68
LVL1::eFEXtauBDT::initPointers
void initPointers(const std::vector< std::vector< int >> &scells, std::vector< unsigned int * > &ptr_list)
Definition: eFEXtauBDT.cxx:112
LVL1::eFEXtauBDT::initHADETPointers
void initHADETPointers()
Definition: eFEXtauBDT.cxx:108
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
LVL1::eFEXtauBDT::setPointerToBDTMinETParam
void setPointerToBDTMinETParam(unsigned int *bdtMinEtThreshold)
Definition: eFEXtauBDT.cxx:73
index
Definition: index.py:1
eFEXBDT::getVariables
const std::vector< BDTVariable > & getVariables() const
Definition: eFEXBDT.h:58
skel.it
it
Definition: skel.GENtoEVGEN.py:396
LVL1::eFEXtauBDT::getET
unsigned int getET() const
Definition: eFEXtauBDT.cxx:410
LVL1::eFEXtauBDT::debugPrintBDTVariables
void debugPrintBDTVariables()
Definition: eFEXtauBDT.cxx:186
LVL1::eFEXtauBDT::debugPrintTowers
void debugPrintTowers()
Definition: eFEXtauBDT.cxx:238
LVL1::eFEXtauBDT::isOverflow
bool isOverflow(unsigned int number, int nBits)
Definition: eFEXtauBDT.cxx:265
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
LVL1::eFEXtauBDT::setPointerToBDTThresholdsParam
void setPointerToBDTThresholdsParam(int index, unsigned int *bdtThresholds)
Definition: eFEXtauBDT.cxx:59
LVL1::eFEXtauBDT::computeETEstimate
void computeETEstimate()
Definition: eFEXtauBDT.cxx:220
LVL1::eFEXtauBDT::computeEMETEstimate
void computeEMETEstimate()
Definition: eFEXtauBDT.cxx:226
ENERGY_WIDTH
#define ENERGY_WIDTH
Definition: eFEXtauBDT.cxx:15
LVL1::eFEXtauBDT::computeTowers
void computeTowers()
Definition: eFEXtauBDT.cxx:252
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
LVL1::eFEXtauBDT::m_log
AthAlgTool * m_log
Definition: eFEXtauBDT.h:148
LVL1::eFEXtauBDT::eFEXtauBDT
eFEXtauBDT(AthAlgTool *log, std::string config_path)
Constructors.
Definition: eFEXtauBDT.cxx:19
lumiFormat.i
int i
Definition: lumiFormat.py:85
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
LVL1::eFEXtauBDT::setPointerToETThresholdParam
void setPointerToETThresholdParam(unsigned int *etThreshold)
Definition: eFEXtauBDT.cxx:64
LVL1::eFEXtauBDT::setPointerToSCell
void setPointerToSCell(int eta, int phi, int layer, unsigned int *sCellPtr)
Definition: eFEXtauBDT.cxx:33
LVL1::eFEXtauBDT::initETPointers
void initETPointers()
Definition: eFEXtauBDT.cxx:100
fitman.by
by
Definition: fitman.py:411
LVL1::eFEXtauBDT::initTowersPointers
void initTowersPointers()
Definition: eFEXtauBDT.cxx:136
internal_poltrig::estimate
REAL estimate(const int &elen, REAL *e)
Definition: PolygonTriangulator.cxx:451
LVL1::eFEXtauBDT::initBDTVars
void initBDTVars()
Definition: eFEXtauBDT.cxx:144
python.selection.number
number
Definition: selection.py:20
LVL1::eFEXtauBDT::m_emEtXMultiplier
std::vector< unsigned int > m_emEtXMultiplier
Definition: eFEXtauBDT.h:127
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
LVL1::eFEXtauBDT::m_fracMultipliers
unsigned int * m_fracMultipliers[3]
Definition: eFEXtauBDT.h:110
eFEXBDT::getNTowers
int getNTowers() const
Definition: eFEXBDT.h:80
LVL1::eFEXtauBDT::buildBDTVariables
void buildBDTVariables()
Definition: eFEXtauBDT.cxx:196
LVL1::eFEXtauBDT::setPointerToFracMultipliersParam
void setPointerToFracMultipliersParam(int index, unsigned int *fracMultipliers)
Definition: eFEXtauBDT.cxx:54
DeMoScan.index
string index
Definition: DeMoScan.py:364
eFEXtauBDT.h
a
TList * a
Definition: liststreamerinfos.cxx:10
LVL1::eFEXtauBDT::computeBDTScore
void computeBDTScore()
Definition: eFEXtauBDT.cxx:209
DEBUG
#define DEBUG
Definition: page_access.h:11
AthCommonMsg::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
LVL1::eFEXtauBDT::computeFracCondition
void computeFracCondition()
Definition: eFEXtauBDT.cxx:313
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
PARAM_WIDTH
#define PARAM_WIDTH
Definition: eFEXtauBDT.cxx:16
LVL1::eFEXtauBDT::superCellToPtr
unsigned int * superCellToPtr(int eta, int phi, int layer)
Definition: eFEXtauBDT.cxx:78
LVL1::eFEXtauBDT::m_emEtXMultiplierOverflow
std::vector< unsigned int > m_emEtXMultiplierOverflow
Definition: eFEXtauBDT.h:128
LVL1::eFEXtauBDT::~eFEXtauBDT
virtual ~eFEXtauBDT()
Destructor.
Definition: eFEXtauBDT.cxx:31
AthAlgTool
Definition: AthAlgTool.h:26
LVL1::eFEXtauBDT::BitLeftShift
unsigned int BitLeftShift(unsigned int number, int by, int totalNBits)
Definition: eFEXtauBDT.cxx:305
MuonParameters::beta
@ beta
Definition: MuonParamDefs.h:144
LVL1::eFEXtauBDT::m_bdtVars
std::vector< unsigned int > m_bdtVars
Definition: eFEXtauBDT.h:132
LVL1::eFEXtauBDT::initEMETPointers
void initEMETPointers()
Definition: eFEXtauBDT.cxx:104
LVL1::eFEXtauBDT::computeIsCentralTowerSeed
void computeIsCentralTowerSeed()
Definition: eFEXtauBDT.cxx:372
LVL1::eFEXtauBDT::computeEstimate
unsigned int computeEstimate(std::vector< unsigned int * > &ptr_list, bool &overflow, int resultNBits)
Definition: eFEXtauBDT.cxx:273
LVL1::eFEXtauBDT::computeHADETEstimate
void computeHADETEstimate()
Definition: eFEXtauBDT.cxx:232
LVL1::eFEXtauBDT::multWithOverflow
unsigned int multWithOverflow(unsigned int a, unsigned int b, bool &overflow, int resultNBits)
Definition: eFEXtauBDT.cxx:286
BDTVariable
Definition: eFEXBDT.h:16
LVL1::eFEXtauBDT::next
void next()
Definition: eFEXtauBDT.cxx:175