ATLAS Offline Software
Loading...
Searching...
No Matches
ConstantInfoDefinitions.h
Go to the documentation of this file.
1//
2// Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3//
4// Dear emacs, this is -*- c++ -*-
5//
6
7#ifndef CALORECGPU_CONSTANTINFODEFINITIONS_H
8#define CALORECGPU_CONSTANTINFODEFINITIONS_H
9
10#include "BaseDefinitions.h"
11#include "Helpers.h"
12
13#include "EtaPhiMap.h"
14#include "NeighArr.h"
15
16#include <cmath>
17
18namespace CaloRecGPU
19{
20
22 {
23 protected:
24
25 constexpr static int s_subcalo_unknown = 999999;
26 constexpr static int s_subcalo_unknown_replacement = 7;
27
28 public:
29
30 constexpr static int from_subcalo_enum(const int subcalo)
31 {
32 if (subcalo == s_subcalo_unknown)
33 {
35 }
36 else
37 {
38 return subcalo;
39 }
40 }
41
42 constexpr static int to_subcalo_enum(const int subcalo)
43 {
44 if (subcalo == s_subcalo_unknown_replacement)
45 {
46 return s_subcalo_unknown;
47 }
48 else
49 {
50 return subcalo;
51 }
52 }
53
54 protected:
55
56 constexpr static int s_region_unknown = 999999;
57 constexpr static int s_region_unknown_replacement = 7;
58
59 public:
60
61 constexpr static int from_region_enum(const int region)
62 {
63 if (region == s_region_unknown)
64 {
66 }
67 else
68 {
69 return region;
70 }
71 }
72
73 constexpr static int to_region_enum(const int region)
74 {
75 if (region == s_region_unknown_replacement)
76 {
77 return s_region_unknown;
78 }
79 else
80 {
81 return region;
82 }
83 }
84
85 protected:
86
87 constexpr static int s_sampling_unknown = 999999;
88 constexpr static int s_sampling_unknown_replacement = 7;
89
90 public:
91
92 constexpr static int from_intra_calorimeter_sampling_enum(const int sampling)
93 {
94 if (sampling == s_sampling_unknown)
95 {
97 }
98 else
99 {
100 return sampling;
101 }
102 }
103
104 constexpr static int to_intra_calorimeter_sampling_enum(const int sampling)
105 {
106 if (sampling == s_sampling_unknown_replacement)
107 {
108 return s_sampling_unknown;
109 }
110 else
111 {
112 return sampling;
113 }
114 }
115
116 };
117
118
127 {
128 using carrier = unsigned int;
129
131
132private:
133
134 static constexpr carrier s_sampling_mask = 0x0000001FU;
135 static constexpr carrier s_intra_sampling_mask = 0x000000E0U;
136 static constexpr carrier s_subcalo_mask = 0x00000700U;
137 static constexpr carrier s_region_mask = 0x00003800U;
138
139 static constexpr carrier s_is_PS_flag = 0x00004000U;
140 static constexpr carrier s_is_HECIW_FCal_flag = 0x00008000U;
141
142 static constexpr carrier s_sampling_offset = 0;
143 static constexpr carrier s_intra_sampling_offset = 5;
144 static constexpr carrier s_subcalo_offset = 8;
145 static constexpr carrier s_region_offset = 11;
146
153
155
156public:
157
158 constexpr operator carrier () const
159 {
160 return value;
161 }
162
163 constexpr OtherCellInfo (const carrier v): value(v)
164 {
165 }
166
167 constexpr OtherCellInfo & operator = (const carrier v)
168 {
169 value = v;
170 return (*this);
171 }
172
173 constexpr carrier sampling() const
174 {
176 }
177
182
183 constexpr carrier subcalo() const
184 {
186 }
187
188 constexpr carrier region() const
189 {
190 return (value & s_region_mask) >> s_region_offset;
191 }
192
193 constexpr bool is_HECIW_or_FCal() const
194 {
196 }
197
198 constexpr bool is_PS() const
199 {
200 return value & s_is_PS_flag;
201 }
202
204 const carrier intra_calo_sampling,
205 const carrier subcalo,
206 const carrier region,
207 const bool PS,
208 const bool HECIW_or_FCal):
209 value(0)
210 {
212 ( intra_calo_sampling << s_intra_sampling_offset ) |
214 ( region << s_region_offset ) |
215 ( s_is_PS_flag * PS ) |
216 ( s_is_HECIW_FCal_flag * HECIW_or_FCal );
217 }
218 };
219
221 {
222 float x[NCaloCells];
223 float y[NCaloCells];
224 float z[NCaloCells];
225 float r[NCaloCells];
228
235
237
239
241
242#if CALORECGPU_ADD_FULL_PAIRS_LIST_TO_CONSTANT_INFORMATION
243 NeighPairsArr neighPairs;
244#endif
245
247
249
250 constexpr static bool is_tile (const int cell)
251 {
252 return cell >= TileCellStart && cell < TileCellAfterEnd;
253 }
254
255 constexpr bool is_HECIW_or_FCal(const int cell) const
256 {
257 const OtherCellInfo cell_info = otherCellInfo[cell];
258 return cell_info.is_HECIW_or_FCal();
259 }
260
261 constexpr bool is_PS(const int cell) const
262 {
263 const OtherCellInfo cell_info = otherCellInfo[cell];
264 return cell_info.is_PS();
265 }
266
267 constexpr int sampling(const int cell) const
268 {
269 const OtherCellInfo cell_info = otherCellInfo[cell];
270 return cell_info.sampling();
271 }
272
273 constexpr int intra_calorimeter_sampling(const int cell) const
274 {
275 const OtherCellInfo cell_info = otherCellInfo[cell];
276 return cell_info.intra_calorimeter_sampling();
277 }
278
279 constexpr int subcalo(const int cell) const
280 {
281 const OtherCellInfo cell_info = otherCellInfo[cell];
282 return cell_info.subcalo();
283 }
284
285 constexpr int region(const int cell) const
286 {
287 const OtherCellInfo cell_info = otherCellInfo[cell];
288 return cell_info.region();
289 }
290
296 constexpr int get_neighbours(const unsigned int neigh_options, const int cell, int * neigh_arr) const
297 {
298 return neighbours.get_neighbours(neigh_options, cell, neigh_arr);
299 }
300
301 constexpr int get_number_of_neighbours(const unsigned int neigh_options, const int cell) const
302 {
303 return neighbours.get_number_of_neighbours(neigh_options, cell);
304 }
305
307 {
308 for (int i = 0; i < NCaloCells; ++i)
309 {
310 etaPhiToCell.register_cell(i, sampling(i), eta[i], phi[i], deta[i], dphi[i]);
311 }
312
313 struct DeAllocWrapper
314 {
315 int * buf;
316 CUDA_HOS_DEV DeAllocWrapper(const size_t new_size)
317 {
318 buf = new int[Helpers::int_ceil_div(new_size, sizeof(int))];
319 }
320 CUDA_HOS_DEV ~DeAllocWrapper()
321 {
322 delete[] buf;
323 }
324 CUDA_HOS_DEV DeAllocWrapper (const DeAllocWrapper &) = delete;
325 CUDA_HOS_DEV DeAllocWrapper (DeAllocWrapper &&) = delete;
326 CUDA_HOS_DEV DeAllocWrapper & operator=(const DeAllocWrapper &) = delete;
327 CUDA_HOS_DEV DeAllocWrapper & operator=(DeAllocWrapper &&) = delete;
328 };
329 //Simple allocation/de-allocation
330 //to still be GPU-compatible if needed
331 //(new and delete valid on GPU code...),
332 //while still preventing leaks,
333 //all without pulling in unique_ptr.
334
335 DeAllocWrapper wrapper(etaPhiToCell.finish_initializing_buffer_size());
336
337#if CALORECGPU_ETA_PHI_MAP_DEBUG
338 printf("CALORECGPU ETA PHI MAP DEBUG OUTPUT: Max occupied cells is %d\n", etaPhiToCell.get_max_real_overlap());
339#endif
340 etaPhiToCell.finish_initializing(wrapper.buf);
341
342 }
343
344 constexpr int get_closest_cell(const int sampling, const float test_eta, const float test_phi) const
345 {
347
348 const int n_cells = etaPhiToCell.get_possible_cells_from_coords(sampling, test_eta, test_phi, cells);
349
350 if (n_cells < 1)
351 {
352 return -1;
353 }
354 else if (n_cells == 1)
355 {
356 return cells[0];
357 }
358 else
359 {
360 float distance = 1e38f;
361 int ret = -1;
362
363 for (int i = 0; i < n_cells; ++i)
364 {
365 const int this_cell = cells[i];
366
367 const float delta_eta = eta[this_cell] - test_eta;
368 const float delta_phi = Helpers::angular_difference(phi[this_cell], test_phi);
369
370 using namespace std;
371
372 const float this_dist = fabsf(delta_eta) + fabsf(delta_phi);
373 if (this_dist < distance || (this_dist == distance && this_cell > ret))
374 {
375 distance = this_dist;
376 ret = this_cell;
377 }
378 }
379 return ret;
380 }
381 }
382 };
383
385 {
386 using carrier = unsigned int;
388
389 protected:
390
391 static constexpr carrier s_first_16_bit_mask = 0x0000FFFFU;
392 static constexpr carrier s_last_16_bit_mask = 0xFFFF0000U;
394
395 public:
396
397
398 constexpr operator carrier () const
399 {
400 return value;
401 }
402
403 constexpr CellNoiseProperties (const carrier v): value(v)
404 {
405 }
406
408 {
409 value = v;
410 return (*this);
411 }
412
413 constexpr carrier version() const
414 {
415 return value & s_first_16_bit_mask;
416 }
417
418 constexpr carrier noise_type() const
419 {
420 return (value & s_last_16_bit_mask) >> 16;
421 }
422
423 constexpr bool is_electronic_noise() const
424 {
425 return is_valid() && ((value & s_last_16_bit_mask) == 0x00000000U);
426 }
427
428 constexpr bool is_pile_up_noise() const
429 {
430 return is_valid() && ((value & s_last_16_bit_mask) == 0x00010000U);
431 }
432
433 constexpr bool is_total_noise() const
434 {
435 return is_valid() && ((value & s_last_16_bit_mask) == 0x00020000U);
436 }
437
440 {
441 value = (value << 16) | (version & s_first_16_bit_mask);
442 }
443
444 constexpr bool is_invalid() const
445 {
447 }
448
449 constexpr bool is_valid() const
450 {
451 return !is_invalid();
452 }
453
454 static constexpr carrier invalid_value()
455 {
457 }
458
459 };
460
462 {
463 static constexpr int s_numDoubleGaussianConstants = 4;
464
466 //Given the low number of possible gain sates
467
469
471
473
474 constexpr float get_noise(const int cell, const int gain) const
475 {
476 return noise[cell][gain];
477 }
478
479 protected:
480
481 CUDA_HOS_DEV float get_double_gaussian_significance(const int cell, const int gain, const float energy) const
482 {
483
484 using namespace std;
485
486 const int delta_from_tile_start = cell - TileCellStart;
487
488 const float sigma_1 = this->double_gaussian_constants[0][delta_from_tile_start][gain];
489 const float sigma_2 = this->double_gaussian_constants[1][delta_from_tile_start][gain];
490 const float ratio = this->double_gaussian_constants[2][delta_from_tile_start][gain];
491
492 if ((sigma_1 == 0.f && sigma_2 == 0.f) || energy == 0.f)
493 {
494 return 0.f;
495 }
496 else if (sigma_1 == 0.f)
497 {
498 return energy / sigma_2;
499 }
500 else if (ratio == 0.f || sigma_2 == 0.f)
501 {
502 return energy / sigma_1;
503 }
504
505 const float x_1 = energy / sigma_1;
506 const float x_2 = energy / sigma_2;
507 const float x_1_abs = fabsf(x_1);
508 const float x_2_abs = fabsf(x_2);
509
510 const float min_abs = min(x_1_abs, x_2_abs);
511
512 const float max_abs = max(x_1_abs, x_2_abs);
513
514 if (min_abs > 7.4f)
515 {
516 return min_abs;
517 }
518 if (max_abs < 0.9f)
519 {
520 return max_abs;
521 }
522
523 const float y_1 = erff(Helpers::Constants::inv_sqrt2<float> * x_1);
524 const float y_2 = erff(Helpers::Constants::inv_sqrt2<float> * x_2);
525
526
527 const float z = (y_1 * sigma_1 + ratio * y_2 * sigma_2) / (sigma_1 + ratio * sigma_2);
528
530
531 //printf("GPU %d %f %f %f %f %f %f\n", delta_from_tile_start, min_abs, max_abs, y_1, y_2, z, ret);
532
533 return ret;
534
535 }
536
537 public:
538
541 CUDA_HOS_DEV float get_double_gaussian_noise(const int cell, const int gain, const float energy) const
542 {
543 using namespace std;
544
545 CellNoiseProperties props(this->noise_properties);
546 if (!props.is_valid())
547 {
548 return get_noise(cell, gain);
549 }
550
551 const float sigma = get_double_gaussian_significance(cell, gain, energy);
552
553 const float first_factor = (sigma != 0.f ? fabsf(energy / sigma) : 0.f);
554
555 if (props.is_electronic_noise())
556 {
557 return first_factor;
558 }
559 else
560 {
561 const float second_factor = this->double_gaussian_constants[3][cell - TileCellStart][gain];
562
563 switch (props.version())
564 {
565 case 1:
566 return sqrtf(first_factor * first_factor + second_factor * second_factor * this->luminosity);
567 case 2:
568 return first_factor + second_factor * this->luminosity;
569 default:
570 return 0.f / 0.f;
571 }
572 }
573 }
574
575 };
576
577}
578
579#endif
#define z
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
static constexpr int to_subcalo_enum(const int subcalo)
static constexpr int from_region_enum(const int region)
static constexpr int to_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)
static constexpr int to_intra_calorimeter_sampling_enum(const int sampling)
constexpr auto int_ceil_div(const T1 num, const T2 denom)
Returns the ceiling of num/denom, with proper rounding.
static CUDA_HOS_DEV float erf_inv_wrapper(const float x)
static CUDA_HOS_DEV T angular_difference(const T x, const T y)
Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration.
constexpr int NumSamplings
constexpr int TileCellAfterEnd
constexpr int NTileCells
constexpr int NCaloCells
constexpr int TileCellStart
constexpr int NumGainStates
STL namespace.
float double_gaussian_constants[s_numDoubleGaussianConstants][NTileCells][NumGainStates]
CUDA_HOS_DEV float get_double_gaussian_noise(const int cell, const int gain, const float energy) const
Calculates the double gaussian noise for a Tile cell.
constexpr float get_noise(const int cell, const int gain) const
float noise[NCaloCells][NumGainStates]
CUDA_HOS_DEV float get_double_gaussian_significance(const int cell, const int gain, const float energy) const
CellNoiseProperties::carrier noise_properties
static constexpr int s_numDoubleGaussianConstants
static constexpr carrier s_invalid_double_gaussian
constexpr CellNoiseProperties(const carrier version, const carrier noise_type)
static constexpr carrier invalid_value()
static constexpr carrier s_first_16_bit_mask
constexpr CellNoiseProperties(const carrier v)
constexpr CellNoiseProperties & operator=(const carrier v)
static constexpr carrier s_last_16_bit_mask
static constexpr int s_max_overlap_cells
Definition EtaPhiMap.h:1086
CUDA_HOS_DEV void fill_eta_phi_map()
OtherCellInfo::carrier otherCellInfo[NCaloCells]
constexpr int get_closest_cell(const int sampling, const float test_eta, const float test_phi) const
static constexpr bool is_tile(const int cell)
constexpr bool is_HECIW_or_FCal(const int cell) const
constexpr int intra_calorimeter_sampling(const int cell) const
constexpr int region(const int cell) const
constexpr int sampling(const int cell) const
constexpr int get_neighbours(const unsigned int neigh_options, const int cell, int *neigh_arr) const
Places the neighbours according to the option(s) in neigh_options in the array and returns the number...
constexpr int subcalo(const int cell) const
constexpr bool is_PS(const int cell) const
constexpr int get_number_of_neighbours(const unsigned int neigh_options, const int cell) const
Packs the calo sampling, the intra-calorimeter sampling, the subcalo, the region and whether the cell...
static constexpr carrier s_region_offset
static constexpr carrier s_sampling_mask
static constexpr carrier s_bits_unused
static constexpr carrier s_intra_sampling_mask
constexpr carrier region() const
static constexpr carrier s_subcalo_mask
static constexpr carrier s_sampling_offset
constexpr OtherCellInfo(const carrier sampling, const carrier intra_calo_sampling, const carrier subcalo, const carrier region, const bool PS, const bool HECIW_or_FCal)
static constexpr carrier s_is_HECIW_FCal_flag
constexpr carrier subcalo() const
constexpr carrier intra_calorimeter_sampling() const
constexpr OtherCellInfo(const carrier v)
constexpr carrier sampling() const
constexpr bool is_HECIW_or_FCal() const
static constexpr carrier s_subcalo_offset
static constexpr carrier s_intra_sampling_offset
static constexpr carrier s_is_PS_flag
static constexpr carrier s_region_mask
static constexpr carrier s_bits_used
constexpr OtherCellInfo & operator=(const carrier v)