ATLAS Offline Software
Loading...
Searching...
No Matches
CaloCellsCounterGPU Class Reference

Outputs counts of cells, both by type and cluster presence, with each cluster being identified by its cell with the largest signal-to-noise ratio. More...

#include <CaloCellsCounterGPU.h>

Inheritance diagram for CaloCellsCounterGPU:
Collaboration diagram for CaloCellsCounterGPU:

Public Member Functions

 CaloCellsCounterGPU (const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode execute (const EventContext &ctx, const CaloRecGPU::ConstantDataHolder &constant_data, CaloRecGPU::EventDataHolder &event_data, void *temporary_buffer) const override
virtual ~CaloCellsCounterGPU ()=default

Private Attributes

Gaudi::Property< std::string > m_savePath {this, "SavePath", "./cell_counts", "Path to where the files should be saved"}
 The path specifying the folder to which the files should be saved.
Gaudi::Property< std::string > m_filePrefix {this, "FilePrefix", "", "Prefix of the saved files"}
 The prefix of the saved files.
Gaudi::Property< std::string > m_fileSuffix {this, "FileSuffix", "", "Suffix of the saved files"}
 The suffix of the saved files.
Gaudi::Property< unsigned int > m_numWidth {this, "NumberWidth", 9, "The number of digits to reserve for the events"}
 The number of digits to reserve for the events.
Gaudi::Property< float > m_seedThreshold {this, "SeedThresholdOnEorAbsEinSigma", 4., "Seed threshold (in units of noise Sigma)"}
 Value to consider for the seed threshold.
Gaudi::Property< float > m_growThreshold {this, "NeighborThresholdOnEorAbsEinSigma", 2., "Neighbor (grow) threshold (in units of noise Sigma)"}
 Value to consider for the seed threshold.
Gaudi::Property< float > m_cellThreshold {this, "CellThresholdOnEorAbsEinSigma", 0., "Cell (terminal) threshold (in units of noise Sigma)"}
 Value to consider for the seed threshold.

Detailed Description

Outputs counts of cells, both by type and cluster presence, with each cluster being identified by its cell with the largest signal-to-noise ratio.

Author
Nuno Fernandes nuno..nosp@m.dos..nosp@m.santo.nosp@m.s.fe.nosp@m.rnand.nosp@m.es@c.nosp@m.ern.c.nosp@m.h
Date
22 July 2022

Definition at line 22 of file CaloCellsCounterGPU.h.

Constructor & Destructor Documentation

◆ CaloCellsCounterGPU()

CaloCellsCounterGPU::CaloCellsCounterGPU ( const std::string & type,
const std::string & name,
const IInterface * parent )

Definition at line 16 of file CaloCellsCounterGPU.cxx.

16 :
17 base_class(type, name, parent)
18{
19}

◆ ~CaloCellsCounterGPU()

virtual CaloCellsCounterGPU::~CaloCellsCounterGPU ( )
virtualdefault

Member Function Documentation

◆ execute()

StatusCode CaloCellsCounterGPU::execute ( const EventContext & ctx,
const CaloRecGPU::ConstantDataHolder & constant_data,
CaloRecGPU::EventDataHolder & event_data,
void * temporary_buffer ) const
overridevirtual

Definition at line 50 of file CaloCellsCounterGPU.cxx.

51{
53 //We could try to keep this in CPU memory by default,
54 //but, since it isn't quite needed and we don't mind taking a bit longer for this
55 //since we're only debugging, let this be as generic as possible.
56
59
60 unsigned int gain_counts[GainConversion::num_gain_values()] = {0};
61
62 size_struct global_counts, global_cluster_counts;
63
64 std::vector<int> cluster_max_cell(clusters->number, -1);
65 std::vector<float> cluster_max_snr(clusters->number, -9e99);
66 std::vector<float> cluster_max_energy(clusters->number, -9e99);
67
68 std::vector<size_struct> cluster_counts(clusters->number);
69
70 if (clusters->has_cells_per_cluster())
71 {
72 for (int i = 0; i < cell_info->number; ++i)
73 {
74 if (!cell_info->is_valid(i))
75 {
76 continue;
77 }
78
79 const int gain = cell_info->gain[i];
80 ++gain_counts[gain - GainConversion::min_gain_value()];
81
82 const float energy = cell_info->energy[i];
83
84 const float SNR = std::abs( energy / cell_noise->get_noise(cell_info->hashID[i], gain) );
85
86 if (SNR > m_seedThreshold)
87 {
88 ++global_counts.seed;
89 }
90 else if (SNR > m_growThreshold)
91 {
92 ++global_counts.grow;
93 }
94 else if (SNR > m_cellThreshold)
95 {
96 ++global_counts.term;
97 }
98 else
99 {
100 ++global_counts.invalid;
101 }
102 }
103
104 std::vector<char> counted_cells(NCaloCells, 0);
105
106 for (int i = 0; i < clusters->number_cells; ++i)
107 {
108 const int cell_index = clusters->cells.indices[i];
109 const int cell_hash_ID = cell_info->hashID[cell_index];
110
111
112 const int gain = cell_info->gain[cell_index];
113 ++gain_counts[gain - GainConversion::min_gain_value()];
114
115 const float energy = cell_info->energy[cell_index];
116
117 const float SNR = std::abs( energy / cell_noise->get_noise(cell_hash_ID, gain) );
118
119 const bool is_new_cell = !counted_cells[cell_index];
120
121 if (is_new_cell)
122 {
123 counted_cells[cell_index] = 1;
124 ++global_cluster_counts.total;
125 }
126
127 const int cluster_index = clusters->clusterIndices[i];
128
129 if (SNR > cluster_max_snr[cluster_index] || (SNR == cluster_max_snr[cluster_index] && cell_hash_ID > cluster_max_cell[cluster_index]))
130 {
131 cluster_max_snr[cluster_index] = SNR;
132 cluster_max_cell[cluster_index] = cell_hash_ID;
133 cluster_max_energy[cluster_index] = std::abs(energy);
134 }
135
136 if (SNR > m_seedThreshold)
137 {
138 global_cluster_counts.seed += is_new_cell;
139 ++cluster_counts[cluster_index].seed;
140 }
141 else if (SNR > m_growThreshold)
142 {
143 global_cluster_counts.grow += is_new_cell;
144 ++cluster_counts[cluster_index].grow;
145 }
146 else if (SNR > m_cellThreshold)
147 {
148 global_cluster_counts.term += is_new_cell;
149 ++cluster_counts[cluster_index].term;
150 }
151 else
152 {
153 global_cluster_counts.invalid += is_new_cell;
154 ++cluster_counts[cluster_index].invalid;
155 }
156
157
158 ++cluster_counts[cluster_index].total;
159
160 global_cluster_counts.shared += !is_new_cell;
161 cluster_counts[cluster_index].shared += !is_new_cell;
162
163 }
164
165 }
166 else
167 {
168 for (int i = 0; i < cell_info->number; ++i)
169 {
170 if (!cell_info->is_valid(i))
171 {
172 continue;
173 }
174
175 const int gain = cell_info->gain[i];
176 ++gain_counts[gain - GainConversion::min_gain_value()];
177
178 const float energy = cell_info->energy[i];
179
180 const float SNR = std::abs( energy / cell_noise->get_noise(cell_info->hashID[i], gain) );
181
182 const ClusterTag tag = clusters->cells.tags[i];
183
184 const bool is_cluster = tag.is_part_of_cluster();
185
186 global_cluster_counts.total += is_cluster;
187
188 if (SNR > m_seedThreshold)
189 {
190 ++global_counts.seed;
191 global_cluster_counts.seed += is_cluster;
192 }
193 else if (SNR > m_growThreshold)
194 {
195 ++global_counts.grow;
196 global_cluster_counts.grow += is_cluster;
197 }
198 else if (SNR > m_cellThreshold)
199 {
200 ++global_counts.term;
201 global_cluster_counts.term += is_cluster;
202 }
203 else
204 {
205 ++global_counts.invalid;
206 global_cluster_counts.invalid += is_cluster;
207 }
208
209 if (is_cluster)
210 {
211 const int cluster = tag.cluster_index();
212 const int other_cluster = tag.is_shared_between_clusters() ? tag.secondary_cluster_index() : cluster;
213 if (!tag.is_shared_between_clusters() && (SNR > cluster_max_snr[cluster] || (SNR == cluster_max_snr[cluster] && i > cluster_max_cell[cluster])))
214 {
215 cluster_max_snr[cluster] = SNR;
216 cluster_max_cell[cluster] = i;
217 cluster_max_energy[cluster] = std::abs(energy);
218 }
219 ++cluster_counts[cluster].total;
220 cluster_counts[other_cluster].total += (cluster != other_cluster);
221
222 global_cluster_counts.shared += tag.is_shared_between_clusters();
223 cluster_counts[cluster].shared += tag.is_shared_between_clusters();
224 cluster_counts[other_cluster].shared += tag.is_shared_between_clusters();
225
226 if (SNR > m_seedThreshold)
227 {
228 ++cluster_counts[cluster].seed;
229 cluster_counts[other_cluster].seed += (cluster != other_cluster);
230 }
231 else if (SNR > m_growThreshold)
232 {
233 ++cluster_counts[cluster].grow;
234 cluster_counts[other_cluster].grow += (cluster != other_cluster);
235 }
236 else if (SNR > m_cellThreshold)
237 {
238 ++cluster_counts[cluster].term;
239 cluster_counts[other_cluster].term += (cluster != other_cluster);
240 }
241 else
242 {
243 ++cluster_counts[cluster].invalid;
244 cluster_counts[other_cluster].invalid += (cluster != other_cluster);
245 }
246 }
247 }
248 }
249
250 std::map<int, cluster_info_struct> cluster_sizes;
251
252 for (int i = 0; i < clusters->number; ++i)
253 {
254 if (cluster_max_cell[i] >= 0)
255 {
256 cluster_sizes[cluster_max_cell[i]] = cluster_info_struct{cluster_counts[i], cluster_max_snr[i], cluster_max_energy[i]};
257 }
258 }
259
260 const auto err1 = StandaloneDataIO::prepare_folder_for_output(std::string(m_savePath));
262 {
263 return StatusCode::FAILURE;
264 }
265
266 const std::filesystem::path save_file = m_savePath + "/" + StandaloneDataIO::build_filename((m_filePrefix.size() > 0 ? m_filePrefix + "_counts" : "counts"),
267 ctx.evt(), m_fileSuffix, "txt", m_numWidth);
268
269 std::ofstream out_file(save_file);
270
271 if (!out_file.is_open())
272 {
273 return StatusCode::FAILURE;
274 }
275
276 out_file << "Cell counts: " << global_counts << "\n\n";
277
278 out_file << "Cells in clusters count: " << global_cluster_counts << "\n\n";
279 out_file << "Clusters:\n\n";
280
281 for (const auto & it : cluster_sizes)
282 {
283 out_file << it.first << " " << it.second << "\n";
284 }
285
286 out_file << std::endl;
287
288 if (!out_file.good())
289 {
290 return StatusCode::FAILURE;
291 }
292
293 out_file.close();
294
295 return StatusCode::SUCCESS;
296
297}
Gaudi::Property< float > m_cellThreshold
Value to consider for the seed threshold.
Gaudi::Property< std::string > m_savePath
The path specifying the folder to which the files should be saved.
Gaudi::Property< std::string > m_fileSuffix
The suffix of the saved files.
Gaudi::Property< float > m_seedThreshold
Value to consider for the seed threshold.
Gaudi::Property< float > m_growThreshold
Value to consider for the seed threshold.
Gaudi::Property< std::string > m_filePrefix
The prefix of the saved files.
Gaudi::Property< unsigned int > m_numWidth
The number of digits to reserve for the events.
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::CellNoiseArr > m_cell_noise_dev
Definition DataHolders.h:38
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::CellInfoArr > m_cell_info_dev
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::ClusterInfoArr > m_clusters_dev
static constexpr GainType min_gain_value()
static constexpr GainType num_gain_values()
SimpleHolder< T, MemoryContext::CPU, true > CPU_object
Holds an object of type T in CPU memory.
constexpr int NCaloCells
static std::string build_filename(const std::string &prefix, const std::string &text, const std::string &suffix, const std::string &ext)
static ErrorState prepare_folder_for_output(const std::filesystem::path &folder, const bool output_errors=true)

Member Data Documentation

◆ m_cellThreshold

Gaudi::Property<float> CaloCellsCounterGPU::m_cellThreshold {this, "CellThresholdOnEorAbsEinSigma", 0., "Cell (terminal) threshold (in units of noise Sigma)"}
private

Value to consider for the seed threshold.

Should be consistent with the one used in Topological Clustering to ensure cell classification is correct.

Definition at line 73 of file CaloCellsCounterGPU.h.

73{this, "CellThresholdOnEorAbsEinSigma", 0., "Cell (terminal) threshold (in units of noise Sigma)"};

◆ m_filePrefix

Gaudi::Property<std::string> CaloCellsCounterGPU::m_filePrefix {this, "FilePrefix", "", "Prefix of the saved files"}
private

The prefix of the saved files.

Empty string by default.

Definition at line 48 of file CaloCellsCounterGPU.h.

48{this, "FilePrefix", "", "Prefix of the saved files"};

◆ m_fileSuffix

Gaudi::Property<std::string> CaloCellsCounterGPU::m_fileSuffix {this, "FileSuffix", "", "Suffix of the saved files"}
private

The suffix of the saved files.

Empty string by default.

Definition at line 53 of file CaloCellsCounterGPU.h.

53{this, "FileSuffix", "", "Suffix of the saved files"};

◆ m_growThreshold

Gaudi::Property<float> CaloCellsCounterGPU::m_growThreshold {this, "NeighborThresholdOnEorAbsEinSigma", 2., "Neighbor (grow) threshold (in units of noise Sigma)"}
private

Value to consider for the seed threshold.

Should be consistent with the one used in Topological Clustering to ensure cell classification is correct.

Definition at line 68 of file CaloCellsCounterGPU.h.

68{this, "NeighborThresholdOnEorAbsEinSigma", 2., "Neighbor (grow) threshold (in units of noise Sigma)"};

◆ m_numWidth

Gaudi::Property<unsigned int> CaloCellsCounterGPU::m_numWidth {this, "NumberWidth", 9, "The number of digits to reserve for the events"}
private

The number of digits to reserve for the events.

9 by default.

Definition at line 58 of file CaloCellsCounterGPU.h.

58{this, "NumberWidth", 9, "The number of digits to reserve for the events"};

◆ m_savePath

Gaudi::Property<std::string> CaloCellsCounterGPU::m_savePath {this, "SavePath", "./cell_counts", "Path to where the files should be saved"}
private

The path specifying the folder to which the files should be saved.

Default ./cell_counts

Definition at line 43 of file CaloCellsCounterGPU.h.

43{this, "SavePath", "./cell_counts", "Path to where the files should be saved"};

◆ m_seedThreshold

Gaudi::Property<float> CaloCellsCounterGPU::m_seedThreshold {this, "SeedThresholdOnEorAbsEinSigma", 4., "Seed threshold (in units of noise Sigma)"}
private

Value to consider for the seed threshold.

Should be consistent with the one used in Topological Clustering to ensure cell classification is correct.

Definition at line 63 of file CaloCellsCounterGPU.h.

63{this, "SeedThresholdOnEorAbsEinSigma", 4., "Seed threshold (in units of noise Sigma)"};

The documentation for this class was generated from the following files: