Skip to content

Commit 1a9bafa

Browse files
mfasDashahor02
authored andcommitted
[EMCAL-841, EMCAL-830] General tool for cell-level calibration
Outsource all calibrations applied in the cell-recalibrator- workflow into a stand-alone tool that can be used on-the- fly. CCDB objects must be set from outside. Two methods applying calibrations are provided, one for a single cell and one for a collection of cells (both templated in order to support different objects inplemeting the CellInterface) In order to check whehter the calibration has been updated or not the CalibLoader has a bitset caching the update status which is reset in checkUpdates and set for each object separately in finalizeCCDB. The initial size of the bitset has been set to short in order to prepare for other objects to be handled by the calib loader.
1 parent dd1166c commit 1a9bafa

7 files changed

Lines changed: 292 additions & 56 deletions

File tree

Detectors/EMCAL/calib/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ o2_add_library(EMCALCalib
2525
src/CalibDB.cxx
2626
src/ElmbMeasurement.cxx
2727
src/EMCALChannelScaleFactors.cxx
28+
src/CellRecalibrator.cxx
2829
PUBLIC_LINK_LIBRARIES O2::CCDB O2::EMCALBase)
2930

3031
o2_target_root_dictionary(EMCALCalib
@@ -43,6 +44,7 @@ o2_target_root_dictionary(EMCALCalib
4344
include/EMCALCalib/ElmbData.h
4445
include/EMCALCalib/ElmbMeasurement.h
4546
include/EMCALCalib/EMCALChannelScaleFactors.h
47+
include/EMCALCalib/CellRecalibrator.h
4648
LINKDEF src/EMCALCalibLinkDef.h)
4749

4850
o2_add_test(BadChannelMap
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
#ifndef ALCEO2_EMCAL_CELLRECALIBRATOR_H
12+
#define ALCEO2_EMCAL_CELLRECALIBRATOR_H
13+
14+
#include <exception>
15+
#include <iosfwd>
16+
#include <optional>
17+
#include <vector>
18+
#include <gsl/span>
19+
20+
#include "Rtypes.h"
21+
22+
#include <DataFormatsEMCAL/Constants.h>
23+
#include <EMCALCalib/BadChannelMap.h>
24+
#include <EMCALCalib/TimeCalibrationParams.h>
25+
#include <EMCALCalib/GainCalibrationFactors.h>
26+
27+
namespace o2
28+
{
29+
30+
namespace emcal
31+
{
32+
33+
/// \class CellRecalibrator
34+
/// \brief Tool for recalibration at cell level
35+
/// \ingroup EMCALcalib
36+
/// \author Markus Fasel <markus.fasel@cern.ch> Oak Ridge National Laboratory
37+
/// \since Oct 12, 2022
38+
///
39+
/// Applying cell-level calibrations
40+
/// - bad channel removal
41+
/// - time shift
42+
/// - gain calibration
43+
///
44+
/// Attention: All calibrations for which calibration objects
45+
/// are provided are applied. Check for active calibration is
46+
/// therefore related to the presence of the corresponding
47+
/// calibration object.
48+
///
49+
/// Input can be a single cell (getCalibratedCell) or a
50+
/// collection of cells (getCalibratedCells). In case of
51+
/// single cell the result is optional since the cell can
52+
/// be rejected by the bad channel mask. Only cells of type
53+
/// high gain or low gain can be calibrated, in case cells
54+
/// of other types (LEDMON/TRU) are passed to getCalibratedCell
55+
/// an exception will be thrown.
56+
///
57+
/// The calibrator supports all cells of the CellInterface
58+
/// concept.
59+
class CellRecalibrator
60+
{
61+
public:
62+
/// \class CellTypeException
63+
/// \brief Handling of invalid cell types in calibration
64+
class CellTypeException : public std::exception
65+
{
66+
public:
67+
/// \brief Constructor
68+
CellTypeException() = default;
69+
70+
/// \brief Destructor
71+
~CellTypeException() noexcept final = default;
72+
73+
/// \brief Get error message of the exception
74+
/// \return Error message
75+
const char* what() const noexcept final
76+
{
77+
return "Only possible to calibrate cells of type high gain or low gain";
78+
}
79+
};
80+
81+
/// \brief Constructor
82+
CellRecalibrator() = default;
83+
84+
/// \brief Destructor
85+
~CellRecalibrator() = default;
86+
87+
/// \brief Set the bad channel map
88+
/// \param bcm Bad channel map to be applied
89+
void setBadChannelMap(const BadChannelMap* bcm) { mBadChannelMap = bcm; }
90+
91+
/// \brief Set the time calibration params
92+
/// \param tcp Time calibration params to be applied
93+
void setTimeCalibration(const TimeCalibrationParams* tcp) { mTimeCalibration = tcp; }
94+
95+
/// \brief Set the gain calibration params
96+
/// \param gcf Gain calibration factors to be applied
97+
void setGainCalibration(const GainCalibrationFactors* gcf) { mGainCalibration = gcf; }
98+
99+
/// \brief Check if the bad channel calibration is enabled
100+
/// \return True if the bad channel calibration is active (object available), false otherwise
101+
bool hasBadChannelMap() const { return mBadChannelMap != nullptr; }
102+
103+
/// \brief Check if the time calibration is enabled
104+
/// \return True if the time calibration is active (object available), false otherwise
105+
bool hasTimeCalibration() const { return mTimeCalibration != nullptr; }
106+
107+
/// \brief Check if the energy calibration is enabled
108+
/// \return True if the energy calibration is active (object available), false otherwise
109+
bool hasGainCalibration() const { return mGainCalibration != nullptr; }
110+
111+
/// \brief Get bad channel map currently used in the calibrator
112+
/// \return Current bad channel map (nullptr if not set)
113+
const BadChannelMap* getBadChannelMap() const { return mBadChannelMap; }
114+
115+
/// \brief Get time calibration parameters currently used in the calibrator
116+
/// \return Current time calibration parameters (nullptr if not set)
117+
const TimeCalibrationParams* getTimeCalibration() const { return mTimeCalibration; }
118+
119+
/// \brief Get gain calibration factors currently used in the calibrator
120+
/// \return Current gain calibration factors (nullptr if not set)
121+
const GainCalibrationFactors* getGainCalibration() const { return mGainCalibration; }
122+
123+
/// \brief Calibrate single cell
124+
///
125+
/// Applying all calibrations provided based on presence of calibration objects. Only
126+
/// cells of type high-gain or low-gain can be calibrated. Since the cell can be rejected
127+
/// by the bad channel calibration the return type is std::optional, where an empty optional
128+
/// reflects rejected cells.
129+
///
130+
/// \param inputcell Cell to calibrate
131+
/// \return Calibrated cell (empty optional if rejected by the bad channel map)
132+
/// \throw CellTypeException in case the inputcell is neither of type high gain nor low gain
133+
template <typename T>
134+
std::optional<T> getCalibratedCell(const T& inputcell) const
135+
{
136+
if (!(inputcell.getHighGain() || inputcell.getLowGain())) {
137+
throw CellTypeException();
138+
}
139+
if (hasBadChannelMap()) {
140+
if (mBadChannelMap->getChannelStatus(inputcell.getTower()) != BadChannelMap::MaskType_t::GOOD_CELL) {
141+
return std::optional<T>();
142+
}
143+
}
144+
145+
float calibratedEnergy = inputcell.getTimeStamp();
146+
float calibratedTime = inputcell.getEnergy();
147+
148+
if (hasTimeCalibration()) {
149+
calibratedTime -= mTimeCalibration->getTimeCalibParam(inputcell.getTower(), inputcell.getLowGain());
150+
}
151+
152+
if (hasGainCalibration()) {
153+
calibratedEnergy *= mGainCalibration->getGainCalibFactors(inputcell.getTower());
154+
}
155+
return std::make_optional<T>(inputcell.getTower(), calibratedEnergy, calibratedTime, inputcell.getHighGain() ? ChannelType_t::HIGH_GAIN : ChannelType_t::LOW_GAIN);
156+
}
157+
158+
/// \brief Get list of calibrated cells based on a cell input collection
159+
///
160+
/// Applying calibrations to all cells in the input collections and return
161+
/// a vector of accepted and calibrated cells. Cells not of type high gain
162+
/// or low gain are discarded. All calibrations for which calibration objects
163+
/// are available are applied.
164+
///
165+
/// \param inputcells Collection of input cells
166+
/// \return vector of calibrated cells.
167+
template <typename T>
168+
std::vector<T> getCalibratedCells(const gsl::span<const T> inputcells)
169+
{
170+
std::vector<T> result;
171+
for (const auto& cellToCalibrate : inputcells) {
172+
if (!(cellToCalibrate.getHighGain() || cellToCalibrate.getLowGain())) {
173+
continue;
174+
}
175+
auto calibrated = getCalibratedCell(cellToCalibrate);
176+
if (calibrated) {
177+
result.push_back(calibrated.value());
178+
}
179+
}
180+
return result;
181+
}
182+
183+
/// \brief Print settings to the stream
184+
/// \param stream Stream to print on
185+
void printStream(std::ostream& stream) const;
186+
187+
private:
188+
const BadChannelMap* mBadChannelMap = nullptr; ///< Bad channel map
189+
const TimeCalibrationParams* mTimeCalibration = nullptr; ///< Time calibration parameters
190+
const GainCalibrationFactors* mGainCalibration = nullptr; ///< Gain calibration parameters
191+
192+
ClassDefNV(CellRecalibrator, 1);
193+
};
194+
195+
/// \brief Output stream operator for cell-level calibrator
196+
/// \param in Stream to print on
197+
/// \param calib CellRecalibrator object to be printed
198+
/// \return Stream after printing
199+
std::ostream& operator<<(std::ostream& in, const CellRecalibrator& calib);
200+
201+
} // namespace emcal
202+
203+
} // namespace o2
204+
205+
#endif // !ALCEO2_EMCAL_CELLRECALIBRATOR_H
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
#include <iostream>
13+
#include <EMCALCalib/CellRecalibrator.h>
14+
15+
using namespace o2::emcal;
16+
17+
void CellRecalibrator::printStream(std::ostream& stream) const
18+
{
19+
stream << "Calibrator settings: \n"
20+
<< "==========================================================="
21+
<< " Bad channel map: " << (hasBadChannelMap() ? "yes" : "no") << "\n"
22+
<< " Time calibration params: " << (hasTimeCalibration() ? "yes" : "no") << "\n"
23+
<< " Energy calibration factors: " << (hasGainCalibration() ? "yes" : "no") << "\n";
24+
}
25+
26+
std::ostream& o2::emcal::operator<<(std::ostream& in, const o2::emcal::CellRecalibrator& calibrator)
27+
{
28+
calibrator.printStream(in);
29+
return in;
30+
}

Detectors/EMCAL/workflow/include/EMCALWorkflow/CalibLoader.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
1111

12+
#include <bitset>
1213
#include <vector>
1314
#include <Framework/ProcessingContext.h>
1415
#include "Framework/ConcreteDataMatcher.h"
@@ -70,6 +71,18 @@ class CalibLoader
7071
/// \return True if the gain calibration factors are handled, false otherwise
7172
bool hasGainCalib() const { return mEnableGainCalib; }
7273

74+
/// \brief Check whether the bad channel map has been updated
75+
/// \return True if the bad channel map has been updated, false otherwise
76+
bool hasUpdateBadChannelMap() const { return mUpdateStatus.test(OBJ_BADCHANNELMAP); }
77+
78+
/// \brief Check whether the time calibration params have been updated
79+
/// \return True if the time calibration params have been updated, false otherwise
80+
bool hasUpdateTimeCalib() const { return mUpdateStatus.test(OBJ_TIMECALIB); }
81+
82+
/// \brief Check whether the gain calibration params have been updated
83+
/// \return True if the gain calibration params have been updated, false otherwise
84+
bool hasUpdateGainCalib() const { return mUpdateStatus.test(OBJ_GAINCALIB); }
85+
7386
/// \brief Enable loading of the bad channel map
7487
/// \param doEnable If true the bad channel map is loaded (per default from CCDB)
7588
void enableBadChannelMap(bool doEnable) { mEnableBadChannelMap = doEnable; }
@@ -82,6 +95,18 @@ class CalibLoader
8295
/// \param doEnable If true the gain calibration factors are loaded (per default from CCDB)
8396
void enableGainCalib(bool doEnable) { mEnableGainCalib = doEnable; }
8497

98+
/// \brief Mark bad channel map as updated
99+
void setUpdateBadChannelMap() { mUpdateStatus.set(OBJ_BADCHANNELMAP, true); }
100+
101+
/// \brief Mark time calibration params as updated
102+
void setUpdateTimeCalib() { mUpdateStatus.set(OBJ_TIMECALIB, true); }
103+
104+
/// \brief Mark gain calibration params as updated
105+
void setUpdateGainCalib() { mUpdateStatus.set(OBJ_GAINCALIB, true); }
106+
107+
/// \brief Reset the update status (all objects marked as false)
108+
void resetUpdateStatus() { mUpdateStatus.reset(); }
109+
85110
/// \brief Define input specs in workflow for calibration objects to be loaded from the CCDB
86111
/// \param ccdbInputs List of inputs where the CCDB input specs will be added to
87112
///
@@ -104,12 +129,18 @@ class CalibLoader
104129
bool finalizeCCDB(framework::ConcreteDataMatcher& matcher, void* obj);
105130

106131
private:
132+
enum CalibObject_t {
133+
OBJ_BADCHANNELMAP,
134+
OBJ_TIMECALIB,
135+
OBJ_GAINCALIB
136+
};
107137
bool mEnableBadChannelMap; ///< Switch for enabling / disabling loading of the bad channel map
108138
bool mEnableTimeCalib; ///< Switch for enabling / disabling loading of the time calibration params
109139
bool mEnableGainCalib; ///< Switch for enabling / disabling loading of the gain calibration params
110140
o2::emcal::BadChannelMap* mBadChannelMap = nullptr; ///< Container of current bad channel map
111141
o2::emcal::TimeCalibrationParams* mTimeCalibParams = nullptr; ///< Container of current time calibration object
112142
o2::emcal::GainCalibrationFactors* mGainCalibParams = nullptr; ///< Container of current gain calibration object
143+
std::bitset<16> mUpdateStatus; ///< Object update status
113144
};
114145

115146
} // namespace emcal

