Project
Loading...
Searching...
No Matches
TOFChannelCalibratorSpec.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_TOFCHANNEL_CALIBRATOR_H
13#define O2_CALIBRATION_TOFCHANNEL_CALIBRATOR_H
14
17
24#include "Framework/Task.h"
29#include "CCDB/CcdbApi.h"
30#include "CCDB/CcdbObjectInfo.h"
31#include <limits>
32#include "TFile.h"
34
35#include <TSystem.h>
36
37using namespace o2::framework;
38
39namespace o2
40{
41namespace calibration
42{
43
44template <class T>
46{
47
50
51 public:
52 explicit TOFChannelCalibDevice(std::shared_ptr<o2::base::GRPGeomRequest> req, bool useCCDB, bool attachChannelOffsetToLHCphase, bool isCosmics, bool perstrip = false, bool safe = false) : mCCDBRequest(req), mUseCCDB(useCCDB), mAttachToLHCphase(attachChannelOffsetToLHCphase), mCosmics(isCosmics), mDoPerStrip(perstrip), mSafeMode(safe) {}
53
55 {
57 int minEnt = ic.options().get<int>("min-entries"); //std::max(50, ic.options().get<int>("min-entries"));
58 int nb = std::max(500, ic.options().get<int>("nbins"));
59 mRange = ic.options().get<float>("range");
60 int isTest = ic.options().get<bool>("do-TOF-channel-calib-in-test-mode");
61 bool updateAtEORonly = ic.options().get<bool>("update-at-end-of-run-only");
62 auto slotL = ic.options().get<uint32_t>("tf-per-slot");
63 auto delay = ic.options().get<uint32_t>("max-delay");
64 auto updateInterval = ic.options().get<uint32_t>("update-interval");
65 auto deltaUpdateInterval = ic.options().get<uint32_t>("delta-update-interval");
66 mCalibrator = std::make_unique<o2::tof::TOFChannelCalibrator<T>>(minEnt, nb, mRange);
67
68 mCalibrator->doPerStrip(mDoPerStrip);
69 mCalibrator->doSafeMode(mSafeMode);
70
71 // default behaviour is to have only 1 slot at a time, accepting everything for it till the
72 // minimum statistics is reached;
73 // if one defines a different slot length and delay,
74 // the usual time slot calibration behaviour is used;
75 // if one defines that the calibration should happen only at the end of the run,
76 // then the slot length and delay won't matter
77 mCalibrator->setSlotLength(slotL);
78 mCalibrator->setCheckIntervalInfiniteSlot(updateInterval);
79 mCalibrator->setCheckDeltaIntervalInfiniteSlot(deltaUpdateInterval);
80 mCalibrator->setMaxSlotsDelay(delay);
81
82 if (updateAtEORonly) { // has priority over other settings
83 mCalibrator->setUpdateAtTheEndOfRunOnly();
84 }
85
86 mCalibrator->setIsTest(isTest);
87 mCalibrator->setDoCalibWithCosmics(mCosmics);
88
89 // calibration objects set to zero
90 mPhase.addLHCphase(0, 0);
92
93 if (gSystem->AccessPathName("localTimeSlewing.root") == false) {
94 TFile* fsleewing = TFile::Open("localTimeSlewing.root");
95 if (fsleewing) {
96 TimeSlewing* ob = (TimeSlewing*)fsleewing->Get("ccdb_object");
97 mTimeSlewing = *ob;
98 return;
99 }
100 } else {
101 for (int ich = 0; ich < TimeSlewing::NCHANNELS; ich++) {
102 mTimeSlewing.addTimeSlewingInfo(ich, 0, 0);
103 int sector = ich / TimeSlewing::NCHANNELXSECTOR;
104 int channelInSector = ich % TimeSlewing::NCHANNELXSECTOR;
105 mTimeSlewing.setFractionUnderPeak(sector, channelInSector, 1);
106 }
107 }
108 }
109
110 //_________________________________________________________________
111 void finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) final
112 {
114 mUpdateCCDB = false;
115 if (matcher == ConcreteDataMatcher("TOF", "LHCphaseCal", 0)) {
116 mUpdateCCDB = true;
117 return;
118 }
119 if (matcher == ConcreteDataMatcher("TOF", "ChannelCalibCal", 0)) {
120 mUpdateCCDB = true;
121 return;
122 }
123 }
124
126 {
128 long startTimeLHCphase = 0;
129 long startTimeChCalib = 0;
130 o2::base::TFIDInfoHelper::fillTFIDInfo(pc, mCalibrator->getCurrentTFInfo());
131 auto tfcounter = mCalibrator->getCurrentTFInfo().tfCounter;
132
133 if (mUseCCDB) { // read calibration objects from ccdb
134 const auto lhcPhaseIn = pc.inputs().get<LHCphase*>("tofccdbLHCphase");
135 const auto channelCalibIn = pc.inputs().get<TimeSlewing*>("tofccdbChannelCalib");
136
137 if (!mcalibTOFapi) {
138 LHCphase* lhcPhase = new LHCphase(std::move(*lhcPhaseIn));
139 TimeSlewing* channelCalib = new TimeSlewing(std::move(*channelCalibIn));
140 mcalibTOFapi = new o2::tof::CalibTOFapi(long(0), lhcPhase, channelCalib);
141 mUpdateCCDB = false;
142 } else {
143 // if the calib objects were updated, we need to update the mcalibTOFapi
144 if (mUpdateCCDB) {
145 delete mcalibTOFapi;
146 LHCphase* lhcPhase = new LHCphase(*lhcPhaseIn);
147 TimeSlewing* channelCalib = new TimeSlewing(std::move(*channelCalibIn));
148 mcalibTOFapi = new o2::tof::CalibTOFapi(long(0), lhcPhase, channelCalib);
149 mUpdateCCDB = false;
150 }
151 }
152 } else { // we use "fake" initial calibrations
153 if (!mcalibTOFapi) {
154 mcalibTOFapi = new o2::tof::CalibTOFapi(long(0), &mPhase, &mTimeSlewing);
155 }
156 }
157
158 mCalibrator->setCalibTOFapi(mcalibTOFapi);
159
160 auto data = pc.inputs().get<gsl::span<T>>("input");
161 LOG(detail) << "Processing TF " << tfcounter << " with " << data.size() << " tracks";
162
163 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
164 const auto tfOrbitFirst = pc.services().get<o2::framework::TimingInfo>().firstTForbit;
165 mcalibTOFapi->setTimeStamp(0.001 * (o2::base::GRPGeomHelper::instance().getOrbitResetTimeMS() + tfOrbitFirst * o2::constants::lhc::LHCOrbitMUS * 0.001)); // in seconds
166 }
167
168 mCalibrator->process(data);
169
170 sendOutput(pc.outputs());
171 }
172
174 {
175 mCalibrator->checkSlotsToFinalize(o2::calibration::INFINITE_TF);
176 sendOutput(ec.outputs());
177 }
178
179 private:
180 std::unique_ptr<o2::tof::TOFChannelCalibrator<T>> mCalibrator;
181 std::shared_ptr<o2::base::GRPGeomRequest> mCCDBRequest;
182 o2::tof::CalibTOFapi* mcalibTOFapi = nullptr;
183 LHCphase mPhase;
184 TimeSlewing mTimeSlewing;
185 float mRange = 24000.f;
186 bool mUseCCDB = false;
187 bool mAttachToLHCphase = false; // whether to use or not previously defined LHCphase
188 bool mCosmics = false;
189 bool mDoPerStrip = false;
190 bool mSafeMode = false;
191 bool mUpdateCCDB = false;
192
193 //________________________________________________________________
194 void sendOutput(DataAllocator& output)
195 {
196 // extract CCDB infos and calibration objects, convert it to TMemFile and send them to the output
197 // TODO in principle, this routine is generic, can be moved to Utils.h
199 const auto& payloadVec = mCalibrator->getTimeSlewingVector();
200 auto& infoVec = mCalibrator->getTimeSlewingInfoVector(); // use non-const version as we update it
201 assert(payloadVec.size() == infoVec.size());
202
203 for (uint32_t i = 0; i < payloadVec.size(); i++) {
204 auto& w = infoVec[i];
205 auto image = o2::ccdb::CcdbApi::createObjectImage(&payloadVec[i], &w);
206 LOG(info) << "Sending object " << w.getPath() << "/" << w.getFileName() << " of size " << image->size()
207 << " bytes, valid for " << w.getStartValidityTimestamp() << " : " << w.getEndValidityTimestamp();
208
209 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "TOF_CHANCALIB", i}, *image.get()); // vector<char>
210 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "TOF_CHANCALIB", i}, w); // root-serialized
211 }
212 if (payloadVec.size()) {
213 mCalibrator->initOutput(); // reset the outputs once they are already sent
214 }
215 }
216};
217
218} // namespace calibration
219
220namespace framework
221{
222
223template <class T>
224DataProcessorSpec getTOFChannelCalibDeviceSpec(bool useCCDB, bool attachChannelOffsetToLHCphase = false, bool isCosmics = false, bool perstrip = false, bool safe = false)
225{
228
229 std::vector<OutputSpec> outputs;
230 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "TOF_CHANCALIB"}, Lifetime::Sporadic);
231 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "TOF_CHANCALIB"}, Lifetime::Sporadic);
232
233 std::vector<InputSpec> inputs;
234 if (!isCosmics) {
235 inputs.emplace_back("input", "TOF", "CALIBDATA");
236 } else {
237 inputs.emplace_back("input", "TOF", "INFOCALCLUS");
238 }
239 auto ccdbRequest = std::make_shared<o2::base::GRPGeomRequest>(true, // orbitResetTime
240 true, // GRPECS=true
241 false, // GRPLHCIF
242 false, // GRPMagField
243 false, // askMatLUT
245 inputs);
246 if (useCCDB) {
247 inputs.emplace_back("tofccdbLHCphase", o2::header::gDataOriginTOF, "LHCphase", 0, Lifetime::Condition, ccdbParamSpec("TOF/Calib/LHCphase"));
248 inputs.emplace_back("tofccdbChannelCalib", o2::header::gDataOriginTOF, "ChannelCalib", 0, Lifetime::Condition, ccdbParamSpec("TOF/Calib/ChannelCalib"));
249 }
250
251 return DataProcessorSpec{
252 "calib-tofchannel-calibration",
253 inputs,
254 outputs,
255 AlgorithmSpec{adaptFromTask<device>(ccdbRequest, useCCDB, attachChannelOffsetToLHCphase, isCosmics, perstrip, safe)},
256 Options{
257 {"min-entries", VariantType::Int, 500, {"minimum number of entries to fit channel histos"}},
258 {"nbins", VariantType::Int, 1000, {"number of bins for t-texp"}},
259 {"range", VariantType::Float, 24000.f, {"range for t-text"}},
260 {"do-TOF-channel-calib-in-test-mode", VariantType::Bool, false, {"to run in test mode for simplification"}},
261 {"ccdb-path", VariantType::String, o2::base::NameConf::getCCDBServer(), {"Path to CCDB"}},
262 {"update-at-end-of-run-only", VariantType::Bool, false, {"to update the CCDB only at the end of the run; has priority over calibrating in time slots"}},
263 {"tf-per-slot", VariantType::UInt32, 0u, {"number of TFs per calibration time slot, if 0: close once statistics reached"}},
264 {"max-delay", VariantType::UInt32, 0u, {"number of slots in past to consider"}},
265 {"update-interval", VariantType::UInt32, 10u, {"number of TF after which to try to finalize calibration"}},
266 {"delta-update-interval", VariantType::UInt32, 10u, {"number of TF after which to try to finalize calibration, if previous attempt failed"}}}};
267}
268
269} // namespace framework
270} // namespace o2
271
272#endif
Class to store the output of the matching to TOF for calibration.
Utils and constants for calibration and related workflows.
int32_t i
Helper for geometry and GRP related CCDB requests.
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
Definition of the Names Generator class.
void checkUpdates(o2::framework::ProcessingContext &pc)
bool finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
static std::string getCCDBServer()
Definition NameConf.cxx:110
void finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj) final
void endOfStream(o2::framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void init(o2::framework::InitContext &ic) final
TOFChannelCalibDevice(std::shared_ptr< o2::base::GRPGeomRequest > req, bool useCCDB, bool attachChannelOffsetToLHCphase, bool isCosmics, bool perstrip=false, bool safe=false)
void run(o2::framework::ProcessingContext &pc) 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
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
constexpr o2::header::DataOrigin gDataOriginTOF
Definition DataHeader.h:575
constexpr TFType INFINITE_TF
Definition TimeSlot.h:30
constexpr double LHCOrbitMUS
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)
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"