Skip to content

Commit bf75199

Browse files
[EMCAL] implementation of number of local maxima variable
* [EMCAL] implementation of number of local maxima variable * Please consider the following formatting changes * further optimizations of EMCAL evalNExMax * Please consider the following formatting changes --------- Co-authored-by: ALICE Action Bot <alibuild@cern.ch>
1 parent 96e2f45 commit bf75199

File tree

4 files changed

+96
-0
lines changed

4 files changed

+96
-0
lines changed

Detectors/EMCAL/base/include/EMCALBase/ClusterFactory.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,10 @@ class ClusterFactory
401401
/// in cell units
402402
void evalElipsAxis(gsl::span<const int> inputsIndices, AnalysisCluster& clusterAnalysis) const;
403403

404+
///
405+
/// Calculate the number of local maxima in the cluster
406+
void evalNExMax(gsl::span<const int> inputsIndices, AnalysisCluster& clusterAnalysis) const;
407+
404408
///
405409
/// Time is set to the time of the digit with the maximum energy
406410
void evalTime(gsl::span<const int> inputsIndices, AnalysisCluster& clusterAnalysis) const;

Detectors/EMCAL/base/include/EMCALBase/Geometry.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,14 @@ class Geometry
429429
/// \return Position (0 - phi, 1 - eta) of the cell inside teh supermodule
430430
std::tuple<int, int> GetCellPhiEtaIndexInSModule(int supermoduleID, int moduleID, int phiInModule, int etaInModule) const;
431431

432+
/// \brief Get topological row and column of cell in SM (same as for clusteriser with artifical gaps)
433+
/// \param supermoduleID super module number
434+
/// \param moduleID module number
435+
/// \param phiInModule index in phi direction in module
436+
/// \param etaInModule index in phi direction in module
437+
/// \return tuple with (row, column) of the cell, which is global numbering scheme
438+
std::tuple<short, short> GetTopologicalRowColumn(int supermoduleID, int moduleID, int phiInModule, int etaInModule) const;
439+
432440
/// \brief Adapt cell indices in supermodule to online indexing
433441
/// \param supermoduleID super module number of the channel/cell
434442
/// \param iphi row/phi cell index, modified for DCal

Detectors/EMCAL/base/src/ClusterFactory.cxx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ o2::emcal::AnalysisCluster ClusterFactory<InputType>::buildCluster(int clusterIn
120120
evalElipsAxis(inputsIndices, clusterAnalysis);
121121
evalDispersion(inputsIndices, clusterAnalysis);
122122

123+
// evaluate number of local maxima
124+
evalNExMax(inputsIndices, clusterAnalysis);
125+
123126
evalCoreEnergy(inputsIndices, clusterAnalysis);
124127
evalTime(inputsIndices, clusterAnalysis);
125128

@@ -489,6 +492,63 @@ void ClusterFactory<InputType>::evalCoreEnergy(gsl::span<const int> inputsIndice
489492
clusterAnalysis.setCoreEnergy(coreEnergy);
490493
}
491494

495+
///
496+
/// Calculate the number of local maxima in the cluster
497+
//____________________________________________________________________________
498+
template <class InputType>
499+
void ClusterFactory<InputType>::evalNExMax(gsl::span<const int> inputsIndices, AnalysisCluster& clusterAnalysis) const
500+
{
501+
// Pre-compute cell indices and energies for all cells in cluster to avoid multiple expensive geometry lookups
502+
const size_t n = inputsIndices.size();
503+
std::vector<short> rows;
504+
std::vector<short> columns;
505+
std::vector<double> energies;
506+
507+
rows.reserve(n);
508+
columns.reserve(n);
509+
energies.reserve(n);
510+
511+
for (auto iInput : inputsIndices) {
512+
auto [nSupMod, nModule, nIphi, nIeta] = mGeomPtr->GetCellIndex(mInputsContainer[iInput].getTower());
513+
514+
// get a nice topological indexing that is done in exactly the same way as used by the clusterizer
515+
// this way we can handle the shared cluster cases correctly
516+
const auto [row, column] = mGeomPtr->GetTopologicalRowColumn(nSupMod, nModule, nIphi, nIeta);
517+
518+
rows.push_back(row);
519+
columns.push_back(column);
520+
energies.push_back(mInputsContainer[iInput].getEnergy());
521+
}
522+
523+
// Now find local maxima using pre-computed data
524+
int nExMax = 0;
525+
for (size_t i = 0; i < n; i++) {
526+
// this cell is assumed to be local maximum unless we find a higher energy cell in the neighborhood
527+
bool isExMax = true;
528+
529+
// loop over all other cells in cluster
530+
for (size_t j = 0; j < n; j++) {
531+
if (i == j)
532+
continue;
533+
534+
// adjacent cell is any cell with adjacent phi or eta index
535+
if (std::abs(rows[i] - rows[j]) <= 1 &&
536+
std::abs(columns[i] - columns[j]) <= 1) {
537+
538+
// if there is a cell with higher energy than the current cell, it is not a local maximum
539+
if (energies[j] > energies[i]) {
540+
isExMax = false;
541+
break;
542+
}
543+
}
544+
}
545+
if (isExMax) {
546+
nExMax++;
547+
}
548+
}
549+
clusterAnalysis.setNExMax(nExMax);
550+
}
551+
492552
///
493553
/// Calculates the axis of the shower ellipsoid in eta and phi
494554
/// in cell units

Detectors/EMCAL/base/src/Geometry.cxx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,30 @@ std::tuple<int, int> Geometry::GetCellPhiEtaIndexInSModule(int supermoduleID, in
11031103
return std::make_tuple(phiInSupermodule, etaInSupermodule);
11041104
}
11051105

1106+
std::tuple<short, short> Geometry::GetTopologicalRowColumn(int supermoduleID, int moduleID, int phiInModule, int etaInModule) const
1107+
{
1108+
auto [iphi, ieta] = GetCellPhiEtaIndexInSModule(supermoduleID, moduleID, phiInModule, etaInModule);
1109+
int row = iphi;
1110+
int column = ieta;
1111+
1112+
// Add shifts wrt. supermodule and type of calorimeter
1113+
// NOTE:
1114+
// * Rows (phi) are arranged that one space is left empty between supermodules in phi
1115+
// This is due to the physical gap that forbids clustering
1116+
// * For DCAL, there is an additional empty column between two supermodules in eta
1117+
// Again, this is to account for the gap in DCAL
1118+
1119+
row += supermoduleID / 2 * (24 + 1);
1120+
// In DCAL, leave a gap between two SMs with same phi
1121+
if (!IsDCALSM(supermoduleID)) { // EMCAL
1122+
column += supermoduleID % 2 * 48;
1123+
} else {
1124+
column += supermoduleID % 2 * (48 + 1);
1125+
}
1126+
1127+
return std::make_tuple(static_cast<short>(row), static_cast<short>(column));
1128+
}
1129+
11061130
std::tuple<int, int> Geometry::ShiftOnlineToOfflineCellIndexes(Int_t supermoduleID, Int_t iphi, Int_t ieta) const
11071131
{
11081132
if (supermoduleID == 13 || supermoduleID == 15 || supermoduleID == 17) {

0 commit comments

Comments
 (0)