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