Skip to content

Commit 044a4ec

Browse files
TPC: adding option to use custom scalers (IDCs) for SC correction map scaling (#12205)
* TPC: adding option to use custom scalers (IDCs) for SC correction map scaling Adding a generic method to provide scaling of the space-charge correction maps based on the IDCs (and cluster currents). In the `o2-tpc-scaler-workflow` for each TF the last n values (dependent on the specified ion drift time and integration length of the scalers) are averaged and provided as scaling value. - A- and C-side values are averaged for now! Example how to run with scalersfrom local file: ``` scaler="file:///data/mkleiner/run3/LHC23zo/539399_lowIR/=TPC/Calib/Scaler" o2-ctf-reader-workflow --copy-cmd no-copy --onlyDet TPC --ctf-input ${INPUT} --severity warning --condition-remap "${scaler}" | o2-tpc-scaler-workflow | o2-tpc-reco-workflow --lumi-type 2 --input-type compressed-clusters-ctf --output-type "tracks,disable-writer" --disable-mc -b ``` * Fixing setting of lumi from TPC scalers * Adding check for run number, adding option to set ion drift time - Adding mInstLumiFactor as optional scaling factor * Parse lumi-type from TPC_CORR_SCALING to ASK_CTP_LUMI_GPU * Avoid copy when loading object from file
1 parent 67889bb commit 044a4ec

File tree

22 files changed

+434
-33
lines changed

22 files changed

+434
-33
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ enum class CDBType {
8888
CalCorrDerivMap, ///< Cluster correction map (derivative map)
8989
///
9090
CalTimeSeries, ///< integrated DCAs for longer time interval
91+
CalScaler, ///< Scaler from IDCs or combined estimator
9192
};
9293

9394
/// Upload intervention type
@@ -149,6 +150,7 @@ const std::unordered_map<CDBType, const std::string> CDBTypeMap{
149150
{CDBType::CalCorrDerivMap, "TPC/Calib/CorrectionMapDerivativeV2"},
150151
// time series
151152
{CDBType::CalTimeSeries, "TPC/Calib/TimeSeries"},
153+
{CDBType::CalScaler, "TPC/Calib/Scaler"},
152154
};
153155

154156
/// Poor enum reflection ...

Detectors/TPC/calibration/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ o2_add_library(TPCCalibration
5252
src/SACCCDBHelper.cxx
5353
src/TPCFastSpaceChargeCorrectionHelper.cxx
5454
src/CalculatedEdx.cxx
55+
src/TPCScaler.cxx
5556
PUBLIC_LINK_LIBRARIES O2::DataFormatsTPC O2::TPCBase
5657
O2::TPCReconstruction ROOT::Minuit
5758
Microsoft.GSL::GSL
@@ -103,7 +104,8 @@ o2_target_root_dictionary(TPCCalibration
103104
include/TPCCalibration/VDriftHelper.h
104105
include/TPCCalibration/SACCCDBHelper.h
105106
include/TPCCalibration/TPCFastSpaceChargeCorrectionHelper.h
106-
include/TPCCalibration/CalculatedEdx.h)
107+
include/TPCCalibration/CalculatedEdx.h
108+
include/TPCCalibration/TPCScaler.h)
107109

108110
o2_add_test_root_macro(macro/comparePedestalsAndNoise.C
109111
PUBLIC_LINK_LIBRARIES O2::TPCBase

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class CorrectionMapsLoader : public o2::gpu::CorrectionMapsHelper
5050
void init(o2::framework::InitContext& ic);
5151
void copySettings(const CorrectionMapsLoader& src);
5252

53-
static void requestCCDBInputs(std::vector<o2::framework::InputSpec>& inputs, std::vector<o2::framework::ConfigParamSpec>& options, bool requestCTPLumi = false, int lumiScaleMode = 0);
53+
static void requestCCDBInputs(std::vector<o2::framework::InputSpec>& inputs, std::vector<o2::framework::ConfigParamSpec>& options, int lumiScaleType = 0, int lumiScaleMode = 0);
5454
static void addOptions(std::vector<o2::framework::ConfigParamSpec>& options);
5555

5656
protected:
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
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 TPCScaler.h
13+
/// \author Matthias Kleiner <mkleiner@ikf.uni-frankfurt.de>
14+
15+
#ifndef ALICEO2_TPC_TPCSCALER
16+
#define ALICEO2_TPC_TPCSCALER
17+
18+
#include "DataFormatsTPC/Defs.h"
19+
#include <vector>
20+
21+
class TTree;
22+
23+
namespace o2::tpc
24+
{
25+
26+
/*
27+
Class for storing the scalers which are used to calculate an estimate for the mean space-charge density for the last ion drift time
28+
*/
29+
30+
class TPCScaler
31+
{
32+
public:
33+
/// default constructor
34+
TPCScaler() = default;
35+
36+
/// default move assignment
37+
TPCScaler& operator=(TPCScaler&& other) = default;
38+
39+
/// \return returns number of stored TPC scaler values
40+
int getNValues(o2::tpc::Side side) const { return (side == o2::tpc::Side::A ? mScalerA.size() : mScalerC.size()); }
41+
42+
/// set the parameters for the coefficients of the polynomial
43+
/// \param params parameter for the coefficients
44+
void setScaler(const std::vector<float>& values, const o2::tpc::Side side) { (side == o2::tpc::Side::A ? (mScalerA = values) : (mScalerC = values)); }
45+
46+
/// \return returns ion drift time in ms
47+
void setIonDriftTimeMS(float ionDriftTimeMS) { mIonDriftTimeMS = ionDriftTimeMS; }
48+
49+
/// \return returns run number for which this object is valid
50+
void setRun(int run) { mRun = run; }
51+
52+
/// \param firstTFOrbit first TF orbit of first data
53+
void setFirstTFOrbit(unsigned int firstTFOrbit) { mFirstTFOrbit = firstTFOrbit; }
54+
55+
/// \param timeStampMS first time in ms
56+
void setStartTimeStampMS(double timeStampMS) { mTimeStampMS = timeStampMS; }
57+
58+
/// \param integrationTimeMS integration time for each scaler value
59+
void setIntegrationTimeMS(float integrationTimeMS) { mIntegrationTimeMS = integrationTimeMS; }
60+
61+
/// dump this object to a file
62+
/// \param file output file
63+
void dumpToFile(const char* file, const char* name);
64+
65+
/// load parameters from input file (which were written using the writeToFile method)
66+
/// \param inpf input file
67+
void loadFromFile(const char* inpf, const char* name);
68+
69+
/// set this object from input tree
70+
void setFromTree(TTree& tpcScalerTree);
71+
72+
/// \return returns stored scalers for given side and data index
73+
float getScalers(unsigned int idx, o2::tpc::Side side) const { return (side == o2::tpc::Side::A) ? mScalerA[idx] : mScalerC[idx]; }
74+
75+
/// \return returns stored scalers for given side
76+
const auto& getScalers(o2::tpc::Side side) const { return (side == o2::tpc::Side::A) ? mScalerA : mScalerC; }
77+
78+
/// \return returns ion drift time in ms
79+
float getIonDriftTimeMS() const { return mIonDriftTimeMS; }
80+
81+
/// \return returns run number for which this object is valid
82+
int getRun() const { return mRun; }
83+
84+
/// \return returns first TF orbit of first data
85+
unsigned int getFirstTFOrbit() const { return mFirstTFOrbit; }
86+
87+
/// \return return first time in ms
88+
double getStartTimeStampMS() const { return mTimeStampMS; }
89+
90+
/// \return returns integration time for each scaler value
91+
float getIntegrationTimeMS() const { return mIntegrationTimeMS; }
92+
93+
/// \return returns numbers of scalers for one ion drift time
94+
int getNValuesIonDriftTime() const { return mIonDriftTimeMS / mIntegrationTimeMS + 0.5; }
95+
96+
/// \return returns mean scaler value for last ion drift time
97+
/// \param timestamp timestamp for which the last values are used to calculate the mean
98+
float getMeanScaler(double timestamp, o2::tpc::Side side) const;
99+
100+
private:
101+
float mIonDriftTimeMS{200}; ///< ion drift time in ms
102+
int mRun{}; ///< run for which this object is valid
103+
unsigned int mFirstTFOrbit{}; ///< first TF orbit of the stored scalers
104+
double mTimeStampMS{}; ///< time stamp of the first stored values
105+
float mIntegrationTimeMS{1.}; ///< integration time for each stored value in ms
106+
std::vector<float> mScalerA{}; ///< TPC scaler for A-side
107+
std::vector<float> mScalerC{}; ///< TPC scaler for C-side
108+
109+
ClassDefNV(TPCScaler, 1);
110+
};
111+
112+
} // namespace o2::tpc
113+
#endif

Detectors/TPC/calibration/src/CorrectionMapsLoader.cxx

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ void CorrectionMapsLoader::extractCCDBInputs(ProcessingContext& pc)
4646
int dumRep = 0;
4747
o2::ctp::LumiInfo lumiObj;
4848
static o2::ctp::LumiInfo lumiPrev;
49-
if (getUseCTPLumi() && mInstLumiOverride <= 0.) {
49+
if (getLumiScaleType() == 1 && mInstLumiOverride <= 0.) {
5050
if (pc.inputs().get<gsl::span<char>>("CTPLumi").size() == sizeof(o2::ctp::LumiInfo)) {
5151
lumiPrev = lumiObj = pc.inputs().get<o2::ctp::LumiInfo>("CTPLumi");
5252
} else {
@@ -56,13 +56,16 @@ void CorrectionMapsLoader::extractCCDBInputs(ProcessingContext& pc)
5656
lumiObj = lumiPrev;
5757
}
5858
setInstLumi(mInstLumiFactor * (mCTPLumiSource == 0 ? lumiObj.getLumi() : lumiObj.getLumiAlt()));
59+
} else if (getLumiScaleType() == 2 && mInstLumiOverride <= 0.) {
60+
float tpcScaler = pc.inputs().get<float>("tpcscaler");
61+
setInstLumi(mInstLumiFactor * tpcScaler);
5962
}
6063
}
6164

6265
//________________________________________________________
63-
void CorrectionMapsLoader::requestCCDBInputs(std::vector<InputSpec>& inputs, std::vector<o2::framework::ConfigParamSpec>& options, bool requestCTPLumi, int lumiScaleMode)
66+
void CorrectionMapsLoader::requestCCDBInputs(std::vector<InputSpec>& inputs, std::vector<o2::framework::ConfigParamSpec>& options, int lumiScaleType, int lumiScaleMode)
6467
{
65-
addInput(inputs, {"tpcCorrMap", "TPC", "CorrMap", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalCorrMap), {}, 1)}); // time-dependent
68+
addInput(inputs, {"tpcCorrMap", "TPC", "CorrMap", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalCorrMap), {}, 1)}); // time-dependent
6669
if (lumiScaleMode == 0) {
6770
addInput(inputs, {"tpcCorrMapRef", "TPC", "CorrMapRef", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalCorrMapRef), {}, 0)}); // load once
6871
} else if (lumiScaleMode == 1) {
@@ -71,8 +74,10 @@ void CorrectionMapsLoader::requestCCDBInputs(std::vector<InputSpec>& inputs, std
7174
LOG(fatal) << "Correction mode unknown! Choose either 0 (default) or 1 (derivative map) for flag corrmap-lumi-mode.";
7275
}
7376

74-
if (requestCTPLumi) {
77+
if (lumiScaleType == 1) {
7578
addInput(inputs, {"CTPLumi", "CTP", "LUMI", 0, Lifetime::Timeframe});
79+
} else if (lumiScaleType == 2) {
80+
addInput(inputs, {"tpcscaler", o2::header::gDataOriginTPC, "TPCSCALER", 0, Lifetime::Timeframe});
7681
}
7782
addOptions(options);
7883
}
@@ -131,8 +136,10 @@ void CorrectionMapsLoader::init(o2::framework::InitContext& ic)
131136
const auto& inputRouts = ic.services().get<const o2::framework::DeviceSpec>().inputs;
132137
for (const auto& route : inputRouts) {
133138
if (route.matcher == InputSpec{"CTPLumi", "CTP", "LUMI", 0, Lifetime::Timeframe}) {
134-
setUseCTPLumi(true);
139+
setLumiScaleType(1);
135140
break;
141+
} else if (route.matcher == InputSpec{"tpcscaler", o2::header::gDataOriginTPC, "TPCSCALER", 0, Lifetime::Timeframe}) {
142+
setLumiScaleType(2);
136143
}
137144
}
138145
mMeanLumiOverride = ic.options().get<float>("corrmap-lumi-mean");
@@ -146,16 +153,22 @@ void CorrectionMapsLoader::init(o2::framework::InitContext& ic)
146153
if (mInstLumiOverride != 0.) {
147154
setInstLumi(mInstLumiOverride);
148155
}
149-
LOGP(info, "CTP Lumi request for TPC corr.map scaling={}, override values: lumiMean={} lumiInst={} lumiScaleMode={}, LumiInst scale={}, CTP Lumi source={}",
150-
getUseCTPLumi() ? "ON" : "OFF", mMeanLumiOverride, mInstLumiOverride, mLumiScaleMode, mInstLumiFactor, mCTPLumiSource);
156+
const std::array<std::string, 3> lumiS{"OFF", "CTP", "TPC scaler"};
157+
int scaleType = getLumiScaleType();
158+
if (scaleType >= lumiS.size()) {
159+
LOGP(fatal, "Wrong lumi-scale-type provided!");
160+
}
161+
162+
LOGP(info, "Scaling for TPC corr.map scaling={}, override values: lumiMean={} lumiInst={} lumiScaleMode={}, LumiInst scale={}, CTP Lumi source={}",
163+
lumiS[scaleType], mMeanLumiOverride, mInstLumiOverride, mLumiScaleMode, mInstLumiFactor, mCTPLumiSource);
151164
}
152165

