Skip to content

Commit ccca242

Browse files
committed
[EMCAL] implementation of number of local maxima variable
1 parent d6f6148 commit ccca242

File tree

4 files changed

+94
-0
lines changed

4 files changed

+94
-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: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,16 @@ 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+
433+
/// \brief Get topological row and column of cell in SM (same as for clusteriser with artifical gaps)
434+
/// \param supermoduleID super module number
435+
/// \param moduleID module number
436+
/// \param phiInModule index in phi direction in module
437+
/// \param etaInModule index in phi direction in module
438+
/// \return tuple with (row, column) of the cell, which is global numbering scheme
439+
std::tuple<int,int> GetTopologicalRowColumn(int supermoduleID, int moduleID, int phiInModule, int etaInModule) const;
440+
441+
432442
/// \brief Adapt cell indices in supermodule to online indexing
433443
/// \param supermoduleID super module number of the channel/cell
434444
/// \param iphi row/phi cell index, modified for DCal

Detectors/EMCAL/base/src/ClusterFactory.cxx

Lines changed: 56 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,59 @@ 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+
struct CellInfo {
503+
int row;
504+
int column;
505+
double energy;
506+
};
507+
508+
std::vector<CellInfo> cellInfos;
509+
cellInfos.reserve(inputsIndices.size());
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+
auto [row, column] = mGeomPtr->GetTopologicalRowColumn(nSupMod, nModule, nIphi, nIeta);
517+
cellInfos.push_back({row, column, mInputsContainer[iInput].getEnergy()});
518+
}
519+
520+
// Now find local maxima using pre-computed data
521+
int nExMax = 0;
522+
for (size_t i = 0; i < cellInfos.size(); i++) {
523+
// this cell is assumed to be local maximum unless we find a higher energy cell in the neighborhood
524+
bool isExMax = true;
525+
526+
// loop over all other cells in cluster
527+
for (size_t j = 0; j < cellInfos.size(); j++) {
528+
if (i == j) continue;
529+
530+
// adjacent cell is any cell with adjacent phi or eta index
531+
if (std::abs(cellInfos[i].row - cellInfos[j].row) <= 1 &&
532+
std::abs(cellInfos[i].column - cellInfos[j].column) <= 1) {
533+
534+
// if there is a cell with higher energy than the current cell, it is not a local maximum
535+
if (cellInfos[j].energy > cellInfos[i].energy) {
536+
isExMax = false;
537+
break;
538+
}
539+
}
540+
}
541+
if (isExMax) {
542+
nExMax++;
543+
}
544+
}
545+
clusterAnalysis.setNExMax(nExMax);
546+
}
547+
492548
///
493549
/// Calculates the axis of the shower ellipsoid in eta and phi
494550
/// 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<int, int> 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(row, 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)