87 if ( !cell_collection.
isValid() )
89 ATH_MSG_ERROR(
" Cannot retrieve CaloCellContainer: " << cell_collection.
name() );
90 return StatusCode::FAILURE;
94 const CaloNoise * noise_tool = *noise_handle;
96 std::vector<unsigned char> cell_classification(
NCaloCells, 0);
104 for (
const auto & cell_ptr : *cell_collection)
106 const float energy = cell_ptr->energy();
109 noise_tool->
getNoise(cell_ptr->ID(), cell_ptr->gain());
110 const float s_n_r = (noise > 0 ? energy / noise : 0.00001f);
111 const float abs_s_n_r = fabsf(s_n_r);
113 const int this_hash_ID = cell_ptr->caloDDE()->calo_hash();
117 cell_classification[this_hash_ID] = 3;
122 cell_classification[this_hash_ID] = 2;
127 cell_classification[this_hash_ID] = 1;
132 cell_classification[this_hash_ID] = 0;
139 s.min = std::min(s.min, v);
140 s.max = std::max(s.max, v);
145 int cluster_count = 0;
147 std::vector<int> cluster_assignment(
NCaloCells, -1);
149 constexpr int check_seed_flag = 0x40000000;
150 constexpr int check_first_flag = 0x20000000;
153 constexpr int check_mask = ~(check_seed_flag | check_first_flag);
155 std::vector<int> cells_to_check;
156 std::vector<int> new_cells_to_check;
157 std::vector<IdentifierHash> neighs;
159 auto check_for_restrict = [&] (
const auto & hash_ID,
const bool restrict_HECIWandFCal,
const bool restrict_PS)
163 const auto sub_calo =
m_calo_id->sub_calo(cell_identifier);
164 const auto region =
m_calo_id->region(cell_identifier);
165 const auto intra_calo_sampling =
m_calo_id->sampling(cell_identifier);
172 return (is_HECIW_or_FCAL && restrict_HECIWandFCal) || (is_PS && restrict_PS);
175 for (
const auto & cluster_ptr : *cluster_collection)
177 int this_seed = 0, this_grow = 0, this_term = 0;
179 cells_to_check.clear();
183 for (
const CaloCell * cell_ptr : *cluster_ptr)
185 const int this_hash_ID = cell_ptr->caloDDE()->calo_hash();
187 cluster_assignment[this_hash_ID] = cluster_count | check_seed_flag | (first ? 0 : check_first_flag);
189 const unsigned char this_classification = cell_classification[this_hash_ID];
191 switch (this_classification)
195 cluster_assignment[this_hash_ID] = cluster_count | (first ? 0 : check_first_flag);
196 cells_to_check.push_back(this_hash_ID);
205 ATH_MSG_WARNING(
"Invalid cell " << this_hash_ID <<
" in cluster " << cluster_count <<
".");
216 accumulate_stats(ev_perf_info.
cluster_size, cluster_ptr->size());
224 int min_radius = -1, radius = -1;
226 while (cells_to_check.size() > 0)
230 new_cells_to_check.clear();
232 for (
const auto & hash_ID : cells_to_check)
234 if (min_radius < 0 && cell_classification[hash_ID] <= 1)
240 const bool restrict = check_for_restrict(hash_ID,
255 for (
const auto & neigh_hash : neighs)
257 int & neigh_assignment = cluster_assignment[neigh_hash];
258 if ((neigh_assignment & check_seed_flag) && ((neigh_assignment & check_mask) == cluster_count))
260 new_cells_to_check.push_back(neigh_hash) ;
261 neigh_assignment = (neigh_assignment & ~check_seed_flag);
266 cells_to_check.swap(new_cells_to_check);
275 if (cluster_ptr->size() > 0)
277 cells_to_check.clear();
278 cells_to_check.push_back(cluster_ptr->begin()->caloDDE()->calo_hash());
283 while (cells_to_check.size() > 0)
287 new_cells_to_check.clear();
289 for (
const auto & hash_ID : cells_to_check)
291 const bool restrict = check_for_restrict(hash_ID,
307 for (
const auto & neigh_hash : neighs)
309 int & neigh_assignment = cluster_assignment[neigh_hash];
310 if ((neigh_assignment & check_first_flag) && ((neigh_assignment & check_mask) == cluster_count))
312 new_cells_to_check.push_back(neigh_hash) ;
313 neigh_assignment = (neigh_assignment & ~check_first_flag);
318 cells_to_check.swap(new_cells_to_check);
330 s.avg /= cluster_collection->
size();
331 s.stddev /= cluster_collection->
size();
332 s.stddev -= s.avg * s.avg;
348 m_eventInfo.push_back(ev_perf_info);
349 m_eventNumbers.push_back(ctx.evt());
352 return StatusCode::SUCCESS;
362 std::vector<size_t> indices(m_eventNumbers.size());
364 std::iota(indices.begin(), indices.end(), 0);
365 std::sort(indices.begin(), indices.end(), [&](
size_t a,
size_t b)
367 return m_eventNumbers[a] < m_eventNumbers[b];
371 out <<
"Event_Number Number_Clusters "
372 <<
"Total_Seed Total_Grow Total_Term Total_Invalid "
373 <<
"Seed_In_Cluster Term_In_Cluster";
375 auto print_stat_name = [&](
const auto & name)
377 out <<
" " << name <<
"_Min " << name <<
"_Max " << name <<
"_Avg " << name <<
"_Stddev";
380 print_stat_name(
"Size");
381 print_stat_name(
"Num_Seed");
382 print_stat_name(
"Num_Grow");
383 print_stat_name(
"Num_Term");
384 print_stat_name(
"Radius_Seed_Min");
385 print_stat_name(
"Radius_Seed_Max");
386 print_stat_name(
"Radius_First");
392 out <<
" " << s.min <<
" " << s.max <<
" " << s.avg <<
" " << s.stddev;
395 for (
const auto & idx : indices)
397 out << m_eventNumbers[idx] <<
" ";
399 const auto & info = m_eventInfo[idx];
401 out << info.num_clusters <<
" " << info.total_seed <<
" " << info.total_grow <<
" "
402 << info.total_term <<
" " << info.total_invalid <<
" " << info.seed_in_cluster <<
" "
403 << info.grow_in_cluster <<
" " << info.term_in_cluster;
405 print_stat(info.cluster_size);
406 print_stat(info.cluster_num_seed);
407 print_stat(info.cluster_num_grow);
408 print_stat(info.cluster_num_term);
409 print_stat(info.cluster_seed_min_radius);
410 print_stat(info.cluster_seed_max_radius);
411 print_stat(info.cluster_first_max_radius);
422 return StatusCode::SUCCESS;