Skip to content

Commit 6818bb1

Browse files
matthias-kleinershahor02
authored andcommitted
TPC IDC: optimizing outlier filtering
Outlier map: - 1. check for obvious outlier (IDCs around median +- nSigma) - 2. check FECs: masking FECs which are out of sync - 3. check neighbouring outliers (in case not all outlier for larger areas are recognized) Other changes IDCCCDBHelper - add function to get the mean value for IDC0 IDC Drawing - draw plots in current canvas if one is created - draw sector informations IDCFactorize - parallelize loading of large objects from file - add function to normalize IDCZero by gain map and/or median per stack - Moving dump to TTree functionality to CCDBHelper implementation TPC Mapper - mapper make function constexpr
1 parent a9bbc55 commit 6818bb1

File tree

11 files changed

+600
-227
lines changed

11 files changed

+600
-227
lines changed

Detectors/TPC/base/include/TPCBase/Mapper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ class Mapper
405405
static constexpr unsigned short getPadsInOROC() { return mPadsInOROC; }
406406
static constexpr unsigned short getPadsInSector() { return mPadsInSector; }
407407

408-
unsigned short getNumberOfPads(const GEMstack gemStack) const
408+
static constexpr unsigned short getNumberOfPads(const GEMstack gemStack)
409409
{
410410
switch (gemStack) {
411411
case IROCgem: {

Detectors/TPC/calibration/include/TPCCalibration/IDCCCDBHelper.h

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class CalDet;
3939

4040
/*
4141
Usage
42-
o2::tpc::IDCCCDBHelper<short> helper;
42+
o2::tpc::IDCCCDBHelper<unsigned short> helper;
4343
// setting the IDC members manually
4444
helper.setIDCDelta(IDCDelta<DataT>* idcDelta);
4545
helper.setIDCZero(IDCZero* idcZero);
@@ -77,17 +77,8 @@ class IDCCCDBHelper
7777

7878
/// set scaling of IDC0 to 1
7979
/// \param rejectOutlier do not take outlier into account
80-
void setIDCZeroScale(const bool rejectOutlier = true)
81-
{
82-
mScaleIDC0Aside = this->scaleIDC0(Side::A, rejectOutlier);
83-
mScaleIDC0Cside = this->scaleIDC0(Side::C, rejectOutlier);
84-
/// check if IDC0 total is not zero, in that case no scalling is applied
85-
if (mScaleIDC0Aside == 0.0 || mScaleIDC0Cside == 0.0) {
86-
LOGP(error, "Please check the IDC0 total A side {} and C side {}, is zero, therefore no scaling applied!", mScaleIDC0Aside, mScaleIDC0Cside);
87-
mScaleIDC0Aside = 1.0;
88-
mScaleIDC0Cside = 1.0;
89-
}
90-
}
80+
void setIDCZeroScale(const bool rejectOutlier = true);
81+
9182
/// setting the grouping parameters
9283
void setGroupingParameter(IDCGroupHelperSector* helperSector, const Side side = Side::A) { mHelperSector[side] = helperSector; }
9384

@@ -187,16 +178,18 @@ class IDCCCDBHelper
187178
TCanvas* drawFourierCoeff(TCanvas* outputCanvas, Side side, int nbins1D, float xMin1D, float xMax1D) const;
188179

189180
/// dumping the loaded IDC0, IDC1 to a tree for debugging
181+
/// \param side TPC side of the data which will be dumped
190182
/// \param outFileName name of the output file
191-
void dumpToTree(const char* outFileName = "IDCCCDBTree.root") const;
183+
void dumpToTree(const Side side, const char* outFileName = "IDCCCDBTree.root") const;
192184

193185
/// dumping the loaded fourier coefficients to a tree
194186
/// \param outFileName name of the output file
195187
void dumpToFourierCoeffToTree(const char* outFileName = "FourierCCDBTree.root") const;
196188

197189
/// dumping the loaded IDC0, IDC1 to a tree for debugging
190+
/// \param side TPC side of the data which will be dumped
198191
/// \param outFileName name of the output file
199-
void dumpToTreeIDCDelta(const char* outFileName = "IDCCCDBTreeDeltaIDC.root") const;
192+
void dumpToTreeIDCDelta(const Side side, const char* outFileName = "IDCCCDBTreeDeltaIDC.root") const;
200193

201194
/// convert the loaded IDC0 map to a CalDet<float>
202195
/// \return returns CalDet containing the IDCZero
@@ -206,10 +199,34 @@ class IDCCCDBHelper
206199
/// \return returns std vector of CalDets containing the IDCDelta
207200
std::vector<CalDet<float>> getIDCDeltaCalDet() const;
208201

202+
/// \return returns pointer to pad status map
203+
CalDet<PadFlags>* getPadStatusMap() const { return mPadFlagsMap.get(); }
204+
205+
/// \return returns pointer to pad status map
206+
void setPadStatusMap(const CalDet<PadFlags>& outliermap) { mPadFlagsMap = std::make_unique<CalDet<PadFlags>>(outliermap); }
207+
209208
/// scale the stored IDC0 to 1
210-
/// \param rejectOutlier do not take outlier into account
211209
/// \return returns the scaling factor which was used to scale the IDC0
212-
float scaleIDC0(const Side side, const bool rejectOutlier = true);
210+
/// \param factor to scale the IDC0s with (IDC0/=factor)
211+
/// \param side TPC side of the IDCs
212+
void scaleIDC0(const float factor, const Side side);
213+
214+
/// \returns mean of IDC0
215+
/// \param side TPC side of the IDCs
216+
/// \param idcZero IDCZero object for which to get the mean
217+
/// \param outlierMap possible map containing the outliers which will not be taken into account (if nullptr all IDCs are taken into account)
218+
static float getMeanIDC0(const Side side, const IDCZero& idcZero, const CalDet<PadFlags>* outlierMap);
219+
220+
/// get median of IDC0 for given stack and sector
221+
/// \param idcZero IDCZero object for which to get the mean
222+
/// \param sector TPC sector
223+
/// \param stack stack in sector
224+
static float getStackMedian(const IDCZero& idczero, const Sector sector, const GEMstack stack);
225+
226+
/// get medians per stack for given side
227+
/// \param idcZero IDCZero object for which to get the mean
228+
/// \param side TPC side of the IDCZero
229+
static std::array<float, o2::tpc::GEMSTACKSPERSECTOR * o2::tpc::SECTORSPERSIDE> getStackMedian(const IDCZero& idczero, const Side side);
213230

214231
private:
215232
///\ to scale IDC0 from its total
@@ -249,7 +266,7 @@ class IDCCCDBHelper
249266
/// \param urow row of the ungrouped IDCs
250267
/// \param upad pad number of the ungrouped IDCs
251268
/// \param integrationInterval integration interval
252-
unsigned int getUngroupedIndexGlobal(const unsigned int sector, const unsigned int region, unsigned int urow, unsigned int upad, unsigned int integrationInterval) const;
269+
static unsigned int getUngroupedIndexGlobal(const unsigned int sector, const unsigned int region, unsigned int urow, unsigned int upad, unsigned int integrationInterval);
253270

254271
ClassDefNV(IDCCCDBHelper, 3)
255272
};

Detectors/TPC/calibration/include/TPCCalibration/IDCContainer.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,9 @@ enum class PadFlags : unsigned short {
449449
flagSaturatedPad = 1 << 3, ///< flag for saturated status binary 0100
450450
flagHighPad = 1 << 4, ///< flag for pad with extremly high IDC value
451451
flagLowPad = 1 << 5, ///< flag for pad with extremly low IDC value
452-
flagSkip = 1 << 6 ///< flag for defining a pad which is just ignored during the calculation of I1 and IDCDelta
452+
flagSkip = 1 << 6, ///< flag for defining a pad which is just ignored during the calculation of I1 and IDCDelta
453+
flagFEC = 1 << 7, ///< flag for a whole masked FEC
454+
flagNeighbour = 1 << 8 ///< flag if n neighbouring pads are outlier
453455
};
454456

455457
inline PadFlags operator&(PadFlags a, PadFlags b) { return static_cast<PadFlags>(static_cast<int>(a) & static_cast<int>(b)); }

Detectors/TPC/calibration/include/TPCCalibration/IDCFactorization.h

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,29 @@ class IDCFactorization : public IDCGroupHelperSector
7575
void factorizeIDCs(const bool norm, const bool calcDeltas);
7676

7777
/// calculate I_0(r,\phi) = <I(r,\phi,t)>_t
78+
/// \param norm normalize IDCs to pad area
7879
void calcIDCZero(const bool norm);
7980

8081
/// fill I_0 values in case of dead pads,FECs etc.
8182
void fillIDCZeroDeadPads();
8283

8384
/// create status map for pads which are dead or delivering extremly high values (static outliers will be mapped)
85+
/// \param debug create debug output
86+
void createStatusMapOutlier(const bool debug = false);
87+
88+
/// 1. createStatusMap, 2. checkFECs, 3. checkNeighbourOutliers
8489
void createStatusMap();
8590

91+
/// after the pad-by-pad status map has been created it can be used to mark FECs which deliver wrong values
92+
/// \param maxOutliersPerFEC if the ratio n_outliers_per_FEC / n_pads_per_FEC is larger than this value, the whole FEC is masked
93+
void checkFECs(const float maxOutliersPerFEC = 0.7);
94+
95+
/// check for each pad where there is no outlier found the neighbouring pads for outliers. If more than n neighbours contains outliers this pad is also marked as an outlier pad
96+
/// +- one pad in row direction and +- two pads in pad direction are considered
97+
/// \param maxIter maximum number of iterations of the procedure
98+
/// \param nOutliersNeighbours minimum number of outliers of the neighbouring pads which are required to mask a pad as outlier
99+
void checkNeighbourOutliers(const int maxIter = 10, const int nOutliersNeighbours = 8);
100+
86101
/// calculate I_1(t) = <I(r,\phi,t) / I_0(r,\phi)>_{r,\phi}
87102
void calcIDCOne();
88103

@@ -312,13 +327,16 @@ class IDCFactorization : public IDCGroupHelperSector
312327

313328
/// \param integrationIntervals number of integration intervals which will be dumped to the tree (-1: all integration intervalls)
314329
/// \param outFileName name of the output file
315-
void dumpToTree(int integrationIntervals = -1, const char* outFileName = "IDCTree.root") const;
330+
void dumpToTree(const Side side, const char* outFileName = "IDCTree.root");
316331

317332
/// dumping the IDC1 to a TTree including the timestamps (the start time stamp in ms should be set with setTimeStamp())
318333
/// \param integrationTimeOrbits integration time in orbits
319334
/// \param outFileName name of the output file
320335
void dumpToTreeIDC1(const float integrationTimeOrbits = 12, const char* outFileName = "IDC1Tree.root") const;
321336

337+
/// dump IDCDelta to a TTree
338+
void dumpIDCDeltaToTree(const Side side, const int chunk = 0, const char* outFileName = "IDCDeltaTree.root");
339+
322340
/// \returns vector containing the number of integration intervals for each stored TF (dropped TFs not taken into account)
323341
/// \param cru cru which is used for the lookup (cru=-1: automatic cru lookup)
324342
std::vector<unsigned int> getIntegrationIntervalsPerTF(const int cru = -1) const;
@@ -371,6 +389,21 @@ class IDCFactorization : public IDCGroupHelperSector
371389
/// set the IDCOne
372390
void setIDCOne(const Side side, const IDCOne& idcOne) { mIDCOne[mSideIndex[side]] = idcOne; }
373391

392+
/// set the IDCDelta
393+
void setIDCDelta(const Side side, const IDCDelta<float>& idcDelta, const int index = 0) { mIDCDelta[mSideIndex[side]][index] = idcDelta; }
394+
395+
/// \return returns mean of IDC0 for given side
396+
float getMeanZ(const Side side) const;
397+
398+
/// normalize IDC0 with the set gain map
399+
void normIDCZeroGain() { normIDCZero(0); }
400+
401+
/// normalize IDC0 with the median per stack
402+
void normIDCZeroStackMedian() { normIDCZero(1); }
403+
404+
/// \return returns median of IDC0 per stack for all stacks
405+
std::array<float, o2::tpc::GEMSTACKS> getStackMedian() const;
406+
374407
private:
375408
const unsigned int mTimeFrames{}; ///< number of timeframes which are stored
376409
const unsigned int mTimeFramesDeltaIDC{}; ///< number of timeframes of which Delta IDCs are stored
@@ -400,7 +433,7 @@ class IDCFactorization : public IDCGroupHelperSector
400433
void drawIDCZeroHelper(const bool type, const Sector sector, const std::string filename, const float minZ, const float maxZ) const;
401434

402435
/// get time frame and index of integrationInterval in the TF
403-
void getTF(const unsigned int region, unsigned int integrationInterval, unsigned int& timeFrame, unsigned int& interval) const;
436+
void getTF(unsigned int integrationInterval, unsigned int& timeFrame, unsigned int& interval) const;
404437

405438
/// \returns chunk from timeframe
406439
unsigned int getChunk(const unsigned int timeframe) const;
@@ -411,6 +444,9 @@ class IDCFactorization : public IDCGroupHelperSector
411444
/// helper function for drawing
412445
void drawPadFlagMap(const bool type, const Sector sector, const std::string filename, const PadFlags flag) const;
413446

447+
/// normalize IDC0
448+
void normIDCZero(const int type);
449+
414450
ClassDefNV(IDCFactorization, 2)
415451
};
416452

Detectors/TPC/calibration/include/TPCCalibration/IDCGroupingParameter.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,9 @@ struct ParameterIDCGroup : public o2::conf::ConfigurableParamHelper<ParameterIDC
4545
unsigned int groupPadsSectorEdges{0}; ///< decoded number of pads at the sector edges which are grouped differently. First digit specifies the EdgePadGroupingMethod (example: 0: no pads are grouped, 110: first two pads are not grouped, 3210: first pad is not grouped, second + third pads are grouped, fourth + fifth + sixth pads are grouped)
4646
AveragingMethod method = AveragingMethod::FAST; ///< method which is used for averaging
4747
float sigma = 3.f; ///< sigma cut which can be used during the grouping for outlier filtering
48-
float minIDC0Median = 6; ///< this value is used for identifying outliers (pads with high IDC0 values): "accepted IDC 0 values > median_IDC0 + stdDev * minIDC0Median"
49-
float maxIDC0Median = 6; ///< this value is used for identifying outliers (pads with high IDC0 values): "accepted IDC 0 values < median_IDC0 + stdDev * maxIDC0Median"
50-
int minIDC0Val = 1; ///< minimum accepted IDC0 value (should be larger than 0 in case of real data)
51-
int maxIDC0Val = 150; ///< maximum accepted IDC0 value (max IDC0 for 3MHz pp ~30)
48+
float minIDC0Median = 8; ///< this value is used for identifying outliers (pads with low IDC0 values): "accepted IDC 0 values > median_IDC0 + stdDev * minIDC0Median"
49+
float maxIDC0Median = 15; ///< this value is used for identifying outliers (pads with high IDC0 values): "accepted IDC 0 values < median_IDC0 + stdDev * maxIDC0Median"
50+
float minmaxIDC0MedianCentreEdge = 20; ///< this value is used for identifying outliers at the centre of the cross and the edges of the sector i.e. where the gain is significantly lower (cross) and sometimes higher at the edges"
5251

5352
/// Helper function for setting the groupimg parameters from a string (can be "X": parameters in all regions are "X" or can be "1,2,3,4,5,6,7,8,9,10" for setting individual regions)
5453
/// \param sgroupPads string for grouping parameter in pad direction

Detectors/TPC/calibration/include/TPCCalibration/RobustAverage.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ class RobustAverage
7171

7272
/// returns the filtered average value
7373
/// \param sigma maximum accepted standard deviation: sigma*stdev
74-
float getFilteredAverage(const float sigma = 3);
74+
///\param interQuartileRange number of points in inner quartile to consider
75+
std::pair<float, float> getFilteredAverage(const float sigma = 3, const float interQuartileRange = 0.9);
7576

7677
/// \return returns mean of stored values
7778
float getMean() const { return mValues.empty() ? 0 : getMean(mValues.begin(), mValues.end()); }
@@ -83,7 +84,10 @@ class RobustAverage
8384
float getWeightedMean() const { return getWeightedMean(mValues.begin(), mValues.end(), mWeights.begin(), mWeights.end()); }
8485

8586
/// \return returns standard deviation of stored values
86-
float getStdDev() { return getStdDev(getMean()); }
87+
float getStdDev() { return getStdDev(getMean(), mValues.begin(), mValues.end()); }
88+
89+
/// \return returns stored values
90+
const auto& getValues() { return mValues; }
8791

8892
/// values which will be averaged and filtered
8993
void print() const;
@@ -99,13 +103,13 @@ class RobustAverage
99103

100104
/// \return returns standard deviation of stored values
101105
/// \param mean mean of stored values
102-
float getStdDev(const float mean);
106+
float getStdDev(const float mean, std::vector<float>::const_iterator begin, std::vector<float>::const_iterator end);
103107

104108
/// performing outlier filtering of the stored values by defining range of included values in terms of standard deviation
105109
/// \param mean mean of the stored values
106110
/// \param stdev standard deviation of the values
107111
/// \param sigma maximum accepted standard deviation: sigma*stdev
108-
float getFilteredMean(const float mean, const float stdev, const float sigma);
112+
float getFilteredMean(const float mean, const float stdev, const float sigma) const;
109113
};
110114

111115
} // namespace o2::tpc

Detectors/TPC/calibration/src/IDCAverageGroupHelper.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ float o2::tpc::IDCAverageGroupHelper<o2::tpc::IDCAverageGroupCRU>::getGroupedIDC
2020
switch (paramIDCGroup.method) {
2121
case o2::tpc::AveragingMethod::SLOW:
2222
default:
23-
return mRobustAverage[mThreadNum].getFilteredAverage(paramIDCGroup.sigma);
23+
return mRobustAverage[mThreadNum].getFilteredAverage(paramIDCGroup.sigma).first;
2424
break;
2525
case o2::tpc::AveragingMethod::FAST:
2626
return withweights ? mRobustAverage[mThreadNum].getWeightedMean() : mRobustAverage[mThreadNum].getMean();
@@ -80,7 +80,7 @@ float o2::tpc::IDCAverageGroupHelper<o2::tpc::IDCAverageGroupTPC>::getGroupedIDC
8080
switch (paramIDCGroup.method) {
8181
case o2::tpc::AveragingMethod::SLOW:
8282
default:
83-
return mRobustAverage[mThreadNum].getFilteredAverage(paramIDCGroup.sigma);
83+
return mRobustAverage[mThreadNum].getFilteredAverage(paramIDCGroup.sigma).first;
8484
break;
8585
case o2::tpc::AveragingMethod::FAST:
8686
return withweights ? mRobustAverage[mThreadNum].getWeightedMean() : mRobustAverage[mThreadNum].getMean();

0 commit comments

Comments
 (0)