Project
Loading...
Searching...
No Matches
LHCClockCalibratorSpec.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_CALIBRATION_LHCCLOCK_CALIBRATOR_H
13#define O2_CALIBRATION_LHCCLOCK_CALIBRATOR_H
14
17
22#include "Framework/Task.h"
27#include "CCDB/CcdbApi.h"
28#include "CCDB/CcdbObjectInfo.h"
31
32#include <TSystem.h>
33
34using namespace o2::framework;
35
36namespace o2
37{
38namespace calibration
39{
40
42{
45
46 public:
47 LHCClockCalibDevice(std::shared_ptr<o2::base::GRPGeomRequest> req, bool useCCDB) : mCCDBRequest(req), mUseCCDB(useCCDB) {}
48
50 {
52 int minEnt = std::max(300, ic.options().get<int>("min-entries"));
53 int nb = std::max(500, ic.options().get<int>("nbins"));
54 auto slotL = ic.options().get<uint32_t>("tf-per-slot");
55 auto delay = ic.options().get<uint32_t>("max-delay");
56 std::string path = ic.options().get<std::string>("output-path");
57
58 mCalibrator = std::make_unique<o2::tof::LHCClockCalibrator>(minEnt, nb);
59 mCalibrator->setPath(path.data());
60 mCalibrator->setSlotLength(slotL);
61 mCalibrator->setMaxSlotsDelay(delay);
62
63 if (!mUseCCDB) {
64 // calibration objects set to zero
65 mPhase.addLHCphase(0, 0);
67 if (gSystem->AccessPathName("localTimeSlewing.root") == false) {
68 TFile* fsleewing = TFile::Open("localTimeSlewing.root");
69 if (fsleewing) {
70 TimeSlewing* ob = (TimeSlewing*)fsleewing->Get("ccdb_object");
71 mTimeSlewing = *ob;
72 }
73 } else {
74 for (int ich = 0; ich < TimeSlewing::NCHANNELS; ich++) {
75 mTimeSlewing.addTimeSlewingInfo(ich, 0, 0);
76 int sector = ich / TimeSlewing::NCHANNELXSECTOR;
77 int channelInSector = ich % TimeSlewing::NCHANNELXSECTOR;
78 mTimeSlewing.setFractionUnderPeak(sector, channelInSector, 1);
79 }
80 }
81 }
82 }
83
85 {
86
87 LOG(debug) << "We are running LHCPhase";
89 auto data = pc.inputs().get<gsl::span<o2::dataformats::CalibInfoTOF>>("input");
90 o2::base::TFIDInfoHelper::fillTFIDInfo(pc, mCalibrator->getCurrentTFInfo());
91
92 if (mUseCCDB) { // read calibration objects from ccdb with the CCDB fetcher
93 const auto lhcPhaseIn = pc.inputs().get<LHCphase*>("tofccdbLHCphase");
94 const auto channelCalibIn = pc.inputs().get<TimeSlewing*>("tofccdbChannelCalib");
95 if (!mcalibTOFapi) {
96 LHCphase* lhcPhase = new LHCphase(std::move(*lhcPhaseIn));
97 TimeSlewing* channelCalib = new TimeSlewing(std::move(*channelCalibIn));
98 mcalibTOFapi = new o2::tof::CalibTOFapi(long(0), lhcPhase, channelCalib);
99 mUpdateCCDB = false;
100 } else {
101 // if the calib objects were updated, we need to update the mcalibTOFapi
102 if (mUpdateCCDB) {
103 delete mcalibTOFapi;
104 LHCphase* lhcPhase = new LHCphase(*lhcPhaseIn);
105 TimeSlewing* channelCalib = new TimeSlewing(std::move(*channelCalibIn));
106 mcalibTOFapi = new o2::tof::CalibTOFapi(long(0), lhcPhase, channelCalib);
107 mUpdateCCDB = false;
108 }
109 }
110 } else { // we use "fake" initial calibrations
111 if (!mcalibTOFapi) {
112 mcalibTOFapi = new o2::tof::CalibTOFapi(long(0), &mPhase, &mTimeSlewing);
113 }
114 }
115
116 mCalibrator->setCalibTOFapi(mcalibTOFapi);
117 LOG(debug) << "Data size = " << data.size();
118 if (data.size() == 0) {
119 return;
120 }
121
122 if (mUseCCDB) { // setting the timestamp to get the LHCPhase correction; if we don't use CCDB, then it can stay to 0 as set when creating the calibTOFapi above
123 const auto tfOrbitFirst = pc.services().get<o2::framework::TimingInfo>().firstTForbit;
124 mcalibTOFapi->setTimeStamp(0.001 * (o2::base::GRPGeomHelper::instance().getOrbitResetTimeMS() + tfOrbitFirst * o2::constants::lhc::LHCOrbitMUS * 0.001)); // in seconds
125 }
126
127 LOG(debug) << "Processing TF " << mCalibrator->getCurrentTFInfo().tfCounter << " with " << data.size() << " tracks";
128 mCalibrator->process(data);
129 sendOutput(pc.outputs());
130 const auto& infoVec = mCalibrator->getLHCphaseInfoVector();
131 LOG(info) << "Processed TF " << mCalibrator->getCurrentTFInfo().tfCounter << " with " << data.size() << " tracks, for which we created " << infoVec.size() << " objects";
132 }
133
134 void finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) final
135 {
137 mUpdateCCDB = false;
138 if (matcher == ConcreteDataMatcher("TOF", "LHCphaseCal", 0)) {
139 mUpdateCCDB = true;
140 return;
141 }
142 if (matcher == ConcreteDataMatcher("TOF", "ChannelCalibCal", 0)) {
143 mUpdateCCDB = true;
144 return;
145 }
146 }
147
149 {
150 LOG(info) << "Finalizing calibration";
151 mCalibrator->checkSlotsToFinalize(o2::calibration::INFINITE_TF);
152 sendOutput(ec.outputs());
153 }
154
155 private:
156 o2::tof::CalibTOFapi* mcalibTOFapi = nullptr;
157 LHCphase mPhase;
158 TimeSlewing mTimeSlewing;
159 std::unique_ptr<o2::tof::LHCClockCalibrator> mCalibrator;
160 std::shared_ptr<o2::base::GRPGeomRequest> mCCDBRequest;
161 bool mUpdateCCDB = false;
162 bool mUseCCDB = true;
163
164 //________________________________________________________________
165 void sendOutput(DataAllocator& output)
166 {
167 // extract CCDB infos and calibration objects, convert it to TMemFile and send them to the output
168 // TODO in principle, this routine is generic, can be moved to Utils.h
170 const auto& payloadVec = mCalibrator->getLHCphaseVector();
171 auto& infoVec = mCalibrator->getLHCphaseInfoVector(); // use non-const version as we update it
172 assert(payloadVec.size() == infoVec.size());
173
174 for (uint32_t i = 0; i < payloadVec.size(); i++) {
175 auto& w = infoVec[i];
176 auto image = o2::ccdb::CcdbApi::createObjectImage(&payloadVec[i], &w);
177 LOG(info) << "Sending object " << w.getPath() << "/" << w.getFileName() << " of size " << image->size()
178 << " bytes, valid for " << w.getStartValidityTimestamp() << " : " << w.getEndValidityTimestamp();
179 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "TOF_LHCphase", i}, *image.get()); // vector<char>
180 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "TOF_LHCphase", i}, w); // root-serialized
181 }
182 if (payloadVec.size()) {
183 mCalibrator->initOutput(); // reset the outputs once they are already sent
184 }
185 }
186};
187
188} // namespace calibration
189
190namespace framework
191{
192
193DataProcessorSpec getLHCClockCalibDeviceSpec(bool useCCDB)
194{
197 std::vector<InputSpec> inputs{{"input", "TOF", "CALIBDATA"}};
198 auto ccdbRequest = std::make_shared<o2::base::GRPGeomRequest>(true, // orbitResetTime
199 true, // GRPECS=true
200 false, // GRPLHCIF
201 false, // GRPMagField
202 false, // askMatLUT
204 inputs);
205
206 if (useCCDB) {
207 inputs.emplace_back("tofccdbLHCphase", "TOF", "LHCphaseCal", 0, Lifetime::Condition, ccdbParamSpec("TOF/Calib/LHCphase"));
208 inputs.emplace_back("tofccdbChannelCalib", "TOF", "ChannelCalibCal", 0, Lifetime::Condition, ccdbParamSpec("TOF/Calib/ChannelCalib"));
209 inputs.emplace_back("orbitResetTOF", o2::header::gDataOriginCTP, "ORBITRESETTOF", 0, Lifetime::Condition, ccdbParamSpec("CTP/Calib/OrbitReset"));
210 }
211
212 std::vector<OutputSpec> outputs;
213 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "TOF_LHCphase"}, Lifetime::Sporadic);
214 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "TOF_LHCphase"}, Lifetime::Sporadic);
215 return DataProcessorSpec{
216 "calib-lhcclock-calibration",
217 inputs,
218 outputs,
219 AlgorithmSpec{adaptFromTask<device>(ccdbRequest, useCCDB)},
220 Options{
221 {"tf-per-slot", VariantType::UInt32, 5u, {"number of TFs per calibration time slot"}},
222 {"output-path", VariantType::String, "TOF/Calib/LHCphaseSync", {"path to ccdb output"}},
223 {"max-delay", VariantType::UInt32, 3u, {"number of slots in past to consider"}},
224 {"min-entries", VariantType::Int, 500, {"minimum number of entries to fit single time slot"}},
225 {"nbins", VariantType::Int, 4000, {"number of bins for "}}}};
226}
227
228} // namespace framework
229} // namespace o2
230
231#endif
Class to store the output of the matching to TOF for calibration.
Utils and constants for calibration and related workflows.
std::ostringstream debug
int32_t i
Helper for geometry and GRP related CCDB requests.
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
void checkUpdates(o2::framework::ProcessingContext &pc)
bool finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
void endOfStream(o2::framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
LHCClockCalibDevice(std::shared_ptr< o2::base::GRPGeomRequest > req, bool useCCDB)
void init(o2::framework::InitContext &ic) final
void run(o2::framework::ProcessingContext &pc) final
void finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj) final
static std::unique_ptr< std::vector< char > > createObjectImage(const T *obj, CcdbObjectInfo *info=nullptr)
Definition CcdbApi.h:103
static constexpr long INFINITE_TIMESTAMP_SECONDS
void addLHCphase(int timestamp, float phaseLHC)
void addTimeSlewingInfo(int channel, float tot, float time)
void setFractionUnderPeak(int sector, int channel, float value)
void setTimeStamp(long t)
Definition CalibTOFapi.h:58
GLeglImageOES image
Definition glcorearb.h:4021
GLboolean * data
Definition glcorearb.h:298
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
constexpr o2::header::DataOrigin gDataOriginCTP
Definition DataHeader.h:564
constexpr TFType INFINITE_TF
Definition TimeSlot.h:30
constexpr double LHCOrbitMUS
Defining PrimaryVertex explicitly as messageable.
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
static void fillTFIDInfo(o2::framework::ProcessingContext &pc, o2::dataformats::TFIDInfo &ti)
static constexpr o2::header::DataOrigin gDataOriginCDBWrapper
Definition Utils.h:44
static constexpr o2::header::DataOrigin gDataOriginCDBPayload
Definition Utils.h:43
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"