Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EMCAL-788] EMCAL cell selection, on-the-fly calibration #11845

Merged
merged 1 commit into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions EventVisualisation/Workflow/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ if(ALIGPU_BUILD_TYPE STREQUAL "O2"
O2::TOFBase
O2::PHOSBase
O2::EMCALBase
O2::EMCALCalib
O2::EMCALWorkflow
O2::MIDBase
O2::TOFWorkflowIO
O2::TPCReconstruction
Expand Down Expand Up @@ -74,6 +76,7 @@ if(ALIGPU_BUILD_TYPE STREQUAL "O2"
O2::TOFBase
O2::PHOSBase
O2::EMCALBase
O2::EMCALCalib
O2::MIDBase
O2::TOFWorkflowIO
O2::TPCReconstruction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ class Geometry;
namespace o2::emcal
{
class Geometry;
}
class CellRecalibrator;
} // namespace o2::emcal

namespace o2::event_visualisation
{
Expand Down Expand Up @@ -207,6 +208,9 @@ class EveWorkflowHelper
const o2::globaltracking::RecoContainer* mRecoCont = nullptr;
const o2::globaltracking::RecoContainer* getRecoContainer() const { return mRecoCont; }
void setRecoContainer(const o2::globaltracking::RecoContainer* rc) { mRecoCont = rc; }
void setEMCALCellRecalibrator(o2::emcal::CellRecalibrator* calibrator) { mEMCALCalib = calibrator; }
void setMaxEMCALCellTime(float maxtime) { mEMCALMaxCellTime = maxtime; }
void setMinEMCALCellEnergy(float minenergy) { mEMCALMinCellEnergy = minenergy; }
TracksSet mTrackSet;
o2::event_visualisation::VisualisationEvent mEvent;
std::unordered_map<GID, std::size_t> mTotalDataTypes;
Expand All @@ -221,11 +225,14 @@ class EveWorkflowHelper
o2::its::GeometryTGeo* mITSGeom;
o2::phos::Geometry* mPHOSGeom;
o2::emcal::Geometry* mEMCALGeom;
o2::emcal::CellRecalibrator* mEMCALCalib = nullptr;

float mMUS2TPCTimeBins = 5.0098627;
float mITSROFrameLengthMUS = 0; ///< ITS RO frame in mus
float mMFTROFrameLengthMUS = 0; ///< MFT RO frame in mus
float mTPCBin2MUS = 0;
float mEMCALMaxCellTime = 100.; ///< EMCAL cell time cut (in ns)
float mEMCALMinCellEnergy = 0.3; ///< EMCAL cell energy cut (in GeV)
static int BCDiffErrCount;
const o2::vertexing::PVertexerParams* mPVParams = nullptr;
};
Expand Down
11 changes: 9 additions & 2 deletions EventVisualisation/Workflow/include/EveWorkflow/O2DPLDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include "ReconstructionDataFormats/GlobalTrackID.h"
#include "DataFormatsGlobalTracking/RecoContainer.h"
#include "DetectorsBase/GRPGeomHelper.h"
#include "EMCALCalib/CellRecalibrator.h"
#include "EMCALWorkflow/CalibLoader.h"
#include "EveWorkflow/DetectorData.h"
#include "Framework/Task.h"
#include <memory>
Expand Down Expand Up @@ -54,12 +56,13 @@ class O2DPLDisplaySpec : public o2::framework::Task
o2::dataformats::GlobalTrackID::mask_t clMask,
std::shared_ptr<o2::globaltracking::DataRequest> dataRequest,
std::shared_ptr<o2::base::GRPGeomRequest> gr,
std::shared_ptr<o2::emcal::CalibLoader> emcCalibLoader,
const std::string& jsonPath, const std::string& ext,
std::chrono::milliseconds timeInterval, int numberOfFiles, int numberOfTracks,
bool eveHostNameMatch, int minITSTracks, int minTracks, bool filterITSROF, bool filterTime,
const EveWorkflowHelper::Bracket& timeBracket, bool removeTPCEta,
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)
: 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)
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)
: 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)

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

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

} // namespace o2::event_visualisation
Expand Down
27 changes: 26 additions & 1 deletion EventVisualisation/Workflow/src/EveWorkflowHelper.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "ITSBase/GeometryTGeo.h"
#include "PHOSBase/Geometry.h"
#include "EMCALBase/Geometry.h"
#include "EMCALCalib/CellRecalibrator.h"
#include <TGeoBBox.h>
#include <tuple>
#include <gsl/span>
Expand Down Expand Up @@ -644,6 +645,30 @@ void EveWorkflowHelper::drawEMC(GID gid)
const gsl::span cellsForTrigger(cells.data() + trig.getFirstEntry(), trig.getNumberOfObjects());

