ATLAS Offline Software
LArCellPreparationAlg.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3  */
4 
5 /*
6  This Algorithm simulates the energy encoding of all LAr cells for Global and simulated the truncation of cells
7  from overflowing FEB2s. The hardware-accurate cells are then stored in a GlobalLArCellContainer object within
8  StoreGate
9 */
10 
11 #include "LArCellPreparationAlg.h"
12 
14 #include "CaloEvent/CaloCell.h"
16 
17 #include "TMath.h"
18 #include <fstream>
19 #include <vector>
20 #include <cmath>
21 
22 namespace GlobalSim {
23 
24  // Initialize function which defines the parameters of the multilinear energy encoding, calculates the ranges,
25  // determines the maximum number of cells per FEB2 that can be sent to Global and reads the LAr cell map to get
26  // the full list of associated boards and how they are wired to the Global MUXs
28  ATH_MSG_INFO ("Initializing " << name());
29  ATH_MSG_INFO ("Target name of GlobalLArCellContainer is " << m_LArCellContainerKey);
30 
34 
36 
37  ATH_MSG_INFO("Active energy encoding scheme for LAr cells is " << m_numberOfEnergyBits.value() << " energy bits with " << m_valueLSB.value() << " MeV for the least significant bit and a gain factor of " << m_valueGainFactor.value());
38 
40 
41  m_readoutRanges[0] = 0;
47 
48  ATH_MSG_DEBUG("Readout scheme with " << m_numberOfEnergyBits.value() << "-bits provides the following four energy thresholds (with " << m_stepsPerRange << " discrete steps on each threshold)");
49  ATH_MSG_DEBUG("GEP cell energy range 0: min = " << m_readoutRanges[0] << " MeV -> max = " << m_readoutRanges[1] << " MeV");
50  ATH_MSG_DEBUG("GEP cell energy range 1: min = " << m_readoutRanges[1] + m_valueLSB.value() << " MeV -> max = " << m_readoutRanges[2] << " MeV");
51  ATH_MSG_DEBUG("GEP cell energy range 2: min = " << m_readoutRanges[2]+(m_valueGainFactor.value()*m_valueLSB.value()) << " MeV -> max = " << m_readoutRanges[3] << " MeV");
52  ATH_MSG_DEBUG("GEP cell energy range 3: min = " << m_readoutRanges[3]+(m_valueGainFactor.value()*m_valueGainFactor.value()*m_valueLSB.value()) << " MeV -> max = " << m_readoutRanges[4] << " MeV");
53 
54  // At the moment only have a detailed scheme for 6-10 bit readouts, thus rejecting any other value
55  switch(m_numberOfEnergyBits.value()) {
56  case 6: m_maxCellsPerFEB = 62; break;
57  case 7: m_maxCellsPerFEB = 54; break;
58  case 8: m_maxCellsPerFEB = 48; break;
59  case 9: m_maxCellsPerFEB = 43; break;
60  case 10: m_maxCellsPerFEB = 39; break;
61  default: ATH_MSG_FATAL("A LAr cell energy encoding scheme with " << m_numberOfEnergyBits.value() << " energy bits is currently not defined");
62  return StatusCode::FAILURE;
63  }
64 
65  ATH_MSG_INFO("Loading cell map associating LAr cells to FEB2s");
66 
67  std::string cellMapPath = PathResolverFindCalibFile(m_LArCellMap);
68  if(cellMapPath.empty()) ATH_MSG_ERROR("Could not find file with cell map data: " << m_LArCellMap.value());
69 
70  std::ifstream file(cellMapPath.c_str());
71 
72  unsigned n_cells = 0;
73  m_gblLArCellMap.clear();
74 
75  std::map<std::string,Feb2MuxInfo> feb2MuxAssoc;
76 
77  // Read input file
78  if (file.is_open()) {
79 
80  int online_id, offline_id, channel, con_num, fbr;
81  std::string assocFEB2, con_type, muxname, muxrack, cnnctr, laspname, lasprack;
82 
83  // Skipping header of file
84  std::getline(file, assocFEB2);
85 
86  // start reading data
87  while (true) {
88 
89  file >> offline_id >> online_id >> assocFEB2 >> channel >> con_type >> con_num >> fbr >> muxname >> muxrack >> cnnctr >> laspname >> lasprack;
90 
91  if (file.eof()) break;
92 
93  GlobalSim::GlobalLArCell gblLArCell(offline_id, assocFEB2, channel);
94  gblLArCell.setBoardConnector(cnnctr, con_type, con_num, fbr);
95  gblLArCell.setMUX(muxname);
96  gblLArCell.setLASP(laspname);
97 
98  m_gblLArCellMap.insert(std::pair<int, GlobalSim::GlobalLArCell>(offline_id, gblLArCell));
99 
100  int indexOnMux = fbr;
101  if (cnnctr == "B") indexOnMux += 24;
102  if (cnnctr == "C") indexOnMux += 32;
103 
104  // Add FEB2 to MUX association map
105  auto itr = feb2MuxAssoc.find(assocFEB2);
106  if (itr == feb2MuxAssoc.end()) {
107  feb2MuxAssoc.insert(std::pair<std::string,Feb2MuxInfo>(assocFEB2, {muxname, indexOnMux}));
108  }
109 
110  ++n_cells;
111  }
112  }
113  else {
114  ATH_MSG_ERROR("Could not open file containing the cell to FEB2 association");
115  return StatusCode::FAILURE;
116  }
117 
118  ATH_MSG_DEBUG("Loaded FEB2 information for " << n_cells << " LAr cells");
119 
120  // Constructing the GlobalLArCellContainer
121  m_gblLArCellContainerTemplate = std::make_unique<GlobalSim::GlobalLArCellContainer>(feb2MuxAssoc);
122  m_gblLArCellContainerTemplate->setMaxCellsPerFeb2(m_maxCellsPerFEB);
123 
124  return StatusCode::SUCCESS;
125  }
126 
127 
128  // Read in a CaloCell container, encode the cell energy according to the active encoding scheme, perform
129  // the FEB2 truncation and then store all cells which would be sent to Global in a GlobalLArCellContainer
130  StatusCode LArCellPreparationAlg::execute(const EventContext& ctx) const {
131 
132  ATH_MSG_DEBUG ("Executing LArCellPreparationAlg algorithm");
133 
135  CHECK(eventInfo.isValid());
136 
137  // Read in container containing calorimeter cells
138  auto h_caloCells = SG::makeHandle(m_caloCellsKey, ctx);
139  CHECK(h_caloCells.isValid());
140  const auto & cells = *h_caloCells;
141 
142  ATH_MSG_DEBUG("Reading " << std::to_string(h_caloCells->size()) << " cells in input cell container");
143 
145  if (!totalNoiseHdl.isValid()) {return StatusCode::FAILURE;}
146  const CaloNoise* totalNoiseCDO = *totalNoiseHdl;
147 
148  std::map<std::string,std::vector<GlobalSim::GlobalLArCell>> gblLArCellsPerFEB2;
149 
150  for(const auto *cell: cells){
151 
152  int cell_id = (cell->ID().get_identifier32()).get_compact();
153 
154  auto gblLArCell_itr = m_gblLArCellMap.find(cell_id);
155  if (gblLArCell_itr == m_gblLArCellMap.end()) continue;
156 
157  GlobalSim::GlobalLArCell gblLArCell = gblLArCell_itr->second;
158 
159  float totalNoise = totalNoiseCDO->getNoise(cell->ID(), cell->gain());
160  float sigma = cell->energy() / totalNoise;
161 
162  // Only send positive-energy 2sigma cells to the GEP
163  if (sigma < 2.0) continue;
164 
165  if (cell->badcell()) continue;
166 
167  std::pair<float, boost::dynamic_bitset<>> gep_energy = encodeEnergy(cell->energy() / TMath::CosH(cell->eta()));
168 
169  gblLArCell.setEnergy(gep_energy.first, std::move(gep_energy.second));
170  gblLArCell.setSigma(sigma);
171  gblLArCell.setPosition(cell->eta(), cell->phi());
172  gblLArCell.setSampling(cell->caloDDE()->getSampling());
173  gblLArCell.setLayer(cell->caloDDE()->getLayer());
174 
175  // Fill cells into map according to FEB
176  auto feb2_itr = gblLArCellsPerFEB2.find(gblLArCell.getFEB2());
177  if (feb2_itr != gblLArCellsPerFEB2.end()) feb2_itr->second.push_back(gblLArCell);
178  else {
179  std::vector<GlobalSim::GlobalLArCell> cellsThisFEB;
180  cellsThisFEB.push_back(gblLArCell);
181  gblLArCellsPerFEB2.insert(std::pair<std::string,std::vector<GlobalSim::GlobalLArCell>>(gblLArCell.getFEB2(),cellsThisFEB));
182  }
183  }
184 
185  // Set up a GlobalLArCellContainer from template
187  auto gblLArCellContainer = std::make_unique<GlobalSim::GlobalLArCellContainer>(templateRef);
188 
189  // do truncation
190  for (auto& [feb2Name, cells] : gblLArCellsPerFEB2) {
191 
192  // Overflow and error flags
193  bool inOverflow = false;
194  bool inError = false;
195 
196  // LAr FEBs might overflow, so they will get truncated
197  if (cells.size() > m_maxCellsPerFEB) {
198  ATH_MSG_INFO("FEB " << feb2Name << " is sending " << cells.size() << " cells, which is more cells than GEP can receive. Removing all but the possible " << m_maxCellsPerFEB << " cells.");
200  inOverflow = true;
201  }
202 
203  for (auto& gblLArCell : cells)
204  gblLArCellContainer->push_back(std::move(gblLArCell));
205 
206  gblLArCellContainer->setFeb2Flags(feb2Name, inOverflow, inError);
207  }
208  ATH_MSG_DEBUG("Global is receiving a total of " << gblLArCellContainer->size() << " LAr cells in this event");
209 
211  ATH_CHECK( h_gblLArCellContainer.record( std::move(gblLArCellContainer) ) );
212 
213  return StatusCode::SUCCESS;
214  }
215 
216 
217  // Function to emulate the hardware realistic energy of the cell by applying the
218  // multilinear energy encoding scheme defined in the initialize function and at
219  // the same time building the bitstring encoding the energy
220  std::pair<float,boost::dynamic_bitset<>> LArCellPreparationAlg::encodeEnergy(float energy) const {
221 
222  // Negative energy cell
223  if (energy < 0) return std::pair<float,boost::dynamic_bitset<>>(0.0,boost::dynamic_bitset<>(m_numberOfEnergyBits.value(),0));
224 
225  // Saturated cell
226  if (energy > m_readoutRanges[4]) {
227  int max_value = ( m_stepsPerRange + m_stepsPerRange*m_valueGainFactor.value() +
229  (m_stepsPerRange-1)*m_valueGainFactor.value()*m_valueGainFactor.value()*m_valueGainFactor.value() ) * m_valueLSB.value();
230  return std::pair<float,boost::dynamic_bitset<>>(max_value,boost::dynamic_bitset<>(m_numberOfEnergyBits.value(),std::pow(2,m_numberOfEnergyBits.value())-1));
231  }
232 
233  int range = 0;
234  for (int i = 1; i <= 3; ++i) {
235  if (energy > m_readoutRanges[i]) range = i;
236  }
237 
239 
240  float encoded_energy = -1;
241  int used_steps = 0;
242  for (int i = 0; i < m_stepsPerRange; ++i) {
243  encoded_energy = m_readoutRanges[range]+(step*i);
244  used_steps = i;
245  if (energy < (m_readoutRanges[range]+(step*(i+1)))) break;
246  }
247 
248  std::size_t n_bitsE = m_numberOfEnergyBits.value() - 2;
249  boost::dynamic_bitset<> energy_bits(m_numberOfEnergyBits.value(), used_steps);
250  energy_bits |= boost::dynamic_bitset<>(m_numberOfEnergyBits.value(), static_cast<unsigned long>(range) << n_bitsE);
251 
252  return std::pair<float,boost::dynamic_bitset<>>(encoded_energy,energy_bits);
253  }
254 
255 
256  // Function to find FEB2s which have more 2sigma cells in this event than the available
257  // latency allows to send and truncates overflowing cells
258  StatusCode LArCellPreparationAlg::removeCellsFromOverloadedFEB(std::vector<GlobalSim::GlobalLArCell> &cells) const {
259 
260  // Sort cells by channel
261  std::sort(cells.begin(), cells.end(), [](const auto& a, const auto& b) {
262  return a.getChannel() < b.getChannel(); });
263 
264  // Remove overflowing cells from vector
265  if (cells.size() > m_maxCellsPerFEB)
266  cells.erase(std::next(cells.begin(), m_maxCellsPerFEB), cells.end());
267 
268  return StatusCode::SUCCESS;
269  }
270 
271 } // namespace GlobalSim
272 
RunTileCalibRec.cells
cells
Definition: RunTileCalibRec.py:281
GlobalSim::LArCellPreparationAlg::m_gblLArCellContainerTemplate
std::unique_ptr< GlobalSim::GlobalLArCellContainer > m_gblLArCellContainerTemplate
GlobalLArCellContainer template which is constructed in initialize and used in execute.
Definition: LArCellPreparationAlg.h:56
GlobalSim::LArCellPreparationAlg::m_valueGainFactor
Gaudi::Property< int > m_valueGainFactor
Definition: LArCellPreparationAlg.h:64
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
LArCellPreparationAlg.h
pdg_comparison.sigma
sigma
Definition: pdg_comparison.py:324
GlobalSim::GlobalLArCell::setSampling
void setSampling(int sampling)
set sampling of cell
Definition: GlobalLArCell.h:170
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
plotting.yearwise_efficiency.channel
channel
Definition: yearwise_efficiency.py:24
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
GlobalSim::LArCellPreparationAlg::m_gblLArCellMap
std::map< int, GlobalSim::GlobalLArCell > m_gblLArCellMap
LAr cell map where the key is the offline cell ID.
Definition: LArCellPreparationAlg.h:54
GlobalSim::LArCellPreparationAlg::m_totalNoiseKey
SG::ReadCondHandleKey< CaloNoise > m_totalNoiseKey
Key to the total noise used for each CaloCell.
Definition: LArCellPreparationAlg.h:74
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
GlobalSim::LArCellPreparationAlg::m_readoutRanges
int m_readoutRanges[5]
array holding the energy edges of the multilinear encoding
Definition: LArCellPreparationAlg.h:47
GlobalSim::LArCellPreparationAlg::m_valueLSB
Gaudi::Property< int > m_valueLSB
Definition: LArCellPreparationAlg.h:63
GlobalSim::GlobalLArCell::setEnergy
void setEnergy(float energy)
set transverse energy in MeV
Definition: GlobalLArCell.h:161
CaloCell.h
GlobalSim::GlobalLArCell::setSigma
void setSigma(float sigma)
set significancy of energy deposit
Definition: GlobalLArCell.h:172
GlobalSim::GlobalLArCell::setBoardConnector
void setBoardConnector(std::string connector, std::string type, int number, int fiber)
set properties of associated board connector
Definition: GlobalLArCell.h:175
GlobalSim::LArCellPreparationAlg::initialize
virtual StatusCode initialize() override
initialize function running before first event
Definition: LArCellPreparationAlg.cxx:27
MuonR4::to_string
std::string to_string(const SectorProjector proj)
Definition: MsTrackSeeder.cxx:74
CaloNoise::getNoise
float getNoise(const IdentifierHash h, const int gain) const
Accessor by IdentifierHash and gain.
Definition: CaloNoise.h:34
GlobalSim::LArCellPreparationAlg::m_stepsPerRange
int m_stepsPerRange
number of discrete values per multilinear energy encoding range
Definition: LArCellPreparationAlg.h:49
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:274
GlobalSim::GlobalLArCell::getFEB2
const std::string & getFEB2() const
get the name of the FEB2 this cell is associated with
Definition: GlobalLArCell.h:192
GlobalSim
AlgTool that to test whether expected the TIP values generated by data supplied by eEmMultTestBench c...
Definition: dump.h:8
GlobalSim::LArCellPreparationAlg::m_numberOfEnergyBits
Gaudi::Property< int > m_numberOfEnergyBits
Parameters defining the multilinear energy encoding scheme.
Definition: LArCellPreparationAlg.h:62
GlobalSim::LArCellPreparationAlg::encodeEnergy
std::pair< float, boost::dynamic_bitset<> > encodeEnergy(float energy) const
Function to simulate the cell energy as seen by Global.
Definition: LArCellPreparationAlg.cxx:220
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
GlobalSim::LArCellPreparationAlg::m_caloCellsKey
SG::ReadHandleKey< CaloCellContainer > m_caloCellsKey
Key to the CaloCell container.
Definition: LArCellPreparationAlg.h:71
ParticleGun_FastCalo_ChargeFlip_Config.energy
energy
Definition: ParticleGun_FastCalo_ChargeFlip_Config.py:78
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
lumiFormat.i
int i
Definition: lumiFormat.py:85
GlobalSim::GlobalLArCell::setLayer
void setLayer(int layer)
set layer of cell
Definition: GlobalLArCell.h:171
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:194
file
TFile * file
Definition: tile_monitor.h:29
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
GlobalSim::LArCellPreparationAlg::execute
virtual StatusCode execute(const EventContext &) const override
execute function running for every event
Definition: LArCellPreparationAlg.cxx:130
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
CaloNoise
Definition: CaloNoise.h:16
PathResolver.h
GlobalSim::LArCellPreparationAlg::m_LArCellMap
Gaudi::Property< std::string > m_LArCellMap
Path to the LAr cell map in the CVMFS GroupData space.
Definition: LArCellPreparationAlg.h:67
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:76
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
EventInfo.h
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:321
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
GlobalSim::GlobalLArCellContainer
Definition: GlobalLArCellContainer.h:22
GlobalSim::LArCellPreparationAlg::m_maxCellsPerFEB
unsigned m_maxCellsPerFEB
maximum number of cells that can be send to Global for each FEB2
Definition: LArCellPreparationAlg.h:51
a
TList * a
Definition: liststreamerinfos.cxx:10
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
GlobalSim::LArCellPreparationAlg::removeCellsFromOverloadedFEB
StatusCode removeCellsFromOverloadedFEB(std::vector< GlobalSim::GlobalLArCell > &cells) const
Function to simulate the truncation of overflowing FEB2s.
Definition: LArCellPreparationAlg.cxx:258
GlobalSim::GlobalLArCell::setLASP
void setLASP(std::string laspname)
set name of associated LASP
Definition: GlobalLArCell.h:174
GlobalSim::LArCellPreparationAlg::m_eventInfo
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfo
Key for the EventInfo object.
Definition: LArCellPreparationAlg.h:59
LArCellBinning.step
step
Definition: LArCellBinning.py:158
GlobalSim::GlobalLArCell::setMUX
void setMUX(std::string muxname)
set name of associated MUX
Definition: GlobalLArCell.h:173
GlobalSim::GlobalLArCell
Definition: GlobalLArCell.h:14
GlobalSim::GlobalLArCell::setPosition
void setPosition(float eta, float phi)
set position of cell in eta-phi space
Definition: GlobalLArCell.h:166
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
python.LArMinBiasAlgConfig.float
float
Definition: LArMinBiasAlgConfig.py:65
GlobalSim::LArCellPreparationAlg::m_LArCellContainerKey
SG::WriteHandleKey< GlobalSim::GlobalLArCellContainer > m_LArCellContainerKey
Key to writing the GlobalLArCellContainer to StoreGate.
Definition: LArCellPreparationAlg.h:77