Project
Loading...
Searching...
No Matches
CalibLaserTracksSpec.h
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
12#ifndef O2_TPC_CalibLaserTracksSpec_H
13#define O2_TPC_CalibLaserTracksSpec_H
14
17
18#include "TFile.h"
22#include "Framework/Task.h"
26#include "CCDB/CcdbApi.h"
27#include "CCDB/CcdbObjectInfo.h"
30
32
33using namespace o2::framework;
34
35namespace o2::tpc
36{
37
39{
40 public:
42 {
43 mWriteDebug = ic.options().get<bool>("write-debug");
44 mCalib.setWriteDebugTree(mWriteDebug);
45 mMinNumberTFs = ic.options().get<int>("min-tfs");
46 mOnlyPublishOnEOS = ic.options().get<bool>("only-publish-on-eos");
47 mNormalize = !ic.options().get<bool>("ignore-normalization");
48 auto finishFunction = [this]() {
49 if (!mPublished) {
50 const auto nTFs = mCalib.getCalibData().processedTFs;
51 const auto nMatchA = mCalib.getMatchedPairsA();
52 const auto nMatchC = mCalib.getMatchedPairsC();
53 LOGP(error, "Calibration data was not published, laser track calibration might not have enough statistics: {} ({}) matched tracks in {} TFs on the A (C) < {} min TFs * {} min matches per side per TF? Or eos was not called by the framework.", nMatchA, nMatchC, nTFs, mMinNumberTFs, CalibLaserTracks::MinTrackPerSidePerTF);
54 }
55 };
56 ic.services().get<CallbackService>().set<CallbackService::Id::Stop>(finishFunction);
57 }
58
60 {
61 const auto dph = o2::header::get<o2::framework::DataProcessingHeader*>(pc.inputs().get("input").header);
62 if (!dph) {
63 LOGP(warning, "CalibLaserTracksDevice::run: No DataProcessingHeader found for \"input\". Only conditions? Skipping event.");
64 return;
65 }
66 mTPCVDriftHelper.extractCCDBInputs(pc);
67 if (mTPCVDriftHelper.isUpdated()) {
68 mTPCVDriftHelper.acknowledgeUpdate();
69 mCalib.setVDriftRef(mTPCVDriftHelper.getVDriftObject().getVDrift());
70 LOGP(info, "Updated reference drift velocity to: {}", mTPCVDriftHelper.getVDriftObject().getVDrift());
71 }
72 const auto startTime = dph->startTime;
73 const auto endTime = dph->startTime + dph->duration;
74 mRunNumber = processing_helpers::getRunNumber(pc);
75
76 auto data = pc.inputs().get<gsl::span<TrackTPC>>("input");
77 mCalib.setTFtimes(startTime, endTime);
78 mCalib.fill(data);
79
80 if (!mOnlyPublishOnEOS && mCalib.hasEnoughData(mMinNumberTFs) && !mPublished) {
81 sendOutput(pc.outputs());
82 }
83 }
84
86 {
87 LOGP(info, "CalibLaserTracksDevice::endOfStream: Finalizing calibration");
88 if (!mCalib.hasEnoughData(mMinNumberTFs)) {
89 const auto nTFs = mCalib.getCalibData().processedTFs;
90 const auto nMatchA = mCalib.getMatchedPairsA();
91 const auto nMatchC = mCalib.getMatchedPairsC();
92 LOGP(warning, "laser track calibration does not have enough statistics: {} ({}) matched tracks in {} TFs on the A (C) < {} min TFs * {} min matches per side per TF ", nMatchA, nMatchC, nTFs, mMinNumberTFs, CalibLaserTracks::MinTrackPerSidePerTF);
93 }
94 sendOutput(ec.outputs());
95 }
96
97 void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) final
98 {
99 if (mTPCVDriftHelper.accountCCDBInputs(matcher, obj)) {
100 return;
101 }
102 }
103
104 private:
105 CalibLaserTracks mCalib;
106 o2::tpc::VDriftHelper mTPCVDriftHelper{};
107 uint64_t mRunNumber{0};
108 int mMinNumberTFs{100};
109 bool mPublished{false};
110 bool mOnlyPublishOnEOS{false};
111 bool mNormalize{true};
112 bool mWriteDebug{false};
113
114 //________________________________________________________________
115 void sendOutput(DataAllocator& output)
116 {
117 mCalib.finalize();
118 mCalib.print();
119
120 std::map<std::string, std::string> md;
121
123 auto ltrCalib = mCalib.getCalibData();
124 if (!ltrCalib.isValid()) {
125 LOGP(error, "Invalid Laser calibration (corrections: A-side={}, C-side={}, NTracks: A-side={} C-side={}), will NOT upload to CCDB", ltrCalib.dvCorrectionA, ltrCalib.dvCorrectionC, ltrCalib.nTracksA, ltrCalib.nTracksC);
126 return;
127 }
128
129 if (mNormalize) {
130 ltrCalib.normalize(0.);
131 LOGP(info, "After normalization: correction factors: {} / {} for A- / C-Side, reference: {}, vdrift correction: {}", ltrCalib.dvCorrectionA, ltrCalib.dvCorrectionC, ltrCalib.refVDrift, ltrCalib.getDriftVCorrection());
132 }
133
135 auto image = o2::ccdb::CcdbApi::createObjectImage(&ltrCalib, &w);
136
137 md = w.getMetaData();
138 md[o2::base::NameConf::CCDBRunTag.data()] = std::to_string(mRunNumber);
139 w.setMetaData(md);
140
141 const auto now = std::chrono::system_clock::now();
142 const long timeStart = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
143 // const auto timeStart = ltrCalib.firstTime; //TODO: use once it is a correct time not TFid
145
146 w.setPath("TPC/Calib/LaserTracks");
147 w.setStartValidityTimestamp(timeStart);
148 w.setEndValidityTimestamp(timeEnd);
149
150 LOGP(info, "Sending object {} / {} of size {} bytes, valid for {} : {} ", w.getPath(), w.getFileName(), image->size(), w.getStartValidityTimestamp(), w.getEndValidityTimestamp());
151 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "TPC_CalibLtr", 0}, *image.get());
152 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "TPC_CalibLtr", 0}, w);
153
154 mPublished = true;
155
156 if (mWriteDebug) {
157 TFile f("LaserTracks.snapshot.root", "recreate");
158 f.WriteObject(&ltrCalib, "ccdb_object");
159 }
160 }
161};
162
163DataProcessorSpec getCalibLaserTracks(const std::string inputSpec)
164{
165 using device = o2::tpc::CalibLaserTracksDevice;
166
167 std::vector<OutputSpec> outputs;
168 outputs.emplace_back(ConcreteDataTypeMatcher{"TPC", "LtrCalibData"}, Lifetime::Sporadic);
169 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "TPC_CalibLtr"}, Lifetime::Sporadic);
170 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "TPC_CalibLtr"}, Lifetime::Sporadic);
171 std::vector<InputSpec> inputs = select(inputSpec.data());
173
174 return DataProcessorSpec{
175 "tpc-calib-laser-tracks",
176 inputs,
177 outputs,
178 AlgorithmSpec{adaptFromTask<device>()},
179 Options{
180 {"write-debug", VariantType::Bool, false, {"write a debug output tree."}},
181 {"min-tfs", VariantType::Int, 100, {"minimum number of TFs with enough laser tracks to finalize the calibration."}},
182 {"only-publish-on-eos", VariantType::Bool, false, {"only publish the calibration on eos, not during running"}},
183 {"ignore-normalization", VariantType::Bool, false, {"ignore normalization of reference to have mean correction factor 1"}},
184 }};
185}
186
187} // namespace o2::tpc
188
189#endif
calibration using laser tracks
Utils and constants for calibration and related workflows.
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
Definition of the Names Generator class.
Helper class to extract VDrift from different sources.
static constexpr std::string_view CCDBRunTag
Definition NameConf.h:69
static std::unique_ptr< std::vector< char > > createObjectImage(const T *obj, CcdbObjectInfo *info=nullptr)
Definition CcdbApi.h:103
static constexpr long INFINITE_TIMESTAMP
void run(o2::framework::ProcessingContext &pc) final
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
void init(o2::framework::InitContext &ic) final
void endOfStream(o2::framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void finalize()
Finalize full processing.
size_t getMatchedPairsC() const
number of associated laser tracks for all processed TFs on the C-Side
bool hasEnoughData(size_t numTFs=1) const
static constexpr size_t MinTrackPerSidePerTF
void fill(const gsl::span< const TrackTPC > tracks)
process all tracks of one TF
void setWriteDebugTree(bool write)
void print() const
print information
size_t getMatchedPairsA() const
number of associated laser tracks for all processed TFs on the A-Side
void setTFtimes(uint64_t tfStart, uint64_t tfEnd=0)
const LtrCalibData & getCalibData()
drift velocity fit information for full data set
static void requestCCDBInputs(std::vector< o2::framework::InputSpec > &inputs, bool laser=true, bool itstpcTgl=true)
void extractCCDBInputs(o2::framework::ProcessingContext &pc, bool laser=true, bool itstpcTgl=true)
const VDriftCorrFact & getVDriftObject() const
bool accountCCDBInputs(const o2::framework::ConcreteDataMatcher &matcher, void *obj)
bool isUpdated() const
GLeglImageOES image
Definition glcorearb.h:4021
GLdouble f
Definition glcorearb.h:310
GLboolean * data
Definition glcorearb.h:298
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
uint64_t now() noexcept
Definition Clock.h:69
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
std::vector< InputSpec > select(char const *matcher="")
uint64_t getRunNumber(o2::framework::ProcessingContext &pc)
Global TPC definitions and constants.
Definition SimTraits.h:167
DataProcessorSpec getCalibLaserTracks(const std::string inputSpec)
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
static constexpr o2::header::DataOrigin gDataOriginCDBWrapper
Definition Utils.h:44
static constexpr o2::header::DataOrigin gDataOriginCDBPayload
Definition Utils.h:43
size_t processedTFs
number of processed TFs with laser track candidates