Project
Loading...
Searching...
No Matches
KrBoxClusterFinder.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
15
17#include "TPCBase/CalDet.h"
18#include "TPCBase/Utils.h"
19
20#include "Framework/Logger.h"
21
22#include <TFile.h>
23#include <vector>
24
25using namespace o2::tpc;
26
27// If a gain map already exists in form of a CalDet file, it can be specified here
28void KrBoxClusterFinder::loadGainMapFromFile(const std::string_view calDetFileName, const std::string_view gainMapName)
29{
30 auto calPads = utils::readCalPads(calDetFileName, gainMapName);
31 auto gain = calPads[0];
32
33 if (!gain) {
34 LOGP(error, "No valid gain map object '{}' could be loaded from file '{}'", calDetFileName, gainMapName);
35 return;
36 }
37 mGainMap.reset(gain);
38 LOGP(info, "Loaded gain map object '{}' from file '{}'", calDetFileName, gainMapName);
39}
40
41void KrBoxClusterFinder::createInitialMap(const gsl::span<const Digit> eventSector)
42{
43 mSetOfTimeSlices.clear();
44 mThresholdInfo.clear();
45
46 for (int iTimeSlice = 0; iTimeSlice <= 2 * mMaxClusterSizeTime; ++iTimeSlice) {
47 addTimeSlice(eventSector, iTimeSlice);
48 }
49}
50
51void KrBoxClusterFinder::fillADCValueInLastSlice(int cru, int rowInSector, int padInRow, float adcValue)
52{
53 auto& timeSlice = mSetOfTimeSlices.back();
54 auto& thresholdInfo = mThresholdInfo.back();
55
56 // Correct for pad offset:
57 const int padsInRow = mMapperInstance.getNumberOfPadsInRowSector(rowInSector);
58 const int corPad = padInRow - (padsInRow / 2) + (MaxPads / 2);
59
60 if (adcValue > mQThresholdMax) {
61 thresholdInfo.digitAboveThreshold = true;
62 thresholdInfo.rowAboveThreshold[rowInSector] = true;
63 }
64
65 // Get correction factor from gain map:
66 const auto correctionFactorCalDet = mGainMap.get();
67 if (!correctionFactorCalDet) {
68 timeSlice[rowInSector][corPad] = adcValue;
69 return;
70 }
71
72 int padNum = mMapperInstance.globalPadNumber(PadPos(rowInSector, padInRow));
73 float correctionFactor = correctionFactorCalDet->getValue(mSector, padNum);
74
75 if (correctionFactor <= 0) {
76 LOGP(warning, "Encountered correction factor which is zero.");
77 LOGP(warning, "Digit will be set to 0!");
78 adcValue = 0;
79 } else {
80 adcValue /= correctionFactor;
81 }
82
83 timeSlice[rowInSector][corPad] = adcValue;
84}
85
86void KrBoxClusterFinder::addTimeSlice(const gsl::span<const Digit> eventSector, const int timeSlice)
87{
88 mSetOfTimeSlices.emplace_back();
89 mThresholdInfo.emplace_back();
90
91 for (; mFirstDigit < eventSector.size(); ++mFirstDigit) {
92 const auto& digit = eventSector[mFirstDigit];
93 const int time = digit.getTimeStamp();
94 if (time != timeSlice) {
95 return;
96 }
97
98 const int cru = digit.getCRU();
99 mSector = cru / CRU::CRUperSector;
100
101 const int rowInSector = digit.getRow();
102 const int padInRow = digit.getPad();
103 const float adcValue = digit.getChargeFloat();
104
105 fillADCValueInLastSlice(cru, rowInSector, padInRow, adcValue);
106 }
107}
108
109void KrBoxClusterFinder::loopOverSector(const gsl::span<const Digit> eventSector, const int sector)
110{
111 mFirstDigit = 0;
112 mSector = sector;
113
114 createInitialMap(eventSector);
115 for (int iTimeSlice = mMaxClusterSizeTime; iTimeSlice < mMaxTimes - mMaxClusterSizeTime; ++iTimeSlice) {
116 // only search for a local maximum if the central time slice has at least one ADC above the charge threshold
117 if (mThresholdInfo[mMaxClusterSizeTime].digitAboveThreshold) {
118 findLocalMaxima(true, iTimeSlice);
119 }
120 popFirstTimeSliceFromMap();
121 addTimeSlice(eventSector, iTimeSlice + mMaxClusterSizeTime + 1);
122
123 // don't spend unnecessary time looping till mMaxTimes if there is no more data
124 if (mFirstDigit >= eventSector.size()) {
125 break;
126 }
127 }
128}
129
131{
133
134 mMaxClusterSizeTime = param.MaxClusterSizeTime;
135
136 mMaxClusterSizeRowIROC = param.MaxClusterSizeRowIROC;
137 mMaxClusterSizeRowOROC1 = param.MaxClusterSizeRowOROC1;
138 mMaxClusterSizeRowOROC2 = param.MaxClusterSizeRowOROC2;
139 mMaxClusterSizeRowOROC3 = param.MaxClusterSizeRowOROC3;
140
141 mMaxClusterSizePadIROC = param.MaxClusterSizePadIROC;
142 mMaxClusterSizePadOROC1 = param.MaxClusterSizePadOROC1;
143 mMaxClusterSizePadOROC2 = param.MaxClusterSizePadOROC2;
144 mMaxClusterSizePadOROC3 = param.MaxClusterSizePadOROC3;
145
146 mQThresholdMax = param.QThresholdMax;
147 mQThreshold = param.QThreshold;
148 mMinNumberOfNeighbours = param.MinNumberOfNeighbours;
149
150 mCutMinSigmaTime = param.CutMinSigmaTime;
151 mCutMaxSigmaTime = param.CutMaxSigmaTime;
152 mCutMinSigmaPad = param.CutMinSigmaPad;
153 mCutMaxSigmaPad = param.CutMaxSigmaPad;
154 mCutMinSigmaRow = param.CutMinSigmaRow;
155 mCutMaxSigmaRow = param.CutMaxSigmaRow;
156 mCutMaxQtot = param.CutMaxQtot;
157 mCutQtot0 = param.CutQtot0;
158 mCutQtotSizeSlope = param.CutQtotSizeSlope;
159 mCutMaxSize = param.CutMaxSize;
160 mApplyCuts = param.ApplyCuts;
161
162 if (param.GainMapFile.size()) {
163 LOGP(info, "loading gain map '{}' from file {}", param.GainMapName, param.GainMapFile);
164 loadGainMapFromFile(param.GainMapFile, param.GainMapName);
165 }
166}
167
168//#################################################
169
170// Function to update the temporal cluster
171void KrBoxClusterFinder::updateTempClusterFinal(const int timeOffset)
172{
173 if (mTempCluster.totCharge == 0) {
174 mTempCluster.reset();
175 } else {
176 const float oneOverQtot = 1. / mTempCluster.totCharge;
177 mTempCluster.meanPad *= oneOverQtot;
178 mTempCluster.sigmaPad *= oneOverQtot;
179 mTempCluster.meanRow *= oneOverQtot;
180 mTempCluster.sigmaRow *= oneOverQtot;
181 mTempCluster.meanTime *= oneOverQtot;
182 mTempCluster.sigmaTime *= oneOverQtot;
183 mTempCluster.sigmaPad = std::sqrt(std::abs(mTempCluster.sigmaPad - mTempCluster.meanPad * mTempCluster.meanPad));
184 mTempCluster.sigmaRow = std::sqrt(std::abs(mTempCluster.sigmaRow - mTempCluster.meanRow * mTempCluster.meanRow));
185 mTempCluster.sigmaTime = std::sqrt(std::abs(mTempCluster.sigmaTime - mTempCluster.meanTime * mTempCluster.meanTime));
186
187 const int corPadsMean = mMapperInstance.getNumberOfPadsInRowSector(int(mTempCluster.meanRow));
188 const int corPadsMaxCharge = mMapperInstance.getNumberOfPadsInRowSector(int(mTempCluster.maxChargeRow));
189
190 // Since every padrow is shifted such that neighbouring pads are indeed neighbours, we have to shift once back:
191 mTempCluster.meanPad = mTempCluster.meanPad + (corPadsMean / 2.0) - (MaxPads / 2.0);
192 mTempCluster.maxChargePad = mTempCluster.maxChargePad + (corPadsMaxCharge / 2.0) - (MaxPads / 2.0);
193 mTempCluster.sector = (decltype(mTempCluster.sector))mSector;
194
195 mTempCluster.meanTime += timeOffset;
196 }
197}
198
199// Function to update the temporal cluster.
200void KrBoxClusterFinder::updateTempCluster(float tempCharge, int tempPad, int tempRow, int tempTime)
201{
202 if (tempCharge < mQThreshold) {
203 LOGP(warning, "Update cluster was called but current charge is below mQThreshold");
204 return;
205 }
206
207 // Some extrem ugly shaped clusters (mostly noise) might lead to an overflow.
208 // Hence, we have to define an upper limit here:
209 if (mTempCluster.size < 255) {
210 mTempCluster.size += 1;
211 }
212
213 mTempCluster.totCharge += tempCharge;
214
215 mTempCluster.meanPad += tempPad * tempCharge;
216 mTempCluster.sigmaPad += tempPad * tempPad * tempCharge;
217
218 mTempCluster.meanRow += tempRow * tempCharge;
219 mTempCluster.sigmaRow += tempRow * tempRow * tempCharge;
220
221 mTempCluster.meanTime += tempTime * tempCharge;
222 mTempCluster.sigmaTime += tempTime * tempTime * tempCharge;
223
224 if (tempCharge > mTempCluster.maxCharge) {
225 mTempCluster.maxCharge = tempCharge;
226 mTempCluster.maxChargePad = tempPad;
227 mTempCluster.maxChargeRow = tempRow;
228 }
229}
230
231// This function finds and evaluates all clusters in a 3D mSetOfTimeSlices generated by the
232// mSetOfTimeSlicesCreator function, this function also updates the cluster tree
233std::vector<std::tuple<int, int, int>> KrBoxClusterFinder::findLocalMaxima(bool directFilling, const int timeOffset)
234{
235 std::vector<std::tuple<int, int, int>> localMaximaCoords;
236
237 const int iTime = mMaxClusterSizeTime;
238 const auto& mapRow = mSetOfTimeSlices[iTime];
239 const auto& thresholdInfo = mThresholdInfo[iTime];
240
241 for (int iRow = 0; iRow < MaxRows; iRow++) { // mapRow.size()
242 // Since pad size is different for each ROC, we take this into account while looking for maxima:
243 // setMaxClusterSize(iRow);
244 if (iRow == 0) {
245 mMaxClusterSizePad = mMaxClusterSizePadIROC;
246 mMaxClusterSizeRow = mMaxClusterSizeRowIROC;
247 } else if (iRow == MaxRowsIROC) {
248 mMaxClusterSizePad = mMaxClusterSizePadOROC1;
249 mMaxClusterSizeRow = mMaxClusterSizeRowOROC1;
250 } else if (iRow == MaxRowsIROC + MaxRowsOROC1) {
251 mMaxClusterSizePad = mMaxClusterSizePadOROC2;
252 mMaxClusterSizeRow = mMaxClusterSizeRowOROC2;
253 } else if (iRow == MaxRowsIROC + MaxRowsOROC1 + MaxRowsOROC2) {
254 mMaxClusterSizePad = mMaxClusterSizePadOROC3;
255 mMaxClusterSizeRow = mMaxClusterSizeRowOROC3;
256 }
257 // skip rows that don't have charges above the threshold
258 if (!thresholdInfo.rowAboveThreshold[iRow]) {
259 continue;
260 }
261
262 const auto& mapPad = mapRow[iRow];
263 const int padsInRow = mMapperInstance.getNumberOfPadsInRowSector(iRow);
264
265 // Only loop over existing pads:
266 for (int iPad = MaxPads / 2 - padsInRow / 2; iPad < MaxPads / 2 + padsInRow / 2; iPad++) { // mapPad.size()
267
268 const float qMax = mapPad[iPad];
269
270 // cluster Maximum must at least be larger than Threshold
271 if (qMax <= mQThresholdMax) {
272 continue;
273 }
274
275 // Acceptance condition: Require at least mMinNumberOfNeighbours neigbours
276 // with signal in any direction!
277 int noNeighbours = 0;
278 if ((iPad + 1 < MaxPads) && (mapPad[iPad + 1] > mQThreshold)) {
279 if (mapPad[iPad + 1] > qMax) {
280 continue;
281 }
282 noNeighbours++;
283 }
284
285 if ((iPad - 1 >= 0) && (mapPad[iPad - 1] > mQThreshold)) {
286 if (mapPad[iPad - 1] > qMax) {
287 continue;
288 }
289 noNeighbours++;
290 }
291
292 if ((iRow + 1 < MaxRows) && (mSetOfTimeSlices[iTime][iRow + 1][iPad] > mQThreshold)) {
293 if (mSetOfTimeSlices[iTime][iRow + 1][iPad] > qMax) {
294 continue;
295 }
296 noNeighbours++;
297 }
298
299 if ((iRow - 1 >= 0) && (mSetOfTimeSlices[iTime][iRow - 1][iPad] > mQThreshold)) {
300 if (mSetOfTimeSlices[iTime][iRow - 1][iPad] > qMax) {
301 continue;
302 }
303 noNeighbours++;
304 }
305
306 if ((iTime + 1 < mMaxTimes) && (mSetOfTimeSlices[iTime + 1][iRow][iPad] > mQThreshold)) {
307 if (mSetOfTimeSlices[iTime + 1][iRow][iPad] > qMax) {
308 continue;
309 }
310 noNeighbours++;
311 }
312
313 if ((iTime - 1 >= 0) && (mSetOfTimeSlices[iTime - 1][iRow][iPad] > mQThreshold)) {
314 if (mSetOfTimeSlices[iTime - 1][iRow][iPad] > qMax) {
315 continue;
316 }
317 noNeighbours++;
318 }
319 if (noNeighbours < mMinNumberOfNeighbours) {
320 continue;
321 }
322
323 // Check that this is a local maximum
324 // Note that the checking is done so that if 2 charges have the same
325 // qMax then only 1 cluster is generated
326 // (that is why there is BOTH > and >=)
327 // -> only the maximum with the smalest indices will be accepted
328 bool thisIsMax = true;
329
330 for (int j = -mMaxClusterSizeTime; (j <= mMaxClusterSizeTime) && thisIsMax; j++) {
331 if ((iTime + j >= mMaxTimes) || (iTime + j < 0)) {
332 continue;
333 }
334 for (int k = -mMaxClusterSizeRow; (k <= mMaxClusterSizeRow) && thisIsMax; k++) {
335 if ((iRow + k >= MaxRows) || (iRow + k < 0)) {
336 continue;
337 }
338 for (int i = -mMaxClusterSizePad; (i <= mMaxClusterSizePad) && thisIsMax; i++) {
339 if ((iPad + i >= MaxPads) || (iPad + i < 0)) {
340 continue;
341 }
342 if (mSetOfTimeSlices[iTime + j][iRow + k][iPad + i] > qMax) {
343 thisIsMax = false;
344 }
345 }
346 }
347 }
348
349 if (!thisIsMax) {
350 continue;
351 } else {
352 if (directFilling) {
353
354 buildCluster(iPad, iRow, iTime, directFilling, timeOffset);
355 } else {
356 localMaximaCoords.emplace_back(std::make_tuple(iPad, iRow, iTime));
357 }
358
359 // If we have found a local maximum, we can also skip the next few entries:
360 iPad += mMaxClusterSizePad;
361 }
362 }
363 }
364
365 return localMaximaCoords;
366}
367
368// Calculate the total charge as the sum over the region:
369//
370// o o o o o
371// o i i i o
372// o i C i o
373// o i i i o
374// o o o o o
375//
376// with qmax at the center C.
377//
378// The inner charge (i) we always add, but we only add the outer
379// charge (o) if the neighboring inner bin (i) has a signal.
380//
381
382// for loop over whole cluster, to determine if a charge should be added
383// conditions are extrapolation of the 5x5 cluster case to arbitrary
384// cluster sizes in 3 dimensions
385KrCluster KrBoxClusterFinder::buildCluster(int clusterCenterPad, int clusterCenterRow, int clusterCenterTime, bool directFilling, const int timeOffset)
386{
387 mTempCluster.reset();
388 setMaxClusterSize(clusterCenterRow);
389
390 // Loop over all neighbouring time bins:
391 for (int iTime = -mMaxClusterSizeTime; iTime <= mMaxClusterSizeTime; iTime++) {
392 // Loop over all neighbouring row bins:
393
394 for (int iRow = -mMaxClusterSizeRow; iRow <= mMaxClusterSizeRow; iRow++) {
395 // First: Check if we look over array boundaries:
396 if (clusterCenterRow + iRow < 0) {
397 continue;
398 } else if (clusterCenterRow + iRow >= MaxRows) {
399 break;
400 }
401 // Second: Check if we might look over ROC boundaries:
402 else if (clusterCenterRow < MaxRowsIROC) {
403 if (clusterCenterRow + iRow > MaxRowsIROC) {
404 break;
405 }
406 } else if (clusterCenterRow < MaxRowsIROC + MaxRowsOROC1) {
407 if (clusterCenterRow + iRow < MaxRowsIROC || clusterCenterRow + iRow >= MaxRowsIROC + MaxRowsOROC1) {
408 continue;
409 }
410 } else if (clusterCenterRow < MaxRowsIROC + MaxRowsOROC1 + MaxRowsOROC2) {
411 if (clusterCenterRow + iRow < MaxRowsIROC + MaxRowsOROC1 || clusterCenterRow + iRow >= MaxRowsIROC + MaxRowsOROC1 + MaxRowsOROC2) {
412 continue;
413 }
414 } else if (clusterCenterRow < MaxRowsIROC + MaxRowsOROC1 + MaxRowsOROC2 + MaxRowsOROC3) {
415 if (clusterCenterRow + iRow < MaxRowsIROC + MaxRowsOROC1 + MaxRowsOROC2) {
416 continue;
417 }
418 }
419
420 // Loop over all neighbouring pad bins:
421 for (int iPad = -mMaxClusterSizePad; iPad <= mMaxClusterSizePad; iPad++) {
422 // First: Check again if we might look outside of map:
423 if (clusterCenterPad + iPad < 0) {
424 continue;
425 } else if (clusterCenterPad + iPad >= MaxPads) {
426 break;
427 }
428
429 // Second: Check if charge is above threshold
430 // Might be not necessary since we deal with pedestal subtracted data
431 if (mSetOfTimeSlices[clusterCenterTime + iTime][clusterCenterRow + iRow][clusterCenterPad + iPad] <= mQThreshold) {
432 continue;
433 }
434 // If not, there are several cases which were explained (for 2D) in the header of the code.
435 // The first one is for the diagonal. So, the digit we are investigating here is on the diagonal:
436 if (std::abs(iTime) == std::abs(iPad) && std::abs(iTime) == std::abs(iRow)) {
437 // Now we check, if the next inner digit has a signal above threshold:
438 if (mSetOfTimeSlices[clusterCenterTime + iTime - signnum(iTime)][clusterCenterRow + iRow - signnum(iRow)][clusterCenterPad + iPad - signnum(iPad)] > mQThreshold) {
439 // If yes, the cluster gets updated with the digit on the diagonal.
440 updateTempCluster(mSetOfTimeSlices[clusterCenterTime + iTime][clusterCenterRow + iRow][clusterCenterPad + iPad], clusterCenterPad + iPad, clusterCenterRow + iRow, clusterCenterTime + iTime);
441 }
442 }
443 // Basically, we go through every possible case in the next few if-else conditions:
444 else if (std::abs(iTime) == std::abs(iPad)) {
445 if (mSetOfTimeSlices[clusterCenterTime + iTime - signnum(iTime)][clusterCenterRow + iRow][clusterCenterPad + iPad - signnum(iPad)] > mQThreshold) {
446 updateTempCluster(mSetOfTimeSlices[clusterCenterTime + iTime][clusterCenterRow + iRow][clusterCenterPad + iPad], clusterCenterPad + iPad, clusterCenterRow + iRow, clusterCenterTime + iTime);
447 }
448 } else if (std::abs(iTime) == std::abs(iRow)) {
449 if (mSetOfTimeSlices[clusterCenterTime + iTime - signnum(iTime)][clusterCenterRow + iRow - signnum(iRow)][clusterCenterPad + iPad] > mQThreshold) {
450 updateTempCluster(mSetOfTimeSlices[clusterCenterTime + iTime][clusterCenterRow + iRow][clusterCenterPad + iPad], clusterCenterPad + iPad, clusterCenterRow + iRow, clusterCenterTime + iTime);
451 }
452 } else if (std::abs(iPad) == std::abs(iRow)) {
453 if (mSetOfTimeSlices[clusterCenterTime + iTime][clusterCenterRow + iRow - signnum(iRow)][clusterCenterPad + iPad - signnum(iPad)] > mQThreshold) {
454 updateTempCluster(mSetOfTimeSlices[clusterCenterTime + iTime][clusterCenterRow + iRow][clusterCenterPad + iPad], clusterCenterPad + iPad, clusterCenterRow + iRow, clusterCenterTime + iTime);
455 }
456 } else if (std::abs(iTime) > std::abs(iPad) && std::abs(iTime) > std::abs(iRow)) {
457 if (mSetOfTimeSlices[clusterCenterTime + iTime - signnum(iTime)][clusterCenterRow + iRow][clusterCenterPad + iPad] > mQThreshold) {
458 updateTempCluster(mSetOfTimeSlices[clusterCenterTime + iTime][clusterCenterRow + iRow][clusterCenterPad + iPad], clusterCenterPad + iPad, clusterCenterRow + iRow, clusterCenterTime + iTime);
459 }
460 } else if (std::abs(iTime) < std::abs(iPad) && std::abs(iPad) > std::abs(iRow)) {
461 if (mSetOfTimeSlices[clusterCenterTime + iTime][clusterCenterRow + iRow][clusterCenterPad + iPad - signnum(iPad)] > mQThreshold) {
462 updateTempCluster(mSetOfTimeSlices[clusterCenterTime + iTime][clusterCenterRow + iRow][clusterCenterPad + iPad], clusterCenterPad + iPad, clusterCenterRow + iRow, clusterCenterTime + iTime);
463 }
464 } else if (std::abs(iTime) < std::abs(iRow) && std::abs(iPad) < std::abs(iRow)) {
465 if (mSetOfTimeSlices[clusterCenterTime + iTime][clusterCenterRow + iRow - signnum(iRow)][clusterCenterPad + iPad] > mQThreshold) {
466 updateTempCluster(mSetOfTimeSlices[clusterCenterTime + iTime][clusterCenterRow + iRow][clusterCenterPad + iPad], clusterCenterPad + iPad, clusterCenterRow + iRow, clusterCenterTime + iTime);
467 }
468 }
469 }
470 }
471 }
472 // At the end, out mTempCluster should contain all digits that were assigned to the cluster.
473 // So before returning it, we update it one last time to calculate the correct means and sigmas.
474
475 updateTempClusterFinal(timeOffset);
476
477 if (directFilling) {
478 if (!mApplyCuts || acceptCluster(mTempCluster)) {
479 mClusters.emplace_back(mTempCluster);
480 }
481 }
482
483 return mTempCluster;
484}
485
486// Check if we are in IROC, OROC1, OROC2 or OROC3 and adapt the box size (max cluster size) accordingly.
488{
489 if (row < MaxRowsIROC) {
490 mMaxClusterSizePad = mMaxClusterSizePadIROC;
491 mMaxClusterSizeRow = mMaxClusterSizeRowIROC;
492 } else if (row < MaxRowsIROC + MaxRowsOROC1) {
493 mMaxClusterSizePad = mMaxClusterSizePadOROC1;
494 mMaxClusterSizeRow = mMaxClusterSizeRowOROC1;
495 } else if (row < MaxRowsIROC + MaxRowsOROC1 + MaxRowsOROC2) {
496 mMaxClusterSizePad = mMaxClusterSizePadOROC2;
497 mMaxClusterSizeRow = mMaxClusterSizeRowOROC2;
498 } else if (row < MaxRowsIROC + MaxRowsOROC1 + MaxRowsOROC2 + MaxRowsOROC3) {
499 mMaxClusterSizePad = mMaxClusterSizePadOROC3;
500 mMaxClusterSizeRow = mMaxClusterSizeRowOROC3;
501 }
502}
503
504bool KrBoxClusterFinder::acceptCluster(const KrCluster& cl)
505{
506 // Qtot cut
507 if (cl.totCharge > mCutMaxQtot) {
508 return false;
509 }
510
511 // sigma cuts
512 if (cl.sigmaPad < mCutMinSigmaPad || cl.sigmaPad > mCutMaxSigmaPad ||
513 cl.sigmaRow < mCutMinSigmaRow || cl.sigmaRow > mCutMaxSigmaRow ||
514 cl.sigmaTime < mCutMinSigmaTime || cl.sigmaRow > mCutMaxSigmaTime) {
515 return false;
516 }
517
518 // total charge vs size cut
519 if (cl.totCharge > mCutQtot0 + mCutQtotSizeSlope * cl.size) {
520 return false;
521 }
522
523 // maximal size
524 if (cl.size > mCutMaxSize) {
525 return false;
526 }
527
528 return true;
529}
int16_t time
Definition RawEventData.h:4
int32_t i
uint32_t j
Definition RawData.h:0
@ CRUperSector
Definition CRU.h:30
void loadGainMapFromFile(const std::string_view calDetFileName, const std::string_view gainMapName="GainMap")
void init()
initialize the parameters from KrBoxClusterFinderParam
void loopOverSector(const gsl::span< const Digit > eventSector, const int sector)
std::vector< std::tuple< int, int, int > > findLocalMaxima(bool directFilling=true, const int timeOffset=0)
After the map is created, we look for local maxima with this function:
KrCluster buildCluster(int clusterCenterPad, int clusterCenterRow, int clusterCenterTime, bool directFilling=false, const int timeOffset=0)
void setMaxClusterSize(int maxClusterSizeRowIROC, int maxClusterSizeRowOROC1, int maxClusterSizeRowOROC2, int maxClusterSizeRowOROC3, int maxClusterSizePadIROC, int maxClusterSizePadOROC1, int maxClusterSizePadOROC2, int maxClusterSizePadOROC3, int maxClusterSizeTime)
Set Function for maximal cluster sizes in different ROCs.
int getNumberOfPadsInRowSector(int row) const
Definition Mapper.h:340
GlobalPadNumber globalPadNumber(const PadPos &globalPadPosition) const
Definition Mapper.h:56
GLenum GLfloat param
Definition glcorearb.h:271
std::vector< CalPad * > readCalPads(const std::string_view fileName, const std::vector< std::string > &calPadNames)
Definition Utils.cxx:190
Global TPC definitions and constants.
Definition SimTraits.h:167
float meanPad
Center of gravity (Pad number)
Definition KrCluster.h:34
float meanTime
Center of gravity (Time)
Definition KrCluster.h:38
float maxCharge
Maximum charge of the cluster (ADC counts)
Definition KrCluster.h:33
unsigned char sector
Sector number.
Definition KrCluster.h:29
float sigmaTime
RMS of cluster in time direction.
Definition KrCluster.h:39
unsigned char maxChargePad
Pad with max. charge in cluster (for leader pad method)
Definition KrCluster.h:30
void reset()
Used to set all Cluster variables to zero.
Definition KrCluster.h:49
float meanRow
Center of gravity (Row number)
Definition KrCluster.h:35
float sigmaPad
RMS of cluster in pad direction.
Definition KrCluster.h:36
float sigmaRow
RMS of cluster in row direction.
Definition KrCluster.h:37
float totCharge
Total charge of the cluster (ADC counts)
Definition KrCluster.h:32
unsigned char size
Size of the cluster (TPCDigits)
Definition KrCluster.h:28
unsigned char maxChargeRow
Row with max. charge in cluster (for leader pad method)
Definition KrCluster.h:31
std::vector< int > row