153166
//________________________________________________________
154167
void CorrectionMapsLoader::copySettings(const CorrectionMapsLoader& src)
155168
{
156169
setInstLumi(src.getInstLumi(), false);
157170
setMeanLumi(src.getMeanLumi(), false);
158-
setUseCTPLumi(src.getUseCTPLumi());
171+
setLumiScaleType(src.getLumiScaleType());
159172
setMeanLumiOverride(src.getMeanLumiOverride());
160173
setInstLumiOverride(src.getInstLumiOverride());
161174
setLumiScaleMode(src.getLumiScaleMode());

Detectors/TPC/calibration/src/TPCCalibrationLinkDef.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,5 @@
110110
#pragma link C++ class o2::tpc::TPCFastSpaceChargeCorrectionHelper + ;
111111

112112
#pragma link C++ class o2::tpc::CalculatedEdx + ;
113+
#pragma link C++ class o2::tpc::TPCScaler + ;
113114
#endif
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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 TPCScaler.cxx
13+
/// \brief Definition of TPCScaler class
14+
///
15+
/// \author Matthias Kleiner <mkleiner@ikf.uni-frankfurt.de>
16+
17+
#include "TPCCalibration/TPCScaler.h"
18+
#include <TFile.h>
19+
#include <TTree.h>
20+
#include "Framework/Logger.h"
21+
22+
using namespace o2::tpc;
23+
24+
void TPCScaler::dumpToFile(const char* file, const char* name)
25+
{
26+
TFile out(file, "RECREATE");
27+
TTree tree("TPCScaler", "TPCScaler");
28+
tree.Branch("TPCScaler", this);
29+
tree.Fill();
30+
out.WriteObject(&tree, name);
31+
}
32+
33+
void TPCScaler::loadFromFile(const char* inpf, const char* name)
34+
{
35+
TFile out(inpf, "READ");
36+
TTree* tree = (TTree*)out.Get(name);
37+
setFromTree(*tree);
38+
}
39+
40+
void TPCScaler::setFromTree(TTree& tpcScalerTree)
41+
{
42+
TPCScaler* scalerTmp = this;
43+
tpcScalerTree.SetBranchAddress("TPCScaler", &scalerTmp);
44+
const int entries = tpcScalerTree.GetEntries();
45+
if (entries > 0) {
46+
tpcScalerTree.GetEntry(0);
47+
} else {
48+
LOGP(error, "TPCScaler not found in input file");
49+
}
50+
tpcScalerTree.SetBranchAddress("TPCScaler", nullptr);
51+
}
52+
53+
float TPCScaler::getMeanScaler(double timestamp, o2::tpc::Side side) const
54+
{
55+
// index to data buffer
56+
const int idxData = (timestamp - mTimeStampMS) / mIntegrationTimeMS + 0.5;
57+
const int nVals = getNValuesIonDriftTime();
58+
const int nValues = getNValues(side);
59+
if ((nVals == 0) || (nVals > nValues)) {
60+
return -1;
61+
LOGP(error, "Empty data provided {}", nValues);
62+
}
63+
64+
// clamp indices to min and max
65+
const int lastIdx = std::clamp(idxData, nVals, nValues);
66+
const int firstIdx = (lastIdx == nValues) ? (nValues - nVals) : std::clamp(idxData - nVals, 0, nValues);
67+
68+
// sump up values from last ion drift time
69+
float sum = 0;
70+
for (int i = firstIdx; i < lastIdx; ++i) {
71+
sum += getScalers(i, side);
72+
}
73+
return (sum / nVals);
74+
}

Detectors/TPC/workflow/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ o2_add_library(TPCWorkflow
4545
src/TPCTimeSeriesWriterSpec.cxx
4646
src/TPCTimeSeriesReaderSpec.cxx
4747
src/TPCMergeTimeSeriesSpec.cxx
48+
src/TPCScalerSpec.cxx
4849
TARGETVARNAME targetName
4950
PUBLIC_LINK_LIBRARIES O2::Framework O2::DataFormatsTPC
5051
O2::DPLUtils O2::TPCReconstruction
@@ -246,6 +247,11 @@ o2_add_executable(merge-time-series-workflow
246247
COMPONENT_NAME tpc
247248
PUBLIC_LINK_LIBRARIES O2::TPCWorkflow)
248249

250+
o2_add_executable(scaler-workflow
251+
COMPONENT_NAME tpc
252+
SOURCES src/tpc-scaler.cxx
253+
PUBLIC_LINK_LIBRARIES O2::TPCWorkflow)
254+
249255
o2_add_test(workflow
250256
COMPONENT_NAME tpc
251257
LABELS tpc workflow

Detectors/TPC/workflow/include/TPCWorkflow/RecoWorkflow.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ framework::WorkflowSpec getWorkflow(CompletionPolicyData* policyData,
8484
bool askDISTSTF = true,
8585
bool selIR = false,
8686
bool filteredInp = false,
87-
bool requireCTPLumi = false,
87+
int lumiScaleType = 0,
8888
int deadMapSources = -1);
8989

9090
void cleanupCallback();

Detectors/TPC/workflow/include/TPCWorkflow/TPCCalibPadGainTracksSpec.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ class TPCCalibPadGainTracksDevice : public o2::framework::Task
240240
}
241241
};
242242

243-
DataProcessorSpec getTPCCalibPadGainTracksSpec(const uint32_t publishAfterTFs, const bool debug, const bool useLastExtractedMapAsReference, const std::string polynomialsFile, bool disablePolynomialsCCDB, bool requestCTPLumi)
243+
DataProcessorSpec getTPCCalibPadGainTracksSpec(const uint32_t publishAfterTFs, const bool debug, const bool useLastExtractedMapAsReference, const std::string polynomialsFile, bool disablePolynomialsCCDB, int lumiType)
244244
{
245245
std::vector<InputSpec> inputs;
246246
inputs.emplace_back("trackTPC", gDataOriginTPC, "TRACKS", 0, Lifetime::Timeframe);
@@ -282,7 +282,7 @@ DataProcessorSpec getTPCCalibPadGainTracksSpec(const uint32_t publishAfterTFs, c
282282
{"useEveryNthTF", VariantType::Int, 10, {"Using only a fraction of the data: 1: Use every TF, 10: Use only every tenth TF."}},
283283
{"maxTracksPerTF", VariantType::Int, 10000, {"Maximum number of processed tracks per TF (-1 for processing all tracks)"}},
284284
};
285-
o2::tpc::CorrectionMapsLoader::requestCCDBInputs(inputs, opts, requestCTPLumi);
285+
o2::tpc::CorrectionMapsLoader::requestCCDBInputs(inputs, opts, lumiType);
286286

287287
auto ccdbRequest = std::make_shared<o2::base::GRPGeomRequest>(false, // orbitResetTime
288288
false, // GRPECS=true

0 commit comments

Comments
 (0)