89 if ( !cell_collection.
isValid() )
91 ATH_MSG_ERROR(
" Cannot retrieve CaloCellContainer: " << cell_collection.
name() );
92 return StatusCode::FAILURE;
96 const CaloNoise * noise_tool = *noise_handle;
98 std::vector<unsigned char> cell_classification(
NCaloCells, 0);
106 for (
const auto & cell_ptr : *cell_collection)
108 const float energy = cell_ptr->energy();
111 noise_tool->
getNoise(cell_ptr->ID(), cell_ptr->gain());
112 const float s_n_r = (noise > 0 ? energy / noise : 0.00001f);
113 const float abs_s_n_r = fabsf(s_n_r);
115 const int this_hash_ID = cell_ptr->caloDDE()->calo_hash();
119 cell_classification[this_hash_ID] = 3;
124 cell_classification[this_hash_ID] = 2;
129 cell_classification[this_hash_ID] = 1;
134 cell_classification[this_hash_ID] = 0;
141 s.min = std::min(s.min, v);
142 s.max = std::max(s.max, v);
147 int cluster_count = 0;
149 std::vector<int> cluster_assignment(
NCaloCells, -1);
151 constexpr int check_seed_flag = 0x40000000;
152 constexpr int check_first_flag = 0x20000000;
155 constexpr int check_mask = ~(check_seed_flag | check_first_flag);
157 std::vector<int> cells_to_check;
158 std::vector<int> new_cells_to_check;
159 std::vector<IdentifierHash> neighs;
161 auto check_for_restrict = [&] (
const auto & hash_ID,
const bool restrict_HECIWandFCal,
const bool restrict_PS)
165 const auto sub_calo =
m_calo_id->sub_calo(cell_identifier);
166 const auto region =
m_calo_id->region(cell_identifier);
167 const auto intra_calo_sampling =
m_calo_id->sampling(cell_identifier);
174 return (is_HECIW_or_FCAL && restrict_HECIWandFCal) || (is_PS && restrict_PS);
177 for (
const auto & cluster_ptr : *cluster_collection)
179 int this_seed = 0, this_grow = 0, this_term = 0;
181 cells_to_check.clear();
185 for (
const CaloCell * cell_ptr : *cluster_ptr)
187 const int this_hash_ID = cell_ptr->caloDDE()->calo_hash();
189 cluster_assignment[this_hash_ID] = cluster_count | check_seed_flag | (first ? 0 : check_first_flag);
191 const unsigned char this_classification = cell_classification[this_hash_ID];
193 switch (this_classification)
197 cluster_assignment[this_hash_ID] = cluster_count | (first ? 0 : check_first_flag);
198 cells_to_check.push_back(this_hash_ID);
207 ATH_MSG_WARNING(
"Invalid cell " << this_hash_ID <<
" in cluster " << cluster_count <<
".");
218 accumulate_stats(ev_perf_info.
cluster_size, cluster_ptr->size());
226 int min_radius = -1, radius = -1;
228 while (cells_to_check.size() > 0)
232 new_cells_to_check.clear();
234 for (
const auto & hash_ID : cells_to_check)
236 if (min_radius < 0 && cell_classification[hash_ID] <= 1)
242 const bool restrict = check_for_restrict(hash_ID,
257 for (
const auto & neigh_hash : neighs)
259 int & neigh_assignment = cluster_assignment[neigh_hash];
260 if ((neigh_assignment & check_seed_flag) && ((neigh_assignment & check_mask) == cluster_count))
262 new_cells_to_check.push_back(neigh_hash) ;
263 neigh_assignment = (neigh_assignment & ~check_seed_flag);
268 cells_to_check.swap(new_cells_to_check);
277 if (cluster_ptr->size() > 0)
279 cells_to_check.clear();
280 cells_to_check.push_back(cluster_ptr->begin()->caloDDE()->calo_hash());
285 while (cells_to_check.size() > 0)
289 new_cells_to_check.clear();
291 for (
const auto & hash_ID : cells_to_check)
293 const bool restrict = check_for_restrict(hash_ID,
309 for (
const auto & neigh_hash : neighs)
311 int & neigh_assignment = cluster_assignment[neigh_hash];
312 if ((neigh_assignment & check_first_flag) && ((neigh_assignment & check_mask) == cluster_count))
314 new_cells_to_check.push_back(neigh_hash) ;
315 neigh_assignment = (neigh_assignment & ~check_first_flag);
320 cells_to_check.swap(new_cells_to_check);
332 s.avg /= cluster_collection->
size();
333 s.stddev /= cluster_collection->
size();
334 s.stddev -= s.avg * s.avg;
350 m_eventInfo.push_back(ev_perf_info);
351 m_eventNumbers.push_back(ctx.evt());
354 return StatusCode::SUCCESS;
364 std::vector<size_t> indices(m_eventNumbers.size());
366 std::iota(indices.begin(), indices.end(), 0);
367 std::sort(indices.begin(), indices.end(), [&](
size_t a,
size_t b)
369 return m_eventNumbers[a] < m_eventNumbers[b];
373 out <<
"Event_Number Number_Clusters "
374 <<
"Total_Seed Total_Grow Total_Term Total_Invalid "
375 <<
"Seed_In_Cluster Term_In_Cluster";
377 auto print_stat_name = [&](
const auto & name)
379 out <<
" " << name <<
"_Min " << name <<
"_Max " << name <<
"_Avg " << name <<
"_Stddev";
382 print_stat_name(
"Size");
383 print_stat_name(
"Num_Seed");
384 print_stat_name(
"Num_Grow");
385 print_stat_name(
"Num_Term");
386 print_stat_name(
"Radius_Seed_Min");
387 print_stat_name(
"Radius_Seed_Max");
388 print_stat_name(
"Radius_First");
394 out <<
" " << s.min <<
" " << s.max <<
" " << s.avg <<
" " << s.stddev;
397 for (
const auto & idx : indices)
399 out << m_eventNumbers[idx] <<
" ";
401 const auto & info = m_eventInfo[idx];
403 out << info.num_clusters <<
" " << info.total_seed <<
" " << info.total_grow <<
" "
404 << info.total_term <<
" " << info.total_invalid <<
" " << info.seed_in_cluster <<
" "
405 << info.grow_in_cluster <<
" " << info.term_in_cluster;
407 print_stat(info.cluster_size);
408 print_stat(info.cluster_num_seed);
409 print_stat(info.cluster_num_grow);
410 print_stat(info.cluster_num_term);
411 print_stat(info.cluster_seed_min_radius);
412 print_stat(info.cluster_seed_max_radius);
413 print_stat(info.cluster_first_max_radius);
424 return StatusCode::SUCCESS;