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 // if no new VDrift object was loaded and if delta TP is small, do not rescale and return
168 if (!mUpdated && std::abs(tp - vd.refTP) < 1e-5) {
169 return;
170 }
171 mUpdated = true;
172 vd.normalize(0, tp);
173 if (vd.creationTime == saveVD.creationTime) {
174 LOGP(info, "VDriftHelper: Scaling VDrift from {} to {} with T/P from {} to {}", saveVD.getVDrift(), vd.getVDrift(), saveVD.refTP, vd.refTP);
175 } else {
176 LOGP(info, "VDriftHelper: Init new VDrift of {} with T/P {}", vd.getVDrift(), vd.refTP);
177 }
178 }
179 }
180
183
184 if (mForceParamDrift) {
185 mVD.refVDrift = saveVD.refVDrift;
186 mVD.corrFact = saveVD.corrFact;
187 mVD.corrFactErr = 0.f;
188 }
189 if (mForceParamOffset) {
190 mVD.refTimeOffset = saveVD.refTimeOffset;
191 mVD.timeOffsetCorr = 0.f;
192 }
194 auto loseCTime = loserVD.creationTime;
195 loserVD = mVD; // override alternative VD to avoid normalization problems later
196 loserVD.creationTime = loseCTime;
197 std::string rep = fmt::format("Prefer TPC Drift from {} with time {} to {} with time {}",
201 std::string impos = mForceParamDrift ? "VDrift" : "";
202 if (mForceParamOffset) {
203 impos += mForceParamDrift ? " and DriftTimeOffset" : "DriftTimeOffset";
204 }
205 rep += fmt::format(" but {} imposed from command line", impos);
206 }
207 LOGP(info, "{}", rep);
208 }
209}
210
211//________________________________________________________
212void VDriftHelper::requestCCDBInputs(std::vector<InputSpec>& inputs, bool laser, bool itstpcTgl)
213{
214 if (laser) {
215 addInput(inputs, {"laserCalib", "TPC", "CalibLaserTracks", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalLaserTracks))});
216 }
217 if (itstpcTgl) {
218 // VDrift calibration may change during the run (in opposite to Laser calibration, at least at the moment), so ask per-TF query
219 addInput(inputs, {"vdriftTgl", "TPC", "VDriftTgl", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalVDriftTgl), {}, 1)});
220 }
221 // adding pressure and temperature inputs
223}
224
225//________________________________________________________
226void VDriftHelper::addInput(std::vector<InputSpec>& inputs, InputSpec&& isp)
227{
228 if (std::find(inputs.begin(), inputs.end(), isp) == inputs.end()) {
229 inputs.emplace_back(isp);
230 }
231}
232
233//________________________________________________________
235{
236 if (matcher == ConcreteDataMatcher("TPC", "VDriftTgl", 0)) {
238 return true;
239 }
240 if (matcher == ConcreteDataMatcher("TPC", "CalibLaserTracks", 0)) {
241 accountLaserCalibration(static_cast<LtrCalibData*>(obj));
242 return true;
243 }
244 return mPTHelper.accountCCDBInputs(matcher, obj);
245}
246
248{
249 const int64_t tsStart = vdrift.firstTime;
250 const int64_t tsEnd = vdrift.lastTime;
251
252 if (tsStart == tsEnd) {
253 static bool warned = false;
254 if (!warned) {
255 warned = true;
256 LOGP(warn, "VDriftHelper: Cannot extract T/P for VDrift with identical start/end time {}!", tsStart);
257 }
258 return false;
259 }
260
261 // make sanity check of the time range
262 const auto [minValidTime, maxValidTime] = mPTHelper.getMinMaxTime();
263 const int64_t minTimeAccepted = static_cast<int64_t>(minValidTime) - 20 * o2::ccdb::CcdbObjectInfo::MINUTE;
264 const int64_t maxTimeAccepted = static_cast<int64_t>(maxValidTime) + 20 * o2::ccdb::CcdbObjectInfo::MINUTE;
265
266 // check if the stored time stamp range is valid i.e. check if the range is in the vicinity of the current time
267 if ((minTimeAccepted > tsEnd) || (tsStart > maxTimeAccepted)) {
268 // check if creation time can be used
269 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);
270 return false;
271 }
272
273 double meanTP = 0;
274 int countTP = 0;
275
276 for (int64_t ts = tsStart; ts < tsEnd; ts += tsStepMS) {
277 meanTP += mPTHelper.getTP(ts);
278 ++countTP;
279 }
280
281 if (countTP == 0) {
282 LOGP(error, "VDriftHelper: Could not get T/P for time range {} -> {}", tsStart, tsEnd);
283 return false;
284 }
285
286 meanTP /= countTP;
287
288 LOGP(info, "VDriftHelper: Setting mean T/P for VDrift to {} for time range {} -> {}", meanTP, tsStart, tsEnd);
289 vdrift.refTP = meanTP;
290 return true;
291}
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"