ATLAS Offline Software
CaloGPUClusterAndCellDataMonitor.cxx
Go to the documentation of this file.
1 //
2 //
3 // Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
4 //
5 // Dear emacs, this is -*- c++ -*-
6 //
7 
9 #include "CaloRecGPU/Helpers.h"
11 #include "StoreGate/DataHandle.h"
14 
16 
17 #include "CLHEP/Units/SystemOfUnits.h"
18 
19 #include <map>
20 #include <numeric>
21 #include <algorithm>
22 
23 using namespace CaloRecGPU;
24 
25 CaloGPUClusterAndCellDataMonitor::CaloGPUClusterAndCellDataMonitor(const std::string & type, const std::string & name, const IInterface * parent):
27  m_plottedVariablesInitialized(false)
28 {
29  declareInterface<ICaloClusterGPUPlotter> (this);
30 }
31 
33 {
35 
36  ATH_CHECK( detStore()->retrieve(m_calo_id, "CaloCell_ID") );
37 
38  const std::string this_name = this->name();
39 
40  const std::string algorithm_name_prefix = this_name.substr(0, this_name.rfind('.'));
41  //This is so we take into account the fact that tools
42  //are prefixed with the parent algorithm's name.
43 
44  auto final_string = [& algorithm_name_prefix](const std::string & unpref_str) -> std::string
45  {
46  return algorithm_name_prefix + "." + unpref_str;
47  };
48 
50 
51  m_min_similarity = opts.min_similarity;
52  m_seed_weight = opts.seed_w;
53  m_grow_weight = opts.grow_w;
54  m_terminal_weight = opts.term_w;
55 
56  for (const auto & tool : m_toolsToPlot)
57  {
58  const std::string tool_name = final_string(tool.tool);
59  m_toolToIdMap[tool_name] = tool.plot_id;
60  m_toolsToCheckFor[tool_name] = -1;
61  }
62 
63  auto add_tool_from_pair = [this](const std::string & name) -> int
64  {
65  if (!m_toolsToCheckFor.count(name))
66  {
68  m_toolToIdMap[name] = "";
69  return m_numToolsToKeep++;
70  }
71  else
72  {
73  const int current = m_toolsToCheckFor[name];
74  if (current >= 0)
75  {
76  return current;
77  }
78  else
79  {
81  return m_numToolsToKeep++;
82  }
83  }
84  };
85 
86  for (const auto & pair : m_pairsToPlot)
87  {
88  const int first_index = add_tool_from_pair(final_string(pair.tool_ref));
89  const int second_index = add_tool_from_pair(final_string(pair.tool_test));
90  m_toolCombinations.emplace_back(pair_to_plot{first_index, second_index, pair.plot_id,
91  pair.match_in_energy,
92  pair.match_without_shared,
93  pair.match_perfectly});
94  }
95 
96  ATH_CHECK( m_moniTool.retrieve() );
97 
98  return StatusCode::SUCCESS;
99 }
100 
102 {
103  //Well, not do plots, just monitor the number of events and the total number of clusters...
104 
105  auto mon_num_events = Monitored::Scalar("num_events", m_numEvents);
106 
107  for (const auto & k_v : m_toolToIdMap)
108  {
109  auto mon_num_clust = Monitored::Scalar(k_v.second + "_num_total_clusters", m_numClustersPerTool.at(k_v.first).load());
110  }
111 
112  return StatusCode::SUCCESS;
113 }
114 
116  const ConstantDataHolder & /*constant_data*/,
117  const xAOD::CaloClusterContainer * /*cluster_collection_ptr*/) const
118 {
119  if (!m_plottedVariablesInitialized.load())
120  {
121  std::lock_guard<std::mutex> lock_guard(m_mutex);
122  if (!m_plottedVariablesInitialized.load())
123  {
125  //We have the mutex.
126  //It's safe.
127  ATH_CHECK( dhis->initialize_plotted_variables() );
128  m_plottedVariablesInitialized.store(true);
129  }
130  }
131  if (m_numToolsToKeep > 0)
132  {
133  m_storageHolder.get_one().resize(m_numToolsToKeep);
134  }
135  //Allocate a vector of data holders for this thread and resize it to the necessary size.
136 
137  return StatusCode::SUCCESS;
138 }
139 
141  const ConstantDataHolder & constant_data,
142  const xAOD::CaloClusterContainer * /*cluster_collection_ptr*/) const
143 {
144  ATH_MSG_INFO("");
145 
146  for (const auto & combination : m_toolCombinations)
147  {
148  if (combination.index_ref < 0 || combination.index_test < 0)
149  {
150  ATH_MSG_WARNING("Invalid tool combination, please check your configuration! " << combination.prefix);
151  continue;
152  }
153  ATH_CHECK( add_combination(ctx, constant_data, combination.index_ref, combination.index_test, combination.prefix,
154  combination.match_in_energy, combination.match_without_shared, combination.match_perfectly) );
155  }
156 
157  ATH_MSG_INFO("");
158 
159  if (m_numToolsToKeep > 0)
160  {
161  m_storageHolder.release_one();
162  //Release the tool storage.
163  }
164 
165  return StatusCode::SUCCESS;
166 }
167 
169  const ConstantDataHolder & constant_data,
170  const xAOD::CaloClusterContainer * cluster_collection_ptr,
171  const CaloClusterCollectionProcessor * tool) const
172 {
173  if (filter_tool_by_name(tool->name()))
174  {
179 
180  ATH_CHECK( convert_to_GPU_data_structures(ctx, constant_data, cluster_collection_ptr,
181  cell_info, cell_state, clusters, moments ) );
182 
183  return add_data(ctx, constant_data, cell_info, cell_state, clusters, moments, tool->name());
184  }
185  else
186  {
187  return StatusCode::SUCCESS;
188  }
189 }
190 
192  const ConstantDataHolder & constant_data,
193  const xAOD::CaloClusterContainer * /*cluster_collection_ptr*/,
194  const EventDataHolder & event_data,
196 {
197  if (filter_tool_by_name(tool->name()))
198  {
199  return add_data(ctx, constant_data, event_data.m_cell_info_dev, event_data.m_cell_state_dev,
200  event_data.m_clusters_dev, event_data.m_moments_dev, tool->name());
201  }
202  else
203  {
204  return StatusCode::SUCCESS;
205  }
206 }
207 
209  const ConstantDataHolder & constant_data,
210  const xAOD::CaloClusterContainer * /*cluster_collection_ptr*/,
211  const EventDataHolder & event_data,
212  const CaloClusterGPUProcessor * tool) const
213 {
214  if (filter_tool_by_name(tool->name()))
215  {
216  Helpers::CPU_object<CellInfoArr> cell_info = event_data.m_cell_info_dev;
217  Helpers::CPU_object<CellStateArr> cell_state = event_data.m_cell_state_dev;
220 
221  ATH_CHECK( compactify_clusters(ctx, constant_data, cell_info, cell_state, clusters, moments) );
222 
223  return add_data(ctx, constant_data, cell_info, cell_state, clusters, moments, tool->name());
224  }
225  else
226  {
227  return StatusCode::SUCCESS;
228  }
229 }
230 
232  const ConstantDataHolder & constant_data,
233  const xAOD::CaloClusterContainer * cluster_collection_ptr,
234  const EventDataHolder & /*event_data*/,
236 {
237  if (filter_tool_by_name(tool->name()))
238  {
243 
244  ATH_CHECK( convert_to_GPU_data_structures(ctx, constant_data, cluster_collection_ptr,
245  cell_info, cell_state, clusters, moments ) );
246 
247  return add_data(ctx, constant_data, cell_info, cell_state, clusters, moments, tool->name());
248  }
249  else
250  {
251  return StatusCode::SUCCESS;
252  }
253 }
254 
255 bool CaloGPUClusterAndCellDataMonitor::filter_tool_by_name(const std::string & tool_name)
256 const
257 {
258  ATH_MSG_DEBUG("Checking : '" << tool_name << "': " << m_toolsToCheckFor.count(tool_name));
259  return m_toolsToCheckFor.count(tool_name) > 0;
260 }
261 
262 //Note: The following is essentially copied over from two tools.
263 // Maybe we could prevent the repetition?
264 
266  const ConstantDataHolder & /*constant_data*/,
267  const xAOD::CaloClusterContainer * cluster_collection,
272 {
273  SG::ReadHandle<CaloCellContainer> cell_collection(m_cellsKey, ctx);
274  if ( !cell_collection.isValid() )
275  {
276  ATH_MSG_ERROR( " Cannot retrieve CaloCellContainer: " << cell_collection.name() );
277  return StatusCode::FAILURE;
278  }
279 
280  ret_info.allocate();
281 
282  if (cluster_collection != nullptr)
283  {
284  ret_state.allocate();
285  ret_clusts.allocate();
286  ret_moments.allocate();
287  }
288 
289  for (int i = 0; i < NCaloCells; ++i)
290  {
291  ret_info->energy[i] = 0;
292  ret_info->gain[i] = GainConversion::invalid_gain();
293  ret_info->time[i] = 0;
294  ret_info->qualityProvenance[i] = 0;
295 
296  if (cluster_collection != nullptr)
297  {
298  ret_state->clusterTag[i] = ClusterTag::make_invalid_tag();
299  }
300  }
301 
302  for (CaloCellContainer::const_iterator iCells = cell_collection->begin(); iCells != cell_collection->end(); ++iCells)
303  {
304  const CaloCell * cell = (*iCells);
305 
306  const int index = m_calo_id->calo_cell_hash(cell->ID());
307 
308  const float energy = cell->energy();
309 
310  const unsigned int gain = GainConversion::from_standard_gain(cell->gain());
311 
312  ret_info->energy[index] = energy;
313  ret_info->gain[index] = gain;
314  ret_info->time[index] = cell->time();
315  ret_info->qualityProvenance[index] = QualityProvenance{cell->quality(), cell->provenance()};
316 
317  }
318 
319  if (cluster_collection != nullptr)
320  {
321  const auto cluster_end = cluster_collection->end();
322  auto cluster_iter = cluster_collection->begin();
323 
324  for (int cluster_number = 0; cluster_iter != cluster_end; ++cluster_iter, ++cluster_number )
325  {
326  const xAOD::CaloCluster * cluster = (*cluster_iter);
327  const CaloClusterCellLink * cell_links = cluster->getCellLinks();
328  if (!cell_links)
329  {
330  ATH_MSG_ERROR("Can't get valid links to CaloCells (CaloClusterCellLink)!");
331  return StatusCode::FAILURE;
332  }
333 
334  ret_clusts->clusterEnergy[cluster_number] = cluster->e();
335  ret_clusts->clusterEt[cluster_number] = cluster->et();
336  ret_clusts->clusterEta[cluster_number] = cluster->eta();
337  ret_clusts->clusterPhi[cluster_number] = cluster->phi();
338  ret_clusts->seedCellID[cluster_number] = m_calo_id->calo_cell_hash(cluster->cell_begin()->ID());
339  for (int i = 0; i < NumSamplings; ++i)
340  {
341  ret_moments->energyPerSample[i][cluster_number] = cluster->eSample((CaloSampling::CaloSample) i);
342  ret_moments->maxEPerSample[i][cluster_number] = cluster->energy_max((CaloSampling::CaloSample) i);
343  ret_moments->maxPhiPerSample[i][cluster_number] = cluster->phimax((CaloSampling::CaloSample) i);
344  ret_moments->maxEtaPerSample[i][cluster_number] = cluster->etamax((CaloSampling::CaloSample) i);
345  ret_moments->etaPerSample[i][cluster_number] = cluster->etaSample((CaloSampling::CaloSample) i);
346  ret_moments->phiPerSample[i][cluster_number] = cluster->phiSample((CaloSampling::CaloSample) i);
347  ret_moments->nCellSampling[i][cluster_number] = cluster->numberCellsInSampling((CaloSampling::CaloSample) i);
348  }
349  ret_moments->time[cluster_number] = cluster->time();
350  ret_moments->firstPhi[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::FIRST_PHI);
351  ret_moments->firstEta[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::FIRST_ETA);
352  ret_moments->secondR[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::SECOND_R);
353  ret_moments->secondLambda[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::SECOND_LAMBDA);
354  ret_moments->deltaPhi[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::DELTA_PHI);
355  ret_moments->deltaTheta[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::DELTA_THETA);
356  ret_moments->deltaAlpha[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::DELTA_ALPHA);
357  ret_moments->centerX[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::CENTER_X);
358  ret_moments->centerY[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::CENTER_Y);
359  ret_moments->centerZ[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::CENTER_Z);
360  ret_moments->centerMag[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::CENTER_MAG);
361  ret_moments->centerLambda[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::CENTER_LAMBDA);
362  ret_moments->lateral[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::LATERAL);
363  ret_moments->longitudinal[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::LONGITUDINAL);
364  ret_moments->engFracEM[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_FRAC_EM);
365  ret_moments->engFracMax[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_FRAC_MAX);
366  ret_moments->engFracCore[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_FRAC_CORE);
367  ret_moments->firstEngDens[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::FIRST_ENG_DENS);
368  ret_moments->secondEngDens[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::SECOND_ENG_DENS);
369  ret_moments->isolation[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ISOLATION);
370  ret_moments->engBadCells[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_BAD_CELLS);
371  ret_moments->nBadCells[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::N_BAD_CELLS);
372  ret_moments->nBadCellsCorr[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::N_BAD_CELLS_CORR);
373  ret_moments->badCellsCorrE[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::BAD_CELLS_CORR_E);
374  ret_moments->badLArQFrac[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::BADLARQ_FRAC);
375  ret_moments->engPos[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_POS);
376  ret_moments->significance[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::SIGNIFICANCE);
377  ret_moments->cellSignificance[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::CELL_SIGNIFICANCE);
378  ret_moments->cellSigSampling[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::CELL_SIG_SAMPLING);
379  ret_moments->avgLArQ[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::AVG_LAR_Q);
380  ret_moments->avgTileQ[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::AVG_TILE_Q);
381  ret_moments->engBadHVCells[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_BAD_HV_CELLS);
382  ret_moments->nBadHVCells[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::N_BAD_HV_CELLS);
383  ret_moments->PTD[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::PTD);
384  ret_moments->mass[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::MASS);
385  ret_moments->EMProbability[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::EM_PROBABILITY);
386  ret_moments->hadWeight[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::HAD_WEIGHT);
387  ret_moments->OOCweight[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::OOC_WEIGHT);
388  ret_moments->DMweight[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::DM_WEIGHT);
389  ret_moments->tileConfidenceLevel[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::TILE_CONFIDENCE_LEVEL);
390  ret_moments->secondTime[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::SECOND_TIME);
391  ret_moments->nExtraCellSampling[cluster_number] = cluster->numberCellsInSampling(CaloSampling::EME2, true);
392  ret_moments->numCells[cluster_number] = cluster->numberCells();
393  ret_moments->vertexFraction[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::VERTEX_FRACTION);
394  ret_moments->nVertexFraction[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::NVERTEX_FRACTION);
395  ret_moments->etaCaloFrame[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ETACALOFRAME);
396  ret_moments->phiCaloFrame[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::PHICALOFRAME);
397  ret_moments->eta1CaloFrame[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ETA1CALOFRAME);
398  ret_moments->phi1CaloFrame[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::PHI1CALOFRAME);
399  ret_moments->eta2CaloFrame[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ETA2CALOFRAME);
400  ret_moments->phi2CaloFrame[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::PHI2CALOFRAME);
401  ret_moments->engCalibTot[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_TOT);
402  ret_moments->engCalibOutL[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_OUT_L);
403  ret_moments->engCalibOutM[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_OUT_M);
404  ret_moments->engCalibOutT[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_OUT_T);
405  ret_moments->engCalibDeadL[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_DEAD_L);
406  ret_moments->engCalibDeadM[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_DEAD_M);
407  ret_moments->engCalibDeadT[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_DEAD_T);
408  ret_moments->engCalibEMB0[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_EMB0);
409  ret_moments->engCalibEME0[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_EME0);
410  ret_moments->engCalibTileG3[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_TILEG3);
411  ret_moments->engCalibDeadTot[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_DEAD_TOT);
412  ret_moments->engCalibDeadEMB0[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_DEAD_EMB0);
413  ret_moments->engCalibDeadTile0[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_DEAD_TILE0);
414  ret_moments->engCalibDeadTileG3[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_DEAD_TILEG3);
415  ret_moments->engCalibDeadEME0[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_DEAD_EME0);
416  ret_moments->engCalibDeadHEC0[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_DEAD_HEC0);
417  ret_moments->engCalibDeadFCAL[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_DEAD_FCAL);
418  ret_moments->engCalibDeadLeakage[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_DEAD_LEAKAGE);
419  ret_moments->engCalibDeadUnclass[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_DEAD_UNCLASS);
420  ret_moments->engCalibFracEM[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_FRAC_EM);
421  ret_moments->engCalibFracHad[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_FRAC_HAD);
422  ret_moments->engCalibFracRest[cluster_number] = cluster->getMomentValue(xAOD::CaloCluster::ENG_CALIB_FRAC_REST);
423  for (auto it = cell_links->begin(); it != cell_links->end(); ++it)
424  {
425  const int cell_ID = m_calo_id->calo_cell_hash(it->ID());
426  const float weight = it.weight();
427 
428  uint32_t weight_as_int = 0;
429  std::memcpy(&weight_as_int, &weight, sizeof(float));
430  //On the platforms we expect to be running this, it should be fine.
431  //Still UB.
432  //With C++20, we could do that bit-cast thing.
433 
434  if (weight_as_int == 0)
435  {
436  weight_as_int = 1;
437  //Subnormal,
438  //but just to distinguish from
439  //a non-shared cluster.
440  }
441 
442  const ClusterTag other_tag = ret_state->clusterTag[cell_ID];
443 
444  const int other_index = other_tag.is_part_of_cluster() ? other_tag.cluster_index() : -1;
445 
446  if (other_index < 0)
447  {
448  if (weight < 0.5f)
449  {
450  ret_state->clusterTag[cell_ID] = ClusterTag::make_tag(cluster_number, weight_as_int, 0);
451  }
452  else
453  {
454  ret_state->clusterTag[cell_ID] = ClusterTag::make_tag(cluster_number);
455  }
456  }
457  else if (weight > 0.5f)
458  {
459  ret_state->clusterTag[cell_ID] = ClusterTag::make_tag(cluster_number, other_tag.secondary_cluster_weight(), other_index);
460  }
461  else if (weight == 0.5f)
462  //Unlikely, but...
463  {
464  const int max_cluster = cluster_number > other_index ? cluster_number : other_index;
465  const int min_cluster = cluster_number > other_index ? other_index : cluster_number;
466  ret_state->clusterTag[cell_ID] = ClusterTag::make_tag(max_cluster, weight_as_int, min_cluster);
467  }
468  else /*if (weight < 0.5f)*/
469  {
470  ret_state->clusterTag[cell_ID] = ClusterTag::make_tag(other_index, weight_as_int, cluster_number);
471  }
472  }
473  }
474 
475  ret_clusts->number = cluster_collection->size();
476  }
477 
478  return StatusCode::SUCCESS;
479 }
480 
487 {
488  std::map<int, int> tag_map;
489 
490  std::vector<int> cluster_order(clusters->number);
491 
492  std::iota(cluster_order.begin(), cluster_order.end(), 0);
493 
494  std::sort(cluster_order.begin(), cluster_order.end(), [&](const int a, const int b)
495  {
496  if (clusters->seedCellID[a] < 0)
497  {
498  return false;
499  //This means that clusters with no cells
500  //(marked as invalid) always compare lower,
501  //so they appear in the end.
502  }
503  else if (clusters->seedCellID[b] < 0)
504  {
505  return true;
506  }
507  return clusters->clusterEt[a] > clusters->clusterEt[b];
508  } );
509 
510  int real_cluster_numbers = clusters->number;
511 
512  for (size_t i = 0; i < cluster_order.size(); ++i)
513  {
514  const int this_id = cluster_order[i];
515  if (clusters->seedCellID[this_id] < 0)
516  {
517  tag_map[this_id] = -1;
518  --real_cluster_numbers;
519  }
520  else
521  {
522  tag_map[this_id] = i;
523  }
524  }
525 
526  const Helpers::CPU_object<ClusterInfoArr> temp_clusters(clusters);
527  const Helpers::CPU_object<ClusterMomentsArr> temp_moments(moments);
528 
529  clusters->number = real_cluster_numbers;
530 
531  for (int i = 0; i < temp_clusters->number; ++i)
532  {
533  clusters->clusterEnergy[i] = temp_clusters->clusterEnergy[cluster_order[i]];
534  clusters->clusterEt[i] = temp_clusters->clusterEt[cluster_order[i]];
535  clusters->clusterEta[i] = temp_clusters->clusterEta[cluster_order[i]];
536  clusters->clusterPhi[i] = temp_clusters->clusterPhi[cluster_order[i]];
537  clusters->seedCellID[i] = temp_clusters->seedCellID[cluster_order[i]];
538  for (int j = 0; j < NumSamplings; ++j)
539  {
540  moments->energyPerSample[j][i] = temp_moments->energyPerSample[j][cluster_order[i]];
541  moments->maxEPerSample[j][i] = temp_moments->maxEPerSample[j][cluster_order[i]];
542  moments->maxPhiPerSample[j][i] = temp_moments->maxPhiPerSample[j][cluster_order[i]];
543  moments->maxEtaPerSample[j][i] = temp_moments->maxEtaPerSample[j][cluster_order[i]];
544  moments->etaPerSample[j][i] = temp_moments->etaPerSample[j][cluster_order[i]];
545  moments->phiPerSample[j][i] = temp_moments->phiPerSample[j][cluster_order[i]];
546  }
547  moments->time[i] = temp_moments->time[cluster_order[i]];
548  moments->firstPhi[i] = temp_moments->firstPhi[cluster_order[i]];
549  moments->firstEta[i] = temp_moments->firstEta[cluster_order[i]];
550  moments->secondR[i] = temp_moments->secondR[cluster_order[i]];
551  moments->secondLambda[i] = temp_moments->secondLambda[cluster_order[i]];
552  moments->deltaPhi[i] = temp_moments->deltaPhi[cluster_order[i]];
553  moments->deltaTheta[i] = temp_moments->deltaTheta[cluster_order[i]];
554  moments->deltaAlpha[i] = temp_moments->deltaAlpha[cluster_order[i]];
555  moments->centerX[i] = temp_moments->centerX[cluster_order[i]];
556  moments->centerY[i] = temp_moments->centerY[cluster_order[i]];
557  moments->centerZ[i] = temp_moments->centerZ[cluster_order[i]];
558  moments->centerMag[i] = temp_moments->centerMag[cluster_order[i]];
559  moments->centerLambda[i] = temp_moments->centerLambda[cluster_order[i]];
560  moments->lateral[i] = temp_moments->lateral[cluster_order[i]];
561  moments->longitudinal[i] = temp_moments->longitudinal[cluster_order[i]];
562  moments->engFracEM[i] = temp_moments->engFracEM[cluster_order[i]];
563  moments->engFracMax[i] = temp_moments->engFracMax[cluster_order[i]];
564  moments->engFracCore[i] = temp_moments->engFracCore[cluster_order[i]];
565  moments->firstEngDens[i] = temp_moments->firstEngDens[cluster_order[i]];
566  moments->secondEngDens[i] = temp_moments->secondEngDens[cluster_order[i]];
567  moments->isolation[i] = temp_moments->isolation[cluster_order[i]];
568  moments->engBadCells[i] = temp_moments->engBadCells[cluster_order[i]];
569  moments->nBadCells[i] = temp_moments->nBadCells[cluster_order[i]];
570  moments->nBadCellsCorr[i] = temp_moments->nBadCellsCorr[cluster_order[i]];
571  moments->badCellsCorrE[i] = temp_moments->badCellsCorrE[cluster_order[i]];
572  moments->badLArQFrac[i] = temp_moments->badLArQFrac[cluster_order[i]];
573  moments->engPos[i] = temp_moments->engPos[cluster_order[i]];
574  moments->significance[i] = temp_moments->significance[cluster_order[i]];
575  moments->cellSignificance[i] = temp_moments->cellSignificance[cluster_order[i]];
576  moments->cellSigSampling[i] = temp_moments->cellSigSampling[cluster_order[i]];
577  moments->avgLArQ[i] = temp_moments->avgLArQ[cluster_order[i]];
578  moments->avgTileQ[i] = temp_moments->avgTileQ[cluster_order[i]];
579  moments->engBadHVCells[i] = temp_moments->engBadHVCells[cluster_order[i]];
580  moments->nBadHVCells[i] = temp_moments->nBadHVCells[cluster_order[i]];
581  moments->PTD[i] = temp_moments->PTD[cluster_order[i]];
582  moments->mass[i] = temp_moments->mass[cluster_order[i]];
583  moments->EMProbability[i] = temp_moments->EMProbability[cluster_order[i]];
584  moments->hadWeight[i] = temp_moments->hadWeight[cluster_order[i]];
585  moments->OOCweight[i] = temp_moments->OOCweight[cluster_order[i]];
586  moments->DMweight[i] = temp_moments->DMweight[cluster_order[i]];
587  moments->tileConfidenceLevel[i] = temp_moments->tileConfidenceLevel[cluster_order[i]];
588  moments->secondTime[i] = temp_moments->secondTime[cluster_order[i]];
589  for (int j = 0; j < NumSamplings; ++j)
590  {
591  moments->nCellSampling[j][i] = temp_moments->nCellSampling[j][cluster_order[i]];
592  }
593  moments->nExtraCellSampling[i] = temp_moments->nExtraCellSampling[cluster_order[i]];
594  moments->numCells[i] = temp_moments->numCells[cluster_order[i]];
595  moments->vertexFraction[i] = temp_moments->vertexFraction[cluster_order[i]];
596  moments->nVertexFraction[i] = temp_moments->nVertexFraction[cluster_order[i]];
597  moments->etaCaloFrame[i] = temp_moments->etaCaloFrame[cluster_order[i]];
598  moments->phiCaloFrame[i] = temp_moments->phiCaloFrame[cluster_order[i]];
599  moments->eta1CaloFrame[i] = temp_moments->eta1CaloFrame[cluster_order[i]];
600  moments->phi1CaloFrame[i] = temp_moments->phi1CaloFrame[cluster_order[i]];
601  moments->eta2CaloFrame[i] = temp_moments->eta2CaloFrame[cluster_order[i]];
602  moments->phi2CaloFrame[i] = temp_moments->phi2CaloFrame[cluster_order[i]];
603  moments->engCalibTot[i] = temp_moments->engCalibTot[cluster_order[i]];
604  moments->engCalibOutL[i] = temp_moments->engCalibOutL[cluster_order[i]];
605  moments->engCalibOutM[i] = temp_moments->engCalibOutM[cluster_order[i]];
606  moments->engCalibOutT[i] = temp_moments->engCalibOutT[cluster_order[i]];
607  moments->engCalibDeadL[i] = temp_moments->engCalibDeadL[cluster_order[i]];
608  moments->engCalibDeadM[i] = temp_moments->engCalibDeadM[cluster_order[i]];
609  moments->engCalibDeadT[i] = temp_moments->engCalibDeadT[cluster_order[i]];
610  moments->engCalibEMB0[i] = temp_moments->engCalibEMB0[cluster_order[i]];
611  moments->engCalibEME0[i] = temp_moments->engCalibEME0[cluster_order[i]];
612  moments->engCalibTileG3[i] = temp_moments->engCalibTileG3[cluster_order[i]];
613  moments->engCalibDeadTot[i] = temp_moments->engCalibDeadTot[cluster_order[i]];
614  moments->engCalibDeadEMB0[i] = temp_moments->engCalibDeadEMB0[cluster_order[i]];
615  moments->engCalibDeadTile0[i] = temp_moments->engCalibDeadTile0[cluster_order[i]];
616  moments->engCalibDeadTileG3[i] = temp_moments->engCalibDeadTileG3[cluster_order[i]];
617  moments->engCalibDeadEME0[i] = temp_moments->engCalibDeadEME0[cluster_order[i]];
618  moments->engCalibDeadHEC0[i] = temp_moments->engCalibDeadHEC0[cluster_order[i]];
619  moments->engCalibDeadFCAL[i] = temp_moments->engCalibDeadFCAL[cluster_order[i]];
620  moments->engCalibDeadLeakage[i] = temp_moments->engCalibDeadLeakage[cluster_order[i]];
621  moments->engCalibDeadUnclass[i] = temp_moments->engCalibDeadUnclass[cluster_order[i]];
622  moments->engCalibFracEM[i] = temp_moments->engCalibFracEM[cluster_order[i]];
623  moments->engCalibFracHad[i] = temp_moments->engCalibFracHad[cluster_order[i]];
624  moments->engCalibFracRest[i] = temp_moments->engCalibFracRest[cluster_order[i]];
625  }
626 
627  for (int i = 0; i < NCaloCells; ++i)
628  {
629  if (!cell_info->is_valid(i))
630  {
631  continue;
632  }
633  const ClusterTag this_tag = cell_state->clusterTag[i];
634  if (!this_tag.is_part_of_cluster())
635  {
636  cell_state->clusterTag[i] = ClusterTag::make_invalid_tag();
637  }
638  else if (this_tag.is_part_of_cluster())
639  {
640  const int old_idx = this_tag.cluster_index();
641  const int new_idx = tag_map[old_idx];
642  const int old_idx2 = this_tag.is_shared_between_clusters() ? this_tag.secondary_cluster_index() : -1;
643  const int new_idx2 = old_idx2 >= 0 ? tag_map[old_idx2] : -1;
644  if (new_idx < 0 && new_idx2 < 0)
645  {
646  cell_state->clusterTag[i] = ClusterTag::make_invalid_tag();
647  }
648  else if (new_idx < 0)
649  {
650  cell_state->clusterTag[i] = ClusterTag::make_tag(new_idx2);
651  }
652  else if (new_idx2 < 0)
653  {
654  cell_state->clusterTag[i] = ClusterTag::make_tag(new_idx);
655  }
656  else
657  {
658  cell_state->clusterTag[i] = ClusterTag::make_tag(new_idx, this_tag.secondary_cluster_weight(), new_idx2);
659  }
660  }
661  }
662 
663  return StatusCode::SUCCESS;
664 }
665 
666 namespace
667 {
668  template <class ... Args>
669  struct multi_class_holder
670  {
671  static constexpr size_t size()
672  {
673  return sizeof...(Args);
674  }
675  };
676 
677  //To deal with potential lack of maybe_unused in pack expansions.
678  template <class Arg>
679  static constexpr decltype(auto) suppress_warning(Arg && a)
680  {
681  return std::forward<Arg>(a);
682  }
683 
684  template <class F, class ... Types, class ... Args>
685  void apply_to_multi_class(F && f, const multi_class_holder<Types...> &, Args && ... args)
686  {
687  size_t i = 0;
688  if constexpr (std::is_same_v < decltype(f((Types{}, ...), i, std::forward<Args>(args)...)), void > )
689  {
690  (f(Types{}, i++, std::forward<Args>(args)...), ...);
691  }
692  else
693  {
694  (suppress_warning(f(Types{}, i++, std::forward<Args>(args)...)), ...);
695  }
696  }
697 
698  static float float_unhack(const unsigned int bits)
699  {
700  float res;
701  std::memcpy(&res, &bits, sizeof(float));
702  //In C++20, we should bit-cast. For now, for our platform, works.
703  return res;
704  }
705 
706  static double protect_from_zero(const double x)
707  {
708  return x == 0 ? 1e-15 : x;
709  }
710 
711  static float protect_from_zero(const float x)
712  {
713  return x == 0 ? 1e-7 : x;
714  }
715 }
716 
718  const CaloRecGPU::ConstantDataHolder & constant_data,
719  const CaloRecGPU::CellInfoArr & cell_info,
720  const CaloRecGPU::CellStateArr & cell_state_1,
721  const CaloRecGPU::CellStateArr & cell_state_2,
722  const CaloRecGPU::ClusterInfoArr & cluster_info_1,
723  const CaloRecGPU::ClusterInfoArr & cluster_info_2,
724  const CaloRecGPU::ClusterMomentsArr & /*moments_1*/,
725  const CaloRecGPU::ClusterMomentsArr & /*moments_2*/,
726  const bool match_in_energy,
727  const bool match_without_shared) const
728 {
729  sch.r2t_table.clear();
730  sch.r2t_table.resize(cluster_info_1.number, -1);
731 
732  sch.t2r_table.clear();
733  sch.t2r_table.resize(cluster_info_2.number, -1);
734 
735  std::vector<double> similarity_map(cluster_info_1.number * cluster_info_2.number, 0.);
736 
737  std::vector<double> ref_normalization(cluster_info_1.number, 0.);
738  std::vector<double> test_normalization(cluster_info_2.number, 0.);
739 
740  for (int i = 0; i < NCaloCells; ++i)
741  {
742  const ClusterTag ref_tag = cell_state_1.clusterTag[i];
743  const ClusterTag test_tag = cell_state_2.clusterTag[i];
744 
745  if (!cell_info.is_valid(i))
746  {
747  continue;
748  }
749 
750  double SNR = 0.00001;
751 
752  if (!cell_info.is_bad(*(constant_data.m_geometry), i))
753  {
754  const int gain = cell_info.gain[i];
755 
756  const double cellNoise = constant_data.m_cell_noise->get_noise(i, gain);
757  if (std::isfinite(cellNoise) && cellNoise > 0.0f)
758  {
759  SNR = std::abs(cell_info.energy[i] / cellNoise);
760  }
761  }
762 
763  const double quantity = ( match_in_energy ? std::abs(cell_info.energy[i]) : SNR );
764  const double weight = (quantity + 1e-8) *
765  ( SNR > m_seedThreshold ? (match_in_energy ? 1000 : m_seed_weight) :
766  (
767  SNR > m_growThreshold ? (match_in_energy ? 950 : m_grow_weight) :
768  (
769  SNR > m_termThreshold ? (match_in_energy ? 900 : m_terminal_weight) : (match_in_energy ? 100 : 0)
770  )
771  )
772  );
773  int ref_c1 = -1, ref_c2 = -1, test_c1 = -1, test_c2 = -1;
774 
775  if (ref_tag.is_part_of_cluster())
776  {
777  if (match_without_shared && ref_tag.is_shared_between_clusters())
778  {
779  continue;
780  }
781  ref_c1 = ref_tag.cluster_index();
782  ref_c2 = ref_tag.is_shared_between_clusters() ? ref_tag.secondary_cluster_index() : ref_c1;
783  }
784 
785  if (test_tag.is_part_of_cluster())
786  {
787  if (match_without_shared && test_tag.is_shared_between_clusters())
788  {
789  continue;
790  }
791  test_c1 = test_tag.cluster_index();
792  test_c2 = test_tag.is_shared_between_clusters() ? test_tag.secondary_cluster_index() : test_c1;
793  }
794 
795  float ref_rev_cw = float_unhack(ref_tag.secondary_cluster_weight());
796  float test_rev_cw = float_unhack(test_tag.secondary_cluster_weight());
797 
798  float ref_cw = 1.0f - ref_rev_cw;
799  float test_cw = 1.0f - test_rev_cw;
800 
801  if (ref_c1 >= int(cluster_info_1.number) || ref_c2 >= int(cluster_info_1.number) ||
802  test_c1 >= int(cluster_info_2.number) || test_c2 >= int(cluster_info_2.number) )
803  {
804  ATH_MSG_DEBUG( "Error in matches: " << i << " " << ref_c1 << " " << ref_c2 << " "
805  << test_c1 << " " << test_c2 << " ("
806  << cluster_info_1.number << " | " << cluster_info_2.number << ")" );
807  continue;
808  }
809 
810  if (ref_c1 >= 0 && test_c1 >= 0)
811  {
812  similarity_map[test_c1 * cluster_info_1.number + ref_c1] += weight * ref_cw * test_cw;
813  similarity_map[test_c1 * cluster_info_1.number + ref_c2] += weight * ref_rev_cw * test_cw;
814  similarity_map[test_c2 * cluster_info_1.number + ref_c1] += weight * ref_cw * test_rev_cw;
815  similarity_map[test_c2 * cluster_info_1.number + ref_c2] += weight * ref_rev_cw * test_rev_cw;
816  }
817  if (ref_c1 >= 0)
818  {
819  ref_normalization[ref_c1] += weight * ref_cw * ref_cw;
820  ref_normalization[ref_c2] += weight * ref_rev_cw * ref_rev_cw;
821  }
822  if (test_c1 >= 0)
823  {
824  test_normalization[test_c1] += weight * test_cw * test_cw;
825  test_normalization[test_c2] += weight * test_rev_cw * test_rev_cw;
826  }
827  }
828 
829  for (int testc = 0; testc < cluster_info_2.number; ++testc)
830  {
831  const double test_norm = test_normalization[testc] + double(test_normalization[testc] == 0.);
832  for (int refc = 0; refc < cluster_info_1.number; ++refc)
833  {
834  const double ref_norm = ref_normalization[refc] + double(ref_normalization[refc] == 0.);
835  similarity_map[testc * cluster_info_1.number + refc] /= std::sqrt(ref_norm * test_norm);
836  }
837  }
838 
839  //In essence, the Gale-Shapley Algorithm
840 
841  std::vector<std::vector<int>> sorted_GPU_matches;
842 
843  sorted_GPU_matches.reserve(cluster_info_2.number);
844 
845  for (int testc = 0; testc < cluster_info_2.number; ++testc)
846  {
847  std::vector<int> sorter(cluster_info_1.number);
848  std::iota(sorter.begin(), sorter.end(), 0);
849 
850  std::sort(sorter.begin(), sorter.end(),
851  [&](const int a, const int b)
852  {
853  const double a_weight = similarity_map[testc * cluster_info_1.number + a];
854  const double b_weight = similarity_map[testc * cluster_info_1.number + b];
855  return a_weight > b_weight;
856  }
857  );
858 
859  size_t wanted_size = 0;
860 
861  for (; wanted_size < sorter.size(); ++wanted_size)
862  {
863  const double match_weight = similarity_map[testc * cluster_info_1.number + sorter[wanted_size]];
864  if (match_weight < m_min_similarity)
865  {
866  break;
867  }
868  }
869 
870  //Yeah, we could do a binary search for best worst-case complexity,
871  //but we are expecting 1~2 similar clusters and the rest garbage,
872  //so we're expecting only 1~2 iterations.
873  //This actually means all that sorting is way way overkill,
874  //but we must make sure in the most general case that this works...
875 
876  sorter.resize(wanted_size);
877 
878  sorted_GPU_matches.push_back(sorter);
879  }
880 
881  int num_iter = 0;
882 
883  constexpr int max_iter = 32;
884 
885  std::vector<double> matched_weights(cluster_info_1.number, -1.);
886 
887  std::vector<size_t> skipped_matching(cluster_info_2.number, 0);
888 
889  for (int stop_counter = 0; stop_counter < cluster_info_2.number && num_iter < max_iter; ++num_iter)
890  {
891  stop_counter = 0;
892  for (int testc = 0; testc < int(sorted_GPU_matches.size()); ++testc)
893  {
894  if (skipped_matching[testc] < sorted_GPU_matches[testc].size())
895  {
896  const int match_c = sorted_GPU_matches[testc][skipped_matching[testc]];
897  const double match_weight = similarity_map[testc * cluster_info_1.number + match_c];
898  if (match_weight >= m_min_similarity && match_weight > matched_weights[match_c])
899  {
900  const int prev_match = sch.r2t_table[match_c];
901  if (prev_match >= 0)
902  {
903  ++skipped_matching[prev_match];
904  --stop_counter;
905  }
906  sch.r2t_table[match_c] = testc;
907  matched_weights[match_c] = match_weight;
908  ++stop_counter;
909  }
910  else
911  {
912  ++skipped_matching[testc];
913  }
914  }
915  else
916  {
917  ++stop_counter;
918  }
919  }
920  }
921 
922  sch.unmatched_ref_list.clear();
923  sch.unmatched_test_list.clear();
924 
925  for (size_t i = 0; i < sch.r2t_table.size(); ++i)
926  {
927  const int match = sch.r2t_table[i];
928  if (match < 0)
929  {
930  sch.unmatched_ref_list.push_back(i);
931  }
932  else
933  {
934  sch.t2r_table[match] = i;
935  }
936  }
937 
938  for (size_t i = 0; i < sch.t2r_table.size(); ++i)
939  {
940  if (sch.t2r_table[i] < 0)
941  {
942  sch.unmatched_test_list.push_back(i);
943  }
944  }
945 
946  {
947  char message_buffer[256];
948  snprintf(message_buffer, 256,
949  "%2d: %5d / %5d || %5d / %5d || %3d || %5d | %5d || %5d",
950  num_iter,
951  int(sch.r2t_table.size()) - int(sch.unmatched_ref_list.size()), int(sch.r2t_table.size()),
952  int(sch.t2r_table.size()) - int(sch.unmatched_test_list.size()), int(sch.t2r_table.size()),
953  int(sch.r2t_table.size()) - int(sch.t2r_table.size()),
954  int(sch.unmatched_ref_list.size()),
955  int(sch.unmatched_test_list.size()),
956  int(sch.unmatched_ref_list.size()) - int(sch.unmatched_test_list.size())
957  );
958  ATH_MSG_INFO(message_buffer);
959  }
960 
961  return StatusCode::SUCCESS;
962 
963 }
964 
966  const CaloRecGPU::ConstantDataHolder & /*constant_data*/,
967  const CaloRecGPU::CellInfoArr & cell_info,
968  const CaloRecGPU::CellStateArr & cell_state_1,
969  const CaloRecGPU::CellStateArr & cell_state_2,
970  const CaloRecGPU::ClusterInfoArr & cluster_info_1,
971  const CaloRecGPU::ClusterInfoArr & cluster_info_2,
972  const CaloRecGPU::ClusterMomentsArr & /*moments_1*/,
973  const CaloRecGPU::ClusterMomentsArr & /*moments_2*/,
974  const bool match_without_shared) const
975 {
976  sch.r2t_table.clear();
977  sch.r2t_table.resize(cluster_info_1.number, -1);
978 
979  sch.t2r_table.clear();
980  sch.t2r_table.resize(cluster_info_2.number, -1);
981 
982  std::vector<char> match_possibilities(cluster_info_1.number * cluster_info_2.number, 1);
983 
984  for (int i = 0; i < NCaloCells; ++i)
985  {
986  const ClusterTag ref_tag = cell_state_1.clusterTag[i];
987  const ClusterTag test_tag = cell_state_2.clusterTag[i];
988 
989  if (!cell_info.is_valid(i))
990  {
991  continue;
992  }
993 
994  int ref_c1 = -1, ref_c2 = -1, test_c1 = -1, test_c2 = -1;
995 
996  if (ref_tag.is_part_of_cluster())
997  {
998  if (match_without_shared && ref_tag.is_shared_between_clusters())
999  {
1000  continue;
1001  }
1002  ref_c1 = ref_tag.cluster_index();
1003  ref_c2 = ref_tag.is_shared_between_clusters() ? ref_tag.secondary_cluster_index() : -1;
1004  }
1005 
1006  if (test_tag.is_part_of_cluster())
1007  {
1008  if (match_without_shared && test_tag.is_shared_between_clusters())
1009  {
1010  continue;
1011  }
1012  test_c1 = test_tag.cluster_index();
1013  test_c2 = test_tag.is_shared_between_clusters() ? test_tag.secondary_cluster_index() : -1;
1014  }
1015 
1016  for (int refc = 0; refc < cluster_info_1.number; ++refc)
1017  {
1018  if (refc == ref_c1 || refc == ref_c2)
1019  {
1020  continue;
1021  }
1022 
1023  if (test_c1 >= 0)
1024  {
1025  match_possibilities[test_c1 * cluster_info_1.number + refc] = 0;
1026  }
1027  if (test_c2 >= 0)
1028  {
1029  match_possibilities[test_c2 * cluster_info_1.number + refc] = 0;
1030  }
1031  }
1032 
1033  for (int testc = 0; testc < cluster_info_2.number; ++testc)
1034  {
1035  if (testc == test_c1 || testc == test_c2)
1036  {
1037  continue;
1038  }
1039 
1040  if (ref_c1 >= 0)
1041  {
1042  match_possibilities[testc * cluster_info_1.number + ref_c1] = 0;
1043  }
1044  if (ref_c2 >= 0)
1045  {
1046  match_possibilities[testc * cluster_info_1.number + ref_c2] = 0;
1047  }
1048  }
1049 
1050  }
1051 
1052  for (int testc = 0; testc < cluster_info_2.number; ++testc)
1053  {
1054  for (int refc = 0; refc < cluster_info_1.number; ++refc)
1055  {
1056  if (match_possibilities[testc * cluster_info_1.number + refc] > 0)
1057  {
1058  sch.r2t_table[refc] = testc;
1059  sch.t2r_table[testc] = refc;
1060  }
1061  }
1062  }
1063 
1064  for (int refc = 0; refc < cluster_info_1.number; ++refc)
1065  {
1066  if (sch.r2t_table[refc] < 0)
1067  {
1068  sch.unmatched_ref_list.push_back(refc);
1069  }
1070  }
1071 
1072  for (int testc = 0; testc < cluster_info_2.number; ++testc)
1073  {
1074  if (sch.t2r_table[testc] < 0)
1075  {
1076  sch.unmatched_test_list.push_back(testc);
1077  }
1078  }
1079 
1080  {
1081  char message_buffer[256];
1082  snprintf(message_buffer, 256,
1083  "%2d: %5d / %5d || %5d / %5d || %3d || %5d | %5d || %5d",
1084  0,
1085  int(sch.r2t_table.size()) - int(sch.unmatched_ref_list.size()), int(sch.r2t_table.size()),
1086  int(sch.t2r_table.size()) - int(sch.unmatched_test_list.size()), int(sch.t2r_table.size()),
1087  int(sch.r2t_table.size()) - int(sch.t2r_table.size()),
1088  int(sch.unmatched_ref_list.size()),
1089  int(sch.unmatched_test_list.size()),
1090  int(sch.unmatched_ref_list.size()) - int(sch.unmatched_test_list.size())
1091  );
1092  ATH_MSG_INFO(message_buffer);
1093  }
1094 
1095  return StatusCode::SUCCESS;
1096 
1097 }
1098 
1099 namespace
1100 {
1101 
1103  {
1104 #define CALORECGPU_BASIC_CLUSTER_PROPERTY(NAME, ...) \
1105  struct clusters_ ## NAME \
1106  { \
1107  static std::string name() \
1108  { \
1109  return # NAME; \
1110  } \
1111  static double get_property([[maybe_unused]] const ConstantDataHolder & constant_data, \
1112  [[maybe_unused]] const CaloRecGPU::CellInfoArr & cell_info, \
1113  [[maybe_unused]] const CaloRecGPU::CellStateArr & cell_state, \
1114  [[maybe_unused]] const CaloRecGPU::ClusterInfoArr & cluster_info, \
1115  [[maybe_unused]] const CaloRecGPU::ClusterMomentsArr & cluster_moments, \
1116  [[maybe_unused]] const int cluster_index ) \
1117  { \
1118  __VA_ARGS__ \
1119  } \
1120  };
1121 
1122  CALORECGPU_BASIC_CLUSTER_PROPERTY(E, return cluster_info.clusterEnergy[cluster_index] / CLHEP::MeV;)
1123 
1124  CALORECGPU_BASIC_CLUSTER_PROPERTY(abs_E, return std::abs(cluster_info.clusterEnergy[cluster_index]) / CLHEP::MeV;)
1125 
1126  CALORECGPU_BASIC_CLUSTER_PROPERTY(Et, return cluster_info.clusterEt[cluster_index] / CLHEP::MeV;)
1127 
1128  CALORECGPU_BASIC_CLUSTER_PROPERTY(eta, return cluster_info.clusterEta[cluster_index];)
1129 
1130  CALORECGPU_BASIC_CLUSTER_PROPERTY(phi, return cluster_info.clusterPhi[cluster_index];)
1131 
1132  //CALORECGPU_BASIC_CLUSTER_PROPERTY(time, return cluster_moments.time[cluster_index] / CLHEP::us;)
1133 
1134 #define CALORECGPU_CLUSTER_MOMENT(...) CALORECGPU_CLUSTER_MOMENT_INNER(__VA_ARGS__, 1, 1)
1135 #define CALORECGPU_CLUSTER_MOMENT_INNER(NAME, PROPERTY, UNIT, ...) CALORECGPU_BASIC_CLUSTER_PROPERTY(moments_ ## NAME, return cluster_moments . PROPERTY [cluster_index] / UNIT;)
1137  CALORECGPU_CLUSTER_MOMENT(time, time, CLHEP::us)
1138  CALORECGPU_CLUSTER_MOMENT(FIRST_PHI, firstPhi)
1139  CALORECGPU_CLUSTER_MOMENT(FIRST_ETA, firstEta)
1143  CALORECGPU_CLUSTER_MOMENT(DELTA_THETA, deltaTheta)
1144  CALORECGPU_CLUSTER_MOMENT(DELTA_ALPHA, deltaAlpha)
1145  CALORECGPU_CLUSTER_MOMENT(CENTER_X, centerX)
1146  CALORECGPU_CLUSTER_MOMENT(CENTER_Y, centerY)
1147  CALORECGPU_CLUSTER_MOMENT(CENTER_Z, centerZ)
1150  CALORECGPU_CLUSTER_MOMENT(LATERAL, lateral)
1151  CALORECGPU_CLUSTER_MOMENT(LONGITUDINAL, longitudinal)
1152  CALORECGPU_CLUSTER_MOMENT(ENG_FRAC_EM, engFracEM)
1153  CALORECGPU_CLUSTER_MOMENT(ENG_FRAC_MAX, engFracMax)
1154  CALORECGPU_CLUSTER_MOMENT(ENG_FRAC_CORE, engFracCore)
1156  CALORECGPU_CLUSTER_MOMENT(SECOND_ENG_DENS, secondEngDens)
1158  CALORECGPU_CLUSTER_MOMENT(ENG_BAD_CELLS, engBadCells)
1159  CALORECGPU_CLUSTER_MOMENT(N_BAD_CELLS, nBadCells)
1160  CALORECGPU_CLUSTER_MOMENT(N_BAD_CELLS_CORR, nBadCellsCorr)
1161  CALORECGPU_CLUSTER_MOMENT(BAD_CELLS_CORR_E, badCellsCorrE)
1162  CALORECGPU_CLUSTER_MOMENT(BADLARQ_FRAC, badLArQFrac)
1163  CALORECGPU_CLUSTER_MOMENT(ENG_POS, engPos)
1164  CALORECGPU_CLUSTER_MOMENT(SIGNIFICANCE, significance)
1165  CALORECGPU_CLUSTER_MOMENT(CELL_SIGNIFICANCE, cellSignificance)
1166  CALORECGPU_CLUSTER_MOMENT(CELL_SIG_SAMPLING, cellSigSampling)
1167  CALORECGPU_CLUSTER_MOMENT(AVG_LAR_Q, avgLArQ)
1168  CALORECGPU_CLUSTER_MOMENT(AVG_TILE_Q, avgTileQ)
1169  CALORECGPU_CLUSTER_MOMENT(ENG_BAD_HV_CELLS, engBadHVCells)
1170  CALORECGPU_CLUSTER_MOMENT(N_BAD_HV_CELLS, nBadHVCells)
1171  CALORECGPU_CLUSTER_MOMENT(PTD, PTD)
1174  CALORECGPU_CLUSTER_MOMENT(HAD_WEIGHT, hadWeight)
1175  CALORECGPU_CLUSTER_MOMENT(OOC_WEIGHT, OOCweight)
1176  CALORECGPU_CLUSTER_MOMENT(DM_WEIGHT, DMweight)
1177  CALORECGPU_CLUSTER_MOMENT(TILE_CONFIDENCE_LEVEL, tileConfidenceLevel)
1178  CALORECGPU_CLUSTER_MOMENT(SECOND_TIME, secondTime)
1179  CALORECGPU_CLUSTER_MOMENT(number_of_cells, numCells)
1180  CALORECGPU_CLUSTER_MOMENT(VERTEX_FRACTION, vertexFraction)
1181  CALORECGPU_CLUSTER_MOMENT(NVERTEX_FRACTION, nVertexFraction)
1182  CALORECGPU_CLUSTER_MOMENT(ETACALOFRAME, etaCaloFrame)
1183  CALORECGPU_CLUSTER_MOMENT(PHICALOFRAME, phiCaloFrame)
1184  CALORECGPU_CLUSTER_MOMENT(ETA1CALOFRAME, eta1CaloFrame)
1185  CALORECGPU_CLUSTER_MOMENT(PHI1CALOFRAME, phi1CaloFrame)
1186  CALORECGPU_CLUSTER_MOMENT(ETA2CALOFRAME, eta2CaloFrame)
1187  CALORECGPU_CLUSTER_MOMENT(PHI2CALOFRAME, phi2CaloFrame)
1188  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_TOT, engCalibTot)
1189  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_OUT_L, engCalibOutL)
1190  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_OUT_M, engCalibOutM)
1191  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_OUT_T, engCalibOutT)
1192  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_DEAD_L, engCalibDeadL)
1193  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_DEAD_M, engCalibDeadM)
1194  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_DEAD_T, engCalibDeadT)
1195  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_EMB0, engCalibEMB0)
1196  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_EME0, engCalibEME0)
1197  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_TILEG3, engCalibTileG3)
1198  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_DEAD_TOT, engCalibDeadTot)
1199  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_DEAD_EMB0, engCalibDeadEMB0)
1200  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_DEAD_TILE0, engCalibDeadTile0)
1201  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_DEAD_TILEG3, engCalibDeadTileG3)
1202  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_DEAD_EME0, engCalibDeadEME0)
1203  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_DEAD_HEC0, engCalibDeadHEC0)
1204  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_DEAD_FCAL, engCalibDeadFCAL)
1205  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_DEAD_LEAKAGE, engCalibDeadLeakage)
1206  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_DEAD_UNCLASS, engCalibDeadUnclass)
1207  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_FRAC_EM, engCalibFracEM)
1208  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_FRAC_HAD, engCalibFracHad)
1209  CALORECGPU_CLUSTER_MOMENT(ENG_CALIB_FRAC_REST, engCalibFracRest)
1210 
1211  using BasicClusterProperties = multi_class_holder <
1212 
1213  clusters_E,
1214  clusters_abs_E,
1215  clusters_Et,
1216  clusters_eta,
1217  clusters_phi,
1218  clusters_moments_time,
1219  clusters_moments_FIRST_PHI,
1220  clusters_moments_FIRST_ETA,
1221  clusters_moments_SECOND_R,
1222  clusters_moments_SECOND_LAMBDA,
1223  clusters_moments_DELTA_PHI,
1224  clusters_moments_DELTA_THETA,
1225  clusters_moments_DELTA_ALPHA,
1226  clusters_moments_CENTER_X,
1227  clusters_moments_CENTER_Y,
1228  clusters_moments_CENTER_Z,
1229  clusters_moments_CENTER_MAG,
1230  clusters_moments_CENTER_LAMBDA,
1231  clusters_moments_LATERAL,
1232  clusters_moments_LONGITUDINAL,
1233  clusters_moments_ENG_FRAC_EM,
1234  clusters_moments_ENG_FRAC_MAX,
1235  clusters_moments_ENG_FRAC_CORE,
1236  clusters_moments_FIRST_ENG_DENS,
1237  clusters_moments_SECOND_ENG_DENS,
1238  clusters_moments_ISOLATION,
1239  clusters_moments_ENG_BAD_CELLS,
1240  clusters_moments_N_BAD_CELLS,
1241  clusters_moments_N_BAD_CELLS_CORR,
1242  clusters_moments_BAD_CELLS_CORR_E,
1243  clusters_moments_BADLARQ_FRAC,
1244  clusters_moments_ENG_POS,
1245  clusters_moments_SIGNIFICANCE,
1246  clusters_moments_CELL_SIGNIFICANCE,
1247  clusters_moments_CELL_SIG_SAMPLING,
1248  clusters_moments_AVG_LAR_Q,
1249  clusters_moments_AVG_TILE_Q,
1250  clusters_moments_ENG_BAD_HV_CELLS,
1251  clusters_moments_N_BAD_HV_CELLS,
1252  clusters_moments_PTD,
1253  clusters_moments_MASS,
1254  clusters_moments_EM_PROBABILITY,
1255  clusters_moments_HAD_WEIGHT,
1256  clusters_moments_OOC_WEIGHT,
1257  clusters_moments_DM_WEIGHT,
1258  clusters_moments_TILE_CONFIDENCE_LEVEL,
1259  clusters_moments_SECOND_TIME,
1260  clusters_moments_number_of_cells,
1261  clusters_moments_VERTEX_FRACTION,
1262  clusters_moments_NVERTEX_FRACTION,
1263  clusters_moments_ETACALOFRAME,
1264  clusters_moments_PHICALOFRAME,
1265  clusters_moments_ETA1CALOFRAME,
1266  clusters_moments_PHI1CALOFRAME,
1267  clusters_moments_ETA2CALOFRAME,
1268  clusters_moments_PHI2CALOFRAME,
1269  clusters_moments_ENG_CALIB_TOT,
1270  clusters_moments_ENG_CALIB_OUT_L,
1271  clusters_moments_ENG_CALIB_OUT_M,
1272  clusters_moments_ENG_CALIB_OUT_T,
1273  clusters_moments_ENG_CALIB_DEAD_L,
1274  clusters_moments_ENG_CALIB_DEAD_M,
1275  clusters_moments_ENG_CALIB_DEAD_T,
1276  clusters_moments_ENG_CALIB_EMB0,
1277  clusters_moments_ENG_CALIB_EME0,
1278  clusters_moments_ENG_CALIB_TILEG3,
1279  clusters_moments_ENG_CALIB_DEAD_TOT,
1280  clusters_moments_ENG_CALIB_DEAD_EMB0,
1281  clusters_moments_ENG_CALIB_DEAD_TILE0,
1282  clusters_moments_ENG_CALIB_DEAD_TILEG3,
1283  clusters_moments_ENG_CALIB_DEAD_EME0,
1284  clusters_moments_ENG_CALIB_DEAD_HEC0,
1285  clusters_moments_ENG_CALIB_DEAD_FCAL,
1286  clusters_moments_ENG_CALIB_DEAD_LEAKAGE,
1287  clusters_moments_ENG_CALIB_DEAD_UNCLASS,
1288  clusters_moments_ENG_CALIB_FRAC_EM,
1289  clusters_moments_ENG_CALIB_FRAC_HAD,
1290  clusters_moments_ENG_CALIB_FRAC_REST
1291 
1292  >;
1293 
1294  }
1295 
1296  using ClusterProperties::BasicClusterProperties;
1297 
1299  {
1300 #define CALORECGPU_COMPARED_CLUSTER_PROPERTY(NAME, ...) \
1301  struct clusters_ ## NAME \
1302  { \
1303  static std::string name() \
1304  { \
1305  return # NAME; \
1306  } \
1307  static double get_property([[maybe_unused]] const ConstantDataHolder & constant_data, \
1308  [[maybe_unused]] const CaloRecGPU::CellInfoArr & cell_info_1, \
1309  [[maybe_unused]] const CaloRecGPU::CellStateArr & cell_state_1, \
1310  [[maybe_unused]] const CaloRecGPU::ClusterInfoArr & cluster_info_1, \
1311  [[maybe_unused]] const CaloRecGPU::ClusterMomentsArr & cluster_moments_1, \
1312  [[maybe_unused]] const int cluster_index_1, \
1313  [[maybe_unused]] const CaloRecGPU::CellInfoArr & cell_info_2, \
1314  [[maybe_unused]] const CaloRecGPU::CellStateArr & cell_state_2, \
1315  [[maybe_unused]] const CaloRecGPU::ClusterInfoArr & cluster_info_2, \
1316  [[maybe_unused]] const CaloRecGPU::ClusterMomentsArr & cluster_moments_2, \
1317  [[maybe_unused]] const int cluster_index_2) \
1318  { \
1319  __VA_ARGS__ \
1320  } \
1321  };
1322 
1323  CALORECGPU_COMPARED_CLUSTER_PROPERTY(delta_phi_in_range,
1324  return Helpers::regularize_angle( Helpers::regularize_angle(cluster_info_2.clusterPhi[cluster_index_2]) -
1325  Helpers::regularize_angle(cluster_info_1.clusterPhi[cluster_index_1]) );
1326  )
1327 
1329  const double delta_eta = cluster_info_2.clusterEta[cluster_index_2] - cluster_info_1.clusterEta[cluster_index_1];
1330  const double delta_phi = Helpers::regularize_angle( Helpers::regularize_angle(cluster_info_2.clusterPhi[cluster_index_2]) -
1331  Helpers::regularize_angle(cluster_info_1.clusterPhi[cluster_index_1]) );
1332  return std::sqrt(delta_eta * delta_eta + delta_phi * delta_phi);
1333 
1334  )
1335 
1336 
1337  using ComparedClusterProperties = multi_class_holder <
1338 
1339  clusters_delta_phi_in_range,
1340  clusters_delta_R
1341 
1342  >;
1343 
1344  }
1345 
1346  using ExtraClusterComparisons::ComparedClusterProperties;
1347 
1348  namespace CellProperties
1349  {
1350 #define CALORECGPU_BASIC_CELL_PROPERTY(NAME, ...) \
1351  struct cells_ ## NAME \
1352  { \
1353  static std::string name() \
1354  { \
1355  return # NAME; \
1356  } \
1357  static double get_property([[maybe_unused]] const ConstantDataHolder & constant_data, \
1358  [[maybe_unused]] const CaloRecGPU::CellInfoArr & cell_info, \
1359  [[maybe_unused]] const CaloRecGPU::CellStateArr & cell_state, \
1360  [[maybe_unused]] const CaloRecGPU::ClusterInfoArr & cluster_info, \
1361  [[maybe_unused]] const CaloRecGPU::ClusterMomentsArr & cluster_moments, \
1362  [[maybe_unused]] const int cell ) \
1363  { \
1364  __VA_ARGS__ \
1365  } \
1366  };
1367 
1368  CALORECGPU_BASIC_CELL_PROPERTY(E, return cell_info.energy[cell] / CLHEP::MeV;)
1369  CALORECGPU_BASIC_CELL_PROPERTY(abs_E, return std::abs(cell_info.energy[cell]) / CLHEP::MeV; )
1370 
1371  CALORECGPU_BASIC_CELL_PROPERTY(gain, return cell_info.gain[cell];)
1372 
1373  CALORECGPU_BASIC_CELL_PROPERTY(noise, return constant_data.m_cell_noise->get_noise(cell, cell_info.gain[cell]);)
1374 
1375  CALORECGPU_BASIC_CELL_PROPERTY(SNR, return cell_info.energy[cell] /
1376  protect_from_zero(constant_data.m_cell_noise->get_noise(cell, cell_info.gain[cell]));
1377  )
1378 
1379  CALORECGPU_BASIC_CELL_PROPERTY(abs_SNR, return std::abs(cell_info.energy[cell] /
1380  protect_from_zero(constant_data.m_cell_noise->get_noise(cell, cell_info.gain[cell])));)
1381 
1382  CALORECGPU_BASIC_CELL_PROPERTY(time, return cell_info.time[cell] / CLHEP::us;)
1383 
1385 
1386  CALORECGPU_BASIC_CELL_PROPERTY(sampling, return constant_data.m_geometry->sampling(cell);)
1387 
1388 
1389  CALORECGPU_BASIC_CELL_PROPERTY(x, return constant_data.m_geometry->x[cell] / CLHEP::cm; )
1390  CALORECGPU_BASIC_CELL_PROPERTY(y, return constant_data.m_geometry->y[cell] / CLHEP::cm; )
1391  CALORECGPU_BASIC_CELL_PROPERTY(z, return constant_data.m_geometry->z[cell] / CLHEP::cm; )
1392 
1393  CALORECGPU_BASIC_CELL_PROPERTY(phi, return constant_data.m_geometry->phi[cell];)
1394 
1395  CALORECGPU_BASIC_CELL_PROPERTY(eta, return constant_data.m_geometry->eta[cell];)
1396 
1397 
1398  CALORECGPU_BASIC_CELL_PROPERTY(primary_cluster_index, return ClusterTag{cell_state.clusterTag[cell]}.cluster_index(); )
1399 
1400  CALORECGPU_BASIC_CELL_PROPERTY(secondary_cluster_index, return ClusterTag{cell_state.clusterTag[cell]}.secondary_cluster_index(); )
1401 
1402  CALORECGPU_BASIC_CELL_PROPERTY(primary_weight,
1403  {
1404  const ClusterTag tag = cell_state.clusterTag[cell];
1405  if (tag.is_part_of_cluster())
1406  {
1407  float rev_weight = float_unhack(tag.secondary_cluster_weight());
1408  return 1.0f - rev_weight;
1409  }
1410  else
1411  {
1412  return 0.f;
1413  }
1414  }
1415  )
1416 
1417  CALORECGPU_BASIC_CELL_PROPERTY(secondary_weight,
1418  {
1419  const ClusterTag tag = cell_state.clusterTag[cell];
1420  if (tag.is_part_of_cluster())
1421  {
1422  float rev_weight = float_unhack(tag.secondary_cluster_weight());
1423  return rev_weight;
1424  }
1425  else
1426  {
1427  return 0.f;
1428  }
1429  }
1430  )
1431 
1432  using BasicCellProperties = multi_class_holder <
1433 
1434  cells_E,
1435  cells_abs_E,
1436  cells_gain,
1437  cells_noise,
1438  cells_SNR,
1439  cells_abs_SNR,
1440  cells_time,
1441  cells_index,
1442  cells_sampling,
1443  cells_x,
1444  cells_y,
1445  cells_z,
1446  cells_phi,
1447  cells_eta,
1448  cells_primary_cluster_index,
1449  cells_secondary_cluster_index,
1450  cells_primary_weight,
1451  cells_secondary_weight
1452 
1453  >;
1454 
1455  }
1456 
1457  using CellProperties::BasicCellProperties;
1458 
1459  namespace CellTypes
1460  {
1461 #define CALORECGPU_BASIC_CELL_TYPE(NAME, ...) \
1462  struct cell_type_ ## NAME \
1463  { \
1464  static std::string name() \
1465  { \
1466  return # NAME; \
1467  } \
1468  static bool is_type([[maybe_unused]] const ConstantDataHolder & constant_data, \
1469  [[maybe_unused]] const CaloRecGPU::CellInfoArr & cell_info, \
1470  [[maybe_unused]] const CaloRecGPU::CellStateArr & cell_state, \
1471  [[maybe_unused]] const CaloRecGPU::ClusterInfoArr & cluster_info, \
1472  [[maybe_unused]] const CaloRecGPU::ClusterMomentsArr & cluster_moments, \
1473  [[maybe_unused]] const int cell ) \
1474  { \
1475  __VA_ARGS__ \
1476  } \
1477  };
1478 
1479  CALORECGPU_BASIC_CELL_TYPE(intracluster, return ClusterTag{cell_state.clusterTag[cell]}.is_part_of_cluster();)
1480 
1481  CALORECGPU_BASIC_CELL_TYPE(extracluster, return !ClusterTag{cell_state.clusterTag[cell]}.is_part_of_cluster();)
1482 
1484  ClusterTag tag = cell_state.clusterTag[cell];
1485  return tag.is_part_of_cluster() && tag.is_shared_between_clusters(); )
1486 
1487  using BasicCellTypes = multi_class_holder <
1488 
1489  cell_type_intracluster,
1490  cell_type_extracluster,
1491  cell_type_shared
1492 
1493  >;
1494 
1495  }
1496 
1497  using CellTypes::BasicCellTypes;
1498 
1499 
1500  enum ExtraThingsToCalculate
1501  {
1502  ClusterSize = 0,
1503  ClusterComparedSize,
1504  DiffCells,
1505  SameECells,
1506  SameECellsCombined,
1507  SameSNRCells,
1508  SameSNRCellsCombined,
1509  ExtraThingsSize
1510  };
1511 }
1512 
1514 {
1515  const std::vector<std::string> histo_strings = m_moniTool->histogramService()->getHists();
1516  //Small problem: other histograms with matching names.
1517  //Mitigated by the fact that we use cell_<property> and cluster_<property>...
1518 
1524  m_cellTypesToDo.resize(BasicCellTypes::size(), false);
1526  m_extraThingsToDo.resize(ExtraThingsSize, false);
1527 
1528  auto string_contains = [](const std::string & container, const std::string & contained) -> bool
1529  {
1530  return container.find(contained) != std::string::npos;
1531  };
1532 
1533  auto search_lambda = [&](const auto & prop, const size_t count, bool & check,
1534  const std::string & str, std::vector<bool> & to_do,
1535  const std::string & prefix = "", const std::string & suffix = "")
1536  {
1537  if (string_contains(str, prefix + prop.name() + suffix))
1538  {
1539  to_do[count] = true;
1540  check = true;
1541  }
1542  };
1543 
1544  for (const auto & str : histo_strings)
1545  {
1546  bool found = false;
1547 
1548  apply_to_multi_class(search_lambda, BasicCellProperties{}, found, str, m_cellPropertiesToDo, "_cell_");
1549  apply_to_multi_class(search_lambda, BasicCellTypes{}, found, str, m_cellTypesToDo, "_", "_cells");
1550 
1551  if (found)
1552  {
1553  m_doCells = true;
1554  }
1555 
1556  found = false;
1557 
1558  apply_to_multi_class(search_lambda, BasicClusterProperties{}, found, str, m_clusterPropertiesToDo, "_cluster_");
1559 
1560  if (found)
1561  {
1562  m_doClusters = true;
1563  }
1564 
1565  found = false;
1566 
1567  apply_to_multi_class(search_lambda, BasicCellProperties{}, found, str, m_comparedCellPropertiesToDo, "_cell_delta_");
1568  apply_to_multi_class(search_lambda, BasicCellProperties{}, found, str, m_comparedCellPropertiesToDo, "_cell_", "_ref");
1569  apply_to_multi_class(search_lambda, BasicCellProperties{}, found, str, m_comparedCellPropertiesToDo, "_cell_", "_test");
1570  apply_to_multi_class(search_lambda, BasicCellTypes{}, found, str, m_comparedCellTypesToDo, "num_ref_", "_cells");
1571  apply_to_multi_class(search_lambda, BasicCellTypes{}, found, str, m_comparedCellTypesToDo, "num_test_", "_cells");
1572  apply_to_multi_class(search_lambda, BasicCellTypes{}, found, str, m_comparedCellTypesToDo, "delta_", "_cells");
1573 
1574  if (found)
1575  {
1576  m_doCombinedCells = true;
1577  }
1578 
1579  found = false;
1580 
1581  apply_to_multi_class(search_lambda, BasicClusterProperties{}, found, str, m_comparedClusterPropertiesToDo, "_cluster_delta_", "");
1582  apply_to_multi_class(search_lambda, BasicClusterProperties{}, found, str, m_comparedClusterPropertiesToDo, "_cluster_", "_ref");
1583  apply_to_multi_class(search_lambda, BasicClusterProperties{}, found, str, m_comparedClusterPropertiesToDo, "_cluster_", "_test");
1584  apply_to_multi_class(search_lambda, ComparedClusterProperties{}, found, str, m_extraComparedClusterPropertiesToDo);
1585 
1586  if (found)
1587  {
1588  m_doCombinedClusters = true;
1589  }
1590 
1591  if ( string_contains(str, "cluster_size_ref") ||
1592  string_contains(str, "cluster_size_test") ||
1593  string_contains(str, "cluster_delta_size") ||
1594  string_contains(str, "cluster_weighted_size_ref") ||
1595  string_contains(str, "cluster_weighted_size_test") ||
1596  string_contains(str, "cluster_delta_weighted_size") )
1597  {
1598  m_extraThingsToDo[ClusterComparedSize] = true;
1599  m_doCombinedCells = true;
1600  m_doCombinedClusters = true;
1601  }
1602  else if ( string_contains(str, "cluster_size") ||
1603  string_contains(str, "cluster_weighted_size") )
1604  {
1605  m_extraThingsToDo[ClusterSize] = true;
1606  m_doCells = true;
1607  m_doClusters = true;
1608  }
1609 
1610  if (string_contains(str, "cluster_diff_cells"))
1611  {
1612  m_extraThingsToDo[DiffCells] = true;
1613  m_doCombinedCells = true;
1614  m_doCombinedClusters = true;
1615  }
1616 
1617  if ( string_contains(str, "_num_same_E_cells_ref") ||
1618  string_contains(str, "_num_same_E_cells_test") ||
1619  string_contains(str, "delta_num_same_E_cells") ||
1620  string_contains(str, "_num_same_abs_E_cells_ref") ||
1621  string_contains(str, "_num_same_abs_E_cells_test") ||
1622  string_contains(str, "delta_num_same_abs_E_cells") )
1623  {
1624  m_extraThingsToDo[SameECellsCombined] = true;
1625  m_doCombinedCells = true;
1626  }
1627  else if ( string_contains(str, "_num_same_E_cells") ||
1628  string_contains(str, "_num_same_abs_E_cells") )
1629  {
1630  m_extraThingsToDo[SameECells] = true;
1631  m_doCells = true;
1632  }
1633 
1634  if ( string_contains(str, "_num_same_SNR_cells_ref") ||
1635  string_contains(str, "_num_same_SNR_cells_test") ||
1636  string_contains(str, "delta_num_same_SNR_cells") ||
1637  string_contains(str, "_num_same_abs_SNR_cells_ref") ||
1638  string_contains(str, "_num_same_abs_SNR_cells_test") ||
1639  string_contains(str, "delta_num_same_abs_SNR_cells") )
1640  {
1641  m_extraThingsToDo[SameSNRCellsCombined] = true;
1642  m_doCombinedCells = true;
1643  }
1644  else if ( string_contains(str, "_num_same_SNR_cells") ||
1645  string_contains(str, "_num_same_abs_SNR_cells") )
1646  {
1647  m_extraThingsToDo[SameSNRCells] = true;
1648  m_doCells = true;
1649  }
1650  }
1651 
1652  return StatusCode::SUCCESS;
1653 
1654 }
1655 
1656 
1658  const ConstantDataHolder & constant_data,
1663  const std::string & tool_name) const
1664 {
1665  m_numClustersPerTool[tool_name].fetch_add(clusters->number);
1666 
1667  const std::string prefix = m_toolToIdMap.at(tool_name);
1668 
1669  const int index = m_toolsToCheckFor.at(tool_name);
1670 
1671  if (index >= 0 && m_numToolsToKeep > 0)
1672  {
1673  std::vector<per_tool_storage> & store_vec = m_storageHolder.get_for_thread();
1674  store_vec[index].cell_info = *cell_info;
1675  store_vec[index].cell_state = *cell_state;
1676  store_vec[index].clusters = *clusters;
1677  store_vec[index].moments = *moments;
1678  }
1679 
1680  if (prefix != "")
1681  //Tools that are not meant to be plotted individually
1682  //have the empty string as a prefix.
1683  {
1684  std::unordered_map<std::string, std::vector<double>> cluster_properties, cell_properties;
1685 
1686  std::unordered_map<std::string, long long int> cell_counts;
1687 
1688  cluster_properties["size"].resize(clusters->number, 0.);
1689  cluster_properties["weighted_size"].resize(clusters->number, 0.);
1690 
1691  long long int same_energy = 0, same_abs_energy = 0, same_snr = 0, same_abs_snr = 0;
1692 
1693  std::set<double> energies, snrs;
1694 
1695  if (m_doCells)
1696  {
1697 
1698  for (int cell = 0; cell < NCaloCells; ++cell)
1699  {
1700  if (!cell_info->is_valid(cell))
1701  {
1702  continue;
1703  }
1704 
1705  apply_to_multi_class([&](const auto & prop, const size_t i)
1706  {
1707  if (m_cellPropertiesToDo[i])
1708  {
1709  cell_properties[prop.name()].push_back(prop.get_property(constant_data, *cell_info, *cell_state, *clusters, *moments, cell));
1710  }
1711  }, BasicCellProperties{});
1712 
1713  apply_to_multi_class([&](const auto & prop, const size_t i)
1714  {
1715  if (m_cellTypesToDo[i])
1716  {
1717  cell_counts[prop.name()] += prop.is_type(constant_data, *cell_info, *cell_state, *clusters, *moments, cell);
1718  }
1719  }, BasicCellTypes{});
1720 
1721  const float this_energy = cell_info->energy[cell];
1722 
1723  if (m_extraThingsToDo[SameECells])
1724  {
1725 
1726  if (energies.count(this_energy))
1727  {
1728  ++same_energy;
1729  ++same_abs_energy;
1730  }
1731  else if (energies.count(-this_energy))
1732  {
1733  ++same_abs_energy;
1734  }
1735  energies.insert(this_energy);
1736  }
1737 
1738  if (m_extraThingsToDo[SameSNRCells])
1739  {
1740 
1741  const float this_snr = this_energy / protect_from_zero(constant_data.m_cell_noise->get_noise(cell, cell_info->gain[cell]));
1742 
1743  if (snrs.count(this_snr))
1744  {
1745  ++same_snr;
1746  ++same_abs_snr;
1747  }
1748  else if (snrs.count(-this_snr))
1749  {
1750  ++same_abs_snr;
1751  }
1752  snrs.insert(this_snr);
1753  }
1754 
1755  if (m_extraThingsToDo[ClusterSize])
1756  {
1757  const ClusterTag tag = cell_state->clusterTag[cell];
1758  const float weight = float_unhack(tag.secondary_cluster_weight());
1759  if (tag.is_part_of_cluster())
1760  {
1761  cluster_properties["size"][tag.cluster_index()] += 1;
1762  cluster_properties["weighted_size"][tag.cluster_index()] += 1.0f - weight;
1763  if (tag.is_shared_between_clusters())
1764  {
1765  cluster_properties["size"][tag.secondary_cluster_index()] += 1;
1766  cluster_properties["weighted_size"][tag.secondary_cluster_index()] += weight;
1767  }
1768  }
1769  }
1770  }
1771  }
1772 
1773  if (m_doClusters)
1774  {
1775  for (int cluster = 0; cluster < clusters->number; ++cluster)
1776  {
1777  apply_to_multi_class([&](const auto & prop, const size_t i)
1778  {
1780  {
1781  cluster_properties[prop.name()].push_back(prop.get_property(constant_data, *cell_info, *cell_state, *clusters, *moments, cluster));
1782  }
1783  }, BasicClusterProperties{});
1784  }
1785  }
1786 
1787  using coll_type = decltype(Monitored::Collection("", std::declval<std::vector<double> &>()));
1788  using scalar_type = decltype(Monitored::Scalar("", std::declval<long long int>()));
1789 
1790  std::vector<coll_type> collections;
1791  std::vector<scalar_type> count_scalars;
1792  std::vector<std::reference_wrapper<Monitored::IMonitoredVariable>> cluster_group, cell_group, counts_group;
1793 
1794  collections.reserve(cluster_properties.size() + cell_properties.size());
1795  count_scalars.reserve(cell_counts.size());
1796  cluster_group.reserve(cluster_properties.size());
1797  cell_group.reserve(cell_properties.size());
1798  counts_group.reserve(cell_counts.size() + 5);
1799 
1800  auto mon_clus_num = Monitored::Scalar(prefix + "_num_clusters", clusters->number);
1801  auto mon_same_energy = Monitored::Scalar(prefix + "_num_same_E_cells", same_energy);
1802  auto mon_same_abs_energy = Monitored::Scalar(prefix + "_num_same_abs_E_cells", same_abs_energy);
1803  auto mon_same_snr = Monitored::Scalar(prefix + "_num_same_SNR_cells", same_snr);
1804  auto mon_same_abs_snr = Monitored::Scalar(prefix + "_num_same_abs_SNR_cells", same_abs_snr);
1805 
1806  counts_group.push_back(std::ref(mon_clus_num));
1807  counts_group.push_back(std::ref(mon_same_energy));
1808  counts_group.push_back(std::ref(mon_same_abs_energy));
1809  counts_group.push_back(std::ref(mon_same_snr));
1810  counts_group.push_back(std::ref(mon_same_abs_snr));
1811 
1812  //If we're not doing these plots,
1813  //we're still saving,
1814  //which is slightly inefficient, but.. let's not complicate.
1815 
1816  for (const auto & k_v : cluster_properties)
1817  {
1818  collections.emplace_back(Monitored::Collection(prefix + "_cluster_" + k_v.first, k_v.second));
1819  cluster_group.push_back(std::ref(collections.back()));
1820  }
1821 
1822  for (const auto & k_v : cell_properties)
1823  {
1824  collections.emplace_back(Monitored::Collection(prefix + "_cell_" + k_v.first, k_v.second));
1825  cell_group.push_back(std::ref(collections.back()));
1826  }
1827 
1828  for (const auto & k_v : cell_counts)
1829  {
1830  count_scalars.emplace_back(Monitored::Scalar(prefix + "_num_" + k_v.first + "_cells", k_v.second));
1831  counts_group.push_back(std::ref(count_scalars.back()));
1832  }
1833 
1834  auto monitor_clusters = Monitored::Group(m_moniTool, cluster_group);
1835  auto monitor_cells = Monitored::Group(m_moniTool, cell_group);
1836  auto monitor_counts = Monitored::Group(m_moniTool, counts_group);
1837 
1838  }
1839  return StatusCode::SUCCESS;
1840 }
1841 
1842 
1844  const CaloRecGPU::ConstantDataHolder & constant_data,
1845  const int index_1,
1846  const int index_2,
1847  const std::string & prefix,
1848  const bool match_in_energy,
1849  const bool match_without_shared,
1850  const bool match_perfectly) const
1851 {
1852 
1853  //Note: Part of the work here is superfluous in the case
1854  // where we are monitoring the tools individually too,
1855  // but in the most generic case that is not guaranteed.
1856  // Partially wasted work, but it's cleaner than the alternative...
1857 
1858  std::vector<per_tool_storage> & store_vec = m_storageHolder.get_for_thread();
1859 
1860  const CaloRecGPU::CellInfoArr & cell_info_1 = store_vec[index_1].cell_info;
1861  const CaloRecGPU::CellStateArr & cell_state_1 = store_vec[index_1].cell_state;
1862  const CaloRecGPU::ClusterInfoArr & clusters_1 = store_vec[index_1].clusters;
1863  const CaloRecGPU::ClusterMomentsArr & moments_1 = store_vec[index_1].moments;
1864 
1865  const CaloRecGPU::CellInfoArr & cell_info_2 = store_vec[index_2].cell_info;
1866  const CaloRecGPU::CellStateArr & cell_state_2 = store_vec[index_2].cell_state;
1867  const CaloRecGPU::ClusterInfoArr & clusters_2 = store_vec[index_2].clusters;
1868  const CaloRecGPU::ClusterMomentsArr & moments_2 = store_vec[index_2].moments;
1869 
1871 
1872  if (match_perfectly)
1873  {
1874  ATH_CHECK( match_clusters_perfectly(sch, constant_data, cell_info_1, cell_state_1, cell_state_2,
1875  clusters_1, clusters_2, moments_1, moments_2, match_without_shared) );
1876  }
1877  else
1878  {
1879  ATH_CHECK( match_clusters(sch, constant_data, cell_info_1, cell_state_1, cell_state_2,
1880  clusters_1, clusters_2, moments_1, moments_2, match_in_energy, match_without_shared) );
1881  }
1882 
1883  std::unordered_map<std::string, std::vector<double>> cluster_properties, cell_properties;
1884 
1885  std::unordered_map<std::string, long long int> cell_counts;
1886 
1887  std::vector<double> ref_size_vec(clusters_1.number, 0.), test_size_vec(clusters_2.number, 0.),
1888  ref_weighted_size_vec(clusters_1.number, 0.), test_weighted_size_vec(clusters_2.number, 0.),
1889  ref_diff_cells(clusters_1.number, 0.), test_diff_cells(clusters_2.number, 0.),
1890  ref_diff_cells_weight(clusters_1.number, 0.), test_diff_cells_weight(clusters_2.number, 0.);
1891  //We can store integers up to 2^53 on a double...
1892 
1893  long long int same_energy_1 = 0, same_energy_2 = 0,
1894  same_abs_energy_1 = 0, same_abs_energy_2 = 0,
1895  same_snr_1 = 0, same_snr_2 = 0,
1896  same_abs_snr_1 = 0, same_abs_snr_2 = 0,
1897  same_cluster_cells_count = 0, diff_cluster_cells_count = 0;
1898 
1899  std::set<double> energies_1, energies_2, snrs_1, snrs_2;
1900 
1901  if (m_doCombinedCells)
1902  {
1903  for (int cell = 0; cell < NCaloCells; ++cell)
1904  {
1905  if (!cell_info_1.is_valid(cell) || !cell_info_2.is_valid(cell))
1906  {
1907  continue;
1908  }
1909 
1910  apply_to_multi_class([&](const auto & prop, const size_t i)
1911  {
1913  {
1914  const auto prop_1 = prop.get_property(constant_data, cell_info_1, cell_state_1, clusters_1, moments_1, cell);
1915  const auto prop_2 = prop.get_property(constant_data, cell_info_2, cell_state_2, clusters_2, moments_2, cell);
1916 
1917  cell_properties[prop.name() + "_ref"].push_back(prop_1);
1918  cell_properties[prop.name() + "_test"].push_back(prop_2);
1919 
1920  cell_properties["delta_" + prop.name()].push_back(prop_2 - prop_1);
1921  cell_properties["delta_" + prop.name() + "_rel_ref"].push_back((prop_2 - prop_1) / protect_from_zero(std::abs(prop_1)));
1922  cell_properties["delta_" + prop.name() + "_rel_test"].push_back((prop_2 - prop_1) / protect_from_zero(std::abs(prop_2)));
1923  }
1924  }, BasicCellProperties{});
1925 
1926  apply_to_multi_class([&](const auto & prop, const size_t i)
1927  {
1929  {
1930  const auto is_1 = prop.is_type(constant_data, cell_info_1, cell_state_1, clusters_1, moments_1, cell);
1931  const auto is_2 = prop.is_type(constant_data, cell_info_2, cell_state_2, clusters_2, moments_2, cell);
1932 
1933  cell_counts["num_" + prop.name() + "_cells_ref"] += is_1;
1934  cell_counts["num_" + prop.name() + "_cells_test"] += is_2;
1935  cell_counts["delta_num_" + prop.name() + "_cells"] += is_2 - is_1;
1936  }
1937  }, BasicCellTypes{});
1938 
1939  const float this_energy_1 = cell_info_1.energy[cell];
1940  const float this_energy_2 = cell_info_2.energy[cell];
1941 
1942  if (m_extraThingsToDo[SameECellsCombined])
1943  {
1944 
1945  if (energies_1.count(this_energy_1))
1946  {
1947  ++same_energy_1;
1948  ++same_abs_energy_1;
1949  }
1950  else if (energies_1.count(-this_energy_1))
1951  {
1952  ++same_abs_energy_1;
1953  }
1954  energies_1.insert(this_energy_1);
1955 
1956  if (energies_2.count(this_energy_2))
1957  {
1958  ++same_energy_2;
1959  ++same_abs_energy_2;
1960  }
1961  else if (energies_2.count(-this_energy_2))
1962  {
1963  ++same_abs_energy_2;
1964  }
1965  energies_2.insert(this_energy_2);
1966  }
1967 
1968  if (m_extraThingsToDo[SameSNRCellsCombined])
1969  {
1970  const float this_snr_1 = this_energy_1 / protect_from_zero(constant_data.m_cell_noise->get_noise(cell, cell_info_1.gain[cell]));
1971 
1972  if (snrs_1.count(this_snr_1))
1973  {
1974  ++same_snr_1;
1975  ++same_abs_snr_1;
1976  }
1977  else if (snrs_1.count(-this_snr_1))
1978  {
1979  ++same_abs_snr_1;
1980  }
1981  snrs_1.insert(this_snr_1);
1982 
1983 
1984  const float this_snr_2 = this_energy_2 / protect_from_zero(constant_data.m_cell_noise->get_noise(cell, cell_info_2.gain[cell]));
1985 
1986  if (snrs_2.count(this_snr_2))
1987  {
1988  ++same_snr_2;
1989  ++same_abs_snr_2;
1990  }
1991  else if (snrs_2.count(-this_snr_2))
1992  {
1993  ++same_abs_snr_2;
1994  }
1995  snrs_2.insert(this_snr_2);
1996  }
1997 
1998  if (m_extraThingsToDo[DiffCells] || m_extraThingsToDo[ClusterComparedSize])
1999  {
2000 
2001  const ClusterTag ref_tag = cell_state_1.clusterTag[cell];
2002  const ClusterTag test_tag = cell_state_2.clusterTag[cell];
2003  int ref_c1 = -3, ref_c2 = -3, test_c1 = -3, test_c2 = -3;
2004  if (ref_tag.is_part_of_cluster())
2005  {
2006  ref_c1 = ref_tag.cluster_index();
2007  ref_c2 = ref_tag.is_shared_between_clusters() ? ref_tag.secondary_cluster_index() : -2;
2008  }
2009 
2010  if (test_tag.is_part_of_cluster())
2011  {
2012  test_c1 = test_tag.cluster_index();
2013  test_c2 = test_tag.is_shared_between_clusters() ? test_tag.secondary_cluster_index() : -2;
2014  }
2015 
2016  const int match_1 = test_c1 < 0 ? -1 : sch.t2r(test_c1);
2017  const int match_2 = test_c2 < 0 ? -1 : sch.t2r(test_c2);
2018 
2019  const float ref_rev_weight = float_unhack(ref_tag.secondary_cluster_weight());
2020  const float test_rev_weight = float_unhack(test_tag.secondary_cluster_weight());
2021 
2022  const float ref_weight = 1.0f - ref_rev_weight;
2023  const float test_weight = 1.0f - test_rev_weight;
2024 
2025  bool cell_is_diff = false;
2026 
2027  if (ref_c1 >= 0)
2028  {
2029  ref_size_vec[ref_c1] += 1;
2030  ref_weighted_size_vec[ref_c1] += ref_weight;
2031 #if CALORECGPU_DISABLE_STRICT_MATCHING
2032  if (!(ref_c1 == match_1 || ref_c1 == match_2 || (match_1 < 0 || match_2 < 0)))
2033 #else
2034  if (!(ref_c1 == match_1 || ref_c1 == match_2))
2035 #endif
2036  {
2037  cell_is_diff = true;
2038  ref_diff_cells[ref_c1] += 1;
2039  ref_diff_cells_weight[ref_c1] += ref_weight;
2040  }
2041  }
2042 
2043  if (ref_c2 >= 0)
2044  {
2045  ref_size_vec[ref_c2] += 1;
2046  ref_weighted_size_vec[ref_c2] += ref_rev_weight;
2047 #if CALORECGPU_DISABLE_STRICT_MATCHING
2048  if (!(ref_c2 == match_1 || ref_c2 == match_2 || (match_1 < 0 || match_2 < 0)))
2049 #else
2050  if (!(ref_c2 == match_1 || ref_c2 == match_2))
2051 #endif
2052  {
2053  cell_is_diff = true;
2054  ref_diff_cells[ref_c2] += 1;
2055  ref_diff_cells_weight[ref_c2] += ref_rev_weight;
2056  }
2057  }
2058 
2059  if (test_c1 >= 0)
2060  {
2061  test_size_vec[test_c1] += 1;
2062  test_weighted_size_vec[test_c1] += test_weight;
2063 #if CALORECGPU_DISABLE_STRICT_MATCHING
2064  if (match_1 >= 0 && !(match_1 == ref_c1 || match_1 == ref_c2 || (ref_c1 < 0 || ref_c2 < 0)))
2065 #else
2066  if (match_1 < 0 || !(match_1 == ref_c1 || match_1 == ref_c2))
2067 #endif
2068  {
2069  cell_is_diff = true;
2070  test_diff_cells[test_c1] += 1;
2071  test_diff_cells_weight[test_c1] += test_weight;
2072  }
2073  }
2074 
2075  if (test_c2 >= 0)
2076  {
2077  test_size_vec[test_c2] += 1;
2078  test_weighted_size_vec[test_c2] += test_rev_weight;
2079 #if CALORECGPU_DISABLE_STRICT_MATCHING
2080  if (match_2 >= 0 && !(match_2 == ref_c1 || match_2 == ref_c2 || (ref_c1 < 0 || ref_c2 < 0)))
2081 #else
2082  if (match_2 < 0 || !(match_2 == ref_c1 || match_2 == ref_c2))
2083 #endif
2084  {
2085  cell_is_diff = true;
2086  test_diff_cells[test_c2] += 1;
2087  test_diff_cells_weight[test_c2] += test_rev_weight;
2088  }
2089  }
2090 
2091  if (!cell_is_diff && (ref_c1 >= 0 || ref_c2 >= 0 || test_c1 >= 0 || test_c2 >= 0))
2092  {
2093  ++same_cluster_cells_count;
2094  }
2095  else if (cell_is_diff)
2096  {
2097  char message_buffer[256];
2098  snprintf(message_buffer, 256,
2099  "%7d | %18f || %6d | %6d | %6d | %6d || %6d | %6d || %016llX | %016llX",
2100  cell, this_energy_1 / protect_from_zero(constant_data.m_cell_noise->get_noise(cell, cell_info_1.gain[cell])),
2101  ref_c1, ref_c2, test_c1, test_c2,
2102  match_1, match_2,
2103  static_cast<tag_type>(ref_tag), static_cast<tag_type>(test_tag));
2104  ATH_MSG_DEBUG(message_buffer);
2105  ++diff_cluster_cells_count;
2106  }
2107 
2108  }
2109  }
2110  }
2111 
2113  {
2114 
2115  for (int cluster = 0; cluster < clusters_1.number; ++cluster)
2116  {
2117  const int match = sch.r2t(cluster);
2118  if (match < 0)
2119  //The cluster isn't matched.
2120  {
2121  continue;
2122  }
2123 
2124  apply_to_multi_class([&](const auto & prop, const size_t i)
2125  {
2127  {
2128  const auto prop_1 = prop.get_property(constant_data, cell_info_1, cell_state_1, clusters_1, moments_1, cluster);
2129  const auto prop_2 = prop.get_property(constant_data, cell_info_2, cell_state_2, clusters_2, moments_2, match);
2130 
2131  cluster_properties[prop.name() + "_ref"].push_back(prop_1);
2132  cluster_properties[prop.name() + "_test"].push_back(prop_2);
2133 
2134  cluster_properties["delta_" + prop.name()].push_back(prop_2 - prop_1);
2135  cluster_properties["delta_" + prop.name() + "_rel_ref"].push_back((prop_2 - prop_1) / protect_from_zero(std::abs(prop_1)));
2136  cluster_properties["delta_" + prop.name() + "_rel_test"].push_back((prop_2 - prop_1) / protect_from_zero(std::abs(prop_2)));
2137  }
2138  }, BasicClusterProperties{});
2139 
2140  apply_to_multi_class([&](const auto & prop, const size_t i)
2141  {
2143  {
2144  cluster_properties[prop.name()].push_back(prop.get_property(constant_data, cell_info_1, cell_state_1, clusters_1, moments_1, cluster,
2145  cell_info_2, cell_state_2, clusters_2, moments_2, match));
2146  }
2147  }, ComparedClusterProperties{});
2148 
2149  if (m_extraThingsToDo[ClusterComparedSize])
2150  {
2151  cluster_properties["size_ref"].push_back(ref_size_vec[cluster]);
2152  cluster_properties["size_test"].push_back(test_size_vec[match]);
2153  cluster_properties["delta_size"].push_back(ref_size_vec[cluster] - test_size_vec[match]);
2154  cluster_properties["delta_size_rel_ref"].push_back((ref_size_vec[cluster] - test_size_vec[match]) / protect_from_zero(ref_size_vec[cluster]));
2155  cluster_properties["delta_size_rel_test"].push_back((ref_size_vec[cluster] - test_size_vec[match]) / protect_from_zero(test_size_vec[match]));
2156 
2157  cluster_properties["weighted_size_ref"].push_back(ref_weighted_size_vec[cluster]);
2158  cluster_properties["weighted_size_test"].push_back(test_weighted_size_vec[match]);
2159  cluster_properties["delta_weighted_size"].push_back(ref_weighted_size_vec[cluster] - test_weighted_size_vec[match]);
2160  cluster_properties["delta_weighted_size_rel_ref"].push_back((ref_weighted_size_vec[cluster] - test_weighted_size_vec[match]) / protect_from_zero(ref_weighted_size_vec[cluster]));
2161  cluster_properties["delta_weighted_size_rel_test"].push_back((ref_weighted_size_vec[cluster] - test_weighted_size_vec[match]) / protect_from_zero(test_weighted_size_vec[match]));
2162  }
2163 
2164  if (m_extraThingsToDo[DiffCells])
2165  {
2166  cluster_properties["diff_cells_ref"].push_back(ref_diff_cells[cluster]);
2167  cluster_properties["diff_cells_ref_rel_size"].push_back(ref_diff_cells[cluster] / protect_from_zero(ref_size_vec[cluster]));
2168  cluster_properties["diff_cells_test"].push_back(test_diff_cells[match]);
2169  cluster_properties["diff_cells_test_rel_size"].push_back(test_diff_cells[match] / protect_from_zero(test_size_vec[match]));
2170  cluster_properties["diff_cells"].push_back(ref_diff_cells[cluster] + test_diff_cells[match]);
2171 
2172  cluster_properties["weighted_diff_cells_ref"].push_back(ref_diff_cells_weight[cluster]);
2173  cluster_properties["weighted_diff_cells_ref_rel_size"].push_back(ref_diff_cells_weight[cluster] / protect_from_zero(ref_weighted_size_vec[cluster]));
2174  cluster_properties["weighted_diff_cells_test"].push_back(test_diff_cells_weight[match]);
2175  cluster_properties["weighted_diff_cells_test_rel_size"].push_back(test_diff_cells_weight[match] / protect_from_zero(test_weighted_size_vec[match]));
2176  cluster_properties["weighted_diff_cells"].push_back(ref_diff_cells_weight[cluster] + test_diff_cells_weight[match]);
2177  }
2178  }
2179  }
2180 
2181  using coll_type = decltype(Monitored::Collection("", std::declval<std::vector<double> &>()));
2182  using scalar_type = decltype(Monitored::Scalar("", std::declval<long long int>()));
2183 
2184  std::vector<coll_type> collections;
2185  std::vector<scalar_type> count_scalars;
2186  std::vector<std::reference_wrapper<Monitored::IMonitoredVariable>> cluster_group, cell_group, counts_group;
2187 
2188  collections.reserve(cluster_properties.size() + cell_properties.size());
2189  count_scalars.reserve(cell_counts.size() + 6 * 3);
2190  cluster_group.reserve(cluster_properties.size());
2191  cell_group.reserve(cell_properties.size());
2192  counts_group.reserve(cell_counts.size() + 3 + 6 * 3);
2193 
2194  auto add_count_vars = [&](const std::string & name, const long long int ref_num, const long long int test_num)
2195  {
2196  count_scalars.emplace_back(Monitored::Scalar(prefix + "_" + name + "_ref", ref_num));
2197  counts_group.push_back(std::ref(count_scalars.back()));
2198 
2199  count_scalars.emplace_back(Monitored::Scalar(prefix + "_" + name + "_test", test_num));
2200  counts_group.push_back(std::ref(count_scalars.back()));
2201 
2202  count_scalars.emplace_back(Monitored::Scalar(prefix + "_delta_" + name, test_num - ref_num));
2203  counts_group.push_back(std::ref(count_scalars.back()));
2204  };
2205 
2206  add_count_vars("num_clusters", clusters_1.number, clusters_2.number);
2207  add_count_vars("num_unmatched_clusters", sch.ref_unmatched(), sch.test_unmatched());
2208 
2209  add_count_vars("num_same_E_cells", same_energy_1, same_energy_2);
2210  add_count_vars("num_same_abs_E_cells", same_abs_energy_1, same_abs_energy_2);
2211  add_count_vars("num_same_SNR_cells", same_snr_1, same_snr_2);
2212  add_count_vars("num_same_abs_SNR_cells", same_abs_snr_1, same_abs_snr_2);
2213 
2214  auto mon_total_unmatched = Monitored::Scalar(prefix + "_num_unmatched_clusters", sch.ref_unmatched() + sch.test_unmatched());
2215  auto mon_same_cluster_cell = Monitored::Scalar(prefix + "_same_cluster_cells", same_cluster_cells_count);
2216  auto mon_diff_cluster_cell = Monitored::Scalar(prefix + "_diff_cluster_cells", diff_cluster_cells_count);
2217 
2218  counts_group.push_back(std::ref(mon_total_unmatched));
2219  counts_group.push_back(std::ref(mon_same_cluster_cell));
2220  counts_group.push_back(std::ref(mon_diff_cluster_cell));
2221 
2222  for (const auto & k_v : cluster_properties)
2223  {
2224  collections.emplace_back(Monitored::Collection(prefix + "_cluster_" + k_v.first, k_v.second));
2225  cluster_group.push_back(std::ref(collections.back()));
2226  }
2227 
2228  for (const auto & k_v : cell_properties)
2229  {
2230  collections.emplace_back(Monitored::Collection(prefix + "_cell_" + k_v.first, k_v.second));
2231  cell_group.push_back(std::ref(collections.back()));
2232  }
2233 
2234  for (const auto & k_v : cell_counts)
2235  {
2236  count_scalars.emplace_back(Monitored::Scalar(prefix + "_" + k_v.first, k_v.second));
2237  counts_group.push_back(std::ref(count_scalars.back()));
2238  }
2239 
2240  auto monitor_clusters = Monitored::Group(m_moniTool, cluster_group);
2241  auto monitor_cells = Monitored::Group(m_moniTool, cell_group);
2242  auto monitor_counts = Monitored::Group(m_moniTool, counts_group);
2243 
2244  return StatusCode::SUCCESS;
2245 }
CaloGPUClusterAndCellDataMonitor::m_cellPropertiesToDo
std::vector< bool > m_cellPropertiesToDo
Definition: CaloGPUClusterAndCellDataMonitor.h:296
xAOD::CaloCluster_v1::CENTER_MAG
@ CENTER_MAG
Cluster Centroid ( )
Definition: CaloCluster_v1.h:135
xAOD::CaloCluster_v1::SECOND_R
@ SECOND_R
Second Moment in .
Definition: CaloCluster_v1.h:123
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAOD::CaloCluster_v1::phimax
float phimax(const CaloSample sampling) const
Retrieve of cell with maximum energy in given sampling.
Definition: CaloCluster_v1.cxx:589
xAOD::CaloCluster_v1::phi
virtual double phi() const
The azimuthal angle ( ) of the particle.
Definition: CaloCluster_v1.cxx:256
xAOD::CaloCluster_v1::time
flt_t time() const
Access cluster time.
fillPileUpNoiseLumi.current
current
Definition: fillPileUpNoiseLumi.py:52
CaloRecGPU::CellInfoArr::gain
unsigned char gain[NCaloCells]
Definition: EventInfoDefinitions.h:190
xAOD::CaloCluster_v1::ENG_CALIB_DEAD_UNCLASS
@ ENG_CALIB_DEAD_UNCLASS
Attached Calibration Hit energy in dead material in unclassified areas of the detector.
Definition: CaloCluster_v1.h:246
xAOD::CaloCluster_v1::FIRST_PHI
@ FIRST_PHI
First Moment in .
Definition: CaloCluster_v1.h:121
TauGNNUtils::Variables::Cluster::CENTER_LAMBDA
bool CENTER_LAMBDA(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:831
python.CaloRecoConfig.f
f
Definition: CaloRecoConfig.py:127
xAOD::CaloCluster_v1::OOC_WEIGHT
@ OOC_WEIGHT
Out-of-cluster weight (E_ooc/E_w)
Definition: CaloCluster_v1.h:175
xAOD::CaloCluster_v1::ENG_FRAC_CORE
@ ENG_FRAC_CORE
Energy fraction of the sum of the hottest cells in each sampling.
Definition: CaloCluster_v1.h:142
xAOD::CaloCluster_v1::cell_begin
const_cell_iterator cell_begin() const
Iterator of the underlying CaloClusterCellLink (const version)
Definition: CaloCluster_v1.h:812
CaloRecGPU::ClusterInfoArr::number
int number
Definition: EventInfoDefinitions.h:329
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
CaloGPUClusterAndCellDataMonitor::CaloGPUClusterAndCellDataMonitor
CaloGPUClusterAndCellDataMonitor(const std::string &type, const std::string &name, const IInterface *parent)
Definition: CaloGPUClusterAndCellDataMonitor.cxx:25
CaloGPUClusterAndCellDataMonitor.h
TrigDefs::Group
Group
Properties of a chain group.
Definition: GroupProperties.h:13
hotSpotInTAG.suffix
string suffix
Definition: hotSpotInTAG.py:186
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
xAOD::CaloCluster_v1::numberCells
int numberCells() const
Return total number of cells in cluster.
Definition: CaloCluster_v1.cxx:818
xAOD::CaloCluster_v1::VERTEX_FRACTION
@ VERTEX_FRACTION
Vertex fraction of this cluster wrt.
Definition: CaloCluster_v1.h:184
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
CaloRecGPU::ClusterTag::secondary_cluster_index
constexpr int32_t secondary_cluster_index() const
Definition: TagDefinitions.h:253
CaloGPUClusterAndCellDataMonitor::update_plots_end
virtual StatusCode update_plots_end(const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const xAOD::CaloClusterContainer *cluster_collection_ptr) const override
Definition: CaloGPUClusterAndCellDataMonitor.cxx:140
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
xAOD::CaloCluster_v1::getMomentValue
double getMomentValue(MomentType type) const
Retrieve individual moment - no check for existance! Returns -999 on error.
Definition: CaloCluster_v1.h:906
xAOD::CaloCluster_v1::MASS
@ MASS
cell based mass i.e. the mass of the 4-vector sum of all massless positive energetic cells
Definition: CaloCluster_v1.h:172
TauGNNUtils::Variables::Cluster::EM_PROBABILITY
bool EM_PROBABILITY(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:900
xAOD::CaloCluster_v1::EM_PROBABILITY
@ EM_PROBABILITY
Classification probability to be em-like.
Definition: CaloCluster_v1.h:173
CaloGPUClusterAndCellDataMonitor::m_extraThingsToDo
std::vector< bool > m_extraThingsToDo
Definition: CaloGPUClusterAndCellDataMonitor.h:298
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
CaloRecGPU::ClusterTag::is_shared_between_clusters
constexpr bool is_shared_between_clusters() const
Definition: TagDefinitions.h:273
xAOD::CaloCluster_v1::CENTER_X
@ CENTER_X
Cluster Centroid ( )
Definition: CaloCluster_v1.h:131
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
CaloRecGPU::EventDataHolder::m_moments_dev
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::ClusterMomentsArr > m_moments_dev
Definition: DataHolders.h:91
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
index
Definition: index.py:1
CaloGPUClusterAndCellDataMonitor::m_min_similarity
double m_min_similarity
Parameters for the cluster matching algorithm, for easier access.
Definition: CaloGPUClusterAndCellDataMonitor.h:242
SG::VarHandleBase::name
const std::string & name() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:75
xAOD::CaloCluster_v1::ENG_CALIB_DEAD_LEAKAGE
@ ENG_CALIB_DEAD_LEAKAGE
Attached Calibration Hit energy in dead material behind calorimeters.
Definition: CaloCluster_v1.h:243
xAOD::deltaPhi
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap setEtaBin setIsTgcFailure setDeltaPt deltaPhi
Definition: L2StandAloneMuon_v1.cxx:160
xAOD::CaloCluster_v1::ETA2CALOFRAME
@ ETA2CALOFRAME
Eta of sampling 2 in the calo frame (for egamma)
Definition: CaloCluster_v1.h:191
eFEXNTuple.delta_R
def delta_R(eta1, phi1, eta2, phi2)
Definition: eFEXNTuple.py:21
CaloGPUClusterAndCellDataMonitor::update_plots
virtual StatusCode update_plots(const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const xAOD::CaloClusterContainer *cluster_collection_ptr, const CaloClusterCollectionProcessor *tool) const override
Definition: CaloGPUClusterAndCellDataMonitor.cxx:168
xAOD::CaloCluster_v1::AVG_LAR_Q
@ AVG_LAR_Q
Sum(E_cell_LAr^2 Q_cell_LAr)/Sum(E_cell_LAr^2)
Definition: CaloCluster_v1.h:163
xAOD::CaloCluster_v1::ETA1CALOFRAME
@ ETA1CALOFRAME
Eta of sampling 1 in the calo frame (for egamma)
Definition: CaloCluster_v1.h:189
CaloCondBlobAlgs_fillNoiseFromASCII.gain
gain
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:110
python.SystemOfUnits.MeV
int MeV
Definition: SystemOfUnits.py:154
CaloRecGPU::Helpers::SimpleHolder
Holds one objects of type \T in memory context Context.
Definition: Calorimeter/CaloRecGPU/CaloRecGPU/Helpers.h:1069
CaloGPUClusterAndCellDataMonitor::sample_comparisons_holder::test_unmatched
int test_unmatched() const
Returns the number of unmatched clusters in the test (second) tool.
Definition: CaloGPUClusterAndCellDataMonitor.h:151
CaloRecGPU::EventDataHolder::m_cell_state_dev
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::CellStateArr > m_cell_state_dev
Definition: DataHolders.h:89
CaloGPUClusterAndCellDataMonitor::m_comparedClusterPropertiesToDo
std::vector< bool > m_comparedClusterPropertiesToDo
Definition: CaloGPUClusterAndCellDataMonitor.h:295
skel.it
it
Definition: skel.GENtoEVGEN.py:423
CaloClusterGPUProcessor
Base class for GPU-accelerated cluster processing tools to be called from CaloGPUHybridClusterProcess...
Definition: CaloClusterGPUProcessor.h:27
CaloGPUClusterAndCellDataMonitor::m_plottedVariablesInitialized
std::atomic< bool > m_plottedVariablesInitialized
A flag to signal that the variables to be monitored have been detected based on the booked histograms...
Definition: CaloGPUClusterAndCellDataMonitor.h:308
CaloGPUClusterAndCellDataMonitor::m_cellTypesToDo
std::vector< bool > m_cellTypesToDo
Definition: CaloGPUClusterAndCellDataMonitor.h:297
CaloRecGPU::EventDataHolder::m_clusters_dev
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::ClusterInfoArr > m_clusters_dev
Definition: DataHolders.h:90
CALORECGPU_BASIC_CELL_PROPERTY
#define CALORECGPU_BASIC_CELL_PROPERTY(NAME,...)
Definition: CaloGPUClusterAndCellDataMonitor.cxx:1350
xAOD::CaloCluster_v1::ENG_CALIB_TILEG3
@ ENG_CALIB_TILEG3
Calibration Hit energy inside the cluster scintillator.
Definition: CaloCluster_v1.h:222
xAOD::CaloCluster_v1::ENG_CALIB_DEAD_T
@ ENG_CALIB_DEAD_T
Attached Calibration Hit energy in dead material with tight matching (Angle < 0.3).
Definition: CaloCluster_v1.h:214
CaloGPUClusterAndCellDataMonitor::match_clusters
StatusCode match_clusters(sample_comparisons_holder &sch, const CaloRecGPU::ConstantDataHolder &constant_data, const CaloRecGPU::CellInfoArr &cell_info, const CaloRecGPU::CellStateArr &cell_state_1, const CaloRecGPU::CellStateArr &cell_state_2, const CaloRecGPU::ClusterInfoArr &cluster_info_1, const CaloRecGPU::ClusterInfoArr &cluster_info_2, const CaloRecGPU::ClusterMomentsArr &, const CaloRecGPU::ClusterMomentsArr &, const bool match_in_energy, const bool match_without_shared) const
Definition: CaloGPUClusterAndCellDataMonitor.cxx:717
xAOD::CaloCluster_v1::ENG_CALIB_OUT_M
@ ENG_CALIB_OUT_M
Attached Calibration Hit energy outside clusters but inside the calorimeter with medium matching (Ang...
Definition: CaloCluster_v1.h:200
xAOD::CaloCluster_v1::et
double et() const
Definition: CaloCluster_v1.h:856
xAOD::CaloCluster_v1::CENTER_LAMBDA
@ CENTER_LAMBDA
Shower depth at Cluster Centroid.
Definition: CaloCluster_v1.h:136
CaloRecGPU::CellInfoArr::energy
float energy[NCaloCells]
Definition: EventInfoDefinitions.h:189
CaloClusterCollectionProcessor
Definition: CaloClusterCollectionProcessor.h:32
xAOD::CaloCluster_v1::ENG_CALIB_EMB0
@ ENG_CALIB_EMB0
Calibration Hit energy inside the cluster barrel presampler.
Definition: CaloCluster_v1.h:218
postInclude.sorter
sorter
Definition: postInclude.SortInput.py:23
CALORECGPU_CLUSTER_MOMENT
#define CALORECGPU_CLUSTER_MOMENT(...)
Definition: CaloGPUClusterAndCellDataMonitor.cxx:1134
xAOD::CaloCluster_v1::ENG_CALIB_DEAD_TILE0
@ ENG_CALIB_DEAD_TILE0
Attached Calibration Hit energy in dead material between EMB3 and TILE0.
Definition: CaloCluster_v1.h:230
CaloRecGPU::CellStateArr::clusterTag
tag_type clusterTag[NCaloCells]
Definition: EventInfoDefinitions.h:324
Args
Definition: test_lwtnn_fastgraph.cxx:12
CaloRecGPU::NumSamplings
constexpr int NumSamplings
Definition: BaseDefinitions.h:44
xAOD::CaloCluster_v1::ENG_FRAC_MAX
@ ENG_FRAC_MAX
Energy fraction of hottest cell.
Definition: CaloCluster_v1.h:140
CaloRecGPU::ConstantDataHolder::m_geometry
CaloRecGPU::Helpers::CPU_object< CaloRecGPU::GeometryArr > m_geometry
Definition: DataHolders.h:24
x
#define x
CaloGPUClusterAndCellDataMonitor::add_data
StatusCode add_data(const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellInfoArr > &cell_info, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellStateArr > &cell_state, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::ClusterInfoArr > &clusters, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::ClusterMomentsArr > &moments, const std::string &tool_name) const
Definition: CaloGPUClusterAndCellDataMonitor.cxx:1657
xAOD::CaloCluster_v1::etamax
float etamax(const CaloSample sampling) const
Retrieve of cell with maximum energy in given sampling.
Definition: CaloCluster_v1.cxx:576
xAOD::CaloCluster_v1::PHI1CALOFRAME
@ PHI1CALOFRAME
Phi of sampling 1 in the calo frame (for egamma)
Definition: CaloCluster_v1.h:190
CaloGPUClusterAndCellDataMonitor::m_numEvents
size_t m_numEvents
Counts the number of events.
Definition: CaloGPUClusterAndCellDataMonitor.h:278
DataHandle.h
D3PD::Types
std::tuple< WrapType< TYPES >... > Types
A simple tuple of multiple types.
Definition: PhysicsAnalysis/D3PDMaker/D3PDMakerUtils/D3PDMakerUtils/Types.h:61
CaloGPUClusterAndCellDataMonitor::m_terminal_weight
double m_terminal_weight
Definition: CaloGPUClusterAndCellDataMonitor.h:242
CaloGPUClusterAndCellDataMonitor::pair_to_plot
Definition: CaloGPUClusterAndCellDataMonitor.h:264
dqt_zlumi_pandas.mass
mass
Definition: dqt_zlumi_pandas.py:170
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
CaloGPUClusterAndCellDataMonitor::m_seedThreshold
Gaudi::Property< float > m_seedThreshold
Seed threshold to use for cluster matching.
Definition: CaloGPUClusterAndCellDataMonitor.h:199
CaloRecGPU::ClusterTag
Definition: TagDefinitions.h:222
CaloRecGPU::EventDataHolder::m_cell_info_dev
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::CellInfoArr > m_cell_info_dev
Definition: DataHolders.h:88
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
CaloGPUClusterAndCellDataMonitor::sample_comparisons_holder::ref_unmatched
int ref_unmatched() const
Returns the number of unmatched clusters in the reference (first) tool.
Definition: CaloGPUClusterAndCellDataMonitor.h:146
Monitored::Collection
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
Definition: MonitoredCollection.h:38
CaloGPUClusterAndCellDataMonitor::m_toolsToCheckFor
std::map< std::string, int > m_toolsToCheckFor
Map of the strings corresponding to all the tools that will be relevant for plotting (individually or...
Definition: CaloGPUClusterAndCellDataMonitor.h:255
CaloGPUClusterAndCellDataMonitor::finalize_plots
virtual StatusCode finalize_plots() const override
Definition: CaloGPUClusterAndCellDataMonitor.cxx:101
xAOD::CaloCluster_v1::SECOND_LAMBDA
@ SECOND_LAMBDA
Second Moment in .
Definition: CaloCluster_v1.h:124
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:200
xAOD::CaloCluster_v1::PTD
@ PTD
relative spread of pT of constiuent cells = sqrt(n)*RMS/Mean
Definition: CaloCluster_v1.h:170
xAOD::CaloCluster_v1::etaSample
float etaSample(const CaloSample sampling) const
Retrieve barycenter in a given sample.
Definition: CaloCluster_v1.cxx:532
xAOD::CaloCluster_v1::CENTER_Z
@ CENTER_Z
Cluster Centroid ( )
Definition: CaloCluster_v1.h:133
cm
const double cm
Definition: Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/tools/FCAL_ChannelMap.cxx:25
CaloGPUClusterAndCellDataMonitor::m_doCombinedCells
bool m_doCombinedCells
Definition: CaloGPUClusterAndCellDataMonitor.h:302
CaloGPUClusterAndCellDataMonitor::sample_comparisons_holder::r2t_table
std::vector< int > r2t_table
Definition: CaloGPUClusterAndCellDataMonitor.h:130
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
CaloGPUClusterAndCellDataMonitor::sample_comparisons_holder::r2t
int r2t(const int i) const
Converts a cluster index from the reference tool (first) to the test tool (second).
Definition: CaloGPUClusterAndCellDataMonitor.h:135
CaloRecGPU::ClusterTag::cluster_index
constexpr int32_t cluster_index() const
Definition: TagDefinitions.h:243
xAOD::CaloCluster_v1::SECOND_ENG_DENS
@ SECOND_ENG_DENS
Second Moment in E/V.
Definition: CaloCluster_v1.h:144
CaloGPUClusterAndCellDataMonitor::m_grow_weight
double m_grow_weight
Definition: CaloGPUClusterAndCellDataMonitor.h:242
CellTypes
Definition: CaloGPUClusterAndCellDataMonitor.cxx:1460
CaloRecGPU::CellStateArr
Definition: EventInfoDefinitions.h:323
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
xAOD::CaloCluster_v1::DM_WEIGHT
@ DM_WEIGHT
Dead-material weight (E_dm/E_ooc)
Definition: CaloCluster_v1.h:176
CaloGPUClusterAndCellDataMonitor::m_growThreshold
Gaudi::Property< float > m_growThreshold
Neighbor (growing) threshold to use for cluster matching.
Definition: CaloGPUClusterAndCellDataMonitor.h:194
CaloGPUClusterAndCellDataMonitor::m_toolToIdMap
std::map< std::string, std::string > m_toolToIdMap
Maps tools to their respective identifying prefix for variables.
Definition: CaloGPUClusterAndCellDataMonitor.h:258
CaloRecGPU::tag_type
TagBase::carrier tag_type
Definition: TagDefinitions.h:325
CaloRecGPU::EventDataHolder
Definition: DataHolders.h:35
xAOD::CaloCluster_v1::HAD_WEIGHT
@ HAD_WEIGHT
Hadronic weight (E_w/E_em)
Definition: CaloCluster_v1.h:174
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
CaloGPUClusterAndCellDataMonitor::sample_comparisons_holder::unmatched_test_list
std::vector< int > unmatched_test_list
Definition: CaloGPUClusterAndCellDataMonitor.h:131
CaloGPUClusterAndCellDataMonitor::m_moniTool
ToolHandle< GenericMonitoringTool > m_moniTool
Monitoring tool.
Definition: CaloGPUClusterAndCellDataMonitor.h:208
ParticleGun_FastCalo_ChargeFlip_Config.energy
energy
Definition: ParticleGun_FastCalo_ChargeFlip_Config.py:78
CaloGPUClusterAndCellDataMonitor::m_calo_id
const CaloCell_ID * m_calo_id
Pointer to Calo ID Helper.
Definition: CaloGPUClusterAndCellDataMonitor.h:247
CaloGPUClusterAndCellDataMonitor::sample_comparisons_holder::t2r
int t2r(const int i) const
Converts a cluster index from the test tool (second) to the reference tool (first).
Definition: CaloGPUClusterAndCellDataMonitor.h:141
xAOD::CaloCluster_v1::eta
virtual double eta() const
The pseudorapidity ( ) of the particle.
Definition: CaloCluster_v1.cxx:251
lumiFormat.i
int i
Definition: lumiFormat.py:92
CaloSampling::CaloSample
CaloSample
Definition: Calorimeter/CaloGeoHelpers/CaloGeoHelpers/CaloSampling.h:22
z
#define z
Helpers.h
CaloClusterGPUProcessor.h
xAOD::CaloCluster_v1::energy_max
float energy_max(const CaloSample sampling) const
Retrieve maximum cell energy in given sampling.
Definition: CaloCluster_v1.cxx:563
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
xAOD::CaloCluster_v1::CELL_SIG_SAMPLING
@ CELL_SIG_SAMPLING
CaloSample of the cell with the largest |E|/sig.
Definition: CaloCluster_v1.h:161
CaloGPUClusterAndCellDataMonitor::initialize
virtual StatusCode initialize() override
Definition: CaloGPUClusterAndCellDataMonitor.cxx:32
xAOD::CaloCluster_v1::ENG_CALIB_TOT
@ ENG_CALIB_TOT
Calibration Hit energy inside the cluster.
Definition: CaloCluster_v1.h:195
CaloGPUClusterAndCellDataMonitor::m_cellsKey
SG::ReadHandleKey< CaloCellContainer > m_cellsKey
vector of names of the cell containers to use as input.
Definition: CaloGPUClusterAndCellDataMonitor.h:204
CaloGPUClusterAndCellDataMonitor::sample_comparisons_holder::t2r_table
std::vector< int > t2r_table
Definition: CaloGPUClusterAndCellDataMonitor.h:130
CaloGPUClusterAndCellDataMonitor::m_clusterPropertiesToDo
std::vector< bool > m_clusterPropertiesToDo
Control which properties will actually be calculated and stored.
Definition: CaloGPUClusterAndCellDataMonitor.h:295
xAOD::CaloCluster_v1::ENG_CALIB_FRAC_EM
@ ENG_CALIB_FRAC_EM
Calibration Hit energy inside the cluster caused by e/gamma/pi0.
Definition: CaloCluster_v1.h:248
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:14
xAOD::CaloCluster_v1::ISOLATION
@ ISOLATION
Energy weighted fraction of non-clustered perimeter cells.
Definition: CaloCluster_v1.h:146
xAOD::CaloCluster_v1::ENG_CALIB_FRAC_REST
@ ENG_CALIB_FRAC_REST
Calibration Hit energy inside the cluster caused by other particles.
Definition: CaloCluster_v1.h:253
CALORECGPU_COMPARED_CLUSTER_PROPERTY
#define CALORECGPU_COMPARED_CLUSTER_PROPERTY(NAME,...)
Definition: CaloGPUClusterAndCellDataMonitor.cxx:1300
checkCorrelInHIST.prefix
dictionary prefix
Definition: checkCorrelInHIST.py:391
CaloRecGPU::ClusterInfoArr
Definition: EventInfoDefinitions.h:328
CaloGPUClusterAndCellDataMonitor::m_mutex
std::mutex m_mutex
This mutex is locked to ensure only one thread detects the monotired variables.
Definition: CaloGPUClusterAndCellDataMonitor.h:313
test_pyathena.parent
parent
Definition: test_pyathena.py:15
CaloRecGPU::ConstantDataHolder::m_cell_noise
CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellNoiseArr > m_cell_noise
Definition: DataHolders.h:26
ICaloClusterGPUInputTransformer
Base class for tools that convert event information from the Athena structures to the GPU-friendly fo...
Definition: CaloClusterGPUTransformers.h:66
CaloGPUClusterAndCellDataMonitor::m_matchingOptions
Gaudi::Property< MatchingOptions > m_matchingOptions
Option for adjusting the parameters for the cluster matching algorithm.
Definition: CaloGPUClusterAndCellDataMonitor.h:231
xAOD::CaloCluster_v1::DELTA_PHI
@ DELTA_PHI
Angular shower axis deviation ( ) from IP-to-Center.
Definition: CaloCluster_v1.h:126
xAOD::CaloCluster_v1::ENG_CALIB_DEAD_FCAL
@ ENG_CALIB_DEAD_FCAL
Attached Calibration Hit energy in dead material before FCAL, between FCAL and HEC.
Definition: CaloCluster_v1.h:241
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CaloGPUClusterAndCellDataMonitor::m_doClusters
bool m_doClusters
Definition: CaloGPUClusterAndCellDataMonitor.h:302
xAOD::CaloCluster_v1::phiSample
float phiSample(const CaloSample sampling) const
Retrieve barycenter in a given sample.
Definition: CaloCluster_v1.cxx:547
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
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
TauGNNUtils::Variables::Cluster::SECOND_LAMBDA
bool SECOND_LAMBDA(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:826
xAOD::CaloCluster_v1::FIRST_ENG_DENS
@ FIRST_ENG_DENS
First Moment in E/V.
Definition: CaloCluster_v1.h:143
CaloGPUClusterAndCellDataMonitor::m_extraComparedClusterPropertiesToDo
std::vector< bool > m_extraComparedClusterPropertiesToDo
Definition: CaloGPUClusterAndCellDataMonitor.h:296
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
CaloGPUClusterAndCellDataMonitor::pair_to_plot::match_in_energy
bool match_in_energy
Definition: CaloGPUClusterAndCellDataMonitor.h:267
Monitored.h
Header file to be included by clients of the Monitored infrastructure.
xAOD::CaloCluster_v1::getCellLinks
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version)
Definition: CaloCluster_v1.cxx:905
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
xAOD::CaloCluster_v1::ENG_BAD_CELLS
@ ENG_BAD_CELLS
Total em-scale energy of bad cells in this cluster.
Definition: CaloCluster_v1.h:148
CaloRecGPU::CellInfoArr
Definition: EventInfoDefinitions.h:188
CaloGPUClusterAndCellDataMonitor::m_comparedCellTypesToDo
std::vector< bool > m_comparedCellTypesToDo
Definition: CaloGPUClusterAndCellDataMonitor.h:298
xAOD::CaloCluster_v1::TILE_CONFIDENCE_LEVEL
@ TILE_CONFIDENCE_LEVEL
Confidence Level of a tile calorimeter cluster to be noise.
Definition: CaloCluster_v1.h:178
xAOD::CaloCluster_v1::ENG_CALIB_EME0
@ ENG_CALIB_EME0
Calibration Hit energy inside the cluster endcap presampler.
Definition: CaloCluster_v1.h:220
xAOD::CaloCluster_v1::ENG_FRAC_EM
@ ENG_FRAC_EM
Energy fraction in EM calorimeters.
Definition: CaloCluster_v1.h:139
CaloGPUClusterAndCellDataMonitor::filter_tool_by_name
bool filter_tool_by_name(const std::string &tool_name) const
Returns true if this tool should be plotted for.
Definition: CaloGPUClusterAndCellDataMonitor.cxx:255
xAOD::CaloCluster_v1::ENG_CALIB_DEAD_M
@ ENG_CALIB_DEAD_M
Attached Calibration Hit energy in dead material with medium matching (Angle < 0.5).
Definition: CaloCluster_v1.h:211
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
VP1PartSpect::E
@ E
Definition: VP1PartSpectFlags.h:21
CaloGPUClusterAndCellDataMonitor::compactify_clusters
StatusCode compactify_clusters(const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellInfoArr > &cell_info, CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellStateArr > &cell_state, CaloRecGPU::Helpers::CPU_object< CaloRecGPU::ClusterInfoArr > &clusters, CaloRecGPU::Helpers::CPU_object< CaloRecGPU::ClusterMomentsArr > &moments) const
Remove invalid clusters, reorder by ET and update the tags accordingly.
Definition: CaloGPUClusterAndCellDataMonitor.cxx:481
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
xAOD::CaloCluster_v1::ENG_CALIB_DEAD_HEC0
@ ENG_CALIB_DEAD_HEC0
Attached Calibration Hit energy in dead material between EME3 and HEC0.
Definition: CaloCluster_v1.h:238
CaloGPUClusterAndCellDataMonitor::m_doCells
bool m_doCells
If no properties are asked for, skip the relevant loops entirely...
Definition: CaloGPUClusterAndCellDataMonitor.h:302
CaloClusterCollectionProcessor.h
Base class for cluster processing tools called from CaloClusterMaker.
top::ISOLATION
@ ISOLATION
Definition: ScaleFactorRetriever.h:213
AtlCoolConsole.tool
tool
Definition: AtlCoolConsole.py:453
TauGNNUtils::Variables::Cluster::SECOND_R
bool SECOND_R(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:821
ClusterProperties
Definition: CaloGPUClusterAndCellDataMonitor.cxx:1103
CaloCell::ID
Identifier ID() const
get ID (from cached data member) non-virtual and inline for fast access
Definition: CaloCell.h:279
CaloRecGPU::ClusterMomentsArr
Definition: EventInfoDefinitions.h:342
xAOD::CaloCluster_v1::AVG_TILE_Q
@ AVG_TILE_Q
Sum(E_cell_Tile^2 Q_cell_Tile)/Sum(E_cell_Tile^2)
Definition: CaloCluster_v1.h:165
LArNewCalib_Delay_OFC_Cali.check
check
Definition: LArNewCalib_Delay_OFC_Cali.py:208
CaloGPUClusterAndCellDataMonitor::initialize_plotted_variables
StatusCode initialize_plotted_variables()
Definition: CaloGPUClusterAndCellDataMonitor.cxx:1513
xAOD::CaloCluster_v1::PHICALOFRAME
@ PHICALOFRAME
Phi in the calo frame (for egamma)
Definition: CaloCluster_v1.h:188
ICaloClusterGPUOutputTransformer
Base class for tools that convert event information from the GPU-friendly format used in CaloGPUHybri...
Definition: CaloClusterGPUTransformers.h:94
CaloRecGPU::ClusterTag::is_part_of_cluster
constexpr bool is_part_of_cluster() const
Definition: TagDefinitions.h:233
CALORECGPU_BASIC_CLUSTER_PROPERTY
#define CALORECGPU_BASIC_CLUSTER_PROPERTY(NAME,...)
Definition: CaloGPUClusterAndCellDataMonitor.cxx:1104
CaloGPUClusterAndCellDataMonitor::m_termThreshold
Gaudi::Property< float > m_termThreshold
Cell (terminal) threshold to use for cluster matching.
Definition: CaloGPUClusterAndCellDataMonitor.h:189
TauGNNUtils::Variables::Cluster::CENTER_MAG
bool CENTER_MAG(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:907
xAOD::CaloCluster_v1::ENG_CALIB_DEAD_TILEG3
@ ENG_CALIB_DEAD_TILEG3
Attached Calibration Hit energy in dead material before scintillator.
Definition: CaloCluster_v1.h:232
CaloGPUClusterAndCellDataMonitor::match_clusters_perfectly
StatusCode match_clusters_perfectly(sample_comparisons_holder &sch, const CaloRecGPU::ConstantDataHolder &constant_data, const CaloRecGPU::CellInfoArr &cell_info, const CaloRecGPU::CellStateArr &cell_state_1, const CaloRecGPU::CellStateArr &cell_state_2, const CaloRecGPU::ClusterInfoArr &cluster_info_1, const CaloRecGPU::ClusterInfoArr &cluster_info_2, const CaloRecGPU::ClusterMomentsArr &, const CaloRecGPU::ClusterMomentsArr &, const bool match_without_shared) const
Definition: CaloGPUClusterAndCellDataMonitor.cxx:965
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
xAOD::CaloCluster_v1::FIRST_ETA
@ FIRST_ETA
First Moment in .
Definition: CaloCluster_v1.h:122
MatchingOptions
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:355
CellProperties
Definition: CaloGPUClusterAndCellDataMonitor.cxx:1349
ExtraClusterComparisons
Definition: CaloGPUClusterAndCellDataMonitor.cxx:1299
xAOD::CaloCluster_v1::DELTA_THETA
@ DELTA_THETA
Angular shower axis deviation ( ) from IP-to-Center.
Definition: CaloCluster_v1.h:128
DeMoScan.index
string index
Definition: DeMoScan.py:362
xAOD::CaloCluster_v1::eSample
float eSample(const CaloSample sampling) const
Definition: CaloCluster_v1.cxx:521
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
CaloGPUClusterAndCellDataMonitor::m_numToolsToKeep
int m_numToolsToKeep
The number of tools that will actually need to be kept in memory for combined plotting.
Definition: CaloGPUClusterAndCellDataMonitor.h:261
a
TList * a
Definition: liststreamerinfos.cxx:10
xAOD::TauJetParameters::numCells
@ numCells
Definition: TauDefs.h:171
xAOD::CaloCluster_v1::ENG_CALIB_DEAD_TOT
@ ENG_CALIB_DEAD_TOT
Attached Calibration Hit energy in dead material.
Definition: CaloCluster_v1.h:224
y
#define y
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
CaloGPUClusterAndCellDataMonitor::update_plots_start
virtual StatusCode update_plots_start(const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const xAOD::CaloClusterContainer *cluster_collection_ptr) const override
Definition: CaloGPUClusterAndCellDataMonitor.cxx:115
CaloGPUClusterAndCellDataMonitor::add_combination
StatusCode add_combination(const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const int index_1, const int index_2, const std::string &prefix, const bool match_in_energy, const bool match_without_shared, const bool match_perfectly) const
Definition: CaloGPUClusterAndCellDataMonitor.cxx:1843
CondAlgsOpts.found
int found
Definition: CondAlgsOpts.py:101
python.CaloScaleNoiseConfig.str
str
Definition: CaloScaleNoiseConfig.py:78
CaloSwCorrections.time
def time(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:242
xAOD::CaloCluster_v1::SIGNIFICANCE
@ SIGNIFICANCE
Cluster significance.
Definition: CaloCluster_v1.h:157
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
ref
const boost::regex ref(r_ef)
xAOD::CaloCluster_v1::PHI2CALOFRAME
@ PHI2CALOFRAME
Phi of sampling 2 in the calo frame (for egamma)
Definition: CaloCluster_v1.h:192
eFEXNTuple.delta_phi
def delta_phi(phi1, phi2)
Definition: eFEXNTuple.py:15
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
CaloRecGPU::QualityProvenance
Definition: EventInfoDefinitions.h:116
CUDAFriendlyClasses.h
F
#define F(x, y, z)
Definition: MD5.cxx:112
RunTileMonitoring.clusters
clusters
Definition: RunTileMonitoring.py:133
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:569
TauGNNUtils::Variables::Cluster::FIRST_ENG_DENS
bool FIRST_ENG_DENS(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:893
CaloRecGPU::ConstantDataHolder
Definition: DataHolders.h:19
xAOD::CaloCluster_v1::ENG_CALIB_DEAD_L
@ ENG_CALIB_DEAD_L
Attached Calibration Hit energy in dead material with loose matching (Angle < 1.0).
Definition: CaloCluster_v1.h:208
CaloRecGPU::CellInfoArr::is_valid
constexpr bool is_valid(const int cell) const
Definition: EventInfoDefinitions.h:316
xAOD::CaloCluster_v1::LATERAL
@ LATERAL
Normalized lateral moment.
Definition: CaloCluster_v1.h:137
CaloGPUClusterAndCellDataMonitor::m_seed_weight
double m_seed_weight
Definition: CaloGPUClusterAndCellDataMonitor.h:242
CaloGPUClusterAndCellDataMonitor
Places (matched) cluster and cell properties in monitored variables to enable plotting with the Athen...
Definition: CaloGPUClusterAndCellDataMonitor.h:42
xAOD::CaloCluster_v1::SECOND_TIME
@ SECOND_TIME
Second moment of cell time distribution in cluster.
Definition: CaloCluster_v1.h:180
str
Definition: BTagTrackIpAccessor.cxx:11
CaloGPUClusterAndCellDataMonitor::sample_comparisons_holder
Definition: CaloGPUClusterAndCellDataMonitor.h:129
CaloGPUClusterAndCellDataMonitor::sample_comparisons_holder::unmatched_ref_list
std::vector< int > unmatched_ref_list
Definition: CaloGPUClusterAndCellDataMonitor.h:131
xAOD::CaloCluster_v1::DELTA_ALPHA
@ DELTA_ALPHA
Angular shower axis deviation ( ) from IP-to-Center.
Definition: CaloCluster_v1.h:130
xAOD::CaloCluster_v1::ENG_CALIB_FRAC_HAD
@ ENG_CALIB_FRAC_HAD
Calibration Hit energy inside the cluster caused by charged pi+ and pi-.
Definition: CaloCluster_v1.h:251
xAOD::CaloCluster_v1::CELL_SIGNIFICANCE
@ CELL_SIGNIFICANCE
Cell significance = E/sig of the cell with the largest |E|/sig.
Definition: CaloCluster_v1.h:159
xAOD::CaloCluster_v1::ENG_CALIB_OUT_L
@ ENG_CALIB_OUT_L
Attached Calibration Hit energy outside clusters but inside the calorimeter with loose matching (Angl...
Definition: CaloCluster_v1.h:196
xAOD::CaloCluster_v1::ENG_CALIB_DEAD_EME0
@ ENG_CALIB_DEAD_EME0
Attached Calibration Hit energy in dead material before EME0, between EME0 and EME1.
Definition: CaloCluster_v1.h:235
CaloCondBlobAlgs_fillNoiseFromASCII.tag
string tag
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:24
xAOD::CaloCluster_v1::ENG_CALIB_OUT_T
@ ENG_CALIB_OUT_T
Attached Calibration Hit energy outside clusters but inside the calorimeter with tight matching (Angl...
Definition: CaloCluster_v1.h:204
CaloGPUClusterAndCellDataMonitor::m_toolCombinations
std::vector< pair_to_plot > m_toolCombinations
Definition: CaloGPUClusterAndCellDataMonitor.h:272
xAOD::CaloCluster_v1::BAD_CELLS_CORR_E
@ BAD_CELLS_CORR_E
Energy of bad cells with energy density average correction applied.
Definition: CaloCluster_v1.h:153
Monitored::Scalar
Declare a monitored scalar variable.
Definition: MonitoredScalar.h:34
AthAlgTool
Definition: AthAlgTool.h:26
CaloRecGPU::CellInfoArr::is_bad
static constexpr bool is_bad(const bool is_tile, const QualityProvenance qp, const bool treat_L1_predicted_as_good=false)
GPU version of CaloBadCellHelper::isBad.
Definition: EventInfoDefinitions.h:199
athena.opts
opts
Definition: athena.py:86
xAOD::CaloCluster_v1::ETACALOFRAME
@ ETACALOFRAME
Eta in the calo frame (for egamma)
Definition: CaloCluster_v1.h:187
xAOD::CaloCluster_v1::N_BAD_CELLS_CORR
@ N_BAD_CELLS_CORR
Number of bad cells with energy density average correction applied.
Definition: CaloCluster_v1.h:151
xAOD::CaloCluster_v1::LONGITUDINAL
@ LONGITUDINAL
Normalized longitudinal moment.
Definition: CaloCluster_v1.h:138
CaloRecGPU
Definition: BaseDefinitions.h:11
CaloGPUClusterAndCellDataMonitor::ATLAS_THREAD_SAFE
std::map< std::string, std::atomic< size_t > > m_numClustersPerTool ATLAS_THREAD_SAFE
Counts the total number of clusters per tool.
Definition: CaloGPUClusterAndCellDataMonitor.h:275
xAOD::CaloCluster_v1::NVERTEX_FRACTION
@ NVERTEX_FRACTION
slightly updated vertex fraction more pile up independent (similar to nJVF)
Definition: CaloCluster_v1.h:185
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
xAOD::CaloCluster_v1::N_BAD_CELLS
@ N_BAD_CELLS
number of bad cells
Definition: CaloCluster_v1.h:149
CALORECGPU_BASIC_CELL_TYPE
#define CALORECGPU_BASIC_CELL_TYPE(NAME,...)
Definition: CaloGPUClusterAndCellDataMonitor.cxx:1461
CaloGPUClusterAndCellDataMonitor::convert_to_GPU_data_structures
StatusCode convert_to_GPU_data_structures(const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, const xAOD::CaloClusterContainer *cluster_collection_ptr, CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellInfoArr > &cell_info, CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellStateArr > &cell_state, CaloRecGPU::Helpers::CPU_object< CaloRecGPU::ClusterInfoArr > &clusters, CaloRecGPU::Helpers::CPU_object< CaloRecGPU::ClusterMomentsArr > &moments) const
Definition: CaloGPUClusterAndCellDataMonitor.cxx:265
xAOD::CaloCluster_v1::e
virtual double e() const
The total energy of the particle.
Definition: CaloCluster_v1.cxx:265
xAOD::CaloCluster_v1::CENTER_Y
@ CENTER_Y
Cluster Centroid ( )
Definition: CaloCluster_v1.h:132
xAOD::CaloCluster_v1::ENG_CALIB_DEAD_EMB0
@ ENG_CALIB_DEAD_EMB0
Attached Calibration Hit energy in dead material before EMB0, between EMB0 and EMB1.
Definition: CaloCluster_v1.h:227
constants.EME2
int EME2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:56
python.CaloScaleNoiseConfig.args
args
Definition: CaloScaleNoiseConfig.py:80
CaloRecGPU::ClusterTag::secondary_cluster_weight
constexpr int32_t secondary_cluster_weight() const
Definition: TagDefinitions.h:263
WriteCellNoiseToCool.noise
noise
Definition: WriteCellNoiseToCool.py:380
CaloGPUClusterAndCellDataMonitor::m_toolsToPlot
Gaudi::Property< std::vector< SimpleSingleTool > > m_toolsToPlot
Tools to plot individually.
Definition: CaloGPUClusterAndCellDataMonitor.h:221
CaloGPUClusterAndCellDataMonitor::m_doCombinedClusters
bool m_doCombinedClusters
Definition: CaloGPUClusterAndCellDataMonitor.h:302
match
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition: hcg.cxx:356
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
xAOD::CaloCluster_v1::ENG_POS
@ ENG_POS
Total positive Energy of this cluster.
Definition: CaloCluster_v1.h:156
CaloGPUClusterAndCellDataMonitor::m_comparedCellPropertiesToDo
std::vector< bool > m_comparedCellPropertiesToDo
Definition: CaloGPUClusterAndCellDataMonitor.h:297
CaloGPUClusterAndCellDataMonitor::m_pairsToPlot
Gaudi::Property< std::vector< SimpleToolPair > > m_pairsToPlot
Pairs of tools to compare.
Definition: CaloGPUClusterAndCellDataMonitor.h:226
xAOD::CaloCluster_v1::numberCellsInSampling
int numberCellsInSampling(const CaloSample samp, bool isInnerWheel=false) const
Returns number of cells in given sampling.
Definition: CaloCluster_v1.cxx:802
xAOD::CaloCluster_v1::BADLARQ_FRAC
@ BADLARQ_FRAC
Energy fraction of LAr cells with quality larger than a given cut.
Definition: CaloCluster_v1.h:155