ATLAS Offline Software
GPUToAthenaImporterWithMoments.cxx
Go to the documentation of this file.
1 //
2 // Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 //
4 // Dear emacs, this is -*- c++ -*-
5 //
6 
8 
10 
12 
13 #include <vector>
14 #include <algorithm>
15 #include <memory>
16 
19 
20 #include "boost/chrono/chrono.hpp"
21 #include "boost/chrono/thread_clock.hpp"
22 
23 using namespace CaloRecGPU;
24 
25 GPUToAthenaImporterWithMoments::GPUToAthenaImporterWithMoments(const std::string & type, const std::string & name, const IInterface * parent):
27  CaloGPUTimed(this),
28  m_doHVMoments(false)
29 {
30  declareInterface<ICaloClusterGPUOutputTransformer> (this);
31 
32 }
33 
34 #include "MacroHelpers.h"
35 
37 {
39 
40  ATH_CHECK( detStore()->retrieve(m_calo_id, "CaloCell_ID") );
41 
43 
46 
47  auto get_cluster_size_from_string = [](const std::string & str, bool & failed)
48  {
49  failed = false;
52  SW_55ele,
53  SW_35ele,
54  SW_37ele,
55  SW_55gam,
56  SW_35gam,
57  SW_37gam,
58  SW_55Econv,
59  SW_35Econv,
60  SW_37Econv,
61  SW_softe,
62  Topo_420,
63  Topo_633,
64  SW_7_11,
65  SuperCluster,
66  Tower_01_01,
67  Tower_005_005,
68  Tower_fixed_area
69  )
70  )
71  //I know Topological Clustering only supports a subset of those,
72  //but this is supposed to be a general data exporting tool...
73  else
74  {
75  //failed = true;
77  }
78  };
79 
80  bool size_failed = false;
81  m_clusterSize = get_cluster_size_from_string(m_clusterSizeString, size_failed);
82 
84  {
85  ATH_MSG_ERROR("Invalid Cluster Size: " << m_clusterSizeString);
86  }
87 
88  if (size_failed)
89  {
90  return StatusCode::FAILURE;
91  }
92 
93 
94  auto get_moment_from_string = [](const std::string & str, bool & failed)
95  {
96  failed = false;
99  FIRST_PHI,
100  FIRST_ETA,
101  SECOND_R,
103  DELTA_PHI,
104  DELTA_THETA,
105  DELTA_ALPHA,
106  CENTER_X,
107  CENTER_Y,
108  CENTER_Z,
109  CENTER_MAG,
111  LATERAL,
112  LONGITUDINAL,
113  ENG_FRAC_EM,
114  ENG_FRAC_MAX,
115  ENG_FRAC_CORE,
117  SECOND_ENG_DENS,
118  ISOLATION,
119  ENG_BAD_CELLS,
120  N_BAD_CELLS,
121  N_BAD_CELLS_CORR,
122  BAD_CELLS_CORR_E,
123  BADLARQ_FRAC,
124  ENG_POS,
125  SIGNIFICANCE,
126  CELL_SIGNIFICANCE,
127  CELL_SIG_SAMPLING,
128  AVG_LAR_Q,
129  AVG_TILE_Q,
130  ENG_BAD_HV_CELLS,
131  N_BAD_HV_CELLS,
132  PTD,
133  MASS,
135  HAD_WEIGHT,
136  OOC_WEIGHT,
137  DM_WEIGHT,
138  TILE_CONFIDENCE_LEVEL,
139  SECOND_TIME,
140  NCELL_SAMPLING,
141  VERTEX_FRACTION,
142  NVERTEX_FRACTION,
143  ETACALOFRAME,
144  PHICALOFRAME,
145  ETA1CALOFRAME,
146  PHI1CALOFRAME,
147  ETA2CALOFRAME,
148  PHI2CALOFRAME,
149  ENG_CALIB_TOT,
150  ENG_CALIB_OUT_L,
151  ENG_CALIB_OUT_M,
152  ENG_CALIB_OUT_T,
153  ENG_CALIB_DEAD_L,
154  ENG_CALIB_DEAD_M,
155  ENG_CALIB_DEAD_T,
156  ENG_CALIB_EMB0,
157  ENG_CALIB_EME0,
158  ENG_CALIB_TILEG3,
159  ENG_CALIB_DEAD_TOT,
160  ENG_CALIB_DEAD_EMB0,
161  ENG_CALIB_DEAD_TILE0,
162  ENG_CALIB_DEAD_TILEG3,
163  ENG_CALIB_DEAD_EME0,
164  ENG_CALIB_DEAD_HEC0,
165  ENG_CALIB_DEAD_FCAL,
166  ENG_CALIB_DEAD_LEAKAGE,
167  ENG_CALIB_DEAD_UNCLASS,
168  ENG_CALIB_FRAC_EM,
169  ENG_CALIB_FRAC_HAD,
170  ENG_CALIB_FRAC_REST)
171  )
172  else
173  {
174  failed = true;
176  }
177  };
178 
179 
180  auto process_moments = [&](const std::vector<std::string> & moment_names, std::string & invalid_names)
181  {
182  for (const std::string & mom_name : moment_names)
183  {
184  bool failed = false;
185  const int linear_num = MomentsOptionsArray::moment_to_linear(get_moment_from_string(mom_name, failed));
186 
187  failed = failed || linear_num >= MomentsOptionsArray::num_moments;
188 
189  if (failed)
190  {
191  if (invalid_names.size() == 0)
192  {
193  invalid_names = "'" + mom_name + "'";
194  }
195  else
196  {
197  invalid_names += ", '" + mom_name + "'";
198  }
199  }
200  else
201  {
202  m_momentsToDo.array[linear_num] = true;
203  }
204  }
205  };
206 
207  std::string invalid_names;
208 
209  process_moments(m_momentsNames, invalid_names);
210 
211  if (invalid_names.size() > 0)
212  {
213  ATH_MSG_ERROR( "Moments " << invalid_names
214  << " are not valid moments and will be ignored!" );
215  }
216 
218  return StatusCode::SUCCESS;
219 }
220 
221 
223  const ConstantDataHolder & cdh,
224  EventDataHolder & ed,
225  xAOD::CaloClusterContainer * cluster_container) const
226 {
227  using clock_type = boost::chrono::thread_clock;
228  auto time_cast = [](const auto & before, const auto & after)
229  {
230  return boost::chrono::duration_cast<boost::chrono::microseconds>(after - before).count();
231  };
232 
233 
234  const auto start = clock_type::now();
235 
236  SG::ReadHandle<CaloCellContainer> cell_collection(m_cellsKey, ctx);
237  if ( !cell_collection.isValid() )
238  {
239  ATH_MSG_ERROR( " Cannot retrieve CaloCellContainer: " << cell_collection.name() );
240  return StatusCode::FAILURE;
241  }
242  const DataLink<CaloCellContainer> cell_collection_link (cell_collection.name(), ctx);
243 
244  //ed.returnToCPU(!m_keepGPUData, true, true, true);
245 
246  const auto pre_processing = clock_type::now();
247 
250 
251 
252  const auto cluster_number = clock_type::now();
253 
254  ed.returnSomeClustersToCPU(ed.m_clusters->number);
255 
256  std::vector<std::unique_ptr<CaloClusterCellLink>> cell_links;
257 
258  cell_links.reserve(ed.m_clusters->number);
259 
261 
262  const auto clusters = clock_type::now();
263 
264  ed.returnCellsToCPU();
265 
266  for (int i = 0; i < ed.m_clusters->number; ++i)
267  {
268  if (ed.m_clusters->seedCellID[i] >= 0)
269  {
270  cell_links.emplace_back(std::make_unique<CaloClusterCellLink>(cell_collection_link));
271  cell_links.back()->reserve(256);
272  //To be adjusted.
273  }
274  else
275  {
276  cell_links.emplace_back(nullptr);
277  //The excluded clusters don't have any cells.
278  }
279  }
280 
281  std::vector<float> HV_energy(ed.m_clusters->number * m_doHVMoments, 0.f);
282  std::vector<int> HV_number(ed.m_clusters->number * m_doHVMoments, 0 );
283 
284  const LArOnOffIdMapping * cabling = nullptr;
285  const ILArHVScaleCorr * hvcorr = nullptr;
286 
287  if (m_fillHVMoments)
288  {
291  cabling = *cablingHdl;
292  hvcorr = *hvScaleHdl;
293  }
294 
296 
297  const auto cells = clock_type::now();
298 
299  ed.returnSomeMomentsToCPU(ed.m_clusters->number);
300 
301  //cell_index is the actual cell index in the full set of cells (identifier hash)
302  //cell_count is the cell position in the cell collection (what we want for the weight)
303  const auto process_cell = [&](const int cell_index, const int cell_count)
304  {
305  const ClusterTag this_tag = ed.m_cell_state->clusterTag[cell_index];
306  if (this_tag.is_part_of_cluster())
307  {
308  const int this_index = this_tag.cluster_index();
309  const int32_t weight_pattern = this_tag.secondary_cluster_weight();
310 
311  float tempf = 1.0f;
312 
313  std::memcpy(&tempf, &weight_pattern, sizeof(float));
314  //C++20 would give us bit cast to do this more properly.
315  //Still, given how the bit pattern is created,
316  //it should be safe.
317 
318  const float reverse_weight = tempf;
319 
320  const float this_weight = 1.0f - reverse_weight;
321 
322  if (cell_links[this_index])
323  {
324  cell_links[this_index]->addCell(cell_count, this_weight);
325 
326  if (cell_index == ed.m_clusters->seedCellID[this_index] && cell_links[this_index]->size() > 1)
327  //Seed cells aren't shared,
328  //so no need to check this on the other case.
329  {
330  CaloClusterCellLink::iterator begin_it = cell_links[this_index]->begin();
331  CaloClusterCellLink::iterator back_it = std::prev(cell_links[this_index]->end());
332 
333  const unsigned int first_idx = begin_it.index();
334  const double first_wgt = begin_it.weight();
335 
336  begin_it.reindex(back_it.index());
337  begin_it.reweight(back_it.weight());
338 
339  back_it.reindex(first_idx);
340  back_it.reweight(first_wgt);
341 
342  //Of course, this is to ensure the first cell is the seed cell,
343  //in accordance to the way some cluster properties
344  //(mostly phi-related) are calculated.
345  }
346  }
347 
348  if (this_tag.is_shared_between_clusters())
349  {
350  const int other_index = this_tag.secondary_cluster_index();
351  if (cell_links[other_index])
352  {
353  cell_links[other_index]->addCell(cell_count, reverse_weight);
354  }
355  }
356 
357  if (m_doHVMoments && !cdh.m_geometry->is_tile(cell_index))
358  {
359  HWIdentifier hwid = cabling->createSignalChannelIDFromHash((IdentifierHash) cell_index);
360  const float corr = hvcorr->HVScaleCorr(hwid);
361  if (corr > 0.f && corr < 100.f && fabsf(corr - 1.f) > m_HVthreshold)
362  {
363  const float abs_energy = fabsf(ed.m_cell_info->energy[cell_index]);
364  HV_energy[this_index] += abs_energy;
365  ++HV_number[this_index];
366  if (this_tag.is_shared_between_clusters())
367  {
368  const int other_index = this_tag.secondary_cluster_index();
369  HV_energy[other_index] += abs_energy;
370  ++HV_number[other_index];
371  }
372  }
373  }
374  }
375  };
376 
377  if (cell_collection->isOrderedAndComplete())
378  //Fast path: cell indices within the collection and identifierHashes match!
379  {
380  for (int cell_index = 0; cell_index < NCaloCells; ++cell_index)
381  {
382  process_cell(cell_index, cell_index);
383  }
384  }
385  else if (cell_collection->isOrdered() && m_missingCellsToFill.size() > 0)
386  {
387  size_t missing_cell_count = 0;
388  for (int cell_index = 0; cell_index < NCaloCells; ++cell_index)
389  {
390  if (missing_cell_count < m_missingCellsToFill.size() && cell_index == m_missingCellsToFill[missing_cell_count])
391  {
392  ++missing_cell_count;
393  continue;
394  }
395  process_cell(cell_index, cell_index - missing_cell_count);
396  }
397  }
398  else
399  //Slow path: be careful.
400  {
401  CaloCellContainer::const_iterator iCells = cell_collection->begin();
402 
403  for (int cell_count = 0; iCells != cell_collection->end(); ++iCells, ++cell_count)
404  {
405  const CaloCell * cell = (*iCells);
406 
407  //const int cell_index = m_calo_id->calo_cell_hash(cell->ID());
408  const int cell_index = cell->caloDDE()->calo_hash();
409 
410  process_cell(cell_index, cell_count);
411  }
412  }
413 
414  const auto end_cell_cycle = clock_type::now();
415 
416  std::vector<int> cluster_order(ed.m_clusters->number);
417 
418  std::iota(cluster_order.begin(), cluster_order.end(), 0);
419 
420  std::sort(cluster_order.begin(), cluster_order.end(), [&](const int a, const int b) -> bool
421  {
422  const bool a_valid = ed.m_clusters->seedCellID[a] >= 0;
423  const bool b_valid = ed.m_clusters->seedCellID[b] >= 0;
424  if (a_valid && b_valid)
425  {
426  return ed.m_clusters->clusterEt[a]
427  > ed.m_clusters->clusterEt[b];
428  }
429  else if (a_valid)
430  {
431  return true;
432  }
433  else if (b_valid)
434  {
435  return false;
436  }
437  else
438  {
439  return b > a;
440  }
441  } );
442 
443  //Ordered by Et as in the default algorithm...
444  //The fact that some invalid clusters
445  //(with possibly trash values for Et)
446  //can crop up is irrelevant since
447  //we don't add those anyway:
448  //the rest is still ordered like we want it to be.
449 
450  const auto ordered = clock_type::now();
451 
452  cluster_container->clear();
453  cluster_container->reserve(cell_links.size());
454 
455  std::vector<int> real_cluster_order;
456  real_cluster_order.reserve(cluster_order.size());
457 
458  for (size_t i = 0; i < cluster_order.size(); ++i)
459  {
460  const int cluster_index = cluster_order[i];
461 
462  if (cell_links[cluster_index] != nullptr && cell_links[cluster_index]->size() > 0)
463  {
464  xAOD::CaloCluster * cluster = new xAOD::CaloCluster();
465  cluster_container->push_back(cluster);
466 
467  cluster->addCellLink(cell_links[cluster_index].release());
468  cluster->setClusterSize(m_clusterSize);
469 
470  cluster->setEta(ed.m_clusters->clusterEta[cluster_index]);
471  cluster->setPhi(ed.m_clusters->clusterPhi[cluster_index]);
472 
473  cluster->setE(ed.m_clusters->clusterEnergy[cluster_index]);
474  cluster->setM(0.0);
475 
476 
477  if (m_saveUncalibrated)
478  {
479  cluster->setRawE(cluster->calE());
480  cluster->setRawEta(cluster->calEta());
481  cluster->setRawPhi(cluster->calPhi());
482  cluster->setRawM(cluster->calM());
483  }
484 
485  real_cluster_order.push_back(cluster_index);
486  }
487 
488  }
489 
490  const auto pre_moments = clock_type::now();
491 
493 
494 
495  const auto post_moments = clock_type::now();
496 
497  for (size_t i = 0; i < cluster_container->size(); ++i)
498  {
499  xAOD::CaloCluster * cluster = (*cluster_container)[i];
500  const int cluster_index = real_cluster_order[i];
501 
502  cluster->setTime(ed.m_moments->time[cluster_index]);
503  cluster->setSecondTime(ed.m_moments->secondTime[cluster_index]);
504  cluster->clearSamplingData();
505 
506  uint32_t sampling_pattern = 0;
507  for (int sampl = 0; sampl < NumSamplings; ++sampl)
508  {
509  const int cells_per_sampling = ed.m_moments->nCellSampling[sampl][cluster_index];
510 
511  if (cells_per_sampling > 0)
512  {
513  sampling_pattern |= (0x1U << sampl);
514  }
515  }
516  cluster->setSamplingPattern(sampling_pattern);
517 
518  for (int sampl = 0; sampl < NumSamplings; ++sampl)
519  {
520  const int cells_per_sampling = ed.m_moments->nCellSampling[sampl][cluster_index];
521 
522  if (cells_per_sampling > 0)
523  {
524  cluster->setEnergy ((CaloSampling::CaloSample) sampl, ed.m_moments->energyPerSample [sampl][cluster_index]);
525  cluster->setEta ((CaloSampling::CaloSample) sampl, ed.m_moments->etaPerSample [sampl][cluster_index]);
526  cluster->setPhi ((CaloSampling::CaloSample) sampl, ed.m_moments->phiPerSample [sampl][cluster_index]);
527  cluster->setEmax ((CaloSampling::CaloSample) sampl, ed.m_moments->maxEPerSample [sampl][cluster_index]);
528  cluster->setEtamax ((CaloSampling::CaloSample) sampl, ed.m_moments->maxEtaPerSample [sampl][cluster_index]);
529  cluster->setPhimax ((CaloSampling::CaloSample) sampl, ed.m_moments->maxPhiPerSample [sampl][cluster_index]);
530  }
531 
532  if (m_momentsToDo[xAOD::CaloCluster::NCELL_SAMPLING])
533  {
534  cluster->setNumberCellsInSampling((CaloSampling::CaloSample) sampl, cells_per_sampling, false);
535  }
536  }
537 
538 #define CALORECGPU_MOMENTS_CONVERSION_HELPER(MOMENT_ENUM, MOMENT_ARRAY) \
539  if (m_momentsToDo[xAOD::CaloCluster:: MOMENT_ENUM ] ) \
540  { \
541  cluster->insertMoment(xAOD::CaloCluster:: MOMENT_ENUM , ed.m_moments-> MOMENT_ARRAY [cluster_index]); \
542  }
543 
544 
545 #define CALORECGPU_MOMENTS_CONVERSION_INVALID(MOMENT_ENUM) \
546  if (m_momentsToDo[xAOD::CaloCluster:: MOMENT_ENUM ] ) \
547  { \
548  ATH_MSG_WARNING("Moment '" << # MOMENT_ENUM << \
549  "' given as a calculated moment, but not yet supported on the GPU side..."); \
550  }
551 
552  CALORECGPU_MOMENTS_CONVERSION_HELPER(FIRST_PHI, firstPhi );
553  CALORECGPU_MOMENTS_CONVERSION_HELPER(FIRST_ETA, firstEta );
557  CALORECGPU_MOMENTS_CONVERSION_HELPER(DELTA_THETA, deltaTheta );
558  CALORECGPU_MOMENTS_CONVERSION_HELPER(DELTA_ALPHA, deltaAlpha );
559  CALORECGPU_MOMENTS_CONVERSION_HELPER(CENTER_X, centerX );
560  CALORECGPU_MOMENTS_CONVERSION_HELPER(CENTER_Y, centerY );
561  CALORECGPU_MOMENTS_CONVERSION_HELPER(CENTER_Z, centerZ );
564  CALORECGPU_MOMENTS_CONVERSION_HELPER(LATERAL, lateral );
565  CALORECGPU_MOMENTS_CONVERSION_HELPER(LONGITUDINAL, longitudinal );
566  CALORECGPU_MOMENTS_CONVERSION_HELPER(ENG_FRAC_EM, engFracEM );
567  CALORECGPU_MOMENTS_CONVERSION_HELPER(ENG_FRAC_MAX, engFracMax );
568  CALORECGPU_MOMENTS_CONVERSION_HELPER(ENG_FRAC_CORE, engFracCore );
570  CALORECGPU_MOMENTS_CONVERSION_HELPER(SECOND_ENG_DENS, secondEngDens );
571  CALORECGPU_MOMENTS_CONVERSION_HELPER(ISOLATION, isolation );
572  CALORECGPU_MOMENTS_CONVERSION_HELPER(ENG_BAD_CELLS, engBadCells );
573  CALORECGPU_MOMENTS_CONVERSION_HELPER(N_BAD_CELLS, nBadCells );
574  CALORECGPU_MOMENTS_CONVERSION_HELPER(N_BAD_CELLS_CORR, nBadCellsCorr );
575  CALORECGPU_MOMENTS_CONVERSION_HELPER(BAD_CELLS_CORR_E, badCellsCorrE );
576  CALORECGPU_MOMENTS_CONVERSION_HELPER(BADLARQ_FRAC, badLArQFrac );
577  CALORECGPU_MOMENTS_CONVERSION_HELPER(ENG_POS, engPos );
578  CALORECGPU_MOMENTS_CONVERSION_HELPER(SIGNIFICANCE, significance );
579  CALORECGPU_MOMENTS_CONVERSION_HELPER(CELL_SIGNIFICANCE, cellSignificance );
580  CALORECGPU_MOMENTS_CONVERSION_HELPER(CELL_SIG_SAMPLING, cellSigSampling );
581  CALORECGPU_MOMENTS_CONVERSION_HELPER(AVG_LAR_Q, avgLArQ );
582  CALORECGPU_MOMENTS_CONVERSION_HELPER(AVG_TILE_Q, avgTileQ );
583 
584  if (m_doHVMoments && m_momentsToDo[xAOD::CaloCluster::ENG_BAD_HV_CELLS])
585  {
586  cluster->insertMoment(xAOD::CaloCluster::ENG_BAD_HV_CELLS, HV_energy[cluster_index]);
587  }
588  if (m_doHVMoments && m_momentsToDo[xAOD::CaloCluster::N_BAD_HV_CELLS])
589  {
590  cluster->insertMoment(xAOD::CaloCluster::N_BAD_HV_CELLS, HV_number[cluster_index]);
591  }
592 
595 
600  CALORECGPU_MOMENTS_CONVERSION_INVALID(TILE_CONFIDENCE_LEVEL );
601 
602 
603  CALORECGPU_MOMENTS_CONVERSION_HELPER(SECOND_TIME, secondTime);
604 
605  if (m_momentsToDo[xAOD::CaloCluster::NCELL_SAMPLING])
606  {
607  const int extra_sampling_count = ed.m_moments->nExtraCellSampling[cluster_index];
608  if (extra_sampling_count > 0)
609  {
610  cluster->setNumberCellsInSampling(CaloSampling::EME2, extra_sampling_count, true);
611  }
612  }
613 
614  CALORECGPU_MOMENTS_CONVERSION_INVALID(VERTEX_FRACTION );
615  CALORECGPU_MOMENTS_CONVERSION_INVALID(NVERTEX_FRACTION );
623  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_OUT_L );
624  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_OUT_M );
625  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_OUT_T );
626  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_L );
627  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_M );
628  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_T );
629  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_EMB0 );
630  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_EME0 );
631  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_TILEG3 );
632  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_TOT );
633  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_EMB0 );
634  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_TILE0 );
635  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_TILEG3 );
636  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_EME0 );
637  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_HEC0 );
638  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_FCAL );
639  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_LEAKAGE );
640  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_UNCLASS );
641  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_FRAC_EM );
642  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_FRAC_HAD );
643  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_FRAC_REST );
644 
645  //Maybe things to do with DigiHSTruth, if needed?
646  }
647 
648  const auto end = clock_type::now();
649 
650  if (!m_keepGPUData)
651  {
652  ed.clear_GPU();
653  }
654 
655 
656  if (m_measureTimes)
657  {
658  record_times(ctx.evt(),
659  time_cast(start, pre_processing),
660  time_cast(pre_processing, cluster_number),
661  time_cast(cluster_number, clusters),
662  time_cast(clusters, cells),
663  time_cast(cells, end_cell_cycle),
664  time_cast(end_cell_cycle, ordered),
665  time_cast(ordered, pre_moments),
666  time_cast(pre_moments, post_moments),
667  time_cast(post_moments, end)
668  );
669  }
670 
671 
672  return StatusCode::SUCCESS;
673 
674 }
675 
676 
678 {
679  if (m_measureTimes)
680  {
681  print_times("Preprocessing Cluster_Number Clusters Cells Cell_Cycle Ordering Cluster_Creation Moments_Transfer Moments_Fill", 9);
682  }
683  return StatusCode::SUCCESS;
684 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
CaloClusterKineHelper.h
GPUToAthenaImporterWithMoments::MomentsOptionsArray::array
bool array[num_moments]
Definition: GPUToAthenaImporterWithMoments.h:116
GPUToAthenaImporterWithMoments::m_doHVMoments
bool m_doHVMoments
To abbreviate checks of m_momentsToDo...
Definition: GPUToAthenaImporterWithMoments.h:302
RunTileCalibRec.cells
cells
Definition: RunTileCalibRec.py:271
xAOD::CaloCluster_v1::CSize_Unknown
@ CSize_Unknown
Definition: CaloCluster_v1.h:112
TauGNNUtils::Variables::Cluster::CENTER_LAMBDA
bool CENTER_LAMBDA(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:840
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
GPUToAthenaImporterWithMoments::m_HVCablingKey
SG::ReadCondHandleKey< LArOnOffIdMapping > m_HVCablingKey
Cabling for the CPU-based HV moments calculation.
Definition: GPUToAthenaImporterWithMoments.h:86
ILArHVScaleCorr
Definition: ILArHVScaleCorr.h:13
xAOD::CaloCluster_v1::setRawM
void setRawM(flt_t)
Set mass for singal state UNCALIBRATED.
Definition: CaloCluster_v1.cxx:299
GPUToAthenaImporterWithMoments::GPUToAthenaImporterWithMoments
GPUToAthenaImporterWithMoments(const std::string &type, const std::string &name, const IInterface *parent)
Definition: GPUToAthenaImporterWithMoments.cxx:25
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
CaloRecGPU::ClusterTag::secondary_cluster_index
constexpr int32_t secondary_cluster_index() const
Definition: TagDefinitions.h:253
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
TauGNNUtils::Variables::Cluster::EM_PROBABILITY
bool EM_PROBABILITY(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:909
CaloRecGPU::ClusterTag::is_shared_between_clusters
constexpr bool is_shared_between_clusters() const
Definition: TagDefinitions.h:273
Base_Fragment.mass
mass
Definition: Sherpa_i/share/common/Base_Fragment.py:59
xAOD::CaloCluster_v1::ENG_BAD_HV_CELLS
@ ENG_BAD_HV_CELLS
Total em-scale energy of cells with bad HV in this cluster.
Definition: CaloCluster_v1.h:167
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
SG::VarHandleBase::name
const std::string & name() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:75
xAOD::deltaPhi
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap setEtaBin setIsTgcFailure setDeltaPt deltaPhi
Definition: L2StandAloneMuon_v1.cxx:160
xAOD::CaloCluster_v1::calE
flt_t calE() const
Geet Energy in signal state CALIBRATED.
GPUToAthenaImporterWithMoments::m_momentsNames
Gaudi::Property< std::vector< std::string > > m_momentsNames
vector holding the input list of names of moments to calculate.
Definition: GPUToAthenaImporterWithMoments.h:110
GPUToAthenaImporterWithMoments::m_caloMgrKey
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
Key for the CaloDetDescrManager in the Condition Store.
Definition: GPUToAthenaImporterWithMoments.h:75
xAOD::CaloCluster_v1::clearSamplingData
void clearSamplingData()
Clear the sampling data.
Definition: CaloCluster_v1.cxx:717
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
xAOD::CaloCluster_v1::calEta
flt_t calEta() const
Get in signal state CALIBRATED.
ReadCellNoiseFromCool.cabling
cabling
Definition: ReadCellNoiseFromCool.py:154
CaloRecGPU::EventDataHolder::returnClusterNumberToCPU
void returnClusterNumberToCPU(CaloRecGPU::CUDA_Helpers::CUDAStreamPtrHolder stream={})
This function is asynchronous.
CaloRecGPU::CUDA_Helpers::GPU_synchronize
void GPU_synchronize(CUDAStreamPtrHolder stream={})
Synchronizes the stream.
CaloCellContainer::isOrdered
bool isOrdered() const
tell wether container is ordered
Definition: CaloCellContainer.h:293
xAOD::CaloCluster_v1::insertMoment
void insertMoment(MomentType type, double value)
Definition: CaloCluster_v1.cxx:754
CaloRecGPU::EventDataHolder::returnSomeMomentsToCPU
void returnSomeMomentsToCPU(const size_t num_clusters, CaloRecGPU::CUDA_Helpers::CUDAStreamPtrHolder stream={})
We assume the cluster number is already known and thus only return num_clusters clusters.
GPUToAthenaImporterWithMoments::m_clusterSize
xAOD::CaloCluster::ClusterSize m_clusterSize
Definition: GPUToAthenaImporterWithMoments.h:65
xAOD::CaloCluster_v1::setSamplingPattern
void setSamplingPattern(const unsigned sp, const bool clearSamplingVars=false)
Set sampling pattern (one bit per sampling.
Definition: CaloCluster_v1.cxx:81
xAOD::CaloCluster_v1::setEnergy
bool setEnergy(const CaloSample sampling, const float e)
Set energy for a given sampling. Returns false if the sample isn't part of the cluster.
Definition: CaloCluster_v1.cxx:526
CaloRecGPU::NumSamplings
constexpr int NumSamplings
Definition: BaseDefinitions.h:44
CaloRecGPU::ConstantDataHolder::m_geometry
CaloRecGPU::Helpers::CPU_object< CaloRecGPU::GeometryArr > m_geometry
Definition: DataHolders.h:24
xAOD::CaloCluster_v1::calM
flt_t calM() const
Get mass in signal state CALIBRATED.
xAOD::CaloCluster_v1::setTime
void setTime(flt_t)
Set cluster time.
xAOD::CaloCluster_v1::setEmax
bool setEmax(const CaloSample sampling, const float eMax)
Set the Energy of the cell with the highest energy in a particular sampling.
Definition: CaloCluster_v1.cxx:571
CaloGPUTimed
Base class to provide some basic common infrastructure for timing measurements...
Definition: CaloGPUTimed.h:25
xAOD::CaloCluster
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
Definition: Event/xAOD/xAODCaloEvent/xAODCaloEvent/CaloCluster.h:19
CaloDetDescrManager.h
Definition of CaloDetDescrManager.
CaloRecGPU::ClusterTag
Definition: TagDefinitions.h:222
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
xAOD::CaloCluster_v1::NCELL_SAMPLING
@ NCELL_SAMPLING
Number of cells in sampling layer.
Definition: CaloCluster_v1.h:182
xAOD::CaloCluster_v1::setSecondTime
void setSecondTime(flt_t stime)
Set second moment of cell timing distribution.
Definition: CaloCluster_v1.cxx:985
CRGPU_CHEAP_STRING_TO_ENUM
#define CRGPU_CHEAP_STRING_TO_ENUM(VAR, PREFIX, ONE,...)
Checks a string variable, VAR, for matching enum identifiers (ONE and the remaining variadic argument...
Definition: MacroHelpers.h:148
GPUToAthenaImporterWithMoments::m_momentsToDo
MomentsOptionsArray m_momentsToDo
Holds (in a linearized way) the moments and whether to add them to the clusters.
Definition: GPUToAthenaImporterWithMoments.h:298
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
CaloRecGPU::ClusterTag::cluster_index
constexpr int32_t cluster_index() const
Definition: TagDefinitions.h:243
xAOD::CaloCluster_v1::setE
void setE(flt_t)
Definition: CaloCluster_v1.cxx:375
xAOD::CaloCluster_v1::setPhimax
bool setPhimax(const CaloSample sampling, const float phiMax)
Set the phi of the cell with the highest energy in a particular sampling.
Definition: CaloCluster_v1.cxx:597
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
GPUToAthenaImporterWithMoments.h
python.handimod.now
now
Definition: handimod.py:675
CaloRecGPU::EventDataHolder
Definition: DataHolders.h:35
xAOD::CaloCluster_v1::setRawE
void setRawE(flt_t)
Set Energy for signal state UNCALIBRATED.
Definition: CaloCluster_v1.cxx:284
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:85
CaloSampling::CaloSample
CaloSample
Definition: Calorimeter/CaloGeoHelpers/CaloGeoHelpers/CaloSampling.h:22
CRGPU_RECURSIVE_MACRO
#define CRGPU_RECURSIVE_MACRO(...)
Expands recursive macros.
Definition: MacroHelpers.h:70
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
CaloGPUTimed::print_times
void print_times(const std::string &header, const size_t time_size) const
Definition: CaloGPUTimed.h:143
test_pyathena.parent
parent
Definition: test_pyathena.py:15
xAOD::CaloCluster_v1::setRawEta
void setRawEta(flt_t)
Set for signal state UNCALIBRATED.
Definition: CaloCluster_v1.cxx:289
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAOD::CaloCluster_v1::calPhi
flt_t calPhi() const
Get in signal state CALIBRATED.
GPUToAthenaImporterWithMoments::m_cellsKey
SG::ReadHandleKey< CaloCellContainer > m_cellsKey
vector of names of the cell containers to use as input.
Definition: GPUToAthenaImporterWithMoments.h:60
hist_file_dump.f
f
Definition: hist_file_dump.py:135
CaloRecGPU::NCaloCells
constexpr int NCaloCells
Definition: BaseDefinitions.h:13
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
TauGNNUtils::Variables::Cluster::SECOND_LAMBDA
bool SECOND_LAMBDA(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:835
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
MacroHelpers.h
GPUToAthenaImporterWithMoments::MomentsOptionsArray::num_moments
static constexpr int num_moments
Definition: GPUToAthenaImporterWithMoments.h:115
GPUToAthenaImporterWithMoments::m_clusterSizeString
Gaudi::Property< std::string > m_clusterSizeString
Cluster size. Should be set accordingly to the threshold.
Definition: GPUToAthenaImporterWithMoments.h:63
GPUToAthenaImporterWithMoments::m_calo_id
const CaloCell_ID * m_calo_id
Pointer to Calo ID Helper.
Definition: GPUToAthenaImporterWithMoments.h:70
python.EventInfoMgtInit.release
release
Definition: EventInfoMgtInit.py:24
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
GPUToAthenaImporterWithMoments::m_HVScaleKey
SG::ReadCondHandleKey< ILArHVScaleCorr > m_HVScaleKey
HV corrections for the CPU-based HV moments.
Definition: GPUToAthenaImporterWithMoments.h:89
errorcheck.h
Helpers for checking error return status codes and reporting errors.
xAOD::CaloCluster_v1::setNumberCellsInSampling
void setNumberCellsInSampling(CaloSampling::CaloSample samp, int ncells, bool isInnerWheel=false)
Set the number of cells in a sampling layer.
Definition: CaloCluster_v1.cxx:790
CaloRecGPU::EventDataHolder::returnCellsToCPU
void returnCellsToCPU(CaloRecGPU::CUDA_Helpers::CUDAStreamPtrHolder stream={})
This function is asynchronous.
GPUToAthenaImporterWithMoments::m_fillHVMoments
Gaudi::Property< bool > m_fillHVMoments
if set to true, fill the HV-related moments using the respective tools.
Definition: GPUToAthenaImporterWithMoments.h:83
TauGNNUtils::Variables::Cluster::SECOND_R
bool SECOND_R(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:830
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
xAOD::CaloCluster_v1::ENERGY_DigiHSTruth
@ ENERGY_DigiHSTruth
First Moment in .
Definition: CaloCluster_v1.h:256
CaloRecGPU::ClusterTag::is_part_of_cluster
constexpr bool is_part_of_cluster() const
Definition: TagDefinitions.h:233
CALORECGPU_MOMENTS_CONVERSION_INVALID
#define CALORECGPU_MOMENTS_CONVERSION_INVALID(MOMENT_ENUM)
TauGNNUtils::Variables::Cluster::CENTER_MAG
bool CENTER_MAG(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:916
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
a
TList * a
Definition: liststreamerinfos.cxx:10
CaloCellContainer::isOrderedAndComplete
bool isOrderedAndComplete() const
tell wether container is complete and in order
Definition: CaloCellContainer.h:298
xAOD::CaloCluster_v1::addCellLink
void addCellLink(CaloClusterCellLink *CCCL)
Definition: CaloCluster_v1.h:721
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
xAOD::CaloCluster_v1::setClusterSize
void setClusterSize(const ClusterSize)
Get cluster size.
Definition: CaloCluster_v1.cxx:369
CaloRecGPU::EventDataHolder::m_clusters
CaloRecGPU::Helpers::CUDA_pinned_CPU_object< CaloRecGPU::ClusterInfoArr > m_clusters
Definition: DataHolders.h:76
python.CaloScaleNoiseConfig.str
str
Definition: CaloScaleNoiseConfig.py:78
CaloGPUTimed::m_measureTimes
Gaudi::Property< bool > m_measureTimes
If true, times are recorded to the file given by m_timeFileName.
Definition: CaloGPUTimed.h:46
CaloRecGPU::EventDataHolder::m_cell_state
CaloRecGPU::Helpers::CUDA_pinned_CPU_object< CaloRecGPU::CellStateArr > m_cell_state
Definition: DataHolders.h:75
xAOD::CaloCluster_v1::N_BAD_HV_CELLS
@ N_BAD_HV_CELLS
number of cells with bad HV
Definition: CaloCluster_v1.h:168
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
CUDAFriendlyClasses.h
RunTileMonitoring.clusters
clusters
Definition: RunTileMonitoring.py:133
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:567
TauGNNUtils::Variables::Cluster::FIRST_ENG_DENS
bool FIRST_ENG_DENS(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:902
xAOD::CaloCluster_v1::setPhi
bool setPhi(const CaloSample sampling, const float phi)
Set in a given sampling. Returns false if the sample isn't part of the cluster.
Definition: CaloCluster_v1.cxx:556
CaloRecGPU::ConstantDataHolder
Definition: DataHolders.h:19
xAOD::CaloCluster_v1::setEtamax
bool setEtamax(const CaloSample sampling, const float etaMax)
Set the eta of the cell with the highest energy in a particular sampling.
Definition: CaloCluster_v1.cxx:584
str
Definition: BTagTrackIpAccessor.cxx:11
ILArHVScaleCorr::HVScaleCorr
virtual const float & HVScaleCorr(const HWIdentifier &id) const =0
CaloRecGPU::EventDataHolder::returnSomeClustersToCPU
void returnSomeClustersToCPU(const size_t num_clusters, CaloRecGPU::CUDA_Helpers::CUDAStreamPtrHolder stream={})
We assume the cluster number is already known and thus only return num_clusters clusters.
xAOD::CaloCluster_v1::setEta
bool setEta(const CaloSample sampling, const float eta)
Set in a given sampling. Returns false if the sample isn't part of the cluster.
Definition: CaloCluster_v1.cxx:541
AthAlgTool
Definition: AthAlgTool.h:26
CALORECGPU_MOMENTS_CONVERSION_HELPER
#define CALORECGPU_MOMENTS_CONVERSION_HELPER(MOMENT_ENUM, MOMENT_ARRAY)
CaloRecGPU
Definition: BaseDefinitions.h:11
GPUToAthenaImporterWithMoments::m_missingCellsToFill
Gaudi::Property< std::vector< int > > m_missingCellsToFill
Cell indices to fill as disabled cells (useful if the cell vector is always missing the same cells).
Definition: GPUToAthenaImporterWithMoments.h:96
constants.EME2
int EME2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:56
CaloRecGPU::ClusterTag::secondary_cluster_weight
constexpr int32_t secondary_cluster_weight() const
Definition: TagDefinitions.h:263
CaloRecGPU::EventDataHolder::m_cell_info
CaloRecGPU::Helpers::CUDA_pinned_CPU_object< CaloRecGPU::CellInfoArr > m_cell_info
Definition: DataHolders.h:74
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
GPUToAthenaImporterWithMoments::finalize
virtual StatusCode finalize() override
Definition: GPUToAthenaImporterWithMoments.cxx:677
xAOD::CaloCluster_v1::setM
void setM(flt_t)
Set Mass for the current signal state.
Definition: CaloCluster_v1.cxx:424
GPUToAthenaImporterWithMoments::initialize
virtual StatusCode initialize() override
Definition: GPUToAthenaImporterWithMoments.cxx:36
xAOD::CaloCluster_v1::setRawPhi
void setRawPhi(flt_t)
Set for signal state UNCALIBRATED.
Definition: CaloCluster_v1.cxx:294
GPUToAthenaImporterWithMoments::m_HVthreshold
Gaudi::Property< float > m_HVthreshold
Threshold above which a cell contributes to the HV moments.
Definition: GPUToAthenaImporterWithMoments.h:92
GPUToAthenaImporterWithMoments::MomentsOptionsArray::moment_to_linear
static constexpr int moment_to_linear(const xAOD::CaloCluster::MomentType moment)
Definition: GPUToAthenaImporterWithMoments.h:123
GPUToAthenaImporterWithMoments::convert
virtual StatusCode convert(const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, CaloRecGPU::EventDataHolder &event_data, xAOD::CaloClusterContainer *cluster_collection) const override
Fill the @xAODCaloClusterContainer with the relevant information.
Definition: GPUToAthenaImporterWithMoments.cxx:222