Skip to content

Commit aa951c4

Browse files
TPC: Add sector edge fluctuation correction methods
Add option to correct for sector edge fluctuations. The time intervals and sectors with optional scaling factors are parsed from CSV table. Two new CCDB types are added: 1. CalSecEdgeCorrection: the correction map with per sector delta fluctuations 2. CalSecEdgeInfo: the time intervals with optional per sector scaling factors for which the CalSecEdgeCorrection will be applied The applied scaling factors are added to the TPC timeseries for visualisation.
1 parent e24b99a commit aa951c4

16 files changed

Lines changed: 507 additions & 58 deletions

File tree

Detectors/Calibration/include/DetectorsCalibration/IntegratedClusterCalibrator.h

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -331,17 +331,18 @@ struct TimeSeriesdEdx {
331331
};
332332

333333
struct TimeSeriesITSTPC {
334-
float mVDrift = 0; ///< drift velocity in cm/us
335-
float mPressure = 0; ///< pressure
336-
float mTemperature = 0; ///< temperature
337-
TimeSeries mTSTPC; ///< TPC standalone DCAs
338-
TimeSeries mTSITSTPC; ///< ITS-TPC standalone DCAs
339-
ITSTPC_Matching mITSTPCAll; ///< ITS-TPC matching efficiency for ITS standalone + afterburner
340-
ITSTPC_Matching mITSTPCStandalone; ///< ITS-TPC matching efficiency for ITS standalone
341-
ITSTPC_Matching mITSTPCAfterburner; ///< ITS-TPC matchin efficiency fir ITS afterburner
342-
TimeSeriesdEdx mdEdxQTot; ///< time series for dE/dx qTot monitoring
343-
TimeSeriesdEdx mdEdxQMax; ///< time series for dE/dx qMax monitoring
344-
std::vector<unsigned int> mOccupancyMapTPC; ///< cluster occupancy map
334+
float mVDrift = 0; ///< drift velocity in cm/us
335+
float mPressure = 0; ///< pressure
336+
float mTemperature = 0; ///< temperature
337+
TimeSeries mTSTPC; ///< TPC standalone DCAs
338+
TimeSeries mTSITSTPC; ///< ITS-TPC standalone DCAs
339+
ITSTPC_Matching mITSTPCAll; ///< ITS-TPC matching efficiency for ITS standalone + afterburner
340+
ITSTPC_Matching mITSTPCStandalone; ///< ITS-TPC matching efficiency for ITS standalone
341+
ITSTPC_Matching mITSTPCAfterburner; ///< ITS-TPC matchin efficiency fir ITS afterburner
342+
TimeSeriesdEdx mdEdxQTot; ///< time series for dE/dx qTot monitoring
343+
TimeSeriesdEdx mdEdxQMax; ///< time series for dE/dx qMax monitoring
344+
std::vector<unsigned int> mOccupancyMapTPC; ///< cluster occupancy map
345+
std::vector<std::pair<int, float>> mSecEdgeFlucCorr; ///< applied sector edge fluctuation correction
345346

346347
std::vector<float> nPrimVertices; ///< number of primary vertices
347348
std::vector<float> nPrimVertices_ITS; ///< number of primary vertices selected with ITS cut 0.2<nContributorsITS/nContributors<0.8
@@ -502,7 +503,7 @@ struct TimeSeriesITSTPC {
502503
nVertexContributors_Quantiles.resize(nTotalQ);
503504
}
504505

505-
ClassDefNV(TimeSeriesITSTPC, 6);
506+
ClassDefNV(TimeSeriesITSTPC, 7);
506507
};
507508

508509
} // end namespace tpc

