Project
Loading...
Searching...
No Matches
IOTOFDigitizerSpec.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 "IOTOFDigitizerSpec.h"
18#include "Framework/Lifetime.h"
19#include "Framework/Task.h"
30#include "Headers/DataHeader.h"
33
34#include <TChain.h>
35#include <TStopwatch.h>
36
37#include <algorithm>
38#include <memory>
39#include <string>
40
41using namespace o2::framework;
42
43namespace o2::iotof
44{
45
47{
48 public:
49 using BaseDPLDigitizer::init;
50
51 IOTOFDPLDigitizerTask(bool mctruth = true) : BaseDPLDigitizer(o2::base::InitServices::FIELD | o2::base::InitServices::GEOM),
52 mWithMCTruth(mctruth) {}
53
55 {
56 mDisableQED = ic.options().get<bool>("disable-qed");
57 mEnableResponseFiles = ic.options().get<bool>("enable-response-files");
58 mLocalEfficiencyFile = ic.options().get<std::string>("local-efficiency-file");
59 mLocalTimeResoFile = ic.options().get<std::string>("local-timereso-file");
60 mLocalToAFile = ic.options().get<std::string>("local-toa-file");
61
62 auto geom = GeometryTGeo::Instance();
63 geom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G)); // make sure L2G matrices are loaded
64
65 mDigitizer.setGeometry(geom);
66 mDigitizer.init();
67
69 }
70
72 {
73 if (mFinished) {
74 return;
75 }
76
77 if (mEnableResponseFiles) {
78 pc.inputs().get<TH2D*>("madpixeff");
79 pc.inputs().get<TH2D*>("madpixreso");
80 pc.inputs().get<TH2D*>("madpixtoa");
81 }
82
83 mFirstOrbitTF = pc.services().get<o2::framework::TimingInfo>().firstTForbit;
84 const o2::InteractionRecord firstIR(0, mFirstOrbitTF);
85
86 // read collision context from input
87 auto context = pc.inputs().get<o2::steer::DigitizationContext*>("collisioncontext");
88 context->initSimChains(mID, mSimChains);
89 const bool withQED = context->isQEDProvided() && !mDisableQED;
90 auto& timesview = context->getEventRecords();
91 LOG(info) << "GOT " << timesview.size() << " COLLISION TIMES";
92 LOG(info) << "SIMCHAINS " << mSimChains.size();
93
94 // if there is nothing to do ... return
95 if (timesview.empty()) {
96 return;
97 }
98
99 TStopwatch timer;
100 timer.Start();
101 LOG(info) << " CALLING TF3 DIGITIZATION ";
102
103 mDigitizer.setDigits(&mDigits);
104 mDigitizer.setROFRecords(&mROFRecords);
105 mDigitizer.setROFRecordIR(firstIR);
106 if (mWithMCTruth) {
107 mDigitizer.setMCLabels(&mLabels);
108 }
109
110 auto& eventParts = context->getEventParts(withQED);
111 // loop over all composite collisions given from context
112 // (aka loop over all the interaction records)
113 // o2::InteractionTimeRecord firstorbit(o2::InteractionRecord(0, o2::raw::HBFUtils::Instance().orbitFirstSampled), 0.0);
114 for (int collID = 0; collID < timesview.size(); ++collID) {
115 o2::InteractionTimeRecord orbit(timesview[collID]);
116 // orbit += firstorbit
117 mDigitizer.setEventTime(orbit);
118
119 // for each collision, loop over the constituents event and source IDs
120 // (background signal merging is basically taking place here)
121 for (const auto& part : eventParts[collID]) {
122
123 // get the hits for this event and this source
124 mHits.clear();
125 context->retrieveHits(mSimChains, o2::detectors::SimTraits::DETECTORBRANCHNAMES[mID][0].c_str(), part.sourceID, part.entryID, &mHits);
126
127 if (mHits.size() > 0) {
128 mDigits.clear();
129 if (mWithMCTruth) {
130 mLabels.clear();
131 }
132
133 LOG(debug) << "For collision " << collID << " eventID " << part.entryID << " found " << mHits.size() << " hits ";
134 mDigitizer.process(&mHits, part.entryID, part.sourceID); // call actual digitization procedure
135 }
136 }
137 }
138 if (mDigitizer.isContinuous()) {
139 LOG(debug) << "Number of digits before final flush: " << mDigits.size();
140 mDigits.clear();
141 if (mWithMCTruth) {
142 mLabels.clear();
143 }
144 LOG(debug) << "Final flushing for continuous mode";
145 mDigitizer.fillOutputContainer();
146 LOG(debug) << "Number of digits after final flush: " << mDigits.size();
147 }
148
149 // here we have all digits and we can send them to consumer (aka snapshot it onto output)
150 LOG(debug) << "Digitization finished with " << mDigits.size() << " digits and " << mROFRecords.size() << " ROF records";
151 pc.outputs().snapshot(Output{mOrigin, "DIGITS", 0}, mDigits);
152 pc.outputs().snapshot(Output{mOrigin, "DIGITSROF", 0}, mROFRecords);
153 if (mWithMCTruth) {
154 auto& sharedlabels = pc.outputs().make<o2::dataformats::ConstMCTruthContainer<o2::MCCompLabel>>(Output{mOrigin, "DIGITSMCTR", 0});
155 mLabels.flatten_to(sharedlabels);
156 // free space of existing label containers
157 mLabels.clear_andfreememory();
158
159 // write dummy MC2ROF vector to keep writer/readers backward compatible
160 // NOTE: Steer/DigitizerWorkflow/src/ITSMFTDigitizerSpec.cxx also uses dummy MC2ROF
161 static std::vector<o2::itsmft::MC2ROFRecord> dummyMC2ROF;
162 pc.outputs().snapshot(Output{mOrigin, "DIGITSMC2ROF", 0}, dummyMC2ROF);
163 }
164
165 LOG(info) << mID.getName() << ": Sending ROMode= " << mROMode << " to GRPUpdater";
166 pc.outputs().snapshot(Output{mOrigin, "ROMode", 0}, mROMode);
167
168 timer.Stop();
169 LOG(info) << "Digitization took " << timer.CpuTime() << "s";
170
171 // we should be only called once; tell DPL that this process is ready to exit
172 pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
173
174 mFinished = true;
175 }
176
177 void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj)
178 {
179 if (matcher == ConcreteDataMatcher(mOrigin, "MADPIXEFF", 0)) {
180 if (mLocalEfficiencyFile.empty()) {
181 LOG(info) << "Using CCDB/MADPIX efficiency file";
182 mDigitizer.loadEfficiencyMap((TH2D*)obj);
183 } else {
184 LOG(info) << "Response function will be loaded from local file: " << mLocalEfficiencyFile;
185 std::unique_ptr<TFile> file(TFile::Open(mLocalEfficiencyFile.data(), "READ"));
186 if (!file) {
187 LOG(fatal) << "Cannot open response file " << mLocalEfficiencyFile.data();
188 }
189 mDigitizer.loadEfficiencyMap((TH2D*)file->Get("efficiency_pixel"));
190 }
191 return;
192 }
193 if (matcher == ConcreteDataMatcher(mOrigin, "MADPIXRESO", 0)) {
194 if (mLocalTimeResoFile.empty()) {
195 LOG(info) << "Using CCDB/MADPIX time resolution file";
196 mDigitizer.loadResolutionMap((TH2D*)obj);
197 } else {
198 LOG(info) << "Response function will be loaded from local file: " << mLocalTimeResoFile;
199 std::unique_ptr<TFile> file(TFile::Open(mLocalTimeResoFile.data(), "READ"));
200 if (!file) {
201 LOG(fatal) << "Cannot open response file " << mLocalTimeResoFile.data();
202 }
203 mDigitizer.loadResolutionMap((TH2D*)file->Get("sigma_pixel"));
204 }
205 return;
206 }
207 if (matcher == ConcreteDataMatcher(mOrigin, "MADPIXTOA", 0)) {
208 if (mLocalToAFile.empty()) {
209 LOG(info) << "Using CCDB/MADPIX time-of-arrival file";
210 mDigitizer.loadTimeOfArrivalMap((TH2D*)obj);
211 } else {
212 LOG(info) << "Response function will be loaded from local file: " << mLocalToAFile;
213 std::unique_ptr<TFile> file(TFile::Open(mLocalToAFile.data(), "READ"));
214 if (!file) {
215 LOG(fatal) << "Cannot open response file " << mLocalToAFile.data();
216 }
217 mDigitizer.loadTimeOfArrivalMap((TH2D*)file->Get("toa_pixel"));
218 }
219 }
220 }
221
222 private:
223 bool mDisableQED = false;
224 bool mEnableResponseFiles = false;
225 bool mWithMCTruth{true};
226 bool mFinished{false};
227 std::string mLocalEfficiencyFile{""};
228 std::string mLocalTimeResoFile{""};
229 std::string mLocalToAFile{""};
230 unsigned long mFirstOrbitTF = 0x0;
231 const o2::detectors::DetID mID{o2::detectors::DetID::TF3};
233 o2::iotof::Digitizer mDigitizer{};
234 std::vector<o2::iotof::Digit> mDigits{};
235 std::vector<o2::itsmft::ROFRecord> mROFRecords{};
236 std::vector<o2::itsmft::Hit> mHits{};
237 std::vector<o2::itsmft::Hit>* mHitsP{&mHits};
239 std::vector<TChain*> mSimChains{};
241};
242
243std::vector<o2::framework::OutputSpec> makeOutChannels(o2::header::DataOrigin detOrig, bool mctruth)
244{
245 std::vector<o2::framework::OutputSpec> outputs;
246 outputs.emplace_back(detOrig, "DIGITS", o2::framework::Lifetime::Timeframe);
247 outputs.emplace_back(detOrig, "DIGITSROF", o2::framework::Lifetime::Timeframe);
248 if (mctruth) {
249 outputs.emplace_back(detOrig, "DIGITSMC2ROF", o2::framework::Lifetime::Timeframe);
250 outputs.emplace_back(detOrig, "DIGITSMCTR", o2::framework::Lifetime::Timeframe);
251 }
252 outputs.emplace_back(detOrig, "ROMode", 0, o2::framework::Lifetime::Timeframe);
253 return outputs;
254}
255
257{
258 std::vector<o2::framework::InputSpec> inputs;
259 inputs.emplace_back("collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast<o2::header::DataHeader::SubSpecificationType>(channel), o2::framework::Lifetime::Timeframe);
260 inputs.emplace_back("madpixeff", "TF3", "MADPIXEFF", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("Users/g/glucia/tmp/ALICE3/IOTOF/pixelEfficiency"));
261 inputs.emplace_back("madpixreso", "TF3", "MADPIXRESO", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("Users/g/glucia/tmp/ALICE3/IOTOF/pixelResolution"));
262 inputs.emplace_back("madpixtoa", "TF3", "MADPIXTOA", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("Users/g/glucia/tmp/ALICE3/IOTOF/pixelTimeOfArrival"));
263
264 const std::string detStr = o2::detectors::DetID::getName(o2::detectors::DetID::TF3);
265 return o2::framework::DataProcessorSpec{detStr + "Digitizer",
266 inputs,
268 o2::framework::AlgorithmSpec{o2::framework::adaptFromTask<IOTOFDPLDigitizerTask>(mctruth)},
270 {"disable-qed", o2::framework::VariantType::Bool, false, {"disable QED handling"}},
271 {"enable-response-files", o2::framework::VariantType::Bool, false, {"enable in-pixel response maps from data"}},
272 {"local-efficiency-file", o2::framework::VariantType::String, "", {"use efficiency map saved locally at this path/filename"}},
273 {"local-timereso-file", o2::framework::VariantType::String, "", {"use time resolution map saved locally at this path/filename"}},
274 {"local-toa-file", o2::framework::VariantType::String, "", {"use ToA map saved locally at this path/filename"}}}};
275}
276
277} // namespace o2::iotof
Definition of the base digitizer task class.
A const (ready only) version of MCTruthContainer.
Definition of the ITSMFT digit.
std::ostringstream debug
uint64_t orbit
Definition RawEventData.h:6
Header of the General Run Parameters object.
Definition of the ITSMFT ROFrame (trigger) record.
Definition of the ALICE3 TOF digitizer.
A read-only version of MCTruthContainer allowing for storage optimisation.
A container to hold and manage MC truth information/labels.
size_t flatten_to(ContainerType &container) const
Static class with identifiers, bitmasks and names for ALICE detectors.
Definition DetID.h:60
static constexpr const char * getName(ID id)
names of defined detectors
Definition DetID.h:148
static const std::array< std::vector< std::string >, DetID::nDetectors > DETECTORBRANCHNAMES
Definition SimTraits.h:39
void snapshot(const Output &spec, T const &object)
decltype(auto) make(const Output &spec, Args... args)
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.
Digitizer for the ALICE3 Inner/Outer TOF detector.
Definition Digitizer.h:52
void loadResolutionMap(TH2D *map)
Definition Digitizer.h:79
void setROFRecords(std::vector< o2::itsmft::ROFRecord > *rec)
Definition Digitizer.h:56
void setROFRecordIR(const o2::InteractionRecord &ir)
Definition Digitizer.h:66
void init()
Initialize the digitizer.
Definition Digitizer.cxx:43
void fillOutputContainer()
Flush the output container.
void loadTimeOfArrivalMap(TH2D *map)
Definition Digitizer.h:80
void setDigits(std::vector< o2::iotof::Digit > *dig)
Definition Digitizer.h:54
void process(const std::vector< o2::itsmft::Hit > *hits, int evID, int srcID)
Steer conversion of hits to digits.
Definition Digitizer.cxx:87
bool isContinuous() const
Definition Digitizer.h:70
void setEventTime(const o2::InteractionTimeRecord &irt)
Set the event time.
Definition Digitizer.h:65
void setMCLabels(o2::dataformats::MCTruthContainer< o2::MCCompLabel > *mclb)
Definition Digitizer.h:55
void setGeometry(const o2::iotof::GeometryTGeo *gm)
Definition Digitizer.h:76
void loadEfficiencyMap(TH2D *map)
Definition Digitizer.h:78
static GeometryTGeo * Instance()
void run(framework::ProcessingContext &pc)
void initDigitizerTask(framework::InitContext &ic) override
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj)
bool initSimChains(o2::detectors::DetID detid, std::vector< TChain * > &simchains) const
constexpr o2::header::DataOrigin gDataOriginTF3
Definition DataHeader.h:590
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
std::vector< o2::framework::OutputSpec > makeOutChannels(o2::header::DataOrigin detOrig, bool mctruth)
o2::framework::DataProcessorSpec getIOTOFDigitizerSpec(int channel, bool mctruth)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
uint32_t SubSpecificationType
Definition DataHeader.h:625
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"