Project
Loading...
Searching...
No Matches
PHOSDigitizerSpec.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 "PHOSDigitizerSpec.h"
18#include "Framework/Lifetime.h"
19#include "TStopwatch.h"
20#include "Steer/HitProcessingManager.h" // for DigitizationContext
21#include "TChain.h"
30
31using namespace o2::framework;
33
34namespace o2
35{
36namespace phos
37{
38
40{
41
42 auto simulatePileup = ic.options().get<int>("pileup");
43 if (simulatePileup) { // set readout time and dead time parameters
44 mReadoutTime = o2::phos::PHOSSimParams::Instance().mReadoutTimePU; // PHOS readout time in ns
45 mDeadTime = o2::phos::PHOSSimParams::Instance().mDeadTimePU; // PHOS dead time (should include readout => mReadoutTime< mDeadTime)
46 } else {
47 mReadoutTime = o2::phos::PHOSSimParams::Instance().mReadoutTime; // PHOS readout time in ns
48 mDeadTime = o2::phos::PHOSSimParams::Instance().mDeadTime; // PHOS dead time (should include readout => mReadoutTime< mDeadTime)
49 }
50
51 // init digitizer
52 mDigitizer.init();
53 auto mctruth = ic.options().get<bool>("mctruth");
54 if (!mctruth) {
55 mDigitizer.processMC(false);
56 }
57
58 if (mHits) {
59 delete mHits;
60 }
61 mHits = new std::vector<Hit>();
62}
63
65{
66 // read collision context from input
67 auto context = pc.inputs().get<o2::steer::DigitizationContext*>("collisioncontext");
68 context->initSimChains(o2::detectors::DetID::PHS, mSimChains);
69 auto& timesview = context->getEventRecords();
70 LOG(debug) << "GOT " << timesview.size() << " COLLISSION TIMES";
71
72 if (mInitSimParams) { // trigger reading sim/rec parameters from CCDB, singleton initiated in Fetcher
73 pc.inputs().get<o2::phos::PHOSSimParams*>("recoparams");
74 mInitSimParams = false;
75 }
76
77 // if there is nothing to do ... return
78 int n = timesview.size();
79 if (n == 0) {
80 return;
81 }
82
83 TStopwatch timer;
84 timer.Start();
85
86 if (mDigitizer.runStartTime() == 0) { // not set yet
87 long runStartTime = timesview[0].getTimeNS();
88 mDigitizer.setRunStartTime(runStartTime); // set timestamp to access CCDB if necessary
89 }
90
91 LOG(info) << " CALLING PHOS DIGITIZATION ";
92 std::vector<TriggerRecord> triggers;
93
94 int indexStart = mDigitsOut.size();
95 auto& eventParts = context->getEventParts();
96 // if this is last stream of hits and we can write directly to final vector of digits? Otherwize use temporary vectors
97 mDigitsFinal.clear();
98 mDigitsTmp.clear();
99 bool isLastStream = true;
100 double eventTime = timesview[0].getTimeNS() - o2::phos::PHOSSimParams::Instance().mDeadTime; // checked above that list not empty
101 int eventId = 0;
102
103 // the interaction record marking the timeframe start
104 auto firstTF = InteractionTimeRecord(o2::raw::HBFUtils::Instance().getFirstSampledTFIR(), 0);
105
106 // loop over all composite collisions given from context
107 // (aka loop over all the interaction records)
108 for (int collID = 0; collID < n; ++collID) {
109 // Note: Very crude filter to neglect collisions coming before
110 // the first interaction record of the timeframe. Remove this, once these collisions can be handled
111 // within the digitization routine. Collisions before this timeframe might impact digits of this timeframe.
112 // See https://its.cern.ch/jira/browse/O2-5395.
113 if (timesview[collID] < firstTF) {
114 LOG(info) << "Too early: Not digitizing collision " << collID;
115 continue;
116 }
117
118 double dt = timesview[collID].getTimeNS() - eventTime; // start new PHOS readout, continue current or dead time?
119 if (dt > mReadoutTime && dt < mDeadTime) { // dead time, skip event
120 continue;
121 }
122
123 if (dt >= o2::phos::PHOSSimParams::Instance().mDeadTime) { // start new event
124 // new event
125 eventTime = timesview[collID].getTimeNS();
126 dt = 0.;
127 eventId = collID;
128 }
129
130 // Check if next event has to be added to this read-out
131 if (collID < n - 1) {
132 isLastStream = (timesview[collID + 1].getTimeNS() - eventTime > mReadoutTime);
133 } else {
134 isLastStream = true;
135 }
136
137 // for each collision, loop over the constituents event and source IDs
138 // (background signal merging is basically taking place here)
139 // merge new hist to current digit list
140 auto part = eventParts[collID].begin();
141 while (part != eventParts[collID].end()) {
142 // get the hits for this event and this source
143 int source = part->sourceID;
144 int entry = part->entryID;
145 mHits->clear();
146 context->retrieveHits(mSimChains, "PHSHit", source, entry, mHits);
147
148 part++;
149 if (part == eventParts[collID].end() && isLastStream) { // last stream, copy digits directly to output vector
150 mDigitizer.processHits(mHits, mDigitsFinal, mDigitsOut, mLabels, entry, source, dt);
151 mDigitsFinal.clear();
152 // finalyze previous event and clean
153 // Add trigger record
154 triggers.emplace_back(timesview[eventId], indexStart, mDigitsOut.size() - indexStart);
155 indexStart = mDigitsOut.size();
156 } else { // Fill intermediate digitvector
157 mDigitsTmp.swap(mDigitsFinal);
158 mDigitizer.processHits(mHits, mDigitsTmp, mDigitsFinal, mLabels, entry, source, dt);
159 mDigitsTmp.clear();
160 }
161 }
162 }
163 LOG(debug) << "Have " << mLabels.getNElements() << " PHOS labels ";
164 // here we have all digits and we can send them to consumer (aka snapshot it onto output)
165 pc.outputs().snapshot(Output{"PHS", "DIGITS", 0}, mDigitsOut);
166 pc.outputs().snapshot(Output{"PHS", "DIGITTRIGREC", 0}, triggers);
167 if (pc.outputs().isAllowed({"PHS", "DIGITSMCTR", 0})) {
168 pc.outputs().snapshot(Output{"PHS", "DIGITSMCTR", 0}, mLabels);
169 }
170
171 // PHOS is always a triggering detector
173 LOG(debug) << "PHOS: Sending ROMode= " << roMode << " to GRPUpdater";
174 pc.outputs().snapshot(Output{"PHS", "ROMode", 0}, roMode);
175
176 timer.Stop();
177 LOG(info) << "Digitization took " << timer.CpuTime() << "s";
178
179 // we should be only called once; tell DPL that this process is ready to exit
180 pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
181}
182
183DataProcessorSpec getPHOSDigitizerSpec(int channel, bool mctruth)
184{
185 std::vector<OutputSpec> outputs;
186 outputs.emplace_back("PHS", "DIGITS", 0, Lifetime::Timeframe);
187 outputs.emplace_back("PHS", "DIGITTRIGREC", 0, Lifetime::Timeframe);
188 if (mctruth) {
189 outputs.emplace_back("PHS", "DIGITSMCTR", 0, Lifetime::Timeframe);
190 }
191 outputs.emplace_back("PHS", "ROMode", 0, Lifetime::Timeframe);
192
193 std::vector<o2::framework::InputSpec> inputs;
194 inputs.emplace_back("collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast<SubSpecificationType>(channel), Lifetime::Timeframe);
195 inputs.emplace_back("recoparams", o2::header::gDataOriginPHS, "PHS_RecoParams", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("PHS/Config/RecoParams"));
196
197 // create the full data processor spec using
198 // a name identifier
199 // input description
200 // algorithmic description (here a lambda getting called once to setup the actual processing function)
201 // options that can be used for this processor (here: input file names where to take the hits)
202 return DataProcessorSpec{
203 "PHOSDigitizer",
204 inputs,
205 outputs,
206 AlgorithmSpec{o2::framework::adaptFromTask<DigitizerSpec>()},
207 Options{{"pileup", VariantType::Int, 1, {"whether to run in continuous time mode"}},
208 {"mctruth", VariantType::Bool, true, {"whether to process MC info"}}}};
209}
210} // namespace phos
211} // namespace o2
o2::framework::DataAllocator::SubSpecificationType SubSpecificationType
Class to store event ID and index in the event for objects like track, cluster...
Header of the General Run Parameters object.
Definition of a container to keep Monte Carlo truth external to simulation objects.
std::ostringstream debug
static constexpr ID PHS
Definition DetID.h:67
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
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.
void run(framework::ProcessingContext &ctx)
run digitizer
void initDigitizerTask(framework::InitContext &ctx) final
init digitizer
void processMC(bool mc)
Definition Digitizer.h:42
long runStartTime() const
Definition Digitizer.h:45
void setRunStartTime(long t)
Definition Digitizer.h:44
void processHits(const std::vector< Hit > *mHits, const std::vector< Digit > &digitsBg, std::vector< Digit > &digitsOut, o2::dataformats::MCTruthContainer< MCLabel > &mLabels, int source, int entry, double dt)
Steer conversion of hits to digits.
Definition Digitizer.cxx:36
bool initSimChains(o2::detectors::DetID detid, std::vector< TChain * > &simchains) const
GLdouble n
Definition glcorearb.h:1982
GLuint entry
Definition glcorearb.h:5735
GLuint GLuint end
Definition glcorearb.h:469
GLsizei GLsizei GLchar * source
Definition glcorearb.h:798
constexpr o2::header::DataOrigin gDataOriginPHS
Definition DataHeader.h:574
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
std::vector< ConfigParamSpec > Options
header::DataHeader::SubSpecificationType SubSpecificationType
DataProcessorSpec getPHOSDigitizerSpec(int channel, bool mctruth)
Create new digitizer spec.
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"