Project
Loading...
Searching...
No Matches
TOFDigitizerSpec.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
12#include "TOFDigitizerSpec.h"
17#include "Framework/Lifetime.h"
18#include "Framework/Task.h"
19#include "TStopwatch.h"
20#include "Steer/HitProcessingManager.h" // for DigitizationContext
21#include "TChain.h"
29#include "TOFBase/CalibTOFapi.h"
33#include "TOFBase/Geo.h"
37
38using namespace o2::framework;
39using namespace o2::dataformats;
40
42
43namespace o2
44{
45namespace tof
46{
47
49{
50 public:
51 TOFDPLDigitizerTask(bool useCCDB, std::string ccdb_url, int timestamp, uint32_t mask) : mUseCCDB{useCCDB}, mCCDBurl(ccdb_url), mTimestamp(timestamp), o2::base::BaseDPLDigitizer(o2::base::InitServices::FIELD | o2::base::InitServices::GEOM), mPass(o2::conf::DigiParams::Instance().passName), mMaskDRM(mask){};
52
54 {
55 LOG(info) << "Initializing TOF digitization";
56
57 mSimChains = std::move(std::make_unique<std::vector<TChain*>>());
58
59 // the instance of the actual digitizer
60 mDigitizer = std::move(std::make_unique<o2::tof::Digitizer>());
61 // containers for digits and labels
62 mDigits = std::move(std::make_unique<std::vector<o2::tof::Digit>>());
63 mLabels = std::move(std::make_unique<o2::dataformats::MCTruthContainer<o2::MCCompLabel>>());
64
65 // init digitizer
66 mDigitizer->init();
67 const bool isContinuous = ic.options().get<int>("pileup");
68 LOG(info) << "CONTINUOUS " << isContinuous;
69 mDigitizer->setContinuous(isContinuous);
70 mDigitizer->setMCTruthContainer(mLabels.get());
71 LOG(info) << "TOF initialization done";
72 }
73
75 {
76 if (matcher == ConcreteDataMatcher("TOF", "DiagnosticCal", 0)) {
77 mUpdateCCDB = true;
78 return;
79 }
80 if (matcher == ConcreteDataMatcher("TOF", "DiagnosticDRM", 0)) {
81 mUpdateCCDB = true;
82 return;
83 }
84 if (matcher == ConcreteDataMatcher("TOF", "LHCphaseCal", 0)) {
85 mUpdateCCDB = true;
86 return;
87 }
88 if (matcher == ConcreteDataMatcher("TOF", "ChannelCalibCal", 0)) {
89 mUpdateCCDB = true;
90 return;
91 }
92 if (matcher == ConcreteDataMatcher("TOF", "StatusTOF", 0)) {
93 mUpdateCCDB = true;
94 return;
95 }
96 if (matcher == ConcreteDataMatcher("TOF", "parameters", 0)) {
97 mUpdateCCDB = true;
98 return;
99 }
100 }
101
103 {
104 static bool finished = false;
105 if (finished) {
106 return;
107 }
108 // RS: at the moment using hardcoded flag for continuos readout
110
111 // read collision context from input
112 auto context = pc.inputs().get<o2::steer::DigitizationContext*>("collisioncontext");
113 auto& timesview = context->getEventRecords();
114 LOG(debug) << "GOT " << timesview.size() << " COLLISSION TIMES";
115
116 context->initSimChains(o2::detectors::DetID::TOF, *mSimChains.get());
117
118 // if there is nothing to do ... return
119 if (timesview.size() == 0) {
120 return;
121 }
122
123 TStopwatch timer;
124 timer.Start();
125
126 LOG(info) << " CALLING TOF DIGITIZATION ";
129
130 if (mUseCCDB) {
131 const auto lhcPhaseIn = pc.inputs().get<o2::dataformats::CalibLHCphaseTOF*>("tofccdbLHCphase");
132 const auto channelCalibIn = pc.inputs().get<o2::dataformats::CalibTimeSlewingParamTOF*>("tofccdbChannelCalib");
133 const auto diagnosticIn = pc.inputs().get<o2::tof::Diagnostic*>("tofccdbDia");
134 const auto diagnosticDRM = pc.inputs().get<o2::tof::Diagnostic*>("tofccdbDrm");
135 const auto statusIn = pc.inputs().get<o2::tof::TOFFEElightInfo*>("tofccdbStatus");
136 const auto tofParams = pc.inputs().get<o2::tof::ParameterCollection*>("tofccdbParams");
137
138 if (tofParams->getSize(mPass) < 0) { // this is supposed to be temporary till all the pieces are in place
139 LOG(info) << "Pass " << mPass << " requested but not found in the tofParams object -> using unanchored";
140 mPass = "unanchored";
141 }
142
143 if (tofParams->getSize(mPass) < 0) {
144 LOG(fatal) << "Pass " << mPass << " not found in the tofParams object (stop here!)";
145 } else {
146 const auto& params = tofParams->getPars(mPass);
147 if (params.count("time_resolution")) {
148 mDigitizer->setResolution(params.at("time_resolution"));
149 LOG(info) << "time_resolution load from ccdb -> " << params.at("time_resolution");
150 }
151 if (params.count("eff_center")) {
152 mDigitizer->setEffCenter(params.at("eff_center"));
153 LOG(info) << "eff_center load from ccdb -> " << params.at("eff_center");
154 }
155 if (params.count("eff_boundary1")) {
156 mDigitizer->setEffBoundary1(params.at("eff_boundary1"));
157 LOG(info) << "eff_boundary1 load from ccdb -> " << params.at("eff_boundary1");
158 }
159 if (params.count("eff_boundary2")) {
160 mDigitizer->setEffBoundary2(params.at("eff_boundary2"));
161 LOG(info) << "eff_boundary2 load from ccdb -> " << params.at("eff_boundary2");
162 }
163 if (params.count("eff_boundary3")) {
164 mDigitizer->setEffBoundary3(params.at("eff_boundary3"));
165 LOG(info) << "eff_boundary3 load from ccdb -> " << params.at("eff_boundary3");
166 }
167 }
168
169 if (!mCalibApi) {
170 o2::dataformats::CalibLHCphaseTOF* lhcPhase = new o2::dataformats::CalibLHCphaseTOF(std::move(*lhcPhaseIn));
171 o2::dataformats::CalibTimeSlewingParamTOF* channelCalib = new o2::dataformats::CalibTimeSlewingParamTOF(std::move(*channelCalibIn));
172 o2::tof::Diagnostic* diagnostic = new o2::tof::Diagnostic(std::move(*diagnosticIn));
173 o2::tof::Diagnostic* diagnosticDRMerr = new o2::tof::Diagnostic(std::move(*diagnosticDRM));
174 o2::tof::TOFFEElightInfo* status = new o2::tof::TOFFEElightInfo(std::move(*statusIn));
175
176 mCalibApi = new o2::tof::CalibTOFapi(long(0), lhcPhase, channelCalib, diagnostic, diagnosticDRMerr);
177 mCalibApi->setDRMCriticalErrorMask(mMaskDRM);
178 mCalibApi->loadDiagnosticFrequencies();
179 mCalibApi->loadDiagnosticDRMFrequencies();
180 mCalibApi->loadActiveMap(status);
181
182 mUpdateCCDB = false;
183 } else { // update if necessary
184 if (mUpdateCCDB) {
185 LOG(info) << "Update CCDB objects since new";
186 delete mCalibApi;
189 o2::tof::Diagnostic* diagnostic = new o2::tof::Diagnostic(std::move(*diagnosticIn));
190 o2::tof::Diagnostic* diagnosticDRMerr = new o2::tof::Diagnostic(std::move(*diagnosticDRM));
191 o2::tof::TOFFEElightInfo* status = new o2::tof::TOFFEElightInfo(std::move(*statusIn));
192 mCalibApi = new o2::tof::CalibTOFapi(long(0), lhcPhase, channelCalib, diagnostic);
193 mCalibApi->setDRMCriticalErrorMask(mMaskDRM);
194 mCalibApi->loadDiagnosticFrequencies();
195 mCalibApi->loadDiagnosticDRMFrequencies();
196 mCalibApi->loadActiveMap(status);
197
198 mUpdateCCDB = false;
199 } else {
200 // do nothing
201 }
202 }
203 } else if (!mCalibApi) { // calibration objects set to zero
204 auto* lhcPhaseDummy = new o2::dataformats::CalibLHCphaseTOF();
205 auto* channelCalibDummy = new o2::dataformats::CalibTimeSlewingParamTOF();
206
207 lhcPhaseDummy->addLHCphase(0, 0);
208 lhcPhaseDummy->addLHCphase(2000000000, 0);
209
210 for (int ich = 0; ich < o2::dataformats::CalibTimeSlewingParamTOF::NCHANNELS; ich++) {
211 channelCalibDummy->addTimeSlewingInfo(ich, 0, 0);
214 channelCalibDummy->setFractionUnderPeak(sector, channelInSector, 1);
215 }
216 mCalibApi = new o2::tof::CalibTOFapi(long(mTimestamp), lhcPhaseDummy, channelCalibDummy);
217 mCalibApi->setDRMCriticalErrorMask(mMaskDRM);
218
219 if (mUseCCDB) {
220 mCalibApi->setURL(mCCDBurl);
221 mCalibApi->readDiagnosticFrequencies();
222 mCalibApi->readDiagnosticDRMFrequencies();
223 mCalibApi->readLHCphase();
224 mCalibApi->readActiveMap();
225 mCalibApi->readTimeSlewingParam();
226 }
227 }
228
229 mDigitizer->setCalibApi(mCalibApi);
230
231 mCalibApi->setTimeStamp(o2::raw::HBFUtils::Instance().startTime / 1000);
232
233 static std::vector<o2::tof::HitType> hits;
234
235 auto& eventParts = context->getEventParts();
236 // loop over all composite collisions given from context
237 // (aka loop over all the interaction records)
238 // o2::InteractionTimeRecord firstorbit(o2::InteractionRecord(0, o2::raw::HBFUtils::Instance().orbitFirstSampled), 0.0);
239 for (int collID = 0; collID < timesview.size(); ++collID) {
240 o2::InteractionTimeRecord orbit(timesview[collID]);
241 // orbit += firstorbit;
242 mDigitizer->setEventTime(orbit);
243
244 // for each collision, loop over the constituents event and source IDs
245 // (background signal merging is basically taking place here)
246 for (auto& part : eventParts[collID]) {
247 mDigitizer->setEventID(part.entryID);
248 mDigitizer->setSrcID(part.sourceID);
249
250 // get the hits for this event and this source
251 hits.clear();
252 context->retrieveHits(*mSimChains.get(), "TOFHit", part.sourceID, part.entryID, &hits);
253
254 // LOG(info) << "For collision " << collID << " eventID " << part.entryID << " found " << hits.size() << " hits ";
255
256 // call actual digitization procedure
257 mLabels->clear();
258 mDigits->clear();
259 mDigitizer->process(&hits, mDigits.get());
260 }
261 }
262 if (mDigitizer->isContinuous()) {
263 LOG(info) << "clear all";
264 mDigits->clear();
265 mLabels->clear();
266 LOG(info) << "finalize";
267 mDigitizer->flushOutputContainer(*mDigits.get());
268 }
269
270 std::vector<Digit>* digitsVector = mDigitizer->getDigitPerTimeFrame();
271 std::vector<ReadoutWindowData>* readoutwindow = mDigitizer->getReadoutWindowData();
272 std::vector<o2::dataformats::MCTruthContainer<o2::MCCompLabel>>* mcLabVecOfVec = mDigitizer->getMCTruthPerTimeFrame();
273
274 LOG(info) << "Post " << digitsVector->size() << " digits in " << readoutwindow->size() << " RO windows";
275
276 // here we have all digits and we can send them to consumer (aka snapshot it onto output)
277 pc.outputs().snapshot(Output{o2::header::gDataOriginTOF, "DIGITS", 0}, *digitsVector);
278 if (pc.outputs().isAllowed({o2::header::gDataOriginTOF, "DIGITSMCTR", 0})) {
279 pc.outputs().snapshot(Output{o2::header::gDataOriginTOF, "DIGITSMCTR", 0}, *mcLabVecOfVec);
280 }
281 pc.outputs().snapshot(Output{o2::header::gDataOriginTOF, "READOUTWINDOW", 0}, *readoutwindow);
282
283 // send empty pattern from digitizer (it may change in future)
284 std::vector<uint8_t>& patterns = mDigitizer->getPatterns();
285 pc.outputs().snapshot(Output{o2::header::gDataOriginTOF, "PATTERNS", 0}, patterns);
286
287 DigitHeader& digitH = mDigitizer->getDigitHeader();
288 pc.outputs().snapshot(Output{o2::header::gDataOriginTOF, "DIGITHEADER", 0}, digitH);
289
290 LOG(info) << "TOF: Sending ROMode= " << roMode << " to GRPUpdater";
291 pc.outputs().snapshot(Output{o2::header::gDataOriginTOF, "ROMode", 0}, roMode);
292
293 timer.Stop();
294 LOG(info) << "Digitization took " << timer.CpuTime() << "s";
295
296 // we should be only called once; tell DPL that this process is ready to exit
298
299 finished = true;
300 }
301
303 {
304 LOGF(debug, "TOF Digitizer endOfStream");
305 }
306
307 private:
308 std::unique_ptr<std::vector<TChain*>> mSimChains;
309 std::unique_ptr<o2::tof::Digitizer> mDigitizer;
310 std::unique_ptr<std::vector<o2::tof::Digit>> mDigits;
311 std::unique_ptr<o2::dataformats::MCTruthContainer<o2::MCCompLabel>> mLabels;
312 bool mUseCCDB = false;
313 std::string mCCDBurl;
314 int mTimestamp = 0;
315 bool mUpdateCCDB = false;
316 o2::tof::CalibTOFapi* mCalibApi = nullptr;
317 std::string mPass;
318 uint32_t mMaskDRM = 0;
319};
320
321DataProcessorSpec getTOFDigitizerSpec(int channel, bool useCCDB, bool mctruth, std::string ccdb_url, int timestamp, uint32_t maskDRM)
322{
323 // create the full data processor spec using
324 // a name identifier
325 // input description
326 // algorithmic description (here a lambda getting called once to setup the actual processing function)
327 // options that can be used for this processor (here: input file names where to take the hits)
328 std::vector<InputSpec> inputs;
329 inputs.emplace_back("collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast<SubSpecificationType>(channel), Lifetime::Timeframe);
330 // if (useCCDB) {
331 // inputs.emplace_back("tofccdbLHCphase", o2::header::gDataOriginTOF, "LHCphase");
332 // inputs.emplace_back("tofccdbChannelCalib", o2::header::gDataOriginTOF, "ChannelCalib");
333 // }
334
335 if (useCCDB) {
336 inputs.emplace_back("tofccdbStatus", "TOF", "StatusTOF", 0, Lifetime::Condition, ccdbParamSpec("TOF/Calib/FEELIGHT"));
337 inputs.emplace_back("tofccdbDia", "TOF", "DiagnosticCal", 0, Lifetime::Condition, ccdbParamSpec("TOF/Calib/Diagnostic"));
338 inputs.emplace_back("tofccdbDrm", "TOF", "DiagnosticDRM", 0, Lifetime::Condition, ccdbParamSpec("TOF/Calib/DRMerrors"));
339 inputs.emplace_back("tofccdbLHCphase", "TOF", "LHCphaseCal", 0, Lifetime::Condition, ccdbParamSpec("TOF/Calib/LHCphase"));
340 inputs.emplace_back("tofccdbChannelCalib", "TOF", "ChannelCalibCal", 0, Lifetime::Condition, ccdbParamSpec("TOF/Calib/ChannelCalib"));
341 inputs.emplace_back("tofccdbParams", "TOF", "parameters", 0, Lifetime::Condition, ccdbParamSpec("TOF/Calib/Params"));
342 }
343
344 std::vector<OutputSpec> outputs;
345 outputs.emplace_back(o2::header::gDataOriginTOF, "DIGITHEADER", 0, Lifetime::Timeframe);
346 outputs.emplace_back(o2::header::gDataOriginTOF, "DIGITS", 0, Lifetime::Timeframe);
347 outputs.emplace_back(o2::header::gDataOriginTOF, "READOUTWINDOW", 0, Lifetime::Timeframe);
348 outputs.emplace_back(o2::header::gDataOriginTOF, "PATTERNS", 0, Lifetime::Timeframe);
349 if (mctruth) {
350 outputs.emplace_back(o2::header::gDataOriginTOF, "DIGITSMCTR", 0, Lifetime::Timeframe);
351 }
352 outputs.emplace_back(o2::header::gDataOriginTOF, "ROMode", 0, Lifetime::Timeframe);
353 return DataProcessorSpec{
354 "TOFDigitizer",
355 inputs,
356 outputs,
357 AlgorithmSpec{adaptFromTask<TOFDPLDigitizerTask>(useCCDB, ccdb_url, timestamp, maskDRM)},
358 Options{{"pileup", VariantType::Int, 1, {"whether to run in continuous time mode"}}}
359 // I can't use VariantType::Bool as it seems to have a problem
360 };
361}
362} // end namespace tof
363} // end namespace o2
Definition of the base digitizer task class.
Class to store the output of the matching to TOF for calibration.
Class to use TOF calibration (decalibration, calibration)
Class to store the output of the matching to TOF for calibration.
Definition of the GeometryManager class.
o2::framework::DataAllocator::SubSpecificationType SubSpecificationType
std::ostringstream debug
uint64_t orbit
Definition RawEventData.h:6
Header of the General Run Parameters object.
Definition of a container to keep Monte Carlo truth external to simulation objects.
Definitions of the containers for the general parameters.
A container to hold and manage MC truth information/labels.
static constexpr ID TOF
Definition DetID.h:66
void snapshot(const Output &spec, T const &object)
o2::header::DataHeader::SubSpecificationType SubSpecificationType
bool isAllowed(Output const &query)
check if a certain output is allowed
ConfigParamRegistry const & options()
Definition InitContext.h:33
decltype(auto) get(R binding, int part=0) const
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
bool initSimChains(o2::detectors::DetID detid, std::vector< TChain * > &simchains) const
std::vector< o2::InteractionTimeRecord > & getEventRecords(bool withQED=false)
void readDiagnosticDRMFrequencies()
void loadDiagnosticDRMFrequencies()
void setTimeStamp(long t)
Definition CalibTOFapi.h:66
void loadActiveMap(TOFFEElightInfo *fee)
void setURL(const std::string url)
Definition CalibTOFapi.h:70
void setDRMCriticalErrorMask(uint32_t val)
Diagnostic class for TOF.
Definition Diagnostic.h:32
Class container to hold different parameters meant to be stored on the CCDB.
void initDigitizerTask(framework::InitContext &ic) override
void endOfStream(EndOfStreamContext &ec)
void finaliseCCDB(o2::framework::ConcreteDataMatcher matcher, void *obj)
TOFDPLDigitizerTask(bool useCCDB, std::string ccdb_url, int timestamp, uint32_t mask)
void run(framework::ProcessingContext &pc)
GLenum const GLfloat * params
Definition glcorearb.h:272
GLint GLuint mask
Definition glcorearb.h:291
constexpr o2::header::DataOrigin gDataOriginTOF
Definition DataHeader.h:575
Definition of a container to keep/associate and arbitrary number of labels associated to an index wit...
Defining PrimaryVertex explicitly as messageable.
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
std::vector< ConfigParamSpec > Options
header::DataHeader::SubSpecificationType SubSpecificationType
DataProcessorSpec getTOFDigitizerSpec(int channel, bool useCCDB, bool mctruth, std::string ccdb_url, int timestamp, uint32_t maskDRM)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"