ATLAS Offline Software
GPUToAthenaImporterWithMoments.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 
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):
26  base_class(type, name, parent),
27  CaloGPUTimed(this),
28  m_doHVMoments(false)
29 {
30 }
31 
32 #include "MacroHelpers.h"
33 
35 {
37 
38  ATH_CHECK( detStore()->retrieve(m_calo_id, "CaloCell_ID") );
39 
41 
44 
45  auto get_cluster_size_from_string = [](const std::string & str, bool & failed)
46  {
47  failed = false;
50  SW_55ele,
51  SW_35ele,
52  SW_37ele,
53  SW_55gam,
54  SW_35gam,
55  SW_37gam,
56  SW_55Econv,
57  SW_35Econv,
58  SW_37Econv,
59  SW_softe,
60  Topo_420,
61  Topo_633,
62  SW_7_11,
63  SuperCluster,
64  Tower_01_01,
65  Tower_005_005,
66  Tower_fixed_area
67  )
68  )
69  //I know Topological Clustering only supports a subset of those,
70  //but this is supposed to be a general data exporting tool...
71  else
72  {
73  //failed = true;
75  }
76  };
77 
78  bool size_failed = false;
79  m_clusterSize = get_cluster_size_from_string(m_clusterSizeString, size_failed);
80 
82  {
83  ATH_MSG_ERROR("Invalid Cluster Size: " << m_clusterSizeString);
84  }
85 
86  if (size_failed)
87  {
88  return StatusCode::FAILURE;
89  }
90 
91 
92  auto get_moment_from_string = [](const std::string & str, bool & failed)
93  {
94  failed = false;
97  FIRST_PHI,
98  FIRST_ETA,
99  SECOND_R,
101  DELTA_PHI,
102  DELTA_THETA,
103  DELTA_ALPHA,
104  CENTER_X,
105  CENTER_Y,
106  CENTER_Z,
107  CENTER_MAG,
109  LATERAL,
110  LONGITUDINAL,
111  ENG_FRAC_EM,
112  ENG_FRAC_MAX,
113  ENG_FRAC_CORE,
115  SECOND_ENG_DENS,
116  ISOLATION,
117  ENG_BAD_CELLS,
118  N_BAD_CELLS,
119  N_BAD_CELLS_CORR,
120  BAD_CELLS_CORR_E,
121  BADLARQ_FRAC,
122  ENG_POS,
123  SIGNIFICANCE,
124  CELL_SIGNIFICANCE,
125  CELL_SIG_SAMPLING,
126  AVG_LAR_Q,
127  AVG_TILE_Q,
128  ENG_BAD_HV_CELLS,
129  N_BAD_HV_CELLS,
130  PTD,
131  MASS,
133  HAD_WEIGHT,
134  OOC_WEIGHT,
135  DM_WEIGHT,
136  TILE_CONFIDENCE_LEVEL,
137  SECOND_TIME,
138  NCELL_SAMPLING,
139  VERTEX_FRACTION,
140  NVERTEX_FRACTION,
141  ETACALOFRAME,
142  PHICALOFRAME,
143  ETA1CALOFRAME,
144  PHI1CALOFRAME,
145  ETA2CALOFRAME,
146  PHI2CALOFRAME,
147  ENG_CALIB_TOT,
148  ENG_CALIB_OUT_L,
149  ENG_CALIB_OUT_M,
150  ENG_CALIB_OUT_T,
151  ENG_CALIB_DEAD_L,
152  ENG_CALIB_DEAD_M,
153  ENG_CALIB_DEAD_T,
154  ENG_CALIB_EMB0,
155  ENG_CALIB_EME0,
156  ENG_CALIB_TILEG3,
157  ENG_CALIB_DEAD_TOT,
158  ENG_CALIB_DEAD_EMB0,
159  ENG_CALIB_DEAD_TILE0,
160  ENG_CALIB_DEAD_TILEG3,
161  ENG_CALIB_DEAD_EME0,
162  ENG_CALIB_DEAD_HEC0,
163  ENG_CALIB_DEAD_FCAL,
164  ENG_CALIB_DEAD_LEAKAGE,
165  ENG_CALIB_DEAD_UNCLASS,
166  ENG_CALIB_FRAC_EM,
167  ENG_CALIB_FRAC_HAD,
168  ENG_CALIB_FRAC_REST)
169  )
170  else
171  {
172  failed = true;
174  }
175  };
176 
177 
178  auto process_moments = [&](const std::vector<std::string> & moment_names, std::string & invalid_names)
179  {
180  for (const std::string & mom_name : moment_names)
181  {
182  bool failed = false;
183  const int linear_num = MomentsOptionsArray::moment_to_linear(get_moment_from_string(mom_name, failed));
184 
185  failed = failed || linear_num >= MomentsOptionsArray::num_moments;
186 
187  if (failed)
188  {
189  if (invalid_names.size() == 0)
190  {
191  invalid_names = "'" + mom_name + "'";
192  }
193  else
194  {
195  invalid_names += ", '" + mom_name + "'";
196  }
197  }
198  else
199  {
200  m_momentsToDo.array[linear_num] = true;
201  }
202  }
203  };
204 
205  std::string invalid_names;
206 
207  process_moments(m_momentsNames, invalid_names);
208 
209  if (invalid_names.size() > 0)
210  {
211  ATH_MSG_ERROR( "Moments " << invalid_names
212  << " are not valid moments and will be ignored!" );
213  }
214 
216  return StatusCode::SUCCESS;
217 }
218 
219 
221  const ConstantDataHolder & cdh,
222  EventDataHolder & ed,
223  xAOD::CaloClusterContainer * cluster_container) const
224 {
225  using clock_type = boost::chrono::thread_clock;
226  auto time_cast = [](const auto & before, const auto & after)
227  {
228  return boost::chrono::duration_cast<boost::chrono::microseconds>(after - before).count();
229  };
230 
231 
232  const auto start = clock_type::now();
233 
234  SG::ReadHandle<CaloCellContainer> cell_collection(m_cellsKey, ctx);
235  if ( !cell_collection.isValid() )
236  {
237  ATH_MSG_ERROR( " Cannot retrieve CaloCellContainer: " << cell_collection.name() );
238  return StatusCode::FAILURE;
239  }
240  const DataLink<CaloCellContainer> cell_collection_link (cell_collection.name(), ctx);
241 
242  //ed.returnToCPU(!m_keepGPUData, true, true, true);
243 
244  const auto pre_processing = clock_type::now();
245 
248 
249 
250  const auto cluster_number = clock_type::now();
251 
252  ed.returnSomeClustersToCPU(ed.m_clusters->number);
253 
254  std::vector<std::unique_ptr<CaloClusterCellLink>> cell_links;
255 
256  cell_links.reserve(ed.m_clusters->number);
257 
259 
260  const auto clusters = clock_type::now();
261 
262  ed.returnCellsToCPU();
263 
264  for (int i = 0; i < ed.m_clusters->number; ++i)
265  {
266  if (ed.m_clusters->seedCellID[i] >= 0)
267  {
268  cell_links.emplace_back(std::make_unique<CaloClusterCellLink>(cell_collection_link));
269  cell_links.back()->reserve(256);
270  //To be adjusted.
271  }
272  else
273  {
274  cell_links.emplace_back(nullptr);
275  //The excluded clusters don't have any cells.
276  }
277  }
278 
279  std::vector<float> HV_energy(ed.m_clusters->number * m_doHVMoments, 0.f);
280  std::vector<int> HV_number(ed.m_clusters->number * m_doHVMoments, 0 );
281 
282  const LArOnOffIdMapping * cabling = nullptr;
283  const ILArHVScaleCorr * hvcorr = nullptr;
284 
285  if (m_fillHVMoments)
286  {
289  cabling = *cablingHdl;
290  hvcorr = *hvScaleHdl;
291  }
292 
294 
295  const auto cells = clock_type::now();
296 
297  ed.returnSomeMomentsToCPU(ed.m_clusters->number);
298 
299  //cell_index is the actual cell index in the full set of cells (identifier hash)
300  //cell_count is the cell position in the cell collection (what we want for the weight)
301  const auto process_cell = [&](const int cell_index, const int cell_count)
302  {
303  const ClusterTag this_tag = ed.m_cell_state->clusterTag[cell_index];
304  if (this_tag.is_part_of_cluster())
305  {
306  const int this_index = this_tag.cluster_index();
307  const int32_t weight_pattern = this_tag.secondary_cluster_weight();
308 
309  float tempf = 1.0f;
310 
311  std::memcpy(&tempf, &weight_pattern, sizeof(float));
312  //C++20 would give us bit cast to do this more properly.
313  //Still, given how the bit pattern is created,
314  //it should be safe.
315 
316  const float reverse_weight = tempf;
317 
318  const float this_weight = 1.0f - reverse_weight;
319 
320  if (cell_links[this_index])
321  {
322  cell_links[this_index]->addCell(cell_count, this_weight);
323 
324  if (cell_index == ed.m_clusters->seedCellID[this_index] && cell_links[this_index]->size() > 1)
325  //Seed cells aren't shared,
326  //so no need to check this on the other case.
327  {
328  CaloClusterCellLink::iterator begin_it = cell_links[this_index]->begin();
329  CaloClusterCellLink::iterator back_it = std::prev(cell_links[this_index]->end());
330 
331  const unsigned int first_idx = begin_it.index();
332  const double first_wgt = begin_it.weight();
333 
334  begin_it.reindex(back_it.index());
335  begin_it.reweight(back_it.weight());
336 
337  back_it.reindex(first_idx);
338  back_it.reweight(first_wgt);
339 
340  //Of course, this is to ensure the first cell is the seed cell,
341  //in accordance to the way some cluster properties
342  //(mostly phi-related) are calculated.
343  }
344  }
345 
346  if (this_tag.is_shared_between_clusters())
347  {
348  const int other_index = this_tag.secondary_cluster_index();
349  if (cell_links[other_index])
350  {
351  cell_links[other_index]->addCell(cell_count, reverse_weight);
352  }
353  }
354 
355  if (m_doHVMoments && !cdh.m_geometry->is_tile(cell_index))
356  {
357  HWIdentifier hwid = cabling->createSignalChannelIDFromHash((IdentifierHash) cell_index);
358  const float corr = hvcorr->HVScaleCorr(hwid);
359  if (corr > 0.f && corr < 100.f && fabsf(corr - 1.f) > m_HVthreshold)
360  {
361  const float abs_energy = fabsf(ed.m_cell_info->energy[cell_index]);
362  HV_energy[this_index] += abs_energy;
363  ++HV_number[this_index];
364  if (this_tag.is_shared_between_clusters())
365  {
366  const int other_index = this_tag.secondary_cluster_index();
367  HV_energy[other_index] += abs_energy;
368  ++HV_number[other_index];
369  }
370  }
371  }
372  }
373  };
374 
375  if (cell_collection->isOrderedAndComplete())
376  //Fast path: cell indices within the collection and identifierHashes match!
377  {
378  for (int cell_index = 0; cell_index < NCaloCells; ++cell_index)
379  {
380  process_cell(cell_index, cell_index);
381  }
382  }
383  else if (cell_collection->isOrdered() && m_missingCellsToFill.size() > 0)
384  {
385  size_t missing_cell_count = 0;
386  for (int cell_index = 0; cell_index < NCaloCells; ++cell_index)
387  {
388  if (missing_cell_count < m_missingCellsToFill.size() && cell_index == m_missingCellsToFill[missing_cell_count])
389  {
390  ++missing_cell_count;
391  continue;
392  }
393  process_cell(cell_index, cell_index - missing_cell_count);
394  }
395  }
396  else
397  //Slow path: be careful.
398  {
399  CaloCellContainer::const_iterator iCells = cell_collection->begin();
400 
401  for (int cell_count = 0; iCells != cell_collection->end(); ++iCells, ++cell_count)
402  {
403  const CaloCell * cell = (*iCells);
404 
405  //const int cell_index = m_calo_id->calo_cell_hash(cell->ID());
406  const int cell_index = cell->caloDDE()->calo_hash();
407 
408  process_cell(cell_index, cell_count);
409  }
410  }
411 
412  const auto end_cell_cycle = clock_type::now();
413 
414  std::vector<int> cluster_order(ed.m_clusters->number);
415 
416  std::iota(cluster_order.begin(), cluster_order.end(), 0);
417 
418  std::sort(cluster_order.begin(), cluster_order.end(), [&](const int a, const int b) -> bool
419  {
420  const bool a_valid = ed.m_clusters->seedCellID[a] >= 0;
421  const bool b_valid = ed.m_clusters->seedCellID[b] >= 0;
422  if (a_valid && b_valid)
423  {
424  return ed.m_clusters->clusterEt[a]
425  > ed.m_clusters->clusterEt[b];
426  }
427  else if (a_valid)
428  {
429  return true;
430  }
431  else if (b_valid)
432  {
433  return false;
434  }
435  else
436  {
437  return b > a;
438  }
439  } );
440 
441  //Ordered by Et as in the default algorithm...
442  //The fact that some invalid clusters
443  //(with possibly trash values for Et)
444  //can crop up is irrelevant since
445  //we don't add those anyway:
446  //the rest is still ordered like we want it to be.
447 
448  const auto ordered = clock_type::now();
449 
450  cluster_container->clear();
451  cluster_container->reserve(cell_links.size());
452 
453  std::vector<int> real_cluster_order;
454  real_cluster_order.reserve(cluster_order.size());
455 
456  for (size_t i = 0; i < cluster_order.size(); ++i)
457  {
458  const int cluster_index = cluster_order[i];
459 
460  if (cell_links[cluster_index] != nullptr && cell_links[cluster_index]->size() > 0)
461  {
462  xAOD::CaloCluster * cluster = new xAOD::CaloCluster();
463  cluster_container->push_back(cluster);
464 
465  cluster->addCellLink(cell_links[cluster_index].release());
466  cluster->setClusterSize(m_clusterSize);
467 
468  cluster->setEta(ed.m_clusters->clusterEta[cluster_index]);
469  cluster->setPhi(ed.m_clusters->clusterPhi[cluster_index]);
470 
471  cluster->setE(ed.m_clusters->clusterEnergy[cluster_index]);
472  cluster->setM(0.0);
473 
474 
475  if (m_saveUncalibrated)
476  {
477  cluster->setRawE(cluster->calE());
478  cluster->setRawEta(cluster->calEta());
479  cluster->setRawPhi(cluster->calPhi());
480  cluster->setRawM(cluster->calM());
481  }
482 
483  real_cluster_order.push_back(cluster_index);
484  }
485 
486  }
487 
488  const auto pre_moments = clock_type::now();
489 
491 
492 
493  const auto post_moments = clock_type::now();
494 
495  for (size_t i = 0; i < cluster_container->size(); ++i)
496  {
497  xAOD::CaloCluster * cluster = (*cluster_container)[i];
498  const int cluster_index = real_cluster_order[i];
499 
500  cluster->setTime(ed.m_moments->time[cluster_index]);
501  cluster->setSecondTime(ed.m_moments->secondTime[cluster_index]);
502  cluster->clearSamplingData();
503 
504  uint32_t sampling_pattern = 0;
505  for (int sampl = 0; sampl < NumSamplings; ++sampl)
506  {
507  const int cells_per_sampling = ed.m_moments->nCellSampling[sampl][cluster_index];
508 
509  if (cells_per_sampling > 0)
510  {
511  sampling_pattern |= (0x1U << sampl);
512  }
513  }
514  cluster->setSamplingPattern(sampling_pattern);
515 
516  for (int sampl = 0; sampl < NumSamplings; ++sampl)
517  {
518  const int cells_per_sampling = ed.m_moments->nCellSampling[sampl][cluster_index];
519 
520  if (cells_per_sampling > 0)
521  {
522  cluster->setEnergy ((CaloSampling::CaloSample) sampl, ed.m_moments->energyPerSample [sampl][cluster_index]);
523  cluster->setEta ((CaloSampling::CaloSample) sampl, ed.m_moments->etaPerSample [sampl][cluster_index]);
524  cluster->setPhi ((CaloSampling::CaloSample) sampl, ed.m_moments->phiPerSample [sampl][cluster_index]);
525  cluster->setEmax ((CaloSampling::CaloSample) sampl, ed.m_moments->maxEPerSample [sampl][cluster_index]);
526  cluster->setEtamax ((CaloSampling::CaloSample) sampl, ed.m_moments->maxEtaPerSample [sampl][cluster_index]);
527  cluster->setPhimax ((CaloSampling::CaloSample) sampl, ed.m_moments->maxPhiPerSample [sampl][cluster_index]);
528  }
529 
530  if (m_momentsToDo[xAOD::CaloCluster::NCELL_SAMPLING])
531  {
532  cluster->setNumberCellsInSampling((CaloSampling::CaloSample) sampl, cells_per_sampling, false);
533  }
534  }
535 
536 #define CALORECGPU_MOMENTS_CONVERSION_HELPER(MOMENT_ENUM, MOMENT_ARRAY) \
537  if (m_momentsToDo[xAOD::CaloCluster:: MOMENT_ENUM ] ) \
538  { \
539  cluster->insertMoment(xAOD::CaloCluster:: MOMENT_ENUM , ed.m_moments-> MOMENT_ARRAY [cluster_index]); \
540  }
541 
542 
543 #define CALORECGPU_MOMENTS_CONVERSION_INVALID(MOMENT_ENUM) \
544  if (m_momentsToDo[xAOD::CaloCluster:: MOMENT_ENUM ] ) \
545  { \
546  ATH_MSG_WARNING("Moment '" << # MOMENT_ENUM << \
547  "' given as a calculated moment, but not yet supported on the GPU side..."); \
548  }
549 
550  CALORECGPU_MOMENTS_CONVERSION_HELPER(FIRST_PHI, firstPhi );
551  CALORECGPU_MOMENTS_CONVERSION_HELPER(FIRST_ETA, firstEta );
555  CALORECGPU_MOMENTS_CONVERSION_HELPER(DELTA_THETA, deltaTheta );
556  CALORECGPU_MOMENTS_CONVERSION_HELPER(DELTA_ALPHA, deltaAlpha );
557  CALORECGPU_MOMENTS_CONVERSION_HELPER(CENTER_X, centerX );
558  CALORECGPU_MOMENTS_CONVERSION_HELPER(CENTER_Y, centerY );
559  CALORECGPU_MOMENTS_CONVERSION_HELPER(CENTER_Z, centerZ );
562  CALORECGPU_MOMENTS_CONVERSION_HELPER(LATERAL, lateral );
563  CALORECGPU_MOMENTS_CONVERSION_HELPER(LONGITUDINAL, longitudinal );
564  CALORECGPU_MOMENTS_CONVERSION_HELPER(ENG_FRAC_EM, engFracEM );
565  CALORECGPU_MOMENTS_CONVERSION_HELPER(ENG_FRAC_MAX, engFracMax );
566  CALORECGPU_MOMENTS_CONVERSION_HELPER(ENG_FRAC_CORE, engFracCore );
568  CALORECGPU_MOMENTS_CONVERSION_HELPER(SECOND_ENG_DENS, secondEngDens );
569  CALORECGPU_MOMENTS_CONVERSION_HELPER(ISOLATION, isolation );
570  CALORECGPU_MOMENTS_CONVERSION_HELPER(ENG_BAD_CELLS, engBadCells );
571  CALORECGPU_MOMENTS_CONVERSION_HELPER(N_BAD_CELLS, nBadCells );
572  CALORECGPU_MOMENTS_CONVERSION_HELPER(N_BAD_CELLS_CORR, nBadCellsCorr );
573  CALORECGPU_MOMENTS_CONVERSION_HELPER(BAD_CELLS_CORR_E, badCellsCorrE );
574  CALORECGPU_MOMENTS_CONVERSION_HELPER(BADLARQ_FRAC, badLArQFrac );
575  CALORECGPU_MOMENTS_CONVERSION_HELPER(ENG_POS, engPos );
576  CALORECGPU_MOMENTS_CONVERSION_HELPER(SIGNIFICANCE, significance );
577  CALORECGPU_MOMENTS_CONVERSION_HELPER(CELL_SIGNIFICANCE, cellSignificance );
578  CALORECGPU_MOMENTS_CONVERSION_HELPER(CELL_SIG_SAMPLING, cellSigSampling );
579  CALORECGPU_MOMENTS_CONVERSION_HELPER(AVG_LAR_Q, avgLArQ );
580  CALORECGPU_MOMENTS_CONVERSION_HELPER(AVG_TILE_Q, avgTileQ );
581 
582  if (m_doHVMoments && m_momentsToDo[xAOD::CaloCluster::ENG_BAD_HV_CELLS])
583  {
584  cluster->insertMoment(xAOD::CaloCluster::ENG_BAD_HV_CELLS, HV_energy[cluster_index]);
585  }
586  if (m_doHVMoments && m_momentsToDo[xAOD::CaloCluster::N_BAD_HV_CELLS])
587  {
588  cluster->insertMoment(xAOD::CaloCluster::N_BAD_HV_CELLS, HV_number[cluster_index]);
589  }
590 
593 
598  CALORECGPU_MOMENTS_CONVERSION_INVALID(TILE_CONFIDENCE_LEVEL );
599 
600 
601  CALORECGPU_MOMENTS_CONVERSION_HELPER(SECOND_TIME, secondTime);
602 
603  if (m_momentsToDo[xAOD::CaloCluster::NCELL_SAMPLING])
604  {
605  const int extra_sampling_count = ed.m_moments->nExtraCellSampling[cluster_index];
606  if (extra_sampling_count > 0)
607  {
608  cluster->setNumberCellsInSampling(CaloSampling::EME2, extra_sampling_count, true);
609  }
610  }
611 
612  CALORECGPU_MOMENTS_CONVERSION_INVALID(VERTEX_FRACTION );
613  CALORECGPU_MOMENTS_CONVERSION_INVALID(NVERTEX_FRACTION );
621  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_OUT_L );
622  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_OUT_M );
623  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_OUT_T );
624  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_L );
625  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_M );
626  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_T );
627  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_EMB0 );
628  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_EME0 );
629  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_TILEG3 );
630  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_TOT );
631  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_EMB0 );
632  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_TILE0 );
633  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_TILEG3 );
634  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_EME0 );
635  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_HEC0 );
636  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_FCAL );
637  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_LEAKAGE );
638  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_DEAD_UNCLASS );
639  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_FRAC_EM );
640  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_FRAC_HAD );
641  CALORECGPU_MOMENTS_CONVERSION_INVALID(ENG_CALIB_FRAC_REST );
642 
643  //Maybe things to do with DigiHSTruth, if needed?
644  }
645 
646  const auto end = clock_type::now();
647 
648  if (!m_keepGPUData)
649  {
650  ed.clear_GPU();
651  }
652 
653 
654  if (m_measureTimes)
655  {
656  record_times(ctx.evt(),
657  time_cast(start, pre_processing),
658  time_cast(pre_processing, cluster_number),
659  time_cast(cluster_number, clusters),
660  time_cast(clusters, cells),
661  time_cast(cells, end_cell_cycle),
662  time_cast(end_cell_cycle, ordered),
663  time_cast(ordered, pre_moments),
664  time_cast(pre_moments, post_moments),
665  time_cast(post_moments, end)
666  );
667  }
668 
669 
670  return StatusCode::SUCCESS;
671 
672 }
673 
674 
676 {
677  if (m_measureTimes)
678  {
679  print_times("Preprocessing Cluster_Number Clusters Cells Cell_Cycle Ordering Cluster_Creation Moments_Transfer Moments_Fill", 9);
680  }
681  return StatusCode::SUCCESS;
682 }
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:281
xAOD::CaloCluster_v1::CSize_Unknown
@ CSize_Unknown
Definition: CaloCluster_v1.h:115
TauGNNUtils::Variables::Cluster::CENTER_LAMBDA
bool CENTER_LAMBDA(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:851
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:920
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:170
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
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:161
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:671
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:13
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:708
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:519
CaloRecGPU::NumSamplings
constexpr int NumSamplings
Definition: BaseDefinitions.h:43
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:564
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
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:92
xAOD::CaloCluster_v1::NCELL_SAMPLING
@ NCELL_SAMPLING
Number of cells in sampling layer.
Definition: CaloCluster_v1.h:185
xAOD::CaloCluster_v1::setSecondTime
void setSecondTime(flt_t stime)
Set second moment of cell timing distribution.
Definition: CaloCluster_v1.cxx:939
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:590
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:62
GPUToAthenaImporterWithMoments.h
python.handimod.now
now
Definition: handimod.py:674
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
python.CaloAddPedShiftConfig.str
str
Definition: CaloAddPedShiftConfig.py:42
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:140
CaloRecGPU::NCaloCells
constexpr int NCaloCells
Definition: BaseDefinitions.h:12
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:846
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.PyKernel.detStore
detStore
Definition: PyKernel.py:41
python.EventInfoMgtInit.release
release
Definition: EventInfoMgtInit.py:23
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:76
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:744
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:841
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
xAOD::CaloCluster_v1::ENERGY_DigiHSTruth
@ ENERGY_DigiHSTruth
First Moment in .
Definition: CaloCluster_v1.h:259
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:927
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:724
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
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:171
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:913
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:549
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:577
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:534
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:675
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:34
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
Definition: GPUToAthenaImporterWithMoments.cxx:220