Detectors/EMCAL/workflow/include/EMCALWorkflow/CellRecalibratorSpec.h

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <bitset>
1313
#include <cstdint>
1414
#include <optional>
15+
#include "EMCALCalib/CellRecalibrator.h"
1516
#include "EMCALWorkflow/CalibLoader.h"
1617
#include "Framework/ConcreteDataMatcher.h"
1718
#include "Framework/DataProcessorSpec.h"
@@ -107,15 +108,7 @@ class CellRecalibratorSpec : public framework::Task
107108
bool isRunGainCalibration() const { return mCalibrationSettings.test(GAIN_CALIB); }
108109

109110
private:
110-
/// \brief Apply requested calibrations to the cell
111-
/// \param inputcell Cell to be calibrated
112-
/// \return Optional of calibrated cell (empty optional in case the cell is rejected as bad or dead)
113-
///
114-
/// Recalibrating cell for energy and time, and check whether the corresponding tower is not
115-
/// marked as bad or dead. Only calibrations which are enabled are applied.
116-
std::optional<o2::emcal::Cell> getCalibratedCell(const o2::emcal::Cell& inputcell) const;
117-
118-
/// \brief Update internal cache of calibration objects
111+
/// \brief Update calibration objects (if changed)
119112
void updateCalibObjects();
120113