for (const auto& cell : cellsForTrigger) {
if (!(cell.getType() == o2::emcal::ChannelType_t::HIGH_GAIN || cell.getType() == o2::emcal::ChannelType_t::LOW_GAIN)) {
// Select FEE cells (excluding LEDMON or TRU cells)
continue;
}
auto cellTime = cell.getTimeStamp();
auto cellEnergy = cell.getEnergy();
if (mEMCALCalib) {
// try to recalibrate cell in case calibration is available (bad channel removal, energy calibration, time calibration)
auto calibCell = mEMCALCalib->getCalibratedCell(cell);
if (!calibCell) {
// cell was rejected by bad channel calib
continue;
}
cellTime = calibCell->getTimeStamp();
cellEnergy = calibCell->getEnergy();
}
if (std::abs(cellTime) > mEMCALMaxCellTime) {
// cell rejected by time cut (pileup or noise)
continue;
}
if (cellEnergy < mEMCALMinCellEnergy) {
// cell rejected by energy cut (rejection of soft cells)
continue;
}
const auto id = cell.getTower();
// Point3D with x,y,z coordinates of cell with absId inside SM
const auto relPosCell = this->mEMCALGeom->RelPosCellInSModule(id);
Expand All @@ -657,7 +682,7 @@ void EveWorkflowHelper::drawEMC(GID gid)
TVector3 vPos(gPos.data());

auto vCalo = mEvent.addCalo({.time = static_cast<float>(time),
.energy = cell.getEnergy(),
.energy = cellEnergy,
.phi = (float)vPos.Phi(),
.eta = (float)vPos.Eta(),
.PID = 0,
Expand Down
43 changes: 42 additions & 1 deletion EventVisualisation/Workflow/src/O2DPLDisplay.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include "TOFBase/Geo.h"
#include "TPCFastTransform.h"
#include "TRDBase/Geometry.h"
#include "EMCALCalib/CellRecalibrator.h"
#include "EMCALWorkflow/CalibLoader.h"
#include "GlobalTrackingWorkflowHelpers/InputHelper.h"
#include "ReconstructionDataFormats/GlobalTrackID.h"
#include "ReconstructionDataFormats/PrimaryVertex.h"
Expand Down Expand Up @@ -76,6 +78,9 @@ void customize(std::vector<ConfigParamSpec>& workflowOptions)
{"primary-vertex-mode", VariantType::Bool, false, {"produce jsons with individual primary vertices, not total time frame data"}},
{"max-primary-vertices", VariantType::Int, 5, {"maximum number of primary vertices to draw per time frame"}},
{"primary-vertex-triggers", VariantType::Bool, false, {"instead of drawing vertices with tracks (and maybe calorimeter triggers), draw vertices with calorimeter triggers (and maybe tracks)"}},
{"no-calibrate-emcal", VariantType::Bool, false, {"Do not apply on-the-fly EMCAL calibration"}},
{"emcal-max-celltime", VariantType::Float, 100.f, {"Max. EMCAL cell time (in ns)"}},
{"emcal-min-cellenergy", VariantType::Float, 0.3f, {"Min. EMCAL cell energy (in GeV)"}},
{"primary-vertex-min-z", VariantType::Float, -o2::constants::math::VeryBig, {"minimum z position for primary vertex"}},
{"primary-vertex-max-z", VariantType::Float, o2::constants::math::VeryBig, {"maximum z position for primary vertex"}},
{"primary-vertex-min-x", VariantType::Float, -o2::constants::math::VeryBig, {"minimum x position for primary vertex"}},
Expand All @@ -93,6 +98,9 @@ void O2DPLDisplaySpec::init(InitContext& ic)
LOGF(info, "------------------------ O2DPLDisplay::init version ", o2_eve_version, " ------------------------------------");
mData.mConfig.configProcessing.runMC = mUseMC;
o2::base::GRPGeomHelper::instance().setRequest(mGGCCDBRequest);
if (mEMCALCalibLoader) {
mEMCALCalibrator = std::make_unique<o2::emcal::CellRecalibrator>();
}
}

void O2DPLDisplaySpec::run(ProcessingContext& pc)
Expand All @@ -114,6 +122,19 @@ void O2DPLDisplaySpec::run(ProcessingContext& pc)
o2::globaltracking::RecoContainer recoCont;
recoCont.collectData(pc, *mDataRequest);
updateTimeDependentParams(pc); // Make sure that this is called after the RecoContainer collect data, since some condition objects are fetched there
if (mEMCALCalibLoader) {
mEMCALCalibLoader->checkUpdates(pc);
if (mEMCALCalibLoader->hasUpdateBadChannelMap()) {
mEMCALCalibrator->setBadChannelMap(mEMCALCalibLoader->getBadChannelMap());
}
if (mEMCALCalibLoader->hasUpdateTimeCalib()) {
mEMCALCalibrator->setTimeCalibration(mEMCALCalibLoader->getTimeCalibration());
}
if (mEMCALCalibLoader->hasUpdateGainCalib()) {
mEMCALCalibrator->setGainCalibration(mEMCALCalibLoader->getGainCalibration());
}
}

EveWorkflowHelper::FilterSet enabledFilters;

enabledFilters.set(EveWorkflowHelper::Filter::ITSROF, this->mFilterITSROF);
Expand All @@ -122,6 +143,12 @@ void O2DPLDisplaySpec::run(ProcessingContext& pc)
enabledFilters.set(EveWorkflowHelper::Filter::TotalNTracks, this->mNumberOfTracks != -1);
EveWorkflowHelper helper(enabledFilters, this->mNumberOfTracks, this->mTimeBracket, this->mEtaBracket, this->mPrimaryVertexMode);
helper.setRecoContainer(&recoCont);
if (mEMCALCalibrator) {
helper.setEMCALCellRecalibrator(mEMCALCalibrator.get());
}
helper.setMaxEMCALCellTime(mEMCALMaxCellTime);
helper.setMinEMCALCellEnergy(mEMCALMinCellEnergy);

helper.setITSROFs();
helper.selectTracks(&(mData.mConfig.configCalib), mClMask, mTrkMask, mTrkMask);
helper.selectTowers();
Expand Down Expand Up @@ -240,6 +267,9 @@ void O2DPLDisplaySpec::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj)
if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) {
return;
}
if (mEMCALCalibLoader && mEMCALCalibLoader->finalizeCCDB(matcher, obj)) {
return;
}
if (matcher == ConcreteDataMatcher("ITS", "CLUSDICT", 0)) {
LOGF(info, "ITS cluster dictionary updated");
mData.setITSDict((const o2::itsmft::TopologyDictionary*)obj);
Expand Down Expand Up @@ -372,6 +402,8 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
auto primaryVertexMaxX = cfgc.options().get<float>("primary-vertex-max-x");
auto primaryVertexMinY = cfgc.options().get<float>("primary-vertex-min-y");
auto primaryVertexMaxY = cfgc.options().get<float>("primary-vertex-max-y");
auto maxEMCALCellTime = cfgc.options().get<float>("emcal-max-celltime");
auto minEMCALCellEnergy = cfgc.options().get<float>("emcal-min-cellenergy");

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

std::shared_ptr<o2::emcal::CalibLoader> emcalCalibLoader;
if (!cfgc.options().get<bool>("no-calibrate-emcal")) {
emcalCalibLoader = std::make_shared<o2::emcal::CalibLoader>();
emcalCalibLoader->enableTimeCalib(true);
emcalCalibLoader->enableBadChannelMap(true);
emcalCalibLoader->enableGainCalib(true);
emcalCalibLoader->defineInputSpecs(dataRequest->inputs);
}

specs.emplace_back(DataProcessorSpec{
"o2-eve-export",
dataRequest->inputs,
{},
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)}});
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)}});

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