Skip to content

Commit

Permalink
[EMCAL-688] Inclusion of EMCal Cell and Cluster labels (#12660)
Browse files Browse the repository at this point in the history
- Add CellLabel class to handle the pairs of MC particle IDs and amplitdue fraction on cell level which the ClusterFactory now uses as a new container inside the `buildCluster` function. For this function an additional argument was added, more info next bullet.
- Add ClusterLabel class to handel the paris of MC particle IDs and amplitude fraction on cluster level. They get filled inside the `buildCluster` function of the cluster factory where a point to an object of ClusterLabel is now an optional 2nd argument to the function. If one pointer is give, the ClusterLabel is filled with the labels and amplitude fractions and orderer inside the ClusterFactory.
  • Loading branch information
mhemmer-cern authored Feb 8, 2024
1 parent 0667094 commit 4d5481e
Show file tree
Hide file tree
Showing 8 changed files with 292 additions and 10 deletions.
6 changes: 5 additions & 1 deletion DataFormats/Detectors/EMCAL/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ o2_add_library(DataFormatsEMCAL
src/EventHandler.cxx
src/CTF.cxx
src/ErrorTypeFEE.cxx
src/CellLabel.cxx
src/ClusterLabel.cxx
PUBLIC_LINK_LIBRARIES O2::CommonDataFormat
O2::Headers
O2::MathUtils
Expand All @@ -37,7 +39,9 @@ o2_target_root_dictionary(DataFormatsEMCAL
include/DataFormatsEMCAL/EventHandler.h
include/DataFormatsEMCAL/MCLabel.h
include/DataFormatsEMCAL/CTF.h
include/DataFormatsEMCAL/ErrorTypeFEE.h)
include/DataFormatsEMCAL/ErrorTypeFEE.h
include/DataFormatsEMCAL/CellLabel.h
include/DataFormatsEMCAL/ClusterLabel.h)

o2_add_test(Cell
SOURCES test/testCell.cxx
Expand Down
66 changes: 66 additions & 0 deletions DataFormats/Detectors/EMCAL/include/DataFormatsEMCAL/CellLabel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

#ifndef ALICEO2_EMCAL_CELLLABEL_H_
#define ALICEO2_EMCAL_CELLLABEL_H_

#include <fairlogger/Logger.h>
#include <gsl/span>
#include <vector>
#include "Rtypes.h"

namespace o2
{

namespace emcal
{

/// \class CellLabel
/// \brief cell class for MC particle IDs and their respective amplitude fraction
/// \ingroup EMCALDataFormat
/// \author Marvin Hemmer <[email protected]>, Goethe university Frankfurt
/// \since December 13, 2023
///

class CellLabel
{
public:
// CellLabel() = default;

/// \brief Constructor
/// \param labels list of mc labels
/// \param amplitudeFractions list of amplitude fractions
CellLabel(const gsl::span<const int> labels, const gsl::span<const float> amplitudeFractions);

// ~CellLabel() = default;
// CellLabel(const CellLabel& clus) = default;
// CellLabel& operator=(const CellLabel& source) = default;

/// \brief Getter of label size
/// \param index index which label to get
size_t GetLabelSize(void) const { return mLabels.size(); }

/// \brief Getter for label
/// \param index index which label to get
int32_t GetLabel(size_t index) const { return mLabels[index]; }

/// \brief Getter for amplitude fraction
/// \param index index which amplitude fraction to get
float GetAmplitudeFraction(size_t index) const { return mAmplitudeFraction[index]; }

protected:
gsl::span<const int32_t> mLabels; ///< List of MC particles that generated the cluster, ordered in deposited energy.
gsl::span<const float> mAmplitudeFraction; ///< List of the fraction of the cell energy coming from a MC particle. Index aligns with mLabels!
};

} // namespace emcal
} // namespace o2
#endif // ALICEO2_EMCAL_CELLLABEL_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

#ifndef ALICEO2_EMCAL_CLUSTERLABEL_H_
#define ALICEO2_EMCAL_CLUSTERLABEL_H_

#include <fairlogger/Logger.h>
#include <gsl/span>
#include <vector>
#include "Rtypes.h"

namespace o2
{

namespace emcal
{

/// \class ClusterLabel
/// \brief cluster class for MC particle IDs and their respective energy fraction
/// \ingroup EMCALDataFormat
/// \author Marvin Hemmer <[email protected]>, Goethe university Frankfurt
/// \since December 13, 2023
///

class ClusterLabel
{
public:
/// \struct labelWithE
/// \brief Wrapper structure to make cluster label sortable in energy fraction
struct labelWithE {

/// \brief Constructor
labelWithE() : energyFraction(0.), label(0) {}

/// \brief Constructor
/// \param e Energy fraction
/// \param l MC label
labelWithE(float e, int l) : energyFraction(e), label(l) {}

/// \brief Comparison lower operator comparing cells based on energy
///
/// std::sort will require operator>= to compile.
///
/// \param rhs Label to compare to
/// \return True if this cell is has a lower energy, false otherwise
bool operator>=(labelWithE const& rhs) const
{
return energyFraction >= rhs.energyFraction;
}

float energyFraction; ///< Energy Fraction
int label; ///< MC label
};

// ClusterLabel() = default;
// ~ClusterLabel() = default;
// ClusterLabel(const ClusterLabel& clus) = default;
// ClusterLabel& operator=(const ClusterLabel& source) = default;

/// \brief Clear the member variables
void clear();

/// \brief Add label and energy fraction to the
/// \param label MC label
/// \param energyFraction Energy fraction
void addValue(int label, float energyFraction);

/// \brief Normalize the energy fraction
/// \param factor normalization factor
void normalize(float factor);

/// \brief Getter for vector of labels
std::vector<int32_t> getLabels();

/// \brief Getter for vector of energy fractions
std::vector<float> getEnergyFractions();

/// \brief Sort the labels and energy fraction in descending order (largest energy fraction to smallest)
void orderLabels();

protected:
std::vector<labelWithE> mClusterLabels; ///< List of MC particles that generated the cluster, paired with energy fraction
};

} // namespace emcal
} // namespace o2
#endif // ALICEO2_EMCAL_CLUSTERLABEL_H_
23 changes: 23 additions & 0 deletions DataFormats/Detectors/EMCAL/src/CellLabel.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

/// \file CellLabel.cxx

#include "DataFormatsEMCAL/CellLabel.h"

using namespace o2::emcal;

CellLabel::CellLabel(const gsl::span<const int> labels, const gsl::span<const float> amplitudeFractions) : mLabels(labels), mAmplitudeFraction(amplitudeFractions)
{
if (labels.size() != amplitudeFractions.size()) {
LOG(error) << "Size of labels " << labels.size() << " does not match size of amplitude fraction " << amplitudeFractions.size() << " !";
}
}
75 changes: 75 additions & 0 deletions DataFormats/Detectors/EMCAL/src/ClusterLabel.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

/// \file ClusterLabel.cxx

#include "DataFormatsEMCAL/ClusterLabel.h"

using namespace o2::emcal;

//_______________________________________________________________________
void ClusterLabel::clear()
{
mClusterLabels.clear();
}

//_______________________________________________________________________
void ClusterLabel::addValue(int label, float energyFraction)
{
auto it = std::find_if(mClusterLabels.begin(), mClusterLabels.end(),
[label](const labelWithE& lWE) { return lWE.label == label; });

if (it != mClusterLabels.end()) {
// label already exists, accumulate energy fraction
it->energyFraction += energyFraction;
} else {
// label does not exist, add new energy fraction
mClusterLabels.emplace_back(label, energyFraction);
}
}

//_______________________________________________________________________
void ClusterLabel::normalize(float factor)
{
for (auto& clusterlabel : mClusterLabels) {
clusterlabel.energyFraction = clusterlabel.energyFraction / factor;
}
}

//_______________________________________________________________________
std::vector<int32_t> ClusterLabel::getLabels()
{
std::vector<int32_t> vLabels;
vLabels.reserve(mClusterLabels.size());
for (auto& clusterlabel : mClusterLabels) {
vLabels.push_back(clusterlabel.label);
}
return vLabels;
}

//_______________________________________________________________________
std::vector<float> ClusterLabel::getEnergyFractions()
{
std::vector<float> vEnergyFractions;
vEnergyFractions.reserve(mClusterLabels.size());
for (auto& clusterlabel : mClusterLabels) {
vEnergyFractions.push_back(clusterlabel.energyFraction);
}
return vEnergyFractions;
}

//_______________________________________________________________________
void ClusterLabel::orderLabels()
{
// Sort the pairs based on values in descending order
std::sort(mClusterLabels.begin(), mClusterLabels.end(),
[](const labelWithE& a, const labelWithE& b) { return a.label >= b.label; });
}
2 changes: 0 additions & 2 deletions DataFormats/Detectors/EMCAL/src/DataFormatsEMCALLinkDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@
// For channel type in digits and cells
#pragma link C++ enum o2::emcal::ChannelType_t + ;

#pragma link C++ class std::vector < o2::emcal::Cluster> + ;

#pragma link C++ class o2::emcal::EventData < o2::emcal::Cell> + ;
#pragma link C++ class o2::emcal::EventData < o2::emcal::Digit> + ;
#pragma link C++ class o2::emcal::EventHandler < o2::emcal::Cell> + ;
Expand Down
20 changes: 14 additions & 6 deletions Detectors/EMCAL/base/include/EMCALBase/ClusterFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#ifndef ALICEO2_EMCAL_CLUSTERFACTORY_H_
#define ALICEO2_EMCAL_CLUSTERFACTORY_H_
#include <array>
#include <vector>
#include <optional>
#include <utility>
#include <gsl/span>
#include "Rtypes.h"
Expand All @@ -19,6 +21,8 @@
#include "DataFormatsEMCAL/Digit.h"
#include "DataFormatsEMCAL/Cell.h"
#include "DataFormatsEMCAL/AnalysisCluster.h"
#include "DataFormatsEMCAL/CellLabel.h"
#include "DataFormatsEMCAL/ClusterLabel.h"
#include "EMCALBase/Geometry.h"
#include "MathUtils/Cartesian.h"

Expand Down Expand Up @@ -230,7 +234,7 @@ class ClusterFactory

///
/// evaluates cluster parameters: position, shower shape, primaries ...
AnalysisCluster buildCluster(int index) const;
AnalysisCluster buildCluster(int index, o2::emcal::ClusterLabel* clusterLabel = nullptr) const;

void SetECALogWeight(Float_t w) { mLogWeight = w; }
float GetECALogWeight() const { return mLogWeight; }
Expand Down Expand Up @@ -331,14 +335,17 @@ class ClusterFactory
bool getUseWeightExotic() const { return mUseWeightExotic; }
void setUseWeightExotic(float useWeightExotic) { mUseWeightExotic = useWeightExotic; }

void setContainer(gsl::span<const o2::emcal::Cluster> clusterContainer, gsl::span<const InputType> cellContainer, gsl::span<const int> indicesContainer)
void setContainer(gsl::span<const o2::emcal::Cluster> clusterContainer, gsl::span<const InputType> cellContainer, gsl::span<const int> indicesContainer, std::optional<gsl::span<const o2::emcal::CellLabel>> cellLabelContainer = std::nullopt)
{
mClustersContainer = clusterContainer;
mInputsContainer = cellContainer;
mCellsIndices = indicesContainer;
if (!getLookUpInit()) {
setLookUpTable();
}
if (cellLabelContainer) {
mCellLabelContainer = cellLabelContainer.value();
}
}

void setLookUpTable(void)
Expand Down Expand Up @@ -425,10 +432,11 @@ class ClusterFactory
float mExoticCellInCrossMinAmplitude = 0.1; ///< Minimum energy of cells in cross, if lower not considered in cross
bool mUseWeightExotic = false; ///< States if weights should be used for exotic cell cut

gsl::span<const o2::emcal::Cluster> mClustersContainer; ///< Container for all the clusters in the event
gsl::span<const InputType> mInputsContainer; ///< Container for all the cells/digits in the event
gsl::span<const int> mCellsIndices; ///< Container for cells indices in the event
std::array<short, 17664> mLoolUpTowerToIndex; ///< Lookup table to match tower id with cell index, needed for exotic check
gsl::span<const o2::emcal::Cluster> mClustersContainer; ///< Container for all the clusters in the event
gsl::span<const InputType> mInputsContainer; ///< Container for all the cells/digits in the event
gsl::span<const int> mCellsIndices; ///< Container for cells indices in the event
std::array<short, 17664> mLoolUpTowerToIndex; ///< Lookup table to match tower id with cell index, needed for exotic check
gsl::span<const o2::emcal::CellLabel> mCellLabelContainer; ///< Container for all the cell labels in the event

ClassDefNV(ClusterFactory, 2);
};
Expand Down
15 changes: 14 additions & 1 deletion Detectors/EMCAL/base/src/ClusterFactory.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "DataFormatsEMCAL/Cell.h"
#include "DataFormatsEMCAL/AnalysisCluster.h"
#include "DataFormatsEMCAL/Constants.h"
#include "DataFormatsEMCAL/CellLabel.h"
#include "DataFormatsEMCAL/ClusterLabel.h"
#include "EMCALBase/Geometry.h"
#include "MathUtils/Cartesian.h"

Expand All @@ -38,13 +40,14 @@ void ClusterFactory<InputType>::reset()
mInputsContainer = gsl::span<const InputType>();
mCellsIndices = gsl::span<int>();
mLookUpInit = false;
mCellLabelContainer = gsl::span<const o2::emcal::CellLabel>();
}

