Skip to content

Commit d9e8683

Browse files
KlewinSsawenzel
authored andcommitted
add TPC cluster reject options (#1376)
* change output container in task only in one place * add cluster reject options * fix HwClusterer test case 6 * add option to not clear output container first * fix clang-format * update ClustererSpec.cxx
1 parent 49b3bb0 commit d9e8683

File tree

6 files changed

+1251
-229
lines changed

6 files changed

+1251
-229
lines changed

Detectors/TPC/reconstruction/include/TPCReconstruction/ClustererTask.h

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -34,44 +34,46 @@ namespace TPC{
3434
class ClustererTask : public FairTask{
3535

3636
using MCLabelContainer = o2::dataformats::MCTruthContainer<o2::MCCompLabel>;
37+
// using OutputType = Cluster;
38+
using OutputType = ClusterHardwareContainer8kb;
3739

38-
public:
39-
/// Default constructor
40-
/// \param sectorid Sector to be processed
41-
ClustererTask(int sectorid = -1);
40+
public:
41+
/// Default constructor
42+
/// \param sectorid Sector to be processed
43+
ClustererTask(int sectorid = -1);
4244

43-
/// Destructor
44-
~ClustererTask() override = default;
45+
/// Destructor
46+
~ClustererTask() override = default;
4547

46-
/// Initializes the clusterer and connects input and output container
47-
InitStatus Init() override;
48+
/// Initializes the clusterer and connects input and output container
49+
InitStatus Init() override;
4850

49-
/// Clusterization
50-
void Exec(Option_t* option) override;
51+
/// Clusterization
52+
void Exec(Option_t* option) override;
5153

52-
/// Complete Clusterization
53-
void FinishTask() override;
54+
/// Complete Clusterization
55+
void FinishTask() override;
5456

55-
/// Switch for triggered / continuous readout
56-
/// \param isContinuous - false for triggered readout, true for continuous readout
57-
void setContinuousReadout(bool isContinuous);
57+
/// Switch for triggered / continuous readout
58+
/// \param isContinuous - false for triggered readout, true for continuous readout
59+
void setContinuousReadout(bool isContinuous);
5860

59-
private:
60-
bool mIsContinuousReadout; ///< Switch for continuous readout
61-
int mEventCount; ///< Event counter
62-
int mClusterSector; ///< Sector to be processed
61+
private:
62+
bool mIsContinuousReadout; ///< Switch for continuous readout
63+
int mEventCount; ///< Event counter
64+
int mClusterSector; ///< Sector to be processed
6365

64-
std::unique_ptr<HwClusterer> mHwClusterer; ///< Hw Clusterfinder instance
66+
std::unique_ptr<HwClusterer> mHwClusterer; ///< Hw Clusterfinder instance
6567

66-
// Digit arrays
67-
std::unique_ptr<const std::vector<Digit>> mDigitsArray; ///< Array of TPC digits
68-
std::unique_ptr<const MCLabelContainer> mDigitMCTruthArray; ///< Array for MCTruth information associated to digits in mDigitsArrray
68+
// Digit arrays
69+
std::unique_ptr<const std::vector<Digit>> mDigitsArray; ///< Array of TPC digits
70+
std::unique_ptr<const MCLabelContainer> mDigitMCTruthArray; ///< Array for MCTruth information associated to digits in mDigitsArrray
6971

70-
// Cluster arrays
71-
std::unique_ptr<std::vector<ClusterHardwareContainer8kb>> mHwClustersArray; ///< Array of clusters found by Hw Clusterfinder
72-
std::unique_ptr<MCLabelContainer> mHwClustersMCTruthArray; ///< Array for MCTruth information associated to cluster in mHwClustersArrays
72+
// Cluster arrays
73+
std::unique_ptr<std::vector<OutputType>> mHwClustersArray; ///< Array of clusters found by Hw Clusterfinder
74+
std::unique_ptr<MCLabelContainer> mHwClustersMCTruthArray; ///< Array for MCTruth information associated to cluster in mHwClustersArrays
7375

74-
ClassDefOverride(ClustererTask, 1)
76+
ClassDefOverride(ClustererTask, 1)
7577
};
7678

7779
inline

Detectors/TPC/reconstruction/include/TPCReconstruction/HwClusterer.h

Lines changed: 67 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,16 @@ class HwClusterer : public Clusterer
7676
/// Process digits
7777
/// \param digits Container with TPC digits
7878
/// \param mcDigitTruth MC Digit Truth container
79+
/// \param clearContainerFirst Clears the outpcontainer for clusters and MC labels first, before processing
7980
void process(std::vector<o2::TPC::Digit> const& digits, MCLabelContainer const* mcDigitTruth) override;
81+
void process(std::vector<o2::TPC::Digit> const& digits, MCLabelContainer const* mcDigitTruth, bool clearContainerFirst);
8082

8183
/// Finish processing digits
8284
/// \param digits Container with TPC digits
8385
/// \param mcDigitTruth MC Digit Truth container
86+
/// \param clearContainerFirst Clears the outpcontainer for clusters and MC labels first, before processing
8487
void finishProcess(std::vector<o2::TPC::Digit> const& digits, MCLabelContainer const* mcDigitTruth) override;
88+
void finishProcess(std::vector<o2::TPC::Digit> const& digits, MCLabelContainer const* mcDigitTruth, bool clearContainerFirst);
8589

8690
/// Switch for triggered / continuous readout
8791
/// \param isContinuous - false for triggered readout, true for continuous readout
@@ -95,6 +99,24 @@ class HwClusterer : public Clusterer
9599
/// \param charge Threshold which will be used
96100
void setContributionChargeThreshold(unsigned charge);
97101

102+
/// Switch to reject single pad clusters
103+
/// \param doReject - true to reject clusters with sigmaPad2Pre == 0
104+
void setRejectSinglePadClusters(bool doReject);
105+
106+
/// Switch to reject single time clusters
107+
/// \param doReject - true to reject clusters with sigmaTime2Pre == 0
108+
void setRejectSingleTimeClusters(bool doReject);
109+
110+
/// Switch to reject peaks in following timebins
111+
/// \param doReject - true to reject peak, false to NOT reject peaks in following bins
112+
void setRejectLaterTimebin(bool doReject);
113+
114+
/// Switch for mode, how the charge should be shared among nearby clusters
115+
/// \param mode 0 for no splitting, charge is used for all found peaks,
116+
/// 1 for minimum contributes half to all peaks
117+
/// 2 for minimum contributes only to left/older peak
118+
void setSplittingMode(short mode);
119+
98120
private:
99121
/*
100122
* Helper functions
@@ -103,23 +125,23 @@ class HwClusterer : public Clusterer
103125
/// HW Cluster Processor
104126
/// \param peakMask VC-mask with only peaks enabled
105127
/// \param qMaxIndex Buffer index of center pad
106-
/// \param center_pad Pad number to be checked for cluster
107-
/// \param center_time Time to be checked for cluster
128+
/// \param centerPad Pad number to be checked for cluster
129+
/// \param centerTime Time to be checked for cluster
108130
/// \param row Row number for cluster properties
109-
void hwClusterProcessor(Vc::uint_m peakMask, unsigned qMaxIndex, short center_pad, int center_time, unsigned short row);
131+
void hwClusterProcessor(Vc::uint_m peakMask, unsigned qMaxIndex, short centerPad, int centerTime, unsigned short row);
110132

111133
/// HW Peak Finder
112134
/// \param qMaxIndex Buffer index of central pad
113-
/// \param center_pad Pad number to be checked for cluster
114-
/// \param center_time Time to be checked for cluster
135+
/// \param centerPad Pad number to be checked for cluster
136+
/// \param mappedCenterTime Time to be checked for cluster, mapped in available time space
115137
/// \param row Row number for cluster properties
116-
void hwPeakFinder(unsigned qMaxIndex, short center_pad, int center_time, unsigned short row);
138+
void hwPeakFinder(unsigned qMaxIndex, short centerPad, int mappedCenterTime, unsigned short row);
117139

118140
/// Helper function to update cluster properties and MC labels
119141
/// \param selectionMask VC-mask with slected pads enabled
120142
/// \param row Current row
121-
/// \param center_pad Pad of peak
122-
/// \param center_time Timebin of peak
143+
/// \param centerPad Pad of peak
144+
/// \param centerTime Timebin of peak
123145
/// \param dp delta pad
124146
/// \param dt delta time
125147
/// \param qTot Total charge
@@ -128,7 +150,7 @@ class HwClusterer : public Clusterer
128150
/// \param sigmaPad2 Weighted sigma pad ^2 parameter
129151
/// \param sigmaTime2 Weighted sigma time ^2 parameter
130152
/// \param mcLabel Vector with MClabel-counter-pairs
131-
void updateCluster(const Vc::uint_m selectionMask, int row, short center_pad, int center_time, short dp, short dt, Vc::uint_v& qTot, Vc::int_v& pad, Vc::int_v& time, Vc::int_v& sigmaPad2, Vc::int_v& sigmaTime2, std::vector<std::unique_ptr<std::vector<std::pair<MCCompLabel, unsigned>>>>& mcLabels);
153+
void updateCluster(const Vc::uint_m selectionMask, int row, short centerPad, int centerTime, short dp, short dt, Vc::uint_v& qTot, Vc::int_v& pad, Vc::int_v& time, Vc::int_v& sigmaPad2, Vc::int_v& sigmaTime2, std::vector<std::unique_ptr<std::vector<std::pair<MCCompLabel, unsigned>>>>& mcLabels, Vc::uint_m splitMask = Vc::Mask<uint>(false));
132154

133155
/// Writes clusters from temporary storage to cluster output
134156
/// \param timeOffset Time offset of cluster container
@@ -146,7 +168,7 @@ class HwClusterer : public Clusterer
146168
/// \param clear Clears data buffer afterwards (for not continuous readout)
147169
void finishFrame(bool clear = false);
148170

149-
/// Clears the buffer at given timebin TODO: and fills timebin with noise + pedestal
171+
/// Clears the buffer at given timebin
150172
/// \param timebin Timebin to be cleared
151173
void clearBuffer(int timebin);
152174

@@ -163,29 +185,25 @@ class HwClusterer : public Clusterer
163185
/// \param value some value
164186
Vc::uint_v getFpOfADC(const Vc::uint_v value);
165187

166-
/// Does the comparison between two pads and sets the bits accordingly
167-
/// \param qMaxIndex Buffer index of central pad
168-
/// \param compareIndex Buffer index of pad to compare with
169-
/// \param bitMax Bit to be set for peak finding
170-
/// \param bitMin Bit to be set for minimum finding
171-
/// \param row Row number
172-
void compareForPeak(const unsigned qMaxIndex, const unsigned compareIndex, const unsigned bitMax, const unsigned bitMin, const unsigned short row);
173-
174188
/*
175189
* class members
176190
*/
177-
static const int mTimebinsInBuffer = 5;
191+
static const int mTimebinsInBuffer = 6;
178192

179193
unsigned short mNumRows; ///< Number of rows in this sector
180194
unsigned short mNumRowSets; ///< Number of row sets (Number of rows / Vc::Size) in this sector
181195
short mCurrentMcContainerInBuffer; ///< Bit field, where to find the current MC container in buffer
196+
short mSplittingMode; ///< Cluster splitting mode, 0 no splitting, 1 for minimum contributes half to both, 2 for miminum corresponds to left/older cluster
182197
int mClusterSector; ///< Sector to be processed
183198
int mLastTimebin; ///< Last time bin of previous event
184199
unsigned mLastHB; ///< Last HB bin of previous event
185200
unsigned mPeakChargeThreshold; ///< Charge threshold for the central peak in ADC counts
186201
unsigned mContributionChargeThreshold; ///< Charge threshold for the contributing pads in ADC counts
187202
unsigned mClusterCounter; ///< Cluster counter in output container for MC truth matching
188203
bool mIsContinuousReadout; ///< Switch for continuous readout
204+
bool mRejectSinglePadClusters; ///< Switch to reject single pad clusters, sigmaPad2Pre == 0
205+
bool mRejectSingleTimeClusters; ///< Switch to reject single time clusters, sigmaTime2Pre == 0
206+
bool mRejectLaterTimebin; ///< Switch to reject peaks in later timebins of the same pad
189207

190208
std::vector<unsigned short> mPadsPerRow; ///< Number of pads for given row (offset of 2 pads on both sides is already added)
191209
std::vector<unsigned short> mPadsPerRowSet; ///< Number of pads for given row set (offset of 2 pads on both sides is already added), a row set combines rows for parallel SIMD processing
@@ -205,6 +223,16 @@ class HwClusterer : public Clusterer
205223
MCLabelContainer* mClusterMcLabelArray; ///< Pointer to MC Label container
206224
};
207225

226+
inline void HwClusterer::process(std::vector<o2::TPC::Digit> const& digits, o2::dataformats::MCTruthContainer<o2::MCCompLabel> const* mcDigitTruth)
227+
{
228+
process(digits, mcDigitTruth, true);
229+
}
230+
231+
inline void HwClusterer::finishProcess(std::vector<o2::TPC::Digit> const& digits, o2::dataformats::MCTruthContainer<o2::MCCompLabel> const* mcDigitTruth)
232+
{
233+
finishProcess(digits, mcDigitTruth, true);
234+
}
235+
208236
inline void HwClusterer::setContinuousReadout(bool isContinuous)
209237
{
210238
mIsContinuousReadout = isContinuous;
@@ -220,6 +248,26 @@ inline void HwClusterer::setContributionChargeThreshold(unsigned charge)
220248
mContributionChargeThreshold = charge;
221249
}
222250

251+
inline void HwClusterer::setRejectSinglePadClusters(bool doReject)
252+
{
253+
mRejectSinglePadClusters = doReject;
254+
}
255+
256+
inline void HwClusterer::setRejectSingleTimeClusters(bool doReject)
257+
{
258+
mRejectSingleTimeClusters = doReject;
259+
}
260+
261+
inline void HwClusterer::setRejectLaterTimebin(bool doReject)
262+
{
263+
mRejectLaterTimebin = doReject;
264+
}
265+
266+
inline void HwClusterer::setSplittingMode(short mode)
267+
{
268+
mSplittingMode = mode;
269+
}
270+
223271
inline int HwClusterer::mapTimeInRange(int time)
224272
{
225273
return (mTimebinsInBuffer + (time % mTimebinsInBuffer)) % mTimebinsInBuffer;
@@ -239,57 +287,6 @@ inline short HwClusterer::getFirstSetBitOfField()
239287
return -1;
240288
}
241289

242-
inline void HwClusterer::compareForPeak(const unsigned qMaxIndex, const unsigned compareIndex, const unsigned bitMax, const unsigned bitMin, const unsigned short row)
243-
{
244-
245-
const auto tmpMask = getFpOfADC(mDataBuffer[row][qMaxIndex]) >= getFpOfADC(mDataBuffer[row][compareIndex]);
246-
247-
// current center could be peak in one direction
248-
where(tmpMask) | mDataBuffer[row][qMaxIndex] |= (0x1 << bitMax);
249-
250-
// other is smaller than center
251-
// and if other one was not a peak candidate before (bit is 0), it is a minimum in one direction,
252-
// so bitMin has to be set to inverse of bitMax of pad to compare
253-
where(tmpMask) | mDataBuffer[row][compareIndex] |= (~mDataBuffer[row][compareIndex] & (0x1 << bitMax)) >> (bitMax - bitMin);
254-
255-
// other is not peak
256-
where(tmpMask) | mDataBuffer[row][compareIndex] &= ~(0x1 << bitMax);
257-
258-
// other is peak if bit was already set
259-
where(!tmpMask) | mDataBuffer[row][compareIndex] |= (mDataBuffer[row][compareIndex] & (0x1 << bitMax));
260-
}
261-
262-
inline void HwClusterer::updateCluster(
263-
const Vc::uint_m selectionMask, int row, short center_pad, int center_time, short dp, short dt,
264-
Vc::uint_v& qTot, Vc::int_v& pad, Vc::int_v& time, Vc::int_v& sigmaPad2, Vc::int_v& sigmaTime2,
265-
std::vector<std::unique_ptr<std::vector<std::pair<MCCompLabel, unsigned>>>>& mcLabels)
266-
{
267-
const int mappedTime = mapTimeInRange(center_time + dt);
268-
const int index = mappedTime * mPadsPerRowSet[row] + center_pad + dp;
269-
270-
where(selectionMask) | qTot += getFpOfADC(mDataBuffer[row][index]);
271-
where(selectionMask) | pad += getFpOfADC(mDataBuffer[row][index]) * dp;
272-
where(selectionMask) | time += getFpOfADC(mDataBuffer[row][index]) * dt;
273-
where(selectionMask) | sigmaPad2 += getFpOfADC(mDataBuffer[row][index]) * dp * dp;
274-
where(selectionMask) | sigmaTime2 += getFpOfADC(mDataBuffer[row][index]) * dt * dt;
275-
276-
for (int i = 0; i < Vc::uint_v::Size; ++i) {
277-
if (selectionMask[i] && mMCtruth[mappedTime] != nullptr) {
278-
for (auto& label : mMCtruth[mappedTime]->getLabels(mIndexBuffer[row][index][i])) {
279-
bool isKnown = false;
280-
for (auto& vecLabel : *mcLabels[i]) {
281-
if (label == vecLabel.first) {
282-
++vecLabel.second;
283-
isKnown = true;
284-
}
285-
}
286-
if (!isKnown) {
287-
mcLabels[i]->emplace_back(label, 1);
288-
}
289-
}
290-
}
291-
}
292-
}
293290
}
294291
}
295292

Detectors/TPC/reconstruction/src/ClustererTask.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ InitStatus ClustererTask::Init()
7272
}
7373

7474
// Register output container
75-
mHwClustersArray = std::make_unique<std::vector<ClusterHardwareContainer8kb>>();
75+
mHwClustersArray = std::make_unique<std::vector<OutputType>>();
7676
// a trick to register the unique pointer with FairRootManager
7777
static auto clusterArrayTmpPtr = mHwClustersArray.get();
7878
mgr->RegisterAny(Form("TPCClusterHW%i", mClusterSector), clusterArrayTmpPtr, kTRUE);

0 commit comments

Comments
 (0)