18#ifndef O2_CALIBRATION_EMCALCHANNEL_CALIBRATOR_H
19#define O2_CALIBRATION_EMCALCHANNEL_CALIBRATOR_H
60 auto rnr = mSampler(mRandomGenerator);
61 return rnr < mSamplingFraction;
67 auto now = std::chrono::system_clock::now().time_since_epoch().count();
68 std::seed_seq randomseed{uint32_t(now & 0xffffffff), uint32_t(now >> 32)};
69 mRandomGenerator.seed(randomseed);
71 std::mt19937_64 mRandomGenerator;
72 std::uniform_real_distribution<float> mSampler{0, 1};
73 float mSamplingFraction = 1;
82 EMCALChannelCalibDevice(std::shared_ptr<o2::base::GRPGeomRequest> req,
bool params, std::string calibType,
bool rejCalibTrg,
bool rejL0Trig,
bool applyGainCalib) : mCCDBRequest(req), mLoadCalibParamsFromCCDB(
params), mCalibType(calibType), mRejectCalibTriggers(rejCalibTrg), mRejectL0Triggers(rejL0Trig), mApplyGainCalib(applyGainCalib) {}
88 mCalibExtractor = std::make_shared<o2::emcal::EMCALCalibExtractor>();
90 if (mCalibType.find(
"time") != std::string::npos) {
91 isBadChannelCalib =
false;
92 if (!mTimeCalibrator) {
93 mTimeCalibrator = std::make_unique<o2::emcal::EMCALChannelCalibrator<o2::emcal::EMCALTimeCalibData, o2::emcal::TimeCalibrationParams>>();
95 mTimeCalibrator->SetCalibExtractor(mCalibExtractor);
98 mTimeCalibrator->setSaveFileName(
"emc-time-calib.root");
100 isBadChannelCalib =
true;
101 if (!mBadChannelCalibrator) {
102 mBadChannelCalibrator = std::make_unique<o2::emcal::EMCALChannelCalibrator<o2::emcal::EMCALChannelData, o2::emcal::BadChannelMap>>();
104 mBadChannelCalibrator->SetCalibExtractor(mCalibExtractor);
107 mBadChannelCalibrator->setSaveFileName(
"emc-channel-calib.root");
117 LOG(info) <<
"EMCal CalibParams updated";
122 LOG(info) <<
"Configuring scale factors for bad channel map";
124 mScaleFactorsInitialized =
true;
128 if (mBadChannelCalibrator) {
129 LOG(info) <<
"Configuring gain calib factors for bad channel";
131 mGainCalibFactorsInitialized =
true;
134 if (mTimeCalibrator) {
135 LOG(info) <<
"Configuring gain calib factors for time calib";
137 mGainCalibFactorsInitialized =
true;
144 mSelectedClassMasks.clear();
146 std::string delimiter =
":";
148 std::vector<std::string> vSelMasks;
149 while ((
pos = strSelClassMasks.find(delimiter)) != std::string::npos) {
150 vSelMasks.push_back(strSelClassMasks.substr(0,
pos));
151 strSelClassMasks.erase(0,
pos + delimiter.length());
153 vSelMasks.push_back(strSelClassMasks);
157 for (
auto& cls : ctpconf->getCTPClasses()) {
158 LOG(
debug) <<
"CTP class: " << cls.name <<
"\t " << cls.classMask;
160 if (std::find(vSelMasks.begin(), vSelMasks.end(), cls.name) != vSelMasks.end()) {
161 mSelectedClassMasks.push_back(cls.classMask);
162 LOG(info) <<
"Setting selected class mask " << cls.name <<
" to bit " << cls.classMask;
172 timeMeas[0] = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
176 if (tinfo.globalRunNumberChanged) {
177 mRunStopRequested =
false;
179 if (mRunStopRequested) {
184 if (mTimeCalibrator) {
186 }
else if (mBadChannelCalibrator) {
190 if (mLoadCalibParamsFromCCDB) {
201 if (mRejectL0Triggers) {
205 if (!mIsConfigured) {
209 configureCalibrators(tsMS);
210 mIsConfigured =
true;
213 if (mApplyGainCalib && !mGainCalibFactorsInitialized) {
215 std::vector<o2::emcal::Cell> cellDummyData(0);
216 if (isBadChannelCalib) {
217 mBadChannelCalibrator->process(cellDummyData);
219 mTimeCalibrator->process(cellDummyData);
226 if (samplingFraction < 1) {
228 mDownsampler = std::make_unique<CalibInputDownsampler>();
230 mDownsampler->setSamplingFraction(samplingFraction);
233 using ctpDigitsType = std::decay_t<
decltype(pc.inputs().get<gsl::span<o2::ctp::CTPDigit>>(
getCTPDigitsBinding()))>;
234 std::optional<ctpDigitsType> ctpDigits;
235 if (mRejectL0Triggers) {
240 if (mTimeCalibrator) {
241 if (mTimeCalibrator->getSaveAtEOR())
242 mTimeCalibrator->setSaveAtEOR(
false);
243 }
else if (mBadChannelCalibrator) {
244 if (mBadChannelCalibrator->getSaveAtEOR())
245 mBadChannelCalibrator->setSaveAtEOR(
false);
249 uint64_t classMaskCTP = 0;
250 std::unordered_set<int64_t> numBCAccepted;
251 if (mRejectL0Triggers) {
252 for (
auto& ctpDigit : *ctpDigits) {
254 classMaskCTP = ctpDigit.CTPClassMask.to_ulong();
256 for (
const uint64_t& selectedClassMask : mSelectedClassMasks) {
257 if ((classMaskCTP & selectedClassMask) != 0) {
265 auto tfcounter = o2::header::get<o2::framework::DataProcessingHeader*>(pc.inputs().get(
getCellBinding()).header)->startTime;
270 LOG(
debug) <<
"[EMCALCalibrator - run] Received " << InputTriggerRecord.size() <<
" Trigger Records, running calibration ...";
272 LOG(
debug) <<
"Processing TF " << tfcounter <<
" with " <<
data.size() <<
" cells";
275 for (
const auto& trg : InputTriggerRecord) {
276 if (!trg.getNumberOfObjects()) {
280 if (mRejectCalibTriggers) {
283 LOG(
debug) <<
"skipping triggered events due to wrong trigger (no Physics trigger)";
289 if (mRejectL0Triggers) {
290 if (numBCAccepted.find(trg.getBCData().toLong()) == numBCAccepted.end()) {
291 LOG(
debug) <<
"correct trigger not found, rejecting event";
296 if (mDownsampler && !mDownsampler->acceptEvent()) {
299 gsl::span<const o2::emcal::Cell> eventData(
data.data() + trg.getFirstEntry(), trg.getNumberOfObjects());
303 LOG(
debug) <<
"fast calib not yet available!";
306 if (isBadChannelCalib) {
307 mBadChannelCalibrator->process(eventData);
309 mTimeCalibrator->process(eventData);
313 static bool firstCall =
true;
316 if (mTimeCalibrator) {
317 mTimeCalibrator->loadSavedSlot();
318 }
else if (mBadChannelCalibrator) {
319 mBadChannelCalibrator->loadSavedSlot();
323 if (pc.transitionState() == TransitionHandlingState::Requested) {
324 LOG(
debug) <<
"Run stop requested, finalizing";
325 mRunStopRequested =
true;
326 if (isBadChannelCalib) {
327 mBadChannelCalibrator->setSaveAtEOR(
true);
330 mTimeCalibrator->setSaveAtEOR(
true);
335 if (isBadChannelCalib) {
336 sendOutput<o2::emcal::BadChannelMap>(pc.outputs());
338 sendOutput<o2::emcal::TimeCalibrationParams>(pc.outputs());
341 timeMeas[1] = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
342 LOG(info) <<
"end of run function. Time: " << timeMeas[1] - timeMeas[0] <<
" [ns] for " << InputTriggerRecord.size() <<
" events";
348 if (mRunStopRequested) {
351 if (isBadChannelCalib) {
352 mBadChannelCalibrator->setSaveAtEOR(
true);
354 sendOutput<o2::emcal::BadChannelMap>(ec.outputs());
356 mTimeCalibrator->setSaveAtEOR(
true);
358 sendOutput<o2::emcal::TimeCalibrationParams>(ec.outputs());
360 mRunStopRequested =
true;
370 std::unique_ptr<o2::emcal::EMCALChannelCalibrator<o2::emcal::EMCALChannelData, o2::emcal::BadChannelMap>> mBadChannelCalibrator;
371 std::unique_ptr<o2::emcal::EMCALChannelCalibrator<o2::emcal::EMCALTimeCalibData, o2::emcal::TimeCalibrationParams>> mTimeCalibrator;
372 std::shared_ptr<o2::emcal::EMCALCalibExtractor> mCalibExtractor;
373 std::shared_ptr<o2::base::GRPGeomRequest> mCCDBRequest;
374 std::string mCalibType;
375 bool mIsConfigured =
false;
376 bool mScaleFactorsInitialized =
false;
377 bool isBadChannelCalib =
true;
378 bool mLoadCalibParamsFromCCDB =
true;
379 bool mRejectCalibTriggers =
true;
380 bool mRejectL0Triggers =
true;
381 bool mApplyGainCalib =
true;
382 bool mGainCalibFactorsInitialized =
false;
383 bool mRunStopRequested =
false;
384 std::array<double, 2> timeMeas;
385 std::vector<uint64_t> mSelectedClassMasks = {};
386 std::unique_ptr<CalibInputDownsampler> mDownsampler;
389 template <
typename DataOutput>
397 std::vector<DataOutput> payloadVec;
398 std::vector<o2::ccdb::CcdbObjectInfo> infoVec;
399 if constexpr (std::is_same<DataOutput, o2::emcal::TimeCalibrationParams>::value) {
400 payloadVec = mTimeCalibrator->getOutputVector();
401 infoVec = mTimeCalibrator->getInfoVector();
403 payloadVec = mBadChannelCalibrator->getOutputVector();
404 infoVec = mBadChannelCalibrator->getInfoVector();
407 assert(payloadVec.size() == infoVec.size());
408 for (uint32_t
i = 0;
i < payloadVec.size();
i++) {
409 auto&
w = infoVec[
i];
411 if constexpr (std::is_same<DataOutput, o2::emcal::TimeCalibrationParams>::value) {
412 LOG(info) <<
"Sending object " <<
w.getPath() <<
"/" <<
w.getFileName() <<
" of size " <<
image->size()
413 <<
" bytes, valid for " <<
w.getStartValidityTimestamp() <<
" : " <<
w.getEndValidityTimestamp();
417 LOG(info) <<
"Sending object " <<
w.getPath() <<
"/" <<
w.getFileName() <<
" of size " <<
image->size()
418 <<
" bytes, valid for " <<
w.getStartValidityTimestamp() <<
" : " <<
w.getEndValidityTimestamp();
423 if (payloadVec.size()) {
424 if constexpr (std::is_same<DataOutput, o2::emcal::TimeCalibrationParams>::value) {
425 mTimeCalibrator->initOutput();
427 mBadChannelCalibrator->initOutput();
433 void configureCalibrators(
long ts)
437 LOG(
debug) <<
"currFill " << currFill <<
" runtype " << runtype;
439 if (mTimeCalibrator) {
440 LOG(info) <<
"Configuring time calibrator";
444 mTimeCalibrator->setCheckIntervalInfiniteSlot(1e5);
447 mTimeCalibrator->setUpdateAtTheEndOfRunOnly();
449 mTimeCalibrator->setSaveFileName(
"emc-time-calib-" +
std::to_string(runtype) +
".root");
450 mTimeCalibrator->setFillNr(currFill);
451 mTimeCalibrator->setRunType(runtype);
454 if (mBadChannelCalibrator) {
455 LOG(info) <<
"Configuring bad channel calibrator";
459 mBadChannelCalibrator->setCheckIntervalInfiniteSlot(1e5);
462 mBadChannelCalibrator->setUpdateAtTheEndOfRunOnly();
465 mBadChannelCalibrator->setFillNr(currFill);
466 mBadChannelCalibrator->setRunType(runtype);
467 mBadChannelCalibrator->setSaveFileName(
"emc-channel-calib-" +
std::to_string(runtype) +
".root");
478DataProcessorSpec getEMCALChannelCalibDeviceSpec(
const std::string calibType,
const bool loadCalibParamsFromCCDB,
const bool rejectCalibTrigger,
const bool rejectL0Trigger,
const bool ctpcfgperrun,
const bool applyGainCalib)
485 std::vector<OutputSpec> outputs;
486 std::string processorName;
487 if (calibType.find(
"time") != std::string::npos) {
488 processorName =
"calib-emcalchannel-time";
492 processorName =
"calib-emcalchannel-badchannel";
497 std::vector<InputSpec> inputs;
499 inputs.emplace_back(device::getCellTriggerRecordBinding(),
o2::header::gDataOriginEMC,
"CELLSTRGR", 0, o2::framework::Lifetime::Timeframe);
502 if (loadCalibParamsFromCCDB) {
505 if (calibType.find(
"badchannel") != std::string::npos) {
508 if (applyGainCalib) {
513 if (rejectL0Trigger) {
514 inputs.emplace_back(device::getCTPConfigBinding(),
"CTP",
"CTPCONFIG", 0, Lifetime::Condition,
ccdbParamSpec(
"CTP/Config/Config", ctpcfgperrun));
515 inputs.emplace_back(device::getCTPDigitsBinding(),
"CTP",
"DIGITS", 0, Lifetime::Timeframe);
518 auto ccdbRequest = std::make_shared<o2::base::GRPGeomRequest>(
true,
530 AlgorithmSpec{adaptFromTask<device>(ccdbRequest, loadCalibParamsFromCCDB, calibType, rejectCalibTrigger, rejectL0Trigger, applyGainCalib)},
Definition of the 32 Central Trigger System (CTS) Trigger Types defined in https://twiki....
Utils and constants for calibration and related workflows.
definition of CTPDigit, CTPInputDigit
Helper for geometry and GRP related CCDB requests.
Definition of the Names Generator class.
void checkUpdates(o2::framework::ProcessingContext &pc)
bool finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
void init(o2::framework::InitContext &ic) final
static const char * getCellTriggerRecordBinding()
static const char * getCTPConfigBinding()
static const char * getGainCalibBinding()
void run(o2::framework::ProcessingContext &pc) final
void endOfStream(o2::framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
EMCALChannelCalibDevice(std::shared_ptr< o2::base::GRPGeomRequest > req, bool params, std::string calibType, bool rejCalibTrg, bool rejL0Trig, bool applyGainCalib)
static const char * getCellBinding()
static const char * getCTPDigitsBinding()
void finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj) final
static std::unique_ptr< std::vector< char > > createObjectImage(const T *obj, CcdbObjectInfo *info=nullptr)
static constexpr long HOUR
void printKeyValues(bool showProv=true, bool useLogger=false) const final
static const EMCALCalibParams & Instance()
Interface to calibration data from CCDB for EMCAL.
CCDB container for the gain calibration factors.
GLenum const GLfloat * params
GLubyte GLubyte GLubyte GLubyte w
constexpr o2::header::DataOrigin gDataOriginEMC
constexpr TFType INFINITE_TF
long getCurrentTimestamp()
returns the timestamp in long corresponding to "now"
Defining PrimaryVertex explicitly as messageable.
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string to_string(gsl::span< T, Size > span)
static void fillTFIDInfo(o2::framework::ProcessingContext &pc, o2::dataformats::TFIDInfo &ti)
static constexpr o2::header::DataOrigin gDataOriginCDBWrapper
static constexpr o2::header::DataOrigin gDataOriginCDBPayload
std::string selectedClassMasks
name of EMCal min. bias trigger that is used for calibration
float fractionEvents_bc
fraction of events used in bad channel calibration
bool setSavedSlotAllowed_EMC
if true, saving and loading of calibrations from last run and for next run is enabled
bool setSavedSlotAllowedSOR_EMC
if true, stored calibrations from last run can be loaded in the next run (if false,...
float fractionEvents_tc
fraction of events used in time calibration
bool useScaledHisto_bc
use the scaled histogram for the bad channel map
int bcShiftCTP
bc shift of CTP digits to align them with EMC bc in case they are misaligned
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"