From 6e9b57d692c1f3b8ea5213dc5aab06af13591d58 Mon Sep 17 00:00:00 2001 From: Francesco Noferini Date: Mon, 23 Feb 2026 14:12:04 +0100 Subject: [PATCH] add treatment of TOF DRM Errors --- .../TOF/include/DataFormatsTOF/Diagnostic.h | 7 ++ .../TOF/base/include/TOFBase/CalibTOFapi.h | 63 ++++++++-- Detectors/TOF/base/include/TOFBase/Digit.h | 24 ++-- Detectors/TOF/base/src/CalibTOFapi.cxx | 118 +++++++++++++++++- Detectors/TOF/prototyping/CMakeLists.txt | 15 +++ Detectors/TOF/prototyping/checkDRMobj_tof.C | 41 ++++++ Detectors/TOF/prototyping/makeDRMobj_tof.C | 39 ++++++ .../TOF/reconstruction/src/Clusterer.cxx | 2 +- .../include/TOFSimulation/Digitizer.h | 5 +- Detectors/TOF/simulation/src/Digitizer.cxx | 25 +++- .../src/SimpleDigitizerWorkflow.cxx | 5 +- .../src/TOFDigitizerSpec.cxx | 25 +++- .../DigitizerWorkflow/src/TOFDigitizerSpec.h | 2 +- 13 files changed, 343 insertions(+), 28 deletions(-) create mode 100644 Detectors/TOF/prototyping/checkDRMobj_tof.C create mode 100644 Detectors/TOF/prototyping/makeDRMobj_tof.C diff --git a/DataFormats/Detectors/TOF/include/DataFormatsTOF/Diagnostic.h b/DataFormats/Detectors/TOF/include/DataFormatsTOF/Diagnostic.h index 8adcdb63e9d21..028da04b3ef70 100644 --- a/DataFormats/Detectors/TOF/include/DataFormatsTOF/Diagnostic.h +++ b/DataFormats/Detectors/TOF/include/DataFormatsTOF/Diagnostic.h @@ -44,6 +44,13 @@ class Diagnostic uint32_t fillEmptyTOF(uint32_t frequency = 1) { return fill(1, frequency); } static ULong64_t getEmptyCrateKey(int crate); static ULong64_t getNoisyChannelKey(int channel); + static ULong64_t getDRMKey(int crate) { return 1000000 + crate * 1000; } + static ULong64_t getDRMerrorKey(int crate, int error) { return getDRMKey(crate) + error; } + uint32_t getFrequencyDRM(int crate) const { return getFrequency(getDRMKey(crate)); } + uint32_t getFrequencyDRMerror(int crate, int error) const { return getFrequency(getDRMerrorKey(crate, error)); } + uint32_t fillDRM(int crate, uint32_t frequency) { return fill(getDRMKey(crate), frequency); } + uint32_t fillDRMerror(int crate, int error, uint32_t frequency) { return fill(getDRMerrorKey(crate, error), frequency); } + static ULong64_t getTRMKey(int crate, int trm); void print(bool longFormat = false) const; void clear() { mVector.clear(); } diff --git a/Detectors/TOF/base/include/TOFBase/CalibTOFapi.h b/Detectors/TOF/base/include/TOFBase/CalibTOFapi.h index c3d39d3e978e1..29150e0ab1242 100644 --- a/Detectors/TOF/base/include/TOFBase/CalibTOFapi.h +++ b/Detectors/TOF/base/include/TOFBase/CalibTOFapi.h @@ -23,6 +23,9 @@ #include "TOFBase/Geo.h" #include "DataFormatsTOF/Diagnostic.h" #include "DataFormatsTOF/TOFFEElightInfo.h" +#include "DataFormatsTOF/CompressedDataFormat.h" + +class TH2F; namespace o2 { @@ -38,10 +41,12 @@ class CalibTOFapi using CcdbApi = o2::ccdb::CcdbApi; public: + static o2::tof::Diagnostic doDRMerrCalibFromQCHisto(const TH2F* histo, const char* file_output_name); + void resetDia(); CalibTOFapi() = default; CalibTOFapi(const std::string url); - CalibTOFapi(long timestamp, o2::dataformats::CalibLHCphaseTOF* phase, o2::dataformats::CalibTimeSlewingParamTOF* slew, Diagnostic* dia = nullptr) : mTimeStamp(timestamp), mLHCphase(phase), mSlewParam(slew), mDiaFreq(dia) {} + CalibTOFapi(long timestamp, o2::dataformats::CalibLHCphaseTOF* phase, o2::dataformats::CalibTimeSlewingParamTOF* slew, Diagnostic* dia = nullptr, Diagnostic* diaDRM = nullptr) : mTimeStamp(timestamp), mLHCphase(phase), mSlewParam(slew), mDiaFreq(dia), mDiaDRMFreq(diaDRM) {} ~CalibTOFapi() { if (mLHCphase) { @@ -53,6 +58,9 @@ class CalibTOFapi if (mDiaFreq) { // delete mDiaFreq; } + if (mDiaDRMFreq) { + // delete mDiaDRMFreq; + } } void setTimeStamp(long t) @@ -69,6 +77,8 @@ class CalibTOFapi void readTimeSlewingParamFromFile(const char* filename); void readDiagnosticFrequencies(); void loadDiagnosticFrequencies(); + void readDiagnosticDRMFrequencies(); + void loadDiagnosticDRMFrequencies(); void readActiveMap(); void loadActiveMap(TOFFEElightInfo* fee); void writeLHCphase(LhcPhase* phase, std::map metadataLHCphase, uint64_t minTimeSTamp, uint64_t maxTimeStamp); @@ -89,6 +99,8 @@ class CalibTOFapi void setLhcPhase(LhcPhase* obj) { mLHCphase = obj; } Diagnostic* getDiagnostic() { return mDiaFreq; } void setDiagnostic(Diagnostic* obj) { mDiaFreq = obj; } + Diagnostic* getDiagnosticDRM() { return mDiaDRMFreq; } + void setDiagnosticDRM(Diagnostic* obj) { mDiaDRMFreq = obj; } int getNoisyThreshold() const { return mNoisyThreshold; } void setNoisyThreshold(int val) { mNoisyThreshold = val; } @@ -102,12 +114,39 @@ class CalibTOFapi void processError(int crate, int trm, int mask); bool isChannelError(int channel) const; bool checkTRMPolicy(int mask) const; + void resetDRMErrors(); + void processErrorDRM(int crate, int mask); + bool isChannelDRMError(int channel) const; + bool checkDRMPolicy(int mask) const; + + void setDRMCriticalErrorMask(uint32_t val) { mDRMCriticalErrorMask = val; } + uint32_t getDRMCriticalErrorMask() const { return mDRMCriticalErrorMask; } + float getDRMprobError(int crate, int type) const { return mErrorInDRM[crate][type]; } + + // DRM error codes inherited by EDRMDiagnostic_t in CompressedDataFormat.h (shifted by 4 bits) + static const int DRM_ERRINDEX_SHIFT = 4; + enum DRMcodes { + DRM_HEADER_MISSING = o2::tof::diagnostic::DRM_HEADER_MISSING >> DRM_ERRINDEX_SHIFT, + DRM_TRAILER_MISSING = o2::tof::diagnostic::DRM_TRAILER_MISSING >> DRM_ERRINDEX_SHIFT, + DRM_FEEID_MISMATCH = o2::tof::diagnostic::DRM_FEEID_MISMATCH >> DRM_ERRINDEX_SHIFT, + DRM_ORBIT_MISMATCH = o2::tof::diagnostic::DRM_ORBIT_MISMATCH >> DRM_ERRINDEX_SHIFT, + DRM_CRC_MISMATCH = o2::tof::diagnostic::DRM_CRC_MISMATCH >> DRM_ERRINDEX_SHIFT, + DRM_ENAPARTMASK_DIFFER = o2::tof::diagnostic::DRM_ENAPARTMASK_DIFFER >> DRM_ERRINDEX_SHIFT, + DRM_CLOCKSTATUS_WRONG = o2::tof::diagnostic::DRM_CLOCKSTATUS_WRONG >> DRM_ERRINDEX_SHIFT, + DRM_FAULTSLOTMASK_NOTZERO = o2::tof::diagnostic::DRM_FAULTSLOTMASK_NOTZERO >> DRM_ERRINDEX_SHIFT, + DRM_READOUTTIMEOUT_NOTZERO = o2::tof::diagnostic::DRM_READOUTTIMEOUT_NOTZERO >> DRM_ERRINDEX_SHIFT, + DRM_EVENTWORDS_MISMATCH = o2::tof::diagnostic::DRM_EVENTWORDS_MISMATCH >> DRM_ERRINDEX_SHIFT, + DRM_DIAGNOSTIC_SPARE1 = o2::tof::diagnostic::DRM_DIAGNOSTIC_SPARE1 >> DRM_ERRINDEX_SHIFT, + DRM_DECODE_ERROR = o2::tof::diagnostic::DRM_DECODE_ERROR >> DRM_ERRINDEX_SHIFT, + N_DRM_ERRORS = 12 + }; private: - long mTimeStamp; ///< timeStamp for queries - LhcPhase* mLHCphase = nullptr; ///< object for LHC phase - SlewParam* mSlewParam = nullptr; ///< object for timeslewing (containing info also for offset and problematic) - Diagnostic* mDiaFreq = nullptr; ///< object for Diagnostic Frequency + long mTimeStamp; ///< timeStamp for queries + LhcPhase* mLHCphase = nullptr; ///< object for LHC phase + SlewParam* mSlewParam = nullptr; ///< object for timeslewing (containing info also for offset and problematic) + Diagnostic* mDiaFreq = nullptr; ///< object for Diagnostic Frequency + Diagnostic* mDiaDRMFreq = nullptr; ///< object for Diagnostic Frequency // info from diagnostic int mNoisyThreshold = 1; ///< threshold to be noisy @@ -116,13 +155,17 @@ class CalibTOFapi std::vector> mNoisy; ///< probTRMerror std::vector> mTRMerrorProb; ///< probTRMerror std::vector mTRMmask; ///< mask error for TRM + float mErrorInDRM[Geo::kNCrate][N_DRM_ERRORS] = {}; ///< probability of DRM error + uint32_t mDRMCriticalErrorMask = 0; ///< bit mask for critical DRM errors (e.g. Orbit Mismatch -> 1 << 7, see DataFormats/Detectors/TOF/include/DataFormatsTOF/CompressedDataFormat.h) - bool mIsErrorCh[Geo::NCHANNELS] = {}; ///< channels in error (TRM) - std::vector mFillErrChannel; ///< last error channels filled - bool mIsOffCh[Geo::NCHANNELS] = {}; ///< channels in error (TRM) - bool mIsNoisy[Geo::NCHANNELS] = {}; ///< noisy channels + bool mIsErrorCh[Geo::NCHANNELS] = {}; ///< channels in error (TRM) + std::vector mFillErrChannel; ///< last error channels filled + bool mIsOffCh[Geo::NCHANNELS] = {}; ///< channels in error (TRM) + bool mIsNoisy[Geo::NCHANNELS] = {}; ///< noisy channels + bool mIsErrorDRMCh[Geo::NCHANNELS] = {}; ///< channels in error (DRM) + std::vector mFillErrDRMChannel; ///< last error channels filled - ClassDefNV(CalibTOFapi, 1); + ClassDefNV(CalibTOFapi, 2); }; } // namespace tof } // namespace o2 diff --git a/Detectors/TOF/base/include/TOFBase/Digit.h b/Detectors/TOF/base/include/TOFBase/Digit.h index eef03ef84b97c..b48ad9514ad93 100644 --- a/Detectors/TOF/base/include/TOFBase/Digit.h +++ b/Detectors/TOF/base/include/TOFBase/Digit.h @@ -98,24 +98,32 @@ class Digit double getT0true() const { return mT0true; } void setT0true(double val) { mT0true = val; } + int8_t getErrorCode() const { return mErrorCode; } + void setErrorCode(int8_t err) { mErrorCode = err; } + void addDRMError() { mErrorCode |= 2; } + bool hasDRMError() const { return mErrorCode & 2; } + void addTRMError() { mErrorCode |= 1; } + bool hasTRMError() const { return mErrorCode & 1; } + private: friend class boost::serialization::access; - Int_t mChannel; ///< TOF channel index - uint16_t mTDC; ///< TDC bin number - uint16_t mTOT; ///< TOT bin number - InteractionRecord mIR{0, 0}; ///< InteractionRecord (orbit and bc) when digit occurs - Int_t mLabel; ///< Index of the corresponding entry in the MC label array - Double_t mCalibratedTime; //!< time of the digits after calibration (not persistent; it will be filled during clusterization) - Int_t mElectronIndex; //!/< index in electronic format + Int_t mChannel; ///< TOF channel index + uint16_t mTDC; ///< TDC bin number + uint16_t mTOT; ///< TOT bin number + InteractionRecord mIR{0, 0}; ///< InteractionRecord (orbit and bc) when digit occurs + Int_t mLabel; ///< Index of the corresponding entry in the MC label array + Double_t mCalibratedTime; //!< time of the digits after calibration (not persistent; it will be filled during clusterization) + Int_t mElectronIndex; //!/< index in electronic format uint32_t mTriggerOrbit = 0; //!< orbit id of trigger event // RS: orbit must be 32bits long uint16_t mTriggerBunch = 0; //!< bunch id of trigger event Bool_t mIsUsedInCluster; //!/< flag to declare that the digit was used to build a cluster Bool_t mIsProblematic = false; //!< flag to tell whether the channel of the digit was problemati; not persistent; default = ok float mTgeant = 0.0; ///< geant time in MC double mT0true = 0.0; ///< t0true + int8_t mErrorCode = 0; ///< if TRM o DRM error - ClassDefNV(Digit, 5); + ClassDefNV(Digit, 6); }; std::ostream& operator<<(std::ostream& stream, const Digit& dig); diff --git a/Detectors/TOF/base/src/CalibTOFapi.cxx b/Detectors/TOF/base/src/CalibTOFapi.cxx index 281498990a9dd..303439f473b33 100644 --- a/Detectors/TOF/base/src/CalibTOFapi.cxx +++ b/Detectors/TOF/base/src/CalibTOFapi.cxx @@ -11,11 +11,40 @@ #include "TOFBase/CalibTOFapi.h" #include // for LOG +#include using namespace o2::tof; ClassImp(o2::tof::CalibTOFapi); +o2::tof::Diagnostic CalibTOFapi::doDRMerrCalibFromQCHisto(const TH2F* histo, const char* file_output_name) +{ + // this is a method which translate the QC output in qc/TOF/MO/TaskRaw/DRMCounter (TH2F) into a Diagnotic object for DRM (patter(crate, error), frequency) + // note that, differently from TRM errors, DRM ones are not stored in CTF by design (since very rare, as expected). Such an info is available only at the level of raw sync QC + o2::tof::Diagnostic drmDia; + + for (int j = 1; j <= Geo::kNCrate; j++) { + drmDia.fillDRM(j - 1, histo->GetBinContent(1, j)); + for (int i = 2; i <= histo->GetXaxis()->GetNbins(); i++) { + if (histo->GetBinContent(1, j)) { + if (histo->GetBinContent(i, j) > 0) { + drmDia.fillDRMerror(j - 1, i - 1, histo->GetBinContent(i, j)); + } + } + } + } + + TFile* fo = new TFile(file_output_name, "RECREATE"); + fo->WriteObjectAny(&drmDia, drmDia.Class_Name(), "ccdb_object"); + fo->Close(); + LOG(info) << "DRM error ccdb object created in " << file_output_name << " with this content"; + drmDia.print(true); + + return drmDia; +} + +//______________________________________________________________________ + void CalibTOFapi::resetDia() { memset(mEmptyCrateProb, 0., Geo::kNCrate * 4); @@ -116,11 +145,23 @@ void CalibTOFapi::readDiagnosticFrequencies() { auto& mgr = CcdbManager::instance(); long timems = long(mTimeStamp) * 1000; - LOG(info) << "TOF get Diagnostics with timestamp (ms) = " << timems; + LOG(info) << "TOF get TRM Diagnostics with timestamp (ms) = " << timems; mDiaFreq = mgr.getForTimeStamp("TOF/Calib/Diagnostic", timems); loadDiagnosticFrequencies(); } + +//______________________________________________________________________ + +void CalibTOFapi::readDiagnosticDRMFrequencies() +{ + auto& mgr = CcdbManager::instance(); + long timems = long(mTimeStamp) * 1000; + LOG(info) << "TOF get DRM Diagnostics with timestamp (ms) = " << timems; + mDiaFreq = mgr.getForTimeStamp("TOF/Calib/TRMerrors", timems); + + loadDiagnosticDRMFrequencies(); +} //______________________________________________________________________ void CalibTOFapi::loadDiagnosticFrequencies() @@ -210,6 +251,34 @@ void CalibTOFapi::loadDiagnosticFrequencies() //______________________________________________________________________ +void CalibTOFapi::loadDiagnosticDRMFrequencies() +{ + mDiaDRMFreq->print(); + + for (int ic = 0; ic < Geo::kNCrate; ic++) { // loop over crates + float DRMcounters = mDiaDRMFreq->getFrequencyDRM(ic); + + if (DRMcounters < 1) { + for (int ie = 0; ie < N_DRM_ERRORS; ie++) { + mErrorInDRM[ic][ie] = 0.; + } + continue; + } + + for (int ie = 0; ie < N_DRM_ERRORS; ie++) { // loop over error types + int ie_shifted = ie + DRM_ERRINDEX_SHIFT; + + float frequency = mDiaDRMFreq->getFrequencyDRMerror(ic, ie_shifted) * 1. / DRMcounters; // error frequency + if (frequency > 1) { + frequency = 1.; + } + mErrorInDRM[ic][ie] = frequency; + } + } +} + +//______________________________________________________________________ + void CalibTOFapi::writeLHCphase(LhcPhase* phase, std::map metadataLHCphase, uint64_t minTimeStamp, uint64_t maxTimeStamp) { @@ -330,6 +399,17 @@ void CalibTOFapi::resetTRMErrors() //______________________________________________________________________ +void CalibTOFapi::resetDRMErrors() +{ + for (auto index : mFillErrDRMChannel) { + mIsErrorDRMCh[index] = false; + } + + mFillErrDRMChannel.clear(); +} + +//______________________________________________________________________ + void CalibTOFapi::processError(int crate, int trm, int mask) { if (checkTRMPolicy(mask)) { // check the policy of TRM -> true=good TRM @@ -348,6 +428,28 @@ void CalibTOFapi::processError(int crate, int trm, int mask) //______________________________________________________________________ +void CalibTOFapi::processErrorDRM(int crate, int mask) +{ + if (checkDRMPolicy(mask)) { + return; + } + + for (int trm = 3; trm < 13; trm++) { + int ech = (crate << 12) + ((trm - 3) << 8); + for (int i = ech; i < ech + 256; i++) { + int channel = Geo::getCHFromECH(i); + if (channel == -1 || mIsErrorDRMCh[channel] == true) { + continue; + } + + mIsErrorDRMCh[channel] = true; + mFillErrDRMChannel.push_back(channel); + } + } +} + +//______________________________________________________________________ + bool CalibTOFapi::checkTRMPolicy(int mask) const { return false; @@ -355,7 +457,21 @@ bool CalibTOFapi::checkTRMPolicy(int mask) const //______________________________________________________________________ +bool CalibTOFapi::checkDRMPolicy(int mask) const +{ + return false; +} + +//______________________________________________________________________ + bool CalibTOFapi::isChannelError(int channel) const { return mIsErrorCh[channel]; } + +//______________________________________________________________________ + +bool CalibTOFapi::isChannelDRMError(int channel) const +{ + return mIsErrorDRMCh[channel]; +} diff --git a/Detectors/TOF/prototyping/CMakeLists.txt b/Detectors/TOF/prototyping/CMakeLists.txt index 1ce2268f1358a..7dfc9f8cb7361 100644 --- a/Detectors/TOF/prototyping/CMakeLists.txt +++ b/Detectors/TOF/prototyping/CMakeLists.txt @@ -32,6 +32,16 @@ o2_add_test_root_macro(findLabels.C O2::TOFBase LABELS tof) +o2_add_test_root_macro(makeDRMobj_tof.C + PUBLIC_LINK_LIBRARIES O2::DataFormatsTOF + O2::TOFBase + LABELS tof) + +o2_add_test_root_macro(checkDRMobj_tof.C + PUBLIC_LINK_LIBRARIES O2::DataFormatsTOF + O2::TOFBase + LABELS tof) + o2_add_test_root_macro(findTOFclusterFromLabel.C PUBLIC_LINK_LIBRARIES O2::DataFormatsTOF O2::SimulationDataFormat @@ -59,3 +69,8 @@ o2_add_test_root_macro(macroEvTime.C PUBLIC_LINK_LIBRARIES O2::TOFBase O2::TOFReconstruction LABELS tof) + +install( + FILES makeDRMobj_tof.C + checkDRMobj_tof.C + DESTINATION share/macro/) diff --git a/Detectors/TOF/prototyping/checkDRMobj_tof.C b/Detectors/TOF/prototyping/checkDRMobj_tof.C new file mode 100644 index 0000000000000..9652a4fb9823e --- /dev/null +++ b/Detectors/TOF/prototyping/checkDRMobj_tof.C @@ -0,0 +1,41 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "TFile.h" +#include "TH2F.h" +#include "TOFBase/CalibTOFapi.h" +#endif + +void checkDRMobj_tof(const char* fname = "ccdb.root") +{ + TFile* f = new TFile(fname); + + TH2F* hErrors = new TH2F("hDRMerrors", ";error code; frequency", 30, 0, 30, 72, 0, 72); + + o2::tof::Diagnostic* drmDia = (o2::tof::Diagnostic*)f->Get("ccdb_object"); + + for (int j = 1; j <= 72; j++) { + uint32_t patternRDH = o2::tof::Diagnostic::getDRMKey(j - 1); + for (int i = 1; i <= hErrors->GetXaxis()->GetNbins(); i++) { + uint32_t pattern = o2::tof::Diagnostic::getDRMerrorKey(j - 1, i - 1); + if (drmDia->getFrequency(patternRDH)) { + hErrors->SetBinContent(i, j, drmDia->getFrequency(pattern) * 1. / drmDia->getFrequency(patternRDH)); + } + } + } + + TCanvas* c = new TCanvas(); + c->cd(1); + hErrors->Draw("colz"); + + drmDia->print(true); +} diff --git a/Detectors/TOF/prototyping/makeDRMobj_tof.C b/Detectors/TOF/prototyping/makeDRMobj_tof.C new file mode 100644 index 0000000000000..8fabaf3c49c77 --- /dev/null +++ b/Detectors/TOF/prototyping/makeDRMobj_tof.C @@ -0,0 +1,39 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "TFile.h" +#include "TH2F.h" +#include "TOFBase/CalibTOFapi.h" +#endif + +void makeDRMobj_tof(const char* inputfile = "TObject_1764607157510.root", bool dummy = false) +{ + if (dummy) { + o2::tof::Diagnostic drmDia; + for (int j = 1; j <= 72; j++) { + drmDia.fill(o2::tof::Diagnostic::getDRMKey(j - 1)); + } + + TFile* fo = new TFile("ccdb.root", "RECREATE"); + fo->WriteObjectAny(&drmDia, drmDia.Class_Name(), "ccdb_object"); + fo->Close(); + + return; + } + + TFile* f = new TFile(inputfile); + TH2F* h = (TH2F*)f->Get("ccdb_object"); + + o2::tof::Diagnostic drmDia; + + drmDia = o2::tof::CalibTOFapi::doDRMerrCalibFromQCHisto(h, "ccdb.root"); +} diff --git a/Detectors/TOF/reconstruction/src/Clusterer.cxx b/Detectors/TOF/reconstruction/src/Clusterer.cxx index 0b393bfd45e78..202e9432ba61f 100644 --- a/Detectors/TOF/reconstruction/src/Clusterer.cxx +++ b/Detectors/TOF/reconstruction/src/Clusterer.cxx @@ -55,7 +55,7 @@ void Clusterer::calibrateStrip() dig->setBC(dig->getBC() - mBCOffset); // RS Don't use raw BC, always start from the beginning of the TF double calib = mCalibApi->getTimeCalibration(dig->getChannel(), dig->getTOT() * Geo::TOTBIN_NS); //printf("channel %d) isProblematic = %d, fractionUnderPeak = %f\n",dig->getChannel(),mCalibApi->isProblematic(dig->getChannel()),mCalibApi->getFractionUnderPeak(dig->getChannel())); // toberem - bool isProbOrError = mAreCalibStored ? mCalibApi->isChannelError(dig->getChannel()) || mCalibApi->isNoisy(dig->getChannel()) : mCalibApi->isChannelError(dig->getChannel()) || mCalibApi->isNoisy(dig->getChannel()) || mCalibApi->isProblematic(dig->getChannel()); + bool isProbOrError = mAreCalibStored ? mCalibApi->isChannelError(dig->getChannel()) || dig->hasDRMError() || mCalibApi->isNoisy(dig->getChannel()) : dig->hasDRMError() || mCalibApi->isChannelError(dig->getChannel()) || mCalibApi->isNoisy(dig->getChannel()) || mCalibApi->isProblematic(dig->getChannel()); dig->setIsProblematic(isProbOrError); dig->setCalibratedTime(dig->getTDC() * Geo::TDCBIN + dig->getBC() * o2::constants::lhc::LHCBunchSpacingNS * 1E3 - Geo::LATENCYWINDOW * 1E3 - calib); //TODO: to be checked that "-" is correct, and we did not need "+" instead :-) //printf("calibration correction = %f\n",calib); // toberem diff --git a/Detectors/TOF/simulation/include/TOFSimulation/Digitizer.h b/Detectors/TOF/simulation/include/TOFSimulation/Digitizer.h index 5153f168f176f..4e369cecf6e26 100644 --- a/Detectors/TOF/simulation/include/TOFSimulation/Digitizer.h +++ b/Detectors/TOF/simulation/include/TOFSimulation/Digitizer.h @@ -148,7 +148,10 @@ class Digitizer : public WindowFiller float mTotLastHit[10]; Int_t mXLastShift[10]; Int_t mZLastShift[10]; - ClassDefNV(Digitizer, 1); + + float mIsCrateRDHerr[Geo::kNCrate]; + + ClassDefNV(Digitizer, 2); }; } // namespace tof } // namespace o2 diff --git a/Detectors/TOF/simulation/src/Digitizer.cxx b/Detectors/TOF/simulation/src/Digitizer.cxx index ec899bd35fbff..0076bf676bfe6 100644 --- a/Detectors/TOF/simulation/src/Digitizer.cxx +++ b/Detectors/TOF/simulation/src/Digitizer.cxx @@ -95,7 +95,7 @@ int Digitizer::process(const std::vector* hits, std::vector* dig const double max_hit_time = TOFSimParams::Instance().max_hit_time; // hits array of TOF hits for a given simulated event - // digits passed from external to be filled, in continuous readout mode we will push it on mDigitsPerTimeFrame vector of vectors of digits + // digits passed from external to be filled, in continuous readout mode we will push it on mDigitsPerTimeFrame, final vector of digits // printf("process event time = %f with %ld hits\n",mEventTime.getTimeNS(),hits->size()); @@ -891,6 +891,7 @@ void Digitizer::fillOutputContainer(std::vector& digits) // fill diagnostics mCalibApi->resetTRMErrors(); + mCalibApi->resetDRMErrors(); float p = gRandom->Rndm(); if (mCalibApi->getEmptyTOFProb() > p) { // check empty TOF for (int i = 0; i < Geo::kNCrate; i++) { @@ -906,6 +907,15 @@ void Digitizer::fillOutputContainer(std::vector& digits) info.setEmptyCrate(i); isEmptyCrate[i] = true; } else { // check if filling diagnostic (noisy will be masked in clusterization, then skip here) + // Fill DRM RDH errors + // ciao + for (int ie = 0; ie < mCalibApi->N_DRM_ERRORS; ie++) { + p = gRandom->Rndm(); + if (mCalibApi->getDRMprobError(i, ie) > p) { + mCalibApi->processErrorDRM(i, ie); + } + } + isEmptyCrate[i] = false; int slotreached = -1; const std::vector>& trmProg = mCalibApi->getTRMerrorProb(); @@ -969,6 +979,19 @@ void Digitizer::fillOutputContainer(std::vector& digits) } info.setNEntries(digits.size()); + // flag errors in digits + // for TRM: mCalibApi->isChannelError(ch) + // for DRM: + for (auto& d : digits) { + int ch = d.getChannel(); + if (mCalibApi->isChannelError(ch)) { // TRM error affecting this channel + d.addTRMError(); + } + if (mCalibApi->isChannelDRMError(ch)) { // DRM error affecting this channel + d.addDRMError(); + } + } + if (digits.size()) { mDigitsPerTimeFrame.insert(mDigitsPerTimeFrame.end(), digits.begin(), digits.end()); } diff --git a/Steer/DigitizerWorkflow/src/SimpleDigitizerWorkflow.cxx b/Steer/DigitizerWorkflow/src/SimpleDigitizerWorkflow.cxx index c45c746064101..6f956efe79304 100644 --- a/Steer/DigitizerWorkflow/src/SimpleDigitizerWorkflow.cxx +++ b/Steer/DigitizerWorkflow/src/SimpleDigitizerWorkflow.cxx @@ -53,6 +53,7 @@ // for TOF #include "TOFDigitizerSpec.h" #include "TOFWorkflowIO/TOFDigitWriterSpec.h" +#include "TOFBase/CalibTOFapi.h" // for FT0 #include "FT0DigitizerSpec.h" @@ -202,6 +203,7 @@ void customize(std::vector& workflowOptions) // option to use/not use CCDB for TOF workflowOptions.push_back(ConfigParamSpec{"use-ccdb-tof", o2::framework::VariantType::Bool, false, {"enable access to ccdb tof calibration objects"}}); workflowOptions.push_back(ConfigParamSpec{"ccdb-tof-sa", o2::framework::VariantType::Bool, false, {"enable access to ccdb tof calibration objects via CCDBManager (obsolete remap to use-ccdb-tof)"}}); + workflowOptions.push_back(ConfigParamSpec{"tof-drm-bitmask", o2::framework::VariantType::Int, (int)o2::tof::CalibTOFapi::DRM_ORBIT_MISMATCH, {"bit mask of DRM critical errors"}}); // option to use/not use CCDB for FT0 workflowOptions.push_back(ConfigParamSpec{"use-ccdb-ft0", o2::framework::VariantType::Bool, false, {"enable access to ccdb ft0 calibration objects"}}); @@ -677,10 +679,11 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) auto ccdb_url_tof = o2::base::NameConf::getCCDBServer(); auto timestamp = o2::raw::HBFUtils::Instance().startTime / 1000; detList.emplace_back(o2::detectors::DetID::TOF); + auto maskDRM = (uint32_t)configcontext.options().get("tof-drm-bitmask"); // connect the TOF digitization // printf("TOF Setting: use-ccdb = %d ---- ccdb url=%s ---- timestamp=%ld\n", useCCDB, ccdb_url_tof.c_str(), timestamp); - digitizerSpecs.emplace_back(o2::tof::getTOFDigitizerSpec(fanoutsize++, useCCDB, mctruth, ccdb_url_tof.c_str(), timestamp)); + digitizerSpecs.emplace_back(o2::tof::getTOFDigitizerSpec(fanoutsize++, useCCDB, mctruth, ccdb_url_tof.c_str(), timestamp, maskDRM)); // add TOF digit writer writerSpecs.emplace_back(o2::tof::getTOFDigitWriterSpec(mctruth)); } diff --git a/Steer/DigitizerWorkflow/src/TOFDigitizerSpec.cxx b/Steer/DigitizerWorkflow/src/TOFDigitizerSpec.cxx index e512659686c86..ba9ef5fd95986 100644 --- a/Steer/DigitizerWorkflow/src/TOFDigitizerSpec.cxx +++ b/Steer/DigitizerWorkflow/src/TOFDigitizerSpec.cxx @@ -48,7 +48,7 @@ namespace tof class TOFDPLDigitizerTask : public o2::base::BaseDPLDigitizer { public: - TOFDPLDigitizerTask(bool useCCDB, std::string ccdb_url, int timestamp) : mUseCCDB{useCCDB}, mCCDBurl(ccdb_url), mTimestamp(timestamp), o2::base::BaseDPLDigitizer(o2::base::InitServices::FIELD | o2::base::InitServices::GEOM), mPass(o2::conf::DigiParams::Instance().passName){}; + TOFDPLDigitizerTask(bool useCCDB, std::string ccdb_url, int timestamp, uint32_t mask) : mUseCCDB{useCCDB}, mCCDBurl(ccdb_url), mTimestamp(timestamp), o2::base::BaseDPLDigitizer(o2::base::InitServices::FIELD | o2::base::InitServices::GEOM), mPass(o2::conf::DigiParams::Instance().passName), mMaskDRM(mask) {}; void initDigitizerTask(framework::InitContext& ic) override { @@ -77,6 +77,10 @@ class TOFDPLDigitizerTask : public o2::base::BaseDPLDigitizer mUpdateCCDB = true; return; } + if (matcher == ConcreteDataMatcher("TOF", "DiagnosticDRM", 0)) { + mUpdateCCDB = true; + return; + } if (matcher == ConcreteDataMatcher("TOF", "LHCphaseCal", 0)) { mUpdateCCDB = true; return; @@ -127,6 +131,7 @@ class TOFDPLDigitizerTask : public o2::base::BaseDPLDigitizer const auto lhcPhaseIn = pc.inputs().get("tofccdbLHCphase"); const auto channelCalibIn = pc.inputs().get("tofccdbChannelCalib"); const auto diagnosticIn = pc.inputs().get("tofccdbDia"); + const auto diagnosticDRM = pc.inputs().get("tofccdbDrm"); const auto statusIn = pc.inputs().get("tofccdbStatus"); const auto tofParams = pc.inputs().get("tofccdbParams"); @@ -165,11 +170,15 @@ class TOFDPLDigitizerTask : public o2::base::BaseDPLDigitizer o2::dataformats::CalibLHCphaseTOF* lhcPhase = new o2::dataformats::CalibLHCphaseTOF(std::move(*lhcPhaseIn)); o2::dataformats::CalibTimeSlewingParamTOF* channelCalib = new o2::dataformats::CalibTimeSlewingParamTOF(std::move(*channelCalibIn)); o2::tof::Diagnostic* diagnostic = new o2::tof::Diagnostic(std::move(*diagnosticIn)); + o2::tof::Diagnostic* diagnosticDRMerr = new o2::tof::Diagnostic(std::move(*diagnosticDRM)); o2::tof::TOFFEElightInfo* status = new o2::tof::TOFFEElightInfo(std::move(*statusIn)); - mCalibApi = new o2::tof::CalibTOFapi(long(0), lhcPhase, channelCalib, diagnostic); + mCalibApi = new o2::tof::CalibTOFapi(long(0), lhcPhase, channelCalib, diagnostic, diagnosticDRMerr); + mCalibApi->setDRMCriticalErrorMask(mMaskDRM); mCalibApi->loadDiagnosticFrequencies(); + mCalibApi->loadDiagnosticDRMFrequencies(); mCalibApi->loadActiveMap(status); + mUpdateCCDB = false; } else { // update if necessary if (mUpdateCCDB) { @@ -178,10 +187,14 @@ class TOFDPLDigitizerTask : public o2::base::BaseDPLDigitizer o2::dataformats::CalibLHCphaseTOF* lhcPhase = new o2::dataformats::CalibLHCphaseTOF(*lhcPhaseIn); o2::dataformats::CalibTimeSlewingParamTOF* channelCalib = new o2::dataformats::CalibTimeSlewingParamTOF(*channelCalibIn); o2::tof::Diagnostic* diagnostic = new o2::tof::Diagnostic(std::move(*diagnosticIn)); + o2::tof::Diagnostic* diagnosticDRMerr = new o2::tof::Diagnostic(std::move(*diagnosticDRM)); o2::tof::TOFFEElightInfo* status = new o2::tof::TOFFEElightInfo(std::move(*statusIn)); mCalibApi = new o2::tof::CalibTOFapi(long(0), lhcPhase, channelCalib, diagnostic); + mCalibApi->setDRMCriticalErrorMask(mMaskDRM); mCalibApi->loadDiagnosticFrequencies(); + mCalibApi->loadDiagnosticDRMFrequencies(); mCalibApi->loadActiveMap(status); + mUpdateCCDB = false; } else { // do nothing @@ -201,10 +214,12 @@ class TOFDPLDigitizerTask : public o2::base::BaseDPLDigitizer channelCalibDummy->setFractionUnderPeak(sector, channelInSector, 1); } mCalibApi = new o2::tof::CalibTOFapi(long(mTimestamp), lhcPhaseDummy, channelCalibDummy); + mCalibApi->setDRMCriticalErrorMask(mMaskDRM); if (mUseCCDB) { mCalibApi->setURL(mCCDBurl); mCalibApi->readDiagnosticFrequencies(); + mCalibApi->readDiagnosticDRMFrequencies(); mCalibApi->readLHCphase(); mCalibApi->readActiveMap(); mCalibApi->readTimeSlewingParam(); @@ -300,9 +315,10 @@ class TOFDPLDigitizerTask : public o2::base::BaseDPLDigitizer bool mUpdateCCDB = false; o2::tof::CalibTOFapi* mCalibApi = nullptr; std::string mPass; + uint32_t mMaskDRM = 0; }; -DataProcessorSpec getTOFDigitizerSpec(int channel, bool useCCDB, bool mctruth, std::string ccdb_url, int timestamp) +DataProcessorSpec getTOFDigitizerSpec(int channel, bool useCCDB, bool mctruth, std::string ccdb_url, int timestamp, uint32_t maskDRM) { // create the full data processor spec using // a name identifier @@ -319,6 +335,7 @@ DataProcessorSpec getTOFDigitizerSpec(int channel, bool useCCDB, bool mctruth, s if (useCCDB) { inputs.emplace_back("tofccdbStatus", "TOF", "StatusTOF", 0, Lifetime::Condition, ccdbParamSpec("TOF/Calib/FEELIGHT")); inputs.emplace_back("tofccdbDia", "TOF", "DiagnosticCal", 0, Lifetime::Condition, ccdbParamSpec("TOF/Calib/Diagnostic")); + inputs.emplace_back("tofccdbDrm", "TOF", "DiagnosticDRM", 0, Lifetime::Condition, ccdbParamSpec("TOF/Calib/DRMerrors")); inputs.emplace_back("tofccdbLHCphase", "TOF", "LHCphaseCal", 0, Lifetime::Condition, ccdbParamSpec("TOF/Calib/LHCphase")); inputs.emplace_back("tofccdbChannelCalib", "TOF", "ChannelCalibCal", 0, Lifetime::Condition, ccdbParamSpec("TOF/Calib/ChannelCalib")); inputs.emplace_back("tofccdbParams", "TOF", "parameters", 0, Lifetime::Condition, ccdbParamSpec("TOF/Calib/Params")); @@ -337,7 +354,7 @@ DataProcessorSpec getTOFDigitizerSpec(int channel, bool useCCDB, bool mctruth, s "TOFDigitizer", inputs, outputs, - AlgorithmSpec{adaptFromTask(useCCDB, ccdb_url, timestamp)}, + AlgorithmSpec{adaptFromTask(useCCDB, ccdb_url, timestamp, maskDRM)}, Options{{"pileup", VariantType::Int, 1, {"whether to run in continuous time mode"}}} // I can't use VariantType::Bool as it seems to have a problem }; diff --git a/Steer/DigitizerWorkflow/src/TOFDigitizerSpec.h b/Steer/DigitizerWorkflow/src/TOFDigitizerSpec.h index f5841313c1cb0..7951b93eb1419 100644 --- a/Steer/DigitizerWorkflow/src/TOFDigitizerSpec.h +++ b/Steer/DigitizerWorkflow/src/TOFDigitizerSpec.h @@ -19,7 +19,7 @@ namespace o2 namespace tof { -o2::framework::DataProcessorSpec getTOFDigitizerSpec(int channel, bool useCCDB, bool mctruth, std::string ccdb_url, int timestamp); +o2::framework::DataProcessorSpec getTOFDigitizerSpec(int channel, bool useCCDB, bool mctruth, std::string ccdb_url, int timestamp, uint32_t maskDRM = 1 << 1); } // end namespace tof } // end namespace o2