diff --git a/Detectors/TPC/base/include/TPCBase/ParameterElectronics.h b/Detectors/TPC/base/include/TPCBase/ParameterElectronics.h index 8ada729f36103..10a4b5027bdcd 100644 --- a/Detectors/TPC/base/include/TPCBase/ParameterElectronics.h +++ b/Detectors/TPC/base/include/TPCBase/ParameterElectronics.h @@ -48,6 +48,7 @@ struct ParameterElectronics : public o2::conf::ConfigurableParamHelper mTimeBins; ///< Time bin Container for the ADC value - std::unique_ptr mPrevDigArr; ///< Keep track of ToT and ion tail cumul from last time bin - o2::utils::DebugStreamer mStreamer; ///< Debug streamer - const CalPad* mPadParams[3] = {nullptr, nullptr, nullptr}; //!< Ion tail fraction, ion tail slope and common mode k-values per pad - const CalDet* mDeadMap = nullptr; //!< Dead channel map - bool mCMCEnabled = false; //!< Common mode correction enabled in the FEE config (DigiMode Auto) - bool mCalibrationsUpdated = false; //!< Whether updateCalibrations was called - SAMPAProcessing* mSAMPAProcessing = nullptr; //!< SAMPAProcessing used for the output, the singleton if not set - std::vector> mLabelCollector; //!< Workspace to sort the MC labels of a digit + TimeBin mFirstTimeBin = 0; ///< First time bin to consider + TimeBin mEffectiveTimeBin = 0; ///< Effective time bin of that digit + TimeBin mTmaxTriggered = 0; ///< Maximum time bin in case of triggered mode (hard cut at average drift speed with additional margin) + TimeBin mOffset; ///< Size of the container for one event + std::deque mTimeBins; ///< Time bin Container for the ADC value + std::unique_ptr mPrevDigArr; ///< Keep track of ToT and ion tail cumul from last time bin + o2::utils::DebugStreamer mStreamer; ///< Debug streamer + const CalPad* mPadParams[4] = {nullptr, nullptr, nullptr, nullptr}; //!< Ion tail fraction, ion tail slope, common mode k-values and pedestals per pad + const CalDet* mDeadMap = nullptr; //!< Dead channel map + bool mCMCEnabled = false; //!< Common mode correction enabled in the FEE config (DigiMode Auto) + bool mCalibrationsUpdated = false; //!< Whether updateCalibrations was called + SAMPAProcessing* mSAMPAProcessing = nullptr; //!< SAMPAProcessing used for the output, the singleton if not set + std::vector> mLabelCollector; //!< Workspace to sort the MC labels of a digit void reportSettings(); }; diff --git a/Detectors/TPC/simulation/include/TPCSimulation/DigitGlobalPad.h b/Detectors/TPC/simulation/include/TPCSimulation/DigitGlobalPad.h index 6c08abbfca799..2b73caa43ba81 100644 --- a/Detectors/TPC/simulation/include/TPCSimulation/DigitGlobalPad.h +++ b/Detectors/TPC/simulation/include/TPCSimulation/DigitGlobalPad.h @@ -80,7 +80,7 @@ class DigitGlobalPad o2::dataformats::LabelContainer, false>&); /// Fold signal with previous pad signal add ion tail and ToT for sigmal saturation - void foldSignal(PrevDigitInfo& prevDigit, const int sector, const int pad, const TimeBin time, Streamer* debugStream = nullptr, const CalPad* padParams[3] = nullptr); + void foldSignal(PrevDigitInfo& prevDigit, const int sector, const int pad, const TimeBin time, Streamer* debugStream = nullptr, const CalPad* padParams[4] = nullptr); void setID(int id) { mID = id; } int getID() const { return mID; } @@ -132,7 +132,7 @@ inline void DigitGlobalPad::addDigit(const MCCompLabel& label, float signal, mChargePad += signal; } -inline void DigitGlobalPad::foldSignal(PrevDigitInfo& prevDigit, const int sector, const int pad, const TimeBin time, Streamer* debugStream, const CalPad* padParams[3]) +inline void DigitGlobalPad::foldSignal(PrevDigitInfo& prevDigit, const int sector, const int pad, const TimeBin time, Streamer* debugStream, const CalPad* padParams[4]) { const auto& eleParam = ParameterElectronics::Instance(); const auto& itSettings = IonTailSettings::Instance(); diff --git a/Detectors/TPC/simulation/include/TPCSimulation/DigitTime.h b/Detectors/TPC/simulation/include/TPCSimulation/DigitTime.h index 48a84b4fea004..aa4fee1ee74a8 100644 --- a/Detectors/TPC/simulation/include/TPCSimulation/DigitTime.h +++ b/Detectors/TPC/simulation/include/TPCSimulation/DigitTime.h @@ -80,7 +80,7 @@ class DigitTime std::vector& commonModeOutput, const Sector& sector, TimeBin timeBin, SAMPAProcessing& sampaProcessing, std::vector>& labelCollector, PrevDigitInfoArray* prevTime = nullptr, Streamer* debugStream = nullptr, - const CalPad* padParams[3] = nullptr, const CalDet* deadMap = nullptr); + const CalPad* padParams[4] = nullptr, const CalDet* deadMap = nullptr); private: std::array mCommonMode; ///< Common mode container - 4 GEM ROCs per sector @@ -131,7 +131,7 @@ template inline void DigitTime::fillOutputContainer(std::vector& output, dataformats::MCTruthContainer& mcTruth, std::vector& commonModeOutput, const Sector& sector, TimeBin timeBin, SAMPAProcessing& sampaProcessing, std::vector>& labelCollector, - PrevDigitInfoArray* prevTime, Streamer* debugStream, const CalPad* padParams[3], + PrevDigitInfoArray* prevTime, Streamer* debugStream, const CalPad* padParams[4], const CalDet* deadMap) { const auto& mapper = Mapper::instance(); @@ -153,23 +153,33 @@ inline void DigitTime::fillOutputContainer(std::vector& output, dataforma mCommonMode[cru.gemStack()] += digit.getChargePad() * eleParam.commonModeCoupling * cmKValue; // TODO: Add stack-by-stack variation? } - // fill common mode output container - for (size_t i = 0; i < mCommonMode.size(); ++i) { - const float cm = getCommonMode(GEMstack(i)); - if (cm > 0.) { - commonModeOutput.push_back({cm, timeBin, static_cast(i)}); - } - } + // the common mode is induced on all pads of the GEM stack, but the baseline of a pad can at most drop to 0 ADC, + // so the common mode seen by a pad saturates at its pedestal value + const CalPad* pedestals = eleParam.doCommonModePerPadSaturation ? padParams[3] : nullptr; + std::array commonModeSeen{}; // double: sum of ~3000 values per stack for (size_t iPad = 0; iPad < mGlobalPads.size(); ++iPad) { auto& digit = mGlobalPads[iPad]; + const CRU cru = mapper.getCRU(sector, iPad); + float commonMode = getCommonMode(cru); + if (pedestals) { + commonMode = std::min(commonMode, pedestals->getValue(sector.getSector(), iPad)); + commonModeSeen[cru.gemStack()] += commonMode; + } if (eleParam.doNoiseEmptyPads || (digit.getChargePad() > 0.f)) { PrevDigitInfo prevDigit; if (prevTime) { prevDigit = (*prevTime)[iPad]; } - const CRU cru = mapper.getCRU(sector, iPad); - digit.fillOutputContainer(output, mcTruth, cru, timeBin, iPad, mLabels, sampaProcessing, labelCollector, getCommonMode(cru), prevDigit, debugStream, deadMap); + digit.fillOutputContainer(output, mcTruth, cru, timeBin, iPad, mLabels, sampaProcessing, labelCollector, commonMode, prevDigit, debugStream, deadMap); + } + } + + // fill common mode output container, with saturation the average common mode seen by the pads of the GEM stack + for (size_t i = 0; i < mCommonMode.size(); ++i) { + const float cm = pedestals ? static_cast(commonModeSeen[i] / mapper.getNumberOfPads(GEMstack(i))) : getCommonMode(GEMstack(i)); + if (cm > 0.) { + commonModeOutput.push_back({cm, timeBin, static_cast(i)}); } } } diff --git a/Detectors/TPC/simulation/src/DigitContainer.cxx b/Detectors/TPC/simulation/src/DigitContainer.cxx index cb41bf9631500..1ab4e2885cdcd 100644 --- a/Detectors/TPC/simulation/src/DigitContainer.cxx +++ b/Detectors/TPC/simulation/src/DigitContainer.cxx @@ -160,6 +160,9 @@ void DigitContainer::updateCalibrations() mPadParams[2] = &cdb.getCMkValues(); } + // pedestals for the common mode saturation per pad + mPadParams[3] = eleParam.doCommonModePerPadSaturation ? &cdb.getPedestals() : nullptr; + // dead channel map mDeadMap = eleParam.applyDeadMap ? &cdb.getDeadChannelMap() : nullptr; @@ -174,7 +177,7 @@ void DigitContainer::reportSettings() auto& cdb = CDBInterface::instance(); const auto& eleParam = ParameterElectronics::Instance(); const auto& feeConfig = cdb.getFEEConfig(); - LOGP(info, "ParameterElectronics: doIonTail={}, doIonTailPerPad={}, doCommonModePerPad={}, doSaturationTail={}, doNoiseEmptyPads={}, applyDeadMap={}, commonModeCoupling={}, DigiMode={}", - eleParam.doIonTail, eleParam.doIonTailPerPad, eleParam.doCommonModePerPad, eleParam.doSaturationTail, eleParam.doNoiseEmptyPads, eleParam.applyDeadMap, eleParam.commonModeCoupling, (int)eleParam.DigiMode); + LOGP(info, "ParameterElectronics: doIonTail={}, doIonTailPerPad={}, doCommonModePerPad={}, doCommonModePerPadSaturation={}, doSaturationTail={}, doNoiseEmptyPads={}, applyDeadMap={}, commonModeCoupling={}, DigiMode={}", + eleParam.doIonTail, eleParam.doIonTailPerPad, eleParam.doCommonModePerPad, eleParam.doCommonModePerPadSaturation, eleParam.doSaturationTail, eleParam.doNoiseEmptyPads, eleParam.applyDeadMap, eleParam.commonModeCoupling, (int)eleParam.DigiMode); feeConfig.printShort(); }