Project
Loading...
Searching...
No Matches
CellConverterSpec.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#include <gsl/span>
12#include <boost/range/combine.hpp>
13#include <fairlogger/Logger.h>
14
21#include "EMCALBase/Geometry.h"
26
27using namespace o2::emcal::reco_workflow;
28
30{
31 LOG(debug) << "[EMCALCellConverter - init] Initialize converter " << (mPropagateMC ? "with" : "without") << " MC truth container";
32
33 if (!mGeometry) {
35 }
36 if (!mGeometry) {
37 LOG(error) << "Failure accessing geometry";
38 }
39
40 auto fitmethod = ctx.options().get<std::string>("fitmethod");
41 if (fitmethod == "standard") {
42 LOG(info) << "Using standard raw fitter";
43 mRawFitter = std::unique_ptr<o2::emcal::CaloRawFitter>(new o2::emcal::CaloRawFitterStandard);
44 } else if (fitmethod == "gamma2") {
45 LOG(info) << "Using gamma2 raw fitter";
46 mRawFitter = std::unique_ptr<o2::emcal::CaloRawFitter>(new o2::emcal::CaloRawFitterGamma2);
47 }
48 mRawFitter->setAmpCut(0.);
49 mRawFitter->setL1Phase(0.);
50}
51
53{
54 LOG(debug) << "[EMCALCellConverter - run] called";
55
56 mCalibHandler->checkUpdates(ctx);
58
59 double timeshift = RecoParam::Instance().getCellTimeShiftNanoSec(); // subtract offset in ns in order to center the time peak around the nominal delay
60 timeshift = int(timeshift / 100) * 100; // This is a cheat to make the time multiple of 100, since the digitizer takes the delay only as mutiple of 100
61
62 mOutputCells.clear();
63 mOutputLabels.clear();
64 mOutputTriggers.clear();
65 auto digitsAll = ctx.inputs().get<gsl::span<o2::emcal::Digit>>("digits");
66 auto triggers = ctx.inputs().get<gsl::span<o2::emcal::TriggerRecord>>("triggers");
67 std::unique_ptr<const o2::dataformats::MCTruthContainer<o2::emcal::MCLabel>> truthcont = nullptr;
68 if (mPropagateMC) {
70 }
71
72 LOG(debug) << "[EMCALCellConverter - run] Received " << digitsAll.size() << " digits from " << triggers.size() << " trigger ...";
73 int currentstart = mOutputCells.size(), ncellsTrigger = 0;
74 for (const auto& trg : triggers) {
75 if (!trg.getNumberOfObjects()) {
76 mOutputTriggers.emplace_back(trg.getBCData(), trg.getTriggerBits(), currentstart, ncellsTrigger);
77 continue;
78 }
79
80 int bcmod4 = (trg.getBCData().bc + RecoParam::Instance().getPhaseBCmod4()) % 4;
81
82 gsl::span<const o2::emcal::Digit> digits(digitsAll.data() + trg.getFirstEntry(), trg.getNumberOfObjects());
83 std::vector<gsl::span<const o2::emcal::MCLabel>> mcLabels;
84
85 if (mPropagateMC) {
86 for (int digitIndex = trg.getFirstEntry(); digitIndex < (trg.getFirstEntry() + trg.getNumberOfObjects()); digitIndex++) {
87 mcLabels.push_back(truthcont->getLabels(digitIndex));
88 }
89 }
90
91 for (const auto& srucont : digitsToBunches(digits, mcLabels)) {
92
93 if (srucont.mSRUid == 21 || srucont.mSRUid == 22 || srucont.mSRUid == 36 || srucont.mSRUid == 39) {
94 continue;
95 }
96
97 for (const auto& [tower, channelData] : srucont.mChannelsData) {
98
99 // define the conatiner for the fit results, and perform the raw fitting using the stadnard raw fitter
100 ChannelType_t channelType = channelData.mChanType;
101 CaloFitResults fitResults;
102 try {
103 fitResults = mRawFitter->evaluate(channelData.mChannelsBunchesHG);
104
105 // If the high gain bunch is saturated then fit the low gain
106 if (fitResults.getAmp() > o2::emcal::constants::OVERFLOWCUT) {
107 fitResults = mRawFitter->evaluate(channelData.mChannelsBunchesLG);
108 fitResults.setAmp(fitResults.getAmp() * o2::emcal::constants::EMCAL_HGLGFACTOR);
109 channelType = ChannelType_t::LOW_GAIN;
110 } else {
111 channelType = ChannelType_t::HIGH_GAIN;
112 }
113
114 if (fitResults.getAmp() < 0) {
115 fitResults.setAmp(0.);
116 }
117 if (fitResults.getTime() < 0) {
118 fitResults.setTime(0.);
119 }
120 mOutputCells.emplace_back(tower, fitResults.getAmp() * o2::emcal::constants::EMCAL_ADCENERGY, fitResults.getTime() - timeshift - 25 * bcmod4, channelType);
121
122 if (mPropagateMC) {
123 Int_t LabelIndex = mOutputLabels.getIndexedSize();
124 if (channelType == ChannelType_t::HIGH_GAIN) {
125 // if this channel has no bunches, then fill an empty label
126 if (channelData.mChannelLabelsHG.size() == 0) {
128 mOutputLabels.addElementRandomAccess(LabelIndex, label);
129 } else {
130 // Fill only labels that corresponds to bunches with maximum ADC
131 const int bunchindex = selectMaximumBunch(channelData.mChannelsBunchesHG);
132 for (const auto& label : channelData.mChannelLabelsHG[bunchindex]) {
133 mOutputLabels.addElementRandomAccess(LabelIndex, label);
134 }
135 }
136 } else {
137 // if this channel has no bunches, then fill an empty label
138 if (channelData.mChannelLabelsLG.size() == 0) {
140 mOutputLabels.addElementRandomAccess(LabelIndex, label);
141 } else {
142 // Fill only labels that corresponds to bunches with maximum ADC
143 const int bunchindex = selectMaximumBunch(channelData.mChannelsBunchesLG);
144 for (const auto& label : channelData.mChannelLabelsLG[bunchindex]) {
145 mOutputLabels.addElementRandomAccess(LabelIndex, label);
146 }
147 }
148 }
149 }
150 ncellsTrigger++;
151
152 } catch (CaloRawFitter::RawFitterError_t& fiterror) {
154 LOG(error) << "Failure in raw fitting: " << CaloRawFitter::createErrorMessage(fiterror);
155 }
156 }
157 }
158 }
159 mOutputTriggers.emplace_back(trg.getBCData(), trg.getTriggerBits(), currentstart, ncellsTrigger);
160 currentstart = mOutputCells.size();
161 ncellsTrigger = 0;
162 }
163 LOG(debug) << "[EMCALCellConverter - run] Writing " << mOutputCells.size() << " cells ...";
164 ctx.outputs().snapshot(o2::framework::Output{"EMC", "CELLS", mSubspecificationOut}, mOutputCells);
165 ctx.outputs().snapshot(o2::framework::Output{"EMC", "CELLSTRGR", mSubspecificationOut}, mOutputTriggers);
166 if (mPropagateMC) {
167 ctx.outputs().snapshot(o2::framework::Output{"EMC", "CELLSMCTR", mSubspecificationOut}, mOutputLabels);
168 }
169}
170
172{
173 if (mCalibHandler->finalizeCCDB(matcher, obj)) {
174 return;
175 }
176}
177
179{
180 if (mCalibHandler->hasUpdateRecoParam()) {
181 LOG(info) << "RecoParams updated";
182 o2::emcal::RecoParam::Instance().printKeyValues(true, true);
183 }
184}
185
186std::vector<o2::emcal::SRUBunchContainer> CellConverterSpec::digitsToBunches(gsl::span<const o2::emcal::Digit> digits, std::vector<gsl::span<const o2::emcal::MCLabel>>& mcLabels)
187{
188
189 std::vector<o2::emcal::SRUBunchContainer> sruBunchContainer;
190 std::vector<o2::emcal::DigitContainerPerSRU> sruDigitContainer;
191
192 for (auto iddl = 0; iddl < 40; iddl++) {
193 o2::emcal::SRUBunchContainer srucontBunch;
194 srucontBunch.mSRUid = iddl;
195 sruBunchContainer.push_back(srucontBunch);
196
198 srucontDigits.mSRUid = iddl;
199 sruDigitContainer.push_back(srucontDigits);
200 }
201
202 std::vector<const o2::emcal::Digit*>* bunchDigits;
203 std::vector<gsl::span<const o2::emcal::MCLabel>>* bunchLabels;
204 int lasttower = -1;
205 // for (auto& dig : digits) {
206
207 if (!mPropagateMC) {
208 for (const auto& dig : digits) {
209 auto tower = dig.getTower();
210 if (tower != lasttower) {
211 lasttower = tower;
212 if (tower > 20000) {
213 std::cout << "Wrong cell ID " << tower << std::endl;
214 }
215
216 auto onlineindices = mGeometry->getOnlineID(tower);
217 int sruID = std::get<0>(onlineindices);
218
219 auto towerdata = sruDigitContainer[sruID].mChannelsDigits.find(tower);
220 if (towerdata == sruDigitContainer[sruID].mChannelsDigits.end()) {
221 sruDigitContainer[sruID].mChannelsDigits[tower] = {dig.getType(), std::vector<const o2::emcal::Digit*>(o2::emcal::constants::EMCAL_MAXTIMEBINS), std::vector<gsl::span<const o2::emcal::MCLabel>>()};
222 bunchDigits = &(sruDigitContainer[sruID].mChannelsDigits[tower].mChannelDigits);
223 memset(bunchDigits->data(), 0, sizeof(o2::emcal::Digit*) * o2::emcal::constants::EMCAL_MAXTIMEBINS);
224 } else {
225 bunchDigits = &(towerdata->second.mChannelDigits);
226 }
227 }
228
229 // Get time sample of the digit:
230 // Digitizer stores the time sample in ns, needs to be converted to time sample dividing
231 // by the length of the time sample
232 auto timesample = int(dig.getTimeStamp() / emcal::constants::EMCAL_TIMESAMPLE);
233 if (timesample >= o2::emcal::constants::EMCAL_MAXTIMEBINS) {
234 LOG(error) << "Digit time sample " << timesample << " outside range [0," << o2::emcal::constants::EMCAL_MAXTIMEBINS << "]";
235 continue;
236 }
237 (*bunchDigits)[timesample] = &dig;
238 }
239 } else {
240
241 for (const auto& [dig, labels] : boost::combine(digits, mcLabels)) {
242 auto tower = dig.getTower();
243 if (tower != lasttower) {
244 lasttower = tower;
245 if (tower > 20000) {
246 std::cout << "Wrong cell ID " << tower << std::endl;
247 }
248
249 auto onlineindices = mGeometry->getOnlineID(tower);
250 int sruID = std::get<0>(onlineindices);
251
252 auto towerdata = sruDigitContainer[sruID].mChannelsDigits.find(tower);
253 if (towerdata == sruDigitContainer[sruID].mChannelsDigits.end()) {
254 sruDigitContainer[sruID].mChannelsDigits[tower] = {dig.getType(), std::vector<const o2::emcal::Digit*>(o2::emcal::constants::EMCAL_MAXTIMEBINS), mPropagateMC ? std::vector<gsl::span<const o2::emcal::MCLabel>>(o2::emcal::constants::EMCAL_MAXTIMEBINS) : std::vector<gsl::span<const o2::emcal::MCLabel>>()};
255 bunchDigits = &(sruDigitContainer[sruID].mChannelsDigits[tower].mChannelDigits);
256 memset(bunchDigits->data(), 0, sizeof(o2::emcal::Digit*) * o2::emcal::constants::EMCAL_MAXTIMEBINS);
257 if (mPropagateMC) {
258 bunchLabels = &(sruDigitContainer[sruID].mChannelsDigits[tower].mChannelLabels);
259 memset(bunchLabels->data(), 0, sizeof(gsl::span<const o2::emcal::MCLabel>) * o2::emcal::constants::EMCAL_MAXTIMEBINS);
260 }
261 } else {
262 bunchDigits = &(towerdata->second.mChannelDigits);
263 if (mPropagateMC) {
264 bunchLabels = &(towerdata->second.mChannelLabels);
265 }
266 }
267 }
268
269 // Get time sample of the digit:
270 // Digitizer stores the time sample in ns, needs to be converted to time sample dividing
271 // by the length of the time sample
272 auto timesample = int(dig.getTimeStamp() / emcal::constants::EMCAL_TIMESAMPLE);
273 if (timesample >= o2::emcal::constants::EMCAL_MAXTIMEBINS) {
274 LOG(error) << "Digit time sample " << timesample << " outside range [0," << o2::emcal::constants::EMCAL_MAXTIMEBINS << "]";
275 continue;
276 }
277 (*bunchDigits)[timesample] = &dig;
278 if (mPropagateMC) {
279 (*bunchLabels)[timesample] = labels;
280 }
281 }
282 }
283
284 for (auto srucont : sruDigitContainer) {
285
286 if (srucont.mSRUid == 21 || srucont.mSRUid == 22 || srucont.mSRUid == 36 || srucont.mSRUid == 39) {
287 continue;
288 }
289
290 for (const auto& [tower, channelDigits] : srucont.mChannelsDigits) {
291
292 std::vector<o2::emcal::Bunch> rawbunchesHG;
293 std::vector<o2::emcal::Bunch> rawbunchesLG;
294 std::vector<std::vector<o2::emcal::MCLabel>> rawLabelsHG;
295 std::vector<std::vector<o2::emcal::MCLabel>> rawLabelsLG;
296
297 bool saturatedBunch = false;
298
299 // Creating the high gain bunch with labels
300 for (auto& bunch : findBunches(channelDigits.mChannelDigits, channelDigits.mChannelLabels, ChannelType_t::HIGH_GAIN)) {
301 rawbunchesHG.emplace_back(bunch.mADCs.size(), bunch.mStarttime);
302 for (auto adc : bunch.mADCs) {
303 rawbunchesHG.back().addADC(adc);
304 if (adc > o2::emcal::constants::LG_SUPPRESSION_CUT) {
305 saturatedBunch = true;
306 }
307 }
308 if (mPropagateMC) {
309 rawLabelsHG.push_back(bunch.mLabels);
310 }
311 }
312
313 // Creating the low gain bunch with labels if the HG bunch is saturated
314 if (saturatedBunch) {
315 for (auto& bunch : findBunches(channelDigits.mChannelDigits, channelDigits.mChannelLabels, ChannelType_t::LOW_GAIN)) {
316 rawbunchesLG.emplace_back(bunch.mADCs.size(), bunch.mStarttime);
317 for (auto adc : bunch.mADCs) {
318 rawbunchesLG.back().addADC(adc);
319 }
320 if (mPropagateMC) {
321 rawLabelsLG.push_back(bunch.mLabels);
322 }
323 }
324 }
325
326 sruBunchContainer[srucont.mSRUid].mChannelsData[tower] = {channelDigits.mChanType, rawbunchesHG, rawbunchesLG, rawLabelsHG, rawLabelsLG};
327 }
328 }
329
330 return sruBunchContainer;
331}
332
333std::vector<o2::emcal::AltroBunch> CellConverterSpec::findBunches(const std::vector<const o2::emcal::Digit*>& channelDigits, const std::vector<gsl::span<const o2::emcal::MCLabel>>& mcLabels, ChannelType_t channelType)
334{
335 std::vector<AltroBunch> result;
336 AltroBunch currentBunch;
337 bool bunchStarted = false;
338 // Digits in ALTRO bunch in time-reversed order
339 int itime;
340 for (itime = channelDigits.size() - 1; itime >= 0; itime--) {
341 auto dig = channelDigits[itime];
342 gsl::span<const o2::emcal::MCLabel> labels;
343 if (mPropagateMC) {
344 labels = mcLabels[itime];
345 }
346 if (!dig) {
347 if (bunchStarted) {
348 // we have a bunch which is started and needs to be closed
349 // check if the ALTRO bunch has a minimum amount of 3 ADCs
350 if (currentBunch.mADCs.size() >= 3) {
351 // Bunch selected, set start time and push to bunches
352 result.push_back(currentBunch);
353 currentBunch = AltroBunch();
354 bunchStarted = false;
355 }
356 }
357 continue;
358 }
359 int adc = dig->getAmplitudeADC(channelType);
360 if (adc < 3) {
361 // ADC value below threshold
362 // in case we have an open bunch it needs to be stopped bunch
363 // Set the start time to the time sample of previous (passing) digit
364 if (bunchStarted) {
365 // check if the ALTRO bunch has a minimum amount of ADCs
366 if (currentBunch.mADCs.size() >= 3) {
367 // Bunch selected, set start time and push to bunches
368 result.push_back(currentBunch);
369 currentBunch = AltroBunch();
370 bunchStarted = false;
371 }
372 }
373 }
374 // Valid ADC value, if the bunch is closed we start a new bunch
375 if (!bunchStarted) {
376 bunchStarted = true;
377 currentBunch.mStarttime = itime;
378 }
379 currentBunch.mADCs.emplace_back(adc);
380 if (mPropagateMC) {
381 std::vector<o2::emcal::MCLabel> vectorLabels;
382 for (auto& label : labels) {
383 vectorLabels.push_back(label);
384 }
385 currentBunch.mEnergyLabels.insert(std::pair<int, std::vector<o2::emcal::MCLabel>>(adc, vectorLabels));
386 }
387 }
388 // if we have a last bunch set time start time to the time bin of teh previous digit
389 if (bunchStarted) {
390 if (currentBunch.mADCs.size() >= 3) {
391 result.push_back(currentBunch);
392 }
393 }
394
395 if (mPropagateMC) {
397 }
398 return result;
399}
400
401void CellConverterSpec::mergeLabels(std::vector<o2::emcal::AltroBunch>& channelBunches)
402{
403 for (auto& altroBunch : channelBunches) {
404 std::vector<o2::emcal::MCLabel> mcLabels;
405 std::map<uint64_t, std::vector<o2::emcal::MCLabel>> LabelsPerSource;
406 double totalEnergy = 0;
407 for (auto& [energy, Labels] : altroBunch.mEnergyLabels) {
408 for (auto& trueLabel : Labels) {
409 o2::emcal::MCLabel newLabel = trueLabel;
410 newLabel.setAmplitudeFraction(trueLabel.getAmplitudeFraction() * energy);
411 LabelsPerSource[newLabel.getRawValue()].push_back(newLabel);
412 }
413 totalEnergy += energy;
414 }
415
416 for (auto& [trackID, labels] : LabelsPerSource) {
417 o2::emcal::MCLabel newLabel = labels[0];
418 for (int ilabel = 0; ilabel < labels.size(); ilabel++) {
419 auto& trueLabel = labels[ilabel];
420 if (ilabel == 0) {
421 continue;
422 }
423 newLabel.setAmplitudeFraction(newLabel.getAmplitudeFraction() + trueLabel.getAmplitudeFraction());
424 }
425 newLabel.setAmplitudeFraction(newLabel.getAmplitudeFraction() / totalEnergy);
426 mcLabels.push_back(newLabel);
427 }
428
429 std::sort(mcLabels.begin(), mcLabels.end(), [](o2::emcal::MCLabel label1, o2::emcal::MCLabel label2) { return label1.getAmplitudeFraction() > label2.getAmplitudeFraction(); });
430
431 altroBunch.mLabels = mcLabels;
432 // std::copy(mcLabels.begin(), mcLabels.end(), std::back_inserter(altroBunch.mLabels));
433 // altroBunch.mLabels = gsl::span<o2::emcal::MCLabel>(&mcLabels[0], mcLabels.size());
434 altroBunch.mEnergyLabels.clear();
435 }
436}
437
438int CellConverterSpec::selectMaximumBunch(const gsl::span<const Bunch>& bunchvector)
439{
440 int bunchindex = -1;
441 int indexMaxInBunch(0), maxADCallBunches(-1);
442
443 for (unsigned int i = 0; i < bunchvector.size(); i++) {
444 auto [maxADC, maxIndex] = mRawFitter->getMaxAmplitudeBunch(bunchvector[i]); // CRAP PTH, bug fix, trouble if more than one bunches
445 if (mRawFitter->isInTimeRange(maxIndex, mRawFitter->getMaxTimeIndex(), mRawFitter->getMinTimeIndex())) {
446 if (maxADC > maxADCallBunches) {
447 bunchindex = i;
448 indexMaxInBunch = maxIndex;
449 maxADCallBunches = maxADC;
450 }
451 }
452 }
453
454 return bunchindex;
455}
456
457o2::framework::DataProcessorSpec o2::emcal::reco_workflow::getCellConverterSpec(bool propagateMC, int inputSubspec, int outputSubspec)
458{
459 std::vector<o2::framework::InputSpec> inputs;
460 std::vector<o2::framework::OutputSpec> outputs;
461 inputs.emplace_back("digits", o2::header::gDataOriginEMC, "DIGITS", inputSubspec, o2::framework::Lifetime::Timeframe);
462 inputs.emplace_back("triggers", "EMC", "DIGITSTRGR", inputSubspec, o2::framework::Lifetime::Timeframe);
463 outputs.emplace_back("EMC", "CELLS", outputSubspec, o2::framework::Lifetime::Timeframe);
464 outputs.emplace_back("EMC", "CELLSTRGR", outputSubspec, o2::framework::Lifetime::Timeframe);
465 if (propagateMC) {
466 inputs.emplace_back("digitsmctr", "EMC", "DIGITSMCTR", inputSubspec, o2::framework::Lifetime::Timeframe);
467 outputs.emplace_back("EMC", "CELLSMCTR", outputSubspec, o2::framework::Lifetime::Timeframe);
468 }
469 auto calibhandler = std::make_shared<o2::emcal::CalibLoader>();
470 calibhandler->enableRecoParams(true);
471 calibhandler->defineInputSpecs(inputs);
472 return o2::framework::DataProcessorSpec{"EMCALCellConverterSpec",
473 inputs,
474 outputs,
475 o2::framework::adaptFromTask<o2::emcal::reco_workflow::CellConverterSpec>(propagateMC, inputSubspec, outputSubspec, calibhandler),
477 {"fitmethod", o2::framework::VariantType::String, "gamma2", {"Fit method (standard or gamma2)"}}}};
478}
int32_t i
Definition of a container to keep Monte Carlo truth external to simulation objects.
std::ostringstream debug
uint64_t getRawValue() const
Definition MCCompLabel.h:95
A container to hold and manage MC truth information/labels.
void addElementRandomAccess(uint32_t dataindex, TruthElement const &element)
Container class to hold results from fitting.
Raw data fitting: Gamma-2 function.
Raw data fitting: standard TMinuit fit.
RawFitterError_t
Error codes for failures in raw fitter procedure.
static std::string createErrorMessage(RawFitterError_t fiterror)
Create error message for a given error type.
EMCAL digit implementation.
Definition Digit.h:34
static Geometry * GetInstanceFromRunNumber(Int_t runNumber, const std::string_view="", const std::string_view mcname="TGeant3", const std::string_view mctitle="")
Instanciate geometry depending on the run number. Mostly used in analysis and MC anchors.
Definition Geometry.cxx:219
std::tuple< int, int, int > getOnlineID(int towerID)
Get link ID, row and column from cell ID, have a look here: https://alice.its.cern....
Monte-Carlo label for EMCAL clusters / digits.
Definition MCLabel.h:28
Double_t getAmplitudeFraction() const
Definition MCLabel.h:37
void setAmplitudeFraction(Double_t afraction)
Definition MCLabel.h:36
std::vector< AltroBunch > findBunches(const std::vector< const o2::emcal::Digit * > &channelDigits, const std::vector< gsl::span< const o2::emcal::MCLabel > > &mcLabels, ChannelType_t channelType)
void init(framework::InitContext &ctx) final
Initializing the CellConverterSpec.
void updateCalibrationObjects()
Update calibration objects.
int selectMaximumBunch(const gsl::span< const Bunch > &bunchvector)
void mergeLabels(std::vector< o2::emcal::AltroBunch > &channelBunches)
std::vector< o2::emcal::SRUBunchContainer > digitsToBunches(gsl::span< const o2::emcal::Digit > digits, std::vector< gsl::span< const o2::emcal::MCLabel > > &mcLabels)
void run(framework::ProcessingContext &ctx) final
Run conversion of digits to cells.
void finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj) final
void snapshot(const Output &spec, T const &object)
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.
GLuint64EXT * result
Definition glcorearb.h:5662
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
framework::DataProcessorSpec getCellConverterSpec(bool propagateMC, int inputSubsepc=0, int outputSubspec=0)
Creating DataProcessorSpec for the EMCAL Cell Converter Spec.
constexpr o2::header::DataOrigin gDataOriginEMC
Definition DataHeader.h:565
ChannelType_t
Type of a raw data channel.
Definition Constants.h:33
@ HIGH_GAIN
High gain channel.
Definition Constants.h:35
@ LOW_GAIN
Low gain channel.
Definition Constants.h:34
std::vector< ConfigParamSpec > Options
ALTRO bunch information obtained from digits.
Definition AltroHelper.h:31
std::vector< int > mADCs
ADCs belonging to the bunch.
Definition AltroHelper.h:33
std::multimap< int, std::vector< o2::emcal::MCLabel > > mEnergyLabels
Definition AltroHelper.h:34
int mStarttime
Start time of the bunch.
Definition AltroHelper.h:32
Structure for organizing digits within the SRU and preserves the digit type.
Definition AltroHelper.h:63
Structure for organizing Bunches within the SRU.
Definition AltroHelper.h:78
int mSRUid
DDL of the SRU.
Definition AltroHelper.h:79
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits
ArrayADC adc