ATLAS Offline Software
TopoAutomatonSplitting.cxx
Go to the documentation of this file.
1 //
2 // Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 //
4 // Dear emacs, this is -*- c++ -*-
5 //
6 
9 
10 
11 #include <string>
12 #include <climits> //For CHAR_BIT... though it's a slightly inefficient way of saying 8.
13 
15 
16 #include "boost/chrono/chrono.hpp"
17 #include "boost/chrono/thread_clock.hpp"
18 
19 #include "MacroHelpers.h"
20 
21 using namespace CaloRecGPU;
22 using namespace TASplitting;
23 
24 TopoAutomatonSplitting::TopoAutomatonSplitting(const std::string & type, const std::string & name, const IInterface * parent):
25  base_class(type, name, parent),
26  CaloGPUTimed(this)
27 {
28 }
29 
31 {
33 
34  using PackType = decltype(m_options.m_options->valid_sampling_primary);
35 
36  static_assert(CaloCell_ID::getNumberOfSamplings() <= sizeof(PackType) * CHAR_BIT, "We are assuming that we have fewer samplings that bits per int!");
37 
38  auto get_option_from_string = [](const std::string & str, bool & failed)
39  {
40  failed = false;
42  CRGPU_CHEAP_STRING_TO_ENUM( str, CaloCell_ID,
44  EMB1,
45  EMB2,
46  EMB3,
48  EME1,
49  EME2,
50  EME3,
51  HEC0,
52  HEC1,
53  HEC2,
54  HEC3,
55  TileBar0,
56  TileBar1,
57  TileBar2,
58  TileGap1,
59  TileGap2,
60  TileGap3,
61  TileExt0,
62  TileExt1,
63  TileExt2,
64  FCAL0,
65  FCAL1,
66  FCAL2
67  )
68  )
69  else
70  {
71  failed = true;
72  return CaloCell_ID::Unknown;
73  }
74  };
75 
76 
77  auto process_sampling = [&get_option_from_string](const std::vector<std::string> & sampling_names, std::string & invalid_names, PackType & sampling_option)
78  {
79  sampling_option = 0;
80  for (const std::string & samp_name : sampling_names)
81  {
82  bool failed = false;
83  const PackType sampling = (PackType) get_option_from_string(samp_name, failed);
84 
85  if (failed)
86  {
87  if (invalid_names.size() == 0)
88  {
89  invalid_names = "'" + samp_name + "'";
90  }
91  else
92  {
93  invalid_names += ", '" + samp_name + "'";
94  }
95  }
96  else
97  {
98  sampling_option |= ((PackType) 1) << sampling;
99  }
100  }
101  };
102 
103  std::string invalid_names;
104 
105  process_sampling(m_samplingNames, invalid_names, m_options.m_options->valid_sampling_primary);
106 
107  if (invalid_names.size() > 0)
108  {
109  ATH_MSG_ERROR( "Calorimeter samplings " << invalid_names
110  << " are not a valid Calorimeter sampling name and will be ignored! "
111  << "Valid names are: "
112  << "PreSamplerB, EMB1, EMB2, EMB3, "
113  << "PreSamplerE, EME1, EME2, EME3, "
114  << "HEC0, HEC1, HEC2, HEC3, "
115  << "TileBar0, TileBar1, TileBar2, "
116  << "TileGap1, TileGap2, TileGap3, "
117  << "TileExt0, TileExt1, TileExt2, "
118  << "FCAL0, FCAL1, FCAL2." );
119  }
120 
121  invalid_names.clear();
122 
123  process_sampling(m_secondarySamplingNames, invalid_names, m_options.m_options->valid_sampling_secondary);
124 
125  if (invalid_names.size() > 0)
126  {
127  ATH_MSG_ERROR( "Calorimeter samplings " << invalid_names
128  << " are not a valid Calorimeter sampling name and will be ignored! "
129  << "Valid names are: "
130  << "PreSamplerB, EMB1, EMB2, EMB3, "
131  << "PreSamplerE, EME1, EME2, EME3, "
132  << "HEC0, HEC1, HEC2, HEC3, "
133  << "TileBar0, TileBar1, TileBar2, "
134  << "TileGap1, TileGap2, TileGap3, "
135  << "TileExt0, TileExt1, TileExt2, "
136  << "FCAL0, FCAL1, FCAL2." );
137  }
138 
139  auto get_neighbour_option_from_string = [](const std::string & str, bool & failed)
140  {
141  failed = false;
144  prevInPhi,
145  nextInPhi,
146  prevInEta,
147  nextInEta,
148  faces2D,
149  corners2D,
150  all2D,
151  prevInSamp,
152  nextInSamp,
153  upAndDown,
154  prevSubDet,
155  nextSubDet,
156  all3D,
157  corners3D,
161  super3D
162  )
163  )
164  //I know Topological Clustering only supports a subset of those,
165  //but this is supposed to be a general data exporting tool...
166  else
167  {
168  failed = true;
169  return LArNeighbours::super3D;
170  }
171  };
172 
173  bool neigh_failed = false;
174  m_options.m_options->neighbour_options = (unsigned int) get_neighbour_option_from_string(m_neighborOptionString, neigh_failed);
175 
176  if (neigh_failed)
177  {
178  ATH_MSG_ERROR("Invalid Neighbour Option: " << m_neighborOptionString);
179  }
180 
181  //We must repeat this printing part because ATH_MSG_ERROR
182  //is a macro that apparently calls a this->msg(...) function.
183  //Of course it won't work within a lambda...
184 
185  m_options.m_options->min_num_cells = m_nCells;
186  m_options.m_options->min_maximum_energy = m_minEnergy;
187  m_options.m_options->EM_shower_scale = m_emShowerScale;
188  m_options.m_options->share_border_cells = m_shareBorderCells;
189  m_options.m_options->use_absolute_energy = m_absOpt;
190  m_options.m_options->treat_L1_predicted_as_good = m_treatL1PredictedCellsAsGood;
191 
192  m_options.m_options->limit_HECIW_and_FCal_neighs = m_restrictHECIWandFCalNeighbors;
193  m_options.m_options->limit_PS_neighs = m_restrictPSNeighbors;
194 
195  ATH_CHECK( m_kernelSizeOptimizer.retrieve() );
196 
197  return StatusCode::SUCCESS;
198 }
199 
201 {
204 
205  return StatusCode::SUCCESS;
206 }
207 
208 StatusCode TopoAutomatonSplitting::execute(const EventContext & ctx, const ConstantDataHolder & constant_data,
209  EventDataHolder & event_data, void * /*temporary_buffer*/ ) const
210 {
211 
212  using clock_type = boost::chrono::thread_clock;
213  auto time_cast = [](const auto & before, const auto & after)
214  {
215  return boost::chrono::duration_cast<boost::chrono::microseconds>(after - before).count();
216  };
217 
218  static_assert(sizeof(TopoAutomatonSplittingTemporaries) <= sizeof(ClusterMomentsArr), "We store the temporaries in the cluster moments, so the sizes must be compatible!");
219 
220  const auto start = clock_type::now();
221  const auto preprocessing_end = clock_type::now();
222 
223  fillNeighbours(event_data, constant_data, m_options, *(m_kernelSizeOptimizer.get()), m_measureTimes);
224 
225  const auto after_neighs = clock_type::now();
226 
227  findLocalMaxima(event_data, constant_data, m_options, *(m_kernelSizeOptimizer.get()), m_measureTimes);
228 
229  const auto after_maxima = clock_type::now();
230 
231  excludeSecondaryMaxima(event_data, constant_data, m_options, *(m_kernelSizeOptimizer.get()), m_measureTimes);
232 
233  const auto after_secondary_maxima = clock_type::now();
234 
235  splitClusterGrowing(event_data, constant_data, m_options, *(m_kernelSizeOptimizer.get()), m_measureTimes);
236 
237  const auto after_growing = clock_type::now();
238 
239  cellWeightingAndFinalization(event_data, constant_data, m_options, *(m_kernelSizeOptimizer.get()), m_measureTimes);
240 
241  const auto end = clock_type::now();
242 
243  if (m_measureTimes)
244  {
245  record_times(ctx.evt(),
246  time_cast(start, preprocessing_end),
247  time_cast(preprocessing_end, after_neighs),
248  time_cast(after_neighs, after_maxima),
249  time_cast(after_maxima, after_secondary_maxima),
250  time_cast(after_secondary_maxima, after_growing),
251  time_cast(after_growing, end)
252  );
253  }
254 
255  return StatusCode::SUCCESS;
256 
257 
258 }
259 
260 
262 {
263  if (m_measureTimes)
264  {
265  print_times("Preprocessing Fill_List_of_Intra-Cluster_Neighbours Find_Local_Maxima Find_Secondary_Maxima Splitter_Tag_Propagation Cell_Weighting_And_Finalization", 6);
266  }
267  return StatusCode::SUCCESS;
268 }
TASplitting::TopoAutomatonSplittingTemporaries
Definition: TopoAutomatonSplittingImpl.h:327
LArNeighbours::nextSuperCalo
@ nextSuperCalo
Definition: LArNeighbours.h:28
GetLCDefs::Unknown
@ Unknown
Definition: GetLCDefs.h:21
TopoAutomatonSplitting::finalize
virtual StatusCode finalize() override
Definition: TopoAutomatonSplitting.cxx:261
TASplitting
Definition: TopoAutomatonSplittingImpl.h:20
LArNeighbours::corners3D
@ corners3D
Definition: LArNeighbours.h:25
LArNeighbours::upAndDown
@ upAndDown
Definition: LArNeighbours.h:21
CaloCell_ID_FCS::TileExt2
@ TileExt2
Definition: FastCaloSim_CaloCell_ID.h:39
constants.EMB1
int EMB1
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:53
TASplitting::TASOptionsHolder::sendToGPU
void sendToGPU(const bool clear_CPU=false)
TopoAutomatonSplitting::m_neighborOptionString
Gaudi::Property< std::string > m_neighborOptionString
type of neighbor relations to use.
Definition: TopoAutomatonSplitting.h:165
TopoAutomatonSplitting::initialize_non_CUDA
virtual StatusCode initialize_non_CUDA() override
Initialization that does not invoke CUDA functions.
Definition: TopoAutomatonSplitting.cxx:30
LArNeighbours::corners2D
@ corners2D
Definition: LArNeighbours.h:17
CaloCell_ID_FCS::TileExt0
@ TileExt0
Definition: FastCaloSim_CaloCell_ID.h:37
CaloCell_ID_FCS::TileBar1
@ TileBar1
Definition: FastCaloSim_CaloCell_ID.h:32
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:13
TopoAutomatonSplitting::m_secondarySamplingNames
Gaudi::Property< std::vector< std::string > > m_secondarySamplingNames
vector of names of the secondary calorimeter samplings to consider.
Definition: TopoAutomatonSplitting.h:77
LArNeighbours::faces2D
@ faces2D
Definition: LArNeighbours.h:16
TASplitting::splitClusterGrowing
void splitClusterGrowing(CaloRecGPU::EventDataHolder &holder, const CaloRecGPU::ConstantDataHolder &instance_data, const TASOptionsHolder &options, const IGPUKernelSizeOptimizer &optimizer, const bool synchronize=false, CaloRecGPU::CUDA_Helpers::CUDAStreamPtrHolder stream_to_use={})
LArNeighbours::nextSubDet
@ nextSubDet
Definition: LArNeighbours.h:23
CaloCell_ID_FCS::FCAL1
@ FCAL1
Definition: FastCaloSim_CaloCell_ID.h:41
TASplitting::TASOptionsHolder::m_options
CaloRecGPU::Helpers::CPU_object< TopoAutomatonSplittingOptions > m_options
Definition: TopoAutomatonSplittingImpl.h:478
TopoAutomatonSplitting::m_samplingNames
Gaudi::Property< std::vector< std::string > > m_samplingNames
vector of names of the calorimeter samplings to consider for seeds.
Definition: TopoAutomatonSplitting.h:68
CaloCell_ID_FCS::HEC2
@ HEC2
Definition: FastCaloSim_CaloCell_ID.h:29
LArNeighbours::prevInPhi
@ prevInPhi
Definition: LArNeighbours.h:12
CaloCell_ID_FCS::TileGap3
@ TileGap3
Definition: FastCaloSim_CaloCell_ID.h:36
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
CaloGPUTimed
Base class to provide some basic common infrastructure for timing measurements...
Definition: CaloGPUTimed.h:25
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:92
CaloCell_ID.h
TopoAutomatonSplitting::initialize_CUDA
virtual StatusCode initialize_CUDA() override
Initialization that invokes CUDA functions.
Definition: TopoAutomatonSplitting.cxx:200
CRGPU_CHEAP_STRING_TO_ENUM
#define CRGPU_CHEAP_STRING_TO_ENUM(VAR, PREFIX, ONE,...)
Checks a string variable, VAR, for matching enum identifiers (ONE and the remaining variadic argument...
Definition: MacroHelpers.h:148
LArNeighbours::nextInSamp
@ nextInSamp
Definition: LArNeighbours.h:20
LArNeighbours::nextInPhi
@ nextInPhi
Definition: LArNeighbours.h:13
python.handimod.now
now
Definition: handimod.py:674
CaloRecGPU::EventDataHolder
Definition: DataHolders.h:35
CaloCell_ID_FCS::HEC1
@ HEC1
Definition: FastCaloSim_CaloCell_ID.h:28
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
TopoAutomatonSplitting::m_restrictHECIWandFCalNeighbors
Gaudi::Property< bool > m_restrictHECIWandFCalNeighbors
if set to true limit the neighbors in HEC IW and FCal2&3.
Definition: TopoAutomatonSplitting.h:177
constants.EMB2
int EMB2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:54
TopoAutomatonSplitting::m_options
TASplitting::TASOptionsHolder m_options
Options for the algorithm, held in a GPU-friendly way.
Definition: TopoAutomatonSplitting.h:195
CaloCell_ID_FCS::TileBar0
@ TileBar0
Definition: FastCaloSim_CaloCell_ID.h:31
LArNeighbours::all3DwithCorners
@ all3DwithCorners
Definition: LArNeighbours.h:26
CRGPU_RECURSIVE_MACRO
#define CRGPU_RECURSIVE_MACRO(...)
Expands recursive macros.
Definition: MacroHelpers.h:70
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
CaloCell_ID_FCS::TileGap2
@ TileGap2
Definition: FastCaloSim_CaloCell_ID.h:35
python.CaloAddPedShiftConfig.str
str
Definition: CaloAddPedShiftConfig.py:42
CaloGPUTimed::print_times
void print_times(const std::string &header, const size_t time_size) const
Definition: CaloGPUTimed.h:143
test_pyathena.parent
parent
Definition: test_pyathena.py:15
constants.EME1
int EME1
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:55
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
LArNeighbours::prevSuperCalo
@ prevSuperCalo
Definition: LArNeighbours.h:27
LArNeighbours::prevSubDet
@ prevSubDet
Definition: LArNeighbours.h:22
TopoAutomatonSplitting::m_kernelSizeOptimizer
ServiceHandle< IGPUKernelSizeOptimizerSvc > m_kernelSizeOptimizer
Handle to the CUDA kernel block and grid size optimization service.
Definition: TopoAutomatonSplitting.h:198
TASplitting::cellWeightingAndFinalization
void cellWeightingAndFinalization(CaloRecGPU::EventDataHolder &holder, const CaloRecGPU::ConstantDataHolder &instance_data, const TASOptionsHolder &options, const IGPUKernelSizeOptimizer &optimizer, const bool synchronize=false, CaloRecGPU::CUDA_Helpers::CUDAStreamPtrHolder stream_to_use={})
TASplitting::excludeSecondaryMaxima
void excludeSecondaryMaxima(CaloRecGPU::EventDataHolder &holder, const CaloRecGPU::ConstantDataHolder &instance_data, const TASOptionsHolder &options, const IGPUKernelSizeOptimizer &optimizer, const bool synchronize=false, CaloRecGPU::CUDA_Helpers::CUDAStreamPtrHolder stream_to_use={})
TopoAutomatonSplitting::m_shareBorderCells
Gaudi::Property< bool > m_shareBorderCells
share cells at the border between two local maxima
Definition: TopoAutomatonSplitting.h:114
TASplitting::TASOptionsHolder::allocate
void allocate()
Definition: TopoAutomatonSplittingImpl.h:482
CaloCell_ID_FCS::TileGap1
@ TileGap1
Definition: FastCaloSim_CaloCell_ID.h:34
LArNeighbours::prevInSamp
@ prevInSamp
Definition: LArNeighbours.h:19
LArNeighbours::super3D
@ super3D
Definition: LArNeighbours.h:29
MacroHelpers.h
TopoAutomatonSplitting::m_emShowerScale
Gaudi::Property< float > m_emShowerScale
typical EM shower scale to use for distance criteria in shared cells
Definition: TopoAutomatonSplitting.h:129
TopoAutomatonSplitting::m_restrictPSNeighbors
Gaudi::Property< bool > m_restrictPSNeighbors
if set to true limit the neighbors in presampler Barrel and Endcap.
Definition: TopoAutomatonSplitting.h:187
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
CaloCell_ID_FCS::TileExt1
@ TileExt1
Definition: FastCaloSim_CaloCell_ID.h:38
CaloCell_ID_FCS::EME3
@ EME3
Definition: FastCaloSim_CaloCell_ID.h:26
TopoAutomatonSplitting::execute
virtual StatusCode execute(const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, CaloRecGPU::EventDataHolder &event_data, void *temporary_buffer) const override
Definition: TopoAutomatonSplitting.cxx:208
CaloRecGPU::ClusterMomentsArr
Definition: EventInfoDefinitions.h:341
CaloSampling::getNumberOfSamplings
static constexpr unsigned int getNumberOfSamplings()
Get number of available samplings.
Definition: Calorimeter/CaloGeoHelpers/CaloGeoHelpers/CaloSampling.h:30
TopoAutomatonSplitting.h
CaloCell_ID_FCS::HEC0
@ HEC0
Definition: FastCaloSim_CaloCell_ID.h:27
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
CaloGPUTimed::record_times
void record_times(const size_t event_num, const std::vector< size_t > &times) const
Definition: CaloGPUTimed.h:86
TopoAutomatonSplittingImpl.h
TASplitting::findLocalMaxima
void findLocalMaxima(CaloRecGPU::EventDataHolder &holder, const CaloRecGPU::ConstantDataHolder &instance_data, const TASOptionsHolder &options, const IGPUKernelSizeOptimizer &optimizer, const bool synchronize=false, CaloRecGPU::CUDA_Helpers::CUDAStreamPtrHolder stream_to_use={})
CaloGPUTimed::m_measureTimes
Gaudi::Property< bool > m_measureTimes
If true, times are recorded to the file given by m_timeFileName.
Definition: CaloGPUTimed.h:46
CaloCell_ID_FCS::PreSamplerE
@ PreSamplerE
Definition: FastCaloSim_CaloCell_ID.h:23
CaloCell_ID_FCS::PreSamplerB
@ PreSamplerB
Definition: FastCaloSim_CaloCell_ID.h:19
LArNeighbours::nextInEta
@ nextInEta
Definition: LArNeighbours.h:15
TopoAutomatonSplitting::m_absOpt
Gaudi::Property< bool > m_absOpt
if set to true, splitter only looks at absolute value of Energy in order to identify potential seed c...
Definition: TopoAutomatonSplitting.h:134
BasicClusterInfoCalculator::register_kernels
void register_kernels(IGPUKernelSizeOptimizer &optimizer)
CaloRecGPU::ConstantDataHolder
Definition: DataHolders.h:19
LArNeighbours
Definition: LArNeighbours.h:11
TopoAutomatonSplitting::m_minEnergy
Gaudi::Property< float > m_minEnergy
local maxima need at least this energy content
Definition: TopoAutomatonSplitting.h:93
CaloCell_ID_FCS::FCAL2
@ FCAL2
Definition: FastCaloSim_CaloCell_ID.h:42
LArNeighbours::all3D
@ all3D
Definition: LArNeighbours.h:24
LArNeighbours::prevInEta
@ prevInEta
Definition: LArNeighbours.h:14
str
Definition: BTagTrackIpAccessor.cxx:11
TopoAutomatonSplitting::m_nCells
Gaudi::Property< int > m_nCells
local maxima need at least this number of neighbors to become seeds
Definition: TopoAutomatonSplitting.h:86
TASplitting::fillNeighbours
void fillNeighbours(CaloRecGPU::EventDataHolder &holder, const CaloRecGPU::ConstantDataHolder &instance_data, const TASOptionsHolder &options, const IGPUKernelSizeOptimizer &optimizer, const bool synchronize=false, CaloRecGPU::CUDA_Helpers::CUDAStreamPtrHolder stream_to_use={})
CaloCell_ID_FCS::HEC3
@ HEC3
Definition: FastCaloSim_CaloCell_ID.h:30
TopoAutomatonSplitting::m_treatL1PredictedCellsAsGood
Gaudi::Property< bool > m_treatL1PredictedCellsAsGood
if set to true treat cells with a dead OTX which can be predicted by L1 trigger info as good instead ...
Definition: TopoAutomatonSplitting.h:139
TopoAutomatonSplitting::TopoAutomatonSplitting
TopoAutomatonSplitting(const std::string &type, const std::string &name, const IInterface *parent)
Definition: TopoAutomatonSplitting.cxx:24
CaloRecGPU
Definition: BaseDefinitions.h:11
CaloCell_ID_FCS::FCAL0
@ FCAL0
Definition: FastCaloSim_CaloCell_ID.h:40
CaloCell_ID_FCS::EMB3
@ EMB3
Definition: FastCaloSim_CaloCell_ID.h:22
CaloCell_ID_FCS::TileBar2
@ TileBar2
Definition: FastCaloSim_CaloCell_ID.h:33
LArNeighbours::all2D
@ all2D
Definition: LArNeighbours.h:18
constants.EME2
int EME2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:56