diff --git a/GPU/GPUTracking/TPCClusterFinder/CfUtils.h b/GPU/GPUTracking/TPCClusterFinder/CfUtils.h index 4504b8288aee0..75dcc166abd9b 100644 --- a/GPU/GPUTracking/TPCClusterFinder/CfUtils.h +++ b/GPU/GPUTracking/TPCClusterFinder/CfUtils.h @@ -27,11 +27,6 @@ class CfUtils { public: - static GPUdi() bool isAtEdge(const ChargePos& pos, tpccf::GlobalPad padsPerRow) - { - return (pos.pad() < 2 || pos.pad() >= padsPerRow - 2); - } - static GPUdi() bool innerAboveThreshold(uint8_t aboveThreshold, uint16_t outerIdx) { return aboveThreshold & (1 << cfconsts::OuterToInner[outerIdx]); diff --git a/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx b/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx index d145aaed705d9..77dc6e119df7d 100644 --- a/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.cxx @@ -21,45 +21,6 @@ using namespace o2::gpu; using namespace o2::gpu::tpccf; -GPUd() bool ClusterAccumulator::toNative(const ChargePos& pos, Charge q, tpc::ClusterNative& cn, const GPUParam& param) const -{ - cn.qTot = CAMath::Float2UIntRn(mQtot); - if (cn.qTot <= param.rec.tpc.cfQTotCutoff) { - return false; - } - cn.qMax = q; - if (cn.qMax <= param.rec.tpc.cfQMaxCutoff) { - return false; - } - if (mTimeMean < param.rec.tpc.clustersShiftTimebinsClusterizer) { - return false; - } - if (q <= param.rec.tpc.cfQMaxCutoffSingleTime && mTimeSigma == 0) { - return false; - } - if (q <= param.rec.tpc.cfQMaxCutoffSinglePad && mPadSigma == 0) { - return false; - } - - bool isEdgeCluster = CfUtils::isAtEdge(pos, param.tpcGeometry.NPads(pos.row())); - bool wasSplitInTime = mSplitInTime >= param.rec.tpc.cfMinSplitNum; - bool wasSplitInPad = mSplitInPad >= param.rec.tpc.cfMinSplitNum; - bool isSingleCluster = (mPadSigma == 0) || (mTimeSigma == 0); - - uint8_t flags = 0; - flags |= (isEdgeCluster) ? tpc::ClusterNative::flagEdge : 0; - flags |= (wasSplitInTime) ? tpc::ClusterNative::flagSplitTime : 0; - flags |= (wasSplitInPad) ? tpc::ClusterNative::flagSplitPad : 0; - flags |= (isSingleCluster) ? tpc::ClusterNative::flagSingle : 0; - - cn.setTimeFlags(mTimeMean - param.rec.tpc.clustersShiftTimebinsClusterizer, flags); - cn.setPad(mPadMean); - cn.setSigmaTime(mTimeSigma); - cn.setSigmaPad(mPadSigma); - - return true; -} - GPUd() void ClusterAccumulator::update(Charge splitCharge, Delta2 d) { mQtot += splitCharge; @@ -97,7 +58,7 @@ GPUd() Charge ClusterAccumulator::updateOuter(PackedCharge charge, Delta2 d) return q; } -GPUd() void ClusterAccumulator::finalize(const ChargePos& pos, Charge q, TPCTime timeOffset, const GPUTPCGeometry& geo) +GPUd() bool ClusterAccumulator::toNative(const ChargePos& pos, Charge q, tpc::ClusterNative& cn, const GPUParam& param, TPCTime timeOffset, const Array2D& chargeMap) { mQtot += q; @@ -113,9 +74,48 @@ GPUd() void ClusterAccumulator::finalize(const ChargePos& pos, Charge q, TPCTime mPadMean += pad; mTimeMean += timeOffset + pos.time(); - if (CfUtils::isAtEdge(pos, geo.NPads(pos.row()))) { + bool isEdgeCluster = pos.pad() < 2 || pos.pad() >= param.tpcGeometry.NPads(pos.row()) - 2; // Geometrical edge check, peak within 2 pads of sector edge + if (isEdgeCluster) { bool leftEdge = (pad < 2); - bool correct = (leftEdge) ? (pad < mPadMean) : (pad > mPadMean); - mPadMean = (correct) ? pad : mPadMean; + if (leftEdge ? (pad == 1 && chargeMap[pos.delta({-1, 0})].unpack() < 1) : (pad == (param.tpcGeometry.NPads(pos.row()) - 2) && chargeMap[pos.delta({1, 0})].unpack() < 1)) { + isEdgeCluster = false; // No edge cluster if peak is close to edge but no charge at the edge. + } else if (leftEdge ? (pad < mPadMean) : (pad > mPadMean)) { + mPadMean = pad; // Correct to peak position if COG is close to middle of pad than peak + } + } + + cn.qTot = CAMath::Float2UIntRn(mQtot); + if (cn.qTot <= param.rec.tpc.cfQTotCutoff) { + return false; + } + cn.qMax = q; + if (cn.qMax <= param.rec.tpc.cfQMaxCutoff) { + return false; + } + if (mTimeMean < param.rec.tpc.clustersShiftTimebinsClusterizer) { + return false; + } + if (q <= param.rec.tpc.cfQMaxCutoffSingleTime && mTimeSigma == 0) { + return false; + } + if (q <= param.rec.tpc.cfQMaxCutoffSinglePad && mPadSigma == 0) { + return false; } + + bool wasSplitInTime = mSplitInTime >= param.rec.tpc.cfMinSplitNum; + bool wasSplitInPad = mSplitInPad >= param.rec.tpc.cfMinSplitNum; + bool isSingleCluster = (mPadSigma == 0) || (mTimeSigma == 0); + + uint8_t flags = 0; + flags |= (isEdgeCluster) ? tpc::ClusterNative::flagEdge : 0; + flags |= (wasSplitInTime) ? tpc::ClusterNative::flagSplitTime : 0; + flags |= (wasSplitInPad) ? tpc::ClusterNative::flagSplitPad : 0; + flags |= (isSingleCluster) ? tpc::ClusterNative::flagSingle : 0; + + cn.setTimeFlags(mTimeMean - param.rec.tpc.clustersShiftTimebinsClusterizer, flags); + cn.setPad(mPadMean); + cn.setSigmaTime(mTimeSigma); + cn.setSigmaPad(mPadSigma); + + return true; } diff --git a/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.h b/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.h index 26decbf0a5b14..73f7cb439775a 100644 --- a/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.h +++ b/GPU/GPUTracking/TPCClusterFinder/ClusterAccumulator.h @@ -17,6 +17,7 @@ #include "clusterFinderDefs.h" #include "PackedCharge.h" +#include "Array2D.h" namespace o2 { @@ -40,8 +41,7 @@ class ClusterAccumulator GPUd() tpccf::Charge updateInner(PackedCharge, tpccf::Delta2); GPUd() tpccf::Charge updateOuter(PackedCharge, tpccf::Delta2); - GPUd() void finalize(const ChargePos&, tpccf::Charge, tpccf::TPCTime, const GPUTPCGeometry&); - GPUd() bool toNative(const ChargePos&, tpccf::Charge, tpc::ClusterNative&, const GPUParam&) const; + GPUd() bool toNative(const ChargePos&, tpccf::Charge, tpc::ClusterNative&, const GPUParam&, tpccf::TPCTime, const Array2D&); private: float mQtot = 0; diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx index 1aeae812f5193..407deb6a588d0 100644 --- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx +++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.cxx @@ -80,10 +80,8 @@ GPUdii() void GPUTPCCFClusterizer::computeClustersImpl(int32_t nBlocks, int32_t } return; } - pc.finalize(pos, charge, fragment.start, clusterer.Param().tpcGeometry); - tpc::ClusterNative myCluster; - bool rejectCluster = !pc.toNative(pos, charge, myCluster, clusterer.Param()); + bool rejectCluster = !pc.toNative(pos, charge, myCluster, clusterer.Param(), fragment.start, chargeMap); if (rejectCluster) { if (clusterPosInRow) {