Project
Loading...
Searching...
No Matches
VDriftHelper.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
18#include "Framework/Logger.h"
24
25using namespace o2::tpc;
26using namespace o2::framework;
27
28//________________________________________________________
30{
31 const auto& gaspar = o2::tpc::ParameterGas::Instance();
32 const auto& detpar = o2::tpc::ParameterDetector::Instance();
33 const auto& elpar = o2::tpc::ParameterElectronics::Instance();
34 mVD.corrFact = 1.0;
35 mVD.refVDrift = gaspar.DriftV;
36 mVD.refTimeOffset = detpar.DriftTimeOffset * elpar.ZbinWidth; // convert time bins to \mus
37 // was it imposed from the command line?
38 mVD.creationTime = 1; // just to be above 0
39 if (o2::conf::ConfigurableParam::getProvenance("TPCGasParam.DriftV") == o2::conf::ConfigurableParam::EParamProvenance::kRT) { // we stick to this value
40 mVD.creationTime = std::numeric_limits<long>::max();
41 mForceParamDrift = true;
42 LOGP(info, "TPC VDrift was set from command line to {}, will neglect update from CCDB", mVD.refVDrift);
43 }
44 if (o2::conf::ConfigurableParam::getProvenance("TPCDetParam.DriftTimeOffset") == o2::conf::ConfigurableParam::EParamProvenance::kRT) { // we stick to this value
45 mVD.creationTime = std::numeric_limits<long>::max();
46 mForceParamOffset = true;
47 LOGP(info, "TPC drift time offset was set from command line to {} mus ({} TB), will neglect update from CCDB",
48 mVD.refTimeOffset, detpar.DriftTimeOffset);
49 }
50
51 // check if temperature and pressure is set from the command line
53 mForceTPScaling = true;
54 LOGP(info, "VDriftHelper: Temperature and pressure were set from command line to {} C and {} mbar, will neglect updates from CCDB", gaspar.Temperature, gaspar.Pressure);
55 if (gaspar.Temperature <= 0 || gaspar.Pressure <= 0) {
56 LOGP(info, "VDriftHelper: Disabling VDrift scaling with T / P");
57 }
58 }
59
60 mUpdated = true;
62}
63
64//________________________________________________________
65void VDriftHelper::accountLaserCalibration(const LtrCalibData* calib, long fallBackTimeStamp)
66{
67 if (!calib || mForceParamDrift) { // laser may set only DriftParam (the offset is 0)
68 return;
69 }
70 if (!calib->isValid()) {
71 LOGP(warn, "Ignoring invalid laser calibration (corrections: A-side={}, C-side={}, NTracks: A-side={} C-side={})", calib->dvCorrectionA, calib->dvCorrectionC, calib->nTracksA, calib->nTracksC);
72 return;
73 }
74 // old entries of laser calib have no update time assigned
75 long updateTS = calib->creationTime > 0 ? calib->creationTime : fallBackTimeStamp;
76 LOG(info) << "accountLaserCalibration " << calib->refVDrift << " / " << calib->getDriftVCorrection() << " t " << updateTS << " vs " << mVDLaser.creationTime;
77 // old entries of laser calib have no reference assigned
78 float ref = calib->refVDrift > 0. ? calib->refVDrift : o2::tpc::ParameterGas::Instance().DriftV;
79 float corr = calib->getDriftVCorrection();
80 if (corr > 0.) { // laser correction is inverse multiplicative
81 static bool firstCall = true;
82 auto prevRef = mVDLaser.refVDrift;
84 mVDLaser.corrFact = 1. / corr;
87 mVDLaser.refTP = calib->tp;
88 mUpdated = true;
90 if (mMayRenormSrc & (0x1U << Source::Laser)) { // this was 1st setting?
91 if (corr != 1.f) { // this may happen if old-style (non-normalized) standalone or non-normalized run-time laset calibration is used
92 LOGP(warn, "VDriftHelper: renorming initial TPC refVDrift={}/correction={} to {}/1.0, source: {}", mVDLaser.refVDrift, mVDLaser.corrFact, mVDLaser.getVDrift(), getSourceName(mSource));
93 mVDLaser.normalize(); // renorm reference to have correction = 1.
94 }
95 mMayRenormSrc &= ~(0x1U << Source::Laser); // unset MayRenorm
96 } else if (ref != prevRef) { // we want to keep the same reference over the run, this may happen if run-time laser calibration is supplied
97 LOGP(warn, "VDriftHelper: renorming updated TPC refVDrift={}/correction={} previous refVDrift {}, source: {}", mVDLaser.refVDrift, mVDLaser.corrFact, prevRef, getSourceName(mSource));
98 mVDLaser.normalize(prevRef);
99 }
100 }
101}
102
103//________________________________________________________
105{
106 if (!calib || (mForceParamDrift && mForceParamOffset)) {
107 return;
108 }
109 LOG(info) << "accountDriftCorrectionITSTPCTgl " << calib->corrFact << " t " << calib->creationTime << " vs " << mVDTPCITSTgl.creationTime;
110 auto prevRefVDrift = mVDTPCITSTgl.refVDrift;
111 auto prevRefTOffs = mVDTPCITSTgl.refTimeOffset;
112 mVDTPCITSTgl = *calib;
113 mUpdated = true;
115 if (mMayRenormSrc & (0x1U << Source::ITSTPCTgl)) { // this was 1st setting?
116 if (!mForceParamDrift && mVDTPCITSTgl.corrFact != 1.f) { // this may happen if calibration from prevous run is used
117 LOGP(warn, "VDriftHelper: renorming initial TPC refVDrift={}/correction={} to {}/1.0, source: {}", mVDTPCITSTgl.refVDrift, mVDTPCITSTgl.corrFact, mVDTPCITSTgl.getVDrift(), getSourceName(mSource));
118 mVDTPCITSTgl.normalize(); // renorm reference to have correction = 1.
119 }
121 LOGP(warn, "VDriftHelper: renorming initial TPC refTimeOffset={}/correction={} to {}/0.0, source: {}", mVDTPCITSTgl.refTimeOffset, mVDTPCITSTgl.timeOffsetCorr, mVDTPCITSTgl.getTimeOffset(), getSourceName());
123 }
124 mMayRenormSrc &= ~(0x1U << Source::ITSTPCTgl); // unset MayRenorm
125 } else {
126 if (!mForceParamDrift && mVDTPCITSTgl.refVDrift != prevRefVDrift) { // we want to keep the same reference over the run, this should not happen!
127 LOGP(warn, "VDriftHelper: renorming updated TPC refVDrift={}/correction={} previous refVDrift {}, source: {}", mVDTPCITSTgl.refVDrift, mVDTPCITSTgl.corrFact, prevRefVDrift, getSourceName());
128 mVDTPCITSTgl.normalize(prevRefVDrift);
129 }
130 if (!mForceParamOffset && mVDTPCITSTgl.refTimeOffset != prevRefTOffs) { // we want to keep the same reference over the run, this should not happen!
131 LOGP(warn, "VDriftHelper: renorming updated TPC refTimeOffset={}/correction={} previous refTimeOffset {}, source: {}", mVDTPCITSTgl.refTimeOffset, mVDTPCITSTgl.timeOffsetCorr, prevRefTOffs, getSourceName());
132 mVDTPCITSTgl.normalizeOffset(prevRefTOffs);
133 }
134 }
135}
136
137//________________________________________________________
139{
140 if (mForceParamDrift && mForceParamOffset) { // fixed from the command line
141 return;
142 }
143 if (laser && !mForceParamDrift) {
144 pc.inputs().get<o2::tpc::LtrCalibData*>("laserCalib");
145 }
146 if (itstpcTgl) {
147 pc.inputs().get<o2::tpc::VDriftCorrFact*>("vdriftTgl");
148 }
150
151 if (mUpdated || mIsTPScalingPossible) { // there was a change
152 // prefer among laser and tgl VDrift the one with the latest update time
153 auto saveVD = mVD;
154
155 // apply TP scaling of mVD if possible
156 if (float tp = mPTHelper.getTP(pc.services().get<o2::framework::TimingInfo>().creation); tp > 0) {
157 // try to extract refTP if needed
159 if (mForceTPScaling) {
160 const auto& gaspar = o2::tpc::ParameterGas::Instance();
161 tp = (gaspar.Temperature > 0 && gaspar.Pressure > 0) ? ((gaspar.Temperature + 273.15) / gaspar.Pressure) : -1;
162 mIsTPScalingPossible = (tp > 0) && (vd.refTP > 0 || extractTPForVDrift(vd));
163 } else {
164 mIsTPScalingPossible = (vd.refTP > 0) || extractTPForVDrift(vd);
165 }
167 mUpdated = true;
168 vd.normalize(0, tp);
169 if (vd.creationTime == saveVD.creationTime) {
170 LOGP(info, "VDriftHelper: Scaling VDrift from {} to {} with T/P from {} to {}", saveVD.getVDrift(), vd.getVDrift(), saveVD.refTP, vd.refTP);
171 } else {
172 LOGP(info, "VDriftHelper: Init new VDrift of {} with T/P {}", vd.getVDrift(), vd.refTP);
173 }
174 }
175 }
176
179
180 if (mForceParamDrift) {
181 mVD.refVDrift = saveVD.refVDrift;
182 mVD.corrFact = saveVD.corrFact;
183 mVD.corrFactErr = 0.f;
184 }
185 if (mForceParamOffset) {
186 mVD.refTimeOffset = saveVD.refTimeOffset;
187 mVD.timeOffsetCorr = 0.f;
188 }
190 auto loseCTime = loserVD.creationTime;
191 loserVD = mVD; // override alternative VD to avoid normalization problems later
192 loserVD.creationTime = loseCTime;
193 std::string rep = fmt::format("Prefer TPC Drift from {} with time {} to {} with time {}",
197 std::string impos = mForceParamDrift ? "VDrift" : "";
198 if (mForceParamOffset) {
199 impos += mForceParamDrift ? " and DriftTimeOffset" : "DriftTimeOffset";
200 }
201 rep += fmt::format(" but {} imposed from command line", impos);
202 }
203 LOGP(info, "{}", rep);
204 }
205}
206
207//________________________________________________________
208void VDriftHelper::requestCCDBInputs(std::vector<InputSpec>& inputs, bool laser, bool itstpcTgl)
209{
210 if (laser) {
211 addInput(inputs, {"laserCalib", "TPC", "CalibLaserTracks", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalLaserTracks))});
212 }
213 if (itstpcTgl) {
214 // VDrift calibration may change during the run (in opposite to Laser calibration, at least at the moment), so ask per-TF query
215 addInput(inputs, {"vdriftTgl", "TPC", "VDriftTgl", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalVDriftTgl), {}, 1)});
216 }
217 // adding pressure and temperature inputs
219}
220
221//________________________________________________________
222void VDriftHelper::addInput(std::vector<InputSpec>& inputs, InputSpec&& isp)
223{
224 if (std::find(inputs.begin(), inputs.end(), isp) == inputs.end()) {
225 inputs.emplace_back(isp);
226 }
227}
228
229//________________________________________________________
231{
232 if (matcher == ConcreteDataMatcher("TPC", "VDriftTgl", 0)) {
234 return true;
235 }
236 if (matcher == ConcreteDataMatcher("TPC", "CalibLaserTracks", 0)) {
237 accountLaserCalibration(static_cast<LtrCalibData*>(obj));
238 return true;
239 }
240 return mPTHelper.accountCCDBInputs(matcher, obj);
241}
242
244{
245 const int64_t tsStart = vdrift.firstTime;
246 const int64_t tsEnd = vdrift.lastTime;
247
248 // make sanity check of the time range
249 const auto [minValidTime, maxValidTime] = mPTHelper.getMinMaxTime();
250 const int64_t minTimeAccepted = static_cast<int64_t>(minValidTime) - 20 * o2::ccdb::CcdbObjectInfo::MINUTE;
251 const int64_t maxTimeAccepted = static_cast<int64_t>(maxValidTime) + 20 * o2::ccdb::CcdbObjectInfo::MINUTE;
252
253 // check if the stored time stamp range is valid i.e. check if the range is in the vicinity of the current time
254 if ((minTimeAccepted > tsEnd) || (tsStart > maxTimeAccepted)) {
255 // check if creation time can be used
256 LOGP(warn, "VDriftHelper: Time range of VDrift object {} - {} is not valid for time range of T/P object {} - {}! Do not extract ref. T/P for VDrift!", tsStart, tsEnd, minValidTime, maxValidTime);
257 return false;
258 }
259
260 double meanTP = 0;
261 int countTP = 0;
262
263 for (int64_t ts = tsStart; ts < tsEnd; ts += tsStepMS) {
264 meanTP += mPTHelper.getTP(ts);
265 ++countTP;
266 }
267
268 if (countTP == 0) {
269 LOGP(error, "VDriftHelper: Could not get T/P for time range {} -> {}", tsStart, tsEnd);
270 return false;
271 }
272
273 meanTP /= countTP;
274
275 LOGP(info, "VDriftHelper: Setting mean T/P for VDrift to {} for time range {} -> {}", meanTP, tsStart, tsEnd);
276 vdrift.refTP = meanTP;
277 return true;
278}
Simple interface to the CDB manager.
uint64_t laser
calibration data from laser track calibration
Definition of the parameter class for the detector.
Definition of the parameter class for the detector electronics.
Definition of the parameter class for the detector gas.
Helper class to extract VDrift from different sources.
static constexpr long MINUTE
static EParamProvenance getProvenance(const std::string &key)
decltype(auto) get(R binding, int part=0) const
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
static void requestCCDBInputs(std::vector< o2::framework::InputSpec > &inputs)
void extractCCDBInputs(o2::framework::ProcessingContext &pc) const
trigger checking for CCDB objects
std::pair< ULong64_t, ULong64_t > getMinMaxTime() const
get minimum and maximum time stamps of the pressure and temperature data
bool accountCCDBInputs(const o2::framework::ConcreteDataMatcher &matcher, void *obj)
check for new CCDB objects
static void requestCCDBInputs(std::vector< o2::framework::InputSpec > &inputs, bool laser=true, bool itstpcTgl=true)
bool extractTPForVDrift(VDriftCorrFact &vdrift, int64_t tsStepMS=100 *1000)
VDriftCorrFact mVDLaser
void extractCCDBInputs(o2::framework::ProcessingContext &pc, bool laser=true, bool itstpcTgl=true)
static void addInput(std::vector< o2::framework::InputSpec > &inputs, o2::framework::InputSpec &&isp)
std::string_view getSourceName() const
bool accountCCDBInputs(const o2::framework::ConcreteDataMatcher &matcher, void *obj)
static constexpr std::array< std::string_view, NSources > SourceNames
VDriftCorrFact mVD
void accountDriftCorrectionITSTPCTgl(const VDriftCorrFact *calib)
VDriftCorrFact mVDTPCITSTgl
PressureTemperatureHelper mPTHelper
void accountLaserCalibration(const LtrCalibData *calib, long fallBackTimeStamp=2)
GLint ref
Definition glcorearb.h:291
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
Global TPC definitions and constants.
Definition SimTraits.h:167
const std::unordered_map< CDBType, const std::string > CDBTypeMap
Storage name in CCDB for each calibration and parameter type.
Definition CDBTypes.h:96
@ CalVDriftTgl
ITS-TPC difTgl vdrift calibration.
@ CalLaserTracks
Laser track calibration data.
float getDriftVCorrection() const
float dvCorrectionA
drift velocity correction factor A-Side (inverse multiplicative)
float tp
temperature over pressure ratio
float dvCorrectionC
drift velocity correction factor C-Side (inverse multiplicative)
uint16_t nTracksC
number of tracks used for C-Side fit
long creationTime
time of creation
uint16_t nTracksA
number of tracks used for A-Side fit
float refTimeOffset
additive time offset reference (\mus)
float refVDrift
reference vdrift for which factor was extracted
float DriftV
Drift velocity [cm/us].
long creationTime
time of creation
void normalizeOffset(float newRefTimeOffset=-999.)
float corrFactErr
stat error of correction factor
float refTimeOffset
additive time offset reference (\mus)
void normalize(float newVRef=0.f, float tp=0.f)
long lastTime
last time stamp of processed TFs
float refVDrift
reference vdrift for which factor was extracted
float getTimeOffset() const
float timeOffsetCorr
additive time offset correction (\mus)
float corrFact
drift velocity correction factor (multiplicative)
float refTP
reference temperature / pressure for which refVDrift was extracted
long firstTime
first time stamp of processed TFs
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"