Skip to content

Commit 94eca0d

Browse files
mfasDadavidrohr
authored andcommitted
[EMCAL-788] EMCAL cell selection, on-the-fly calibration
- Seletion of good EMCAL cells - Require FEE readout (HG and LG cells) - Time cut around trigger peak - Min. cell energy - On-the-fly recalibration - Optional - Only in synchronous workflow
1 parent 5153ad7 commit 94eca0d

File tree

5 files changed

+88
-5
lines changed

5 files changed

+88
-5
lines changed

EventVisualisation/Workflow/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ if(ALIGPU_BUILD_TYPE STREQUAL "O2"
4040
O2::TOFBase
4141
O2::PHOSBase
4242
O2::EMCALBase
43+
O2::EMCALCalib
44+
O2::EMCALWorkflow
4345
O2::MIDBase
4446
O2::TOFWorkflowIO
4547
O2::TPCReconstruction
@@ -74,6 +76,7 @@ if(ALIGPU_BUILD_TYPE STREQUAL "O2"
7476
O2::TOFBase
7577
O2::PHOSBase
7678
O2::EMCALBase
79+
O2::EMCALCalib
7780
O2::MIDBase
7881
O2::TOFWorkflowIO
7982
O2::TPCReconstruction

EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ class Geometry;
5555
namespace o2::emcal
5656
{
5757
class Geometry;
58-
}
58+
class CellRecalibrator;
59+
} // namespace o2::emcal
5960

6061
namespace o2::event_visualisation
6162
{
@@ -207,6 +208,9 @@ class EveWorkflowHelper
207208
const o2::globaltracking::RecoContainer* mRecoCont = nullptr;
208209
const o2::globaltracking::RecoContainer* getRecoContainer() const { return mRecoCont; }
209210
void setRecoContainer(const o2::globaltracking::RecoContainer* rc) { mRecoCont = rc; }
211+
void setEMCALCellRecalibrator(o2::emcal::CellRecalibrator* calibrator) { mEMCALCalib = calibrator; }
212+
void setMaxEMCALCellTime(float maxtime) { mEMCALMaxCellTime = maxtime; }
213+
void setMinEMCALCellEnergy(float minenergy) { mEMCALMinCellEnergy = minenergy; }
210214
TracksSet mTrackSet;
211215
o2::event_visualisation::VisualisationEvent mEvent;
212216
std::unordered_map<GID, std::size_t> mTotalDataTypes;
@@ -221,11 +225,14 @@ class EveWorkflowHelper
221225
o2::its::GeometryTGeo* mITSGeom;
222226
o2::phos::Geometry* mPHOSGeom;
223227
o2::emcal::Geometry* mEMCALGeom;
228+
o2::emcal::CellRecalibrator* mEMCALCalib = nullptr;
224229

225230
float mMUS2TPCTimeBins = 5.0098627;
226231
float mITSROFrameLengthMUS = 0; ///< ITS RO frame in mus
227232
float mMFTROFrameLengthMUS = 0; ///< MFT RO frame in mus
228233
float mTPCBin2MUS = 0;
234+
float mEMCALMaxCellTime = 100.; ///< EMCAL cell time cut (in ns)
235+
float mEMCALMinCellEnergy = 0.3; ///< EMCAL cell energy cut (in GeV)
229236
static int BCDiffErrCount;
230237
const o2::vertexing::PVertexerParams* mPVParams = nullptr;
231238
};

EventVisualisation/Workflow/include/EveWorkflow/O2DPLDisplay.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "ReconstructionDataFormats/GlobalTrackID.h"
2020
#include "DataFormatsGlobalTracking/RecoContainer.h"
2121
#include "DetectorsBase/GRPGeomHelper.h"
22+
#include "EMCALCalib/CellRecalibrator.h"
23+
#include "EMCALWorkflow/CalibLoader.h"
2224
#include "EveWorkflow/DetectorData.h"
2325
#include "Framework/Task.h"
2426
#include <memory>
@@ -54,12 +56,13 @@ class O2DPLDisplaySpec : public o2::framework::Task
5456
o2::dataformats::GlobalTrackID::mask_t clMask,
5557
std::shared_ptr<o2::globaltracking::DataRequest> dataRequest,
5658
std::shared_ptr<o2::base::GRPGeomRequest> gr,
59+
std::shared_ptr<o2::emcal::CalibLoader> emcCalibLoader,
5760
const std::string& jsonPath, const std::string& ext,
5861
std::chrono::milliseconds timeInterval, int numberOfFiles, int numberOfTracks,
5962
bool eveHostNameMatch, int minITSTracks, int minTracks, bool filterITSROF, bool filterTime,
6063
const EveWorkflowHelper::Bracket& timeBracket, bool removeTPCEta,
61-
const EveWorkflowHelper::Bracket& etaBracket, bool trackSorting, int onlyNthEvent, bool primaryVertex, int maxPrimaryVertices, bool primaryVertexTriggers, float primaryVertexMinZ, float primaryVertexMaxZ, float primaryVertexMinX, float primaryVertexMaxX, float primaryVertexMinY, float primaryVertexMaxY)
62-
: mDisableWrite(disableWrite), mUseMC(useMC), mTrkMask(trkMask), mClMask(clMask), mDataRequest(dataRequest), mGGCCDBRequest(gr), mJsonPath(jsonPath), mExt(ext), mTimeInterval(timeInterval), mNumberOfFiles(numberOfFiles), mNumberOfTracks(numberOfTracks), mEveHostNameMatch(eveHostNameMatch), mMinITSTracks(minITSTracks), mMinTracks(minTracks), mFilterITSROF(filterITSROF), mFilterTime(filterTime), mTimeBracket(timeBracket), mRemoveTPCEta(removeTPCEta), mEtaBracket(etaBracket), mTrackSorting(trackSorting), mOnlyNthEvent(onlyNthEvent), mPrimaryVertexMode(primaryVertex), mMaxPrimaryVertices(maxPrimaryVertices), mPrimaryVertexTriggers(primaryVertexTriggers), mPrimaryVertexMinZ(primaryVertexMinZ), mPrimaryVertexMaxZ(primaryVertexMaxZ), mPrimaryVertexMinX(primaryVertexMinX), mPrimaryVertexMaxX(primaryVertexMaxX), mPrimaryVertexMinY(primaryVertexMinY), mPrimaryVertexMaxY(primaryVertexMaxY), mRunType(o2::parameters::GRPECS::NONE)
64+
const EveWorkflowHelper::Bracket& etaBracket, bool trackSorting, int onlyNthEvent, bool primaryVertex, int maxPrimaryVertices, bool primaryVertexTriggers, float primaryVertexMinZ, float primaryVertexMaxZ, float primaryVertexMinX, float primaryVertexMaxX, float primaryVertexMinY, float primaryVertexMaxY, float maxEMCALCellTime, float minEMCALCellEnergy)
65+
: mDisableWrite(disableWrite), mUseMC(useMC), mTrkMask(trkMask), mClMask(clMask), mDataRequest(dataRequest), mGGCCDBRequest(gr), mEMCALCalibLoader(emcCalibLoader), mJsonPath(jsonPath), mExt(ext), mTimeInterval(timeInterval), mNumberOfFiles(numberOfFiles), mNumberOfTracks(numberOfTracks), mEveHostNameMatch(eveHostNameMatch), mMinITSTracks(minITSTracks), mMinTracks(minTracks), mFilterITSROF(filterITSROF), mFilterTime(filterTime), mTimeBracket(timeBracket), mRemoveTPCEta(removeTPCEta), mEtaBracket(etaBracket), mTrackSorting(trackSorting), mOnlyNthEvent(onlyNthEvent), mPrimaryVertexMode(primaryVertex), mMaxPrimaryVertices(maxPrimaryVertices), mPrimaryVertexTriggers(primaryVertexTriggers), mPrimaryVertexMinZ(primaryVertexMinZ), mPrimaryVertexMaxZ(primaryVertexMaxZ), mPrimaryVertexMinX(primaryVertexMinX), mPrimaryVertexMaxX(primaryVertexMaxX), mPrimaryVertexMinY(primaryVertexMinY), mPrimaryVertexMaxY(primaryVertexMaxY), mEMCALMaxCellTime(maxEMCALCellTime), mEMCALMinCellEnergy(minEMCALCellEnergy), mRunType(o2::parameters::GRPECS::NONE)
6366