///
/// evaluates cluster parameters: position, shower shape, primaries ...
//____________________________________________________________________________
template <class InputType>
o2::emcal::AnalysisCluster ClusterFactory<InputType>::buildCluster(int clusterIndex) const
o2::emcal::AnalysisCluster ClusterFactory<InputType>::buildCluster(int clusterIndex, o2::emcal::ClusterLabel* clusterLabel) const
{
if (clusterIndex >= mClustersContainer.size()) {
throw ClusterRangeException(clusterIndex, mClustersContainer.size());
Expand Down Expand Up @@ -86,9 +89,19 @@ o2::emcal::AnalysisCluster ClusterFactory<InputType>::buildCluster(int clusterIn

std::vector<unsigned short> cellsIdices;

size_t iCell = 0;
for (auto cellIndex : inputsIndices) {
cellsIdices.push_back(cellIndex);
if ((clusterLabel != nullptr) && (mCellLabelContainer.size() > 0)) {
for (size_t iLabel = 0; iLabel < mCellLabelContainer[iCell].GetLabelSize(); iLabel++) {
clusterLabel->addValue(mCellLabelContainer[iCell].GetLabel(iLabel),
mCellLabelContainer[iCell].GetAmplitudeFraction(iLabel) * mInputsContainer[iCell].getEnergy());
}
iCell++;
}
}
clusterLabel->orderLabels();
clusterLabel->normalize(cellAmp);

clusterAnalysis.setCellsIndices(cellsIdices);

Expand Down

0 comments on commit 4d5481e

Please sign in to comment.