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) {
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 LOG(info) << "TPC: Processing " << irecords.size() << " collisions";
291 if (irecords.size() == 0) {
292 return;
293 }
294 auto const* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(inputref);
295
296 bool isContinuous = mDigitizer.isContinuousReadout();
297 // we publish the GRP data once if the output channel is there
298 if (mWriteGRP && pc.outputs().isAllowed({"TPC", "ROMode", 0})) {
300 LOG(info) << "TPC: Sending ROMode= " << (mDigitizer.isContinuousReadout() ? "Continuous" : "Triggered")
301 << " to GRPUpdater from channel " << dh->subSpecification;
302 pc.outputs().snapshot(Output{"TPC", "ROMode", 0}, roMode);
303 }
304 mWriteGRP = false;
305
306 // extract which sector to treat
307 auto const* sectorHeader = DataRefUtils::getHeader<TPCSectorHeader*>(inputref);
308 if (sectorHeader == nullptr) {
309 LOG(error) << "TPC: Sector header missing, skipping processing";
310 return;
311 }
312 auto sector = sectorHeader->sector();
313 mSector = sector;
314 mListOfSectors.push_back(sector);
315 LOG(info) << "TPC: Processing sector " << sector;
316 // the active sectors need to be propagated
317 uint64_t activeSectors = 0;
318 activeSectors = sectorHeader->activeSectors;
319
320 // lambda that creates a DPL owned buffer to accumulate the digits (in shared memory)
321 auto makeDigitBuffer = [this, sector, &pc, activeSectors, &dh]() {
322 o2::tpc::TPCSectorHeader header{sector};
323 header.activeSectors = activeSectors;
324 if (mInternalWriter) {
325 using ContainerType = std::decay_t<decltype(pc.outputs().make<std::vector<o2::tpc::Digit>>(Output{"", "", 0}))>*;
326 return ContainerType(nullptr);
327 } else {
328 // default case
329 return &pc.outputs().make<std::vector<o2::tpc::Digit>>(Output{"TPC", "DIGITS", static_cast<SubSpecificationType>(dh->subSpecification), header});
330 }
331 };
332 // lambda that snapshots the common mode vector to be sent out; prepares and attaches header with sector information
333 auto snapshotCommonMode = [this, sector, &pc, activeSectors, &dh](std::vector<o2::tpc::CommonMode> const& commonMode) {
334 o2::tpc::TPCSectorHeader header{sector};
335 header.activeSectors = activeSectors;
336 if (!mInternalWriter) {
337 // note that snapshoting only works with non-const references (to be fixed?)
338 pc.outputs().snapshot(Output{"TPC", "COMMONMODE", static_cast<SubSpecificationType>(dh->subSpecification), header},
339 const_cast<std::vector<o2::tpc::CommonMode>&>(commonMode));
340 }
341 };
342 // lambda that snapshots labels to be sent out; prepares and attaches header with sector information
343 auto snapshotLabels = [this, &sector, &pc, activeSectors, &dh](o2::dataformats::MCTruthContainer<o2::MCCompLabel> const& labels) {
344 o2::tpc::TPCSectorHeader header{sector};
345 header.activeSectors = activeSectors;
346 if (mWithMCTruth) {
347 if (!mInternalWriter) {
348 auto& sharedlabels = pc.outputs().make<o2::dataformats::ConstMCTruthContainer<o2::MCCompLabel>>(Output{"TPC", "DIGITSMCTR", static_cast<SubSpecificationType>(dh->subSpecification), header});
349 labels.flatten_to(sharedlabels);
350 }
351 }
352 };
353 // lambda that snapshots digits grouping (triggers) to be sent out; prepares and attaches header with sector information
354 auto snapshotEvents = [this, sector, &pc, activeSectors, &dh](const std::vector<DigiGroupRef>& events) {
355 o2::tpc::TPCSectorHeader header{sector};
356 header.activeSectors = activeSectors;
357 if (!mInternalWriter) {
358 LOG(info) << "TPC: Send TRIGGERS for sector " << sector << " channel " << dh->subSpecification << " | size " << events.size();
359 pc.outputs().snapshot(Output{"TPC", "DIGTRIGGERS", static_cast<SubSpecificationType>(dh->subSpecification), header},
360 const_cast<std::vector<DigiGroupRef>&>(events));
361 }
362 };
363
364 auto digitsAccum = makeDigitBuffer(); // accumulator for digits
365 o2::dataformats::MCTruthContainer<o2::MCCompLabel> labelAccum; // timeframe accumulator for labels
366 std::vector<CommonMode> commonModeAccum;
367 std::vector<DigiGroupRef> eventAccum;
368
369 // this should not happen any more, legacy condition when the sector variable was used
370 // to transport control information
371 if (sector < 0) {
372 throw std::runtime_error("Legacy control information is not expected any more");
373 }
374
375 // the TPCSectorHeader now allows to transport information for more than one sector,
376 // e.g. for transporting clusters in one single data block. The digitization is however
377 // only on sector level
378 if (sector >= TPCSectorHeader::NSectors) {
379 throw std::runtime_error("Digitizer can only work on single sectors");
380 }
381
382 mDigitizer.setSector(sector);
383 mDigitizer.init();
384
385 auto& eventParts = context->getEventParts();
386
387 auto flushDigitsAndLabels = [this, digitsAccum, &labelAccum, &commonModeAccum](bool finalFlush = false) {
388 mFlushCounter++;
389 // flush previous buffer
390 mDigits.clear();
391 mLabels.clear();
392 mCommonMode.clear();
393 mDigitizer.flush(mDigits, mLabels, mCommonMode, finalFlush);
394 LOG(info) << "TPC: Flushed " << mDigits.size() << " digits, " << mLabels.getNElements() << " labels and " << mCommonMode.size() << " common mode entries";
395
396 if (mInternalWriter) {
397 // the natural place to write out this independent datachunk immediately ...
399 } else {
400 // ... or to accumulate and later forward to next DPL proc
401 std::copy(mDigits.begin(), mDigits.end(), std::back_inserter(*digitsAccum));
402 if (mWithMCTruth) {
403 labelAccum.mergeAtBack(mLabels);
404 }
405 std::copy(mCommonMode.begin(), mCommonMode.end(), std::back_inserter(commonModeAccum));
406 }
407 mDigitCounter += mDigits.size();
408 };
409
410 if (isContinuous) {
411 auto& hbfu = o2::raw::HBFUtils::Instance();
412 double time = hbfu.getFirstIRofTF(o2::InteractionRecord(0, hbfu.orbitFirstSampled)).bc2ns() / 1000.;
413 mDigitizer.setOutputDigitTimeOffset(time);
414 mDigitizer.setStartTime(irecords[0].getTimeNS() / 1000.f);
415 }
416
417 TStopwatch timer;
418 timer.Start();
419
420 // loop over all composite collisions given from context
421 // (aka loop over all the interaction records)
422 for (int collID = 0; collID < irecords.size(); ++collID) {
423 const double eventTime = irecords[collID].getTimeNS() / 1000.f;
424 LOG(info) << "TPC: Event time " << eventTime << " us";
425 mDigitizer.setEventTime(eventTime);
426 if (!isContinuous) {
427 mDigitizer.setStartTime(eventTime);
428 }
429 size_t startSize = mDigitCounter; // digitsAccum->size();
430
431 // for each collision, loop over the constituents event and source IDs
432 // (background signal merging is basically taking place here)
433 for (auto& part : eventParts[collID]) {
434 const int eventID = part.entryID;
435 const int sourceID = part.sourceID;
436
437 // get the hits for this event and this source
438 std::vector<o2::tpc::HitGroup> hitsLeft;
439 std::vector<o2::tpc::HitGroup> hitsRight;
440 context->retrieveHits(mSimChains, getBranchNameLeft(sector).c_str(), part.sourceID, part.entryID, &hitsLeft);
441 context->retrieveHits(mSimChains, getBranchNameRight(sector).c_str(), part.sourceID, part.entryID, &hitsRight);
442 LOG(debug) << "TPC: Found " << hitsLeft.size() << " hit groups left and " << hitsRight.size() << " hit groups right in collision " << collID << " eventID " << part.entryID;
443
444 mDigitizer.process(hitsLeft, eventID, sourceID);
445 mDigitizer.process(hitsRight, eventID, sourceID);
446
447 flushDigitsAndLabels();
448
449 if (!isContinuous) {
450 eventAccum.emplace_back(startSize, mDigits.size());
451 }
452 }
453 }
454
455 // final flushing step; getting everything not yet written out
456 if (isContinuous) {
457 LOG(info) << "TPC: Final flush";
458 flushDigitsAndLabels(true);
459 eventAccum.emplace_back(0, mDigitCounter); // all digits are grouped to 1 super-event pseudo-triggered mode
460 }
461
462 if (!mInternalWriter) {
463 // send out to next stage
464 snapshotEvents(eventAccum);
465 // snapshotDigits(digitsAccum); --> done automatically
466 snapshotCommonMode(commonModeAccum);
467 snapshotLabels(labelAccum);
468 }
469
470 timer.Stop();
471 LOG(info) << "TPC: Digitization took " << timer.CpuTime() << "s";
472 }
473
474 private:
475 o2::tpc::Digitizer mDigitizer;
476 o2::tpc::VDriftHelper mTPCVDriftHelper{};
477 std::vector<TChain*> mSimChains;
478 std::vector<o2::tpc::Digit> mDigits;
480 std::vector<o2::tpc::CommonMode> mCommonMode;
481 std::vector<int> mListOfSectors; // a list of sectors treated by this task
482 TFile* mInternalROOTFlushFile = nullptr;
483 TTree* mInternalROOTFlushTTree = nullptr;
484 size_t mDigitCounter = 0;
485 size_t mFlushCounter = 0;
486 int mLaneId = 0; // the id of the current process within the parallel pipeline
487 int mSector = 0;
488 bool mWriteGRP = false;
489 bool mWithMCTruth = true;
490 bool mInternalWriter = false;
491 bool mUseCalibrationsFromCCDB = false;
492 int mDistortionType = 0;
493 float mMeanLumiDistortions = -1;
494 float mMeanLumiDistortionsDerivative = -1;
495 bool mRecalcDistortions = false;
496};
497
498o2::framework::DataProcessorSpec getTPCDigitizerSpec(int channel, bool writeGRP, bool mctruth, bool internalwriter, int distortionType)
499{
500 // create the full data processor spec using
501 // a name identifier
502 // input description
503 // algorithmic description (here a lambda getting called once to setup the actual processing function)
504 // options that can be used for this processor (here: input file names where to take the hits)
505 std::stringstream id;
506 id << "TPCDigitizer" << channel;
507
508 std::vector<OutputSpec> outputs; // define channel by triple of (origin, type id of data to be sent on this channel, subspecification)
509
510 if (!internalwriter) {
511 outputs.emplace_back("TPC", "DIGITS", static_cast<SubSpecificationType>(channel), Lifetime::Timeframe);
512 outputs.emplace_back("TPC", "DIGTRIGGERS", static_cast<SubSpecificationType>(channel), Lifetime::Timeframe);
513 if (mctruth) {
514 outputs.emplace_back("TPC", "DIGITSMCTR", static_cast<SubSpecificationType>(channel), Lifetime::Timeframe);
515 }
516 outputs.emplace_back("TPC", "COMMONMODE", static_cast<SubSpecificationType>(channel), Lifetime::Timeframe);
517 }
518 if (writeGRP) {
519 outputs.emplace_back("TPC", "ROMode", 0, Lifetime::Timeframe);
520 LOG(debug) << "TPC: Channel " << channel << " will supply ROMode";
521 }
522
523 std::vector<InputSpec> inputs{InputSpec{"collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast<SubSpecificationType>(channel), Lifetime::Timeframe}};
524 return DataProcessorSpec{
525 id.str().c_str(),
526 inputs,
527 outputs,
528 AlgorithmSpec{adaptFromTask<TPCDPLDigitizerTask>(internalwriter, distortionType)},
529 Options{
530 {"TPCtriggered", VariantType::Bool, false, {"Impose triggered RO mode (default: continuous)"}},
531 {"TPCuseCCDB", VariantType::Bool, false, {"true: load calibrations from CCDB; false: use random calibratoins"}},
532 {"meanLumiDistortions", VariantType::Float, -1.f, {"override lumi of distortion object if >=0"}},
533 {"meanLumiDistortionsDerivative", VariantType::Float, -1.f, {"override lumi of derivative distortion object if >=0"}},
534 {"do-not-recalculate-distortions", VariantType::Bool, false, {"Do not recalculate the distortions"}},
535 {"n-threads-distortions", VariantType::Int, 4, {"Number of threads used for the calculation of the distortions"}},
536 }};
537}
538
539o2::framework::WorkflowSpec getTPCDigitizerSpec(int nLanes, std::vector<int> const& sectors, bool mctruth, bool internalwriter, int distortionType)
540{
541 // channel parameter is deprecated in the TPCDigitizer processor, all descendants
542 // are initialized not to publish GRP mode, but the channel will be added to the first
543 // processor after the pipelines have been created. The processor will decide upon
544 // the index in the ParallelContext whether to publish
545 WorkflowSpec pipelineTemplate{getTPCDigitizerSpec(0, false, mctruth, internalwriter, distortionType)};
546 // override the predefined name, index will be added by parallelPipeline method
547 pipelineTemplate[0].name = "TPCDigitizer";
549 pipelineTemplate, nLanes, [size = sectors.size()]() { return size; }, [&sectors](size_t index) { return sectors[index]; });
550 // add the channel for the GRP information to the first processor
551 for (auto& spec : pipelines) {
552 o2::tpc::VDriftHelper::requestCCDBInputs(spec.inputs); // add the same CCDB request to each pipeline
553 spec.inputs.emplace_back("gasparam", o2::header::gDataOriginTPC, "TPCGASPARAM", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::ParGas)));
554 spec.inputs.emplace_back("gemparam", o2::header::gDataOriginTPC, "TPCGEMPARAM", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::ParGEM)));
555 if (distortionType) {
556 spec.inputs.emplace_back("tpcdistortions", o2::header::gDataOriginTPC, "TPCDIST", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::DistortionMapMC), {}, 1)); // time-dependent
557 // load derivative map in case scaling was requested
558 if (distortionType == 2) {
559 spec.inputs.emplace_back("tpcdistortionsderiv", o2::header::gDataOriginTPC, "TPCDISTDERIV", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::DistortionMapDerivMC), {}, 1)); // time-dependent
560 }
561 }
562 }
563 pipelines[0].outputs.emplace_back("TPC", "ROMode", 0, Lifetime::Timeframe);
564 return pipelines;
565}
566
567} // end namespace tpc
568} // end namespace o2
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
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.
std::ostringstream debug
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:281
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
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:94
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()))