6467
{
6568
this->mTimeStamp = std::chrono::high_resolution_clock::now() - timeInterval; // first run meets condition
@@ -99,6 +102,8 @@ class O2DPLDisplaySpec : public o2::framework::Task
99102
float mPrimaryVertexMaxX; // maximum x position of the primary vertex
100103
float mPrimaryVertexMinY; // minimum y position of the primary vertex
101104
float mPrimaryVertexMaxY; // maximum y position of the primary vertex
105+
float mEMCALMaxCellTime; // max abs EMCAL cell time (in ns)
106+
float mEMCALMinCellEnergy; // min EMCAL cell energy (in GeV)
102107
int mEventCounter = 0;
103108
std::chrono::time_point<std::chrono::high_resolution_clock> mTimeStamp;
104109

@@ -108,6 +113,8 @@ class O2DPLDisplaySpec : public o2::framework::Task
108113
o2::parameters::GRPECS::RunType mRunType;
109114
std::shared_ptr<o2::globaltracking::DataRequest> mDataRequest;
110115
std::shared_ptr<o2::base::GRPGeomRequest> mGGCCDBRequest;
116+
std::shared_ptr<o2::emcal::CalibLoader> mEMCALCalibLoader;
117+
std::unique_ptr<o2::emcal::CellRecalibrator> mEMCALCalibrator;
111118
};
112119

