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
0 commit comments