121114
/// \enum CalibrationType_t
@@ -126,12 +119,10 @@ class CellRecalibratorSpec : public framework::Task
126119
GAIN_CALIB = 2 ///< Gain calibration
127120
};
128121

129-
uint32_t mOutputSubspec = 0; ///< output subspecification;
130-
std::bitset<8> mCalibrationSettings; ///< Recalibration settings (which calibration to be applied)
131-
std::shared_ptr<CalibLoader> mCalibrationHandler; ///< Handler loading calibration objects
132-
const BadChannelMap* mBadChannelMap = nullptr; ///< Bad channelMap
133-
const TimeCalibrationParams* mTimeCalibration = nullptr; ///< Time calibration coefficients
134-
const GainCalibrationFactors* mGainCalibration = nullptr; ///< Gain calibration factors
122+
uint32_t mOutputSubspec = 0; ///< output subspecification;
123+
std::bitset<8> mCalibrationSettings; ///< Recalibration settings (which calibration to be applied)
124+
std::shared_ptr<CalibLoader> mCalibrationHandler; ///< Handler loading calibration objects
125+
CellRecalibrator mCellRecalibrator; ///< Recalibrator at cell level
135126
};
136127

137128
/// \brief Create CellRecalibrator processor spec

Detectors/EMCAL/workflow/src/CalibLoader.cxx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ void CalibLoader::defineInputSpecs(std::vector<o2::framework::InputSpec>& inputs
3737

3838
void CalibLoader::checkUpdates(o2::framework::ProcessingContext& ctx)
3939
{
40+
resetUpdateStatus();
4041
if (hasBadChannelMap()) {
4142
ctx.inputs().get<o2::emcal::BadChannelMap*>("badChannelMap");
4243
}
@@ -54,6 +55,7 @@ bool CalibLoader::finalizeCCDB(o2::framework::ConcreteDataMatcher& matcher, void
5455
if (hasBadChannelMap()) {
5556
LOG(info) << "New bad channel map loaded";
5657
mBadChannelMap = reinterpret_cast<o2::emcal::BadChannelMap*>(obj);
58+
setUpdateBadChannelMap();
5759
} else {
5860
LOG(error) << "New bad channel map available even though bad channel calibration was not enabled, not loading";
5961
}
@@ -63,6 +65,7 @@ bool CalibLoader::finalizeCCDB(o2::framework::ConcreteDataMatcher& matcher, void
6365
if (hasTimeCalib()) {
6466
LOG(info) << "New time calibration paramset loaded";
6567
mTimeCalibParams = reinterpret_cast<o2::emcal::TimeCalibrationParams*>(obj);
68+
setUpdateTimeCalib();
6669
} else {
6770
LOG(error) << "New time calibration paramset available even though time calibration was not enabled, not loading";
6871
}
@@ -72,6 +75,7 @@ bool CalibLoader::finalizeCCDB(o2::framework::ConcreteDataMatcher& matcher, void
7275
if (hasGainCalib()) {
7376
LOG(info) << "New gain calibration paramset loaded";
7477
mGainCalibParams = reinterpret_cast<o2::emcal::GainCalibrationFactors*>(obj);
78+
setUpdateGainCalib();
7579
} else {
7680
LOG(error) << "New gain calibration paramset available even though the gain calibration was not enabled, not loading";
7781
}

0 commit comments

Comments
 (0)