113120
} // namespace o2::event_visualisation

EventVisualisation/Workflow/src/EveWorkflowHelper.cxx

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "ITSBase/GeometryTGeo.h"
3636
#include "PHOSBase/Geometry.h"
3737
#include "EMCALBase/Geometry.h"
38+
#include "EMCALCalib/CellRecalibrator.h"
3839
#include <TGeoBBox.h>
3940
#include <tuple>
4041
#include <gsl/span>
@@ -644,6 +645,30 @@ void EveWorkflowHelper::drawEMC(GID gid)
644645
const gsl::span cellsForTrigger(cells.data() + trig.getFirstEntry(), trig.getNumberOfObjects());
645646

646647
for (const auto& cell : cellsForTrigger) {
648+
if (!(cell.getType() == o2::emcal::ChannelType_t::HIGH_GAIN || cell.getType() == o2::emcal::ChannelType_t::LOW_GAIN)) {
649+
// Select FEE cells (excluding LEDMON or TRU cells)
650+
continue;
651+
}
652+
auto cellTime = cell.getTimeStamp();
653+
auto cellEnergy = cell.getEnergy();
654+
if (mEMCALCalib) {
655+
// try to recalibrate cell in case calibration is available (bad channel removal, energy calibration, time calibration)
656+
auto calibCell = mEMCALCalib->getCalibratedCell(cell);
657+
if (!calibCell) {
658+
// cell was rejected by bad channel calib
659+
continue;
660+
}
661+
cellTime = calibCell->getTimeStamp();
662+
cellEnergy = calibCell->getEnergy();
663+
}
664+
if (std::abs(cellTime) > mEMCALMaxCellTime) {
665+
// cell rejected by time cut (pileup or noise)
666+
continue;
667+
}
668+
if (cellEnergy < mEMCALMinCellEnergy) {
669+
// cell rejected by energy cut (rejection of soft cells)
670+
continue;
671+
}
647672
const auto id = cell.getTower();
648673
// Point3D with x,y,z coordinates of cell with absId inside SM
649674
const auto relPosCell = this->mEMCALGeom->RelPosCellInSModule(id);
@@ -657,7 +682,7 @@ void EveWorkflowHelper::drawEMC(GID gid)
657682
TVector3 vPos(gPos.data());
658683

659684
auto vCalo = mEvent.addCalo({.time = static_cast<float>(time),
660-
.energy = cell.getEnergy(),
685+
.energy = cellEnergy,
661686
.phi = (float)vPos.Phi(),
662687
.eta = (float)vPos.Eta(),
663688
.PID = 0,

EventVisualisation/Workflow/src/O2DPLDisplay.cxx

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "TOFBase/Geo.h"
2727
#include "TPCFastTransform.h"
2828
#include "TRDBase/Geometry.h"
29+
#include "EMCALCalib/CellRecalibrator.h"
30+
#include "EMCALWorkflow/CalibLoader.h"
2931
#include "GlobalTrackingWorkflowHelpers/InputHelper.h"
3032
#include "ReconstructionDataFormats/GlobalTrackID.h"
3133
#include "ReconstructionDataFormats/PrimaryVertex.h"
@@ -76,6 +78,9 @@ void customize(std::vector<ConfigParamSpec>& workflowOptions)
7678
{"primary-vertex-mode", VariantType::Bool, false, {"produce jsons with individual primary vertices, not total time frame data"}},
7779
{"max-primary-vertices", VariantType::Int, 5, {"maximum number of primary vertices to draw per time frame"}},
7880
{"primary-vertex-triggers", VariantType::Bool, false, {"instead of drawing vertices with tracks (and maybe calorimeter triggers), draw vertices with calorimeter triggers (and maybe tracks)"}},
81+
{"no-calibrate-emcal", VariantType::Bool, false, {"Do not apply on-the-fly EMCAL calibration"}},
82+
{"emcal-max-celltime", VariantType::Float, 100.f, {"Max. EMCAL cell time (in ns)"}},
83+
{"emcal-min-cellenergy", VariantType::Float, 0.3f, {"Min. EMCAL cell energy (in GeV)"}},
7984
{"primary-vertex-min-z", VariantType::Float, -o2::constants::math::VeryBig, {"minimum z position for primary vertex"}},
8085
{"primary-vertex-max-z", VariantType::Float, o2::constants::math::VeryBig, {"maximum z position for primary vertex"}},
8186
{"primary-vertex-min-x", VariantType::Float, -o2::constants::math::VeryBig, {"minimum x position for primary vertex"}},
@@ -93,6 +98,9 @@ void O2DPLDisplaySpec::init(InitContext& ic)
9398
LOGF(info, "------------------------ O2DPLDisplay::init version ", o2_eve_version, " ------------------------------------");
9499
mData.mConfig.configProcessing.runMC = mUseMC;
95100
o2::base::GRPGeomHelper::instance().setRequest(mGGCCDBRequest);
101+
if (mEMCALCalibLoader) {
102+
mEMCALCalibrator = std::make_unique<o2::emcal::CellRecalibrator>();
103+
}
96104
}
97105

98106
void O2DPLDisplaySpec::run(ProcessingContext& pc)
@@ -114,6 +122,19 @@ void O2DPLDisplaySpec::run(ProcessingContext& pc)
114122
o2::globaltracking::RecoContainer recoCont;
115123
recoCont.collectData(pc, *mDataRequest);
116124
updateTimeDependentParams(pc); // Make sure that this is called after the RecoContainer collect data, since some condition objects are fetched there
125+
if (mEMCALCalibLoader) {
126+
mEMCALCalibLoader->checkUpdates(pc);
127+
if (mEMCALCalibLoader->hasUpdateBadChannelMap()) {
128+
mEMCALCalibrator->setBadChannelMap(mEMCALCalibLoader->getBadChannelMap());
129+
}
130+
if (mEMCALCalibLoader->hasUpdateTimeCalib()) {
131+
mEMCALCalibrator->setTimeCalibration(mEMCALCalibLoader->getTimeCalibration());
132+
}
133+
if (mEMCALCalibLoader->hasUpdateGainCalib()) {
134+
mEMCALCalibrator->setGainCalibration(mEMCALCalibLoader->getGainCalibration());
135+
}
136+
}
137+
117138
EveWorkflowHelper::FilterSet enabledFilters;
118139

119140
enabledFilters.set(EveWorkflowHelper::Filter::ITSROF, this->mFilterITSROF);
@@ -122,6 +143,12 @@ void O2DPLDisplaySpec::run(ProcessingContext& pc)
122143
enabledFilters.set(EveWorkflowHelper::Filter::TotalNTracks, this->mNumberOfTracks != -1);
123144
EveWorkflowHelper helper(enabledFilters, this->mNumberOfTracks, this->mTimeBracket, this->mEtaBracket, this->mPrimaryVertexMode);
124145
helper.setRecoContainer(&recoCont);
146+
if (mEMCALCalibrator) {
147+
helper.setEMCALCellRecalibrator(mEMCALCalibrator.get());
148+
}
149+
helper.setMaxEMCALCellTime(mEMCALMaxCellTime);
150+
helper.setMinEMCALCellEnergy(mEMCALMinCellEnergy);
151+
125152
helper.setITSROFs();
126153
helper.selectTracks(&(mData.mConfig.configCalib), mClMask, mTrkMask, mTrkMask);
127154
helper.selectTowers();
@@ -240,6 +267,9 @@ void O2DPLDisplaySpec::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj)
240267
if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) {
241268
return;
242269
}
270+
if (mEMCALCalibLoader && mEMCALCalibLoader->finalizeCCDB(matcher, obj)) {
271+
return;
272+
}
243273
if (matcher == ConcreteDataMatcher("ITS", "CLUSDICT", 0)) {
244274
LOGF(info, "ITS cluster dictionary updated");
245275
mData.setITSDict((const o2::itsmft::TopologyDictionary*)obj);
@@ -372,6 +402,8 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
372402
auto primaryVertexMaxX = cfgc.options().get<float>("primary-vertex-max-x");
373403
auto primaryVertexMinY = cfgc.options().get<float>("primary-vertex-min-y");
374404
auto primaryVertexMaxY = cfgc.options().get<float>("primary-vertex-max-y");
405+
auto maxEMCALCellTime = cfgc.options().get<float>("emcal-max-celltime");
406+
auto minEMCALCellEnergy = cfgc.options().get<float>("emcal-min-cellenergy");
375407

376408
if (numberOfTracks == -1) {
377409
tracksSorting = false; // do not sort if all tracks are allowed
@@ -385,11 +417,20 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
385417
dataRequest->inputs,
386418
true); // query only once all objects except mag.field
387419

420+
std::shared_ptr<o2::emcal::CalibLoader> emcalCalibLoader;
421+
if (!cfgc.options().get<bool>("no-calibrate-emcal")) {
422+
emcalCalibLoader = std::make_shared<o2::emcal::CalibLoader>();
423+
emcalCalibLoader->enableTimeCalib(true);
424+
emcalCalibLoader->enableBadChannelMap(true);
425+
emcalCalibLoader->enableGainCalib(true);
426+
emcalCalibLoader->defineInputSpecs(dataRequest->inputs);
427+
}
428+
388429
specs.emplace_back(DataProcessorSpec{
389430
"o2-eve-export",
390431
dataRequest->inputs,
391432
{},
392-
AlgorithmSpec{adaptFromTask<O2DPLDisplaySpec>(disableWrite, useMC, srcTrk, srcCl, dataRequest, ggRequest, jsonFolder, ext, timeInterval, numberOfFiles, numberOfTracks, eveHostNameMatch, minITSTracks, minTracks, filterITSROF, filterTime, timeBracket, removeTPCEta, etaBracket, tracksSorting, onlyNthEvent, primaryVertexMode, maxPrimaryVertices, primaryVertexTriggers, primaryVertexMinZ, primaryVertexMaxZ, primaryVertexMinX, primaryVertexMaxX, primaryVertexMinY, primaryVertexMaxY)}});
433+
AlgorithmSpec{adaptFromTask<O2DPLDisplaySpec>(disableWrite, useMC, srcTrk, srcCl, dataRequest, ggRequest, emcalCalibLoader, jsonFolder, ext, timeInterval, numberOfFiles, numberOfTracks, eveHostNameMatch, minITSTracks, minTracks, filterITSROF, filterTime, timeBracket, removeTPCEta, etaBracket, tracksSorting, onlyNthEvent, primaryVertexMode, maxPrimaryVertices, primaryVertexTriggers, primaryVertexMinZ, primaryVertexMaxZ, primaryVertexMinX, primaryVertexMaxX, primaryVertexMinY, primaryVertexMaxY, maxEMCALCellTime, minEMCALCellEnergy)}});
393434

394435
// configure dpl timer to inject correct firstTForbit: start from the 1st orbit of TF containing 1st sampled orbit
395436
o2::raw::HBFUtilsInitializer hbfIni(cfgc, specs);

0 commit comments

Comments
 (0)