Skip to content

Commit 92b9569

Browse files
authored
[EMCAL-524] Optional energy recalibration on-the-fly (#1881)
- Add option to recalibrate cell energy on-the-fly (synchronous QC only) - Add histograms for average cell energy (sensitive to gain calibration) and average cell time (sensitive to time calibration)
1 parent 5b25acc commit 92b9569

2 files changed

Lines changed: 58 additions & 22 deletions

File tree

Modules/EMCAL/include/EMCAL/CellTask.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ namespace emcal
4141
class Geometry;
4242
class BadChannelMap;
4343
class TimeCalibrationParams;
44+
class GainCalibrationFactors;
4445
class Cell;
4546
} // namespace emcal
4647

@@ -63,6 +64,7 @@ class CellTask final : public TaskInterface
6364
bool mHasAmpVsCellID;
6465
bool mHasTimeVsCellID;
6566
bool mHasHistosCalib;
67+
bool mCalibrateEnergy;
6668

6769
double mAmpThresholdTimePhys = 0.15;
6870
double mAmpThresholdTimeCalib = 0.3;
@@ -96,6 +98,8 @@ class CellTask final : public TaskInterface
9698
TH2* mCellOccupancyGood = nullptr; ///< Cell occupancy EMCAL and DCAL good cells
9799
TH2* mCellOccupancyBad = nullptr; ///< Cell occupancy EMCAL and DCAL bad cells
98100
TH2* mIntegratedOccupancy = nullptr; ///< Cell integrated occupancy
101+
TH2* mAverageCellEnergy = nullptr; ///< Average cell energy
102+
TH2* mAverageCellTime = nullptr; ///< Average cell time
99103
TH1* mCellAmplitude_tot = nullptr; ///< Cell amplitude in EMCAL,DCAL
100104
TH1* mCellAmplitudeEMCAL = nullptr; ///< Cell amplitude in EMCAL
101105
TH1* mCellAmplitudeDCAL = nullptr; ///< Cell amplitude in DCAL
@@ -118,7 +122,7 @@ class CellTask final : public TaskInterface
118122
void reset();
119123
void clean();
120124

121-
void fillHistograms(const o2::emcal::Cell& cell, bool isGood, double timeoffset, int bcphase);
125+
void fillHistograms(const o2::emcal::Cell& cell, bool isGood, double timeoffset, double energycalib, int bcphase);
122126
void countEvent();
123127
};
124128

@@ -172,6 +176,7 @@ class CellTask final : public TaskInterface
172176
o2::emcal::Geometry* mGeometry = nullptr; ///< EMCAL geometry
173177
o2::emcal::BadChannelMap* mBadChannelMap = nullptr; ///< EMCAL channel map
174178
o2::emcal::TimeCalibrationParams* mTimeCalib = nullptr; ///< EMCAL time calib
179+
o2::emcal::GainCalibrationFactors* mEnergyCalib = nullptr; ///< EMCAL energy calibration
175180
int mTimeFramesPerCycles = 0; ///< TF per cycles
176181

177182
TH1* mEvCounterTF = nullptr; ///< Number of Events per timeframe

Modules/EMCAL/src/CellTask.cxx

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "EMCALBase/Geometry.h"
3131
#include "EMCALCalib/CalibDB.h"
3232
#include "EMCALCalib/BadChannelMap.h"
33+
#include "EMCALCalib/GainCalibrationFactors.h"
3334
#include "EMCALCalib/TimeCalibrationParams.h"
3435
#include <Framework/ConcreteDataMatcher.h>
3536
#include <Framework/DataRefUtils.h>
@@ -111,6 +112,7 @@ void CellTask::initialize(o2::framework::InitContext& /*ctx*/)
111112
mTaskSettings.mHasAmpVsCellID = get_bool(getConfigValueLower("hasAmpVsCell")),
112113
mTaskSettings.mHasTimeVsCellID = get_bool(getConfigValueLower("hasTimeVsCell")),
113114
mTaskSettings.mHasHistosCalib = get_bool(getConfigValueLower("hasHistCalib"));
115+
mTaskSettings.mCalibrateEnergy = get_bool(getConfigValue("calibrateEnergy"));
114116
if (hasConfigValue("thresholdTimePhys")) {
115117
mTaskSettings.mAmpThresholdTimePhys = get_double(getConfigValue("thresholdTimePhys"));
116118
}
@@ -123,6 +125,7 @@ void CellTask::initialize(o2::framework::InitContext& /*ctx*/)
123125
if (hasConfigValue("thresholdPHYS")) {
124126
mTaskSettings.mThresholdPHYS = get_double(getConfigValue("thresholdPHYS"));
125127
}
128+
ILOG(Info, Support) << "Apply energy calibration: " << (mTaskSettings.mCalibrateEnergy ? "yes" : "no") << ENDM;
126129
ILOG(Info, Support) << "Amplitude cut time histograms (PhysTrigger) " << mTaskSettings.mAmpThresholdTimePhys << ENDM;
127130
ILOG(Info, Support) << "Amplitude cut time histograms (CalibTrigger) " << mTaskSettings.mAmpThresholdTimeCalib << ENDM;
128131
ILOG(Info, Support) << "Amplitude cut occupancy histograms (PhysTrigger) " << mTaskSettings.mThresholdPHYS << ENDM;
@@ -331,6 +334,13 @@ void CellTask::startOfCycle()
331334
ILOG(Info, Support) << " No Time Calib object " << ENDM;
332335
}
333336
}
337+
if (mTaskSettings.mCalibrateEnergy) {
338+
std::map<std::string, std::string> metadata;
339+
mEnergyCalib = retrieveConditionAny<o2::emcal::GainCalibrationFactors>(o2::emcal::CalibDB::getCDBPathGainCalibrationParams(), metadata);
340+
if (!mBadChannelMap) {
341+
ILOG(Info, Support) << "No energy calibration object " << ENDM;
342+
}
343+
}
334344
}
335345

