Project
Loading...
Searching...
No Matches
TPCDigitizerSpec.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#ifdef NDEBUG
13#undef NDEBUG
14#endif
15#include <cassert>
17#include "TPCDigitizerSpec.h"
23#include "Framework/Lifetime.h"
26#include "Headers/DataHeader.h"
27#include "TStopwatch.h"
28#include "Steer/HitProcessingManager.h" // for DigitizationContext
29#include "TChain.h"
33#include "Framework/Task.h"
47#include <filesystem>
49
50using namespace o2::framework;
54
55namespace o2
56{
57namespace tpc
58{
59
60template <typename T>
61void copyHelper(T const& origin, T& target)
62{
63 std::copy(origin.begin(), origin.end(), std::back_inserter(target));
64}
65template <>
66void copyHelper<o2::dataformats::MCTruthContainer<o2::MCCompLabel>>(o2::dataformats::MCTruthContainer<o2::MCCompLabel> const& origin, o2::dataformats::MCTruthContainer<o2::MCCompLabel>& target)
67{
68 target.mergeAtBack(origin);
69}
70
71template <typename T>
72void writeToBranchHelper(TTree& tree, const char* name, T* accum)
73{
74 auto targetbr = o2::base::getOrMakeBranch(tree, name, accum);
75 targetbr->Fill();
76 targetbr->ResetAddress();
77 targetbr->DropBaskets("all");
78}
79template <>
80void writeToBranchHelper<o2::dataformats::MCTruthContainer<o2::MCCompLabel>>(TTree& tree,
82{
83 // we convert first of all to IOMCTruthContainer
84 std::vector<char> buffer;
85 accum->flatten_to(buffer);
86 accum->clear_andfreememory();
88 auto targetbr = o2::base::getOrMakeBranch(tree, name, &view);
89 targetbr->Fill();
90 targetbr->ResetAddress();
91 targetbr->DropBaskets("all");
92}
93
94std::string getBranchNameLeft(int sector)
95{
96 std::stringstream branchnamestreamleft;
97 branchnamestreamleft << "TPCHitsShiftedSector" << int(o2::tpc::Sector::getLeft(o2::tpc::Sector(sector)));
98 return branchnamestreamleft.str();
99}
100
101std::string getBranchNameRight(int sector)
102{
103 std::stringstream branchnamestreamright;
104 branchnamestreamright << "TPCHitsShiftedSector" << sector;
105 return branchnamestreamright.str();
106}
107
108using namespace o2::base;
110{
111 public:
112 TPCDPLDigitizerTask(bool internalwriter, int distortionType) : mInternalWriter(internalwriter), BaseDPLDigitizer(InitServices::FIELD | InitServices::GEOM), mDistortionType(distortionType)
113 {
114 }
115
117 {
118 LOG(info) << "Initializing TPC digitization";
119
120 mLaneId = ic.services().get<const o2::framework::DeviceSpec>().rank;
121
123 auto triggeredMode = ic.options().get<bool>("TPCtriggered");
124 mRecalcDistortions = !(ic.options().get<bool>("do-not-recalculate-distortions"));
125 const int nthreadsDist = ic.options().get<int>("n-threads-distortions");
126 SC::setNThreads(nthreadsDist);
127 mUseCalibrationsFromCCDB = ic.options().get<bool>("TPCuseCCDB");
128 mMeanLumiDistortions = ic.options().get<float>("meanLumiDistortions");
129 mMeanLumiDistortionsDerivative = ic.options().get<float>("meanLumiDistortionsDerivative");
130
131 LOG(info) << "TPC calibrations from CCDB: " << mUseCalibrationsFromCCDB;
132
133 mDigitizer.setContinuousReadout(!triggeredMode);
134 mDigitizer.setDistortionScaleType(mDistortionType);
135
136 // we send the GRP data once if the corresponding output channel is available
137 // and set the flag to false after
138 mWriteGRP = true;
139
140 // clean up (possibly) existing digit files
141 if (mInternalWriter) {
143 }
144 }
145
147 {
148 // since we update digit files during ordinary processing
149 // it is better to remove possibly existing files in the same dir
150 std::stringstream tmp;
151 tmp << "tpc_driftime_digits_lane" << mLaneId << ".root";
152 if (std::filesystem::exists(tmp.str())) {
153 std::filesystem::remove(tmp.str());
154 }
155 }
156
158 {
159 if (!mInternalROOTFlushFile) {
160 std::stringstream tmp;
161 tmp << "tpc_driftime_digits_lane" << mLaneId << ".root";
162 mInternalROOTFlushFile = new TFile(tmp.str().c_str(), "UPDATE");
163 std::stringstream trname;
164 trname << mSector;
165 mInternalROOTFlushTTree = new TTree(trname.str().c_str(), "o2sim");
166 }
167 {
168 std::stringstream brname;
169 brname << "TPCDigit_" << mSector;
170 auto br = o2::base::getOrMakeBranch(*mInternalROOTFlushTTree, brname.str().c_str(), &mDigits);
171 br->Fill();
172 br->ResetAddress();
173 }
174 if (mWithMCTruth) {
175 // labels
176 std::stringstream brname;
177 brname << "TPCDigitMCTruth_" << mSector;
178 auto br = o2::base::getOrMakeBranch(*mInternalROOTFlushTTree, brname.str().c_str(), &mLabels);
179 br->Fill();
180 br->ResetAddress();
181 }
182 {
183 // common
184 std::stringstream brname;
185 brname << "TPCCommonMode_" << mSector;
186 auto br = o2::base::getOrMakeBranch(*mInternalROOTFlushTTree, brname.str().c_str(), &mCommonMode);
187 br->Fill();
188 br->ResetAddress();
189 }
190 }
191
193 {
194 if (mTPCVDriftHelper.accountCCDBInputs(matcher, obj)) {
195 return;
196 }
197 if (matcher == ConcreteDataMatcher(o2::header::gDataOriginTPC, "TPCDIST", 0)) {
198 LOGP(info, "Updating distortion map");
199 mDigitizer.setUseSCDistortions(static_cast<SC*>(obj));
200 if (mMeanLumiDistortions >= 0) {
201 mDigitizer.setMeanLumiDistortions(mMeanLumiDistortions);
202 }
203 }
204 if (matcher == ConcreteDataMatcher(o2::header::gDataOriginTPC, "TPCDISTDERIV", 0)) {
205 LOGP(info, "Updating reference distortion map");
206 mDigitizer.setSCDistortionsDerivative(static_cast<SC*>(obj));
207 if (mMeanLumiDistortionsDerivative >= 0) {
208 mDigitizer.setMeanLumiDistortionsDerivative(mMeanLumiDistortionsDerivative);
209 }
210 }
211 if (matcher == ConcreteDataMatcher(o2::header::gDataOriginTPC, "TPCGASPARAM", 0)) {
212 LOGP(info, "TPC gas param updated");
213 ParameterGas::Instance().printKeyValues(true, true);
214 }
215 if (matcher == ConcreteDataMatcher(o2::header::gDataOriginTPC, "TPCGEMPARAM", 0)) {
216 LOGP(info, "TPC GEM param updated");
217 ParameterGEM::Instance().printKeyValues(true, true);
218 }
219 }
220
222 {
223 LOG(info) << "Processing TPC digitization";
224
227 cdb.setUseDefaults(!mUseCalibrationsFromCCDB);
228 // whatever are global settings for CCDB usage, we have to extract the TPC vdrift from CCDB for anchored simulations
229 mTPCVDriftHelper.extractCCDBInputs(pc);
230 pc.inputs().get<ParameterGas*>("gasparam");
231 pc.inputs().get<ParameterGEM*>("gemparam");
232 if (mDistortionType) {
233 pc.inputs().get<SC*>("tpcdistortions");
234 if (mDistortionType == 2) {
235 pc.inputs().get<SC*>("tpcdistortionsderiv");
236 mDigitizer.setLumiScaleFactor();
237 if (mRecalcDistortions) {
238 mDigitizer.recalculateDistortions();
239 }
240 }
241 }
242
243 if (mTPCVDriftHelper.isUpdated()) {
244 const auto& vd = mTPCVDriftHelper.getVDriftObject();
245 LOGP(info, "Updating TPC fast transform map with new VDrift factor of {} wrt reference {} and DriftTimeOffset correction {} wrt {} from source {}",
246 vd.corrFact, vd.refVDrift, vd.timeOffsetCorr, vd.refTimeOffset, mTPCVDriftHelper.getSourceName());
247 mDigitizer.setVDrift(vd.getVDrift());
248 mDigitizer.setTDriftOffset(vd.getTimeOffset());
249 mTPCVDriftHelper.acknowledgeUpdate();
250 }
251
252 if (std::filesystem::exists("ThresholdMap.root")) {
253 LOG(info) << "TPC: Using zero suppression map from 'ThresholdMap.root'";
254 cdb.setThresholdMapFromFile("ThresholdMap.root");
255 }
256
257 if (std::filesystem::exists("GainMap.root")) {
258 LOG(info) << "TPC: Using gain map from 'GainMap.root'";
259 cdb.setGainMapFromFile("GainMap.root");
260 }
261
262 for (auto it = pc.inputs().begin(), end = pc.inputs().end(); it != end; ++it) {
263 for (auto const& inputref : it.parts()) {
264 if (inputref.spec->lifetime == o2::framework::Lifetime::Condition) { // process does not need conditions
265 continue;
266 }
267 process(pc, inputref);
268 if (mInternalWriter) {
269 mInternalROOTFlushTTree->SetEntries(mFlushCounter);
270 mInternalROOTFlushFile->Write("", TObject::kOverwrite);
271 mInternalROOTFlushFile->Close();
272 // delete mInternalROOTFlushTTree; --> automatically done by ->Close()
273 delete mInternalROOTFlushFile;
274 mInternalROOTFlushFile = nullptr;
275 }
276 // TODO: make generic reset method?
277 mFlushCounter = 0;
278 mDigitCounter = 0;
279 }
280 }
281 }
282
283 // process one sector
285 {
286 // read collision context from input
287 auto context = pc.inputs().get<o2::steer::DigitizationContext*>(inputref);
288 context->initSimChains(o2::detectors::DetID::TPC, mSimChains);
289 auto& irecords = context->getEventRecords();
290 // A timeframe holds no collision at all whenever the interaction rate is low enough. Do not
291 // return here: the sector still has to produce its usual output, an empty one, so that the
292 // digit file has the same shape as an ordinary timeframe that happens to contain nothing.
293 // Returning also left the chunked writer without a file and a null tree to flush.
294 LOG(info) << "TPC: Processing " << irecords.size() << " collisions";
295 auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(inputref);
296
297 bool isContinuous = mDigitizer.isContinuousReadout();
298 // we publish the GRP data once if the output channel is there
299 if (mWriteGRP && pc.outputs().isAllowed({"TPC", "ROMode", 0})) {
301 LOG(info) << "TPC: Sending ROMode= " << (mDigitizer.isContinuousReadout() ? "Continuous" : "Triggered")
302 << " to GRPUpdater from channel " << dh->subSpecification;
303 pc.outputs().snapshot(Output{"TPC", "ROMode", 0}, roMode);
304 }
305 mWriteGRP = false;
306
307 // extract which sector to treat
308 auto const* sectorHeader = DataRefUtils::getHeader<TPCSectorHeader*>(inputref);
309 if (sectorHeader == nullptr) {
310 LOG(error) << "TPC: Sector header missing, skipping processing";
311 return;
312 }
313 auto sector = sectorHeader->sector();
314 mSector = sector;
315 mListOfSectors.push_back(sector);
316 LOG(info) << "TPC: Processing sector " << sector;
317 // the active sectors need to be propagated
318 uint64_t activeSectors = 0;
319 activeSectors = sectorHeader->activeSectors;
320
321 // lambda that creates a DPL owned buffer to accumulate the digits (in shared memory)
322 auto makeDigitBuffer = [this, sector, &pc, activeSectors, &dh]() {
323 o2::tpc::TPCSectorHeader header{sector};
324 header.activeSectors = activeSectors;
325 if (mInternalWriter) {
326 using ContainerType = std::decay_t<decltype(pc.outputs().make<std::vector<o2::tpc::Digit>>(Output{"", "", 0}))>*;
327 return ContainerType(nullptr);
328 } else {
329 // default case
330 return &pc.outputs().make<std::vector<o2::tpc::Digit>>(Output{"TPC", "DIGITS", static_cast<SubSpecificationType>(dh->subSpecification), header});
331 }
332 };
333 // lambda that snapshots the common mode vector to be sent out; prepares and attaches header with sector information
334 auto snapshotCommonMode = [this, sector, &pc, activeSectors, &dh](std::vector<o2::tpc::CommonMode> const& commonMode) {
335 o2::tpc::TPCSectorHeader header{sector};
336 header.activeSectors = activeSectors;
337 if (!mInternalWriter) {
338 // note that snapshoting only works with non-const references (to be fixed?)
339 pc.outputs().snapshot(Output{"TPC", "COMMONMODE", static_cast<SubSpecificationType>(dh->subSpecification), header},
340 const_cast<std::vector<o2::tpc::CommonMode>&>(commonMode));
341 }
342 };
343 // lambda that snapshots labels to be sent out; prepares and attaches header with sector information
344 auto snapshotLabels = [this, &sector, &pc, activeSectors, &dh](o2::dataformats::MCTruthContainer<o2::MCCompLabel> const& labels) {
345 o2::tpc::TPCSectorHeader header{sector};
346 header.activeSectors = activeSectors;
347 if (mWithMCTruth) {
348 if (!mInternalWriter) {
349 auto& sharedlabels = pc.outputs().make<o2::dataformats::ConstMCTruthContainer<o2::MCCompLabel>>(Output{"TPC", "DIGITSMCTR", static_cast<SubSpecificationType>(dh->subSpecification), header});
350 labels.flatten_to(sharedlabels);
351 }
352 }
353 };
354 // lambda that snapshots digits grouping (triggers) to be sent out; prepares and attaches header with sector information
355 auto snapshotEvents = [this, sector, &pc, activeSectors, &dh](const std::vector<DigiGroupRef>& events) {
356 o2::tpc::TPCSectorHeader header{sector};
357 header.activeSectors = activeSectors;
358 if (!mInternalWriter) {
359 LOG(info) << "TPC: Send TRIGGERS for sector " << sector << " channel " << dh->subSpecification << " | size " << events.size();
360 pc.outputs().snapshot(Output{"TPC", "DIGTRIGGERS", static_cast<SubSpecificationType>(dh->subSpecification), header},
361 const_cast<std::vector<DigiGroupRef>&>(events));
362 }
363 };
364
365 auto digitsAccum = makeDigitBuffer(); // accumulator for digits
366 o2::dataformats::MCTruthContainer<o2::MCCompLabel> labelAccum; // timeframe accumulator for labels
367 std::vector<CommonMode> commonModeAccum;
368 std::vector<DigiGroupRef> eventAccum;
369
370 // this should not happen any more, legacy condition when the sector variable was used
371 // to transport control information
372 if (sector < 0) {
373 throw std::runtime_error("Legacy control information is not expected any more");
374 }
375
376 // the TPCSectorHeader now allows to transport information for more than one sector,
377 // e.g. for transporting clusters in one single data block. The digitization is however
378 // only on sector level
379 if (sector >= TPCSectorHeader::NSectors) {
380 throw std::runtime_error("Digitizer can only work on single sectors");
381 }
382
383 mDigitizer.setSector(sector);
384 mDigitizer.init();
385
386 auto& eventParts = context->getEventParts();
387
388 auto flushDigitsAndLabels = [this, digitsAccum, &labelAccum, &commonModeAccum](bool finalFlush = false) {
389 mFlushCounter++;
390 // flush previous buffer
391 mDigits.clear();
392 mLabels.clear();
393 mCommonMode.clear();
394 mDigitizer.flush(mDigits, mLabels, mCommonMode, finalFlush);
395 LOG(info) << "TPC: Flushed " << mDigits.size() << " digits, " << mLabels.getNElements() << " labels and " << mCommonMode.size() << " common mode entries";
396
397 if (mInternalWriter) {
398 // the natural place to write out this independent datachunk immediately ...
400 } else {
401 // ... or to accumulate and later forward to next DPL proc
402 std::copy(mDigits.begin(), mDigits.end(), std::back_inserter(*digitsAccum));
403 if (mWithMCTruth) {
404 labelAccum.mergeAtBack(mLabels);
405 }
406 std::copy(mCommonMode.begin(), mCommonMode.end(), std::back_inserter(commonModeAccum));
407 }
408 mDigitCounter += mDigits.size();
409 };
410
411 if (isContinuous) {
412 auto& hbfu = o2::raw::HBFUtils::Instance();
413 double time = hbfu.getFirstIRofTF(o2::InteractionRecord(0, hbfu.orbitFirstSampled)).bc2ns() / 1000.;
414 mDigitizer.setOutputDigitTimeOffset(time);
415 if (!irecords.empty()) {
416 mDigitizer.setStartTime(irecords[0].getTimeNS() / 1000.f);
417 }
418 }
419
420 TStopwatch timer;
421 timer.Start();
422
423 // loop over all composite collisions given from context
424 // (aka loop over all the interaction records)
425 for (int collID = 0; collID < irecords.size(); ++collID) {
426 const double eventTime = irecords[collID].getTimeNS() / 1000.f;
427 LOG(info) << "TPC: Event time " << eventTime << " us";
428 mDigitizer.setEventTime(eventTime);
429 if (!isContinuous) {
430 mDigitizer.setStartTime(eventTime);
431 }
432 size_t startSize = mDigitCounter; // digitsAccum->size();
433
434 // for each collision, loop over the constituents event and source IDs
435 // (background signal merging is basically taking place here)
436 for (auto& part : eventParts[collID]) {
437 const int eventID = part.entryID;
438 const int sourceID = part.sourceID;
439
440 // get the hits for this event and this source
441 std::vector<o2::tpc::HitGroup> hitsLeft;
442 std::vector<o2::tpc::HitGroup> hitsRight;
443 context->retrieveHits(mSimChains, getBranchNameLeft(sector).c_str(), part.sourceID, part.entryID, &hitsLeft);
444 context->retrieveHits(mSimChains, getBranchNameRight(sector).c_str(), part.sourceID, part.entryID, &hitsRight);
445 LOG(debug) << "TPC: Found " << hitsLeft.size() << " hit groups left and " << hitsRight.size() << " hit groups right in collision " << collID << " eventID " << part.entryID;
446
447 mDigitizer.process(hitsLeft, eventID, sourceID);
448 mDigitizer.process(hitsRight, eventID, sourceID);
449
450 flushDigitsAndLabels();
451
452 if (!isContinuous) {
453 eventAccum.emplace_back(startSize, mDigits.size());
454 }
455 }
456 }
457
458 // final flushing step; getting everything not yet written out
459 if (isContinuous) {
460 LOG(info) << "TPC: Final flush";
461 flushDigitsAndLabels(true);
462 eventAccum.emplace_back(0, mDigitCounter); // all digits are grouped to 1 super-event pseudo-triggered mode
463 }
464
465 if (!mInternalWriter) {
466 // send out to next stage
467 snapshotEvents(eventAccum);
468 // snapshotDigits(digitsAccum); --> done automatically
469 snapshotCommonMode(commonModeAccum);
470 snapshotLabels(labelAccum);
471 }
472
473 timer.Stop();
474 LOG(info) << "TPC: Digitization took " << timer.CpuTime() << "s";
475 }
476
477 private:
478 o2::tpc::Digitizer mDigitizer;
479 o2::tpc::VDriftHelper mTPCVDriftHelper{};
480 std::vector<TChain*> mSimChains;
481 std::vector<o2::tpc::Digit> mDigits;
483 std::vector<o2::tpc::CommonMode> mCommonMode;
484 std::vector<int> mListOfSectors; // a list of sectors treated by this task
485 TFile* mInternalROOTFlushFile = nullptr;
486 TTree* mInternalROOTFlushTTree = nullptr;
487 size_t mDigitCounter = 0;
488 size_t mFlushCounter = 0;
489 int mLaneId = 0; // the id of the current process within the parallel pipeline
490 int mSector = 0;
491 bool mWriteGRP = false;
492 bool mWithMCTruth = true;
493 bool mInternalWriter = false;
494 bool mUseCalibrationsFromCCDB = false;
495 int mDistortionType = 0;
496 float mMeanLumiDistortions = -1;
497 float mMeanLumiDistortionsDerivative = -1;
498 bool mRecalcDistortions = false;
499};
500
501o2::framework::DataProcessorSpec getTPCDigitizerSpec(int channel, bool writeGRP, bool mctruth, bool internalwriter, int distortionType)
502{
503 // create the full data processor spec using
504 // a name identifier
505 // input description
506 // algorithmic description (here a lambda getting called once to setup the actual processing function)
507 // options that can be used for this processor (here: input file names where to take the hits)
508 std::stringstream id;
509 id << "TPCDigitizer" << channel;
510
511 std::vector<OutputSpec> outputs; // define channel by triple of (origin, type id of data to be sent on this channel, subspecification)
512
513 if (!internalwriter) {
514 outputs.emplace_back("TPC", "DIGITS", static_cast<SubSpecificationType>(channel), Lifetime::Timeframe);
515 outputs.emplace_back("TPC", "DIGTRIGGERS", static_cast<SubSpecificationType>(channel), Lifetime::Timeframe);
516 if (mctruth) {
517 outputs.emplace_back("TPC", "DIGITSMCTR", static_cast<SubSpecificationType>(channel), Lifetime::Timeframe);
518 }
519 outputs.emplace_back("TPC", "COMMONMODE", static_cast<SubSpecificationType>(channel), Lifetime::Timeframe);
520 }
521 if (writeGRP) {
522 outputs.emplace_back("TPC", "ROMode", 0, Lifetime::Timeframe);
523 LOG(debug) << "TPC: Channel " << channel << " will supply ROMode";
524 }
525
526 std::vector<InputSpec> inputs{InputSpec{"collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast<SubSpecificationType>(channel), Lifetime::Timeframe}};
527 return DataProcessorSpec{
528 id.str().c_str(),
529 inputs,
530 outputs,
531 AlgorithmSpec{adaptFromTask<TPCDPLDigitizerTask>(internalwriter, distortionType)},
532 Options{
533 {"TPCtriggered", VariantType::Bool, false, {"Impose triggered RO mode (default: continuous)"}},
534 {"TPCuseCCDB", VariantType::Bool, false, {"true: load calibrations from CCDB; false: use random calibratoins"}},
535 {"meanLumiDistortions", VariantType::Float, -1.f, {"override lumi of distortion object if >=0"}},
536 {"meanLumiDistortionsDerivative", VariantType::Float, -1.f, {"override lumi of derivative distortion object if >=0"}},
537 {"do-not-recalculate-distortions", VariantType::Bool, false, {"Do not recalculate the distortions"}},
538 {"n-threads-distortions", VariantType::Int, 4, {"Number of threads used for the calculation of the distortions"}},
539 }};
540}
541
542o2::framework::WorkflowSpec getTPCDigitizerSpec(int nLanes, std::vector<int> const& sectors, bool mctruth, bool internalwriter, int distortionType)
543{
544 // channel parameter is deprecated in the TPCDigitizer processor, all descendants
545 // are initialized not to publish GRP mode, but the channel will be added to the first
546 // processor after the pipelines have been created. The processor will decide upon
547 // the index in the ParallelContext whether to publish
548 WorkflowSpec pipelineTemplate{getTPCDigitizerSpec(0, false, mctruth, internalwriter, distortionType)};
549 // override the predefined name, index will be added by parallelPipeline method
550 pipelineTemplate[0].name = "TPCDigitizer";
552 pipelineTemplate, nLanes, [size = sectors.size()]() { return size; }, [&sectors](size_t index) { return sectors[index]; });
553 // add the channel for the GRP information to the first processor
554 for (auto& spec : pipelines) {
555 o2::tpc::VDriftHelper::requestCCDBInputs(spec.inputs); // add the same CCDB request to each pipeline
556 spec.inputs.emplace_back("gasparam", o2::header::gDataOriginTPC, "TPCGASPARAM", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::ParGas)));
557 spec.inputs.emplace_back("gemparam", o2::header::gDataOriginTPC, "TPCGEMPARAM", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::ParGEM)));
558 if (distortionType) {
559 spec.inputs.emplace_back("tpcdistortions", o2::header::gDataOriginTPC, "TPCDIST", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::DistortionMapMC), {}, 1)); // time-dependent
560 // load derivative map in case scaling was requested
561 if (distortionType == 2) {
562 spec.inputs.emplace_back("tpcdistortionsderiv", o2::header::gDataOriginTPC, "TPCDISTDERIV", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::DistortionMapDerivMC), {}, 1)); // time-dependent
563 }
564 }
565 }
566 pipelines[0].outputs.emplace_back("TPC", "ROMode", 0, Lifetime::Timeframe);
567 return pipelines;
568}
569
570} // end namespace tpc
571} // end namespace o2
header::DataOrigin origin
std::vector< std::string > labels
Definition of the base digitizer task class.
Definition of the Detector class.
Simple interface to the CDB manager.
A const (ready only) version of MCTruthContainer.
Definition of the TPC Digit.
o2::framework::DataAllocator::SubSpecificationType SubSpecificationType
std::ostringstream debug
int16_t time
Definition RawEventData.h:4
Header of the General Run Parameters object.
A special IO container - splitting a given vector to enable ROOT IO.
Definition of the parameter class for the GEM stack.
Class to refer to the 1st entry and N elements of some group in the continuous container.
This class contains the algorithms for calculation the distortions and corrections.
Definition of the ALICE TPC digitizer.
Helper class to extract VDrift from different sources.
A read-only version of MCTruthContainer allowing for storage optimisation.
A container to hold and manage MC truth information/labels.
void mergeAtBack(MCTruthContainer< TruthElement > const &other)
static constexpr ID TPC
Definition DetID.h:64
void snapshot(const Output &spec, T const &object)
o2::header::DataHeader::SubSpecificationType SubSpecificationType
decltype(auto) make(const Output &spec, Args... args)
bool isAllowed(Output const &query)
check if a certain output is allowed
ServiceRegistryRef services()
Definition InitContext.h:34
ConfigParamRegistry const & options()
Definition InitContext.h:33
const_iterator begin() const
decltype(auto) get(R binding, int part=0) const
const_iterator end() const
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
bool initSimChains(o2::detectors::DetID detid, std::vector< TChain * > &simchains) const
static CDBInterface & instance()
void setMeanLumiDistortions(float meanLumi)
void setUseSCDistortions(const SCDistortionType &distortionType, const TH3 *hisInitialSCDensity)
void setMeanLumiDistortionsDerivative(float meanLumi)
void setDistortionScaleType(int distortionScaleType)
Definition Digitizer.h:135
void flush(std::vector< o2::tpc::Digit > &digits, o2::dataformats::MCTruthContainer< o2::MCCompLabel > &labels, std::vector< o2::tpc::CommonMode > &commonModeOutput, bool finalFlush=false)
void setSector(Sector sec)
Definition Digitizer.h:88
void setOutputDigitTimeOffset(double offset)
Set mOutputDigitTimeOffset.
Definition Digitizer.h:99
void setVDrift(float v)
Definition Digitizer.h:132
void setSCDistortionsDerivative(SC *spaceCharge)
void setStartTime(double time)
void recalculateDistortions()
in case of scaled distortions, the distortions can be recalculated to ensure consistent distortions a...
void setContinuousReadout(bool isContinuous)
Definition Digitizer.h:107
void process(const std::vector< o2::tpc::HitGroup > &hits, const int eventID, const int sourceID=0)
Definition Digitizer.cxx:52
void setEventTime(double time)
Definition Digitizer.h:103
void init()
Initializer.
Definition Digitizer.cxx:42
void setTDriftOffset(float t)
Definition Digitizer.h:133
bool isContinuousReadout()
Definition Digitizer.h:111
static Sector getLeft(const Sector s)
Definition Sector.h:145
static void setNThreads(const int nThreads)
set the number of threads used for some of the calculations
void initDigitizerTask(framework::InitContext &ic) override
void run(framework::ProcessingContext &pc)
void process(framework::ProcessingContext &pc, framework::DataRef const &inputref)
TPCDPLDigitizerTask(bool internalwriter, int distortionType)
void finaliseCCDB(framework::ConcreteDataMatcher &matcher, void *obj)
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)
static std::string_view getSourceName(Source s)
bool isUpdated() const
const GLuint * pipelines
Definition glcorearb.h:1909
GLuint buffer
Definition glcorearb.h:655
GLsizeiptr size
Definition glcorearb.h:659
GLuint GLuint end
Definition glcorearb.h:469
GLuint index
Definition glcorearb.h:781
GLuint const GLchar * name
Definition glcorearb.h:781
GLenum target
Definition glcorearb.h:1641
GLuint id
Definition glcorearb.h:650
constexpr o2::header::DataOrigin gDataOriginTPC
Definition DataHeader.h:576
TBranch * getOrMakeBranch(TTree &tree, const char *brname, T *ptr)
Definition Detector.h:300
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
WorkflowSpec parallelPipeline(const WorkflowSpec &specs, size_t nPipelines, std::function< size_t()> getNumberOfSubspecs, std::function< size_t(size_t)> getSubSpec)
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
std::vector< DataProcessorSpec > WorkflowSpec
std::vector< ConfigParamSpec > Options
header::DataHeader::SubSpecificationType SubSpecificationType
std::string getBranchNameLeft(int sector)
const std::unordered_map< CDBType, const std::string > CDBTypeMap
Storage name in CCDB for each calibration and parameter type.
Definition CDBTypes.h:98
void writeToBranchHelper(TTree &tree, const char *name, T *accum)
o2::framework::DataProcessorSpec getTPCDigitizerSpec(int channel, bool writeGRP, bool mctruth, bool internalwriter, int distortionType)
void copyHelper(T const &origin, R &target)
@ ParGas
Parameter for Gas.
@ DistortionMapDerivMC
derivative distortions for MC used in the digitizer for scaling
@ DistortionMapMC
full distortions (static + IR dependant) for MC used in the digitizer
std::string getBranchNameRight(int sector)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
class listing possible services
static constexpr int NSectors
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))