From 384d150164dd462e45285daf4d685b55037f8fdc Mon Sep 17 00:00:00 2001 From: wiechula Date: Tue, 24 Sep 2024 11:18:43 +0200 Subject: [PATCH 0001/1992] Add option to rescale IT fraction for OROCs --- Detectors/TPC/calibration/macro/prepareITFiles.C | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Detectors/TPC/calibration/macro/prepareITFiles.C b/Detectors/TPC/calibration/macro/prepareITFiles.C index ff58d57583342..eac0355e0ddfd 100644 --- a/Detectors/TPC/calibration/macro/prepareITFiles.C +++ b/Detectors/TPC/calibration/macro/prepareITFiles.C @@ -31,7 +31,7 @@ using namespace o2::tpc::cru_calib_helpers; using namespace o2::tpc; -void prepareCMFiles(const std::string_view itDataFile, std::string outputDir = "./") +void prepareITFiles(const std::string_view itDataFile, std::string outputDir = "./", float orocFractionScale = 1.f) { const auto& mapper = Mapper::instance(); @@ -102,6 +102,10 @@ void prepareCMFiles(const std::string_view itDataFile, std::string outputDir = " float fractionVal = rocFraction.getValue(ipad); float expLambdaVal = rocExpLambda.getValue(ipad); + if (roc.isOROC()) { + fractionVal *= orocFractionScale; + } + if ((fractionVal <= 0) || (fractionVal > 0.6)) { LOGP(error, "Too fraction value in ROC {:2}, CRU {:3}, fec in CRU: {:2}, SAMPA: {}, channel: {:2}: {:.4f}, setting value to roc mean {}", iroc, cruID, fecInPartition, sampa, sampaChannel, fractionVal, meanFraction); fractionVal = meanFraction; From ce7ac94f696921ebec413c2f654e27cb1f20f3d1 Mon Sep 17 00:00:00 2001 From: wiechula Date: Fri, 6 Sep 2024 12:58:27 +0200 Subject: [PATCH 0002/1992] Common mode calculation --- Detectors/TPC/base/CMakeLists.txt | 2 + .../include/TPCBase/CommonModeCorrection.h | 246 ++++++++ .../TPC/base/src/CommonModeCorrection.cxx | 568 ++++++++++++++++++ Detectors/TPC/base/src/TPCBaseLinkDef.h | 3 + 4 files changed, 819 insertions(+) create mode 100644 Detectors/TPC/base/include/TPCBase/CommonModeCorrection.h create mode 100644 Detectors/TPC/base/src/CommonModeCorrection.cxx diff --git a/Detectors/TPC/base/CMakeLists.txt b/Detectors/TPC/base/CMakeLists.txt index c13fec6f03ab7..d4c1bc4602d54 100644 --- a/Detectors/TPC/base/CMakeLists.txt +++ b/Detectors/TPC/base/CMakeLists.txt @@ -38,6 +38,7 @@ o2_add_library(TPCBase src/IonTailSettings.cxx src/FEEConfig.cxx src/DeadChannelMapCreator.cxx + src/CommonModeCorrection.cxx PUBLIC_LINK_LIBRARIES Vc::Vc Boost::boost O2::DataFormatsTPC O2::DetectorsRaw O2::CCDB FairRoot::Base) @@ -70,6 +71,7 @@ o2_target_root_dictionary(TPCBase include/TPCBase/IonTailSettings.h include/TPCBase/FEEConfig.h include/TPCBase/DeadChannelMapCreator.h + include/TPCBase/CommonModeCorrection.h include/TPCBase/CDBTypes.h) o2_add_test(Base COMPONENT_NAME tpc diff --git a/Detectors/TPC/base/include/TPCBase/CommonModeCorrection.h b/Detectors/TPC/base/include/TPCBase/CommonModeCorrection.h new file mode 100644 index 0000000000000..a222327d2b434 --- /dev/null +++ b/Detectors/TPC/base/include/TPCBase/CommonModeCorrection.h @@ -0,0 +1,246 @@ +// 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. + +/// \file CommonModeCorrection.h +/// \brief Calculate the common mode correction factor +/// \author Jens Wiechula, Jens.Wiechula@ikf.uni-frankfurt.de + +#ifndef AliceO2_TPC_CommonModeCorrection_H_ +#define AliceO2_TPC_CommonModeCorrection_H_ + +#include +#include +#include + +#include "DataFormatsTPC/Digit.h" +#include "TPCBase/FEEConfig.h" + +namespace o2::tpc +{ + +/// Class to calculate the common mode correction +/// +/// Calculation of the common mode correction, based on the algorithm propsed by Marian Ivanov +/// The calculation is done for one single CRU and time bin +class CommonModeCorrection +{ + public: + struct CMdata { + std::vector adcValues; + std::vector cmKValues; + std::vector pedestals; + + void resize(size_t newSize) + { + adcValues.resize(newSize); + cmKValues.resize(newSize); + pedestals.resize(newSize); + } + + void clear() + { + adcValues.clear(); + cmKValues.clear(); + pedestals.clear(); + } + }; + + struct CMInfo { + float cmValue{}; ///< common mode value from pseudo code + float cmValueStd{}; ///< std dev of common mode values from pseudo code + float cmValueCRU{}; ///< common mode value from firmware, if available + float sumPos{}; ///< sum of positive signals > mSumPosThreshold + float sumNeg{}; ///< sum of negative signals <= mSumPosThreshold, corrected for k-factor + uint16_t nPadsUsed{}; ///< number of pads used for CM calculation + uint16_t nNeg{}; ///< number of pads used for sumNeg + uint16_t nOccupancy{}; ///< number of CM corrected pads larger than mOccupancyThreshold + uint16_t nSaturation{}; ///< number of pads in saturation + }; + + struct CMDebug { + std::vector nPadsOk{}; + std::vector adcDist{}; + }; + + using CalPadMapType = std::unordered_map; + + /// Calculation of the common mode value + /// + /// \param value pad-by-pad charge values + /// \param cmKValues corresponding pad-by-pad common mode k-factors + /// \param pedestals corresponding pad-by-pad pedestals + /// \param + CMInfo getCommonMode(gsl::span values, gsl::span cmKValues, gsl::span pedestals, CMDebug* cmDebug = nullptr) const; + CMInfo getCommonMode(const std::vector& values, const std::vector& cmKValues, const std::vector& pedestals) const { return getCommonMode(gsl::span(values), gsl::span(cmKValues), gsl::span(pedestals)); } + + CMInfo getCommonMode(const CMdata& cmData) const { return getCommonMode(std::span(cmData.adcValues), std::span(cmData.cmKValues), std::span(cmData.pedestals)); } + + void setNPadsCompRandom(int n) { mNPadsCompRamdom = n; } + int getNPadsCompRandom() const { return mNPadsCompRamdom; } + + void setNPadsCompMin(int n) { mNPadsCompMin = n; } + int getNPadsCompMin() const { return mNPadsCompMin; } + + /// Minimum number of pads required in the CM calculation to be used for digit correction + void setNPadsMinCM(int n) { mNPadsMinCM = n; } + int getNPadsMinCM() const { return mNPadsMinCM; } + + void setQEmpty(float q) { mQEmpty = q; } + float getQEmpty() const { return mQEmpty; } + + void setQComp(float q) { mQComp = q; } + float getQComp() const { return mQComp; } + + /// The mQComp will be set to (cm - mQCompScaleThreshold) * mQCompScale, if cm > mQCompScaleThreshold + void setQCompScaleThreshold(float q) { mQCompScaleThreshold = q; } + float getQCompScaleThreshold() const { return mQCompScaleThreshold; } + + /// The mQComp will be set to (cm - mQCompScaleThreshold) * mQCompScale, if cm > mQCompScaleThreshold + void setQCompScale(float q) { mQCompScale = q; } + float getQCompScale() const { return mQCompScale; } + + /// Threshold above which a signal is considered for sumPos, if debug information is used + void setSumPosThreshold(float threshold) { mSumPosThreshold = threshold; } + float getSumPosThreshold() const { return mSumPosThreshold; } + + /// Threshold above which a signal is considered for the occupancy + void setOccupancyThreshold(float threshold) { mOccupancyThreshold = threshold; } + float getOccupancyThreshold() const { return mOccupancyThreshold; } + + /// Pad maps loaded from FEEConfig + void setPadMaps(CalPadMapType& padMaps) { mPadMaps = padMaps; } + + /// load a CalPad from file and add it to the local mPadMaps + /// \param fileName input file name + /// \param nameInFile name of the CalPad object in the file + /// \param namePadMap name under which to store the object in the mPadMaps, if empty use the same as nameInFile + void loadCalPad(std::string_view fileName, std::string_view nameInFile, std::string_view namePadMap = ""); + + /// load CMkValues from file, assuming it is stored under the name "CMkValues + void loadCMkValues(std::string_view fileName) { loadCalPad(fileName, "CMkValues"); } + + /// load Pedestals from file, assuming it is stored under the name "Pedestals + void loadPedestals(std::string_view fileName) { loadCalPad(fileName, "Pedestals"); } + + /// Custom setting of CalPad, overwriting what was set in mPadMaps + void setCalPad(const CalPad& calPad, std::string_view name) { mPadMaps[name.data()] = calPad; } + + /// cmk value + float getCMkValue(int sector, int row, int pad) { return mPadMaps["CMkValues"].getValue(sector, row, pad); } + + /// pedestal value + float getPedestalValue(int sector, int row, int pad) { return mPadMaps["Pedestals"].getValue(sector, row, pad); } + + /// load the Pad maps from CCDB + void + loadDefaultPadMaps(FEEConfig::Tags feeTag = FEEConfig::Tags::Physics30sigma); + + CMdata collectCMdata(const std::vector& digits, int cru, int timeBin); + + int getCommonMode(std::vector& digits, std::vector>& cmValues, bool negativeOnly = false, bool hasInjectedCMValue = false, std::vector>* cmDebug = nullptr, int minTimeBin = -1, int maxTimeBin = -1) const; + + /// corret digits for common mode + /// \param cmValues will contain CM information for each CRU and time bin + /// \param negativeOnly only correct negative common mode signals + /// \return maximum + int correctDigits(std::vector& digits, std::vector>& cmValues, bool negativeOnly = false, bool hasInjectedCMValue = false, std::vector>* cmDebug = nullptr, int minTimeBin = -1, int maxTimeBin = -1) const; + + void correctDigits(std::string_view digiFileIn, Long64_t maxEntries = -1, std::string_view digitFileOut = "tpcdigit_cmcorr.root", std::string_view cmFileOut = "CommonModeValues.root", bool negativeOnly = false, int nThreads = 1, bool writeOnlyCM = false, bool writeDebug = false, bool hasInjectedCMValue = false, int minTimeBin = -1, int maxTimeBin = -1); + + void limitKFactorPrecision(bool limit = true) { mLimitKFactor = limit; } + void limitPedestalPrecision(bool limit = true) { mLimitPedestal = limit; } + + /// set the number of threads used for CM calculation + /// \param nThreads number of threads + static void setNThreads(const int nThreads) { sNThreads = nThreads; } + + /// \return returns the number of threads used for decoding + static int getNThreads() { return sNThreads; } + + /// add artificial common mode, only works when using the 'correctDigits' function + void addCommonMode(float cm) { mArtificialCM = cm; } + + void setCorrectOutputForPedestal(bool corret = true) { mCorrectOutputForPedestal = corret; } + bool getCorrectOutputForPedestal() const { return mCorrectOutputForPedestal; } + + /// Add zeros for pads without signal + void setAddSubthreshold(bool addSubthreshold) { mSubthreshold = addSubthreshold; } + bool getAddSubthreshold() const { return mSubthreshold; } + + static float decodeInjectedCMValue(float lower, float upper); + + private: + inline static int sNThreads{1}; ///< Number of parallel threads for the CM calculation + int mNPadsCompRamdom{10}; ///< Number of random pads to compare with to check if the present pad is empty + int mNPadsCompMin{7}; ///< Minimum number of neighbouring pads with q close to present pad to define this as empty + int mNPadsMinCM{0}; ///< Minimum number of pads required in the CM calculation to be used for digit correction + float mQEmpty{2}; ///< Threshold to enter check for empty pad + float mQComp{1}; ///< Threshold for comparison with random pads + float mQCompScaleThreshold{0}; ///< Charge threshold from which on to increase mQComp + float mQCompScale{0}; ///< Slope with which to increase mQComp if below mQCompScaleThreshold + float mSumPosThreshold{2}; ///< calculate sumPos > mSumPosThreshold, sumNeg M<= mSumPosThreshold + float mOccupancyThreshold{3}; ///< calculate number of pads > mQCompScaleThreshold after CM correction + bool mLimitKFactor{false}; ///< Limit the k-factor precision to 2I6F + bool mLimitPedestal{false}; ///< Limit the preestal precision to 10I2F + int mSubthreshold{0}; ///< Add data for pads without signal. 1 = add zeros; 2 = add random noise + float mArtificialCM{}; ///< artificial common mode signals + bool mCorrectOutputForPedestal{false}; ///< correct the writte out ADC for the pedestal value + + CalPadMapType mPadMaps; ///< Pad-by-pad CRU configuration values (Pedestal, Noise, ITF + CM parameters) + + struct pos { + int row; + int pad; + }; + + // positions of lower words per CRU in sector + const std::array mCMInjectIDLower{ + // row0 pad0 row1 pad1 + pos{0, 2}, + pos{20, 1}, + pos{32, 2}, + pos{51, 1}, + pos{63, 1}, + pos{84, 1}, + pos{97, 1}, + pos{116, 2}, + pos{127, 2}, + pos{142, 0}, + }; + + // positions of upper words per CRU in sector + const std::array mCMInjectIDUpper{ + // row0 pad0 row1 pad1 + pos{0, 3}, + pos{20, 3}, + pos{32, 3}, + pos{51, 3}, + pos{63, 2}, + pos{84, 4}, + pos{97, 2}, + pos{115, 5}, + pos{127, 3}, + pos{142, 4}, + }; + + /// Return the value stored in mPadMaps["calibName"] + /// \param calibName name of calibraion in mPadMaps + /// \param cru CRU number + /// \param pad Pad number within the CRU + float getCalPadValue(const std::string calibName, int icru, int pad) const; + + bool padMapExists(const std::string& calibName); + + ClassDefNV(CommonModeCorrection, 2); +}; + +} // namespace o2::tpc +#endif diff --git a/Detectors/TPC/base/src/CommonModeCorrection.cxx b/Detectors/TPC/base/src/CommonModeCorrection.cxx new file mode 100644 index 0000000000000..729fb408eb204 --- /dev/null +++ b/Detectors/TPC/base/src/CommonModeCorrection.cxx @@ -0,0 +1,568 @@ +// 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. + +/// \file CommonModeCorrection.cxx +/// \brief Calculate the common mode correction factor + +// #include +#include +#include +#include +#include "CCDB/CcdbApi.h" +#include "TPCBase/CommonModeCorrection.h" +#include "TPCBase/Mapper.h" +#include "TPCBase/Utils.h" +#include "TPCBase/CRUCalibHelpers.h" +#include "TChain.h" +#include "TROOT.h" +#include "TFile.h" +#include "MathUtils/RandomRing.h" +#include "CommonUtils/TreeStreamRedirector.h" + +using namespace o2::tpc; +using namespace o2::tpc::cru_calib_helpers; +CommonModeCorrection::CMInfo CommonModeCorrection::getCommonMode(gsl::span values, gsl::span cmKValues, gsl::span pedestals, CMDebug* cmDebug) const +{ + if (values.size() == 0) { + return CMInfo{}; + } + // sanity check + if (values.size() != cmKValues.size() || values.size() != pedestals.size()) { + LOGP(error, "vector sizes of input values, cmKValues and pedestals don't match: {}, {}, {}", values.size(), cmKValues.size(), pedestals.size()); + return CMInfo{}; + } + static math_utils::RandomRing random(math_utils::RandomRing<>::RandomType::Flat); + std::vector adcCM; //< ADC values used for common mode calculation + + CMInfo cmInfo; + if (cmDebug) { + cmDebug->nPadsOk.resize(mNPadsCompRamdom + 1); + cmDebug->adcDist.resize(10); + } + + for (size_t iPad = 0; iPad < values.size(); ++iPad) { + const float kCM = mLimitKFactor ? fixedSizeToFloat<6>(floatToFixedSize<8, 6>(cmKValues[iPad])) : cmKValues[iPad]; + const float pedestal = mLimitPedestal ? fixedSizeToFloat(floatToFixedSize(pedestals[iPad])) : pedestals[iPad]; + const float adcPadRaw = values[iPad]; + const float adcPad = adcPadRaw - pedestal; + const float adcPadNorm = (kCM > 0) ? adcPad / kCM : 0; + + if (adcPadRaw > 1023.7) { + ++cmInfo.nSaturation; + } + + if (adcPad > mQEmpty) { + continue; + } + + float qCompAdd = 0; + if ((mQCompScaleThreshold < 0) && (adcPadNorm < mQCompScaleThreshold)) { + qCompAdd = (mQCompScaleThreshold - adcPadNorm) * mQCompScale; + LOGP(info, "Setting qCompAdd to {} for {}", qCompAdd, adcPadNorm); + } + + int nPadsOK = 0; + + for (int iRnd = 0; iRnd < mNPadsCompRamdom; ++iRnd) { + int padRnd = 0; + do { + padRnd = int(random.getNextValue() * (values.size() - 1)); + } while (padRnd == iPad); + const float kCMRnd = mLimitKFactor ? fixedSizeToFloat<6>(floatToFixedSize<8, 6>(cmKValues[padRnd])) : cmKValues[padRnd]; + const float pedestalRnd = mLimitPedestal ? fixedSizeToFloat(floatToFixedSize(pedestals[padRnd])) : pedestals[padRnd]; + const float adcPadRnd = values[padRnd] - pedestalRnd; + const float adcPadRndNorm = (kCMRnd > 0) ? adcPadRnd / kCMRnd : 0; + const float adcDist = std::abs(adcPadNorm - adcPadRndNorm); + if (cmDebug) { + const size_t distPos = std::min(cmDebug->adcDist.size() - 1, size_t(adcDist / 0.5)); + ++cmDebug->adcDist[distPos]; + } + if (adcDist < mQComp) { + ++nPadsOK; + } + } + + if (cmDebug) { + ++cmDebug->nPadsOk[nPadsOK]; + } + + if (nPadsOK >= mNPadsCompMin) { + adcCM.emplace_back(adcPadNorm); + } + } + + const int entriesCM = int(adcCM.size()); + float commonMode = 0; // std::accumulate(adcCM.begin(), adcCM.end(), 0.f); + float commonModeStd = 0; + + if (entriesCM > 0) { + std::for_each(adcCM.begin(), adcCM.end(), [&commonMode, &commonModeStd](const auto val) { + commonMode += val; + commonModeStd += val * val; + }); + commonMode /= float(entriesCM); + commonModeStd = std::sqrt(std::abs(commonModeStd / entriesCM - commonMode * commonMode)); + } + cmInfo.cmValue = commonMode; + cmInfo.cmValueStd = commonModeStd; + cmInfo.nPadsUsed = entriesCM; + + for (size_t iPad = 0; iPad < values.size(); ++iPad) { + const float kCM = mLimitKFactor ? fixedSizeToFloat<6>(floatToFixedSize<8, 6>(cmKValues[iPad])) : cmKValues[iPad]; + const float pedestal = mLimitPedestal ? fixedSizeToFloat(floatToFixedSize(pedestals[iPad])) : pedestals[iPad]; + const float adcPadRaw = values[iPad]; + const float adcPad = adcPadRaw - pedestal; + const float adcPadNorm = (kCM > 0) ? adcPad / kCM : 0; + const float adcPadCorr = adcPad - kCM * commonMode; + + if (adcPadCorr > mSumPosThreshold) { + cmInfo.sumPos += adcPadCorr; + } else { + cmInfo.sumNeg += adcPadNorm; + ++cmInfo.nNeg; + } + + if (mOccupancyThreshold > 0) { + if (adcPadCorr > mOccupancyThreshold) { + ++cmInfo.nOccupancy; + } + } + } + + return cmInfo; +} + +void CommonModeCorrection::loadDefaultPadMaps(FEEConfig::Tags tag) +{ + o2::ccdb::CcdbApi cdbApi; + cdbApi.init("http://alice-ccdb.cern.ch"); + const auto feeConfig = cdbApi.retrieveFromTFileAny("TPC/Config/FEE", {}, long(tag)); + if (!feeConfig) { + LOGP(error, "Could not retrieve pad maps"); + return; + } + mPadMaps = feeConfig->padMaps; + delete feeConfig; +} + +CommonModeCorrection::CMdata CommonModeCorrection::collectCMdata(const std::vector& digits, int cru, int timeBin) +{ + + CMdata data; + if (!padMapExists("CMkValues") || padMapExists("Pedestals")) { + return data; + } + + for (const auto& digit : digits) { + if (digit.getTimeStamp() < timeBin) { + continue; + } + + if (digit.getTimeStamp() > timeBin) { + break; + } + + if (digit.getCRU() < cru) { + continue; + } + + if (digit.getCRU() > cru) { + break; + } + + const auto sector = CRU(digit.getCRU()).sector(); + data.adcValues.emplace_back(digit.getChargeFloat()); + data.cmKValues.emplace_back(mPadMaps["CMkValues"].getValue(sector, digit.getRow(), digit.getPad())); + data.pedestals.emplace_back(mPadMaps["Pedestals"].getValue(sector, digit.getRow(), digit.getPad())); + } + return data; +} + +int CommonModeCorrection::getCommonMode(std::vector& digits, std::vector>& cmValues, bool negativeOnly, bool hasInjectedCMValue, std::vector>* cmDebug, int minTimeBin, int maxTimeBin) const +{ + // calculation common mode values + int maxTimeBinProcessed = -1; + int lastCRU = -1; + int lastTimeBin = -1; + CMdata data; + const auto& cmkValues = mPadMaps.at("CMkValues"); + const auto& pedestals = mPadMaps.at("Pedestals"); + + bool doArtificialCM = std::abs(mArtificialCM) > 0; + + // for decoding of the injected common mode signals + float cmInjectedLower{}; + float cmInjectedUpper{}; + + for (size_t iDigit = 0; iDigit < digits.size(); ++iDigit) { + auto& digit = digits[iDigit]; + const auto timeBin = digit.getTimeStamp(); + if ((minTimeBin > -1) && (timeBin < minTimeBin)) { + continue; + } + if ((maxTimeBin > -1) && (timeBin > maxTimeBin)) { + continue; + } + if ((lastCRU > -1) && ((digit.getCRU() != lastCRU) || (digit.getTimeStamp() != lastTimeBin))) { + auto& cmValuesCRU = cmValues[lastCRU]; + if (cmValuesCRU.size() <= lastTimeBin) { + cmValuesCRU.resize(lastTimeBin + 500); + if (cmDebug) { + (*cmDebug)[lastCRU].resize(lastTimeBin + 500); + } + } + if (mSubthreshold > 0) { + const size_t nPadsCRU = Mapper::PADSPERREGION[lastCRU % 10]; + const auto dataSize = data.adcValues.size(); + if (dataSize < nPadsCRU) { + data.resize(nPadsCRU); + if (mSubthreshold == 2) { + for (size_t i = dataSize; i < nPadsCRU; ++i) { + data.adcValues[i] = gRandom->Gaus(); + } + } + } + } + cmValuesCRU[lastTimeBin] = getCommonMode(data.adcValues, data.cmKValues, data.pedestals, cmDebug ? &((*cmDebug)[lastCRU][lastTimeBin]) : nullptr); + if (hasInjectedCMValue) { + cmValuesCRU[lastTimeBin].cmValueCRU = decodeInjectedCMValue(cmInjectedLower, cmInjectedUpper); + } + // LOGP(info, "processing CRU {}, timeBin {}, CM = {}", lastCRU, lastTimeBin, cmValuesCRU[lastTimeBin].cmValue); + + data.clear(); + } + const auto sector = CRU(digit.getCRU()).sector(); + const auto cmkValue = cmkValues.getValue(sector, digit.getRow(), digit.getPad()); + const auto pedestal = pedestals.getValue(sector, digit.getRow(), digit.getPad()); + float charge = digit.getChargeFloat(); + if (doArtificialCM) { + charge = std::clamp(charge + mArtificialCM * cmkValue, 0.f, 1023.f); + } + lastCRU = digit.getCRU(); + lastTimeBin = timeBin; + maxTimeBinProcessed = std::max(lastTimeBin, maxTimeBinProcessed); + + bool isInjectedCMPad = false; + if (hasInjectedCMValue) { + const auto posLow = mCMInjectIDLower[lastCRU % 10]; + const auto posUpper = mCMInjectIDUpper[lastCRU % 10]; + const auto row = digit.getRow(); + const auto pad = digit.getPad(); + if (row == posLow.row) { + if (pad == posLow.pad) { + cmInjectedLower = digit.getChargeFloat(); + isInjectedCMPad = true; + // LOGP(info, "setting lower CM value cru {}, row {}, pad {}: {:012b}", digit.getCRU(), row, pad, floatToFixedSize(digit.getChargeFloat())); + } + } + if (row == posUpper.row) { + if (pad == posUpper.pad) { + cmInjectedUpper = digit.getChargeFloat(); + isInjectedCMPad = true; + // LOGP(info, "setting upper CM value cru {}, row {}, pad {}: {:012b}", digit.getCRU(), row, pad, floatToFixedSize(digit.getChargeFloat())); + if (cmInjectedUpper == 0) { + LOGP(info, "cm upper = 0 cru {}, row {}, pad {}", digit.getCRU(), row, pad); + } + } + } + } + + if (!isInjectedCMPad) { + data.adcValues.emplace_back(charge); + data.cmKValues.emplace_back(cmkValue); + data.pedestals.emplace_back(pedestal); + } + } + { + auto& cmValuesCRU = cmValues[lastCRU]; + if (cmValuesCRU.size() <= lastTimeBin) { + cmValuesCRU.resize(lastTimeBin + 500); + if (cmDebug) { + (*cmDebug)[lastCRU].resize(lastTimeBin + 500); + } + } + cmValuesCRU[lastTimeBin] = getCommonMode(data.adcValues, data.cmKValues, data.pedestals, cmDebug ? &((*cmDebug)[lastCRU][lastTimeBin]) : nullptr); + // LOGP(info, "processing CRU {}, timeBin {}, CM = {}", lastCRU, lastTimeBin, cmValuesCRU[lastTimeBin].cmValue); + + if (hasInjectedCMValue) { + cmValuesCRU[lastTimeBin].cmValueCRU = decodeInjectedCMValue(cmInjectedLower, cmInjectedUpper); + } + + data.clear(); + } + return maxTimeBinProcessed; +} + +int CommonModeCorrection::correctDigits(std::vector& digits, std::vector>& cmValues, bool negativeOnly, bool hasInjectedCMValue, std::vector>* cmDebug, int minTimeBin, int maxTimeBin) const +{ + const auto maxTimeBinProcessed = getCommonMode(digits, cmValues, negativeOnly, hasInjectedCMValue, cmDebug, minTimeBin, maxTimeBin); + const auto& cmkValues = mPadMaps.at("CMkValues"); + const auto& pedestals = mPadMaps.at("Pedestals"); + // ===| apply correction |==== + for (auto& digit : digits) { + const auto timeBin = digit.getTimeStamp(); + if ((minTimeBin > -1) && (timeBin < minTimeBin)) { + continue; + } + if ((maxTimeBin > -1) && (timeBin > maxTimeBin)) { + continue; + } + const auto sector = CRU(digit.getCRU()).sector(); + const auto cmKValue = cmkValues.getValue(sector, digit.getRow(), digit.getPad()); + // LOGP(info, "correcting value for CRU {}, time bin {}", digit.getCRU(), digit.getTimeStamp()); + const auto cmValue = cmValues[digit.getCRU()][digit.getTimeStamp()].cmValue; + const auto cmNPads = cmValues[digit.getCRU()][digit.getTimeStamp()].nPadsUsed; + if ((!negativeOnly || cmValue < 0) && (cmNPads > mNPadsMinCM)) { + digit.setCharge(digit.getCharge() - cmValue * cmKValue); + if (mCorrectOutputForPedestal) { + const auto sector = CRU(digit.getCRU()).sector(); + const auto pedestal = pedestals.getValue(sector, digit.getRow(), digit.getPad()); + digit.setCharge(digit.getChargeFloat() - pedestal); + } + } + } + + return maxTimeBinProcessed; +} + +void CommonModeCorrection::correctDigits(std::string_view digiFileIn, Long64_t maxEntries, std::string_view digitFileOut, std::string_view cmFileOut, bool negativeOnly, int nThreads, bool writeOnlyCM, bool writeDebug, bool hasInjectedCMValue, int minTimeBin, int maxTimeBin) +{ + ROOT::EnableThreadSafety(); + + TChain* tree = o2::tpc::utils::buildChain(fmt::format("ls {}", digiFileIn), "o2sim", "o2sim"); + Long64_t nEntries = tree->GetEntries(); + if (maxEntries > 0) { + nEntries = std::min(nEntries, maxEntries); + } + + if (mPadMaps.find("Pedestals") == mPadMaps.end()) { + LOGP(info, "Using empty pedestals"); + mPadMaps["Pedestals"] = CalPad("Pedestals"); + } + + std::unique_ptr fOut; + std::unique_ptr tOut; + if (!writeOnlyCM) { + fOut.reset(TFile::Open(digitFileOut.data(), "RECREATE")); + fOut->SetCompressionLevel(5); // zstd default level + fOut->SetCompressionAlgorithm(5); // zstd + tOut = std::make_unique("o2sim", "o2sim"); + } + + std::array*, 36> digitizedSignal; + std::array outBranches{}; + for (size_t iSec = 0; iSec < digitizedSignal.size(); ++iSec) { + digitizedSignal[iSec] = nullptr; + tree->SetBranchAddress(Form("TPCDigit_%zu", iSec), &digitizedSignal[iSec]); + if (tOut) { + outBranches[iSec] = tOut->Branch(Form("TPCDigit_%zu", iSec), &digitizedSignal[iSec]); + } + } + + o2::utils::TreeStreamRedirector pcstream(cmFileOut.data(), "recreate"); + pcstream.GetFile()->SetCompressionAlgorithm(5); + pcstream.GetFile()->SetCompressionLevel(5); + + for (Long64_t iTF = 0; iTF < nEntries; ++iTF) { + tree->GetEntry(iTF); + LOGP(info, "Processing entry {}/{}", iTF + 1, nEntries); + + std::vector> cmValues; // CRU * timeBin + std::vector> cmDebug; // CRU * timeBin + + cmValues.resize(CRU::MaxCRU); + if (writeDebug) { + cmDebug.resize(CRU::MaxCRU); + } + int maxTimeBinSeen = -1; + + auto worker = [&](int iTread) { + // for (size_t iSector = 0; iSector < 36; ++iSector) { + for (size_t iSector = iTread; iSector < 36; iSector += nThreads) { + LOGP(info, "Processing entry {}/{}, starting sector {}", iTF + 1, nEntries, iSector); + auto digits = digitizedSignal[iSector]; + int maxTimeBinSector = 0; + if (digits && (digits->size() > 0)) { + maxTimeBinSector = correctDigits(*digits, cmValues, negativeOnly, hasInjectedCMValue, writeDebug ? &cmDebug : nullptr, minTimeBin, maxTimeBin); + } + { + static std::mutex maxMutex; + std::lock_guard lock{maxMutex}; + maxTimeBinSeen = std::max(maxTimeBinSeen, maxTimeBinSector); + if (outBranches[iSector]) { + outBranches[iSector]->Fill(); + LOGP(info, "Filling branch for sector {}", iSector); + } + } + } + }; + + std::vector threads(nThreads); + + for (int i = 0; i < threads.size(); i++) { + threads[i] = std::thread(worker, i); + } + + // wait for the threads to finish + for (auto& th : threads) { + th.join(); + } + + size_t maxTimeCRU = 0; + for (int iCRU = 0; iCRU < cmValues.size(); ++iCRU) { + maxTimeCRU = std::max(maxTimeCRU, cmValues[iCRU].size()); + } + const int maxTBCRU = std::min(maxTimeBinSeen, int(maxTimeCRU)); + + for (int iTimeBin = 0; iTimeBin < maxTBCRU; ++iTimeBin) { + + std::vector cm(CRU::MaxCRU); + std::vector cmD(CRU::MaxCRU); + std::vector sumPosStack(36 * 4); + std::vector nPosStack(36 * 4); + std::vector nSaturationStack(36 * 4); + std::vector sumPosStackCRU(CRU::MaxCRU); + std::vector sumPosStackCRUCorr(CRU::MaxCRU); + std::vector nSaturationStackCRU(CRU::MaxCRU); + + for (int iCRU = 0; iCRU < cmValues.size(); ++iCRU) { + if (cmValues[iCRU].size() == 0) { + continue; + } + cm[iCRU] = cmValues[iCRU][iTimeBin]; + if (writeDebug) { + cmD[iCRU] = cmDebug[iCRU][iTimeBin]; + } + const CRU cru(iCRU); + const StackID stackID{cru.sector(), cru.gemStack()}; + const auto index = stackID.getIndex(); + sumPosStack[index] += cm[iCRU].sumPos; + nPosStack[index] += (Mapper::PADSPERREGION[cru.region()] - cm[iCRU].nNeg); + nSaturationStack[index] += cm[iCRU].nSaturation; + } + + for (int iCRU = 0; iCRU < cmValues.size(); ++iCRU) { + if (cmValues[iCRU].size() == 0) { + continue; + } + const CRU cru(iCRU); + const StackID stackID{cru.sector(), cru.gemStack()}; + const auto index = stackID.getIndex(); + sumPosStackCRU[iCRU] = sumPosStack[index]; + sumPosStackCRUCorr[iCRU] = sumPosStack[index] - nPosStack[index] * cm[iCRU].cmValue; + nSaturationStackCRU[iCRU] = nSaturationStack[index]; + } + + pcstream << "cm" + << "iTF=" << iTF + << "iTimeBin=" << iTimeBin + << "cmInfo=" << cm + << "sumPosStack=" << sumPosStackCRU + << "sumPosStackCorr=" << sumPosStackCRUCorr + << "nSaturationStack=" << nSaturationStackCRU; + + if (writeDebug) { + pcstream << "cm" + << "cmDebug=" << cmD; + } + + pcstream << "cm" + << "\n"; + } + + // if (tOut) { + // tOut->Fill(); + // } + } + + pcstream.Close(); + if (fOut && tOut) { + tOut->SetEntries(nEntries); + fOut->cd(); + tOut->Write(); + tOut.reset(); + fOut->Close(); + } +} + +float CommonModeCorrection::decodeInjectedCMValue(float lower, float upper) +{ + // CRU row0 pad0 row1 pad1 + // 0 0 2 0 3 + // 1 20 1 20 3 + // 2 32 2 32 3 + // 3 51 1 51 3 + // 4 62 1 62 2 + // 5 84 1 84 4 + // 6 97 1 97 2 + // 7 116 2 115 5 + // 8 127 2 127 3 + // 9 142 0 142 4 + // + // CM Value encoding: + // Kanal 0 : Bit 11 ... 8 = 0x8. Bit 7..0 CM-Werte Bits 7...0 + // Kanal 1 : Bit 11.. 9 = "100". Bit 8 = CM Positive, Bits 6..0 = CM-Wert Bits 14..8 + const int ilower = floatToFixedSize(lower); + const int iupper = floatToFixedSize(upper); + if (!(ilower & 0x800) || !(iupper & 0x800)) { + LOGP(error, "Not a CM word: lower: {:012b} upper: {:012b}", ilower, iupper); + return 0; + } + const int fixedSizeCM = ((iupper & 0x7F) << 8) + (ilower & 0xFF); + const float floatCM = fixedSizeToFloat<8>(fixedSizeCM); + + // bit 8 of upper word is the sign 1 = positive + return (iupper & 0x100) ? floatCM : -floatCM; +} + +float CommonModeCorrection::getCalPadValue(const std::string calibName, int icru, int pad) const +{ + if (mPadMaps.find(calibName) == mPadMaps.end()) { + LOGP(error, "{} not set, cannot be used", calibName); + return 0; + } + const auto& calPad = mPadMaps.at(calibName); + const CRU cru(icru); + const int roc = cru.roc(); + const int padOffset = (cru.isIROC()) ? Mapper::GLOBALPADOFFSET[cru.region()] : Mapper::GLOBALPADOFFSET[cru.region()] - Mapper::GLOBALPADOFFSET[4]; + + const auto& calArray = calPad.getCalArray(roc); + + return calArray.getValue(padOffset + pad); +} + +bool CommonModeCorrection::padMapExists(const std::string& calibName) +{ + if (mPadMaps.find(calibName) == mPadMaps.end()) { + LOGP(error, "{} not in mPadMaps", calibName); + return false; + } + return true; +} + +void CommonModeCorrection::loadCalPad(std::string_view fileName, std::string_view nameInFile, std::string_view namePadMap) +{ + if (fileName.size() == 0) { + return; + } + + auto pads = o2::tpc::utils::readCalPads(fileName, nameInFile); + if ((pads.size() == 0) || (pads.at(0) == nullptr)) { + LOGP(error, "Could not load object {} from file {}", nameInFile, fileName); + return; + } + + if (namePadMap.size() == 0) { + namePadMap = nameInFile; + } + + mPadMaps[namePadMap.data()] = *pads[0]; +} diff --git a/Detectors/TPC/base/src/TPCBaseLinkDef.h b/Detectors/TPC/base/src/TPCBaseLinkDef.h index 33b6cf2c03392..60924db3953e2 100644 --- a/Detectors/TPC/base/src/TPCBaseLinkDef.h +++ b/Detectors/TPC/base/src/TPCBaseLinkDef.h @@ -66,6 +66,9 @@ #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::tpc::IonTailSettings> + ; #pragma link C++ class o2::tpc::FEEConfig + ; #pragma link C++ class o2::tpc::CRUConfig + ; +#pragma link C++ class o2::tpc::CommonModeCorrection + ; +#pragma link C++ class std::vector < o2::tpc::CommonModeCorrection::CMInfo> + ; +#pragma link C++ class std::vector < o2::tpc::CommonModeCorrection::CMDebug> + ; #pragma link C++ namespace o2::tpc::utils; #pragma link C++ function o2::tpc::utils::tokenize(const std::string_view, const std::string_view); From b5dd61f47bbfdb4617b805079c54fa248b581748 Mon Sep 17 00:00:00 2001 From: wiechula Date: Fri, 1 Nov 2024 16:27:20 +0100 Subject: [PATCH 0003/1992] Allow setting maxZ2X via config params --- .../SpacePoints/SpacePointsCalibConfParam.h | 39 ++++++++++--------- .../include/SpacePoints/TrackResiduals.h | 1 - .../SpacePoints/src/TrackResiduals.cxx | 20 +++++----- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/Detectors/TPC/calibration/SpacePoints/include/SpacePoints/SpacePointsCalibConfParam.h b/Detectors/TPC/calibration/SpacePoints/include/SpacePoints/SpacePointsCalibConfParam.h index 2465cbf512d2b..9a4d7c1474287 100644 --- a/Detectors/TPC/calibration/SpacePoints/include/SpacePoints/SpacePointsCalibConfParam.h +++ b/Detectors/TPC/calibration/SpacePoints/include/SpacePoints/SpacePointsCalibConfParam.h @@ -29,35 +29,35 @@ struct SpacePointsCalibConfParam : public o2::conf::ConfigurableParamHelpermaxZ2X; mIsInitialized = true; + + if (doBinning) { + // initialize binning + initBinning(); + } + LOG(info) << "Initialization complete"; } @@ -182,10 +184,10 @@ void TrackResiduals::initBinning() } // // Z/X binning - mDZ2XI = mNZ2XBins / sMaxZ2X; + mDZ2XI = mNZ2XBins / mMaxZ2X; mDZ2X = 1.0f / mDZ2XI; // for uniform case only if (mUniformBins[VoxZ]) { - LOGF(info, "Z/X-binning is uniform with %i bins from 0 to %f", mNZ2XBins, sMaxZ2X); + LOGF(info, "Z/X-binning is uniform with %i bins from 0 to %f", mNZ2XBins, mMaxZ2X); for (int iz = 0; iz < mNZ2XBins; ++iz) { mZ2XBinsDH.push_back(.5f * mDZ2X); mZ2XBinsDI.push_back(mDZ2XI); @@ -265,7 +267,7 @@ int TrackResiduals::getRowID(float x) const bool TrackResiduals::findVoxelBin(int secID, float x, float y, float z, std::array& bvox) const { // Z/X bin - if (fabs(z / x) > sMaxZ2X) { + if (fabs(z / x) > mMaxZ2X) { return false; } int bz = getZ2XBinExact(secID < SECTORSPERSIDE ? z / x : -z / x); @@ -601,7 +603,7 @@ int TrackResiduals::validateVoxels(int iSec) resVox.flags |= Masked; } } // loop over Z - } // loop over Y/X + } // loop over Y/X mValidFracXBins[iSec][ix] = static_cast(cntValid) / (mNY2XBins * mNZ2XBins); LOGP(debug, "Sector {}: xBin {} has {} % of voxels valid. Total masked due to fit: {} ,and sigma: {}", iSec, ix, mValidFracXBins[iSec][ix] * 100., cntMaskedFit, cntMaskedSigma); From 62d9460d4c6e5ec1c2d2a7e05caaab2c27017108 Mon Sep 17 00:00:00 2001 From: wiechula Date: Fri, 8 Nov 2024 22:19:40 +0100 Subject: [PATCH 0004/1992] Add functions for specific pad selections * edge pads * stack boundary rows * cross region --- Detectors/TPC/base/include/TPCBase/Mapper.h | 19 ++++++++--- Detectors/TPC/base/src/Mapper.cxx | 36 +++++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/Detectors/TPC/base/include/TPCBase/Mapper.h b/Detectors/TPC/base/include/TPCBase/Mapper.h index cee3d76db85b2..f2ff425675df6 100644 --- a/Detectors/TPC/base/include/TPCBase/Mapper.h +++ b/Detectors/TPC/base/include/TPCBase/Mapper.h @@ -396,6 +396,14 @@ class Mapper bool isOutOfSector(GlobalPosition3D posEle, const Sector& sector, const float margin = 0.f) const; + static bool isEdgePad(int rowInSector, int padInRow); + static bool isFirstOrLastRowInStack(int rowInSector); + static bool isBelowSpacerCross(int rowInSector, int padInRow); + static bool isHighCouplingPad(int rowInSector, int padInRow) + { + return isEdgePad(rowInSector, padInRow) || isFirstOrLastRowInStack(rowInSector) || isBelowSpacerCross(rowInSector, padInRow); + } + static constexpr unsigned short getNumberOfIROCs() { return 36; } static constexpr unsigned short getNumberOfOROCs() { return 36; } static constexpr unsigned short getPadsInIROC() { return mPadsInIROC; } @@ -523,6 +531,7 @@ class Mapper static constexpr unsigned int GLOBALPADOFFSET[NREGIONS]{0, 1200, 2400, 3840, 5280, 6720, 8160, 9760, 11360, 12960}; ///< offset of number of pads for region static constexpr unsigned int ROWSPERREGION[NREGIONS]{17, 15, 16, 15, 18, 16, 16, 14, 13, 12}; ///< number of pad rows for region static constexpr unsigned int ROWOFFSET[NREGIONS]{0, 17, 32, 48, 63, 81, 97, 113, 127, 140}; ///< offset to calculate local row from global row + static constexpr unsigned int ROWOFFSETSTACK[4]{0, 63, 97, 127}; ///< offset to calculate local row from global row static constexpr float REGIONAREA[NREGIONS]{374.4f, 378.f, 453.6f, 470.88f, 864.f, 864.f, 1167.36f, 1128.96f, 1449.6f, 1456.8f}; ///< volume of each region in cm^2 static constexpr float INVPADAREA[NREGIONS]{1 / 0.312f, 1 / 0.315f, 1 / 0.315f, 1 / 0.327f, 1 / 0.6f, 1 / 0.6f, 1 / 0.7296f, 1 / 0.7056f, 1 / 0.906f, 1 / 0.9105f}; ///< inverse size of the pad area padwidth*padLength static constexpr unsigned REGION[PADROWS] = { @@ -542,7 +551,7 @@ class Mapper {0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4}, // region 7 {0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5}, // region 8 {0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5} // region 9 - }; ///< additional pads per row compared to first row + }; ///< additional pads per row compared to first row const inline static std::vector OFFSETCRULOCAL[NREGIONS]{ {0, 66, 132, 198, 266, 334, 402, 472, 542, 612, 684, 756, 828, 902, 976, 1050, 1124}, // region 0 {0, 76, 152, 228, 306, 384, 462, 542, 622, 702, 784, 866, 948, 1032, 1116}, // region 1 @@ -554,7 +563,7 @@ class Mapper {0, 110, 220, 332, 444, 556, 670, 784, 898, 1014, 1130, 1246, 1364, 1482}, // region 7 {0, 118, 236, 356, 476, 598, 720, 844, 968, 1092, 1218, 1344, 1472}, // region 8 {0, 128, 258, 388, 520, 652, 784, 918, 1052, 1188, 1324, 1462} // region 9 - }; ///< row offset in cru for given local pad row + }; ///< row offset in cru for given local pad row const inline static std::vector PADSPERROW[NREGIONS]{ {66, 66, 66, 68, 68, 68, 70, 70, 70, 72, 72, 72, 74, 74, 74, 74, 76}, // region 0 {76, 76, 76, 78, 78, 78, 80, 80, 80, 82, 82, 82, 84, 84, 84}, // region 1 @@ -566,7 +575,7 @@ class Mapper {110, 110, 112, 112, 112, 114, 114, 114, 116, 116, 116, 118, 118, 118}, // region 7 {118, 118, 120, 120, 122, 122, 124, 124, 124, 126, 126, 128, 128}, // region 8 {128, 130, 130, 132, 132, 132, 134, 134, 136, 136, 138, 138} // region 9 - }; ///< number of pads per row in region + }; ///< number of pads per row in region static constexpr unsigned int OFFSETCRUGLOBAL[PADROWS]{ 0, 66, 132, 198, 266, 334, 402, 472, 542, 612, 684, 756, 828, 902, 976, 1050, 1124, // region 0 0, 76, 152, 228, 306, 384, 462, 542, 622, 702, 784, 866, 948, 1032, 1116, // region 1 @@ -578,7 +587,7 @@ class Mapper 0, 110, 220, 332, 444, 556, 670, 784, 898, 1014, 1130, 1246, 1364, 1482, // region 7 0, 118, 236, 356, 476, 598, 720, 844, 968, 1092, 1218, 1344, 1472, // region 8 0, 128, 258, 388, 520, 652, 784, 918, 1052, 1188, 1324, 1462 // region 9 - }; ///< row offset in cru for given global pad row + }; ///< row offset in cru for given global pad row static constexpr unsigned int LinksPerRegionPerEndpoint[NREGIONS][NENDPOINTS]{ {8, 7}, // region 0 @@ -591,7 +600,7 @@ class Mapper {10, 10}, // region 7 {10, 10}, // region 8 {10, 10}, // region 9 - }; ///< number of links per region per end point + }; ///< number of links per region per end point private: Mapper(const std::string& mappingDir); diff --git a/Detectors/TPC/base/src/Mapper.cxx b/Detectors/TPC/base/src/Mapper.cxx index 56ce283178da0..2796d488f014d 100644 --- a/Detectors/TPC/base/src/Mapper.cxx +++ b/Detectors/TPC/base/src/Mapper.cxx @@ -298,5 +298,41 @@ void Mapper::setTraceLengths(std::string_view inputFile, std::vector& len } } +bool Mapper::isEdgePad(int rowInSector, int padInRow) +{ + const auto& mapper = instance(); + return (padInRow == 0) || (padInRow == mapper.getNumberOfPadsInRowSector(rowInSector) - 1); +} + +bool Mapper::isFirstOrLastRowInStack(int rowInSector) +{ + if (rowInSector == 0 || rowInSector == PADROWS - 1) { + return true; + } + + const auto& mapper = instance(); + for (int i = 1; i < 4; ++i) { + if (rowInSector == ROWOFFSETSTACK[i] || rowInSector == ROWOFFSETSTACK[i] - 1) { + return true; + } + } + return false; +} + +bool Mapper::isBelowSpacerCross(int rowInSector, int padInRow) +{ + static std::vector ROWSBELOWCROSS{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + if (ROWSBELOWCROSS[rowInSector]) { + return true; + } + + const auto& mapper = instance(); + const auto padCenter = mapper.getNumberOfPadsInRowSector(rowInSector) / 2; + if (padInRow == padCenter || padInRow == padCenter - 1) { + return true; + } + return false; +} + } // namespace tpc } // namespace o2 From f8d52a4f34d0db206ac59db650ca71b0690c9a01 Mon Sep 17 00:00:00 2001 From: wiechula Date: Wed, 16 Oct 2024 09:13:55 +0200 Subject: [PATCH 0005/1992] Add possibility to limit CM k-value in high coupling regions * Fix conversetion of fixed point to float --- .../TPC/calibration/macro/prepareCMFiles.C | 48 +++++++++++++++---- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/Detectors/TPC/calibration/macro/prepareCMFiles.C b/Detectors/TPC/calibration/macro/prepareCMFiles.C index dc14bc61aa793..08880ccbe4862 100644 --- a/Detectors/TPC/calibration/macro/prepareCMFiles.C +++ b/Detectors/TPC/calibration/macro/prepareCMFiles.C @@ -28,7 +28,10 @@ using namespace o2::tpc::cru_calib_helpers; using namespace o2::tpc; -void prepareCMFiles(const std::string_view pulserFile, std::string outputDir = "./") +/// \param limitHighCouplingPads if > 0 limit pads in the high coupling region to this value +/// \param replaceHighCouplingPads if > 0 replace pads in the high coupling region by this value (take preceedence over limitHighCouplingPads) +/// \param maxValue if > 0 limit to this maximum value +void prepareCMFiles(const std::string_view pulserFile, std::string outputDir = "./", float limitHighCouplingPads = 0, float replaceHighCouplingPads = 0, float maxValue = 0) { constexpr uint32_t DataBits = 8; constexpr uint32_t FractionalBits = 6; @@ -115,6 +118,7 @@ void prepareCMFiles(const std::string_view pulserFile, std::string outputDir = " const int fecInPartition = fecInfo.getIndex() - partInfo.getSectorFECOffset(); const int dataWrapperID = fecInPartition >= fecOffset; const int globalLinkID = (fecInPartition % fecOffset) + dataWrapperID * 12; + const auto& padPos = mapper.padPos(globalPad); float pulserVal = rocPulserQtot.getValue(ipad); @@ -128,6 +132,20 @@ void prepareCMFiles(const std::string_view pulserFile, std::string outputDir = " pulserVal = MaxVal; } + if (replaceHighCouplingPads > 0) { + if (Mapper::isHighCouplingPad(padPos.getRow(), padPos.getPad())) { + pulserVal = replaceHighCouplingPads; + } + } else if (limitHighCouplingPads > 0) { + if (Mapper::isHighCouplingPad(padPos.getRow(), padPos.getPad())) { + pulserVal = std::min(pulserVal, limitHighCouplingPads); + } + } + + if (maxValue > 0) { + pulserVal = std::min(pulserVal, maxValue); + } + const int hwChannel = getHWChannel(sampa, sampaChannel, region % 2); // for debugging // printf("%4d %4d %4d %4d %4d: %u\n", cru.number(), globalLinkID, hwChannel, fecInfo.getSampaChip(), fecInfo.getSampaChannel(), getADCValue(pedestal)); @@ -143,22 +161,36 @@ void prepareCMFiles(const std::string_view pulserFile, std::string outputDir = " const bool onlyFilled = false; // ===| k-Values full float precision |=== - const auto outFileFloatTxt = (outputDir + "/commonMode_K_values_float.txt"); - const auto outFileFloatRoot = (outputDir + "/commonMode_K_values_float.root"); + string nameAdd; + if (replaceHighCouplingPads > 0) { + nameAdd = fmt::format(".replaceHC_{:.2}", replaceHighCouplingPads); + } else if (limitHighCouplingPads > 0) { + nameAdd = fmt::format(".limitHC_{:.2}", limitHighCouplingPads); + } + + if (maxValue > 0) { + nameAdd += fmt::format(".maxValue_{:.2}", maxValue); + } + + string outNameBase = "commonMode_K_values" + nameAdd; + string outNameInvBase = "commonMode_inv_K_values" + nameAdd; + + const auto outFileFloatTxt = (outputDir + "/" + outNameBase + "_float.txt"); + const auto outFileFloatRoot = (outputDir + "/" + outNameBase + "_float.root"); writeValues(outFileFloatTxt, commonModeKValuesFloat, onlyFilled); - getCalPad(outFileFloatTxt, outFileFloatRoot, "CMkValues"); + getCalPad<0>(outFileFloatTxt, outFileFloatRoot, "CMkValues"); // ===| k-Values limited precision 2I6F |=== - const auto outFileTxt = (outputDir + "/commonMode_K_values.txt"); - const auto outFileRoot = (outputDir + "/commonMode_K_values.root"); + const auto outFileTxt = (outputDir + "/" + outNameBase + ".txt"); + const auto outFileRoot = (outputDir + "/" + outNameBase + ".root"); writeValues(outFileTxt, commonModeKValues, onlyFilled); getCalPad(outFileTxt, outFileRoot, "CMkValues"); // ===| inverse k-Values limited precision 2I6F |=== - const auto outFileInvTxt = (outputDir + "/commonMode_inv_K_values.txt"); - const auto outFileInvRoot = (outputDir + "/commonMode_inv_K_values.root"); + const auto outFileInvTxt = (outputDir + "/" + outNameInvBase + ".txt"); + const auto outFileInvRoot = (outputDir + "/" + outNameInvBase + ".root"); writeValues(outFileInvTxt, commonModeInvKValues, onlyFilled); getCalPad(outFileInvTxt, outFileInvRoot, "InvCMkValues"); From 0a49d5203d12a0d22384973b1a9c3731314b0a78 Mon Sep 17 00:00:00 2001 From: wiechula Date: Fri, 13 Dec 2024 12:54:03 +0100 Subject: [PATCH 0006/1992] Add PadFlags treatment, add protection --- Detectors/TPC/base/src/Painter.cxx | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/Detectors/TPC/base/src/Painter.cxx b/Detectors/TPC/base/src/Painter.cxx index 863547a666611..9f143d3fa45ce 100644 --- a/Detectors/TPC/base/src/Painter.cxx +++ b/Detectors/TPC/base/src/Painter.cxx @@ -334,9 +334,9 @@ TCanvas* painter::draw(const CalDet& calDet, int nbins1D, float xMin1D, float const GlobalPosition2D pos = mapper.getPadCentre(PadROCPos(roc, irow, ipad)); const int bin = hist2D->FindBin(pos.X(), pos.Y()); if (!hist2D->GetBinContent(bin)) { - hist2D->SetBinContent(bin, val); + hist2D->SetBinContent(bin, double(val)); } - hist1D->Fill(val); + hist1D->Fill(double(val)); } } } @@ -430,7 +430,7 @@ void painter::fillHistogram2D(TH2& h2D, const CalDet& calDet, Side side) const GlobalPosition2D pos = mapper.getPadCentre(PadROCPos(roc, irow, ipad)); const int bin = h2D.FindBin(pos.X(), pos.Y()); if (!h2D.GetBinContent(bin)) { - h2D.SetBinContent(bin, val); + h2D.SetBinContent(bin, double(val)); } } } @@ -454,7 +454,7 @@ void painter::fillHistogram2D(TH2& h2D, const CalArray& calArray) const GlobalPadNumber pad = mapper.getPadNumber(padSubset, position, irow, ipad); const auto val = calArray.getValue(pad); const int cpad = ipad - padsInRow / 2; - h2D.Fill(irow, cpad, val); + h2D.Fill(irow, cpad, double(val)); } } } @@ -523,6 +523,17 @@ std::enable_if_t::value, bool> hasData(const CalArray& ca return cal.getSum() > T{0}; } +template +std::enable_if_t::value, bool> hasData(const CalArray& cal) +{ + for (const auto v : cal.getData()) { + if (int(v) > 0) { + return true; + } + } + return false; +} + template std::vector painter::makeSummaryCanvases(const CalDet& calDet, int nbins1D, float xMin1D, float xMax1D, bool onlyFilled, std::vector* outputCanvases) { @@ -589,7 +600,7 @@ std::vector painter::makeSummaryCanvases(const CalDet& calDet, int // ===| 1D histogram |=== auto h1D = new TH1F(fmt::format("h1_{}_{:02d}", calName, iroc).data(), fmt::format("{} distribution ROC {:02d} ({});ADC value", calName, iroc, getROCTitle(iroc)).data(), nbins1D, xMin1D, xMax1D); for (const auto& val : roc.getData()) { - h1D->Fill(val); + h1D->Fill(double(val)); } // ===| 2D histogram |=== @@ -1342,6 +1353,9 @@ void painter::adjustPalette(TH1* h, float x2ndc, float tickLength) gPad->Modified(); gPad->Update(); auto palette = (TPaletteAxis*)h->GetListOfFunctions()->FindObject("palette"); + if (!palette) { + return; + } palette->SetX2NDC(x2ndc); auto ax = h->GetZaxis(); ax->SetTickLength(tickLength); @@ -1425,6 +1439,12 @@ template TCanvas* painter::draw(const CalArray& calArray); template TH2* painter::getHistogram2D(const CalDet& calDet, Side side); template TH2* painter::getHistogram2D(const CalArray& calArray); +template TCanvas* painter::draw(const CalDet& calDet, int, float, float, TCanvas*); +template std::vector painter::makeSummaryCanvases(const CalDet& calDet, int, float, float, bool, std::vector*); +template TCanvas* painter::draw(const CalArray& calArray); +template TH2* painter::getHistogram2D(const CalDet& calDet, Side side); +template TH2* painter::getHistogram2D(const CalArray& calArray); + template TCanvas* painter::draw(const CalDet& calDet, int, float, float, TCanvas*); template std::vector painter::makeSummaryCanvases(const CalDet& calDet, int, float, float, bool, std::vector*); template TCanvas* painter::draw(const CalArray& calArray); From 366d75ee07add61d1b172c2ac3dbfcc95e8df522 Mon Sep 17 00:00:00 2001 From: wiechula Date: Fri, 13 Dec 2024 12:55:17 +0100 Subject: [PATCH 0007/1992] Add possibility to store canvases in single PDF --- Detectors/TPC/base/src/Utils.cxx | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/Detectors/TPC/base/src/Utils.cxx b/Detectors/TPC/base/src/Utils.cxx index 8879e8ab342d2..d8a420ea4f03c 100644 --- a/Detectors/TPC/base/src/Utils.cxx +++ b/Detectors/TPC/base/src/Utils.cxx @@ -133,7 +133,7 @@ void utils::addFECInfo() h->SetTitle(title.data()); } -void utils::saveCanvases(TObjArray& arr, std::string_view outDir, std::string_view types, std::string_view rootFileName, std::string nameAdd) +void utils::saveCanvases(TObjArray& arr, std::string_view outDir, std::string_view types, std::string_view singleOutFileName, std::string nameAdd) { if (types.size()) { for (auto c : arr) { @@ -141,21 +141,39 @@ void utils::saveCanvases(TObjArray& arr, std::string_view outDir, std::string_vi } } - if (rootFileName.size()) { - std::unique_ptr outFile(TFile::Open(fmt::format("{}/{}", outDir, rootFileName).data(), "recreate")); - arr.Write(arr.GetName(), TObject::kSingleKey); - outFile->Close(); + if (singleOutFileName.size()) { + const auto outFileNames = o2::utils::Str::tokenize(singleOutFileName.data(), ','); + for (const auto& outFileName : outFileNames) { + auto fileName = fmt::format("{}/{}", outDir, outFileName); + if (o2::utils::Str::endsWith(outFileName, ".root")) { + std::unique_ptr outFile(TFile::Open(fileName.data(), "recreate")); + arr.Write(arr.GetName(), TObject::kSingleKey); + outFile->Close(); + } else if (o2::utils::Str::endsWith(outFileName, ".pdf")) { + const auto nCanv = arr.GetEntries(); + for (int i = 0; i < nCanv; ++i) { + auto fileName2 = fileName; + if (i == 0) { + fileName2 += "("; + } else if (i == nCanv - 1) { + fileName2 += ")"; + } + auto c = static_cast(arr.UncheckedAt(i)); + c->Print(fileName2.data(), fmt::format("Title:{}", c->GetTitle()).data()); + } + } + } } } -void utils::saveCanvases(std::vector& canvases, std::string_view outDir, std::string_view types, std::string_view rootFileName, std::string nameAdd) +void utils::saveCanvases(std::vector& canvases, std::string_view outDir, std::string_view types, std::string_view singleOutFileName, std::string nameAdd) { TObjArray arr; for (auto c : canvases) { arr.Add(c); } - saveCanvases(arr, outDir, types, rootFileName, nameAdd); + saveCanvases(arr, outDir, types, singleOutFileName, nameAdd); } void utils::saveCanvas(TCanvas& c, std::string_view outDir, std::string_view types, std::string nameAdd) From 89375b501cc663d8b4943e317ee166a917e1e42e Mon Sep 17 00:00:00 2001 From: wiechula Date: Thu, 19 Dec 2024 16:03:50 +0100 Subject: [PATCH 0008/1992] Add treatment of clustom dE/dx file and disabling dE/dx input --- Detectors/TPC/workflow/src/CalibdEdxSpec.cxx | 36 ++++++++++++++++--- .../TPC/workflow/src/CalibratordEdxSpec.cxx | 34 +++++++++++++++--- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/Detectors/TPC/workflow/src/CalibdEdxSpec.cxx b/Detectors/TPC/workflow/src/CalibdEdxSpec.cxx index a32a4a1bb3089..97b69156a2a6d 100644 --- a/Detectors/TPC/workflow/src/CalibdEdxSpec.cxx +++ b/Detectors/TPC/workflow/src/CalibdEdxSpec.cxx @@ -18,17 +18,18 @@ // o2 includes #include "CCDB/CcdbApi.h" #include "CCDB/CcdbObjectInfo.h" -#include "CommonUtils/NameConf.h" +// #include "CommonUtils/NameConf.h" #include "DataFormatsTPC/TrackTPC.h" -#include "DataFormatsParameters/GRPObject.h" +// #include "DataFormatsParameters/GRPObject.h" #include "DetectorsCalibration/Utils.h" #include "Framework/Task.h" #include "Framework/DataProcessorSpec.h" #include "Framework/ConfigParamRegistry.h" #include "Framework/CCDBParamSpec.h" +#include "GPUO2InterfaceConfigurableParam.h" #include "TPCCalibration/CalibdEdx.h" #include "TPCWorkflow/ProcessingHelpers.h" -#include "TPCBase/CDBInterface.h" +#include "TPCBase/CDBTypes.h" #include "TPCBase/Utils.h" #include "DetectorsBase/GRPGeomHelper.h" @@ -68,6 +69,29 @@ class CalibdEdxDevice : public Task mCalib->set2DFitThreshold(minEntries2D); mCalib->setElectronCut(fitThreshold, fitPasses, fitThresholdLowFactor); mCalib->setMaterialType(mMatType); + + mCustomdEdxFileName = o2::gpu::GPUConfigurableParamGPUSettingsO2::Instance().dEdxCorrFile; + mDisableTimeGain = o2::gpu::GPUConfigurableParamGPUSettingsO2::Instance().dEdxDisableResidualGain; + + if (mDisableTimeGain) { + LOGP(info, "TimeGain correction was disabled via GPU_global.dEdxDisableResidualGain=1"); + } + + if (!mDisableTimeGain && !mCustomdEdxFileName.empty()) { + std::unique_ptr fdEdxCustom(TFile::Open(mCustomdEdxFileName.data())); + if (!fdEdxCustom || !fdEdxCustom->IsOpen() || fdEdxCustom->IsZombie()) { + LOGP(error, "Could not open custom TimeGain file {}", mCustomdEdxFileName); + } else { + const auto timeGain = fdEdxCustom->Get("CalibdEdxCorrection"); + if (!timeGain) { + LOGP(error, "Could not load 'CalibdEdxCorrection' from file {}", mCustomdEdxFileName); + } else { + const auto meanParamTot = timeGain->getMeanParams(ChargeType::Tot); + LOGP(info, "Loaded custom TimeGain from file {} with {} dimensions and mean qTot Params {}", mCustomdEdxFileName, timeGain->getDims(), utils::elementsToString(meanParamTot)); + mCalib->setCalibrationInput(*timeGain); + } + } + } } void finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) final @@ -75,7 +99,7 @@ class CalibdEdxDevice : public Task if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) { return; } - if (matcher == ConcreteDataMatcher("TPC", "TIMEGAIN", 0)) { + if ((mDisableTimeGain == 0) && mCustomdEdxFileName.empty() && (matcher == ConcreteDataMatcher("TPC", "TIMEGAIN", 0))) { mCalib->setCalibrationInput(*(o2::tpc::CalibdEdxCorrection*)obj); const auto meanParamTot = mCalib->getCalibrationInput().getMeanParams(ChargeType::Tot); LOGP(info, "Updating TimeGain with {} dimensions and mean qTot Params {}", mCalib->getCalibrationInput().getDims(), utils::elementsToString(meanParamTot)); @@ -143,7 +167,9 @@ class CalibdEdxDevice : public Task uint64_t mRunNumber{0}; ///< processed run number uint64_t mTimeStampStart{0}; ///< time stamp for first TF for CCDB output std::unique_ptr mCalib; - bool mMakeGaussianFits{true}; ///< make gaussian fits or take the mean + bool mMakeGaussianFits{true}; ///< make gaussian fits or take the mean + bool mDisableTimeGain{false}; ///< if time gain is disabled via GPU_global.dEdxDisableResidualGain=1 + std::string mCustomdEdxFileName{}; ///< name of the custom dE/dx file configured via GPU_global.dEdxCorrFile }; DataProcessorSpec getCalibdEdxSpec(const o2::base::Propagator::MatCorrType matType) diff --git a/Detectors/TPC/workflow/src/CalibratordEdxSpec.cxx b/Detectors/TPC/workflow/src/CalibratordEdxSpec.cxx index 6e477084d992c..ce45356aa28c8 100644 --- a/Detectors/TPC/workflow/src/CalibratordEdxSpec.cxx +++ b/Detectors/TPC/workflow/src/CalibratordEdxSpec.cxx @@ -21,18 +21,19 @@ // o2 includes #include "CCDB/CcdbApi.h" #include "CCDB/CcdbObjectInfo.h" -#include "CommonUtils/NameConf.h" +// #include "CommonUtils/NameConf.h" #include "DataFormatsTPC/TrackTPC.h" -#include "DataFormatsParameters/GRPObject.h" +// #include "DataFormatsParameters/GRPObject.h" #include "DetectorsCalibration/Utils.h" #include "Framework/Task.h" #include "Framework/DataProcessorSpec.h" #include "Framework/ConfigParamRegistry.h" #include "Framework/CCDBParamSpec.h" +#include "GPUO2InterfaceConfigurableParam.h" #include "TPCCalibration/CalibratordEdx.h" #include "TPCWorkflow/ProcessingHelpers.h" #include "DetectorsBase/GRPGeomHelper.h" -#include "TPCBase/CDBInterface.h" +#include "TPCBase/CDBTypes.h" #include "TPCBase/Utils.h" using namespace o2::framework; @@ -85,6 +86,29 @@ class CalibratordEdxDevice : public Task mCalibrator->setTrackDebug(trackDebug); mCalibrator->setMakeGaussianFits(makeGaussianFits); + mCustomdEdxFileName = o2::gpu::GPUConfigurableParamGPUSettingsO2::Instance().dEdxCorrFile; + mDisableTimeGain = o2::gpu::GPUConfigurableParamGPUSettingsO2::Instance().dEdxDisableResidualGain; + + if (mDisableTimeGain) { + LOGP(info, "TimeGain correction was disabled via GPU_global.dEdxDisableResidualGain=1"); + } + + if (!mDisableTimeGain && !mCustomdEdxFileName.empty()) { + std::unique_ptr fdEdxCustom(TFile::Open(mCustomdEdxFileName.data())); + if (!fdEdxCustom || !fdEdxCustom->IsOpen() || fdEdxCustom->IsZombie()) { + LOGP(error, "Could not open custom TimeGain file {}", mCustomdEdxFileName); + } else { + const auto timeGain = fdEdxCustom->Get("CalibdEdxCorrection"); + if (!timeGain) { + LOGP(error, "Could not load 'CalibdEdxCorrection' from file {}", mCustomdEdxFileName); + } else { + mTimeGain = *timeGain; + const auto meanParamTot = mTimeGain.getMeanParams(ChargeType::Tot); + LOGP(info, "Loaded custom TimeGain from file {} with {} dimensions and mean qTot Params {}", mCustomdEdxFileName, mTimeGain.getDims(), utils::elementsToString(meanParamTot)); + } + } + } + if (dumpData) { const auto dumpDataName = ic.options().get("file-dump-name"); mCalibrator->enableDebugOutput(dumpDataName); @@ -96,7 +120,7 @@ class CalibratordEdxDevice : public Task if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) { return; } - if (matcher == ConcreteDataMatcher("TPC", "TIMEGAIN", 0)) { + if ((mDisableTimeGain == 0) && mCustomdEdxFileName.empty() && (matcher == ConcreteDataMatcher("TPC", "TIMEGAIN", 0))) { mTimeGain = *(o2::tpc::CalibdEdxCorrection*)obj; const auto meanParamTot = mTimeGain.getMeanParams(ChargeType::Tot); LOGP(info, "Updating TimeGain with {} dimensions and mean qTot Params {}", mTimeGain.getDims(), utils::elementsToString(meanParamTot)); @@ -181,6 +205,8 @@ class CalibratordEdxDevice : public Task uint32_t mRunNumber{0}; ///< processed run number long mCalibIntervalExtensionMS{0}; ///< Extension of the calibration interval end in ms o2::tpc::CalibdEdxCorrection mTimeGain{}; ///< currently valid TimeGain + bool mDisableTimeGain{false}; ///< if time gain is disabled via GPU_global.dEdxDisableResidualGain=1 + std::string mCustomdEdxFileName{}; ///< name of the custom dE/dx file configured via GPU_global.dEdxCorrFile }; DataProcessorSpec getCalibratordEdxSpec(const o2::base::Propagator::MatCorrType matType) From e01e68248b89b2e69d4222aacc360e69fefecea8 Mon Sep 17 00:00:00 2001 From: lietava Date: Sun, 24 Nov 2024 18:38:51 +0100 Subject: [PATCH 0009/1992] dev: modification of getRate needed for qc --- .../CTP/include/DataFormatsCTP/Scalers.h | 2 +- .../Detectors/CTP/src/CTPRateFetcher.cxx | 6 ++--- DataFormats/Detectors/CTP/src/Scalers.cxx | 22 ++++++++++++++----- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h b/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h index eacbadbe9bedc..518b3b4f10a69 100644 --- a/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h +++ b/DataFormats/Detectors/CTP/include/DataFormatsCTP/Scalers.h @@ -128,7 +128,7 @@ class CTPRunScalers std::pair getRate(uint32_t orbit, int classindex, int type) const; /// same with absolute timestamp (not orbit) as argument - std::pair getRateGivenT(double timestamp, int classindex, int type) const; + std::pair getRateGivenT(double timestamp, int classindex, int type, bool qc = 0) const; /// retrieves integral for class std::array getIntegralForClass(int i) const diff --git a/DataFormats/Detectors/CTP/src/CTPRateFetcher.cxx b/DataFormats/Detectors/CTP/src/CTPRateFetcher.cxx index d9fc250bdc2ac..6be4c3b301802 100644 --- a/DataFormats/Detectors/CTP/src/CTPRateFetcher.cxx +++ b/DataFormats/Detectors/CTP/src/CTPRateFetcher.cxx @@ -84,14 +84,14 @@ double CTPRateFetcher::fetchCTPratesClassesNoPuCorr(uint64_t timeStamp, const st LOG(warn) << "Trigger class " << className << " not found in CTPConfiguration"; return -2.; } - auto rate{mScalers.getRateGivenT(timeStamp * 1.e-3, classIndex, inputType)}; + auto rate{mScalers.getRateGivenT(timeStamp * 1.e-3, classIndex, inputType, 1)}; return rate.second; } double CTPRateFetcher::fetchCTPratesInputs(uint64_t timeStamp, int input) { std::vector& recs = mScalers.getScalerRecordO2(); if (recs[0].scalersInps.size() == 48) { - return pileUpCorrection(mScalers.getRateGivenT(timeStamp * 1.e-3, input, 7).second); + return pileUpCorrection(mScalers.getRateGivenT(timeStamp * 1.e-3, input, 7, 1).second); } else { LOG(error) << "Inputs not available"; return -1.; @@ -101,7 +101,7 @@ double CTPRateFetcher::fetchCTPratesInputsNoPuCorr(uint64_t timeStamp, int input { std::vector& recs = mScalers.getScalerRecordO2(); if (recs[0].scalersInps.size() == 48) { - return mScalers.getRateGivenT(timeStamp * 1.e-3, input, 7).second; + return mScalers.getRateGivenT(timeStamp * 1.e-3, input, 7, 1).second; } else { LOG(error) << "Inputs not available"; return -1.; diff --git a/DataFormats/Detectors/CTP/src/Scalers.cxx b/DataFormats/Detectors/CTP/src/Scalers.cxx index f1881df76a80d..8634c23a42be8 100644 --- a/DataFormats/Detectors/CTP/src/Scalers.cxx +++ b/DataFormats/Detectors/CTP/src/Scalers.cxx @@ -723,7 +723,7 @@ std::pair CTPRunScalers::getRate(uint32_t orbit, int classindex, // rate in Hz at a certain orbit number within the run // type - 7 : inputs // type - 1..6 : lmb,lma,l0b,l0a,l1b,l1a -std::pair CTPRunScalers::getRateGivenT(double timestamp, int classindex, int type) const +std::pair CTPRunScalers::getRateGivenT(double timestamp, int classindex, int type, bool qc) const { if (mScalerRecordO2.size() <= 1) { LOG(error) << "not enough data"; @@ -775,12 +775,24 @@ std::pair CTPRunScalers::getRateGivenT(double timestamp, int cla return -1; // wrong type } }; - if (nextindex == 0 || nextindex == mScalerRecordO2.size()) { + if (nextindex == 0) { // orbit is out of bounds - LOG(info) << "query timestamp " << (long)timestamp << " out of bounds; Just returning the global rate"; - return std::make_pair(/*global mean rate*/ calcRate(0, mScalerRecordO2.size() - 1), /* current rate */ -1); + if(qc == 0) { + LOG(info) << "query timestamp " << (long)timestamp << " before first record; Just returning the global rate"; + return std::make_pair(/*global mean rate*/ calcRate(0, mScalerRecordO2.size() - 1), /* current rate */ -1); + } else { + LOG(info) << "query timestamp " << (long)timestamp << " before first record; Returning the first rate"; + return std::make_pair(/*global mean rate*/ calcRate(0, mScalerRecordO2.size() - 1), /* first rate */ calcRate(0,1) ); + } + } else if(nextindex == mScalerRecordO2.size()){ + if(qc == 0) { + LOG(info) << "query timestamp " << (long)timestamp << " after last record; Just returning the global rate"; + return std::make_pair(/*global mean rate*/ calcRate(0, mScalerRecordO2.size() - 1), /* current rate */ -1); + } else { + LOG(info) << "query timestamp " << (long)timestamp << " after last record; Returning the last rate"; + return std::make_pair(/*global mean rate*/ calcRate(0, mScalerRecordO2.size() - 1), /* last rate */ calcRate(mScalerRecordO2.size() - 2, mScalerRecordO2.size() - 1) ); + } } else { - return std::make_pair(/*global mean rate*/ calcRate(0, mScalerRecordO2.size() - 1), /* current rate */ calcRate(nextindex - 1, nextindex)); } return std::make_pair(-1., -1.); From d2dcb6b08c9d7fd85cb0d7a2d69c35afa15a0a29 Mon Sep 17 00:00:00 2001 From: lietava Date: Sun, 24 Nov 2024 18:42:49 +0100 Subject: [PATCH 0010/1992] clang --- DataFormats/Detectors/CTP/src/Scalers.cxx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/DataFormats/Detectors/CTP/src/Scalers.cxx b/DataFormats/Detectors/CTP/src/Scalers.cxx index 8634c23a42be8..1ebeb239aa034 100644 --- a/DataFormats/Detectors/CTP/src/Scalers.cxx +++ b/DataFormats/Detectors/CTP/src/Scalers.cxx @@ -777,20 +777,20 @@ std::pair CTPRunScalers::getRateGivenT(double timestamp, int cla }; if (nextindex == 0) { // orbit is out of bounds - if(qc == 0) { + if (qc == 0) { LOG(info) << "query timestamp " << (long)timestamp << " before first record; Just returning the global rate"; return std::make_pair(/*global mean rate*/ calcRate(0, mScalerRecordO2.size() - 1), /* current rate */ -1); } else { LOG(info) << "query timestamp " << (long)timestamp << " before first record; Returning the first rate"; - return std::make_pair(/*global mean rate*/ calcRate(0, mScalerRecordO2.size() - 1), /* first rate */ calcRate(0,1) ); + return std::make_pair(/*global mean rate*/ calcRate(0, mScalerRecordO2.size() - 1), /* first rate */ calcRate(0, 1)); } - } else if(nextindex == mScalerRecordO2.size()){ - if(qc == 0) { + } else if (nextindex == mScalerRecordO2.size()) { + if (qc == 0) { LOG(info) << "query timestamp " << (long)timestamp << " after last record; Just returning the global rate"; return std::make_pair(/*global mean rate*/ calcRate(0, mScalerRecordO2.size() - 1), /* current rate */ -1); } else { LOG(info) << "query timestamp " << (long)timestamp << " after last record; Returning the last rate"; - return std::make_pair(/*global mean rate*/ calcRate(0, mScalerRecordO2.size() - 1), /* last rate */ calcRate(mScalerRecordO2.size() - 2, mScalerRecordO2.size() - 1) ); + return std::make_pair(/*global mean rate*/ calcRate(0, mScalerRecordO2.size() - 1), /* last rate */ calcRate(mScalerRecordO2.size() - 2, mScalerRecordO2.size() - 1)); } } else { return std::make_pair(/*global mean rate*/ calcRate(0, mScalerRecordO2.size() - 1), /* current rate */ calcRate(nextindex - 1, nextindex)); From 6374d895834ddc540bb7d5a8366d621b4f7a8920 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 3 Jan 2025 00:44:51 +0100 Subject: [PATCH 0011/1992] DPL: drop unneeded ScopedExit helper (#13831) --- Framework/Core/src/DataProcessingDevice.cxx | 2 - Framework/Core/src/ScopedExit.h | 148 -------------------- 2 files changed, 150 deletions(-) delete mode 100644 Framework/Core/src/ScopedExit.h diff --git a/Framework/Core/src/DataProcessingDevice.cxx b/Framework/Core/src/DataProcessingDevice.cxx index da92c73e1e16a..8a3fbbcf5b2f1 100644 --- a/Framework/Core/src/DataProcessingDevice.cxx +++ b/Framework/Core/src/DataProcessingDevice.cxx @@ -52,8 +52,6 @@ #include "Headers/DataHeader.h" #include "Headers/DataHeaderHelpers.h" -#include "ScopedExit.h" - #include #include diff --git a/Framework/Core/src/ScopedExit.h b/Framework/Core/src/ScopedExit.h deleted file mode 100644 index aca3c1a19d8b1..0000000000000 --- a/Framework/Core/src/ScopedExit.h +++ /dev/null @@ -1,148 +0,0 @@ -// 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. -#include -#include - -namespace o2::framework -{ -namespace detail -{ -// Original from https://github.com/ricab/scope_guard -// which is licensed to public domain -// Type trait determining whether a type is callable with no arguments -template -struct is_noarg_callable_t - : public std::false_type { -}; // in general, false - -template -struct is_noarg_callable_t()())> - : public std::true_type { -}; // only true when call expression valid - -// Type trait determining whether a no-argument callable returns void -template -struct returns_void_t - : public std::is_same()())> { -}; - -/* Type trait determining whether a no-arg callable is nothrow invocable if - required. This is where SG_REQUIRE_NOEXCEPT logic is encapsulated. */ -template -struct is_nothrow_invocable_if_required_t - : public std::is_nothrow_invocable /* Note: _r variants not enough to - confirm void return: any return can be - discarded so all returns are - compatible with void */ -{ -}; - -template -struct and_t : public and_t> { -}; - -template -struct and_t : public std::conditional::type { -}; - -template -struct is_proper_sg_callback_t - : public and_t, - returns_void_t, - is_nothrow_invocable_if_required_t, - std::is_nothrow_destructible> { -}; - -template ::value>::type> -class scope_guard; - -template -detail::scope_guard make_scope_guard(Callback&& callback) noexcept(std::is_nothrow_constructible::value); - -template -class scope_guard final -{ - public: - typedef Callback callback_type; - - scope_guard(scope_guard&& other) noexcept(std::is_nothrow_constructible::value); - - ~scope_guard() noexcept; // highlight noexcept dtor - - void dismiss() noexcept; - - public: - scope_guard() = delete; - scope_guard(const scope_guard&) = delete; - scope_guard& operator=(const scope_guard&) = delete; - scope_guard& operator=(scope_guard&&) = delete; - - private: - explicit scope_guard(Callback&& callback) noexcept(std::is_nothrow_constructible::value); /* - meant for friends only */ - - friend scope_guard make_scope_guard(Callback&&) noexcept(std::is_nothrow_constructible::value); /* - only make_scope_guard can create scope_guards from scratch (i.e. non-move) - */ - - private: - Callback mCallback; - bool mActive; -}; - -} // namespace detail - -using detail::make_scope_guard; // see comment on declaration above - -template -detail::scope_guard::scope_guard(Callback&& callback) noexcept(std::is_nothrow_constructible::value) - : mCallback(std::forward(callback)) /* use () instead of {} because - of DR 1467 (https://is.gd/WHmWuo), which still impacts older compilers - (e.g. GCC 4.x and clang <=3.6, see https://godbolt.org/g/TE9tPJ and - https://is.gd/Tsmh8G) */ - , - mActive{true} -{ -} - -template -detail::scope_guard::~scope_guard() noexcept -{ - if (mActive) { - mCallback(); - } -} - -template -detail::scope_guard::scope_guard(scope_guard&& other) noexcept(std::is_nothrow_constructible::value) - : mCallback(std::forward(other.mCallback)) // idem - , - mActive{std::move(other.mActive)} -{ - other.mActive = false; -} - -template -inline void detail::scope_guard::dismiss() noexcept -{ - mActive = false; -} - -template -inline auto detail::make_scope_guard(Callback&& callback) noexcept(std::is_nothrow_constructible::value) - -> detail::scope_guard -{ - return detail::scope_guard{std::forward(callback)}; -} - -} // namespace o2::framework From f5d37d2676f9bb3d8f77a3c15d86feeab03e73f4 Mon Sep 17 00:00:00 2001 From: shahoian Date: Sat, 28 Dec 2024 00:21:32 +0100 Subject: [PATCH 0012/1992] ITS/MFT decoder sends vector with certain errors details An output vector is added with information about ChipStat::RepeatingPixel error details (at the moment, other errors may be added). Each element of ErrorMessage is assigned as: errMsg.id = chipID errMsg.errType = ChipStat::RepeatingPixel (at the moment) errMsg.errInfo0 = row errMsg.errInfo1 = col --- .../ITSMFTReconstruction/DecodingStat.h | 8 ++++++ .../ITSMFTReconstruction/RUDecodeData.h | 2 ++ .../ITSMFTReconstruction/RawPixelDecoder.h | 27 ++++++++++++++----- .../src/ITSMFTReconstructionLinkDef.h | 3 +++ .../reconstruction/src/RUDecodeData.cxx | 8 ++++++ .../common/workflow/src/STFDecoderSpec.cxx | 4 ++- 6 files changed, 44 insertions(+), 8 deletions(-) diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/DecodingStat.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/DecodingStat.h index 9a57228ddce1e..012059749d995 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/DecodingStat.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/DecodingStat.h @@ -290,6 +290,14 @@ struct GBTLinkDecodingStat { ClassDefNV(GBTLinkDecodingStat, 3); }; +struct ErrorMessage { + uint16_t id = -1; + uint16_t errType = 0; + uint16_t errInfo0 = 0; + uint16_t errInfo1 = 0; + ClassDefNV(ErrorMessage, 1) +}; + } // namespace itsmft } // namespace o2 #endif diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RUDecodeData.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RUDecodeData.h index 9e3b1daa00a26..85c6b39fdd1b5 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RUDecodeData.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RUDecodeData.h @@ -54,6 +54,8 @@ struct RUDecodeData { bool ROFRampUpStage = false; // flag that the data come from the ROF rate ramp-up stage GBTCalibData calibData{}; // calibration info from GBT calibration word std::unordered_map> chipErrorsTF{}; // vector of chip decoding errors seen in the given TF + std::vector errMsgVecTF; // Specific errors info collected for sending for the whole TF + const RUInfo* ruInfo = nullptr; RUDecodeData() diff --git a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RawPixelDecoder.h b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RawPixelDecoder.h index 810bff1037513..3a53253da2b42 100644 --- a/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RawPixelDecoder.h +++ b/Detectors/ITSMFT/common/reconstruction/include/ITSMFTReconstruction/RawPixelDecoder.h @@ -69,8 +69,8 @@ class RawPixelDecoder final : public PixelReader template void fillCalibData(CalibContainer& calib); - template - void collectDecodingErrors(LinkErrors& linkErrors, DecErrors& decErrors); + template + void collectDecodingErrors(LinkErrors& linkErrors, DecErrors& decErrors, ErrMsgs& errInfos); const RUDecodeData* getRUDecode(int ruSW) const { return mRUEntry[ruSW] < 0 ? nullptr : &mRUDecodeVec[mRUEntry[ruSW]]; } const GBTLink* getGBTLink(int i) const { return i < 0 ? nullptr : &mGBTLinks[i]; } @@ -267,8 +267,8 @@ void RawPixelDecoder::fillCalibData(CalibContainer& calib) ///______________________________________________________________________ template -template -void RawPixelDecoder::collectDecodingErrors(LinkErrors& linkErrors, DecErrors& decErrors) +template +void RawPixelDecoder::collectDecodingErrors(LinkErrors& linkErrors, DecErrors& decErrors, ErrMsgs& errInfos) { for (auto& lnk : mGBTLinks) { if (lnk.gbtErrStatUpadated) { @@ -276,11 +276,24 @@ void RawPixelDecoder::collectDecodingErrors(LinkErrors& linkErrors, Dec lnk.gbtErrStatUpadated = false; } } + size_t nerr = 0, nerrMsg = 0; for (auto& ru : mRUDecodeVec) { - for (const auto& err : ru.chipErrorsTF) { - decErrors.emplace_back(ChipError{err.first, err.second.first, err.second.second}); // id, nerrors, errorFlags + nerr += ru.chipErrorsTF.size(); + nerrMsg += ru.errMsgVecTF.size(); + } + if (nerr || nerrMsg) { + decErrors.reserve(nerr); + errInfos.reserve(nerrMsg); + for (auto& ru : mRUDecodeVec) { + for (const auto& err : ru.chipErrorsTF) { + decErrors.emplace_back(ChipError{err.first, err.second.first, err.second.second}); // id, nerrors, errorFlags + } + for (auto& err : ru.errMsgVecTF) { + errInfos.push_back(err); + } + ru.chipErrorsTF.clear(); + ru.errMsgVecTF.clear(); } - ru.chipErrorsTF.clear(); } } diff --git a/Detectors/ITSMFT/common/reconstruction/src/ITSMFTReconstructionLinkDef.h b/Detectors/ITSMFT/common/reconstruction/src/ITSMFTReconstructionLinkDef.h index e6785e4402f37..19f4ca06d0220 100644 --- a/Detectors/ITSMFT/common/reconstruction/src/ITSMFTReconstructionLinkDef.h +++ b/Detectors/ITSMFT/common/reconstruction/src/ITSMFTReconstructionLinkDef.h @@ -55,4 +55,7 @@ #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::itsmft::ClustererParam < o2::detectors::DetID::ITS>> + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::itsmft::ClustererParam < o2::detectors::DetID::MFT>> + ; +#pragma link C++ class o2::itsmft::ErrorMessage + ; +#pragma link C++ class std::vector < o2::itsmft::ErrorMessage> + ; + #endif diff --git a/Detectors/ITSMFT/common/reconstruction/src/RUDecodeData.cxx b/Detectors/ITSMFT/common/reconstruction/src/RUDecodeData.cxx index e81194666fcb8..a9ed2748ec004 100644 --- a/Detectors/ITSMFT/common/reconstruction/src/RUDecodeData.cxx +++ b/Detectors/ITSMFT/common/reconstruction/src/RUDecodeData.cxx @@ -62,6 +62,14 @@ void RUDecodeData::fillChipStatistics(int icab, const ChipPixelData* chipData) auto& chErr = chipErrorsTF[compid]; chErr.first++; chErr.second |= chipData->getErrorFlags(); + + if (chipData->isErrorSet(ChipStat::RepeatingPixel)) { + auto& errMsg = errMsgVecTF.emplace_back(); + errMsg.id = chipData->getChipID(); + errMsg.errType = ChipStat::RepeatingPixel; + errMsg.errInfo0 = chipData->getErrorInfo() & 0xffff; // row + errMsg.errInfo1 = (chipData->getErrorInfo() >> 16) & 0xffff; // row + } } if (action & ChipStat::ErrActDump) { linkHBFToDump[(uint64_t(cableLinkPtr[icab]->subSpec) << 32) + cableLinkPtr[icab]->hbfEntry] = cableLinkPtr[icab]->irHBF.orbit; diff --git a/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx b/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx index 76bd1ec7454a0..7042cb7433ac5 100644 --- a/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx +++ b/Detectors/ITSMFT/common/workflow/src/STFDecoderSpec.cxx @@ -247,7 +247,8 @@ void STFDecoder::run(ProcessingContext& pc) } auto& linkErrors = pc.outputs().make>(Output{orig, "LinkErrors", 0}); auto& decErrors = pc.outputs().make>(Output{orig, "ChipErrors", 0}); - mDecoder->collectDecodingErrors(linkErrors, decErrors); + auto& errMessages = pc.outputs().make>(Output{orig, "ErrorInfo", 0}); + mDecoder->collectDecodingErrors(linkErrors, decErrors, errMessages); pc.outputs().snapshot(Output{orig, "PHYSTRIG", 0}, mDecoder->getExternalTriggers()); @@ -398,6 +399,7 @@ DataProcessorSpec getSTFDecoderSpec(const STFDecoderInp& inp) outputs.emplace_back(inp.origin, "LinkErrors", 0, Lifetime::Timeframe); outputs.emplace_back(inp.origin, "ChipErrors", 0, Lifetime::Timeframe); + outputs.emplace_back(inp.origin, "ErrorInfo", 0, Lifetime::Timeframe); outputs.emplace_back(inp.origin, "CHIPSSTATUS", 0, Lifetime::Timeframe); if (inp.askSTFDist) { From 64dd90cfb914805f3334aa32022581e7a05971b7 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 3 Jan 2025 20:05:56 +0100 Subject: [PATCH 0013/1992] DPL: use requires rather than enable_if / static_assert --- Framework/Core/include/Framework/ServiceRegistry.h | 9 ++++----- Framework/Core/include/Framework/ServiceRegistryRef.h | 3 ++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Framework/Core/include/Framework/ServiceRegistry.h b/Framework/Core/include/Framework/ServiceRegistry.h index e3fa23294ee78..2236562e6da75 100644 --- a/Framework/Core/include/Framework/ServiceRegistry.h +++ b/Framework/Core/include/Framework/ServiceRegistry.h @@ -267,33 +267,32 @@ struct ServiceRegistry { /// @deprecated old API to be substituted with the ServiceHandle one template + requires std::is_base_of_v void registerService(C* service, Salt salt = ServiceRegistry::globalDeviceSalt()) { // This only works for concrete implementations of the type T. // We need type elision as we do not want to know all the services in // advance - static_assert(std::is_base_of::value == true, - "Registered service is not derived from declared interface"); constexpr ServiceTypeHash typeHash{TypeIdHelpers::uniqueId()}; ServiceRegistry::registerService(typeHash, reinterpret_cast(service), K, salt, typeid(C).name()); } /// @deprecated old API to be substituted with the ServiceHandle one template + requires std::is_base_of_v void registerService(C const* service, Salt salt = ServiceRegistry::globalDeviceSalt()) { // This only works for concrete implementations of the type T. // We need type elision as we do not want to know all the services in // advance - static_assert(std::is_base_of::value == true, - "Registered service is not derived from declared interface"); constexpr ServiceTypeHash typeHash{TypeIdHelpers::uniqueId()}; this->registerService(typeHash, reinterpret_cast(const_cast(service)), K, salt, typeid(C).name()); } /// Check if service of type T is currently active. template - std::enable_if_t == false, bool> active(Salt salt) const + requires(std::is_const_v == false) + bool active(Salt salt) const { constexpr ServiceTypeHash typeHash{TypeIdHelpers::uniqueId()}; if (this->getPos(typeHash, GLOBAL_CONTEXT_SALT) != -1) { diff --git a/Framework/Core/include/Framework/ServiceRegistryRef.h b/Framework/Core/include/Framework/ServiceRegistryRef.h index fa791cc8c4643..910d4e726c080 100644 --- a/Framework/Core/include/Framework/ServiceRegistryRef.h +++ b/Framework/Core/include/Framework/ServiceRegistryRef.h @@ -72,7 +72,8 @@ class ServiceRegistryRef /// Check if service of type T is currently active. template - std::enable_if_t == false, bool> active() const + requires(std::is_const_v == false) + [[nodiscard]] bool active() const { return mRegistry.active(mSalt); } From 1d6f86c001175dc7152b7b51a3f9e029c011e4ed Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Sun, 5 Jan 2025 10:00:37 +0100 Subject: [PATCH 0014/1992] DPL: cleanup ServiceRegistry headers --- Detectors/TPC/workflow/src/tpc-integrate-idc.cxx | 1 + Detectors/TPC/workflow/src/tpc-krypton-clusterer.cxx | 1 + Framework/Core/include/Framework/ServiceRegistry.h | 4 ---- Framework/Core/src/ArrowSupport.cxx | 2 ++ Framework/Core/src/DataProcessingStates.cxx | 1 + Framework/Core/src/WorkflowHelpers.cxx | 1 + Framework/Core/src/runDataProcessing.cxx | 1 + Framework/Core/test/test_ComputingQuotaEvaluator.cxx | 1 + Framework/Core/test/test_DataRelayer.cxx | 1 + Framework/Core/test/test_Services.cxx | 1 + 10 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Detectors/TPC/workflow/src/tpc-integrate-idc.cxx b/Detectors/TPC/workflow/src/tpc-integrate-idc.cxx index cd7e777a293e0..4aae6683f29b0 100644 --- a/Detectors/TPC/workflow/src/tpc-integrate-idc.cxx +++ b/Detectors/TPC/workflow/src/tpc-integrate-idc.cxx @@ -11,6 +11,7 @@ #include #include +#include #include "Algorithm/RangeTokenizer.h" #include "Framework/WorkflowSpec.h" #include "Framework/ConfigParamSpec.h" diff --git a/Detectors/TPC/workflow/src/tpc-krypton-clusterer.cxx b/Detectors/TPC/workflow/src/tpc-krypton-clusterer.cxx index e815a4fc85e3a..d7c1839f94c6b 100644 --- a/Detectors/TPC/workflow/src/tpc-krypton-clusterer.cxx +++ b/Detectors/TPC/workflow/src/tpc-krypton-clusterer.cxx @@ -12,6 +12,7 @@ #include #include #include +#include #include "Algorithm/RangeTokenizer.h" #include "Framework/WorkflowSpec.h" diff --git a/Framework/Core/include/Framework/ServiceRegistry.h b/Framework/Core/include/Framework/ServiceRegistry.h index 2236562e6da75..ebafd466929ff 100644 --- a/Framework/Core/include/Framework/ServiceRegistry.h +++ b/Framework/Core/include/Framework/ServiceRegistry.h @@ -14,17 +14,13 @@ #include "Framework/ThreadSafetyAnalysis.h" #include "Framework/ServiceHandle.h" #include "Framework/ServiceSpec.h" -#include "Framework/ServiceRegistryHelpers.h" #include "Framework/CompilerBuiltins.h" #include "Framework/TypeIdHelpers.h" -#include #include -#include #include #include #include -#include #include #include diff --git a/Framework/Core/src/ArrowSupport.cxx b/Framework/Core/src/ArrowSupport.cxx index 3f9014d8fbe3b..1dcc85c1d4f04 100644 --- a/Framework/Core/src/ArrowSupport.cxx +++ b/Framework/Core/src/ArrowSupport.cxx @@ -31,6 +31,8 @@ #include "WorkflowHelpers.h" #include "Framework/WorkflowSpecNode.h" #include "Framework/AnalysisSupportHelpers.h" +#include "Framework/ServiceRegistryRef.h" +#include "Framework/ServiceRegistryHelpers.h" #include "CommonMessageBackendsHelpers.h" #include diff --git a/Framework/Core/src/DataProcessingStates.cxx b/Framework/Core/src/DataProcessingStates.cxx index 094b83f01d7b4..64be1829d8c97 100644 --- a/Framework/Core/src/DataProcessingStates.cxx +++ b/Framework/Core/src/DataProcessingStates.cxx @@ -18,6 +18,7 @@ #include #include #include +#include #include namespace o2::framework diff --git a/Framework/Core/src/WorkflowHelpers.cxx b/Framework/Core/src/WorkflowHelpers.cxx index 3782c48e81c56..597f3d32856c1 100644 --- a/Framework/Core/src/WorkflowHelpers.cxx +++ b/Framework/Core/src/WorkflowHelpers.cxx @@ -27,6 +27,7 @@ #include "Framework/DataTakingContext.h" #include "Framework/DefaultsHelpers.h" #include "Framework/Signpost.h" +#include "Framework/ServiceRegistryHelpers.h" #include "Framework/Variant.h" #include "Headers/DataHeader.h" diff --git a/Framework/Core/src/runDataProcessing.cxx b/Framework/Core/src/runDataProcessing.cxx index 4bfbc3232822a..03b013d266316 100644 --- a/Framework/Core/src/runDataProcessing.cxx +++ b/Framework/Core/src/runDataProcessing.cxx @@ -34,6 +34,7 @@ #include "Framework/DeviceState.h" #include "Framework/DeviceConfig.h" #include "DeviceStateHelpers.h" +#include "Framework/ServiceRegistryHelpers.h" #include "Framework/DevicesManager.h" #include "Framework/DebugGUI.h" #include "Framework/LocalRootFileService.h" diff --git a/Framework/Core/test/test_ComputingQuotaEvaluator.cxx b/Framework/Core/test/test_ComputingQuotaEvaluator.cxx index 92fedcfe78614..cd0d79538e12a 100644 --- a/Framework/Core/test/test_ComputingQuotaEvaluator.cxx +++ b/Framework/Core/test/test_ComputingQuotaEvaluator.cxx @@ -16,6 +16,7 @@ #include "Framework/Logger.h" #include "Framework/TimingHelpers.h" #include "Framework/DataProcessingStats.h" +#include "Framework/ServiceRegistryHelpers.h" #include "uv.h" #pragma GCC diagnostic push diff --git a/Framework/Core/test/test_DataRelayer.cxx b/Framework/Core/test/test_DataRelayer.cxx index 64a1827820638..7d5a3ded88e16 100644 --- a/Framework/Core/test/test_DataRelayer.cxx +++ b/Framework/Core/test/test_DataRelayer.cxx @@ -22,6 +22,7 @@ #include "Framework/TimingHelpers.h" #include "../src/DataRelayerHelpers.h" #include "Framework/DataProcessingHeader.h" +#include "Framework/ServiceRegistryHelpers.h" #include "Framework/WorkflowSpec.h" #include #include diff --git a/Framework/Core/test/test_Services.cxx b/Framework/Core/test/test_Services.cxx index 23092127fb37b..056a3d0d9b6c4 100644 --- a/Framework/Core/test/test_Services.cxx +++ b/Framework/Core/test/test_Services.cxx @@ -14,6 +14,7 @@ #include "Framework/ServiceRegistry.h" #include "Framework/CallbackService.h" #include "Framework/CommonServices.h" +#include "Framework/ServiceRegistryHelpers.h" #include #include #include From 8b7ba4ea4b242235dd95400ded04ec83e8da8859 Mon Sep 17 00:00:00 2001 From: noferini <9963644+noferini@users.noreply.github.com> Date: Mon, 30 Dec 2024 14:22:27 +0100 Subject: [PATCH 0015/1992] fix in TOF sim digitization (decalibration), and add MC truth for QC plots --- .../TOF/include/DataFormatsTOF/Cluster.h | 10 ++++- DataFormats/Detectors/TOF/src/Cluster.cxx | 2 +- .../ReconstructionDataFormats/MatchInfoTOF.h | 10 ++++- Detectors/GlobalTracking/src/MatchTOF.cxx | 19 ++++++++ Detectors/TOF/base/include/TOFBase/Digit.h | 15 +++++-- Detectors/TOF/base/include/TOFBase/Strip.h | 2 +- Detectors/TOF/base/src/Digit.cxx | 12 +++--- Detectors/TOF/base/src/Strip.cxx | 9 ++-- .../TOF/reconstruction/src/Clusterer.cxx | 2 + .../include/TOFSimulation/Digitizer.h | 4 +- Detectors/TOF/simulation/src/Digitizer.cxx | 43 ++++++++++--------- 11 files changed, 88 insertions(+), 40 deletions(-) diff --git a/DataFormats/Detectors/TOF/include/DataFormatsTOF/Cluster.h b/DataFormats/Detectors/TOF/include/DataFormatsTOF/Cluster.h index 589afc8a2cde9..f36150e18fbbc 100644 --- a/DataFormats/Detectors/TOF/include/DataFormatsTOF/Cluster.h +++ b/DataFormats/Detectors/TOF/include/DataFormatsTOF/Cluster.h @@ -53,7 +53,7 @@ class Cluster : public o2::BaseCluster Cluster() = default; - Cluster(std::int16_t sensid, float x, float y, float z, float sy2, float sz2, float syz, double timeRaw, double time, float tot, int L0L1latency, int deltaBC); + Cluster(std::int16_t sensid, float x, float y, float z, float sy2, float sz2, float syz, double timeRaw, double time, float tot, int L0L1latency, int deltaBC, float geanttime = 0.0, double t0 = 0.0); ~Cluster() = default; @@ -134,6 +134,10 @@ class Cluster : public o2::BaseCluster int getDigitInfoCH(int idig) const { return mDigitInfoCh[idig]; } double getDigitInfoT(int idig) const { return mDigitInfoT[idig]; } float getDigitInfoTOT(int idig) const { return mDigitInfoTOT[idig]; } + float getTgeant() const { return mTgeant; } + void setTgeant(float val) { mTgeant = val; } + double getT0true() const { return mT0true; } + void setT0true(double val) { mT0true = val; } private: #if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) @@ -153,8 +157,10 @@ class Cluster : public o2::BaseCluster int mDigitInfoCh[6] = {0, 0, 0, 0, 0, 0}; double mDigitInfoT[6] = {0., 0., 0., 0., 0., 0.}; float mDigitInfoTOT[6] = {0., 0., 0., 0., 0., 0.}; + float mTgeant = 0.0; + double mT0true = 0.0; - ClassDefNV(Cluster, 4); + ClassDefNV(Cluster, 5); }; #ifndef GPUCA_GPUCODE diff --git a/DataFormats/Detectors/TOF/src/Cluster.cxx b/DataFormats/Detectors/TOF/src/Cluster.cxx index 2ca3edeb19f0a..a7f3473e0b61c 100644 --- a/DataFormats/Detectors/TOF/src/Cluster.cxx +++ b/DataFormats/Detectors/TOF/src/Cluster.cxx @@ -23,7 +23,7 @@ using namespace o2::tof; ClassImp(o2::tof::Cluster); -Cluster::Cluster(std::int16_t sensid, float x, float y, float z, float sy2, float sz2, float syz, double timeRaw, double time, float tot, int L0L1Latency, int deltaBC) : o2::BaseCluster(sensid, x, y, z, sy2, sz2, syz), mTimeRaw(timeRaw), mTime(time), mTot(tot), mL0L1Latency(L0L1Latency), mDeltaBC(deltaBC) +Cluster::Cluster(std::int16_t sensid, float x, float y, float z, float sy2, float sz2, float syz, double timeRaw, double time, float tot, int L0L1Latency, int deltaBC, float geanttime, double t0) : o2::BaseCluster(sensid, x, y, z, sy2, sz2, syz), mTimeRaw(timeRaw), mTime(time), mTot(tot), mL0L1Latency(L0L1Latency), mDeltaBC(deltaBC), mTgeant(geanttime), mT0true(t0) { // caching R and phi diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/MatchInfoTOF.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/MatchInfoTOF.h index edc1b99822ca0..3b872374dd35a 100644 --- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/MatchInfoTOF.h +++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/MatchInfoTOF.h @@ -28,7 +28,7 @@ class MatchInfoTOF using GTrackID = o2::dataformats::GlobalTrackID; public: - MatchInfoTOF(int idLocal, int idxTOFCl, double time, float chi2, o2::track::TrackLTIntegral trkIntLT, GTrackID idxTrack, float dt = 0, float z = 0, float dx = 0, float dz = 0, float dy = 0) : mIdLocal(idLocal), mIdxTOFCl(idxTOFCl), mSignal(time), mChi2(chi2), mIntLT(trkIntLT), mIdxTrack(idxTrack), mDeltaT(dt), mZatTOF(z), mDXatTOF(dx), mDZatTOF(dz), mDYatTOF(dy){}; + MatchInfoTOF(int idLocal, int idxTOFCl, double time, float chi2, o2::track::TrackLTIntegral trkIntLT, GTrackID idxTrack, float dt = 0, float z = 0, float dx = 0, float dz = 0, float dy = 0, float geanttime = 0.0, double t0 = 0.0) : mIdLocal(idLocal), mIdxTOFCl(idxTOFCl), mSignal(time), mChi2(chi2), mIntLT(trkIntLT), mIdxTrack(idxTrack), mDeltaT(dt), mZatTOF(z), mDXatTOF(dx), mDZatTOF(dz), mDYatTOF(dy), mTgeant(geanttime), mT0true(t0){}; MatchInfoTOF() = default; void setIdxTOFCl(int index) { mIdxTOFCl = index; } void setIdxTrack(GTrackID index) { mIdxTrack = index; } @@ -70,6 +70,10 @@ class MatchInfoTOF void setVz(float val) { mVz = val; } int getChannel() const { return mChannel; } void setChannel(int val) { mChannel = val; } + float getTgeant() const { return mTgeant; } + void setTgeant(float val) { mTgeant = val; } + double getT0true() const { return mT0true; } + void setT0true(double val) { mT0true = val; } private: int mIdLocal; // track id in sector of the pair track-TOFcluster @@ -88,8 +92,10 @@ class MatchInfoTOF // Hit pattern information bool mHitUpDown = false; ///< hit pattern in TOF up-down bool mHitLeftRight = false; ///< hit pattern in TOF left-right + float mTgeant = 0.0; ///< geant time in MC + double mT0true = 0.0; ///< t0true - ClassDefNV(MatchInfoTOF, 7); + ClassDefNV(MatchInfoTOF, 8); }; } // namespace dataformats } // namespace o2 diff --git a/Detectors/GlobalTracking/src/MatchTOF.cxx b/Detectors/GlobalTracking/src/MatchTOF.cxx index 015f9497293af..89d6f8347373d 100644 --- a/Detectors/GlobalTracking/src/MatchTOF.cxx +++ b/Detectors/GlobalTracking/src/MatchTOF.cxx @@ -967,6 +967,9 @@ void MatchTOF::doMatching(int sec) } } + // adjust accordingly to DeltaY + updateTL(trkLTInt[nStripsCrossedInPropagation - 1], -deltaPosTemp[1]); + detId[nStripsCrossedInPropagation - 1][0] = detIdTemp[0]; detId[nStripsCrossedInPropagation - 1][1] = detIdTemp[1]; detId[nStripsCrossedInPropagation - 1][2] = detIdTemp[2]; @@ -1340,11 +1343,14 @@ void MatchTOF::doMatchingForTPC(int sec) for (int ii = 0; ii < 3; ii++) { // we need to change the type... posFloat[ii] = pos[ii]; } + while (deltaPosTemp2[1] < -0.05 && detIdTemp2[2] != -1 && nstep < maxnstep) { // continuing propagation if dy is negative and we are still inside the strip volume nstep++; xStop += 0.1; propagateToRefXWithoutCov(trefTrk, xStop, 0.1, mBz, posFloat); + posFloat[2] += ZshiftCurrent; + Geo::getPadDxDyDz(posFloat, detIdTemp2, deltaPosTemp2, sec); if (detIdTemp2[2] != -1) { // if propation was succesful -> update params float dx = deltaPosTemp2[0] - deltaPosTemp[0]; @@ -1356,9 +1362,15 @@ void MatchTOF::doMatchingForTPC(int sec) detIdTemp[2] = detIdTemp2[2]; detIdTemp[3] = detIdTemp2[3]; detIdTemp[4] = detIdTemp2[4]; + deltaPosTemp[0] = deltaPosTemp2[0]; + deltaPosTemp[1] = deltaPosTemp2[1]; + deltaPosTemp[2] = deltaPosTemp2[2]; } } + // adjust accordingly to DeltaY + updateTL(trkLTInt[ibc][nStripsCrossedInPropagation[ibc] - 1], -deltaPosTemp[1]); + detId[ibc][nStripsCrossedInPropagation[ibc] - 1][0] = detIdTemp[0]; detId[ibc][nStripsCrossedInPropagation[ibc] - 1][1] = detIdTemp[1]; detId[ibc][nStripsCrossedInPropagation[ibc] - 1][2] = detIdTemp[2]; @@ -1671,6 +1683,10 @@ void MatchTOF::BestMatches(std::vector& match if (std::abs(timeNew - timeOld) < 200) { // update time information averaging the two (the second one corrected for the difference in the track length) prevMatching.setSignal((timeNew + timeOld) * 0.5); + float geanttime = (TOFClusWork[matchingPair.getTOFClIndex()].getTgeant() + TOFClusWork[prevMatching.getTOFClIndex()].getTgeant() - deltaT * 1E-3) * 0.5; + double t0 = (TOFClusWork[matchingPair.getTOFClIndex()].getT0true() + TOFClusWork[prevMatching.getTOFClIndex()].getT0true()) * 0.5; + prevMatching.setTgeant(geanttime); + prevMatching.setT0true(t0); prevMatching.setChi2(0); // flag such cases with chi2 equal to zero matchedClustersIndex[matchingPair.getTOFClIndex()] = matchedTracksIndex[trkType][itrk]; // flag also the second cluster as already used } @@ -1682,6 +1698,9 @@ void MatchTOF::BestMatches(std::vector& match matchedTracksIndex[trkType][itrk] = matchedTracks[trkTypeSplitted].size(); // index of the MatchInfoTOF correspoding to this track matchedClustersIndex[matchingPair.getTOFClIndex()] = matchedTracksIndex[trkType][itrk]; // index of the track that was matched to this cluster + matchingPair.setTgeant(TOFClusWork[matchingPair.getTOFClIndex()].getTgeant()); + matchingPair.setT0true(TOFClusWork[matchingPair.getTOFClIndex()].getT0true()); + // let's check if cluster has multiple-hits (noferini) if (TOFClusWork[matchingPair.getTOFClIndex()].getNumOfContributingChannels() > 1) { const auto& tofcl = TOFClusWork[matchingPair.getTOFClIndex()]; diff --git a/Detectors/TOF/base/include/TOFBase/Digit.h b/Detectors/TOF/base/include/TOFBase/Digit.h index d23c138012e81..eef03ef84b97c 100644 --- a/Detectors/TOF/base/include/TOFBase/Digit.h +++ b/Detectors/TOF/base/include/TOFBase/Digit.h @@ -32,8 +32,8 @@ class Digit public: Digit() = default; - Digit(Int_t channel, Int_t tdc, Int_t tot, uint64_t bc, Int_t label = -1, uint32_t triggerorbit = 0, uint16_t triggerbunch = 0); - Digit(Int_t channel, Int_t tdc, Int_t tot, uint32_t orbit, uint16_t bc, Int_t label = -1, uint32_t triggerorbit = 0, uint16_t triggerbunch = 0); + Digit(Int_t channel, Int_t tdc, Int_t tot, uint64_t bc, Int_t label = -1, uint32_t triggerorbit = 0, uint16_t triggerbunch = 0, float geanttime = 0, double t0 = 0); + Digit(Int_t channel, Int_t tdc, Int_t tot, uint32_t orbit, uint16_t bc, Int_t label = -1, uint32_t triggerorbit = 0, uint16_t triggerbunch = 0, float geanttime = 0, double t0 = 0); ~Digit() = default; /// Get global ordering key made of @@ -66,7 +66,7 @@ class Digit void printStream(std::ostream& stream) const; - void merge(Int_t tdc, Int_t tot); + bool merge(Int_t tdc, Int_t tot); void getPhiAndEtaIndex(int& phi, int& eta) const; @@ -93,6 +93,11 @@ class Digit void setTriggerBunch(uint16_t value) { mTriggerBunch = value; } uint16_t getTriggerBunch() const { return mTriggerBunch; } + float getTgeant() const { return mTgeant; } + void setTgeant(float val) { mTgeant = val; } + double getT0true() const { return mT0true; } + void setT0true(double val) { mT0true = val; } + private: friend class boost::serialization::access; @@ -107,8 +112,10 @@ class Digit 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 - ClassDefNV(Digit, 4); + ClassDefNV(Digit, 5); }; std::ostream& operator<<(std::ostream& stream, const Digit& dig); diff --git a/Detectors/TOF/base/include/TOFBase/Strip.h b/Detectors/TOF/base/include/TOFBase/Strip.h index 3d23545552f34..f1152e25ab294 100644 --- a/Detectors/TOF/base/include/TOFBase/Strip.h +++ b/Detectors/TOF/base/include/TOFBase/Strip.h @@ -80,7 +80,7 @@ class Strip /// reset points container o2::tof::Digit* findDigit(ULong64_t key); - Int_t addDigit(Int_t channel, Int_t tdc, Int_t tot, uint64_t bc, Int_t lbl = 0, uint32_t triggerorbit = 0, uint16_t triggerbunch = 0); // returns the MC label + Int_t addDigit(Int_t channel, Int_t tdc, Int_t tot, uint64_t bc, Int_t lbl = 0, uint32_t triggerorbit = 0, uint16_t triggerbunch = 0, float geanttime = 0, double t0 = 0); // returns the MC label void fillOutputContainer(std::vector& digits); diff --git a/Detectors/TOF/base/src/Digit.cxx b/Detectors/TOF/base/src/Digit.cxx index ed58623877e8d..00f96a0007cec 100644 --- a/Detectors/TOF/base/src/Digit.cxx +++ b/Detectors/TOF/base/src/Digit.cxx @@ -17,14 +17,14 @@ using namespace o2::tof; ClassImp(o2::tof::Digit); -Digit::Digit(Int_t channel, Int_t tdc, Int_t tot, uint64_t bc, Int_t label, uint32_t triggerorbit, uint16_t triggerbunch) - : mChannel(channel), mTDC(tdc), mTOT(tot), mIR(0, 0), mLabel(label), mTriggerOrbit(triggerorbit), mTriggerBunch(triggerbunch), mIsUsedInCluster(kFALSE) +Digit::Digit(Int_t channel, Int_t tdc, Int_t tot, uint64_t bc, Int_t label, uint32_t triggerorbit, uint16_t triggerbunch, float geanttime, double t0) + : mChannel(channel), mTDC(tdc), mTOT(tot), mIR(0, 0), mLabel(label), mTriggerOrbit(triggerorbit), mTriggerBunch(triggerbunch), mIsUsedInCluster(kFALSE), mTgeant(geanttime), mT0true(t0) { mIR.setFromLong(bc); } //______________________________________________________________________ -Digit::Digit(Int_t channel, Int_t tdc, Int_t tot, uint32_t orbit, uint16_t bc, Int_t label, uint32_t triggerorbit, uint16_t triggerbunch) - : mChannel(channel), mTDC(tdc), mTOT(tot), mIR(bc, orbit), mLabel(label), mTriggerOrbit(triggerorbit), mTriggerBunch(triggerbunch), mIsUsedInCluster(kFALSE) +Digit::Digit(Int_t channel, Int_t tdc, Int_t tot, uint32_t orbit, uint16_t bc, Int_t label, uint32_t triggerorbit, uint16_t triggerbunch, float geanttime, double t0) + : mChannel(channel), mTDC(tdc), mTOT(tot), mIR(bc, orbit), mLabel(label), mTriggerOrbit(triggerorbit), mTriggerBunch(triggerbunch), mIsUsedInCluster(kFALSE), mTgeant(geanttime), mT0true(t0) { } //______________________________________________________________________ @@ -44,16 +44,18 @@ std::ostream& operator<<(std::ostream& stream, const Digit& digi) //______________________________________________________________________ -void Digit::merge(Int_t tdc, Int_t tot) +bool Digit::merge(Int_t tdc, Int_t tot) { // merging two digits if (tdc < mTDC) { mTDC = tdc; + return 1; // new came first // TODO: adjust TOT } else { // TODO: adjust TOT + return 0; } } diff --git a/Detectors/TOF/base/src/Strip.cxx b/Detectors/TOF/base/src/Strip.cxx index a008776c2690f..e72bd5183c78e 100644 --- a/Detectors/TOF/base/src/Strip.cxx +++ b/Detectors/TOF/base/src/Strip.cxx @@ -34,7 +34,7 @@ Strip::Strip(Int_t index) { } //_______________________________________________________________________ -Int_t Strip::addDigit(Int_t channel, Int_t tdc, Int_t tot, uint64_t bc, Int_t lbl, uint32_t triggerorbit, uint16_t triggerbunch) +Int_t Strip::addDigit(Int_t channel, Int_t tdc, Int_t tot, uint64_t bc, Int_t lbl, uint32_t triggerorbit, uint16_t triggerbunch, float geanttime, double t0) { // return the MC label. We pass it also as argument, but it can change in @@ -44,10 +44,13 @@ Int_t Strip::addDigit(Int_t channel, Int_t tdc, Int_t tot, uint64_t bc, Int_t lb auto dig = findDigit(key); if (dig) { lbl = dig->getLabel(); // getting the label from the already existing digit - dig->merge(tdc, tot); // merging to the existing digit + if (dig->merge(tdc, tot)) { // merging to the existing digit (if new came first upload also MC truth) + dig->setTgeant(geanttime); + dig->setT0true(t0); + } mDigitMerged++; } else { - mDigits.emplace(std::make_pair(key, Digit(channel, tdc, tot, bc, lbl, triggerorbit, triggerbunch))); + mDigits.emplace(std::make_pair(key, Digit(channel, tdc, tot, bc, lbl, triggerorbit, triggerbunch, geanttime, t0))); } return lbl; diff --git a/Detectors/TOF/reconstruction/src/Clusterer.cxx b/Detectors/TOF/reconstruction/src/Clusterer.cxx index 47dcbd805b162..0b393bfd45e78 100644 --- a/Detectors/TOF/reconstruction/src/Clusterer.cxx +++ b/Detectors/TOF/reconstruction/src/Clusterer.cxx @@ -173,6 +173,8 @@ void Clusterer::buildCluster(Cluster& c, MCLabelContainer const* digitMCTruth) } c.setMainContributingChannel(mContributingDigit[0]->getChannel()); + c.setTgeant(mContributingDigit[0]->getTgeant()); + c.setT0true(mContributingDigit[0]->getT0true()); c.setTime(mContributingDigit[0]->getCalibratedTime()); // time in ps (for now we assume it calibrated) c.setTimeRaw(mContributingDigit[0]->getTDC() * Geo::TDCBIN + mContributingDigit[0]->getBC() * o2::constants::lhc::LHCBunchSpacingNS * 1E3); // time in ps (for now we assume it calibrated) diff --git a/Detectors/TOF/simulation/include/TOFSimulation/Digitizer.h b/Detectors/TOF/simulation/include/TOFSimulation/Digitizer.h index 15a71b9e57c1f..5153f168f176f 100644 --- a/Detectors/TOF/simulation/include/TOFSimulation/Digitizer.h +++ b/Detectors/TOF/simulation/include/TOFSimulation/Digitizer.h @@ -135,11 +135,11 @@ class Digitizer : public WindowFiller CalibApi* mCalibApi = nullptr; //! calib api to handle the TOF calibration - void fillDigitsInStrip(std::vector* strips, o2::dataformats::MCTruthContainer* mcTruthContainer, int channel, int tdc, int tot, uint64_t nbc, UInt_t istrip, Int_t trackID, Int_t eventID, Int_t sourceID); + void fillDigitsInStrip(std::vector* strips, o2::dataformats::MCTruthContainer* mcTruthContainer, int channel, int tdc, int tot, uint64_t nbc, UInt_t istrip, Int_t trackID, Int_t eventID, Int_t sourceID, float geanttime = 0, double t0 = 0.0); Int_t processHit(const HitType& hit, Double_t event_time); void addDigit(Int_t channel, UInt_t istrip, Double_t time, Float_t x, Float_t z, Float_t charge, Int_t iX, Int_t iZ, Int_t padZfired, - Int_t trackID); + Int_t trackID, float geanttime = 0, double t0 = 0.0); void checkIfReuseFutureDigits(); diff --git a/Detectors/TOF/simulation/src/Digitizer.cxx b/Detectors/TOF/simulation/src/Digitizer.cxx index 50ea2c194616c..ec899bd35fbff 100644 --- a/Detectors/TOF/simulation/src/Digitizer.cxx +++ b/Detectors/TOF/simulation/src/Digitizer.cxx @@ -170,7 +170,7 @@ Int_t Digitizer::processHit(const HitType& hit, Double_t event_time) Float_t charge = getCharge(hit.GetEnergyLoss()); // NOTE: FROM NOW ON THE TIME IS IN PS ... AND NOT IN NS - Double_t time = getShowerTimeSmeared((double(hit.GetTime()) + event_time) * 1E3, charge); + Double_t time = getShowerTimeSmeared((double(hit.GetTime()) + event_time) * 1E3 + 0.5 * Geo::TDCBIN, charge); Float_t xLocal = deltapos[0]; Float_t zLocal = deltapos[2]; @@ -192,7 +192,7 @@ Int_t Digitizer::processHit(const HitType& hit, Double_t event_time) ndigits++; mXLastShift[mNLastHit] = 0; mZLastShift[mNLastHit] = 0; - addDigit(channel, istrip, time, xLocal, zLocal, charge, 0, 0, detInd[3], trackID); + addDigit(channel, istrip, time, xLocal, zLocal, charge, 0, 0, detInd[3], trackID, hit.GetTime(), event_time * 1E3); } // check PAD 2 @@ -209,7 +209,7 @@ Int_t Digitizer::processHit(const HitType& hit, Double_t event_time) ndigits++; mXLastShift[mNLastHit] = 0; mZLastShift[mNLastHit] = iZshift; - addDigit(channel, istrip, time, xLocal, zLocal, charge, 0, iZshift, detInd[3], trackID); + addDigit(channel, istrip, time, xLocal, zLocal, charge, 0, iZshift, detInd[3], trackID, hit.GetTime(), event_time * 1E3); } // check PAD 3 @@ -223,7 +223,7 @@ Int_t Digitizer::processHit(const HitType& hit, Double_t event_time) ndigits++; mXLastShift[mNLastHit] = -1; mZLastShift[mNLastHit] = 0; - addDigit(channel, istrip, time, xLocal, zLocal, charge, -1, 0, detInd[3], trackID); + addDigit(channel, istrip, time, xLocal, zLocal, charge, -1, 0, detInd[3], trackID, hit.GetTime(), event_time * 1E3); } } @@ -238,7 +238,7 @@ Int_t Digitizer::processHit(const HitType& hit, Double_t event_time) ndigits++; mXLastShift[mNLastHit] = 1; mZLastShift[mNLastHit] = 0; - addDigit(channel, istrip, time, xLocal, zLocal, charge, 1, 0, detInd[3], trackID); + addDigit(channel, istrip, time, xLocal, zLocal, charge, 1, 0, detInd[3], trackID, hit.GetTime(), event_time * 1E3); } } @@ -257,7 +257,7 @@ Int_t Digitizer::processHit(const HitType& hit, Double_t event_time) ndigits++; mXLastShift[mNLastHit] = -1; mZLastShift[mNLastHit] = iZshift; - addDigit(channel, istrip, time, xLocal, zLocal, charge, -1, iZshift, detInd[3], trackID); + addDigit(channel, istrip, time, xLocal, zLocal, charge, -1, iZshift, detInd[3], trackID, hit.GetTime(), event_time * 1E3); } } @@ -276,7 +276,7 @@ Int_t Digitizer::processHit(const HitType& hit, Double_t event_time) ndigits++; mXLastShift[mNLastHit] = 1; mZLastShift[mNLastHit] = iZshift; - addDigit(channel, istrip, time, xLocal, zLocal, charge, 1, iZshift, detInd[3], trackID); + addDigit(channel, istrip, time, xLocal, zLocal, charge, 1, iZshift, detInd[3], trackID, hit.GetTime(), event_time * 1E3); } } return ndigits; @@ -284,7 +284,7 @@ Int_t Digitizer::processHit(const HitType& hit, Double_t event_time) //______________________________________________________________________ void Digitizer::addDigit(Int_t channel, UInt_t istrip, Double_t time, Float_t x, Float_t z, Float_t charge, Int_t iX, Int_t iZ, - Int_t padZfired, Int_t trackID) + Int_t padZfired, Int_t trackID, float geanttime, double t0) { // TOF digit requires: channel, time and time-over-threshold @@ -297,10 +297,11 @@ void Digitizer::addDigit(Int_t channel, UInt_t istrip, Double_t time, Float_t x, charge *= getFractionOfCharge(x, z); // tot tuned to reproduce 0.8% of orphans tot(=0) - Float_t tot = gRandom->Gaus(12., 1.5); // time-over-threshold - if (tot < 8.4) { - tot = 0; + Float_t totf = gRandom->Gaus(12. * Geo::NTOTBIN_PER_NS, 1.5 * Geo::NTOTBIN_PER_NS); // time-over-threshold + if (totf < 172) { + totf = 0; } + int tot = int(totf); Float_t xborder = Geo::XPAD * 0.5 - std::abs(x); Float_t zborder = Geo::ZPAD * 0.5 - std::abs(z); @@ -309,7 +310,7 @@ void Digitizer::addDigit(Int_t channel, UInt_t istrip, Double_t time, Float_t x, Float_t timewalkX = x * mTimeWalkeSlope; Float_t timewalkZ = (z - (padZfired - 0.5) * Geo::ZPAD) * mTimeWalkeSlope; - if (border < 0) { // keep the effect onlu if hit out of pad + if (border < 0) { // keep the effect only if hit out of pad border *= -1; Float_t extraTimeSmear = border * mTimeSlope; time += gRandom->Gaus(mTimeDelay, extraTimeSmear); @@ -325,7 +326,7 @@ void Digitizer::addDigit(Int_t channel, UInt_t istrip, Double_t time, Float_t x, time += TMath::Sqrt(timewalkX * timewalkX + timewalkZ * timewalkZ) - mTimeDelayCorr - mTimeWalkeSlope * 2; // Decalibrate - float tsCorr = mCalibApi->getTimeDecalibration(channel, tot); + float tsCorr = mCalibApi->getTimeDecalibration(channel, tot * Geo::TOTBIN_NS); if (std::abs(tsCorr) > 200E3) { // accept correction up to 200 ns LOG(error) << "Wrong de-calibration correction for ch = " << channel << ", tot = " << tot << " (Skip it)"; return; @@ -344,8 +345,10 @@ void Digitizer::addDigit(Int_t channel, UInt_t istrip, Double_t time, Float_t x, int tdc = int((time - Geo::BC_TIME_INPS * nbc) * Geo::NTDCBIN_PER_PS); + static long firstlongbc = long(o2::raw::HBFUtils::Instance().orbitFirstSampled) * o2::constants::lhc::LHCMaxBunches; // add orbit and bc nbc += mEventTime.toLong(); + t0 += (mEventTime.toLong() - firstlongbc - Geo::LATENCYWINDOW_IN_BC) * Geo::BC_TIME_INPS; // printf("orbit = %d -- bc = %d -- nbc = (%d) %d\n",mEventTime.orbit,mEventTime.bc, mEventTime.toLong(),nbc); @@ -386,7 +389,7 @@ void Digitizer::addDigit(Int_t channel, UInt_t istrip, Double_t time, Float_t x, mFutureItrackID.push_back(trackID); // fill temporary digits array - insertDigitInFuture(channel, tdc, tot * Geo::NTOTBIN_PER_NS, nbc, lblCurrent); + insertDigitInFuture(channel, tdc, tot, nbc, lblCurrent); return; // don't fill if doesn't match any available readout window } else if (isIfOverlap == MAXWINDOWS) { // add in future digits but also in one of the current readout windows (beacuse of windows overlap) lblCurrent = mFutureIevent.size(); @@ -395,7 +398,7 @@ void Digitizer::addDigit(Int_t channel, UInt_t istrip, Double_t time, Float_t x, mFutureItrackID.push_back(trackID); // fill temporary digits array - insertDigitInFuture(channel, tdc, tot * Geo::NTOTBIN_PER_NS, nbc, lblCurrent); + insertDigitInFuture(channel, tdc, tot, nbc, lblCurrent); } if (isnext) { @@ -416,7 +419,7 @@ void Digitizer::addDigit(Int_t channel, UInt_t istrip, Double_t time, Float_t x, mcTruthContainer = mMCTruthContainerNext[isnext - 1]; } - fillDigitsInStrip(strips, mcTruthContainer, channel, tdc, tot, nbc, istrip, trackID, mEventID, mSrcID); + fillDigitsInStrip(strips, mcTruthContainer, channel, tdc, tot, nbc, istrip, trackID, mEventID, mSrcID, geanttime, t0); if (isIfOverlap > -1 && isIfOverlap < MAXWINDOWS) { // fill also a second readout window because of the overlap if (!isIfOverlap) { @@ -427,18 +430,18 @@ void Digitizer::addDigit(Int_t channel, UInt_t istrip, Double_t time, Float_t x, mcTruthContainer = mMCTruthContainerNext[isIfOverlap - 1]; } - fillDigitsInStrip(strips, mcTruthContainer, channel, tdc, tot, nbc, istrip, trackID, mEventID, mSrcID); + fillDigitsInStrip(strips, mcTruthContainer, channel, tdc, tot, nbc, istrip, trackID, mEventID, mSrcID, geanttime, t0); } } //______________________________________________________________________ -void Digitizer::fillDigitsInStrip(std::vector* strips, o2::dataformats::MCTruthContainer* mcTruthContainer, int channel, int tdc, int tot, uint64_t nbc, UInt_t istrip, Int_t trackID, Int_t eventID, Int_t sourceID) +void Digitizer::fillDigitsInStrip(std::vector* strips, o2::dataformats::MCTruthContainer* mcTruthContainer, int channel, int tdc, int tot, uint64_t nbc, UInt_t istrip, Int_t trackID, Int_t eventID, Int_t sourceID, float geanttime, double t0) { int lblCurrent; if (mcTruthContainer) { lblCurrent = mcTruthContainer->getIndexedSize(); // this is the size of mHeaderArray; } - Int_t lbl = (*strips)[istrip].addDigit(channel, tdc, tot * Geo::NTOTBIN_PER_NS, nbc, lblCurrent); + Int_t lbl = (*strips)[istrip].addDigit(channel, tdc, tot, nbc, lblCurrent, 0, 0, geanttime, t0); if (mcTruthContainer) { if (lbl == lblCurrent) { // it means that the digit was a new one --> we have to add the info in the MC container @@ -1099,7 +1102,7 @@ void Digitizer::checkIfReuseFutureDigits() int trackID = mFutureItrackID[digit->getLabel()]; int sourceID = mFutureIsource[digit->getLabel()]; int eventID = mFutureIevent[digit->getLabel()]; - fillDigitsInStrip(strips, mcTruthContainer, digit->getChannel(), digit->getTDC(), digit->getTOT(), digit->getBC(), digit->getChannel() / Geo::NPADS, trackID, eventID, sourceID); + fillDigitsInStrip(strips, mcTruthContainer, digit->getChannel(), digit->getTDC(), digit->getTOT(), digit->getBC(), digit->getChannel() / Geo::NPADS, trackID, eventID, sourceID, digit->getTgeant()); if (isIfOverlap < 0) { // if there is no overlap candidate // remove digit from array in the future From c68ddc8a0e4e313bdbd21c79b214e6f4c1ef9ad2 Mon Sep 17 00:00:00 2001 From: Marco Giacalone Date: Sun, 22 Dec 2024 15:35:10 +0100 Subject: [PATCH 0016/1992] Apply encoding to boxgen particles --- Generators/include/Generators/BoxGenerator.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Generators/include/Generators/BoxGenerator.h b/Generators/include/Generators/BoxGenerator.h index e24694296a70f..e109bcf90ebf8 100644 --- a/Generators/include/Generators/BoxGenerator.h +++ b/Generators/include/Generators/BoxGenerator.h @@ -19,6 +19,8 @@ #include #include #include "SimulationDataFormat/MCEventHeader.h" +#include "SimulationDataFormat/ParticleStatus.h" +#include namespace o2::eventgen { @@ -90,6 +92,14 @@ class BoxGenerator : public Generator { mParticles.clear(); std::copy(mEvent.begin(), mEvent.end(), std::back_insert_iterator(mParticles)); + for (auto& particle : mParticles) { + auto statusCode = particle.GetStatusCode(); + if (!mcgenstatus::isEncoded(statusCode)) { + particle.SetStatusCode(mcgenstatus::MCGenStatusEncoding(statusCode, 0).fullEncoding); + } + // Set the transport bit according to the HepMC status code + particle.SetBit(ParticleStatus::kToBeDone, mcgenstatus::getHepMCStatusCode(particle.GetStatusCode()) == 1); + } return true; } From 9ede2d59a03c7c159af187e15b3f30001e27879f Mon Sep 17 00:00:00 2001 From: yuanzhe Date: Fri, 20 Dec 2024 12:24:05 +0100 Subject: [PATCH 0017/1992] Fix the decay branch ratio of antihyperhelium4sigma --- Steer/src/O2MCApplication.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Steer/src/O2MCApplication.cxx b/Steer/src/O2MCApplication.cxx index 02d332b0c0641..e1bba03e81c50 100644 --- a/Steer/src/O2MCApplication.cxx +++ b/Steer/src/O2MCApplication.cxx @@ -902,14 +902,14 @@ void addSpecialParticles() amode4s[kz][1] = 0; amode4s[kz][2] = 0; } - abratio4s[0] = 50.; + abratio4s[0] = 20.; amode4s[0][0] = -1000020040; // anti-Helium4 amode4s[0][1] = 111; // pion0 - abratio4s[1] = 50.; + abratio4s[1] = 40.; amode4s[1][0] = -1000010030; // anti-tritium amode4s[1][2] = -2212; // anti-proton amode4s[1][1] = 111; // pion0 - abratio4s[2] = 50.; + abratio4s[2] = 40.; amode4s[2][0] = -1000010030; // anti-tritium amode4s[2][2] = -211; // pion- amode4s[2][1] = -2112; // anti-neutron From 4a1f6f87243b2f60f4c07af248640c7e994b8465 Mon Sep 17 00:00:00 2001 From: Anton Alkin Date: Mon, 6 Jan 2025 10:57:33 +0100 Subject: [PATCH 0018/1992] DPL Analysis: out-of-line throws --- Framework/Core/include/Framework/ASoA.h | 7 ++++-- .../Core/include/Framework/ASoAHelpers.h | 7 +++--- .../include/Framework/IndexBuilderHelpers.h | 5 +++-- Framework/Core/src/ASoA.cxx | 10 +++++++++ Framework/Core/src/ASoAHelpers.cxx | 22 +++++++++++++++++++ Framework/Core/src/IndexBuilderHelpers.cxx | 6 +++++ 6 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 Framework/Core/src/ASoAHelpers.cxx diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index 6894eda42dccf..7b0b69ec8941f 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -2126,6 +2126,9 @@ class Table template using InPlaceTable = Table, o2::aod::Hash, o2::aod::Hash<"TEST"_h>, C...>; +void getterNotFound(const char* targetColumnLabel); +void emptyColumnLabel(); + namespace row_helpers { template @@ -2232,7 +2235,7 @@ ColumnGetterFunction getColumnGetterByLabel(o2::framework::pack, co (void)((func = createGetterPtr(targetColumnLabel), func) || ...); if (!func) { - throw framework::runtime_error_f("Getter for \"%s\" not found", targetColumnLabel); + getterNotFound(targetColumnLabel.data()); } return func; @@ -2248,7 +2251,7 @@ ColumnGetterFunction getColumnGetterByLabel(const std:: using TypesWithCommonGetter = o2::framework::selected_pack_multicondition, typename T::columns_t>; if (targetColumnLabel.size() == 0) { - throw framework::runtime_error("columnLabel: must not be empty"); + emptyColumnLabel(); } return getColumnGetterByLabel(TypesWithCommonGetter{}, targetColumnLabel); diff --git a/Framework/Core/include/Framework/ASoAHelpers.h b/Framework/Core/include/Framework/ASoAHelpers.h index 6de6662769ef7..5bf474e61f935 100644 --- a/Framework/Core/include/Framework/ASoAHelpers.h +++ b/Framework/Core/include/Framework/ASoAHelpers.h @@ -14,7 +14,6 @@ #include "Framework/ASoA.h" #include "Framework/BinningPolicy.h" -#include "Framework/RuntimeError.h" #include #include @@ -72,6 +71,8 @@ inline bool diffCategory(BinningIndex const& a, BinningIndex const& b) return a.bin >= b.bin; } +void dataSizeVariesBetweenColumns(); + template