336346
void CellTask::monitorData(o2::framework::ProcessingContext& ctx)
@@ -436,11 +446,12 @@ void CellTask::monitorData(o2::framework::ProcessingContext& ctx)
436446
// int index = cell.getHighGain() ? 0 : (cell.getLowGain() ? 1 : -1);
437447
// int index = cell.getHighGain() ? 0 : 1;
438448
auto timeoffset = mTimeCalib ? mTimeCalib->getTimeCalibParam(cell.getTower(), cell.getLowGain()) : 0.;
449+
auto energycalib = mEnergyCalib ? mEnergyCalib->getGainCalibFactors(cell.getTower()) : 1.;
439450
bool goodcell = true;
440451
if (mBadChannelMap) {
441452
goodcell = mBadChannelMap->getChannelStatus(cell.getTower()) == MaskType_t::GOOD_CELL;
442453
}
443-
histos.fillHistograms(cell, goodcell, timeoffset, bcphase);
454+
histos.fillHistograms(cell, goodcell, timeoffset, energycalib, bcphase);
444455
if (isPhysTrigger) {
445456
auto [sm, mod, iphi, ieta] = mGeometry->GetCellIndex(cell.getTower());
446457
numCellsSM[sm]++;
@@ -731,6 +742,16 @@ void CellTask::CellHistograms::initForTrigger(const std::string trigger, const T
731742
mCellOccupancyThrBelow = histBuilder2D("cellOccupancyEMCwThrBelow", Form("Cell Occupancy EMCAL,DCAL with E<%.1f GeV/c", mCellThreshold), 96, -0.5, 95.5, 208, -0.5, 207.5, false);
732743
mCellOccupancyThrBelow->SetStats(false);
733744

745+
mAverageCellEnergy = histBuilder2D("averageCellEnergy", "Average cell energy", 96, -0.5, 95.5, 208, -0.5, 207.5, true);
746+
mAverageCellEnergy->GetXaxis()->SetTitle("col");
747+
mAverageCellEnergy->GetYaxis()->SetTitle("row");
748+
mAverageCellEnergy->SetStats(false);
749+
750+
mAverageCellTime = histBuilder2D("averageCellTime", "Average cell time", 96, -0.5, 95.5, 208, -0.5, 207.5, true);
751+
mAverageCellTime->GetXaxis()->SetTitle("col");
752+
mAverageCellTime->GetYaxis()->SetTitle("row");
753+
mAverageCellTime->SetStats(false);
754+
734755
mIntegratedOccupancy = histBuilder2D("cellOccupancyInt", "Cell Occupancy Integrated", 96, -0.5, 95.5, 208, -0.5, 207.5, true);
735756
mIntegratedOccupancy->GetXaxis()->SetTitle("col");
736757
mIntegratedOccupancy->GetYaxis()->SetTitle("row");
@@ -765,7 +786,7 @@ void CellTask::CellHistograms::initForTrigger(const std::string trigger, const T
765786
}
766787
}
767788

768-
void CellTask::CellHistograms::fillHistograms(const o2::emcal::Cell& cell, bool goodCell, double timecalib, int bcphase)
789+
void CellTask::CellHistograms::fillHistograms(const o2::emcal::Cell& cell, bool goodCell, double timecalib, double energycalib, int bcphase)
769790
{
770791
auto fillOptional1D = [](TH1* hist, double x, double weight = 1.) {
771792
if (hist) {
@@ -778,11 +799,13 @@ void CellTask::CellHistograms::fillHistograms(const o2::emcal::Cell& cell, bool
778799
}
779800
};
780801

781-
fillOptional2D(mCellAmplitude, cell.getEnergy(), cell.getTower());
802+
double energy = cell.getEnergy() * energycalib;
803+
804+
fillOptional2D(mCellAmplitude, energy, cell.getTower());
782805
// fillOptional2D(mCellAmplitude[index], cell.getEnergy(), cell.getTower());
783806

784807
if (goodCell) {
785-
fillOptional2D(mCellAmplitudeCalib, cell.getEnergy(), cell.getTower());
808+
fillOptional2D(mCellAmplitudeCalib, energy, cell.getTower());
786809
fillOptional2D(mCellTimeCalib, cell.getTimeStamp() - timecalib, cell.getTower());
787810
// fillOptional2D(mCellAmplitudeCalib[index], cell.getEnergy(), cell.getTower());
788811
// fillOptional2D(mCellTimeCalib[index], cell.getTimeStamp() - timeoffset, cell.getTower());
@@ -802,11 +825,13 @@ void CellTask::CellHistograms::fillHistograms(const o2::emcal::Cell& cell, bool
802825
}
803826
if (goodCell) {
804827
fillOptional2D(mCellOccupancyGood, col, row);
828+
fillOptional2D(mAverageCellEnergy, col, row, energy);
829+
fillOptional2D(mAverageCellTime, col, row, cell.getTimeStamp() - timecalib);
805830
} else {
806831
fillOptional2D(mCellOccupancyBad, col, row);
807832
}
808833

809-
fillOptional2D(mIntegratedOccupancy, col, row, cell.getEnergy());
834+
fillOptional2D(mIntegratedOccupancy, col, row, energy);
810835

811836
} catch (o2::emcal::InvalidCellIDException& e) {
812837
ILOG(Error, Support) << "Invalid cell ID: " << e.getCellID() << ENDM;
@@ -815,25 +840,25 @@ void CellTask::CellHistograms::fillHistograms(const o2::emcal::Cell& cell, bool
815840
try {
816841
auto cellindices = mGeometry->GetCellIndex(cell.getTower());
817842
auto supermoduleID = std::get<0>(cellindices);
818-
fillOptional2D(mCellAmpSupermodule, cell.getEnergy(), supermoduleID);
819-
fillOptional2D(mCellAmplitudeTime, cell.getEnergy(), cell.getTimeStamp());
843+
fillOptional2D(mCellAmpSupermodule, energy, supermoduleID);
844+
fillOptional2D(mCellAmplitudeTime, energy, cell.getTimeStamp());
820845
if (cell.getEnergy() > mAmplitudeThresholdTime) {
821846
fillOptional2D(mCellTimeSupermodule, cell.getTimeStamp(), supermoduleID);
822847
}
823848
if (goodCell) {
824-
fillOptional2D(mCellAmpSupermoduleCalib, cell.getEnergy(), supermoduleID);
825-
if (cell.getEnergy() > mAmplitudeThresholdTime) {
849+
fillOptional2D(mCellAmpSupermoduleCalib, energy, supermoduleID);
850+
if (energy > mAmplitudeThresholdTime) {
826851
fillOptional2D(mCellTimeSupermoduleCalib, cell.getTimeStamp() - timecalib, supermoduleID);
827-
fillOptional2D(mCellAmplitudeTimeCalib, cell.getEnergy(), cell.getTimeStamp() - timecalib);
852+
fillOptional2D(mCellAmplitudeTimeCalib, energy, cell.getTimeStamp() - timecalib);
828853
}
829854
} else {
830-
fillOptional2D(mCellAmpSupermoduleBad, cell.getEnergy(), supermoduleID);
855+
fillOptional2D(mCellAmpSupermoduleBad, energy, supermoduleID);
831856
}
832-
fillOptional1D(mCellAmplitude_tot, cell.getEnergy());
857+
fillOptional1D(mCellAmplitude_tot, energy);
833858
if (goodCell) {
834-
fillOptional1D(mCellAmplitudeCalib_tot, cell.getEnergy()); // EMCAL+DCAL Calib, shifter
859+
fillOptional1D(mCellAmplitudeCalib_tot, energy); // EMCAL+DCAL Calib, shifter
835860
}
836-
if (cell.getEnergy() > mAmplitudeThresholdTime) {
861+
if (energy > mAmplitudeThresholdTime) {
837862
fillOptional1D(mCellTimeSupermodule_tot, cell.getTimeStamp()); // EMCAL+DCAL shifter
838863
if (goodCell) {
839864
fillOptional1D(mCellTimeSupermoduleCalib_tot, cell.getTimeStamp() - timecalib); // EMCAL+DCAL Calib shifter
@@ -842,23 +867,23 @@ void CellTask::CellHistograms::fillHistograms(const o2::emcal::Cell& cell, bool
842867
// check Gain
843868
int index = cell.getHighGain() ? 0 : 1; //(0=highGain, 1 = lowGain)
844869
if (supermoduleID < 12) { // EMCAL
845-
if (cell.getEnergy() > mAmplitudeThresholdTime) {
870+
if (energy > mAmplitudeThresholdTime) {
846871
fillOptional1D(mCellTimeSupermoduleEMCAL, cell.getTimeStamp());
847872
if (goodCell) {
848873
fillOptional1D(mCellTimeSupermoduleCalib_EMCAL, cell.getTimeStamp() - timecalib);
849874
}
850875
fillOptional1D(mCellTimeSupermoduleEMCAL_Gain[index], cell.getTimeStamp());
851876
}
852-
fillOptional1D(mCellAmplitudeEMCAL, cell.getEnergy());
877+
fillOptional1D(mCellAmplitudeEMCAL, energy);
853878
if (goodCell) {
854-
fillOptional1D(mCellAmplitudeCalib_EMCAL, cell.getEnergy());
879+
fillOptional1D(mCellAmplitudeCalib_EMCAL, energy);
855880
}
856881
} else {
857-
fillOptional1D(mCellAmplitudeDCAL, cell.getEnergy());
882+
fillOptional1D(mCellAmplitudeDCAL, energy);
858883
if (goodCell) {
859-
fillOptional1D(mCellAmplitudeCalib_DCAL, cell.getEnergy());
884+
fillOptional1D(mCellAmplitudeCalib_DCAL, energy);
860885
}
861-
if (cell.getEnergy() > mAmplitudeThresholdTime) {
886+
if (energy > mAmplitudeThresholdTime) {
862887
fillOptional1D(mCellTimeSupermoduleDCAL, cell.getTimeStamp());
863888
if (goodCell) {
864889
fillOptional1D(mCellTimeSupermoduleCalib_DCAL, cell.getTimeStamp() - timecalib);
@@ -867,7 +892,7 @@ void CellTask::CellHistograms::fillHistograms(const o2::emcal::Cell& cell, bool
867892
}
868893
}
869894
// bc phase histograms
870-
if (cell.getEnergy() > mAmplitudeThresholdTime) {
895+
if (energy > mAmplitudeThresholdTime) {
871896
auto bchistos = mCellTimeBC[bcphase];
872897
auto histcontainer = bchistos;
873898
histcontainer->Fill(cell.getTimeStamp());
@@ -919,6 +944,8 @@ void CellTask::CellHistograms::startPublishing(o2::quality_control::core::Object
919944
publishOptional(mCellOccupancyGood);
920945
publishOptional(mCellOccupancyBad);
921946
publishOptional(mIntegratedOccupancy);
947+
publishOptional(mAverageCellEnergy);
948+
publishOptional(mAverageCellTime);
922949
publishOptional(mnumberEvents);
923950

924951
for (auto histos : mCellTimeSupermoduleEMCAL_Gain) {
@@ -970,6 +997,8 @@ void CellTask::CellHistograms::reset()
970997
resetOptional(mCellOccupancyGood);
971998
resetOptional(mCellOccupancyBad);
972999
resetOptional(mIntegratedOccupancy);
1000+
resetOptional(mAverageCellEnergy);
1001+
resetOptional(mAverageCellTime);
9731002
resetOptional(mnumberEvents);
9741003

9751004
for (auto histos : mCellTimeSupermoduleEMCAL_Gain) {
@@ -1019,6 +1048,8 @@ void CellTask::CellHistograms::clean()
10191048
cleanOptional(mCellOccupancyGood);
10201049
cleanOptional(mCellOccupancyBad);
10211050
cleanOptional(mIntegratedOccupancy);
1051+
cleanOptional(mAverageCellEnergy);
1052+
cleanOptional(mAverageCellTime);
10221053
cleanOptional(mnumberEvents);
10231054

10241055
for (auto histos : mCellTimeSupermoduleEMCAL_Gain) {

0 commit comments

Comments
 (0)