Detectors/TPC/baserecsim/include/TPCBaseRecSim/CDBTypes.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ enum class CDBType {
8383
CalScaler, ///< Scaler from IDCs or combined estimator
8484
CalScalerWeights, ///< Weights for scalers
8585
CalMShape, ///< calibration object for M-shape distortions
86+
CalSecEdgeCorrection, ///< calibration object for sector edge distortions
87+
CalSecEdgeInfo, ///< time slots and scaling for sector edge distortions
8688
///
8789
CorrMapParam, ///< parameters for CorrectionMapsLoader configuration
8890
///
@@ -154,6 +156,8 @@ const std::unordered_map<CDBType, const std::string> CDBTypeMap{
154156
{CDBType::CalScaler, "TPC/Calib/Scaler"},
155157
{CDBType::CalScalerWeights, "TPC/Calib/ScalerWeights"},
156158
{CDBType::CalMShape, "TPC/Calib/MShapePotential"},
159+
{CDBType::CalSecEdgeCorrection, "TPC/Calib/CorrectionMapSecEdgeFluc"},
160+
{CDBType::CalSecEdgeInfo, "TPC/Calib/SecEdgeFlucInfo"},
157161
// correction maps loader params
158162
{CDBType::CorrMapParam, "TPC/Calib/CorrMapParam"},
159163
// distortion maps

Detectors/TPC/calibration/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ o2_add_library(TPCCalibration
6161
src/CMVContainer.cxx
6262
src/CorrectionMapsLoader.cxx
6363
src/CMVHelper.cxx
64+
src/SectorEdgeFluctuations.cxx
6465
PUBLIC_LINK_LIBRARIES O2::DataFormatsTPC O2::TPCBaseRecSim
6566
O2::TPCReconstruction ROOT::Minuit
6667
Microsoft.GSL::GSL
@@ -121,7 +122,8 @@ o2_target_root_dictionary(TPCCalibration
121122
include/TPCCalibration/PressureTemperatureHelper.h
122123
include/TPCCalibration/CMVContainer.h
123124
include/TPCCalibration/CorrectionMapsLoader.h
124-
include/TPCCalibration/CMVHelper.h)
125+
include/TPCCalibration/CMVHelper.h
126+
include/TPCCalibration/SectorEdgeFluctuations.h)
125127

126128
o2_add_test_root_macro(macro/comparePedestalsAndNoise.C
127129
PUBLIC_LINK_LIBRARIES O2::TPCBaseRecSim

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <vector>
2020
#include "CorrectionMapsHelper.h"
2121
#include "CorrectionMapsTypes.h"
22+
#include "TPCCalibration/SectorEdgeFluctuations.h"
2223

2324
namespace o2
2425
{
@@ -47,6 +48,9 @@ class CorrectionMapsLoader : public o2::gpu::CorrectionMapsHelper
4748
void checkMeanScaleConsistency(float meanLumi, float threshold) const;
4849

4950
static void requestCCDBInputs(std::vector<o2::framework::InputSpec>& inputs, const o2::tpc::CorrectionMapsGloOpts& gloOpts);
51+
void enableSecEdgeFlucCorrection(const bool enable = true) { mApplySecEdgeFlucCorr = enable; }
52+
bool applySecEdgeFlucCorrection() const { return mApplySecEdgeFlucCorr; }
53+
const auto& getSectorEdgeFlucInfo() const { return mSecEdgeFlucInfo; }
5054

5155
protected:
5256
static void addOption(std::vector<o2::framework::ConfigParamSpec>& options, o2::framework::ConfigParamSpec&& osp);
@@ -55,6 +59,8 @@ class CorrectionMapsLoader : public o2::gpu::CorrectionMapsHelper
5559
float mInstLumiCTPFactor = 1.0; // multiplicative factor for inst. lumi
5660
int mLumiCTPSource = 0; // 0: main, 1: alternative CTP lumi source
5761
bool mIDC2CTPFallbackActive = false; // flag indicating that fallback from IDC to CTP scaling is active
62+
o2::tpc::SectorEdgeFluctuations mSecEdgeFlucInfo; // definition of sector edge fluctuation distortion map scaling
63+
bool mApplySecEdgeFlucCorr = true; // flag indicating if sector edge fluctuation correction is enabled
5864
};
5965

6066
} // namespace tpc
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
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+
12+
/// \file SectorEdgeFluctuations.h
13+
/// \brief Class to parse and query time-dependent TPC sector edge fluctuation intervals
14+
/// \author Matthias Kleiner <matthias.kleiner@cern.ch>
15+
16+
#ifndef ALICEO2_TPC_SECTOREDGEFLUCTUATIONS_H
17+
#define ALICEO2_TPC_SECTOREDGEFLUCTUATIONS_H
18+
19+
#include <map>
20+
#include <vector>
21+
#include <string>
22+
#include <utility>
23+
#include "Rtypes.h"
24+
25+
class TTree;
26+
27+
namespace o2::tpc
28+
{
29+
30+
/// One time interval during which a set of TPC sectors has edge fluctuations.
31+
/// Each sector carries an optional scaling factor (default 1.0).
32+
struct SectorEdgeInterval {
33+
Long64_t startTimeMS{0}; ///< interval start, Unix time in ms
34+
Long64_t endTimeMS{0}; ///< interval end, Unix time in ms
35+
std::vector<std::pair<int, float>> sectors; ///< {o2SectorId, scalingFactor}
36+
ClassDefNV(SectorEdgeInterval, 1);
37+
};
38+
39+
/// Parses and queries TPC sector edge fluctuation intervals from a CSV text file.
40+
///
41+
/// Expected line format (comma-separated, whitespace around tokens is ignored):
42+
/// runNumber, startMS, endMS, durationMS, label[, SectorID[=scale], ...]
43+
///
44+
/// The sector list is optional. If omitted (or all tokens fail to parse), the
45+
/// interval is applied to all 36 sectors (A0-A17 and C0-C17) with scale 1.0.
46+
///
47+
/// Examples:
48+
/// 560352,1732244770094,1732244771094,1000,edge distortions,A3
49+
/// 560352,1732244771344,1732244776344,5000,edge distortions,A3=1.2,C0,C1=0.6,C2,C3
50+
///
51+
/// If the same sector appears in multiple overlapping intervals at a queried
52+
/// timestamp, the scale from the interval with the latest end-time is used.
53+
class SectorEdgeFluctuations
54+
{
55+
public:
56+
/// Load intervals from file. Clears any previously loaded data.
57+
/// Throws std::runtime_error if the file cannot be opened.
58+
bool loadFromCSVFile(const std::string& filename);
59+
60+
/// dump this object to a file
61+
/// \param file output file
62+
/// \param name name of the output object
63+
void dumpToFile(const char* file, const char* name = "ccdb_object", const char* brName = "SectorEdgeFluctuation");
64+
65+
/// load from input file (which were written using the dumpToFile method)
66+
/// \param inpf input file
67+
/// \param name name of the object in the file
68+
void loadFromFile(const char* inpf, const char* name = "ccdb_object", const int iEntry = 0, const char* brName = "SectorEdgeFluctuation");
69+
70+
/// set this object from input tree
71+
void setFromTree(TTree& tree, const int iEntry = 0, const char* brName = "SectorEdgeFluctuation");
72+
73+
/// Returns all {o2SectorId, scalingFactor} pairs active for the given run
74+
/// at the given Unix timestamp (milliseconds). Returns empty if none are active
75+
/// or if the run is not known.
76+
std::vector<std::pair<int, float>> getSectorsAtTime(int run, Long64_t timestampMS) const;
77+
78+
/// Convert a sector string such as "A3" or "C14" to the O2 integer sector
79+
/// index (0-35). Returns -1 on parse error.
80+
static int parseSectorId(const std::string& sectorStr);
81+
82+
/// Total number of intervals across all runs.
83+
size_t size() const
84+
{
85+
size_t n = 0;
86+
for (const auto& [run, v] : mIntervals) {
87+
n += v.size();
88+
}
89+
return n;
90+
}
91+
92+
/// number of total runs stored
93+
size_t getNRuns() const { return mIntervals.size(); }
94+
bool empty() const { return mIntervals.empty(); }
95+
96+
/// get stored data
97+
const auto& getIntervals() const { return mIntervals; }
98+
99+
private:
100+
/// Per-run intervals, each sorted by startTimeMS.
101+
std::map<int, std::vector<SectorEdgeInterval>> mIntervals;
102+
103+
ClassDefNV(SectorEdgeFluctuations, 1);
104+
};
105+
106+
} // namespace o2::tpc
107+
108+
#endif // ALICEO2_TPC_SECTOREDGEFLUCTUATIONS_H

Detectors/TPC/calibration/src/CorrectionMapsLoader.cxx

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ void CorrectionMapsLoader::extractCCDBInputs(ProcessingContext& pc, float tpcSca
3535
if (lumiMode != LumiScaleMode::NoCorrection) {
3636
pc.inputs().get<o2::gpu::TPCFastTransform*>("tpcCorrMapRef");
3737
}
38+
39+
if(mApplySecEdgeFlucCorr) {
40+
pc.inputs().get<o2::gpu::TPCFastTransform*>("tpcCorrMapSecFluc");
41+
pc.inputs().get<TTree*>("tpSecFlucInfo");
42+
}
43+
3844
const int maxDumRep = 5;
3945
int dumRep = 0;
4046
o2::ctp::LumiInfo lumiObj;
@@ -93,11 +99,11 @@ void CorrectionMapsLoader::requestCCDBInputs(std::vector<InputSpec>& inputs, con
9399
{
94100
LOGP(info, "Requesting CCDB inputs for TPC correction maps with lumiType={} and lumiMode={}", static_cast<int>(gloOpts.lumiType), static_cast<int>(gloOpts.lumiMode));
95101
if (gloOpts.lumiMode == LumiScaleMode::Linear) {
96-
addInput(inputs, {"tpcCorrMap", "TPC", "CorrMap", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalCorrMap), {}, 1)}); // time-dependent
97-
addInput(inputs, {"tpcCorrMapRef", "TPC", "CorrMapRef", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalCorrMapRef), {}, 0)}); // load once
102+
addInput(inputs, {"tpcCorrMap", o2::header::gDataOriginTPC, "CorrMap", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalCorrMap), {}, 1)}); // time-dependent
103+
addInput(inputs, {"tpcCorrMapRef", o2::header::gDataOriginTPC, "CorrMapRef", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalCorrMapRef), {}, 0)}); // load once
98104
} else if (gloOpts.lumiMode == LumiScaleMode::DerivativeMap) {
99-
addInput(inputs, {"tpcCorrMap", "TPC", "CorrMap", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalCorrMap), {}, 1)}); // time-dependent
100-
addInput(inputs, {"tpcCorrMapRef", "TPC", "CorrMapRef", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalCorrDerivMap), {}, 1)}); // time-dependent
105+
addInput(inputs, {"tpcCorrMap", o2::header::gDataOriginTPC, "CorrMap", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalCorrMap), {}, 1)}); // time-dependent
106+
addInput(inputs, {"tpcCorrMapRef", o2::header::gDataOriginTPC, "CorrMapRef", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalCorrDerivMap), {}, 1)}); // time-dependent
101107
} else if (gloOpts.lumiMode == LumiScaleMode::DerivativeMapMC) {
102108
// for MC corrections
103109
addInput(inputs, {"tpcCorrMap", "TPC", "CorrMap", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalCorrMapMC), {}, 1)}); // time-dependent
@@ -110,11 +116,17 @@ void CorrectionMapsLoader::requestCCDBInputs(std::vector<InputSpec>& inputs, con
110116
LOG(fatal) << "Correction mode unknown! Choose either 0 (default) or 1 (derivative map) for flag corrmap-lumi-mode.";
111117
}
112118

