Project
Loading...
Searching...
No Matches
HMPIDDigitizerSpec.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 "HMPIDDigitizerSpec.h"
17#include "Framework/Lifetime.h"
18#include "Headers/DataHeader.h"
19#include "TStopwatch.h"
20#include "Steer/HitProcessingManager.h" // for DigitizationContext
21#include "TChain.h"
24#include "Framework/Task.h"
34
35using namespace o2::framework;
37
38namespace o2
39{
40namespace hmpid
41{
42
44{
45 public:
46 HMPIDDPLDigitizerTask() : o2::base::BaseDPLDigitizer(o2::base::InitServices::GEOM) {}
47
49 {
50 }
51
53 {
54 static bool finished = false;
55 if (finished) {
56 return;
57 }
58 LOG(info) << "Doing HMPID digitization";
59
60 // read collision context from input
61 auto context = pc.inputs().get<o2::steer::DigitizationContext*>("collisioncontext");
62
63 if (context->hasTriggerInput()) {
64 auto ctpdigits = context->getCTPDigits();
65 LOG(info) << "Yes, we have CTP digits";
66 LOG(info) << "We have " << ctpdigits->size() << " digits";
67 } else {
68 LOG(info) << "No trigger input available ... selftriggering";
69 }
70
71 context->initSimChains(o2::detectors::DetID::HMP, mSimChains);
72
73 auto& irecords = context->getEventRecords();
74 for (auto& record : irecords) {
75 LOG(info) << "HMPID TIME RECEIVED " << record.getTimeNS();
76 }
77
78 auto& eventParts = context->getEventParts();
79 std::vector<o2::hmpid::Digit> digitsAccum; // accumulator for digits
80 o2::dataformats::MCTruthContainer<o2::MCCompLabel> labelAccum; // timeframe accumulator for labels
81 mIntRecord.clear();
82
83 auto flushDigitsAndLabels = [this, &digitsAccum, &labelAccum]() {
84 // flush previous buffer
85 mDigits.clear();
86 mLabels.clear();
87 mDigitizer.flush(mDigits);
88 LOG(info) << "HMPID flushed " << mDigits.size() << " digits at this time ";
89 LOG(info) << "NUMBER OF LABEL OBTAINED " << mLabels.getNElements();
90 int32_t first = digitsAccum.size(); // this is the first
91 std::copy(mDigits.begin(), mDigits.end(), std::back_inserter(digitsAccum));
92 labelAccum.mergeAtBack(mLabels);
93
94 // save info for the triggers accepted
95 LOG(info) << "Trigger Orbit :" << mDigitizer.getOrbit() << " BC:" << mDigitizer.getBc();
96 mIntRecord.push_back(o2::hmpid::Trigger(o2::InteractionRecord(mDigitizer.getBc(), mDigitizer.getOrbit()), first, digitsAccum.size() - first));
97 };
98
99 // the interaction record marking the timeframe start
100 auto firstTF = InteractionTimeRecord(o2::raw::HBFUtils::Instance().getFirstSampledTFIR(), 0);
101
102 // loop over all composite collisions given from context
103 // (aka loop over all the interaction records)
104 for (int collID = 0; collID < irecords.size(); ++collID) {
105 // Note: Very crude filter to neglect collisions coming before
106 // the first interaction record of the timeframe. Remove this, once these collisions can be handled
107 // within the digitization routine. Collisions before this timeframe might impact digits of this timeframe.
108 // See https://its.cern.ch/jira/browse/O2-5395.
109 if (irecords[collID] < firstTF) {
110 LOG(info) << "Too early: Not digitizing collision " << collID;
111 continue;
112 }
113
114 // try to start new readout cycle by setting the trigger time
115 auto triggeraccepted = mDigitizer.setTriggerTime(irecords[collID].getTimeNS());
116 if (triggeraccepted) {
117 auto withinactivetime = mDigitizer.setEventTime(irecords[collID].getTimeNS());
118 if (withinactivetime) {
119 // for each collision, loop over the constituents event and source IDs
120 // (background signal merging is basically taking place here)
121 for (auto& part : eventParts[collID]) {
122 mDigitizer.setEventID(part.entryID);
123 mDigitizer.setSrcID(part.sourceID);
124
125 // get the hits for this event and this source
126 std::vector<o2::hmpid::HitType> hits;
127 context->retrieveHits(mSimChains, "HMPHit", part.sourceID, part.entryID, &hits);
128 LOG(info) << "For collision " << collID << " eventID " << part.entryID << " found HMP " << hits.size() << " hits ";
129
130 mDigitizer.setLabelContainer(&mLabels);
131 mLabels.clear();
132 mDigits.clear();
133
134 mDigitizer.process(hits, mDigits);
135 }
136
137 flushDigitsAndLabels(); // flush previous readout cycle
138 } else {
139 LOG(info) << "COLLISION " << collID << "FALLS WITHIN A DEAD TIME";
140 }
141 }
142 }
143
144 // send out to next stage
145 pc.outputs().snapshot(Output{"HMP", "DIGITS", 0}, digitsAccum);
146 pc.outputs().snapshot(Output{"HMP", "INTRECORDS", 0}, mIntRecord);
147 if (pc.outputs().isAllowed({"HMP", "DIGITLBL", 0})) {
148 pc.outputs().snapshot(Output{"HMP", "DIGITLBL", 0}, labelAccum);
149 }
150 LOG(info) << "HMP: Sending ROMode= " << mROMode << " to GRPUpdater";
151 pc.outputs().snapshot(Output{"HMP", "ROMode", 0}, mROMode);
152
153 // we should be only called once; tell DPL that this process is ready to exit
154 pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
155 finished = true;
156 }
157
158 private:
159 HMPIDDigitizer mDigitizer;
160 std::vector<TChain*> mSimChains;
161 std::vector<o2::hmpid::Digit> mDigits;
162 o2::dataformats::MCTruthContainer<o2::MCCompLabel> mLabels; // labels which get filled
163 std::vector<o2::hmpid::Trigger> mIntRecord;
164
165 // RS: at the moment using hardcoded flag for continuous readout
167};
168
170{
171 // create the full data processor spec using
172 // a name identifier
173 // input description
174 // algorithmic description (here a lambda getting called once to setup the actual processing function)
175 // options that can be used for this processor (here: input file names where to take the hits)
176 std::vector<OutputSpec> outputs;
177 outputs.emplace_back("HMP", "DIGITS", 0, Lifetime::Timeframe);
178 outputs.emplace_back("HMP", "INTRECORDS", 0, Lifetime::Timeframe);
179 if (mctruth) {
180 outputs.emplace_back("HMP", "DIGITLBL", 0, Lifetime::Timeframe);
181 }
182 outputs.emplace_back("HMP", "ROMode", 0, Lifetime::Timeframe);
183
184 return DataProcessorSpec{
185 "HMPIDDigitizer",
186 Inputs{InputSpec{"collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast<SubSpecificationType>(channel), Lifetime::Timeframe}},
187
188 outputs,
189 AlgorithmSpec{adaptFromTask<HMPIDDPLDigitizerTask>()}, Options{}};
190}
191
192} // end namespace hmpid
193} // end namespace o2
Definition of the base digitizer task class.
o2::framework::DataAllocator::SubSpecificationType SubSpecificationType
Header of the General Run Parameters object.
Definition of a container to keep Monte Carlo truth external to simulation objects.
A container to hold and manage MC truth information/labels.
void mergeAtBack(MCTruthContainer< TruthElement > const &other)
static constexpr ID HMP
Definition DetID.h:70
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 process(std::vector< o2::hmpid::HitType > const &, std::vector< o2::hmpid::Digit > &digit)
void setEventID(int eventID)
bool setTriggerTime(double timeNS)
void flush(std::vector< o2::hmpid::Digit > &digit)
void setLabelContainer(o2::dataformats::MCTruthContainer< o2::MCCompLabel > *labels)
bool setEventTime(double timeNS)
HMPID Trigger declaration.
Definition Trigger.h:32
std::vector< o2::ctp::CTPDigit > const * getCTPDigits() const
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
header::DataHeader::SubSpecificationType SubSpecificationType
std::vector< InputSpec > Inputs
o2::framework::DataProcessorSpec getHMPIDDigitizerSpec(int channel, bool mctruth)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"