ATLAS Offline Software
CaloCellsCounterCPU.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 
7 #include "CaloCellsCounterCPU.h"
8 #include "CaloRecGPU/Helpers.h"
11 #include "StoreGate/DataHandle.h"
12 
13 #include <map>
14 #include <filesystem>
15 
16 using namespace CaloRecGPU;
17 
18 CaloCellsCounterCPU::CaloCellsCounterCPU(const std::string & type, const std::string & name, const IInterface * parent):
20 {
21  declareInterface<CaloClusterCollectionProcessor> (this);
22 }
23 
24 
26 {
29  ATH_CHECK( detStore()->retrieve(m_calo_id, "CaloCell_ID") );
30  return StatusCode::SUCCESS;
31 }
32 
33 namespace {
34 
35 struct size_struct
36 {
37  unsigned int total = 0, seed = 0, grow = 0, term = 0, invalid = 0, shared = 0;
38  template <class Str>
39  friend Str & operator << (Str & s, const size_struct & sst)
40  {
41  s << sst.total << " " << sst.seed << " " << sst.grow << " " << sst.term << " " << sst.invalid << " " << sst.shared;
42  return s;
43  }
44 };
45 
46 struct cluster_info_struct
47 {
48  size_struct size;
49  float seed_snr = -9e99;
50  float seed_energy = -9e99;
51  int seed_index = -1;
52  template <class Str>
53  friend Str & operator << (Str & s, const cluster_info_struct & cis)
54  {
55  s << cis.seed_index << " " << cis.size << " (" << cis.seed_snr << " " << cis.seed_energy << ")";
56  return s;
57  }
58 };
59 
60 } // anonymous namespace
61 
62 StatusCode CaloCellsCounterCPU::execute (const EventContext & ctx, xAOD::CaloClusterContainer * cluster_collection) const
63 {
64 
65  SG::ReadHandle<CaloCellContainer> cell_collection(m_cellsKey, ctx);
66  if ( !cell_collection.isValid() )
67  {
68  ATH_MSG_ERROR( " Cannot retrieve CaloCellContainer: " << cell_collection.name() );
69  return StatusCode::FAILURE;
70  }
71 
72 
74  const CaloNoise * noise_tool = *noise_handle;
75 
76  unsigned int gain_counts[GainConversion::num_gain_values()] = {0};
77 
78  size_struct global_counts, global_cluster_counts;
79 
80  for (CaloCellContainer::const_iterator iCells = cell_collection->begin(); iCells != cell_collection->end(); ++iCells)
81  {
82  const CaloCell * cell = (*iCells);
83 
84  const float energy = cell->energy();
85 
86  float SNR = energy / noise_tool->getNoise(m_calo_id->calo_cell_hash(cell->ID()), cell->gain());
87 
88  const unsigned int gain = GainConversion::from_standard_gain(cell->gain());
89 
90  ++gain_counts[gain - GainConversion::min_gain_value()];
91 
92  SNR = std::abs(SNR);
93 
94  if (SNR > m_seedThreshold)
95  {
96  ++global_counts.seed;
97  }
98  else if (SNR > m_growThreshold)
99  {
100  ++global_counts.grow;
101  }
102  else if (SNR > m_cellThreshold)
103  {
104  ++global_counts.term;
105  }
106  else
107  {
108  ++global_counts.invalid;
109  }
110  }
111 
112  struct cluster_cell_info
113  {
114  const xAOD::CaloCluster * cl_1 = nullptr, * cl_2 = nullptr;
115  double w_1 = -1, w_2 = -1, energy = -9e99, SNR = -9e99;
116  void add_cluster(const int cell_id, const xAOD::CaloCluster * cl, const double w)
117  {
118  if (cl_1 == nullptr)
119  {
120  cl_1 = cl;
121  w_1 = w;
122  }
123  else if (cl_2 == nullptr)
124  {
125  cl_2 = cl;
126  w_2 = w;
127  }
128  else
129  {
130  std::cout << "WARNING! Multiple shared cell: " << cell_id << " " << cl_1 << " " << cl_2 << " " << cl << std::endl;
131  }
132  }
133 
134  bool is_shared() const
135  {
136  return cl_1 != nullptr && cl_2 != nullptr;
137  }
138 
139  };
140 
141  std::map<int, cluster_cell_info> cluster_cells;
142 
143 
144  for (const xAOD::CaloCluster * cluster : *cluster_collection)
145  {
146  //const xAOD::CaloCluster * cluster = (*cluster_iter);
147  const CaloClusterCellLink * cell_links = cluster->getCellLinks();
148  if (!cell_links)
149  {
150  ATH_MSG_ERROR("Can't get valid links to CaloCells (CaloClusterCellLink)!");
151  return StatusCode::FAILURE;
152  }
153 
154  for (auto it = cell_links->begin(); it != cell_links->end(); ++it)
155  {
156  const CaloCell * cell = *it;
157  const float weight = it.weight();
158 
159  const float this_energy = std::abs(cell->energy());
160 
161  const float this_snr = std::abs(this_energy / noise_tool->getNoise(m_calo_id->calo_cell_hash(cell->ID()), cell->gain()));
162 
163  const IdentifierHash this_hash = m_calo_id->calo_cell_hash(cell->ID());
164 
165  auto & info = cluster_cells[this_hash];
166 
167  info.energy = this_energy;
168  info.SNR = this_snr;
169 
170  info.add_cluster(this_hash, cluster, weight);
171 
172  }
173  }
174 
175  std::unordered_map<const xAOD::CaloCluster *, cluster_info_struct> cluster_sizes;
176 
177  auto update_clusters = [&](const cluster_cell_info & cci, const int cell)
178  {
179  auto update_one = [&](const xAOD::CaloCluster * cl)
180  {
181  if (cl)
182  {
183  auto & c_info = cluster_sizes[cl];
184  ++c_info.size.total;
185  if (cci.SNR > m_seedThreshold)
186  {
187  ++c_info.size.seed;
188  }
189  else if (cci.SNR > m_growThreshold)
190  {
191  ++c_info.size.grow;
192  }
193  else if (cci.SNR > m_cellThreshold)
194  {
195  ++c_info.size.term;
196  }
197  else
198  {
199  ++c_info.size.invalid;
200  }
201 
202  if (cci.is_shared())
203  {
204  ++c_info.size.shared;
205  }
206  else
207  {
208  if (cci.SNR > c_info.seed_snr || (cci.SNR == c_info.seed_snr && cell > c_info.seed_index))
209  {
210  c_info.seed_index = cell;
211  c_info.seed_snr = cci.SNR;
212  c_info.seed_energy = cci.energy;
213  }
214  }
215  }
216  };
217 
218  if (cci.cl_1 != nullptr || cci.cl_2 != nullptr)
219  {
220  ++global_cluster_counts.total;
221  if (cci.SNR > m_seedThreshold)
222  {
223  ++global_cluster_counts.seed;
224  }
225  else if (cci.SNR > m_growThreshold)
226  {
227  ++global_cluster_counts.grow;
228  }
229  else if (cci.SNR > m_cellThreshold)
230  {
231  ++global_cluster_counts.term;
232  }
233  else
234  {
235  ++global_cluster_counts.invalid;
236  }
237  if (cci.is_shared())
238  {
239  ++global_cluster_counts.shared;
240  }
241  }
242 
243  update_one(cci.cl_1);
244  update_one(cci.cl_2);
245  };
246 
247  for (auto & it : cluster_cells)
248  {
249  update_clusters(it.second, it.first);
250  }
251 
252  std::vector<cluster_info_struct> sorted_info;
253 
254  sorted_info.reserve(cluster_sizes.size());
255 
256  for (auto & v : cluster_sizes)
257  {
258  sorted_info.push_back(v.second);
259  }
260 
261  std::sort(sorted_info.begin(), sorted_info.end(),
262  [](const auto & a, const auto & b)
263  {
264  return a.seed_index < b.seed_index;
265  });
266 
267 
268  const auto err1 = StandaloneDataIO::prepare_folder_for_output(std::string(m_savePath));
270  {
271  return StatusCode::FAILURE;
272  }
273 
274  const std::filesystem::path save_file = m_savePath + "/" + StandaloneDataIO::build_filename((m_filePrefix.size() > 0 ? m_filePrefix + "_counts" : "counts"),
275  ctx.evt(), m_fileSuffix, "txt", m_numWidth);
276 
277  std::ofstream out_file(save_file);
278 
279  if (!out_file.is_open())
280  {
281  return StatusCode::FAILURE;
282  }
283 
284  out_file << "Cell counts: " << global_counts << "\n\n";
285 
286  out_file << "Cells in clusters count: " << global_cluster_counts << "\n\n";
287  out_file << "Clusters:\n\n";
288 
289  for (const auto & info : sorted_info)
290  {
291  out_file << info << "\n";
292  }
293 
294  out_file << std::endl;
295 
296  if (!out_file.good())
297  {
298  return StatusCode::FAILURE;
299  }
300 
301  out_file.close();
302 
303  return StatusCode::SUCCESS;
304 
305 }
306 
grepfile.info
info
Definition: grepfile.py:38
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
StandaloneDataIO::build_filename
static std::string build_filename(const std::string &prefix, const std::string &text, const std::string &suffix, const std::string &ext)
Definition: StandaloneDataIO.h:273
CaloCellsCounterCPU::m_fileSuffix
Gaudi::Property< std::string > m_fileSuffix
The suffix of the saved files.
Definition: CaloCellsCounterCPU.h:59
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:128
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
SG::VarHandleBase::name
const std::string & name() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:75
CaloCondBlobAlgs_fillNoiseFromASCII.gain
gain
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:110
skel.it
it
Definition: skel.GENtoEVGEN.py:396
CaloCellsCounterCPU::m_cellThreshold
Gaudi::Property< float > m_cellThreshold
Value to consider for the seed threshold.
Definition: CaloCellsCounterCPU.h:89
CaloCellsCounterCPU::m_cellsKey
SG::ReadHandleKey< CaloCellContainer > m_cellsKey
vector of names of the cell containers to use as input.
Definition: CaloCellsCounterCPU.h:69
CaloNoise::getNoise
float getNoise(const IdentifierHash h, const int gain) const
Accessor by IdentifierHash and gain.
Definition: CaloNoise.h:34
DataHandle.h
AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:189
CaloCellsCounterCPU::m_seedThreshold
Gaudi::Property< float > m_seedThreshold
Value to consider for the seed threshold.
Definition: CaloCellsCounterCPU.h:79
CaloCellsCounterCPU::initialize
virtual StatusCode initialize() override
Definition: CaloCellsCounterCPU.cxx:25
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
StandaloneDataIO::ErrorState::OK
@ OK
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
ParticleGun_FastCalo_ChargeFlip_Config.energy
energy
Definition: ParticleGun_FastCalo_ChargeFlip_Config.py:78
Helpers.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
test_pyathena.parent
parent
Definition: test_pyathena.py:15
StandaloneDataIO.h
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
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
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
CaloNoise
Definition: CaloNoise.h:16
StandaloneDataIO::prepare_folder_for_output
static ErrorState prepare_folder_for_output(const std::filesystem::path &folder, const bool output_errors=true)
Definition: StandaloneDataIO.h:264
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
CaloCellsCounterCPU::m_savePath
Gaudi::Property< std::string > m_savePath
The path specifying the folder to which the files should be saved.
Definition: CaloCellsCounterCPU.h:49
operator<<
std::ostream & operator<<(std::ostream &lhs, const TestGaudiProperty &rhs)
Definition: TestGaudiProperty.cxx:69
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
CaloCellsCounterCPU::m_calo_id
const CaloCell_ID * m_calo_id
Pointer to Calo ID Helper.
Definition: CaloCellsCounterCPU.h:96
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
python.PyAthena.v
v
Definition: PyAthena.py:154
a
TList * a
Definition: liststreamerinfos.cxx:10
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
CaloCellsCounterCPU.h
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
CaloCellsCounterCPU::m_numWidth
Gaudi::Property< unsigned int > m_numWidth
The number of digits to reserve for the events.
Definition: CaloCellsCounterCPU.h:64
CUDAFriendlyClasses.h
CaloCellsCounterCPU::CaloCellsCounterCPU
CaloCellsCounterCPU(const std::string &type, const std::string &name, const IInterface *parent)
Definition: CaloCellsCounterCPU.cxx:18
CaloCellsCounterCPU::m_noiseCDOKey
SG::ReadCondHandleKey< CaloNoise > m_noiseCDOKey
Key of the CaloNoise Conditions data object.
Definition: CaloCellsCounterCPU.h:74
AthAlgTool
Definition: AthAlgTool.h:26
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:200
CaloRecGPU
Definition: BaseDefinitions.h:11
CaloCellsCounterCPU::execute
virtual StatusCode execute(const EventContext &ctx, xAOD::CaloClusterContainer *cluster_collection) const override
Execute on an entire collection of clusters.
Definition: CaloCellsCounterCPU.cxx:62
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:26
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
CaloCellsCounterCPU::m_filePrefix
Gaudi::Property< std::string > m_filePrefix
The prefix of the saved files.
Definition: CaloCellsCounterCPU.h:54
CaloCellsCounterCPU::m_growThreshold
Gaudi::Property< float > m_growThreshold
Value to consider for the seed threshold.
Definition: CaloCellsCounterCPU.h:84