Project
Loading...
Searching...
No Matches
CPVDigitizerSpec.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 "CPVDigitizerSpec.h"
17#include "Framework/Lifetime.h"
18#include "TStopwatch.h"
19#include "Steer/HitProcessingManager.h" // for DigitizationContext
20#include "TChain.h"
21
33
34using namespace o2::framework;
36
37namespace o2
38{
39namespace cpv
40{
41
43{
44 if (mHits) {
45 delete mHits;
46 }
47 mHits = new std::vector<Hit>();
48
49 auto simulatePileup = ic.options().get<int>("pileup");
50 if (simulatePileup) { // set readout time and dead time parameters
51 mReadoutTime = o2::cpv::CPVSimParams::Instance().mReadoutTimePU; // PHOS readout time in ns
52 mDeadTime = o2::cpv::CPVSimParams::Instance().mDeadTimePU; // PHOS dead time (should include readout => mReadoutTime< mDeadTime)
53 } else {
54 mReadoutTime = o2::cpv::CPVSimParams::Instance().mReadoutTime; // PHOS readout time in ns
55 mDeadTime = o2::cpv::CPVSimParams::Instance().mDeadTime; // PHOS dead time (should include readout => mReadoutTime< mDeadTime)
56 }
57}
58
59void DigitizerSpec::updateTimeDependentParams(framework::ProcessingContext& ctx)
60{
61 static bool updateOnlyOnce = false;
62 if (!updateOnlyOnce) {
63 LOG(info) << "DigitizerSpec::run() : fetching o2::cpv::CPVSimParams from CCDB";
64 ctx.inputs().get<o2::cpv::CPVSimParams*>("simparams");
65 LOG(info) << "DigitizerSpec::run() : o2::cpv::CPVSimParams::Instance() now is following:";
67
68 auto pedPtr = ctx.inputs().get<o2::cpv::Pedestals*>("peds");
69 mDigitizer.setPedestals(pedPtr.get());
70
71 auto badMapPtr = ctx.inputs().get<o2::cpv::BadChannelMap*>("badmap");
72 mDigitizer.setBadChannelMap(badMapPtr.get());
73
74 auto gainsPtr = ctx.inputs().get<o2::cpv::CalibParams*>("gains");
75 mDigitizer.setGains(gainsPtr.get());
76
77 // init digitizer
78 mDigitizer.init();
79
80 updateOnlyOnce = true;
81 }
82}
83
85{
86 updateTimeDependentParams(pc);
87 // read collision context from input
88 auto context = pc.inputs().get<o2::steer::DigitizationContext*>("collisioncontext");
89 context->initSimChains(o2::detectors::DetID::CPV, mSimChains);
90 auto& timesview = context->getEventRecords();
91 LOG(debug) << "GOT " << timesview.size() << " COLLISSION TIMES";
92
93 // if there is nothing to do ... return
94 int n = timesview.size();
95 if (n == 0) {
96 return;
97 }
98
99 TStopwatch timer;
100 timer.Start();
101
102 LOG(info) << " CALLING CPV DIGITIZATION ";
103 std::vector<TriggerRecord> triggers;
104
105 int indexStart = mDigitsOut.size();
106 auto& eventParts = context->getEventParts();
107 // if this is last stream of hits and we can write directly to final vector of digits? Otherwize use temporary vectors
108 bool isLastStream = true;
109 double eventTime = timesview[0].getTimeNS() - o2::cpv::CPVSimParams::Instance().mDeadTime; // checked above that list not empty
110 int eventId = 0;
111
112 // the interaction record marking the timeframe start
113 auto firstTF = InteractionTimeRecord(o2::raw::HBFUtils::Instance().getFirstSampledTFIR(), 0);
114
115 // loop over all composite collisions given from context
116 // (aka loop over all the interaction records)
117 for (int collID = 0; collID < n; ++collID) {
118 // Note: Very crude filter to neglect collisions coming before
119 // the first interaction record of the timeframe. Remove this, once these collisions can be handled
120 // within the digitization routine. Collisions before this timeframe might impact digits of this timeframe.
121 // See https://its.cern.ch/jira/browse/O2-5395.
122 if (timesview[collID] < firstTF) {
123 LOG(info) << "Too early: Not digitizing collision " << collID;
124 continue;
125 }
126
127 double dt = timesview[collID].getTimeNS() - eventTime; // start new PHOS readout, continue current or dead time?
128 if (dt > mReadoutTime && dt < mDeadTime) { // dead time, skip event
129 continue;
130 }
131
132 if (dt >= o2::cpv::CPVSimParams::Instance().mDeadTime) { // start new event
133 // new event
134 eventTime = timesview[collID].getTimeNS();
135 dt = 0.;
136 eventId = collID;
137 }
138
139 // Check if next event has to be added to this read-out
140 if (collID < n - 1) {
141 isLastStream = (timesview[collID + 1].getTimeNS() - eventTime > mReadoutTime);
142 } else {
143 isLastStream = true;
144 }
145
146 // for each collision, loop over the constituents event and source IDs
147 // (background signal merging is basically taking place here)
148 // merge new hist to current digit list
149 auto part = eventParts[collID].begin();
150 while (part != eventParts[collID].end()) {
151 // get the hits for this event and this source
152 int source = part->sourceID;
153 int entry = part->entryID;
154 mHits->clear();
155 context->retrieveHits(mSimChains, "CPVHit", source, entry, mHits);
156 part++;
157 if (part == eventParts[collID].end() && isLastStream) { // last stream, copy digits directly to output vector
158 mDigitizer.processHits(mHits, mDigitsFinal, mDigitsOut, mLabels, collID, source, dt);
159 mDigitsFinal.clear();
160 // finalyze previous event and clean
161 // Add trigger record
162 triggers.emplace_back(timesview[eventId], indexStart, mDigitsOut.size() - indexStart);
163 indexStart = mDigitsOut.size();
164 mDigitsFinal.clear();
165 } else { // Fill intermediate digitvector
166 mDigitsTmp.swap(mDigitsFinal);
167 mDigitizer.processHits(mHits, mDigitsTmp, mDigitsFinal, mLabels, collID, source, dt);
168 mDigitsTmp.clear();
169 }
170 }
171 }
172 LOG(debug) << "Have " << mLabels.getNElements() << " CPV labels ";
173 // here we have all digits and we can send them to consumer (aka snapshot it onto output)
174 pc.outputs().snapshot(Output{"CPV", "DIGITS", 0}, mDigitsOut);
175 pc.outputs().snapshot(Output{"CPV", "DIGITTRIGREC", 0}, triggers);
176 if (pc.outputs().isAllowed({"CPV", "DIGITSMCTR", 0})) {
177 pc.outputs().snapshot(Output{"CPV", "DIGITSMCTR", 0}, mLabels);
178 }
179 // CPV is always a triggered detector
181 LOG(debug) << "CPV: Sending ROMode= " << roMode << " to GRPUpdater";
182 pc.outputs().snapshot(Output{"CPV", "ROMode", 0}, roMode);
183
184 timer.Stop();
185 LOG(info) << "Digitization took " << timer.CpuTime() << "s";
186
187 // pc.services().get<o2::framework::ControlService>().endOfStream();
188 // we should be only called once; tell DPL that this process is ready to exit
189 pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
190}
191
192DataProcessorSpec getCPVDigitizerSpec(int channel, bool mctruth)
193{
194 // inputs
195 std::vector<o2::framework::InputSpec> inputs;
196 inputs.emplace_back("collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast<SubSpecificationType>(channel), Lifetime::Timeframe);
197 inputs.emplace_back("peds", "CPV", "CPV_Pedestals", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("CPV/Calib/Pedestals"));
198 inputs.emplace_back("badmap", "CPV", "CPV_BadMap", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("CPV/Calib/BadChannelMap"));
199 inputs.emplace_back("gains", "CPV", "CPV_Gains", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("CPV/Calib/Gains"));
200 inputs.emplace_back("simparams", "CPV", "CPV_SimPars", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("CPV/Config/CPVSimParams"));
201
202 // outputs
203 std::vector<OutputSpec> outputs;
204 outputs.emplace_back("CPV", "DIGITS", 0, Lifetime::Timeframe);
205 outputs.emplace_back("CPV", "DIGITTRIGREC", 0, Lifetime::Timeframe);
206 if (mctruth) {
207 outputs.emplace_back("CPV", "DIGITSMCTR", 0, Lifetime::Timeframe);
208 }
209 outputs.emplace_back("CPV", "ROMode", 0, Lifetime::Timeframe);
210
211 return DataProcessorSpec{
212 "CPVDigitizer",
213 inputs,
214 outputs,
215 AlgorithmSpec{o2::framework::adaptFromTask<DigitizerSpec>()},
216 Options{{"pileup", VariantType::Int, 1, {"whether to run in continuous time mode"}}}};
217}
218} // namespace cpv
219} // namespace o2
Definition of the base digitizer task class.
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
void printKeyValues(bool showProv=true, bool useLogger=false) const final
CCDB container for bad (masked) channels in CPV.
void run(framework::ProcessingContext &ctx)
run digitizer
void initDigitizerTask(framework::InitContext &ctx) final
init digitizer
void setGains(const CalibParams *gains)
Definition Digitizer.h:40
void setBadChannelMap(const BadChannelMap *bcm)
Definition Digitizer.h:39
void setPedestals(const Pedestals *peds)
Definition Digitizer.h:38
void processHits(const std::vector< Hit > *mHits, const std::vector< Digit > &digitsBg, std::vector< Digit > &digitsOut, o2::dataformats::MCTruthContainer< o2::MCCompLabel > &mLabels, int source, int entry, double dt)
Steer conversion of hits to digits.
Definition Digitizer.cxx:47
static constexpr ID CPV
Definition DetID.h:68
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.
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
DataProcessorSpec getCPVDigitizerSpec(int channel, bool mctruth)
Create new digitizer spec.
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
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"