22{
24 {
25 std::lock_guard<std::mutex> lock_guard(
m_mutex);
27 {
31 {
32 return StatusCode::FAILURE;
33 }
35 }
36 }
37
39
41 {
43
45 {
46 return StatusCode::FAILURE;
47 }
48
49 return StatusCode::SUCCESS;
50 }
51
52
54
55
56 std::vector<int> cluster_order(
clusters->number);
57
58
59 std::vector<int> reverse_cluster_order(
clusters->number, -1);
60
61 std::iota(cluster_order.begin(), cluster_order.end(), 0);
62
64 {
65 std::sort(cluster_order.begin(), cluster_order.end(), [&](
const int a,
const int b)
66 {
67 if (clusters->seedCellIndex[a] < 0)
68 {
69 return false;
70
71
72
73 }
75 {
76 return true;
77 }
79 } );
80
81 unsigned int real_cluster_number = 0;
82
83 for (real_cluster_number = 0; real_cluster_number < cluster_order.size(); ++real_cluster_number)
84 {
85 if (
clusters->seedCellIndex[real_cluster_number] < 0)
86 {
87 break;
88 }
89 else
90 {
91 reverse_cluster_order[cluster_order[real_cluster_number]] = real_cluster_number;
92 }
93 }
94
95 cluster_order.resize(real_cluster_number);
96
97 final_clusters->number = real_cluster_number;
98 final_clusters->has_deleted_clusters = false;
99 }
100
102 {
103 if (
clusters->has_cells_per_cluster())
104 {
105 for (
int i = 0;
i < cell_info->number; ++
i)
106 {
107 final_clusters->cells.tags[
i] = 0;
108 }
109 for (
int i = 0;
i <
clusters->number_cells; ++
i)
110 {
111 const int real_cluster_index = reverse_cluster_order[
clusters->clusterIndices[
i]];
112
113 if (real_cluster_index < 0)
114 {
115 continue;
116 }
117
118 const int this_cell_index =
clusters->cells.indices[
i];
119
121
123 std::memcpy(&weight_as_int, &weight, sizeof(float));
124
125
126
127
128 if (weight_as_int == 0)
129 {
130 weight_as_int = 1;
131
132
133
134 }
135
136 const ClusterTag this_tag = final_clusters->cells.tags[this_cell_index];
137
139
140 if (other_index < 0)
141 {
142 if (weight < 0.5f)
143 {
144 final_clusters->cells.tags[this_cell_index] =
ClusterTag::make_tag(real_cluster_index, weight_as_int, 0);
145 }
146 else
147 {
149 }
150 }
151 else if (weight > 0.5f)
152 {
154 }
155 else if (weight == 0.5f)
156
157 {
158 const int max_cluster = real_cluster_index > other_index ? real_cluster_index : other_index;
159 const int min_cluster = real_cluster_index > other_index ? other_index : real_cluster_index;
160 final_clusters->cells.tags[this_cell_index] =
ClusterTag::make_tag(max_cluster, weight_as_int, min_cluster);
161 }
162 else
163 {
164 final_clusters->cells.tags[this_cell_index] =
ClusterTag::make_tag(other_index, weight_as_int, real_cluster_index);
165 }
166
167
168
169
170
171 }
172 }
173 else
174 {
175 for (
int i = 0;
i <
clusters->number_cells; ++
i)
176 {
177 const ClusterTag this_tag =
clusters->cells.tags[
i];
178
181 -1
182 );
185 -1
186 );
187
189
190 if (primary_index >= 0 && secondary_index >= 0)
191 {
193 }
194 else if (primary_index >= 0)
195 {
197 }
198 else if (secondary_index >= 0)
199 {
201 }
202 else
203 {
204 final_clusters->cells.tags[
i] = 0;
205 }
206 }
207 }
208
209 final_clusters->number_cells = cell_info->number;
210 final_clusters->state = ClusterInformationState::TagsWithBasicInfo;
211 }
212 else
213 {
214 auto update_prefix_sum = [&]()
215 {
216 int running_count = 0;
217 for (
int i = 1;
i <= final_clusters->number; ++
i)
218 {
219 running_count += final_clusters->cellsPrefixSum[
i];
220 final_clusters->cellsPrefixSum[
i] = running_count;
221 }
222 final_clusters->number_cells = running_count;
223 };
224
225 for (
int i = 0;
i <= final_clusters->number; ++
i)
226 {
227 final_clusters->cellsPrefixSum[
i] = 0;
228 if (i < final_clusters->
number)
229 {
231
232 }
233 }
234
235 if (!
clusters->has_cells_per_cluster())
236 {
237 for (
int i = 0;
i <
clusters->number_cells; ++
i)
238 {
239 const ClusterTag this_tag =
clusters->cells.tags[
i];
240
243 -1
244 );
247 -1
248 );
249
250 if (primary_index >= 0)
251 {
252 final_clusters->cellsPrefixSum[primary_index + 1] += 1;
253 }
254
255 if (secondary_index >= 0)
256 {
257 final_clusters->cellsPrefixSum[secondary_index + 1] += 1;
258 }
259 }
260
261 update_prefix_sum();
262
263 for (
int i = 0;
i <
clusters->number_cells; ++
i)
264 {
265 const ClusterTag this_tag =
clusters->cells.tags[
i];
266
269 -1
270 );
273 -1
274 );
275
277
279
280 std::memcpy(&weight, &weight_as_int, sizeof(float));
281
282 if (primary_index >= 0)
283 {
284 const int this_cell_start = final_clusters->cellsPrefixSum[primary_index];
285
286 int & this_cell_count =
clusters->clusterIndices[primary_index];
287
288 ++this_cell_count;
289
291
292 const int this_index_in_cluster = this_cell_start + this_cell_count * is_seed_cell;
293
294 final_clusters->cells.indices[this_index_in_cluster] =
i;
295 final_clusters->cellWeights[this_index_in_cluster] = 1.0f -
weight;
296 final_clusters->clusterIndices[this_index_in_cluster] = primary_index;
297 }
298
299 if (secondary_index >= 0)
300 {
301 const int this_cell_start = final_clusters->cellsPrefixSum[secondary_index];
302
303 int & this_cell_count =
clusters->clusterIndices[secondary_index];
304
305 ++this_cell_count;
306
308
309 const int this_index_in_cluster = this_cell_start + this_cell_count * is_seed_cell;
310
311 final_clusters->cells.indices[this_index_in_cluster] =
i;
312 final_clusters->cellWeights[this_index_in_cluster] =
weight;
313 final_clusters->clusterIndices[this_index_in_cluster] = primary_index;
314 }
315 }
316 }
317 else
318 {
319 final_clusters->cellsPrefixSum[0] = 0;
320
321 for (
unsigned int i = 0;
i < cluster_order.size(); ++
i)
322 {
323 const int original_cluster = cluster_order[
i];
324 final_clusters->cellsPrefixSum[
i + 1] =
clusters->cellsPrefixSum[original_cluster + 1] -
clusters->cellsPrefixSum[original_cluster];
325 }
326
327 update_prefix_sum();
328
329 for (
unsigned int i = 0;
i < cluster_order.size(); ++
i)
330 {
331 const int original_cluster = cluster_order[
i];
332
333 int new_index = final_clusters->cellsPrefixSum[
i];
334
335 for (
int j =
clusters->cellsPrefixSum[original_cluster]; j < clusters->cellsPrefixSum[original_cluster + 1]; ++j, ++new_index)
336 {
337 final_clusters->cells.indices[new_index] =
clusters->cells.indices[j];
338 final_clusters->cellWeights[new_index] =
clusters->cellWeights[j];
339 final_clusters->clusterIndices[new_index] =
clusters->clusterIndices[j];
340 }
341 }
342
343 }
344
345 final_clusters->state = ClusterInformationState::WithBasicInfo;
346 }
347
348 for (
unsigned int i = 0;
i < cluster_order.size(); ++
i)
349 {
350 final_clusters->clusterEnergy[
i] =
clusters->clusterEnergy[cluster_order[
i]];
351 final_clusters->clusterEt[
i] =
clusters->clusterEt[cluster_order[
i]];
352 final_clusters->clusterEta[
i] =
clusters->clusterEta[cluster_order[
i]];
353 final_clusters->clusterPhi[
i] =
clusters->clusterPhi[cluster_order[
i]];
354 final_clusters->seedCellIndex[
i] =
clusters->seedCellIndex[cluster_order[
i]];
355 }
356
359
361 {
362 return StatusCode::FAILURE;
363 }
364
365 return StatusCode::SUCCESS;
366
367}
Gaudi::Property< std::string > m_savePath
The path specifying the folder to which the files should be saved.
std::mutex m_mutex
This mutex is locked when saving the constant data on the first event to ensure thread safety.
Gaudi::Property< bool > m_outputTags
Whether to output cell assignment as tags instead of a list of indices per cluster.
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.
Gaudi::Property< bool > m_onlyCellInfo
If true, only output cell info (useful for reducing disk usage when running the full standalone versi...
Gaudi::Property< bool > m_sortedAndCutClusters
If true, sort the clusters by transverse energy and compactify the tags to ensure sequentiality.
Gaudi::Property< std::string > m_fileSuffix
The suffix of the saved files.
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::CellNoiseArr > m_cell_noise_dev
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::GeometryArr > m_geometry_dev
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::CellInfoArr > m_cell_info_dev
CaloRecGPU::Helpers::CUDA_object< CaloRecGPU::ClusterInfoArr > m_clusters_dev
SimpleHolder< T, MemoryContext::CPU, true > CPU_object
Holds an object of type T in CPU memory.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
constexpr int32_t secondary_cluster_index() const
constexpr int32_t secondary_cluster_weight() const
constexpr bool is_shared_between_clusters() const
constexpr bool is_part_of_cluster() const
constexpr int32_t cluster_index() const
static constexpr carrier make_tag(const uint16_t cluster_index=0, const int32_t weight=0, const uint16_t second_cluster_index=0)
static ErrorState save_constants_to_folder(const std::filesystem::path &folder, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::GeometryArr > &geo, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellNoiseArr > &noise, const std::string &prefix="", const std::string &suffix="", const bool output_errors=true)
static ErrorState save_event_to_folder(const size_t event_number, const std::filesystem::path &folder, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellInfoArr > &cell_info, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::ClusterInfoArr > &clusters, const std::string &prefix="", const std::string &suffix="", const unsigned int num_width=9, const bool output_errors=true)
static ErrorState save_cell_info_to_folder(const size_t event_number, const std::filesystem::path &folder, const CaloRecGPU::Helpers::CPU_object< CaloRecGPU::CellInfoArr > &cell_info, const std::string &prefix="", const std::string &suffix="", const unsigned int num_width=9, const bool output_errors=true)
std::string number(const double &d, const std::string &s)