ATLAS Offline Software
Loading...
Searching...
No Matches
BasicConstantGPUDataExporter.cxx
Go to the documentation of this file.
1//
2// Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3//
4// Dear emacs, this is -*- c++ -*-
5//
6
8
10
12
17
18#include "boost/chrono/chrono.hpp"
19#include "boost/chrono/thread_clock.hpp"
20
21#include <algorithm>
22
23using namespace CaloRecGPU;
24
25BasicConstantGPUDataExporter::BasicConstantGPUDataExporter(const std::string & type, const std::string & name, const IInterface * parent):
26 base_class(type, name, parent),
27 CaloGPUTimed(this),
29{
30}
31
33{
35 {
36 ATH_MSG_INFO("Initializing data tool again...");
37 return StatusCode::SUCCESS;
38 }
39
40 ATH_CHECK(m_noiseCDOKey.initialize());
41
42 ATH_CHECK(m_caloMgrKey.initialize());
43
45
46 return StatusCode::SUCCESS;
47}
48
50{
51 ATH_MSG_ERROR("BasicConstantGPUDataExporter (" << this->name() << ") must be used with the "
52 "GPU data preparation happening on the first event.");
53
54 return StatusCode::FAILURE;
55}
56
57StatusCode BasicConstantGPUDataExporter::convert(const EventContext & ctx, ConstantDataHolder & cd, const bool keep_CPU_info) const
58{
59 using clock_type = boost::chrono::thread_clock;
60 auto time_cast = [](const auto & before, const auto & after)
61 {
62 return boost::chrono::duration_cast<boost::chrono::microseconds>(after - before).count();
63 };
64
65 auto start = clock_type::now();
66
68 const CaloDetDescrManager * calo_dd_man = *caloMgrHandle;
69
70 cd.m_geometry.allocate();
71
72 const CaloCell_ID * calo_id = calo_dd_man->getCaloCell_ID();
73
74#if CALORECGPU_ETA_PHI_MAP_DEBUG
75 float min_eta_pos[NumSamplings], max_eta_pos[NumSamplings],
76 min_eta_neg[NumSamplings], max_eta_neg[NumSamplings],
77 min_phi_pos[NumSamplings], max_phi_pos[NumSamplings],
78 min_phi_neg[NumSamplings], max_phi_neg[NumSamplings],
79 min_deta [NumSamplings], min_dphi [NumSamplings],
80 max_deta [NumSamplings], max_dphi [NumSamplings],
81 avg_deta [NumSamplings], avg_dphi [NumSamplings],
82 min_dr [NumSamplings], min_dz [NumSamplings],
83 max_dr [NumSamplings], max_dz [NumSamplings];
84
85 for (int i = 0; i < NumSamplings; ++i)
86 {
87 min_eta_pos[i] = std::numeric_limits<float>::max();
88 max_eta_pos[i] = std::numeric_limits<float>::lowest();
89 min_eta_neg[i] = std::numeric_limits<float>::max();
90 max_eta_neg[i] = std::numeric_limits<float>::lowest();
91 min_phi_pos[i] = std::numeric_limits<float>::max();
92 max_phi_pos[i] = std::numeric_limits<float>::lowest();
93 min_phi_neg[i] = std::numeric_limits<float>::max();
94 max_phi_neg[i] = std::numeric_limits<float>::lowest();
95 min_deta [i] = std::numeric_limits<float>::max();
96 min_dphi [i] = std::numeric_limits<float>::max();
97 max_deta [i] = std::numeric_limits<float>::lowest();
98 max_dphi [i] = std::numeric_limits<float>::lowest();
99 avg_deta [i] = 0.f;
100 avg_dphi [i] = 0.f;
101 min_dr [i] = std::numeric_limits<float>::max();
102 min_dz [i] = std::numeric_limits<float>::max();
103 max_dr [i] = std::numeric_limits<float>::lowest();
104 max_dz [i] = std::numeric_limits<float>::lowest();
105
106 cd.m_geometry->nCellsPerSampling[i] = 0;
107 }
108#else
109 float min_eta[NumSamplings], max_eta[NumSamplings];
110
111 for (int i = 0; i < NumSamplings; ++i)
112 {
113 min_eta[i] = std::numeric_limits<float>::max();
114 max_eta[i] = std::numeric_limits<float>::lowest();
115
116 cd.m_geometry->nCellsPerSampling[i] = 0;
117 }
118#endif
119
120 for (int cell = 0; cell < NCaloCells; ++cell)
121 {
122 const CaloDetDescrElement * caloElement = calo_dd_man->get_element((IdentifierHash) cell);
123
124 const Identifier cell_identifier = calo_id->cell_id((IdentifierHash) cell);
125
126 const int sampling = calo_id->calo_sample(cell_identifier);
127 const int intra_calo_sampling = calo_id->sampling(cell_identifier);
128 const int subcalo = caloElement->getSubCalo();
129 const int region = calo_id->region(cell_identifier);
130
131 const bool is_PS = (subcalo == CaloCell_ID::LAREM && intra_calo_sampling == 0);
132
133 const bool is_HECIW_or_FCAL = ( (subcalo == CaloCell_ID::LARHEC && region == 1 ) ||
134 (subcalo == CaloCell_ID::LARFCAL && intra_calo_sampling > 1 ) );
135
136 cd.m_geometry->otherCellInfo[cell] = OtherCellInfo(sampling,
140 is_PS,
141 is_HECIW_or_FCAL);
142 cd.m_geometry->x[cell] = caloElement->x();
143 cd.m_geometry->y[cell] = caloElement->y();
144 cd.m_geometry->z[cell] = caloElement->z();
145 cd.m_geometry->r[cell] = caloElement->r();
146 cd.m_geometry->eta[cell] = caloElement->eta();
147 cd.m_geometry->phi[cell] = caloElement->phi();
148
149 cd.m_geometry->dx[cell] = caloElement->dx();
150 cd.m_geometry->dy[cell] = caloElement->dy();
151 cd.m_geometry->dz[cell] = caloElement->dz();
152 cd.m_geometry->dr[cell] = caloElement->dr();
153 cd.m_geometry->deta[cell] = caloElement->deta();
154 cd.m_geometry->dphi[cell] = caloElement->dphi();
155
156 cd.m_geometry->volume[cell] = caloElement->volume();
157 cd.m_geometry->neighbours.offsets[cell] = 0;
158
159#if CALORECGPU_ETA_PHI_MAP_DEBUG
160 const float eta_minus = caloElement->eta() - caloElement->deta() / 2;
161 const float eta_plus = caloElement->eta() + caloElement->deta() / 2;
162 const float phi_minus = caloElement->phi() - caloElement->dphi() / 2;
163 const float phi_plus = caloElement->phi() + caloElement->dphi() / 2;
164
165 if (caloElement->eta() >= 0)
166 {
167 min_eta_pos[sampling] = std::min({min_eta_pos[sampling], eta_minus, eta_plus});
168 min_phi_pos[sampling] = std::min({min_phi_pos[sampling], phi_minus, phi_plus});
169 max_eta_pos[sampling] = std::max({max_eta_pos[sampling], eta_minus, eta_plus});
170 max_phi_pos[sampling] = std::max({max_phi_pos[sampling], phi_minus, phi_plus});
171 }
172 else
173 {
174 min_eta_neg[sampling] = std::min({min_eta_neg[sampling], eta_minus, eta_plus});
175 min_phi_neg[sampling] = std::min({min_phi_neg[sampling], phi_minus, phi_plus});
176 max_eta_neg[sampling] = std::max({max_eta_neg[sampling], eta_minus, eta_plus});
177 max_phi_neg[sampling] = std::max({max_phi_neg[sampling], phi_minus, phi_plus});
178 }
179 min_deta[sampling] = std::min(min_deta[sampling], caloElement->deta());
180 min_dphi[sampling] = std::min(min_dphi[sampling], caloElement->dphi());
181 max_deta[sampling] = std::max(max_deta[sampling], caloElement->deta());
182 max_dphi[sampling] = std::max(max_dphi[sampling], caloElement->dphi());
183 min_dr [sampling] = std::min(min_dr [sampling], caloElement->dr ());
184 min_dz [sampling] = std::min(min_dz [sampling], caloElement->dz ());
185 max_dr [sampling] = std::max(max_dr [sampling], caloElement->dr ());
186 max_dz [sampling] = std::max(max_dz [sampling], caloElement->dz ());
187
188 avg_deta[sampling] += caloElement->deta();
189 avg_dphi[sampling] += caloElement->dphi();
190#else
191 const float eta_below = fabsf(caloElement->eta() - caloElement->deta() / 2);
192 const float eta_above = fabsf(caloElement->eta() + caloElement->deta() / 2);
193 min_eta[sampling] = std::min(min_eta[sampling], std::min(eta_below, eta_above));
194 max_eta[sampling] = std::max(max_eta[sampling], std::max(eta_below, eta_above));
195#endif
196
197 cd.m_geometry->nCellsPerSampling[sampling] += 1;
198 }
199
200 auto after_geo = clock_type::now();
201
202 for (int i = 0; i < NumSamplings; ++i)
203 {
204#if CALORECGPU_ETA_PHI_MAP_DEBUG
205 avg_deta[i] /= cd.m_geometry->nCellsPerSampling[i];
206 avg_dphi[i] /= cd.m_geometry->nCellsPerSampling[i];
207 if (cd.m_geometry->nCellsPerSampling[i] > 0)
208 {
209 printf("CALORECGPU ETA PHI MAP DEBUG OUTPUT: %d | %f %f %f %f | %f %f %f %f | %f %f | %f %f | %f %f %d | %f %f | %f %f\n",
210 i, min_eta_neg[i], min_phi_neg[i], max_eta_neg[i], max_phi_neg[i],
211 min_eta_pos[i], min_phi_pos[i], max_eta_pos[i], max_phi_pos[i],
212 min_deta[i], min_dphi[i], max_deta[i], max_dphi[i],
213 avg_deta[i], avg_dphi[i], cd.m_geometry->nCellsPerSampling[i],
214 min_dr[i], min_dz[i], max_dr[i], max_dz[i]);
215 }
216 const float this_min_eta = std::min(fabsf(max_eta_neg[i]), fabsf(min_eta_pos[i]));
217 const float this_max_eta = std::max(fabsf(min_eta_neg[i]), fabsf(max_eta_pos[i]));
218#else
219 const float this_min_eta = min_eta[i];
220 const float this_max_eta = max_eta[i];
221#endif
222
223 if (cd.m_geometry->nCellsPerSampling[i] <= 0)
224 {
225 cd.m_geometry->etaPhiToCell.initialize(i, -1, 1);
226 //Just to prevent NaN.
227 }
228 else
229 {
230 cd.m_geometry->etaPhiToCell.initialize(i, this_min_eta, this_max_eta);
231 }
232 }
233
234 cd.m_geometry->fill_eta_phi_map();
235
236#if CALORECGPU_ETA_PHI_MAP_DEBUG
237 for (int i = 0; i < NumSamplings; ++i)
238 {
239 auto printer = [&](const auto & entry)
240 {
241 printf("CALORECGPU ETA PHI MAP DEBUG OUTPUT: %d | %d\n", i, entry.get_max_real_overlap());
242 };
243
244 cd.m_geometry->etaPhiToCell.apply_to_sampling(i, printer);
245 }
246#endif
247
248 auto after_eta_phi = clock_type::now();
249
250 std::vector<IdentifierHash> neighbour_vector, full_neighs, prev_neighs;
251
252 for (int cell = 0; cell < NCaloCells; ++cell)
253 {
254 for (int neigh_bit_set = 0; neigh_bit_set < NumNeighOptions; ++neigh_bit_set)
255 {
256 const unsigned int curr_neigh_opt = (1U << neigh_bit_set);
257
258 if (curr_neigh_opt == LArNeighbours::corners2D || curr_neigh_opt == LArNeighbours::corners3D)
259 //Scanning the ATLAS codebase, neighbour handling has special cases
260 //for all2D (LarFCAL_Base_ID.cxx, LArMiniFCAL_ID.cxx, Tile_Base_ID.cxx)
261 //and all3DwithCorners (Tile_Base_ID.cxx), which include
262 //neighbours not returned when just the constituent bits are set separately.
263 //As an imperfect workaround, we stuff them in the immediately previous option
264 //(corners, for both 2D and 3D).
265 {
266 if (curr_neigh_opt == LArNeighbours::corners2D)
267 {
268 calo_id->get_neighbours((IdentifierHash) cell,
270 full_neighs);
271 }
272 else /*if (curr_neigh_opt == LArNeighbours::corners3D)*/
273 {
274 calo_id->get_neighbours((IdentifierHash) cell,
276 prev_neighs);
277 calo_id->get_neighbours((IdentifierHash) cell,
279 neighbour_vector);
280 //We will exclude the cells that could come from later options
281 //(it seems, from Tile_Base_ID.cxx, all3DwithCorners will give more than super3D),
282 //which... might make some sense, but seems unexpected.
283
284
285 std::sort(neighbour_vector.begin(), neighbour_vector.end());
286 std::sort(prev_neighs.begin(), prev_neighs.end());
287
288 full_neighs.clear();
289
290 std::set_difference( prev_neighs.begin(), prev_neighs.end(),
291 neighbour_vector.begin(), neighbour_vector.end(),
292 std::back_inserter(full_neighs) );
293
294 }
295
296 prev_neighs.resize(cd.m_geometry->neighbours.get_total_number_of_neighbours(cell));
297 //We want to add just the neighbours that are not part of this.
298
299 for (size_t neigh = 0; neigh < prev_neighs.size(); ++neigh)
300 {
301 prev_neighs[neigh] = cd.m_geometry->neighbours.get_neighbour(cell, neigh);
302 }
303
304 std::sort(full_neighs.begin(), full_neighs.end());
305 std::sort(prev_neighs.begin(), prev_neighs.end());
306
307 neighbour_vector.clear();
308
309 std::set_difference( full_neighs.begin(), full_neighs.end(),
310 prev_neighs.begin(), prev_neighs.end(),
311 std::back_inserter(neighbour_vector) );
312 }
313 else
314 {
315 calo_id->get_neighbours((IdentifierHash) cell, (LArNeighbours::neighbourOption) curr_neigh_opt, neighbour_vector);
316 }
317
318 std::sort(neighbour_vector.begin(), neighbour_vector.end());
319
320 const int neighs_start = cd.m_geometry->neighbours.get_total_number_of_neighbours(cell);
321
322 for (size_t neigh_num = 0; neigh_num < neighbour_vector.size(); ++neigh_num)
323 {
324 cd.m_geometry->neighbours.set_neighbour(cell, neighs_start + neigh_num, neighbour_vector[neigh_num]);
325 }
326
327 cd.m_geometry->neighbours.offsets[cell] += NeighOffset::offset_delta(neigh_bit_set) * neighbour_vector.size();
328
329 }
330 }
331
332#if CALORECGPU_ADD_FULL_PAIRS_LIST_TO_CONSTANT_INFORMATION
333
334//Note: the commented out code is used to output the hard-coded numbers
335//in NeighPairsArr. For the time being, it should remain here until
336//a more definitive solution for the geometry is found.
337
338 {
339 int num_pairs = 0;
340
341 auto add_neighbours = [&](const int cell, const unsigned int curr_neigh_opt)
342 {
343 int neighbours[NMaxNeighbours];
344
345 const int num_neighs = cd.m_geometry->neighbours.get_neighbours(curr_neigh_opt, cell, neighbours);
346
347 for (int neigh = 0; neigh < num_neighs; ++neigh)
348 {
349 cd.m_geometry->neighPairs.cell_A[num_pairs] = cell;
350 cd.m_geometry->neighPairs.cell_B[num_pairs] = neighbours[neigh];
351 ++num_pairs;
352 }
353 };
354
355 for (int neigh_bit_set = 0; neigh_bit_set < NumNeighOptions; ++neigh_bit_set)
356 {
357 const unsigned int curr_neigh_opt = (1U << neigh_bit_set);
358
359 for (int cell = 0; cell < NCaloCells; ++cell)
360 {
361 if (cd.m_geometry->is_PS(cell) || cd.m_geometry->is_HECIW_or_FCal(cell))
362 {
363 continue;
364 }
365
366 add_neighbours(cell, curr_neigh_opt);
367 }
368
369 //const int PS_start = num_pairs;
370
371 for (int cell = 0; cell < NCaloCells; ++cell)
372 {
373 if (!cd.m_geometry->is_PS(cell))
374 {
375 continue;
376 }
377
378 add_neighbours(cell, curr_neigh_opt);
379 }
380
381 //const int HECIW_FCal_start = num_pairs;
382
383 for (int cell = 0; cell < NCaloCells; ++cell)
384 {
385 if (!cd.m_geometry->is_HECIW_or_FCal(cell))
386 {
387 continue;
388 }
389
390 add_neighbours(cell, curr_neigh_opt);
391 }
392
393 //std::cout << neigh_bit_set << " " << num_pairs << " " << PS_start << " " << HECIW_FCal_start << std::endl;
394 }
395 }
396#endif
397
398 auto after_pairs = clock_type::now();
399
400 /*
401 //Useful output for debugging and studying regularities in calorimeter geometry...
402
403 std::cout << "ID\tCaloSample\tSampling\tRegion\tSubCalo";
404 for (int j = 0; j < NumNeighOptions; ++j)
405 {
406 std::cout << "\tn_" << j;
407 }
408 std::cout << "\tn_total\tOffset" << std::endl;
409
410 for (int cell = 0; cell < NCaloCells; ++cell)
411 {
412
413 const CaloDetDescrElement * caloElement = calo_dd_man->get_element((IdentifierHash) cell);
414 std::cout << cell << "\t"
415 << (int) calo_id->calo_sample(calo_id->cell_id((IdentifierHash) cell)) << "\t"
416 << (int) calo_id->sampling(calo_id->cell_id((IdentifierHash) cell)) << "\t"
417 << (int) calo_id->region(calo_id->cell_id((IdentifierHash) cell)) << "\t"
418 << (int) caloElement->getSubCalo();
419
420 const NeighOffset n_off = cd.m_geometry->neighbours.offsets[cell];
421
422 for (int j = 0; j < NumNeighOptions; ++j)
423 {
424 std::cout << "\t" << n_off.get_num_cells(j);
425 }
426
427 std::cout << "\t" << n_off.get_total_number() << "\t" << n_off << std::endl;
428 }
429 // */
430
432 const CaloNoise * noise_tool = *noise_handle;
433
434 IdentifierHash t_start, t_end;
435 calo_id->calo_cell_hash_range(CaloCell_ID::TILE, t_start, t_end);
436
437 if (t_start != TileCellStart)
438 {
439 ATH_MSG_WARNING("Tile start (" << t_start << ") differs from assumed constant value (" << TileCellStart << ")!");
440 }
441 if (t_end != TileCellAfterEnd)
442 {
443 ATH_MSG_WARNING("Tile end (" << t_end << ") differs from assumed constant value (" << TileCellAfterEnd << ")!");
444 }
445
446 const CaloCondBlobFlt * blob = noise_tool->getTileBlob();
447
448 cd.m_cell_noise.allocate();
449
450 if (!blob)
451 {
452 cd.m_cell_noise->noise_properties = CellNoiseProperties::invalid_value();
453 }
454 else
455 {
456 cd.m_cell_noise->noise_properties = CellNoiseProperties(blob->getObjVersion(), noise_tool->getNoiseType());
457 }
458
459 cd.m_cell_noise->luminosity = noise_tool->getLumi();
460
461 for (int cell = 0; cell < int(t_start); ++cell)
462 {
463 for (int gain_state = 0; gain_state < CaloRecGPU::NumGainStates; ++gain_state)
464 {
465 cd.m_cell_noise->noise[cell][gain_state] = noise_tool->larStorage()[(gain_state > 2 ? 0 : gain_state)][cell];
466 }
467 }
468 for (int cell = t_start; cell < int(t_end); ++cell)
469 {
470 for (int gain_state = 0; gain_state < CaloRecGPU::NumGainStates; ++gain_state)
471 {
472 cd.m_cell_noise->noise[cell][gain_state] = noise_tool->tileStorage()[gain_state][cell - t_start];
473 cd.m_cell_noise->double_gaussian_constants[0][cell - t_start][gain_state] = blob->getData(cell - t_start, gain_state, 2);
474 cd.m_cell_noise->double_gaussian_constants[1][cell - t_start][gain_state] = blob->getData(cell - t_start, gain_state, 3);
475 cd.m_cell_noise->double_gaussian_constants[2][cell - t_start][gain_state] = blob->getData(cell - t_start, gain_state, 4);
476 cd.m_cell_noise->double_gaussian_constants[3][cell - t_start][gain_state] = blob->getData(cell - t_start, gain_state, 1);
477 }
478 }
479 for (int cell = t_end; cell < NCaloCells; ++cell)
480 {
481 for (int gain_state = 0; gain_state < CaloRecGPU::NumGainStates; ++gain_state)
482 {
483 cd.m_cell_noise->noise[cell][gain_state] = 0;
484 }
485 }
486
487 auto after_noise = clock_type::now();
488
489 cd.sendToGPU(!(m_keepCPUData || keep_CPU_info));
490
491
492 auto after_send = clock_type::now();
493
494 if (m_measureTimes)
495 {
496 record_times(ctx.evt(),
497 time_cast(start, after_geo),
498 time_cast(after_geo, after_eta_phi),
499 time_cast(after_eta_phi, after_pairs),
500 time_cast(after_pairs, after_noise),
501 time_cast(after_noise, after_send)
502 );
503 }
504
505 return StatusCode::SUCCESS;
506
507}
508
510{
511
512 if (m_measureTimes)
513 {
514 print_times("Basic_Geometry Eta_Phi_Map_Finalize Pairs Noise Transfer_to_GPU", 5);
515 }
516 return StatusCode::SUCCESS;
517}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
Helpers for checking error return status codes and reporting errors.
defines an "iterator" over instances of a given type in StoreGateSvc
Define macros for attributes used to control the static checker.
virtual StatusCode initialize() override
virtual StatusCode convert(CaloRecGPU::ConstantDataHolder &constant_data, const bool override_keep_CPU_info) const override
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
Key for the CaloDetDescrManager in the Condition Store.
BasicConstantGPUDataExporter(const std::string &type, const std::string &name, const IInterface *parent)
Gaudi::Property< bool > m_keepCPUData
If true, do not delete the CPU version of the GPU-friendly data representation.
SG::ReadCondHandleKey< CaloNoise > m_noiseCDOKey
Key of the CaloNoise Conditions data object.
int sampling(const Identifier id) const
LAr field values (NOT_VALID == invalid request)
int get_neighbours(const IdentifierHash caloHash, const LArNeighbours::neighbourOption &option, std::vector< IdentifierHash > &neighbourList) const
access to hashes for neighbours return == 0 for neighbours found
void calo_cell_hash_range(const Identifier id, IdentifierHash &caloCellMin, IdentifierHash &caloCellMax) const
to loop on 'global' cell hashes of one sub-calorimeter alone
int region(const Identifier id) const
LAr field values (NOT_VALID == invalid request)
int calo_sample(const Identifier id) const
returns an int taken from Sampling enum and describing the subCalo to which the Id belongs.
Identifier cell_id(const int subCalo, const int barec_or_posneg, const int sampling_or_fcalmodule, const int region_or_dummy, const int eta, const int phi) const
Make a cell (== channel) ID from constituting fields and subCalo index; for (Mini)FCAL,...
Helper class for offline cell identifiers.
Definition CaloCell_ID.h:34
Class for storing a number of floats (Flt) and functions on those.
This class groups all DetDescr information related to a CaloCell.
const CaloDetDescrElement * get_element(const Identifier &cellId) const
get element by its identifier
This class provides the client interface for accessing the detector description information common to...
const CaloCell_ID * getCaloCell_ID() const
get calo cell ID helper
Gaudi::Property< bool > m_measureTimes
If true, times are recorded to the file given by m_timeFileName.
CaloGPUTimed(T *ptr)
void print_times(const std::string &header, const size_t time_size) const
void record_times(const size_t event_num, const std::vector< size_t > &times) const
const CaloCondBlobFlt * getTileBlob() const
Definition CaloNoise.h:83
boost::multi_array< float, 2 > & larStorage()
Non-const accessor to underlying storage for filling:
Definition CaloNoise.h:71
NOISETYPE getNoiseType() const
Definition CaloNoise.h:87
float getLumi() const
Definition CaloNoise.h:85
boost::multi_array< float, 2 > & tileStorage()
Definition CaloNoise.h:72
Holds CPU and GPU versions of the geometry and cell noise information, which are assumed to be consta...
Definition DataHolders.h:27
static constexpr int from_region_enum(const int region)
static constexpr int from_subcalo_enum(const int subcalo)
static constexpr int from_intra_calorimeter_sampling_enum(const int sampling)
This is a "hash" representation of an Identifier.
Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration.
constexpr int NumSamplings
constexpr int NMaxNeighbours
constexpr int TileCellAfterEnd
constexpr int NumNeighOptions
constexpr int NCaloCells
constexpr int TileCellStart
constexpr int NumGainStates
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
static constexpr carrier invalid_value()
static constexpr carrier offset_delta(const int i)
Returns, for each i, what must be added to the offset to increase the stores numbers appropriately wh...
Definition NeighArr.h:144
Packs the calo sampling, the intra-calorimeter sampling, the subcalo, the region and whether the cell...