88 if ( !cell_collection.
isValid() )
90 ATH_MSG_ERROR(
" Cannot retrieve CaloCellContainer: " << cell_collection.
name() );
91 return StatusCode::FAILURE;
95 const CaloNoise * noise_tool = *noise_handle;
97 std::vector<unsigned char> cell_classification(
NCaloCells, 0);
105 for (
const auto & cell_ptr : *cell_collection)
107 const float energy = cell_ptr->energy();
110 noise_tool->
getNoise(cell_ptr->ID(), cell_ptr->gain());
111 const float s_n_r = (noise > 0 ? energy / noise : 0.00001f);
112 const float abs_s_n_r = fabsf(s_n_r);
114 const int this_hash_ID = cell_ptr->caloDDE()->calo_hash();
118 cell_classification[this_hash_ID] = 3;
123 cell_classification[this_hash_ID] = 2;
128 cell_classification[this_hash_ID] = 1;
133 cell_classification[this_hash_ID] = 0;
140 s.min = std::min(s.min, v);
141 s.max = std::max(s.max, v);
146 int cluster_count = 0;
148 std::vector<int> cluster_assignment(
NCaloCells, -1);
150 constexpr int check_seed_flag = 0x40000000;
151 constexpr int check_first_flag = 0x20000000;
154 constexpr int check_mask = ~(check_seed_flag | check_first_flag);
156 std::vector<int> cells_to_check;
157 std::vector<int> new_cells_to_check;
158 std::vector<IdentifierHash> neighs;
160 auto check_for_restrict = [&] (
const auto & hash_ID,
const bool restrict_HECIWandFCal,
const bool restrict_PS)
164 const auto sub_calo =
m_calo_id->sub_calo(cell_identifier);
165 const auto region =
m_calo_id->region(cell_identifier);
166 const auto intra_calo_sampling =
m_calo_id->sampling(cell_identifier);
173 return (is_HECIW_or_FCAL && restrict_HECIWandFCal) || (is_PS && restrict_PS);
176 for (
const auto & cluster_ptr : *cluster_collection)
178 int this_seed = 0, this_grow = 0, this_term = 0;
180 cells_to_check.clear();
184 for (
const CaloCell * cell_ptr : *cluster_ptr)
186 const int this_hash_ID = cell_ptr->caloDDE()->calo_hash();
188 cluster_assignment[this_hash_ID] = cluster_count | check_seed_flag | (first ? 0 : check_first_flag);
190 const unsigned char this_classification = cell_classification[this_hash_ID];
192 switch (this_classification)
196 cluster_assignment[this_hash_ID] = cluster_count | (first ? 0 : check_first_flag);
197 cells_to_check.push_back(this_hash_ID);
206 ATH_MSG_WARNING(
"Invalid cell " << this_hash_ID <<
" in cluster " << cluster_count <<
".");
217 accumulate_stats(ev_perf_info.
cluster_size, cluster_ptr->size());
225 int min_radius = -1, radius = -1;
227 while (cells_to_check.size() > 0)
231 new_cells_to_check.clear();
233 for (
const auto & hash_ID : cells_to_check)
235 if (min_radius < 0 && cell_classification[hash_ID] <= 1)
241 const bool restrict = check_for_restrict(hash_ID,
256 for (
const auto & neigh_hash : neighs)
258 int & neigh_assignment = cluster_assignment[neigh_hash];
259 if ((neigh_assignment & check_seed_flag) && ((neigh_assignment & check_mask) == cluster_count))
261 new_cells_to_check.push_back(neigh_hash) ;
262 neigh_assignment = (neigh_assignment & ~check_seed_flag);
267 cells_to_check.swap(new_cells_to_check);
276 if (cluster_ptr->size() > 0)
278 cells_to_check.clear();
279 cells_to_check.push_back(cluster_ptr->begin()->caloDDE()->calo_hash());
284 while (cells_to_check.size() > 0)
288 new_cells_to_check.clear();
290 for (
const auto & hash_ID : cells_to_check)
292 const bool restrict = check_for_restrict(hash_ID,
308 for (
const auto & neigh_hash : neighs)
310 int & neigh_assignment = cluster_assignment[neigh_hash];
311 if ((neigh_assignment & check_first_flag) && ((neigh_assignment & check_mask) == cluster_count))
313 new_cells_to_check.push_back(neigh_hash) ;
314 neigh_assignment = (neigh_assignment & ~check_first_flag);
319 cells_to_check.swap(new_cells_to_check);
331 s.avg /= cluster_collection->
size();
332 s.stddev /= cluster_collection->
size();
333 s.stddev -= s.avg * s.avg;
349 m_eventInfo.push_back(ev_perf_info);
350 m_eventNumbers.push_back(ctx.evt());
353 return StatusCode::SUCCESS;
363 std::vector<size_t> indices(m_eventNumbers.size());
365 std::iota(indices.begin(), indices.end(), 0);
366 std::sort(indices.begin(), indices.end(), [&](
size_t a,
size_t b)
368 return m_eventNumbers[a] < m_eventNumbers[b];
372 out <<
"Event_Number Number_Clusters "
373 <<
"Total_Seed Total_Grow Total_Term Total_Invalid "
374 <<
"Seed_In_Cluster Term_In_Cluster";
376 auto print_stat_name = [&](
const auto & name)
378 out <<
" " << name <<
"_Min " << name <<
"_Max " << name <<
"_Avg " << name <<
"_Stddev";
381 print_stat_name(
"Size");
382 print_stat_name(
"Num_Seed");
383 print_stat_name(
"Num_Grow");
384 print_stat_name(
"Num_Term");
385 print_stat_name(
"Radius_Seed_Min");
386 print_stat_name(
"Radius_Seed_Max");
387 print_stat_name(
"Radius_First");
393 out <<
" " << s.min <<
" " << s.max <<
" " << s.avg <<
" " << s.stddev;
396 for (
const auto & idx : indices)
398 out << m_eventNumbers[idx] <<
" ";
400 const auto & info = m_eventInfo[idx];
402 out << info.num_clusters <<
" " << info.total_seed <<
" " << info.total_grow <<
" "
403 << info.total_term <<
" " << info.total_invalid <<
" " << info.seed_in_cluster <<
" "
404 << info.grow_in_cluster <<
" " << info.term_in_cluster;
406 print_stat(info.cluster_size);
407 print_stat(info.cluster_num_seed);
408 print_stat(info.cluster_num_grow);
409 print_stat(info.cluster_num_term);
410 print_stat(info.cluster_seed_min_radius);
411 print_stat(info.cluster_seed_max_radius);
412 print_stat(info.cluster_first_max_radius);
423 return StatusCode::SUCCESS;