ATLAS Offline Software
TopoAutomatonSplitting.cxx
Go to the documentation of this file.
1 //
2 // Copyright (C) 2002-2023 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):
26  CaloGPUTimed(this)
27 {
28  declareInterface<CaloClusterGPUProcessor> (this);
29 
30 }
31 
33 {
35 
36  using PackType = decltype(m_options.m_options->valid_sampling_primary);
37 
38  static_assert(CaloCell_ID::getNumberOfSamplings() <= sizeof(PackType) * CHAR_BIT, "We are assuming that we have fewer samplings that bits per int!");
39 
40  auto get_option_from_string = [](const std::string & str, bool & failed)
41  {
42  failed = false;
44  CRGPU_CHEAP_STRING_TO_ENUM( str, CaloCell_ID,
46  EMB1,
47  EMB2,
48  EMB3,
50  EME1,
51  EME2,
52  EME3,
53  HEC0,
54  HEC1,
55  HEC2,
56  HEC3,
57  TileBar0,
58  TileBar1,
59  TileBar2,
60  TileGap1,
61  TileGap2,
62  TileGap3,
63  TileExt0,
64  TileExt1,
65  TileExt2,
66  FCAL0,
67  FCAL1,
68  FCAL2
69  )
70  )
71  else
72  {
73  failed = true;
74  return CaloCell_ID::Unknown;
75  }
76  };
77 
78 
79  auto process_sampling = [&get_option_from_string](const std::vector<std::string> & sampling_names, std::string & invalid_names, PackType & sampling_option)
80  {
81  sampling_option = 0;
82  for (const std::string & samp_name : sampling_names)
83  {
84  bool failed = false;
85  const PackType sampling = (PackType) get_option_from_string(samp_name, failed);
86 
87  if (failed)
88  {
89  if (invalid_names.size() == 0)
90  {
91  invalid_names = "'" + samp_name + "'";
92  }
93  else
94  {
95  invalid_names += ", '" + samp_name + "'";
96  }
97  }
98  else
99  {
100  sampling_option |= ((PackType) 1) << sampling;
101  }
102  }
103  };
104 
105  std::string invalid_names;
106 
107  process_sampling(m_samplingNames, invalid_names, m_options.m_options->valid_sampling_primary);
108 
109  if (invalid_names.size() > 0)
110  {
111  ATH_MSG_ERROR( "Calorimeter samplings " << invalid_names
112  << " are not a valid Calorimeter sampling name and will be ignored! "
113  << "Valid names are: "
114  << "PreSamplerB, EMB1, EMB2, EMB3, "
115  << "PreSamplerE, EME1, EME2, EME3, "
116  << "HEC0, HEC1, HEC2, HEC3, "
117  << "TileBar0, TileBar1, TileBar2, "
118  << "TileGap1, TileGap2, TileGap3, "
119  << "TileExt0, TileExt1, TileExt2, "
120  << "FCAL0, FCAL1, FCAL2." );
121  }
122 
123  invalid_names.clear();
124 
125  process_sampling(m_secondarySamplingNames, invalid_names, m_options.m_options->valid_sampling_secondary);
126 
127  if (invalid_names.size() > 0)
128  {
129  ATH_MSG_ERROR( "Calorimeter samplings " << invalid_names
130  << " are not a valid Calorimeter sampling name and will be ignored! "
131  << "Valid names are: "
132  << "PreSamplerB, EMB1, EMB2, EMB3, "
133  << "PreSamplerE, EME1, EME2, EME3, "
134  << "HEC0, HEC1, HEC2, HEC3, "
135  << "TileBar0, TileBar1, TileBar2, "
136  << "TileGap1, TileGap2, TileGap3, "
137  << "TileExt0, TileExt1, TileExt2, "
138  << "FCAL0, FCAL1, FCAL2." );
139  }
140 
141  auto get_neighbour_option_from_string = [](const std::string & str, bool & failed)
142  {
143  failed = false;
146  prevInPhi,
147  nextInPhi,
148  prevInEta,
149  nextInEta,
150  faces2D,
151  corners2D,
152  all2D,
153  prevInSamp,
154  nextInSamp,
155  upAndDown,
156  prevSubDet,
157  nextSubDet,
158  all3D,
159  corners3D,
163  super3D
164  )
165  )
166  //I know Topological Clustering only supports a subset of those,
167  //but this is supposed to be a general data exporting tool...
168  else
169  {
170  failed = true;
171  return LArNeighbours::super3D;
172  }
173  };
174 
175  bool neigh_failed = false;
176  m_options.m_options->neighbour_options = (unsigned int) get_neighbour_option_from_string(m_neighborOptionString, neigh_failed);
177 
178  if (neigh_failed)
179  {
180  ATH_MSG_ERROR("Invalid Neighbour Option: " << m_neighborOptionString);
181  }
182 
183  //We must repeat this printing part because ATH_MSG_ERROR
184  //is a macro that apparently calls a this->msg(...) function.
185  //Of course it won't work within a lambda...
186 
187  m_options.m_options->min_num_cells = m_nCells;
188  m_options.m_options->min_maximum_energy = m_minEnergy;
189  m_options.m_options->EM_shower_scale = m_emShowerScale;
190  m_options.m_options->share_border_cells = m_shareBorderCells;
191  m_options.m_options->use_absolute_energy = m_absOpt;
192  m_options.m_options->treat_L1_predicted_as_good = m_treatL1PredictedCellsAsGood;
193 
194  m_options.m_options->limit_HECIW_and_FCal_neighs = m_restrictHECIWandFCalNeighbors;
195  m_options.m_options->limit_PS_neighs = m_restrictPSNeighbors;
196 
197  ATH_CHECK( m_kernelSizeOptimizer.retrieve() );
198 
199  return StatusCode::SUCCESS;
200 }
201 
203 {
206 
207  return StatusCode::SUCCESS;
208 }
209 
210 StatusCode TopoAutomatonSplitting::execute(const EventContext & ctx, const ConstantDataHolder & constant_data,
211  EventDataHolder & event_data, void * /*temporary_buffer*/ ) const
212 {
213 
214  using clock_type = boost::chrono::thread_clock;
215  auto time_cast = [](const auto & before, const auto & after)
216  {
217  return boost::chrono::duration_cast<boost::chrono::microseconds>(after - before).count();
218  };
219 
220  static_assert(sizeof(TopoAutomatonSplittingTemporaries) <= sizeof(ClusterMomentsArr), "We store the temporaries in the cluster moments, so the sizes must be compatible!");
221 
222  const auto start = clock_type::now();
223  const auto preprocessing_end = clock_type::now();
224 
225  fillNeighbours(event_data, constant_data, m_options, *(m_kernelSizeOptimizer.get()), m_measureTimes);
226 
227  const auto after_neighs = clock_type::now();
228 
229  findLocalMaxima(event_data, constant_data, m_options, *(m_kernelSizeOptimizer.get()), m_measureTimes);
230 
231  const auto after_maxima = clock_type::now();
232 
233  excludeSecondaryMaxima(event_data, constant_data, m_options, *(m_kernelSizeOptimizer.get()), m_measureTimes);
234 
235  const auto after_secondary_maxima = clock_type::now();
236 
237  splitClusterGrowing(event_data, constant_data, m_options, *(m_kernelSizeOptimizer.get()), m_measureTimes);
238 
239  const auto after_growing = clock_type::now();
240 
241  cellWeightingAndFinalization(event_data, constant_data, m_options, *(m_kernelSizeOptimizer.get()), m_measureTimes);
242 
243  const auto end = clock_type::now();
244 
245  if (m_measureTimes)
246  {
247  record_times(ctx.evt(),
248  time_cast(start, preprocessing_end),
249  time_cast(preprocessing_end, after_neighs),
250  time_cast(after_neighs, after_maxima),
251  time_cast(after_maxima, after_secondary_maxima),
252  time_cast(after_secondary_maxima, after_growing),
253  time_cast(after_growing, end)
254  );
255  }
256 
257  return StatusCode::SUCCESS;
258 
259 
260 }
261 
262 
264 {
265  if (m_measureTimes)
266  {
267  print_times("Preprocessing Fill_List_of_Intra-Cluster_Neighbours Find_Local_Maxima Find_Secondary_Maxima Splitter_Tag_Propagation Cell_Weighting_And_Finalization", 6);
268  }
269  return StatusCode::SUCCESS;
270 }
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:263
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
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
TopoAutomatonSplitting::initialize_non_CUDA
virtual StatusCode initialize_non_CUDA() override
Initialization that does not invoke CUDA functions.
Definition: TopoAutomatonSplitting.cxx:32
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:14
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
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:93
CaloCell_ID.h
TopoAutomatonSplitting::initialize_CUDA
virtual StatusCode initialize_CUDA() override
Initialization that invokes CUDA functions.
Definition: TopoAutomatonSplitting.cxx:202
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:675
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
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:228
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
Process the clusters on GPU.
Definition: TopoAutomatonSplitting.cxx:210
CaloRecGPU::ClusterMomentsArr
Definition: EventInfoDefinitions.h:342
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.CaloScaleNoiseConfig.str
str
Definition: CaloScaleNoiseConfig.py:78
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
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
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
AthAlgTool
Definition: AthAlgTool.h:26
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