From 9ffc1b6e1259acc058dc29b3751640c359f74b70 Mon Sep 17 00:00:00 2001 From: Gauthier Legras Date: Mon, 9 Nov 2026 13:47:03 +0100 Subject: [PATCH 1/3] TRD: additional pile-up selections --- Detectors/TRD/calibration/CMakeLists.txt | 3 +- .../TRDCalibration/CalibrationParams.h | 1 + .../include/TRDCalibration/PulseHeight.h | 5 +++ Detectors/TRD/calibration/src/PulseHeight.cxx | 41 ++++++++++++++++--- .../include/TRDWorkflow/TRDPulseHeightSpec.h | 6 ++- 5 files changed, 48 insertions(+), 8 deletions(-) diff --git a/Detectors/TRD/calibration/CMakeLists.txt b/Detectors/TRD/calibration/CMakeLists.txt index 52444d2855b1f..73affa8f20b66 100644 --- a/Detectors/TRD/calibration/CMakeLists.txt +++ b/Detectors/TRD/calibration/CMakeLists.txt @@ -29,7 +29,8 @@ o2_add_library(TRDCalibration O2::DetectorsCalibration O2::MathUtils O2::GPUTracking - O2::DetectorsDCS) + O2::DetectorsDCS + O2::FT0Reconstruction) o2_target_root_dictionary(TRDCalibration HEADERS include/TRDCalibration/TrackBasedCalib.h diff --git a/Detectors/TRD/calibration/include/TRDCalibration/CalibrationParams.h b/Detectors/TRD/calibration/include/TRDCalibration/CalibrationParams.h index 48dfb0c953911..c159ad763c890 100644 --- a/Detectors/TRD/calibration/include/TRDCalibration/CalibrationParams.h +++ b/Detectors/TRD/calibration/include/TRDCalibration/CalibrationParams.h @@ -48,6 +48,7 @@ struct TRDCalibParams : public o2::conf::ConfigurableParamHelper // Creation of PH plots float pileupCut = 0.7; + int digitsThreshold = 13; // parameters related to noise calibration size_t minNumberOfDigits = 1'000'000'000UL; ///< when reached, noise calibration will be finalized diff --git a/Detectors/TRD/calibration/include/TRDCalibration/PulseHeight.h b/Detectors/TRD/calibration/include/TRDCalibration/PulseHeight.h index 52305cc585b34..406a8e11238c3 100644 --- a/Detectors/TRD/calibration/include/TRDCalibration/PulseHeight.h +++ b/Detectors/TRD/calibration/include/TRDCalibration/PulseHeight.h @@ -22,6 +22,8 @@ #include "DataFormatsTRD/TrackTriggerRecord.h" #include "DataFormatsTRD/PHData.h" #include "TRDCalibration/CalibrationParams.h" +#include "DataFormatsFT0/RecPoints.h" +#include "ReconstructionDataFormats/GlobalTrackID.h" #include "TFile.h" #include "TTree.h" @@ -52,6 +54,7 @@ class PulseHeight void reset(); void setApplyShift(bool f) { mApplyShift = f; } + void setTrkMask(o2::dataformats::GlobalTrackID::mask_t trkMask) { mTrkMask = trkMask;} /// Main processing function void process(); @@ -75,6 +78,8 @@ class PulseHeight gsl::span mTriggerRecords; ///< array of trigger records gsl::span mTrackTriggerRecordsTPCTRD; ///< array of track trigger records gsl::span mTrackTriggerRecordsITSTPCTRD; ///< array of track trigger records + gsl::span mFT0RecPoints; ///< array of FT0 rec points + o2::dataformats::GlobalTrackID::mask_t mTrkMask; ///< seeding track sources (TPC, ITS-TPC, FT0) // output std::vector mPHValues, *mPHValuesPtr{&mPHValues}; ///< vector of values used to fill the PH spectra per detector diff --git a/Detectors/TRD/calibration/src/PulseHeight.cxx b/Detectors/TRD/calibration/src/PulseHeight.cxx index 44446d40df438..beb6c928e6cbd 100644 --- a/Detectors/TRD/calibration/src/PulseHeight.cxx +++ b/Detectors/TRD/calibration/src/PulseHeight.cxx @@ -15,6 +15,7 @@ #include "TRDCalibration/PulseHeight.h" #include "DataFormatsTRD/Constants.h" #include "DataFormatsGlobalTracking/RecoContainer.h" +#include "FT0Reconstruction/InteractionTag.h" #include using namespace o2::trd; @@ -71,6 +72,9 @@ void PulseHeight::setInput(const o2::globaltracking::RecoContainer& input, gsl:: mTriggerRecords = input.getTRDTriggerRecords(); mTrackTriggerRecordsTPCTRD = input.getTPCTRDTriggers(); mTrackTriggerRecordsITSTPCTRD = input.getITSTPCTRDTriggers(); + if (mTrkMask[o2::dataformats::GlobalTrackID::FT0]) { + mFT0RecPoints = input.getFT0RecPoints(); + } mDigits = digits; } @@ -83,6 +87,9 @@ void PulseHeight::process() } size_t nTrkTrig[2] = {mTrackTriggerRecordsITSTPCTRD.size(), mTrackTriggerRecordsTPCTRD.size()}; int lastTrkTrig[2] = {0}; + + int currentFT0[2] = {0}; + for (const auto& trig : mTriggerRecords) { if (trig.getNumberOfDigits() == 0) { continue; @@ -103,10 +110,26 @@ void PulseHeight::process() ++lastTrkTrig[iTrackType]; continue; } - if ((*tracks)[trigTrack.getFirstTrack()].hasPileUpInfo() && (*tracks)[trigTrack.getFirstTrack()].getPileUpTimeShiftMUS() < mParams.pileupCut) { - // rejecting triggers which are close to other collisions (avoid pile-up) + // find closest interacting bc after the trigger record + uint8_t nClosestBC = 0; + if (mTrkMask[o2::dataformats::GlobalTrackID::FT0]) { + for (size_t ft0id = currentFT0[iTrackType]; ft0id < mFT0RecPoints.size(); ft0id++) { + const auto& f0rec = mFT0RecPoints[ft0id]; + if (o2::ft0::InteractionTag::Instance().isSelected(f0rec)) { + int64_t bcdiff = f0rec.getInteractionRecord().differenceInBC(trigTrack.getBCData()); + if (bcdiff > 0) { + nClosestBC = bcdiff; + currentFT0[iTrackType] = ft0id; + break; + } + } + } + } + if (((*tracks)[trigTrack.getFirstTrack()].getPileUpDistanceBwd() > 0) || ((!mTrkMask[o2::dataformats::GlobalTrackID::FT0] || mFT0RecPoints.size() == 0) && (*tracks)[trigTrack.getFirstTrack()].getPileUpTimeShiftMUS() < mParams.pileupCut) || (nClosestBC > 0 && nClosestBC * o2::constants::lhc::LHCBunchSpacingMUS < mParams.pileupCut)) { + // rejecting triggers with a collision closely after (needs the full colliding BC history because track only keeps the furthest BC within window) + // or with a collision before (avoid pile-up) ++lastTrkTrig[iTrackType]; - LOGP(debug, "Rececting trigger due to pileup of {}", (*tracks)[trigTrack.getFirstTrack()].getPileUpTimeShiftMUS()); + LOGP(debug, "Rejecting trigger due to pileup of {}", (*tracks)[trigTrack.getFirstTrack()].getPileUpTimeShiftMUS()); break; } for (int iTrk = trigTrack.getFirstTrack(); iTrk < trigTrack.getFirstTrack() + trigTrack.getNumberOfTracks(); iTrk++) { @@ -133,11 +156,11 @@ void PulseHeight::findDigitsForTracklet(const Tracklet64& trklt, const TriggerRe int iDigitFirst = trig.getFirstDigit(); int iDigitLast = trig.getFirstDigit() + trig.getNumberOfDigits(); for (int iDigit = iDigitFirst + 1; iDigit < iDigitLast - 1; ++iDigit) { - const auto& digit = (*mDigits)[iDigit]; + const auto& digit = (*mDigits)[iDigit]; if (digit.isSharedDigit()) { continue; // avoid double-counting of the same digit } - if (digit.getDetector() != trkltDet || digit.getPadRow() != trklt.getPadRow() || digit.getPadCol() != trklt.getPadCol(mApplyShift)) { + if (digit.getDetector() != trkltDet || digit.getPadRow() != trklt.getPadRow() || digit.getPadCol() != trklt.getPadCol(false)) { // for now we loose charge information from padrow-crossing tracklets (~15% of all tracklets) continue; } @@ -167,6 +190,14 @@ void PulseHeight::findDigitsForTracklet(const Tracklet64& trklt, const TriggerRe right = true; } if (nNeighbours > 0) { + // pile-up removal: if we have several consecutive digits with very small value for the first time bins, this is likely to come from pile-up + int nOverThreshold = 0; + for (int iTb = 0; iTb < ((int) (mParams.pileupCut * 10)); iTb++) { + if (digit.getADC()[iTb] > mParams.digitsThreshold) nOverThreshold++; + } + if (nOverThreshold <= 2) { + continue; + } int digitTrackletDistance = 0; auto adcSumMax = digit.getADCsum(); if (left && digitLeft->getADCsum() > adcSumMax) { diff --git a/Detectors/TRD/workflow/include/TRDWorkflow/TRDPulseHeightSpec.h b/Detectors/TRD/workflow/include/TRDWorkflow/TRDPulseHeightSpec.h index be00e478608ec..2173518bc829b 100644 --- a/Detectors/TRD/workflow/include/TRDWorkflow/TRDPulseHeightSpec.h +++ b/Detectors/TRD/workflow/include/TRDWorkflow/TRDPulseHeightSpec.h @@ -36,7 +36,7 @@ namespace trd class PuseHeightDevice : public o2::framework::Task { public: - PuseHeightDevice(std::shared_ptr dr) : mDataRequest(dr) {} + PuseHeightDevice(std::shared_ptr dr, o2::dataformats::GlobalTrackID::mask_t src) : mDataRequest(dr), mTrkMask(src) {} void init(o2::framework::InitContext& ic) final { mPulseHeight = std::make_unique(); @@ -47,6 +47,7 @@ class PuseHeightDevice : public o2::framework::Task // apply artificial pad shift in case non-ideal alignment is used to compensate for shift in current alignment from real data mPulseHeight->setApplyShift(false); } + mPulseHeight->setTrkMask(mTrkMask); } void run(o2::framework::ProcessingContext& pc) final @@ -92,6 +93,7 @@ class PuseHeightDevice : public o2::framework::Task std::shared_ptr mDataRequest; std::unique_ptr mPulseHeight; bool mRunStopRequested = false; // flag that run was stopped (and the last output is sent) + o2::dataformats::GlobalTrackID::mask_t mTrkMask; }; } // namespace trd @@ -127,7 +129,7 @@ DataProcessorSpec getTRDPulseHeightSpec(GID::mask_t src, bool digitsFromReader) "trd-pulseheight", dataRequest->inputs, outputs, - AlgorithmSpec{adaptFromTask(dataRequest)}, + AlgorithmSpec{adaptFromTask(dataRequest, src)}, Options{ {"enable-root-output", VariantType::Bool, false, {"output PH and debug data to root file"}}}}; } From 3f7219a19de9f9aef0de5c1458d72d590eb83557 Mon Sep 17 00:00:00 2001 From: Gauthier Legras Date: Mon, 9 Nov 2026 13:47:36 +0100 Subject: [PATCH 2/3] clang format --- .../calibration/include/TRDCalibration/PulseHeight.h | 2 +- Detectors/TRD/calibration/src/PulseHeight.cxx | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Detectors/TRD/calibration/include/TRDCalibration/PulseHeight.h b/Detectors/TRD/calibration/include/TRDCalibration/PulseHeight.h index 406a8e11238c3..8422022a5b4f1 100644 --- a/Detectors/TRD/calibration/include/TRDCalibration/PulseHeight.h +++ b/Detectors/TRD/calibration/include/TRDCalibration/PulseHeight.h @@ -54,7 +54,7 @@ class PulseHeight void reset(); void setApplyShift(bool f) { mApplyShift = f; } - void setTrkMask(o2::dataformats::GlobalTrackID::mask_t trkMask) { mTrkMask = trkMask;} + void setTrkMask(o2::dataformats::GlobalTrackID::mask_t trkMask) { mTrkMask = trkMask; } /// Main processing function void process(); diff --git a/Detectors/TRD/calibration/src/PulseHeight.cxx b/Detectors/TRD/calibration/src/PulseHeight.cxx index beb6c928e6cbd..0631d8690c7b8 100644 --- a/Detectors/TRD/calibration/src/PulseHeight.cxx +++ b/Detectors/TRD/calibration/src/PulseHeight.cxx @@ -87,9 +87,9 @@ void PulseHeight::process() } size_t nTrkTrig[2] = {mTrackTriggerRecordsITSTPCTRD.size(), mTrackTriggerRecordsTPCTRD.size()}; int lastTrkTrig[2] = {0}; - + int currentFT0[2] = {0}; - + for (const auto& trig : mTriggerRecords) { if (trig.getNumberOfDigits() == 0) { continue; @@ -156,7 +156,7 @@ void PulseHeight::findDigitsForTracklet(const Tracklet64& trklt, const TriggerRe int iDigitFirst = trig.getFirstDigit(); int iDigitLast = trig.getFirstDigit() + trig.getNumberOfDigits(); for (int iDigit = iDigitFirst + 1; iDigit < iDigitLast - 1; ++iDigit) { - const auto& digit = (*mDigits)[iDigit]; + const auto& digit = (*mDigits)[iDigit]; if (digit.isSharedDigit()) { continue; // avoid double-counting of the same digit } @@ -192,8 +192,9 @@ void PulseHeight::findDigitsForTracklet(const Tracklet64& trklt, const TriggerRe if (nNeighbours > 0) { // pile-up removal: if we have several consecutive digits with very small value for the first time bins, this is likely to come from pile-up int nOverThreshold = 0; - for (int iTb = 0; iTb < ((int) (mParams.pileupCut * 10)); iTb++) { - if (digit.getADC()[iTb] > mParams.digitsThreshold) nOverThreshold++; + for (int iTb = 0; iTb < ((int)(mParams.pileupCut * 10)); iTb++) { + if (digit.getADC()[iTb] > mParams.digitsThreshold) + nOverThreshold++; } if (nOverThreshold <= 2) { continue; From dd75628a67a4ca4d9d107df3d188bb252e013861 Mon Sep 17 00:00:00 2001 From: Gauthier Legras Date: Tue, 10 Nov 2026 16:56:16 +0100 Subject: [PATCH 3/3] fix --- Detectors/TRD/calibration/src/PulseHeight.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Detectors/TRD/calibration/src/PulseHeight.cxx b/Detectors/TRD/calibration/src/PulseHeight.cxx index 0631d8690c7b8..a005fe2cee076 100644 --- a/Detectors/TRD/calibration/src/PulseHeight.cxx +++ b/Detectors/TRD/calibration/src/PulseHeight.cxx @@ -193,8 +193,9 @@ void PulseHeight::findDigitsForTracklet(const Tracklet64& trklt, const TriggerRe // pile-up removal: if we have several consecutive digits with very small value for the first time bins, this is likely to come from pile-up int nOverThreshold = 0; for (int iTb = 0; iTb < ((int)(mParams.pileupCut * 10)); iTb++) { - if (digit.getADC()[iTb] > mParams.digitsThreshold) + if (digit.getADC()[iTb] > mParams.digitsThreshold) { nOverThreshold++; + } } if (nOverThreshold <= 2) { continue;