119+
// load sector edge fluctuation correction only for data
120+
if (gloOpts.enableSecEdgeFlucCorrection) {
121+
addInput(inputs, {"tpcCorrMapSecFluc", o2::header::gDataOriginTPC, "CorrMapSecFluc", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalSecEdgeCorrection), {}, 1)}); // time-dependent
122+
addInput(inputs, {"tpSecFlucInfo", o2::header::gDataOriginTPC, "InfoMapSecFluc", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalSecEdgeInfo), {}, 1)}); // time-dependent
123+
}
124+
113125
if (gloOpts.requestCTPLumi) {
114126
addInput(inputs, {"CTPLumi", "CTP", "LUMI", 0, Lifetime::Timeframe});
115127
}
116128

117-
addInput(inputs, {"tpcCorrPar", "TPC", "CorrMapParam", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CorrMapParam), {}, 0)}); // load once
129+
addInput(inputs, {"tpcCorrPar", o2::header::gDataOriginTPC, "CorrMapParam", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CorrMapParam), {}, 0)}); // load once
118130
}
119131

120132
//________________________________________________________
@@ -136,7 +148,7 @@ void CorrectionMapsLoader::addOption(std::vector<ConfigParamSpec>& options, Conf
136148
//________________________________________________________
137149
bool CorrectionMapsLoader::accountCCDBInputs(const ConcreteDataMatcher& matcher, void* obj)
138150
{
139-
if (matcher == ConcreteDataMatcher("TPC", "CorrMap", 0)) {
151+
if (matcher == ConcreteDataMatcher(o2::header::gDataOriginTPC, "CorrMap", 0)) {
140152
setCorrMap((o2::gpu::TPCFastTransform*)obj);
141153
mCorrMap->rectifyAfterReadingFromFile();
142154
mCorrMap->setCTP2IDCFallBackThreshold(o2::tpc::CorrMapParam::Instance().CTP2IDCFallBackThreshold);
@@ -165,7 +177,7 @@ bool CorrectionMapsLoader::accountCCDBInputs(const ConcreteDataMatcher& matcher,
165177
setUpdatedMap();
166178
return true;
167179
}
168-
if (matcher == ConcreteDataMatcher("TPC", "CorrMapRef", 0)) {
180+
if (matcher == ConcreteDataMatcher(o2::header::gDataOriginTPC, "CorrMapRef", 0)) {
169181
setCorrMapRef((o2::gpu::TPCFastTransform*)obj);
170182
mCorrMapRef->rectifyAfterReadingFromFile();
171183
mCorrMapRef->setCTP2IDCFallBackThreshold(o2::tpc::CorrMapParam::Instance().CTP2IDCFallBackThreshold);
@@ -194,7 +206,7 @@ bool CorrectionMapsLoader::accountCCDBInputs(const ConcreteDataMatcher& matcher,
194206
setUpdatedMapRef();
195207
return true;
196208
}
197-
if (matcher == ConcreteDataMatcher("TPC", "CorrMapParam", 0)) {
209+
if (matcher == ConcreteDataMatcher(o2::header::gDataOriginTPC, "CorrMapParam", 0)) {
198210
const auto& par = o2::tpc::CorrMapParam::Instance();
199211
mMeanLumiOverride = par.lumiMean; // negative value switches off corrections !!!
200212
mMeanLumiRefOverride = par.lumiMeanRef;
@@ -225,6 +237,18 @@ bool CorrectionMapsLoader::accountCCDBInputs(const ConcreteDataMatcher& matcher,
225237
canUseCorrections() ? "ON" : "OFF",
226238
lumiS[scaleType], mMeanLumiOverride, mMeanLumiRefOverride, static_cast<int>(getLumiScaleMode()), mLumiCTPSource, mInstCTPLumiOverride, mInstLumiCTPFactor);
227239
}
240+
if (matcher == ConcreteDataMatcher(o2::header::gDataOriginTPC, "CorrMapSecFluc", 0)) {
241+
setCorrMapSecEdgeFluc((o2::gpu::TPCFastTransform*)obj);
242+
mCorrMapSecEdgeFluc->rectifyAfterReadingFromFile();
243+
setUpdatedMapSecEdgeFluc();
244+
return true;
245+
}
246+
if (matcher == ConcreteDataMatcher(o2::header::gDataOriginTPC, "InfoMapSecFluc", 0)) {
247+
LOGP(info, "Updating TPC sector edge fluctuation info");
248+
mSecEdgeFlucInfo.setFromTree(*((TTree*)obj));
249+
LOGP(info, "Loaded sector edge fluctuation information with {} intervals for {} runs", mSecEdgeFlucInfo.size(), mSecEdgeFlucInfo.getNRuns());
250+
return true;
251+
}
228252
return false;
229253
}
230254

Detectors/TPC/calibration/src/CorrectionMapsOptions.cxx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ CorrectionMapsGloOpts CorrectionMapsOptions::parseGlobalOptions(const o2::framew
3333
tpcopt.lumiMode = static_cast<LumiScaleMode>(lumiModeVal);
3434

3535
tpcopt.enableMShapeCorrection = opts.get<bool>("enable-M-shape-correction");
36+
tpcopt.enableSecEdgeFlucCorrection = opts.get<bool>("enable-sec-edge-fluc-correction");
3637
tpcopt.requestCTPLumi = !opts.get<bool>("disable-ctp-lumi-request");
3738
tpcopt.checkCTPIDCconsistency = !opts.get<bool>("disable-lumi-type-consistency-check");
3839
if (!tpcopt.requestCTPLumi && tpcopt.lumiType == LumiScaleType::CTPLumi) {
@@ -49,6 +50,7 @@ void CorrectionMapsOptions::addGlobalOptions(std::vector<ConfigParamSpec>& optio
4950
addOption(options, ConfigParamSpec{"enable-M-shape-correction", o2::framework::VariantType::Bool, false, {"Enable M-shape distortion correction"}});
5051
addOption(options, ConfigParamSpec{"disable-ctp-lumi-request", o2::framework::VariantType::Bool, false, {"do not request CTP lumi (regardless what is used for corrections)"}});
5152
addOption(options, ConfigParamSpec{"disable-lumi-type-consistency-check", o2::framework::VariantType::Bool, false, {"disable check of selected CTP or IDC scaling source being consistent with the map"}});
53+
addOption(options, ConfigParamSpec{"enable-sec-edge-fluc-correction", o2::framework::VariantType::Bool, false, {"Enable sector edge fluctuation correction"}});
5254
}
5355

5456
void CorrectionMapsOptions::addOption(std::vector<ConfigParamSpec>& options, ConfigParamSpec&& osp)

0 commit comments

Comments
 (0)