Project
Loading...
Searching...
No Matches
MCHDigitizerSpec.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 "MCHDigitizerSpec.h"
13
22#include "Framework/Lifetime.h"
23#include "Framework/Task.h"
28#include "MCHSimulation/Hit.h"
30#include "TChain.h"
33#include <TGeoManager.h>
34#include <algorithm>
35#include <map>
36
37using namespace o2::framework;
39
40namespace o2
41{
42namespace mch
43{
44
46{
47 public:
48 MCHDPLDigitizerTask() : o2::base::BaseDPLDigitizer(o2::base::InitServices::FIELD | o2::base::InitServices::GEOM) {}
49
51 {
53 mDigitizer = std::make_unique<Digitizer>(transformation);
54 }
55
56 void logStatus(gsl::span<Digit> digits, gsl::span<ROFRecord> rofs, o2::dataformats::MCLabelContainer& labels,
57 size_t nPileup, std::chrono::high_resolution_clock::time_point start)
58 {
59 LOGP(info, "Number of digits : {}", digits.size());
60 LOGP(info, "Number of rofs : {}", rofs.size());
61 LOGP(info, "Number of labels : {} (indexed {})", labels.getNElements(), labels.getIndexedSize());
62 if (labels.getIndexedSize() != digits.size()) {
63 LOGP(error, "Number of labels != number of digits");
64 }
65 LOGP(info, "Number of signal pileup : {} ({} %)", nPileup, 100. * nPileup / digits.size());
66 auto tEnd = std::chrono::high_resolution_clock::now();
67 auto duration = tEnd - start;
68 auto d = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
69 LOGP(info, "Digitizer time {} ms", d);
70 }
71
73 {
74 static bool finished = false;
75 if (finished) {
76 return;
77 }
78
79 mDigitizer->setFirstTFOrbit(pc.services().get<o2::framework::TimingInfo>().firstTForbit);
80
81 auto tStart = std::chrono::high_resolution_clock::now();
82 auto context = pc.inputs().get<o2::steer::DigitizationContext*>("collisioncontext");
83 context->initSimChains(o2::detectors::DetID::MCH, mSimChains);
84 const auto& eventRecords = context->getEventRecords();
85 auto timeOffset = DigitFilterParam::Instance().timeOffset;
86
87 // generate signals produced by every hits
88 if (!DigitizerParam::Instance().onlyNoise) {
89 const auto& eventParts = context->getEventParts();
90 for (auto i = 0; i < eventRecords.size(); i++) {
91 auto ir = eventRecords[i];
92 // apply time offset, discarding events going to negative IR
93 if (ir.toLong() < timeOffset) {
94 continue;
95 }
96 ir -= timeOffset;
97 for (const auto& part : eventParts[i]) {
98 std::vector<Hit> hits{};
99 context->retrieveHits(mSimChains, "MCHHit", part.sourceID, part.entryID, &hits);
100 mDigitizer->processHits(hits, ir, part.entryID, part.sourceID);
101 }
102 }
103 }
104
105 // generate noise-only signals between first and last collisions ± 100 BC (= 25 ADC samples)
106 auto firstIR = InteractionRecord::long2IR(std::max(int64_t(0), eventRecords.front().toLong() - timeOffset - 100));
107 auto lastIR = InteractionRecord::long2IR(std::max(int64_t(0), eventRecords.back().toLong() - timeOffset + 100));
108 mDigitizer->addNoise(firstIR, lastIR);
109
110 // digitize
111 std::vector<Digit> digits{};
112 std::vector<ROFRecord> rofs{};
114 auto nPileup = mDigitizer->digitize(rofs, digits, labels);
115
116 pc.outputs().snapshot(Output{"MCH", "DIGITS", 0}, digits);
117 pc.outputs().snapshot(Output{"MCH", "DIGITROFS", 0}, rofs);
118 if (pc.outputs().isAllowed({"MCH", "DIGITSLABELS", 0})) {
119 pc.outputs().snapshot(Output{"MCH", "DIGITSLABELS", 0}, labels);
120 }
121 pc.outputs().snapshot(Output{"MCH", "ROMode", 0},
123
124 // we should be only called once; tell DPL that this process is ready to exit
125 pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
126 finished = true;
127
128 logStatus(digits, rofs, labels, nPileup, tStart);
129 }
130
131 private:
132 std::unique_ptr<Digitizer> mDigitizer{};
133 std::vector<TChain*> mSimChains{};
134};
135
137{
138 std::vector<OutputSpec> outputs{};
139 outputs.emplace_back("MCH", "DIGITS", 0, Lifetime::Timeframe);
140 outputs.emplace_back("MCH", "DIGITROFS", 0, Lifetime::Timeframe);
141 if (mctruth) {
142 outputs.emplace_back("MCH", "DIGITSLABELS", 0, Lifetime::Timeframe);
143 }
144 outputs.emplace_back("MCH", "ROMode", 0, Lifetime::Timeframe);
145
146 return DataProcessorSpec{
147 "MCHDigitizer",
148 Inputs{InputSpec{"collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast<SubSpecificationType>(channel), Lifetime::Timeframe}},
149 outputs,
150 AlgorithmSpec{adaptFromTask<MCHDPLDigitizerTask>()},
151 Options{}};
152}
153
154} // end namespace mch
155} // end namespace o2
Definition of the base digitizer task class.
o2::framework::DataAllocator::SubSpecificationType SubSpecificationType
int32_t i
Header of the General Run Parameters object.
Definition of a container to keep Monte Carlo truth external to simulation objects.
Definition of the MCH ROFrame record.
static constexpr ID MCH
Definition DetID.h:72
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
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.
void run(framework::ProcessingContext &pc)
void initDigitizerTask(framework::InitContext &ic) override
void logStatus(gsl::span< Digit > digits, gsl::span< ROFRecord > rofs, o2::dataformats::MCLabelContainer &labels, size_t nPileup, std::chrono::high_resolution_clock::time_point start)
bool initSimChains(o2::detectors::DetID detid, std::vector< TChain * > &simchains) const
GLuint start
Definition glcorearb.h:469
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
header::DataHeader::SubSpecificationType SubSpecificationType
std::vector< InputSpec > Inputs
TransformationCreator transformationFromTGeoManager(const TGeoManager &geo)
o2::framework::DataProcessorSpec getMCHDigitizerSpec(int channel, bool mctruth)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
static InteractionRecord long2IR(int64_t l)
auto transformation
o2::InteractionRecord ir(0, 0)
std::vector< Digit > digits