From 1521406a72a77fe07fb4c086313fce8aa7fad834 Mon Sep 17 00:00:00 2001 From: Wiktor Pierozak Date: Mon, 19 Oct 2026 11:51:46 +0200 Subject: [PATCH 01/11] Draft of FDD reco refactor --- .../include/DataFormatsFDD/FDDRecoConfig.h | 17 ++++++ .../FIT/FDD/include/DataFormatsFDD/RecPoint.h | 1 + .../FDD/reconstruction/src/Reconstructor.cxx | 59 +++++++++++-------- 3 files changed, 51 insertions(+), 26 deletions(-) diff --git a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h index 3679db655228c..6c037ebb548b3 100644 --- a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h +++ b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h @@ -13,11 +13,28 @@ #define ALICEO2_FDD_RECO_PARAM #include "CommonUtils/ConfigurableParamHelper.h" +#include "DataFormatsFDD/ChannelData.h" namespace o2::fdd { struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { float AmplitudeCutOnCollisionTimeWeights = 3; + float AmplitudeCollisionTimeCutSideA = 1.0; + float AmplitudeCollisionTimeCutSideC = 0.0; + + float SwTriggerTimeLowThreshold= -1.25; + float SwTriggerTimeHighThreshold= 1.25; + float SwTriggerAmplitudeLowThreshold = 0.0; + float SwTriggerAmplitudeHighThreshold = 4096.0; + bool SwTriggerEnabled = false; + + uint8_t ValidPmInputFlagMask = static_cast(~(1u << ChannelData::kNumberADC)); + uint8_t ValidPmInputFlags = static_cast((1u << ChannelData::kIsCFDinADCgate) | (1u << ChannelData::kIsEventInTVDC)); + bool areChannelDataFlagsGood(uint8_t flags) const + { + return (flags & mValidPmInputFlagMask) == mValidPmInputFlags; + } + O2ParamDef(FDDRecoConfig, "FDDRecoConfig"); ClassDefNV(FDDRecoConfig, 1); }; diff --git a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/RecPoint.h b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/RecPoint.h index f784d99145728..54fe33ce241d5 100644 --- a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/RecPoint.h +++ b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/RecPoint.h @@ -53,6 +53,7 @@ class RecPoint public: enum TimeTypeIndex : int { TimeA, TimeC }; + enum ETriggerBits { kSwTrigger = 7 }; RecPoint() = default; RecPoint(const std::array& collisiontime, int first, int ne, o2::InteractionRecord iRec, o2::fdd::Triggers triggers) diff --git a/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx b/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx index 10d27ca1a5da0..19d9318325db3 100644 --- a/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx +++ b/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx @@ -35,6 +35,9 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::spanisChannelAlive(inChData[ich].mPMNumber)) { LOG(debug) << "Channel " << ich << " is dead - discarding data"; @@ -48,43 +51,47 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::span FDDRecoConfig::Instance().AmplitudeCutOnCollisionTimeWeights) { - timeErr = 1. / adc; + timeWeight = adc * adc; } if ((int)inChData[ich].mPMNumber < 8) { nInTimeC += inTime; - timeFDC += time / (timeErr * timeErr); - weightFDC += 1. / (timeErr * timeErr); + timeFDC += time * timeWeight; + weightFDC += timeWeight; } else { nInTimeA += inTime; - timeFDA += time / (timeErr * timeErr); - weightFDA += 1. / (timeErr * timeErr); + timeFDA += time * timeWeight; + weightFDA += timeWeight; } + + atLeastOneVertexChannel = FDDRecoConfig::areChannelDataFlagsGood(inChData[ich].mFEEBits); + atLeastOneChannelInSwAmplitudeRange = (adc >= FDDRecoConfig::SwTriggerAmplitudeLowThreshold && adc <= FDDRecoConfig::SwTriggerAmplitudeHighThreshold); } const int nsToPs = 1e3; std::array mCollisionTime = {o2::fdd::RecPoint::sDummyCollissionTime, o2::fdd::RecPoint::sDummyCollissionTime}; - /// Avg time for each side, only if one channel satisfy the TVDC condition (if not, also avg time is propagated for background study using AO2D) - if (nInTimeA > 0) { - mCollisionTime[o2::fdd::RecPoint::TimeA] = (weightFDA > 1) ? round(timeFDA / weightFDA * nsToPs) - : o2::fdd::RecPoint::sDummyCollissionTime; - } else { - if (weightFDA > 0) { - mCollisionTime[o2::fdd::RecPoint::TimeA] = round(timeFDA / weightFDA * nsToPs); - } + + float meanTimeSideA = round(timeFDA / weightFDA * nsToPs); + float meanTimeSideC = round(timeFDC / weightFDC * nsToPs); + float sideTimeDifference = fabs(meanTimeSideC - meanTimeSideA); + bool swTriggerBit = false; + swTriggerBit = ( + FDDRecoConfig::SwTriggerEnabled && + (sideTimeDifference => FDDRecoConfig::SwTriggerTimeLowThreshold + && sideTimeDifference <= FDDRecoConfig::SwTriggerTimeHighThreshold + && atLeastOneVertexChannel + && atLeastOneChannelInSwAmplitudeRange + ) + ); + + if (nInTimeA > 0 && weightFDA > FDDRecoConfig::Instance().AmplitudeCollisionTimeCutSideA) { + mCollisionTime[o2::fdd::RecPoint::TimeA] = round(timeFDA / weightFDA * nsToPs); } - if (nInTimeC > 0) { - mCollisionTime[o2::fdd::RecPoint::TimeC] = (weightFDC > 1) ? round(timeFDC / weightFDC * nsToPs) - : o2::fdd::RecPoint::sDummyCollissionTime; - } else { - if (weightFDC > 0) { - mCollisionTime[o2::fdd::RecPoint::TimeC] = round(timeFDC / weightFDC * nsToPs); - } + if (nInTimeC > 0 && weightFDC > FDDRecoConfig::Instance().AmplitudeCollisionTimeCutSideC) { + mCollisionTime[o2::fdd::RecPoint::TimeC] = round(timeFDC / weightFDC * nsToPs); } RecPoints.emplace_back(mCollisionTime, firstEntry, nStored, digitBC.getIntRecord(), digitBC.mTriggers); } From 797b0e9dc95124534293103fe81f72ceed8e2294 Mon Sep 17 00:00:00 2001 From: Wiktor Pierozak Date: Wed, 28 Oct 2026 12:21:46 +0100 Subject: [PATCH 02/11] draft --- .../include/DataFormatsFDD/FDDRecoConfig.h | 41 ++++++++++++++----- .../include/FDDReconstruction/Reconstructor.h | 5 +++ .../FDD/reconstruction/src/Reconstructor.cxx | 13 ++++++ 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h index 6c037ebb548b3..950fa566d4d8f 100644 --- a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h +++ b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h @@ -18,9 +18,37 @@ namespace o2::fdd { struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { - float AmplitudeCutOnCollisionTimeWeights = 3; - float AmplitudeCollisionTimeCutSideA = 1.0; - float AmplitudeCollisionTimeCutSideC = 0.0; + int16_t ChannelAmplitudeUpper = 4096; + int16_t ChannelAmplitudeLower = 0; + int16_t ChannelTimeLower = -2050; + int16_t ChannelTimeUpper = 2050; + + uint8_t ChannelValidPmInputFlagMask = 0; + uint8_t ChannelValidPmInputFlags = 0; + bool isChannelDataGoodForCollisionTime(uint8_t flags) const + { + return (flags & ChannelValidPmInputFlagMask) == ChannelValidPmInputFlags; + } + + uint8_t TriggerBitsValidationMask = 0; + uint8_t TriggerBitsValid = 0; + bool areTriggerBitsGood(uint8_t flags) const + { + return (flags & TriggerBitsValidationMask) == TriggerBitsValid; + } + + + int16_t CollisionTimeAmpltudeUpper = 4096; + int16_t CollisionTimeAmplitudeLower = 0; + int16_t CollisionTimeTimeLower = -2050; + int16_t CollisionTimeTimeUpper = 2050; + + uint8_t CollisionTimeValidPmInputFlagMask = static_cast(~(1u << ChannelData::kNumberADC)); + uint8_t CollisionTimeValidPmInputFlags = static_cast((1u << ChannelData::kIsCFDinADCgate) | (1u << ChannelData::kIsEventInTVDC)); + bool isChannelDataGoodForCollisionTime(uint8_t flags) const + { + return (flags & CollisionTimeValidPmInputFlagMask) == CollisionTimeValidPmInputFlags; + } float SwTriggerTimeLowThreshold= -1.25; float SwTriggerTimeHighThreshold= 1.25; @@ -28,13 +56,6 @@ struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { float SwTriggerAmplitudeHighThreshold = 4096.0; bool SwTriggerEnabled = false; - uint8_t ValidPmInputFlagMask = static_cast(~(1u << ChannelData::kNumberADC)); - uint8_t ValidPmInputFlags = static_cast((1u << ChannelData::kIsCFDinADCgate) | (1u << ChannelData::kIsEventInTVDC)); - bool areChannelDataFlagsGood(uint8_t flags) const - { - return (flags & mValidPmInputFlagMask) == mValidPmInputFlags; - } - O2ParamDef(FDDRecoConfig, "FDDRecoConfig"); ClassDefNV(FDDRecoConfig, 1); }; diff --git a/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h b/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h index 8881605b652ac..af7568cfa6b9c 100644 --- a/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h +++ b/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h @@ -18,6 +18,7 @@ #include "DataFormatsFDD/Digit.h" #include "DataFormatsFDD/RecPoint.h" #include "DataFormatsFIT/DeadChannelMap.h" +#include "DataFormatsFDD/FDDRecoConfig.h" namespace o2 { namespace fdd @@ -40,6 +41,10 @@ class Reconstructor } private: + bool isInAmplitudeWindow(int16_t amplitude) { + return amplitude >= FDDRecoConfig::Instance().ChannelAmplitudeLower && amplitude <= FDDRecoConfig::Instance().ChannelAmplitudeUpper; + } + o2::fit::DeadChannelMap const* mDeadChannelMap = nullptr; ClassDefNV(Reconstructor, 3); }; diff --git a/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx b/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx index 19d9318325db3..29b21c050762f 100644 --- a/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx +++ b/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx @@ -38,6 +38,19 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::spanisChannelAlive(channelData.mPMNumber)) { + LOG(debug) << "Channel " << channelData.mPMNumber << " is dead - discarding data"; + continue; + } + + } + for (int ich = 0; ich < nch; ich++) { if (mDeadChannelMap && !mDeadChannelMap->isChannelAlive(inChData[ich].mPMNumber)) { LOG(debug) << "Channel " << ich << " is dead - discarding data"; From ad6ce1021a94cb1247f0c8dd4afbf100a4a08b43 Mon Sep 17 00:00:00 2001 From: wpierozak Date: Wed, 28 Oct 2026 13:32:13 +0100 Subject: [PATCH 03/11] Implemented FT0-like collision time calulcation for FDD. Prepared methods and data structure for SW trigger implementation --- .../include/DataFormatsFDD/FDDRecoConfig.h | 6 +- .../include/FDDReconstruction/Reconstructor.h | 34 ++++++++ .../FDD/reconstruction/src/Reconstructor.cxx | 84 +++++++++---------- 3 files changed, 76 insertions(+), 48 deletions(-) diff --git a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h index 950fa566d4d8f..a6cf6b69b7f84 100644 --- a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h +++ b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h @@ -25,7 +25,7 @@ struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { uint8_t ChannelValidPmInputFlagMask = 0; uint8_t ChannelValidPmInputFlags = 0; - bool isChannelDataGoodForCollisionTime(uint8_t flags) const + bool isChannelDataGood(uint8_t flags) const { return (flags & ChannelValidPmInputFlagMask) == ChannelValidPmInputFlags; } @@ -54,10 +54,12 @@ struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { float SwTriggerTimeHighThreshold= 1.25; float SwTriggerAmplitudeLowThreshold = 0.0; float SwTriggerAmplitudeHighThreshold = 4096.0; + float SwTriggerTimeDiffMin = -1.25; + float SwTriggerTimeDiffMax = 1.25; bool SwTriggerEnabled = false; O2ParamDef(FDDRecoConfig, "FDDRecoConfig"); - ClassDefNV(FDDRecoConfig, 1); + ClassDefNV(FDDRecoConfig, 2); }; } // namespace o2::fdd #endif \ No newline at end of file diff --git a/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h b/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h index af7568cfa6b9c..bf8a24ef51e95 100644 --- a/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h +++ b/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h @@ -44,6 +44,40 @@ class Reconstructor bool isInAmplitudeWindow(int16_t amplitude) { return amplitude >= FDDRecoConfig::Instance().ChannelAmplitudeLower && amplitude <= FDDRecoConfig::Instance().ChannelAmplitudeUpper; } + bool isInTimeWindow(int16_t time) { + return time >= FDDRecoConfig::Instance().ChannelTimeLower && time <= FDDRecoConfig::Instance().ChannelTimeUpper; + } + bool isChannelDataGood(uint8_t channelBits) { + return FDDRecoConfig::Instance().isChannelDataGood(channelBits); + } + + bool isInCollisionTimeAmplitudeWindow(int16_t amplitude) { + return amplitude >= FDDRecoConfig::Instance().CollisionTimeAmplitudeLower && amplitude <= FDDRecoConfig::Instance().CollisionTimeAmpltudeUpper; + } + bool isInCollisionTimeTimeWindow(int16_t time) { + return time >= FDDRecoConfig::Instance().CollisionTimeTimeLower && time <= FDDRecoConfig::Instance().CollisionTimeTimeUpper; + } + bool isChannelDataGoodForCollisionTime(uint8_t channelBits) { + return FDDRecoConfig::Instance().isChannelDataGoodForCollisionTime(channelBits); + } + + bool checkSwOrGateConditions(const ChannelData& channelData) { + bool isAmplitudeInRange = channelData.mChargeADC >= FDDRecoConfig::Instance().SwTriggerAmplitudeLowThreshold + && channelData.mChargeADC <= FDDRecoConfig::Instance().SwTriggerAmplitudeHighThreshold; + bool isInTimeWindow = std::abs(channelData.mTime) >= FDDRecoConfig::Instance().SwTriggerTimeLowThreshold + && std::abs(channeData.mTime) <= FDDRecoConfig::Instance().SwTriggerTimeHighThreshold; + bool isCfdInAdcGate = channelData.getFlag(ChannelData::EEventDataBit::kIsCFDinADCgate); + return isAmplitudeInRange && isInTimeWindow && isCfdInAdcGate; + } + + bool calculateSwTrigger(float meanTimeSideA, float meanTimeSideC, bool orGateSideA, bool orGateSideC) + { + return (meanTimeSideC - meanTimeSideA) >= FDDRecoConfig::SwTriggerTimeDiffMin + && (meanTimeSideC - meanTimeSideA) <= FDDRecoConfig::SwTriggerTimeDiffMax + && orGateSideA + && orGateSideC; + } + static constexpr uint8_t sSideAMaxId = 7; o2::fit::DeadChannelMap const* mDeadChannelMap = nullptr; ClassDefNV(Reconstructor, 3); diff --git a/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx b/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx index 29b21c050762f..c1205fd59bc78 100644 --- a/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx +++ b/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx @@ -42,69 +42,61 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::spanisChannelAlive(channelData.mPMNumber)) { LOG(debug) << "Channel " << channelData.mPMNumber << " is dead - discarding data"; continue; } - - } - for (int ich = 0; ich < nch; ich++) { - if (mDeadChannelMap && !mDeadChannelMap->isChannelAlive(inChData[ich].mPMNumber)) { - LOG(debug) << "Channel " << ich << " is dead - discarding data"; - continue; - } - bool inTime = inChData[ich].getFlag(ChannelData::EEventDataBit::kIsEventInTVDC); - bool inAdcGate = inChData[ich].getFlag(ChannelData::EEventDataBit::kIsCFDinADCgate); - if (inAdcGate) { + if (isInAmplitudeWindow(channelData.mChargeADC) + && isInTimeWindow(channelData.mTime) + && isChannelDataGood(channelData.mFEEBits)) + { outChData.emplace_back((int)inChData[ich].mPMNumber, (inChData[ich].mTime) * timePerTDC, (double)inChData[ich].mChargeADC, inChData[ich].mFEEBits); - nStored++; + storedEntries++; } - - float adc = inChData[ich].mChargeADC; - float time = (inChData[ich].mTime) * timePerTDC; - - float timeWeight = 1; - if (adc > FDDRecoConfig::Instance().AmplitudeCutOnCollisionTimeWeights) { - timeWeight = adc * adc; + + if (FDDRecoConfig::Instance().SwTriggerEnabled) { + if(channelData.mPMNumber <= sSideAMaxId) { + swOrGateSideA |= checkSwOrGateConditions(channelData); + } else { + swOrGateSideC |= checkSwOrGateConditions(channelData); + } } - if ((int)inChData[ich].mPMNumber < 8) { - nInTimeC += inTime; - timeFDC += time * timeWeight; - weightFDC += timeWeight; + + if (!isInAmplitudeWindow(channelData.mChargeADC) + || !isInTimeWindow(channelData.mTime) + || !isChannelDataGood(channelData.mFEEBits)) { + continue; + } + + if(channelData.mPMNumber <= sSideAMaxId) { + timeSideA += channelData.mTime; + entriesNumSideA++; } else { - nInTimeA += inTime; - timeFDA += time * timeWeight; - weightFDA += timeWeight; + timeSideC += channelData.mTime; + entriesNumSideC++; } - - atLeastOneVertexChannel = FDDRecoConfig::areChannelDataFlagsGood(inChData[ich].mFEEBits); - atLeastOneChannelInSwAmplitudeRange = (adc >= FDDRecoConfig::SwTriggerAmplitudeLowThreshold && adc <= FDDRecoConfig::SwTriggerAmplitudeHighThreshold); } - const int nsToPs = 1e3; - std::array mCollisionTime = {o2::fdd::RecPoint::sDummyCollissionTime, o2::fdd::RecPoint::sDummyCollissionTime}; - float meanTimeSideA = round(timeFDA / weightFDA * nsToPs); - float meanTimeSideC = round(timeFDC / weightFDC * nsToPs); - float sideTimeDifference = fabs(meanTimeSideC - meanTimeSideA); - bool swTriggerBit = false; - swTriggerBit = ( - FDDRecoConfig::SwTriggerEnabled && - (sideTimeDifference => FDDRecoConfig::SwTriggerTimeLowThreshold - && sideTimeDifference <= FDDRecoConfig::SwTriggerTimeHighThreshold - && atLeastOneVertexChannel - && atLeastOneChannelInSwAmplitudeRange - ) - ); + constexpr float nsToPs = 1e3; + float meanTimeSideA = std::round(float(timeSideA) * timePerTDC / float(entriesNumSideA)); + float meanTimeSideC = std::round(float(timeSideC) * timePerTDC / float(entriesNumSideC)); + + bool swVertexTrg = FDDRecoConfig::Instance().SwTriggerEnabled ? calculateSwTrigger(meanTimeSideA, meanTimeSideC, swOrGateSideA, swOrGateSideC) : false; - if (nInTimeA > 0 && weightFDA > FDDRecoConfig::Instance().AmplitudeCollisionTimeCutSideA) { - mCollisionTime[o2::fdd::RecPoint::TimeA] = round(timeFDA / weightFDA * nsToPs); + std::array mCollisionTime = {o2::fdd::RecPoint::sDummyCollissionTime, o2::fdd::RecPoint::sDummyCollissionTime}; + if (entriesSideA > 0) { + mCollisionTime[o2::fdd::RecPoint::TimeA] = meanTimeSideA * nsToPs; } - if (nInTimeC > 0 && weightFDC > FDDRecoConfig::Instance().AmplitudeCollisionTimeCutSideC) { - mCollisionTime[o2::fdd::RecPoint::TimeC] = round(timeFDC / weightFDC * nsToPs); + if (entriesSideC > 0) { + mCollisionTime[o2::fdd::RecPoint::TimeC] = meanTimeSideC * nsToPs; } RecPoints.emplace_back(mCollisionTime, firstEntry, nStored, digitBC.getIntRecord(), digitBC.mTriggers); } From 5819a483e2323e34e1cf40d4942e36f9d2001261 Mon Sep 17 00:00:00 2001 From: wpierozak Date: Thu, 29 Oct 2026 12:18:52 +0100 Subject: [PATCH 04/11] Implemented SwTrigger bit in FDD recpoints, bumped RecPoints class version to 4 --- .../include/DataFormatsFDD/FDDRecoConfig.h | 9 +++-- .../FIT/FDD/include/DataFormatsFDD/RecPoint.h | 17 +++++++--- .../include/FDDReconstruction/Reconstructor.h | 32 +++++++++--------- .../FDD/reconstruction/src/Reconstructor.cxx | 33 ++++++++----------- 4 files changed, 48 insertions(+), 43 deletions(-) diff --git a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h index a6cf6b69b7f84..0edc1c7150c99 100644 --- a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h +++ b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h @@ -32,12 +32,11 @@ struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { uint8_t TriggerBitsValidationMask = 0; uint8_t TriggerBitsValid = 0; - bool areTriggerBitsGood(uint8_t flags) const + bool areTriggerBitsGood(uint8_t flags) const { return (flags & TriggerBitsValidationMask) == TriggerBitsValid; } - int16_t CollisionTimeAmpltudeUpper = 4096; int16_t CollisionTimeAmplitudeLower = 0; int16_t CollisionTimeTimeLower = -2050; @@ -49,9 +48,9 @@ struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { { return (flags & CollisionTimeValidPmInputFlagMask) == CollisionTimeValidPmInputFlags; } - - float SwTriggerTimeLowThreshold= -1.25; - float SwTriggerTimeHighThreshold= 1.25; + + float SwTriggerTimeLowThreshold = -1.25; + float SwTriggerTimeHighThreshold = 1.25; float SwTriggerAmplitudeLowThreshold = 0.0; float SwTriggerAmplitudeHighThreshold = 4096.0; float SwTriggerTimeDiffMin = -1.25; diff --git a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/RecPoint.h b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/RecPoint.h index 54fe33ce241d5..faaf729c68d52 100644 --- a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/RecPoint.h +++ b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/RecPoint.h @@ -53,16 +53,17 @@ class RecPoint public: enum TimeTypeIndex : int { TimeA, TimeC }; - enum ETriggerBits { kSwTrigger = 7 }; + enum ETriggerBits { kSwVtxTrigger = 7 }; RecPoint() = default; RecPoint(const std::array& collisiontime, int first, int ne, - o2::InteractionRecord iRec, o2::fdd::Triggers triggers) + o2::InteractionRecord iRec, o2::fdd::Triggers triggers, bool swVertexTrigger) : mCollisionTimePs(collisiontime) { mRef.setFirstEntry(first); mRef.setEntries(ne); mIntRecord = iRec; mTriggers = triggers; + updateTriggers(swVertexTrigger); } ~RecPoint() = default; @@ -87,12 +88,20 @@ class RecPoint bool operator==(const RecPoint&) const = default; private: + void updateTriggers(bool swVertexTrigger) + { + auto [triggerBits, technicalWords] = o2::fit::Triggers::parseDigitTriggerWord(mTriggers.getTriggersignals(), true); + triggerBits |= (uint8_t(swVertexTrigger) << kSwVtxTrigger); + mTriggers.setTriggers(triggerBits); + mTechnicalWords = technicalWords; + } o2::dataformats::RangeReference mRef; o2::InteractionRecord mIntRecord; - o2::fdd::Triggers mTriggers; // pattern of triggers in this BC + o2::fdd::Triggers mTriggers; // pattern of triggers in this BC + uint8_t mTechnicalWords{0}; std::array mCollisionTimePs = {sDummyCollissionTime, sDummyCollissionTime}; // in picoseconds - ClassDefNV(RecPoint, 3); + ClassDefNV(RecPoint, 4); }; } // namespace fdd } // namespace o2 diff --git a/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h b/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h index bf8a24ef51e95..86d4222e5aad7 100644 --- a/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h +++ b/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h @@ -41,41 +41,43 @@ class Reconstructor } private: - bool isInAmplitudeWindow(int16_t amplitude) { + bool isInAmplitudeWindow(int16_t amplitude) + { return amplitude >= FDDRecoConfig::Instance().ChannelAmplitudeLower && amplitude <= FDDRecoConfig::Instance().ChannelAmplitudeUpper; } - bool isInTimeWindow(int16_t time) { + bool isInTimeWindow(int16_t time) + { return time >= FDDRecoConfig::Instance().ChannelTimeLower && time <= FDDRecoConfig::Instance().ChannelTimeUpper; } - bool isChannelDataGood(uint8_t channelBits) { + bool isChannelDataGood(uint8_t channelBits) + { return FDDRecoConfig::Instance().isChannelDataGood(channelBits); } - bool isInCollisionTimeAmplitudeWindow(int16_t amplitude) { + bool isInCollisionTimeAmplitudeWindow(int16_t amplitude) + { return amplitude >= FDDRecoConfig::Instance().CollisionTimeAmplitudeLower && amplitude <= FDDRecoConfig::Instance().CollisionTimeAmpltudeUpper; } - bool isInCollisionTimeTimeWindow(int16_t time) { + bool isInCollisionTimeTimeWindow(int16_t time) + { return time >= FDDRecoConfig::Instance().CollisionTimeTimeLower && time <= FDDRecoConfig::Instance().CollisionTimeTimeUpper; } - bool isChannelDataGoodForCollisionTime(uint8_t channelBits) { + bool isChannelDataGoodForCollisionTime(uint8_t channelBits) + { return FDDRecoConfig::Instance().isChannelDataGoodForCollisionTime(channelBits); } - bool checkSwOrGateConditions(const ChannelData& channelData) { - bool isAmplitudeInRange = channelData.mChargeADC >= FDDRecoConfig::Instance().SwTriggerAmplitudeLowThreshold - && channelData.mChargeADC <= FDDRecoConfig::Instance().SwTriggerAmplitudeHighThreshold; - bool isInTimeWindow = std::abs(channelData.mTime) >= FDDRecoConfig::Instance().SwTriggerTimeLowThreshold - && std::abs(channeData.mTime) <= FDDRecoConfig::Instance().SwTriggerTimeHighThreshold; + bool checkSwOrGateConditions(const ChannelData& channelData) + { + bool isAmplitudeInRange = channelData.mChargeADC >= FDDRecoConfig::Instance().SwTriggerAmplitudeLowThreshold && channelData.mChargeADC <= FDDRecoConfig::Instance().SwTriggerAmplitudeHighThreshold; + bool isInTimeWindow = std::abs(channelData.mTime) >= FDDRecoConfig::Instance().SwTriggerTimeLowThreshold && std::abs(channelData.mTime) <= FDDRecoConfig::Instance().SwTriggerTimeHighThreshold; bool isCfdInAdcGate = channelData.getFlag(ChannelData::EEventDataBit::kIsCFDinADCgate); return isAmplitudeInRange && isInTimeWindow && isCfdInAdcGate; } bool calculateSwTrigger(float meanTimeSideA, float meanTimeSideC, bool orGateSideA, bool orGateSideC) { - return (meanTimeSideC - meanTimeSideA) >= FDDRecoConfig::SwTriggerTimeDiffMin - && (meanTimeSideC - meanTimeSideA) <= FDDRecoConfig::SwTriggerTimeDiffMax - && orGateSideA - && orGateSideC; + return (meanTimeSideC - meanTimeSideA) >= FDDRecoConfig::Instance().SwTriggerTimeDiffMin && (meanTimeSideC - meanTimeSideA) <= FDDRecoConfig::Instance().SwTriggerTimeDiffMax && orGateSideA && orGateSideC; } static constexpr uint8_t sSideAMaxId = 7; diff --git a/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx b/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx index c1205fd59bc78..8904831c44fc8 100644 --- a/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx +++ b/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx @@ -47,36 +47,31 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::spanisChannelAlive(channelData.mPMNumber)) { LOG(debug) << "Channel " << channelData.mPMNumber << " is dead - discarding data"; continue; } - if (isInAmplitudeWindow(channelData.mChargeADC) - && isInTimeWindow(channelData.mTime) - && isChannelDataGood(channelData.mFEEBits)) - { - outChData.emplace_back((int)inChData[ich].mPMNumber, (inChData[ich].mTime) * timePerTDC, - (double)inChData[ich].mChargeADC, inChData[ich].mFEEBits); + if (isInAmplitudeWindow(channelData.mChargeADC) && isInTimeWindow(channelData.mTime) && isChannelDataGood(channelData.mFEEBits)) { + outChData.emplace_back((int)channelData.mPMNumber, (channelData.mTime) * timePerTDC, + (double)channelData.mChargeADC, channelData.mFEEBits); storedEntries++; } - + if (FDDRecoConfig::Instance().SwTriggerEnabled) { - if(channelData.mPMNumber <= sSideAMaxId) { + if (channelData.mPMNumber <= sSideAMaxId) { swOrGateSideA |= checkSwOrGateConditions(channelData); } else { swOrGateSideC |= checkSwOrGateConditions(channelData); } } - if (!isInAmplitudeWindow(channelData.mChargeADC) - || !isInTimeWindow(channelData.mTime) - || !isChannelDataGood(channelData.mFEEBits)) { - continue; - } - - if(channelData.mPMNumber <= sSideAMaxId) { + if (!isInAmplitudeWindow(channelData.mChargeADC) || !isInTimeWindow(channelData.mTime) || !isChannelDataGood(channelData.mFEEBits)) { + continue; + } + + if (channelData.mPMNumber <= sSideAMaxId) { timeSideA += channelData.mTime; entriesNumSideA++; } else { @@ -92,13 +87,13 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::span mCollisionTime = {o2::fdd::RecPoint::sDummyCollissionTime, o2::fdd::RecPoint::sDummyCollissionTime}; - if (entriesSideA > 0) { + if (entriesNumSideA > 0) { mCollisionTime[o2::fdd::RecPoint::TimeA] = meanTimeSideA * nsToPs; } - if (entriesSideC > 0) { + if (entriesNumSideC > 0) { mCollisionTime[o2::fdd::RecPoint::TimeC] = meanTimeSideC * nsToPs; } - RecPoints.emplace_back(mCollisionTime, firstEntry, nStored, digitBC.getIntRecord(), digitBC.mTriggers); + RecPoints.emplace_back(mCollisionTime, firstEntry, nStored, digitBC.getIntRecord(), digitBC.mTriggers, swVertexTrg); } //________________________________________________________ void Reconstructor::finish() From 33fa1322384d607189f9d7759c0f366bb851009d Mon Sep 17 00:00:00 2001 From: wpierozak Date: Fri, 30 Oct 2026 16:38:09 +0100 Subject: [PATCH 05/11] Fixed incorrect rounding to ns in collision time calculation; Fixed bug with number of entries counter --- .../FDD/include/DataFormatsFDD/FDDRecoConfig.h | 16 ++++++++-------- .../FDD/reconstruction/src/Reconstructor.cxx | 18 ++++++------------ 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h index 0edc1c7150c99..c7c8acf9db225 100644 --- a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h +++ b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h @@ -39,8 +39,8 @@ struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { int16_t CollisionTimeAmpltudeUpper = 4096; int16_t CollisionTimeAmplitudeLower = 0; - int16_t CollisionTimeTimeLower = -2050; - int16_t CollisionTimeTimeUpper = 2050; + int16_t CollisionTimeTimeLower = -500; + int16_t CollisionTimeTimeUpper = 500; uint8_t CollisionTimeValidPmInputFlagMask = static_cast(~(1u << ChannelData::kNumberADC)); uint8_t CollisionTimeValidPmInputFlags = static_cast((1u << ChannelData::kIsCFDinADCgate) | (1u << ChannelData::kIsEventInTVDC)); @@ -49,12 +49,12 @@ struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { return (flags & CollisionTimeValidPmInputFlagMask) == CollisionTimeValidPmInputFlags; } - float SwTriggerTimeLowThreshold = -1.25; - float SwTriggerTimeHighThreshold = 1.25; - float SwTriggerAmplitudeLowThreshold = 0.0; - float SwTriggerAmplitudeHighThreshold = 4096.0; - float SwTriggerTimeDiffMin = -1.25; - float SwTriggerTimeDiffMax = 1.25; + int16_t SwTriggerTimeLowThreshold = -153; + int16_t SwTriggerTimeHighThreshold = 153; + int16_t SwTriggerAmplitudeLowThreshold = 10; + int16_t SwTriggerAmplitudeHighThreshold = 4096; + float SwTriggerTimeDiffMin = -1.3; + float SwTriggerTimeDiffMax = 1.3; bool SwTriggerEnabled = false; O2ParamDef(FDDRecoConfig, "FDDRecoConfig"); diff --git a/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx b/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx index 8904831c44fc8..ecef5d372ba88 100644 --- a/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx +++ b/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx @@ -27,13 +27,7 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::span& RecPoints, std::vector& outChData) // gsl::span outChData) { - // Compute charge weighted average time - Double_t timeFDA = 0, timeFDC = 0; - Double_t weightFDA = 0.0, weightFDC = 0.0; - Int_t nInTimeA = 0, nInTimeC = 0; - int firstEntry = outChData.size(); - int nStored = 0; - int nch = inChData.size(); + const int firstEntry = outChData.size(); bool atLeastOneVertexChannel = false; bool atLeastOneChannelInSwAmplitudeRange = false; @@ -81,19 +75,19 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::span mCollisionTime = {o2::fdd::RecPoint::sDummyCollissionTime, o2::fdd::RecPoint::sDummyCollissionTime}; if (entriesNumSideA > 0) { - mCollisionTime[o2::fdd::RecPoint::TimeA] = meanTimeSideA * nsToPs; + mCollisionTime[o2::fdd::RecPoint::TimeA] = std::round(meanTimeSideA * nsToPs); } if (entriesNumSideC > 0) { - mCollisionTime[o2::fdd::RecPoint::TimeC] = meanTimeSideC * nsToPs; + mCollisionTime[o2::fdd::RecPoint::TimeC] = std::round(meanTimeSideC * nsToPs); } - RecPoints.emplace_back(mCollisionTime, firstEntry, nStored, digitBC.getIntRecord(), digitBC.mTriggers, swVertexTrg); + RecPoints.emplace_back(mCollisionTime, firstEntry, storedEntries, digitBC.getIntRecord(), digitBC.mTriggers, swVertexTrg); } //________________________________________________________ void Reconstructor::finish() From e716a5d4448a45ed02a9805ada69ca0ac6407cce Mon Sep 17 00:00:00 2001 From: wpierozak Date: Sun, 1 Nov 2026 02:26:46 +0100 Subject: [PATCH 06/11] Refactored parameters name; Preparing structure for coincidence checks --- .../FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h | 12 ++++++------ .../include/FDDReconstruction/Reconstructor.h | 10 +++++++--- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h index c7c8acf9db225..05606c185c3fd 100644 --- a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h +++ b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h @@ -49,12 +49,12 @@ struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { return (flags & CollisionTimeValidPmInputFlagMask) == CollisionTimeValidPmInputFlags; } - int16_t SwTriggerTimeLowThreshold = -153; - int16_t SwTriggerTimeHighThreshold = 153; - int16_t SwTriggerAmplitudeLowThreshold = 10; - int16_t SwTriggerAmplitudeHighThreshold = 4096; - float SwTriggerTimeDiffMin = -1.3; - float SwTriggerTimeDiffMax = 1.3; + int16_t SwOrTriggerTimeLowThreshold = -153; + int16_t SwOrTriggerTimeHighThreshold = 153; + int16_t SwOrTriggerAmplitudeLowThreshold = 10; + int16_t SwOrTriggerAmplitudeHighThreshold = 4096; + int16_t SwVtxTriggerTimeDiffMin = -100; + int16_t SwVtxTriggerTimeDiffMax = 100; bool SwTriggerEnabled = false; O2ParamDef(FDDRecoConfig, "FDDRecoConfig"); diff --git a/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h b/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h index 86d4222e5aad7..6c9be1e031ce1 100644 --- a/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h +++ b/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h @@ -19,6 +19,7 @@ #include "DataFormatsFDD/RecPoint.h" #include "DataFormatsFIT/DeadChannelMap.h" #include "DataFormatsFDD/FDDRecoConfig.h" +#include "FDDBase/Constants.h" namespace o2 { namespace fdd @@ -41,6 +42,9 @@ class Reconstructor } private: + static const int coincidencePairsSideC[4][2] = {{0, 4}, {1, 5}, {2, 6}, {3, 7}}; + static const int coincidencePairsSideA[4][2] = {{8, 12}, {9, 13}, {10, 14}, {11, 15}}; + bool isInAmplitudeWindow(int16_t amplitude) { return amplitude >= FDDRecoConfig::Instance().ChannelAmplitudeLower && amplitude <= FDDRecoConfig::Instance().ChannelAmplitudeUpper; @@ -69,15 +73,15 @@ class Reconstructor bool checkSwOrGateConditions(const ChannelData& channelData) { - bool isAmplitudeInRange = channelData.mChargeADC >= FDDRecoConfig::Instance().SwTriggerAmplitudeLowThreshold && channelData.mChargeADC <= FDDRecoConfig::Instance().SwTriggerAmplitudeHighThreshold; - bool isInTimeWindow = std::abs(channelData.mTime) >= FDDRecoConfig::Instance().SwTriggerTimeLowThreshold && std::abs(channelData.mTime) <= FDDRecoConfig::Instance().SwTriggerTimeHighThreshold; + bool isAmplitudeInRange = channelData.mChargeADC >= FDDRecoConfig::Instance().SwOrTriggerAmplitudeLowThreshold && channelData.mChargeADC <= FDDRecoConfig::Instance().SwOrTriggerAmplitudeHighThreshold; + bool isInTimeWindow = std::abs(channelData.mTime) >= o2::fdd::timePerTDC * FDDRecoConfig::Instance().SwOrTriggerTimeLowThreshold && std::abs(channelData.mTime) <= o2::fdd::timePerTDC * FDDRecoConfig::Instance().SwOrTriggerTimeHighThreshold; bool isCfdInAdcGate = channelData.getFlag(ChannelData::EEventDataBit::kIsCFDinADCgate); return isAmplitudeInRange && isInTimeWindow && isCfdInAdcGate; } bool calculateSwTrigger(float meanTimeSideA, float meanTimeSideC, bool orGateSideA, bool orGateSideC) { - return (meanTimeSideC - meanTimeSideA) >= FDDRecoConfig::Instance().SwTriggerTimeDiffMin && (meanTimeSideC - meanTimeSideA) <= FDDRecoConfig::Instance().SwTriggerTimeDiffMax && orGateSideA && orGateSideC; + return (meanTimeSideC - meanTimeSideA) >= o2::fdd::timePerTDC * FDDRecoConfig::Instance().SwVtxTriggerTimeDiffMin && (meanTimeSideC - meanTimeSideA) <= o2::fdd::timePerTDC * FDDRecoConfig::Instance().SwVtxTriggerTimeDiffMax && orGateSideA && orGateSideC; } static constexpr uint8_t sSideAMaxId = 7; From 15a3914b016aedfb9c743afa208d4257a78c4bf6 Mon Sep 17 00:00:00 2001 From: wpierozak Date: Mon, 2 Nov 2026 20:50:46 +0100 Subject: [PATCH 07/11] Implemented coincidence mode; Renamed reco parameters --- .../include/DataFormatsFDD/FDDRecoConfig.h | 20 +++++++++---- .../FIT/FDD/include/DataFormatsFDD/RecPoint.h | 12 ++++---- .../include/FDDReconstruction/Reconstructor.h | 27 ++++++++++++------ .../FDD/reconstruction/src/Reconstructor.cxx | 28 ++++++++++--------- 4 files changed, 54 insertions(+), 33 deletions(-) diff --git a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h index 05606c185c3fd..2da845b6f2d77 100644 --- a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h +++ b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h @@ -49,14 +49,22 @@ struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { return (flags & CollisionTimeValidPmInputFlagMask) == CollisionTimeValidPmInputFlags; } - int16_t SwOrTriggerTimeLowThreshold = -153; - int16_t SwOrTriggerTimeHighThreshold = 153; - int16_t SwOrTriggerAmplitudeLowThreshold = 10; - int16_t SwOrTriggerAmplitudeHighThreshold = 4096; - int16_t SwVtxTriggerTimeDiffMin = -100; - int16_t SwVtxTriggerTimeDiffMax = 100; + int16_t SwOrGate = 153; + int16_t SwOrTriggerAmplitudeLowThresholdSideA = 6; + int16_t SwOrTriggerAmplitudeLowThresholdSideC = 0; + int16_t SwOrTriggerAmplitudeHighThresholdSideA = 4095; + int16_t SwOrTriggerAmplitudeHighThresholdSideC = 4095; + int16_t SwVtxTriggerTimeWindow = 100; + bool SwTriggerCoincidenceMode = true; bool SwTriggerEnabled = false; + uint8_t SwTriggerValidPmInputFlagMask = static_cast(~(1u << ChannelData::kNumberADC)); + uint8_t SwTriggerValidPmInputFlags = static_cast((1u << ChannelData::kIsCFDinADCgate) | (1u << ChannelData::kIsEventInTVDC)); + bool isChannelDataGoodForSwTrigger(uint8_t flags) const + { + return (flags & SwTriggerValidPmInputFlagMask) == SwTriggerValidPmInputFlags; + } + O2ParamDef(FDDRecoConfig, "FDDRecoConfig"); ClassDefNV(FDDRecoConfig, 2); }; diff --git a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/RecPoint.h b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/RecPoint.h index faaf729c68d52..f8102e37ce4c5 100644 --- a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/RecPoint.h +++ b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/RecPoint.h @@ -53,17 +53,19 @@ class RecPoint public: enum TimeTypeIndex : int { TimeA, TimeC }; - enum ETriggerBits { kSwVtxTrigger = 7 }; + enum ETriggerBits { kSwOrTrgSideA, + kSwOrTrgSideC, + kSwVtxTrg = 7 }; RecPoint() = default; RecPoint(const std::array& collisiontime, int first, int ne, - o2::InteractionRecord iRec, o2::fdd::Triggers triggers, bool swVertexTrigger) + o2::InteractionRecord iRec, o2::fdd::Triggers triggers, bool swOrTrgSideA, bool swOrTrgSideC, bool swVtxTrg) : mCollisionTimePs(collisiontime) { mRef.setFirstEntry(first); mRef.setEntries(ne); mIntRecord = iRec; mTriggers = triggers; - updateTriggers(swVertexTrigger); + updateTriggers(swOrTrgSideA, swOrTrgSideC, swVtxTrg); } ~RecPoint() = default; @@ -88,10 +90,10 @@ class RecPoint bool operator==(const RecPoint&) const = default; private: - void updateTriggers(bool swVertexTrigger) + void updateTriggers(bool swOrTrgSideA, bool swOrTrgSideC, bool swVertexTrigger) { auto [triggerBits, technicalWords] = o2::fit::Triggers::parseDigitTriggerWord(mTriggers.getTriggersignals(), true); - triggerBits |= (uint8_t(swVertexTrigger) << kSwVtxTrigger); + triggerBits |= (uint8_t(swVertexTrigger) << kSwVtxTrg) | (uint8_t(swOrTrgSideA) << kSwOrTrgSideA) | (uint8_t(swOrTrgSideC) << kSwOrTrgSideC); mTriggers.setTriggers(triggerBits); mTechnicalWords = technicalWords; } diff --git a/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h b/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h index 6c9be1e031ce1..ed3b0002eaa34 100644 --- a/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h +++ b/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h @@ -42,29 +42,33 @@ class Reconstructor } private: - static const int coincidencePairsSideC[4][2] = {{0, 4}, {1, 5}, {2, 6}, {3, 7}}; - static const int coincidencePairsSideA[4][2] = {{8, 12}, {9, 13}, {10, 14}, {11, 15}}; + static constexpr uint8_t coincidencePairsSideC[8] = {4, 5, 6, 7, 0, 1, 2, 3}; + static constexpr uint8_t coincidencePairsSideA[8] = {12, 13, 14, 15, 8, 9, 10, 11}; bool isInAmplitudeWindow(int16_t amplitude) { - return amplitude >= FDDRecoConfig::Instance().ChannelAmplitudeLower && amplitude <= FDDRecoConfig::Instance().ChannelAmplitudeUpper; + return amplitude > FDDRecoConfig::Instance().ChannelAmplitudeLower && amplitude < FDDRecoConfig::Instance().ChannelAmplitudeUpper; } bool isInTimeWindow(int16_t time) { - return time >= FDDRecoConfig::Instance().ChannelTimeLower && time <= FDDRecoConfig::Instance().ChannelTimeUpper; + return time > FDDRecoConfig::Instance().ChannelTimeLower && time < FDDRecoConfig::Instance().ChannelTimeUpper; } bool isChannelDataGood(uint8_t channelBits) { return FDDRecoConfig::Instance().isChannelDataGood(channelBits); } + bool isCoincidenceConditionFulFilled(const bool* coincidencePairs, uint8_t channelNumber) + { + return (!FDDRecoConfig::Instance().SwTriggerCoincidenceMode) || ((channelNumber <= sSideAMaxId) ? coincidencePairs[coincidencePairsSideA[channelNumber]] : coincidencePairs[coincidencePairsSideC[channelNumber]]); + } bool isInCollisionTimeAmplitudeWindow(int16_t amplitude) { - return amplitude >= FDDRecoConfig::Instance().CollisionTimeAmplitudeLower && amplitude <= FDDRecoConfig::Instance().CollisionTimeAmpltudeUpper; + return amplitude > FDDRecoConfig::Instance().CollisionTimeAmplitudeLower && amplitude < FDDRecoConfig::Instance().CollisionTimeAmpltudeUpper; } bool isInCollisionTimeTimeWindow(int16_t time) { - return time >= FDDRecoConfig::Instance().CollisionTimeTimeLower && time <= FDDRecoConfig::Instance().CollisionTimeTimeUpper; + return time > FDDRecoConfig::Instance().CollisionTimeTimeLower && time < FDDRecoConfig::Instance().CollisionTimeTimeUpper; } bool isChannelDataGoodForCollisionTime(uint8_t channelBits) { @@ -73,15 +77,20 @@ class Reconstructor bool checkSwOrGateConditions(const ChannelData& channelData) { - bool isAmplitudeInRange = channelData.mChargeADC >= FDDRecoConfig::Instance().SwOrTriggerAmplitudeLowThreshold && channelData.mChargeADC <= FDDRecoConfig::Instance().SwOrTriggerAmplitudeHighThreshold; - bool isInTimeWindow = std::abs(channelData.mTime) >= o2::fdd::timePerTDC * FDDRecoConfig::Instance().SwOrTriggerTimeLowThreshold && std::abs(channelData.mTime) <= o2::fdd::timePerTDC * FDDRecoConfig::Instance().SwOrTriggerTimeHighThreshold; + bool isAmplitudeInRange = false; + if (channelData.mPMNumber <= sSideAMaxId) { + isAmplitudeInRange = channelData.mChargeADC > FDDRecoConfig::Instance().SwOrTriggerAmplitudeLowThresholdSideA && channelData.mChargeADC < FDDRecoConfig::Instance().SwOrTriggerAmplitudeHighThresholdSideA; + } else { + isAmplitudeInRange = channelData.mChargeADC > FDDRecoConfig::Instance().SwOrTriggerAmplitudeLowThresholdSideC && channelData.mChargeADC < FDDRecoConfig::Instance().SwOrTriggerAmplitudeHighThresholdSideC; + } + bool isInTimeWindow = std::abs(channelData.mTime) <= FDDRecoConfig::Instance().SwOrGate; bool isCfdInAdcGate = channelData.getFlag(ChannelData::EEventDataBit::kIsCFDinADCgate); return isAmplitudeInRange && isInTimeWindow && isCfdInAdcGate; } bool calculateSwTrigger(float meanTimeSideA, float meanTimeSideC, bool orGateSideA, bool orGateSideC) { - return (meanTimeSideC - meanTimeSideA) >= o2::fdd::timePerTDC * FDDRecoConfig::Instance().SwVtxTriggerTimeDiffMin && (meanTimeSideC - meanTimeSideA) <= o2::fdd::timePerTDC * FDDRecoConfig::Instance().SwVtxTriggerTimeDiffMax && orGateSideA && orGateSideC; + return std::abs(meanTimeSideC - meanTimeSideA) < o2::fdd::timePerTDC * FDDRecoConfig::Instance().SwVtxTriggerTimeWindow && orGateSideA && orGateSideC; } static constexpr uint8_t sSideAMaxId = 7; diff --git a/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx b/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx index ecef5d372ba88..d5443acd7b103 100644 --- a/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx +++ b/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx @@ -41,30 +41,32 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::spanisChannelAlive(channelData.mPMNumber)) { LOG(debug) << "Channel " << channelData.mPMNumber << " is dead - discarding data"; continue; } - - if (isInAmplitudeWindow(channelData.mChargeADC) && isInTimeWindow(channelData.mTime) && isChannelDataGood(channelData.mFEEBits)) { - outChData.emplace_back((int)channelData.mPMNumber, (channelData.mTime) * timePerTDC, - (double)channelData.mChargeADC, channelData.mFEEBits); - storedEntries++; + if (!isInAmplitudeWindow(channelData.mChargeADC) || !isInTimeWindow(channelData.mTime) || !isChannelDataGood(channelData.mFEEBits)) { + continue; } + const auto& chNum = channelData.mPMNumber; + + outChData.emplace_back((int)chNum, (channelData.mTime) * timePerTDC, + (double)channelData.mChargeADC, channelData.mFEEBits); + storedEntries++; if (FDDRecoConfig::Instance().SwTriggerEnabled) { - if (channelData.mPMNumber <= sSideAMaxId) { - swOrGateSideA |= checkSwOrGateConditions(channelData); + if (chNum <= sSideAMaxId) { + coincidencePairs[chNum] |= checkSwOrGateConditions(channelData); + swOrGateSideA |= coincidencePairs[chNum] && isCoincidenceConditionFulFilled(coincidencePairs, chNum); } else { - swOrGateSideC |= checkSwOrGateConditions(channelData); + coincidencePairs[chNum] |= checkSwOrGateConditions(channelData); + swOrGateSideC |= coincidencePairs[chNum] && isCoincidenceConditionFulFilled(coincidencePairs, chNum); } } - if (!isInAmplitudeWindow(channelData.mChargeADC) || !isInTimeWindow(channelData.mTime) || !isChannelDataGood(channelData.mFEEBits)) { - continue; - } - if (channelData.mPMNumber <= sSideAMaxId) { timeSideA += channelData.mTime; entriesNumSideA++; @@ -87,7 +89,7 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::span 0) { mCollisionTime[o2::fdd::RecPoint::TimeC] = std::round(meanTimeSideC * nsToPs); } - RecPoints.emplace_back(mCollisionTime, firstEntry, storedEntries, digitBC.getIntRecord(), digitBC.mTriggers, swVertexTrg); + RecPoints.emplace_back(mCollisionTime, firstEntry, storedEntries, digitBC.getIntRecord(), digitBC.mTriggers, swVertexTrg, swOrGateSideA, swOrGateSideC); } //________________________________________________________ void Reconstructor::finish() From 580af2fee89d3717b7323269f168a76490ae79aa Mon Sep 17 00:00:00 2001 From: wpierozak Date: Tue, 3 Nov 2026 15:04:26 +0100 Subject: [PATCH 08/11] Fixed trigger bits assigment --- .../include/DataFormatsFDD/FDDRecoConfig.h | 4 +- .../FIT/FDD/include/DataFormatsFDD/RecPoint.h | 4 +- .../include/FDDReconstruction/Reconstructor.h | 18 +++---- .../FDD/reconstruction/src/Reconstructor.cxx | 54 ++++++++++++++----- 4 files changed, 52 insertions(+), 28 deletions(-) diff --git a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h index 2da845b6f2d77..1d0c28c1350b2 100644 --- a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h +++ b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h @@ -58,8 +58,8 @@ struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { bool SwTriggerCoincidenceMode = true; bool SwTriggerEnabled = false; - uint8_t SwTriggerValidPmInputFlagMask = static_cast(~(1u << ChannelData::kNumberADC)); - uint8_t SwTriggerValidPmInputFlags = static_cast((1u << ChannelData::kIsCFDinADCgate) | (1u << ChannelData::kIsEventInTVDC)); + uint8_t SwTriggerValidPmInputFlagMask = static_cast(~((1u << ChannelData::kNumberADC) | (1u << ChannelData::kIsEventInTVDC))); + uint8_t SwTriggerValidPmInputFlags = static_cast(1u << ChannelData::kIsCFDinADCgate); bool isChannelDataGoodForSwTrigger(uint8_t flags) const { return (flags & SwTriggerValidPmInputFlagMask) == SwTriggerValidPmInputFlags; diff --git a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/RecPoint.h b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/RecPoint.h index f8102e37ce4c5..ea2cf84833d33 100644 --- a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/RecPoint.h +++ b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/RecPoint.h @@ -53,8 +53,8 @@ class RecPoint public: enum TimeTypeIndex : int { TimeA, TimeC }; - enum ETriggerBits { kSwOrTrgSideA, - kSwOrTrgSideC, + enum ETriggerBits { kSwOrTrgSideA = 5, + kSwOrTrgSideC = 6, kSwVtxTrg = 7 }; RecPoint() = default; RecPoint(const std::array& collisiontime, int first, int ne, diff --git a/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h b/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h index ed3b0002eaa34..50fdce6a1381f 100644 --- a/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h +++ b/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h @@ -42,8 +42,7 @@ class Reconstructor } private: - static constexpr uint8_t coincidencePairsSideC[8] = {4, 5, 6, 7, 0, 1, 2, 3}; - static constexpr uint8_t coincidencePairsSideA[8] = {12, 13, 14, 15, 8, 9, 10, 11}; + static constexpr uint8_t coincidencePairs[Nchannels] = {4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11}; bool isInAmplitudeWindow(int16_t amplitude) { @@ -57,10 +56,6 @@ class Reconstructor { return FDDRecoConfig::Instance().isChannelDataGood(channelBits); } - bool isCoincidenceConditionFulFilled(const bool* coincidencePairs, uint8_t channelNumber) - { - return (!FDDRecoConfig::Instance().SwTriggerCoincidenceMode) || ((channelNumber <= sSideAMaxId) ? coincidencePairs[coincidencePairsSideA[channelNumber]] : coincidencePairs[coincidencePairsSideC[channelNumber]]); - } bool isInCollisionTimeAmplitudeWindow(int16_t amplitude) { @@ -78,21 +73,20 @@ class Reconstructor bool checkSwOrGateConditions(const ChannelData& channelData) { bool isAmplitudeInRange = false; - if (channelData.mPMNumber <= sSideAMaxId) { + if (channelData.mPMNumber >= sSideAStartId) { isAmplitudeInRange = channelData.mChargeADC > FDDRecoConfig::Instance().SwOrTriggerAmplitudeLowThresholdSideA && channelData.mChargeADC < FDDRecoConfig::Instance().SwOrTriggerAmplitudeHighThresholdSideA; } else { isAmplitudeInRange = channelData.mChargeADC > FDDRecoConfig::Instance().SwOrTriggerAmplitudeLowThresholdSideC && channelData.mChargeADC < FDDRecoConfig::Instance().SwOrTriggerAmplitudeHighThresholdSideC; } - bool isInTimeWindow = std::abs(channelData.mTime) <= FDDRecoConfig::Instance().SwOrGate; - bool isCfdInAdcGate = channelData.getFlag(ChannelData::EEventDataBit::kIsCFDinADCgate); - return isAmplitudeInRange && isInTimeWindow && isCfdInAdcGate; + bool isInTimeWindow = std::abs(channelData.mTime) < FDDRecoConfig::Instance().SwOrGate; + return isAmplitudeInRange && isInTimeWindow && FDDRecoConfig::Instance().isChannelDataGoodForSwTrigger(channelData.mFEEBits); } bool calculateSwTrigger(float meanTimeSideA, float meanTimeSideC, bool orGateSideA, bool orGateSideC) { - return std::abs(meanTimeSideC - meanTimeSideA) < o2::fdd::timePerTDC * FDDRecoConfig::Instance().SwVtxTriggerTimeWindow && orGateSideA && orGateSideC; + return (std::abs(meanTimeSideC - meanTimeSideA) < o2::fdd::timePerTDC * FDDRecoConfig::Instance().SwVtxTriggerTimeWindow) && orGateSideA && orGateSideC; } - static constexpr uint8_t sSideAMaxId = 7; + static constexpr uint8_t sSideAStartId = 8; o2::fit::DeadChannelMap const* mDeadChannelMap = nullptr; ClassDefNV(Reconstructor, 3); diff --git a/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx b/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx index d5443acd7b103..e5b4788ceb5b6 100644 --- a/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx +++ b/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx @@ -40,8 +40,13 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::spanisChannelAlive(channelData.mPMNumber)) { @@ -58,16 +63,36 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::span= sSideAStartId) { + swOrGateSideA = true; + swTimeSideA += channelData.mTime + coincidencePairsTime[coincidencePairs[chNum]]; + swEntriesNumSideA += 2; + } else { + swOrGateSideC = true; + swTimeSideC += channelData.mTime + coincidencePairsTime[coincidencePairs[chNum]]; + swEntriesNumSideC += 2; + } + } else if (!FDDRecoConfig::Instance().SwTriggerCoincidenceMode && coincidencePairsOrTrg[chNum]) { + if (chNum >= sSideAStartId) { + swOrGateSideA = true; + swTimeSideA += channelData.mTime; + swEntriesNumSideA++; + } else { + swOrGateSideC = true; + swTimeSideC += channelData.mTime; + swEntriesNumSideC++; + } } } - if (channelData.mPMNumber <= sSideAMaxId) { + if (!isChannelDataGoodForCollisionTime(channelData.mFEEBits) || !isInCollisionTimeAmplitudeWindow(channelData.mChargeADC) || !isInCollisionTimeTimeWindow(channelData.mTime)) { + continue; + } + + if (channelData.mPMNumber >= sSideAStartId) { timeSideA += channelData.mTime; entriesNumSideA++; } else { @@ -77,10 +102,15 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::span 0 ? float(timeSideA) * timePerTDC / float(entriesNumSideA) : 0; + float meanTimeSideC = entriesNumSideC > 0 ? float(timeSideC) * timePerTDC / float(entriesNumSideC) : 0; - bool swVertexTrg = FDDRecoConfig::Instance().SwTriggerEnabled ? calculateSwTrigger(meanTimeSideA, meanTimeSideC, swOrGateSideA, swOrGateSideC) : false; + bool swVertexTrg = false; + if (FDDRecoConfig::Instance().SwTriggerEnabled) { + float swMeanTimeSideA = swEntriesNumSideA > 0 ? float(swTimeSideA) * timePerTDC / float(swEntriesNumSideA) : 0; + float swMeanTimeSideC = swEntriesNumSideC > 0 ? float(swTimeSideC) * timePerTDC / float(swEntriesNumSideC) : 0; + swVertexTrg = calculateSwTrigger(swMeanTimeSideA, swMeanTimeSideC, swOrGateSideA, swOrGateSideC); + } std::array mCollisionTime = {o2::fdd::RecPoint::sDummyCollissionTime, o2::fdd::RecPoint::sDummyCollissionTime}; if (entriesNumSideA > 0) { @@ -89,7 +119,7 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::span 0) { mCollisionTime[o2::fdd::RecPoint::TimeC] = std::round(meanTimeSideC * nsToPs); } - RecPoints.emplace_back(mCollisionTime, firstEntry, storedEntries, digitBC.getIntRecord(), digitBC.mTriggers, swVertexTrg, swOrGateSideA, swOrGateSideC); + RecPoints.emplace_back(mCollisionTime, firstEntry, storedEntries, digitBC.getIntRecord(), digitBC.mTriggers, swOrGateSideA, swOrGateSideC, swVertexTrg); } //________________________________________________________ void Reconstructor::finish() From cf7ae551afbdf6f5234188a17374c3d8ba322afd Mon Sep 17 00:00:00 2001 From: wpierozak Date: Tue, 3 Nov 2026 16:08:21 +0100 Subject: [PATCH 09/11] clang-format --- .../Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h index 1d0c28c1350b2..e9fe519c4c834 100644 --- a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h +++ b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h @@ -69,4 +69,4 @@ struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { ClassDefNV(FDDRecoConfig, 2); }; } // namespace o2::fdd -#endif \ No newline at end of file +#endif From 79c8499dff1a62e904dbbed0284c55a05e04db61 Mon Sep 17 00:00:00 2001 From: Wiktor Pierozak Date: Thu, 12 Nov 2026 11:42:00 +0100 Subject: [PATCH 10/11] Refactored FDDRecoConfig - created enum DetectorSide, created amplitude threholds for A and C side --- .../FDD/include/DataFormatsFDD/FDDRecoConfig.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h index e9fe519c4c834..dcd28419fc415 100644 --- a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h +++ b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h @@ -18,8 +18,10 @@ namespace o2::fdd { struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { - int16_t ChannelAmplitudeUpper = 4096; - int16_t ChannelAmplitudeLower = 0; + enum DetectorSide {SideA = 0, SideC = 1} + int16_t ChannelAmplitudeUpper[2] = {4096, 4096}; + int16_t ChannelAmplitudeLower[2] = {6, 0}; + int16_t ChannelTimeLower = -2050; int16_t ChannelTimeUpper = 2050; @@ -37,8 +39,8 @@ struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { return (flags & TriggerBitsValidationMask) == TriggerBitsValid; } - int16_t CollisionTimeAmpltudeUpper = 4096; - int16_t CollisionTimeAmplitudeLower = 0; + int16_t CollisionTimeAmpltudeUpper[2]= {4096, 4096}; + int16_t CollisionTimeAmplitudeLower[2] = {6, 0}; int16_t CollisionTimeTimeLower = -500; int16_t CollisionTimeTimeUpper = 500; @@ -50,10 +52,8 @@ struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { } int16_t SwOrGate = 153; - int16_t SwOrTriggerAmplitudeLowThresholdSideA = 6; - int16_t SwOrTriggerAmplitudeLowThresholdSideC = 0; - int16_t SwOrTriggerAmplitudeHighThresholdSideA = 4095; - int16_t SwOrTriggerAmplitudeHighThresholdSideC = 4095; + int16_t SwOrTriggerAmplitudeLowThreshold[2] = {6, 0}; + int16_t SwOrTriggerAmplitudeHighThreshold[2] = {4095, 4095}; int16_t SwVtxTriggerTimeWindow = 100; bool SwTriggerCoincidenceMode = true; bool SwTriggerEnabled = false; From 2abbcf46f4f9b2ebfca37336b865139814ad315b Mon Sep 17 00:00:00 2001 From: wpierozak Date: Thu, 12 Nov 2026 11:49:53 +0100 Subject: [PATCH 11/11] Implemented side-wise amplitude condition check in FDD reco --- .../FDD/include/DataFormatsFDD/FDDRecoConfig.h | 5 +++-- .../include/FDDReconstruction/Reconstructor.h | 17 ++++++----------- .../FDD/reconstruction/src/Reconstructor.cxx | 7 ++++--- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h index dcd28419fc415..df9e12e0321df 100644 --- a/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h +++ b/DataFormats/Detectors/FIT/FDD/include/DataFormatsFDD/FDDRecoConfig.h @@ -18,7 +18,8 @@ namespace o2::fdd { struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { - enum DetectorSide {SideA = 0, SideC = 1} + enum DetectorSide { SideA = 0, + SideC = 1 }; int16_t ChannelAmplitudeUpper[2] = {4096, 4096}; int16_t ChannelAmplitudeLower[2] = {6, 0}; @@ -39,7 +40,7 @@ struct FDDRecoConfig : o2::conf::ConfigurableParamHelper { return (flags & TriggerBitsValidationMask) == TriggerBitsValid; } - int16_t CollisionTimeAmpltudeUpper[2]= {4096, 4096}; + int16_t CollisionTimeAmpltudeUpper[2] = {4096, 4096}; int16_t CollisionTimeAmplitudeLower[2] = {6, 0}; int16_t CollisionTimeTimeLower = -500; int16_t CollisionTimeTimeUpper = 500; diff --git a/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h b/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h index 50fdce6a1381f..1ba81b46e5f11 100644 --- a/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h +++ b/Detectors/FIT/FDD/reconstruction/include/FDDReconstruction/Reconstructor.h @@ -44,9 +44,9 @@ class Reconstructor private: static constexpr uint8_t coincidencePairs[Nchannels] = {4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11}; - bool isInAmplitudeWindow(int16_t amplitude) + bool isInAmplitudeWindow(int16_t amplitude, FDDRecoConfig::DetectorSide side) { - return amplitude > FDDRecoConfig::Instance().ChannelAmplitudeLower && amplitude < FDDRecoConfig::Instance().ChannelAmplitudeUpper; + return amplitude > FDDRecoConfig::Instance().ChannelAmplitudeLower[side] && amplitude < FDDRecoConfig::Instance().ChannelAmplitudeUpper[side]; } bool isInTimeWindow(int16_t time) { @@ -57,9 +57,9 @@ class Reconstructor return FDDRecoConfig::Instance().isChannelDataGood(channelBits); } - bool isInCollisionTimeAmplitudeWindow(int16_t amplitude) + bool isInCollisionTimeAmplitudeWindow(int16_t amplitude, FDDRecoConfig::DetectorSide side) { - return amplitude > FDDRecoConfig::Instance().CollisionTimeAmplitudeLower && amplitude < FDDRecoConfig::Instance().CollisionTimeAmpltudeUpper; + return amplitude > FDDRecoConfig::Instance().CollisionTimeAmplitudeLower[side] && amplitude < FDDRecoConfig::Instance().CollisionTimeAmpltudeUpper[side]; } bool isInCollisionTimeTimeWindow(int16_t time) { @@ -70,14 +70,9 @@ class Reconstructor return FDDRecoConfig::Instance().isChannelDataGoodForCollisionTime(channelBits); } - bool checkSwOrGateConditions(const ChannelData& channelData) + bool checkSwOrGateConditions(const ChannelData& channelData, FDDRecoConfig::DetectorSide side) { - bool isAmplitudeInRange = false; - if (channelData.mPMNumber >= sSideAStartId) { - isAmplitudeInRange = channelData.mChargeADC > FDDRecoConfig::Instance().SwOrTriggerAmplitudeLowThresholdSideA && channelData.mChargeADC < FDDRecoConfig::Instance().SwOrTriggerAmplitudeHighThresholdSideA; - } else { - isAmplitudeInRange = channelData.mChargeADC > FDDRecoConfig::Instance().SwOrTriggerAmplitudeLowThresholdSideC && channelData.mChargeADC < FDDRecoConfig::Instance().SwOrTriggerAmplitudeHighThresholdSideC; - } + bool isAmplitudeInRange = channelData.mChargeADC > FDDRecoConfig::Instance().SwOrTriggerAmplitudeLowThreshold[side] && channelData.mChargeADC < FDDRecoConfig::Instance().SwOrTriggerAmplitudeHighThreshold[side]; bool isInTimeWindow = std::abs(channelData.mTime) < FDDRecoConfig::Instance().SwOrGate; return isAmplitudeInRange && isInTimeWindow && FDDRecoConfig::Instance().isChannelDataGoodForSwTrigger(channelData.mFEEBits); } diff --git a/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx b/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx index e5b4788ceb5b6..5a12c8e8dcfe2 100644 --- a/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx +++ b/Detectors/FIT/FDD/reconstruction/src/Reconstructor.cxx @@ -53,7 +53,8 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::span= sSideAStartId ? FDDRecoConfig::SideA : FDDRecoConfig::SideC; + if (!isInAmplitudeWindow(channelData.mChargeADC, side) || !isInTimeWindow(channelData.mTime) || !isChannelDataGood(channelData.mFEEBits)) { continue; } const auto& chNum = channelData.mPMNumber; @@ -63,7 +64,7 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::span= sSideAStartId) { @@ -88,7 +89,7 @@ void Reconstructor::process(o2::fdd::Digit const& digitBC, gsl::span