Project
Loading...
Searching...
No Matches
Digitizer.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 <TRandom.h>
13#include <cmath>
14#include <numeric>
17#include "FV0Base/Geometry.h"
18#include "FV0Base/Constants.h"
19#include "TF1Convolution.h"
20
22
23using namespace o2::math_utils;
24using namespace o2::fv0;
25
27{
28 mEventId = -1;
29 mSrcId = -1;
30 for (auto& analogSignal : mPmtChargeVsTime) {
31 std::fill_n(std::begin(analogSignal), analogSignal.size(), 0);
32 }
33 mLastBCCache.clear();
34 mCfdStartIndex.fill(0);
35}
36
37//_______________________________________________________________________
39{
40 LOG(info) << "init";
41 mNBins = FV0DigParam::Instance().waveformNbins; //Will be computed using detector set-up from CDB
42 mBinSize = FV0DigParam::Instance().waveformBinWidth; //Will be set-up from CDB
43 mNTimeBinsPerBC = std::lround(o2::constants::lhc::LHCBunchSpacingNS / mBinSize); // 1920 bins/BC
44
45 for (Int_t detID = 0; detID < Constants::nFv0Channels; detID++) {
46 mPmtChargeVsTime[detID].resize(mNBins);
47 mLastBCCache.mPmtChargeVsTime[detID].resize(mNBins);
48 }
49
51 TF1Convolution convolutionRingA1ToA4("expo", "landau", 5.e-09, 90.e-09, false);
52 TF1 convolutionRingA1ToA4Fn("convolutionFn", convolutionRingA1ToA4, 5.e-09, 90.e-09, convolutionRingA1ToA4.GetNpar());
53 convolutionRingA1ToA4Fn.SetParameters(FV0DigParam::Instance().constRingA1ToA4, FV0DigParam::Instance().slopeRingA1ToA4,
54 FV0DigParam::Instance().mpvRingA1ToA4, FV0DigParam::Instance().sigmaRingA1ToA4);
55
57 TF1Convolution convolutionRing5("expo", "landau", 5.e-09, 90.e-09, false);
58 TF1 convolutionRing5Fn("convolutionFn", convolutionRing5, 5.e-09, 90.e-09, convolutionRing5.GetNpar());
59 convolutionRing5Fn.SetParameters(FV0DigParam::Instance().constRing5, FV0DigParam::Instance().slopeRing5,
60 FV0DigParam::Instance().mpvRing5, FV0DigParam::Instance().sigmaRing5);
62 mPmtResponseGlobalRingA1ToA4.resize(mNBins);
63 const float binSizeInNs = mBinSize * 1.e-09; // to convert ns into sec
64 double x = (binSizeInNs) / 2.0;
65 for (auto& y : mPmtResponseGlobalRingA1ToA4) {
66 y = FV0DigParam::Instance().getNormRingA1ToA4() // normalisation to have MIP adc at 16
67 * convolutionRingA1ToA4Fn.Eval(x + FV0DigParam::Instance().offsetRingA1ToA4); // offset to adjust mean position of waveform
68 x += binSizeInNs;
69 }
71 mPmtResponseGlobalRing5.resize(mNBins);
72 x = (binSizeInNs) / 2.0;
73 for (auto& y : mPmtResponseGlobalRing5) {
74 y = FV0DigParam::Instance().getNormRing5() // normalisation to have MIP adc at 16
75 * convolutionRing5Fn.Eval(x + FV0DigParam::Instance().offsetRing5); // offset to adjust mean position of waveform
76 x += binSizeInNs;
77 }
78 mLastBCCache.clear();
79 mCfdStartIndex.fill(0);
80 LOG(info) << "init -> finished";
81}
82
83void Digitizer::process(const std::vector<o2::fv0::Hit>& hits,
84 std::vector<o2::fv0::Digit>& digitsBC,
85 std::vector<o2::fv0::ChannelData>& digitsCh,
86 std::vector<o2::fv0::DetTrigInput>& digitsTrig,
88{
89 LOG(debug) << "Begin with " << hits.size() << " hits";
90 flush(digitsBC, digitsCh, digitsTrig, labels); // flush cached signal which cannot be affect by new event
91
92 std::vector<int> hitIdx(hits.size());
93 std::iota(std::begin(hitIdx), std::end(hitIdx), 0);
94 std::sort(std::begin(hitIdx), std::end(hitIdx),
95 [&hits](int a, int b) { return hits[a].GetTrackID() < hits[b].GetTrackID(); });
96
97 // use ordered hits
98 for (auto ids : hitIdx) {
99 const auto& hit = hits[ids];
100 Int_t detId = hit.GetDetectorID();
101 Double_t hitEdep = hit.GetHitValue() * 1e3; // convert to MeV
102 Float_t const hitTime = hit.GetTime() * 1e9; // convert to ns
103 // TODO: check how big is inaccuracy if more than 1 'below-threshold' particles hit the same detector cell
105 continue;
106 }
107 float distanceFromXc = 0;
108 if (Geometry::instance()->isRing5(detId)) {
109 distanceFromXc = getDistFromCellCenter(detId, hit.GetX(), hit.GetY());
110 }
111
112 int iChannelPerCell = 0;
113 while (iChannelPerCell < 2) { // loop over 2 channels, into which signal from each cell in ring 5 is split
114 if (Geometry::instance()->isRing5(detId)) {
115 // The first channel number is located counter-clockwise from the cell center
116 // and remains identical to the detector number, the second one is clockwise and incremented by 8
117 if (iChannelPerCell == 1) {
118 detId += 8;
119 }
120 // Split signal magnitude to fractions depending on the distance of the hit from the cell center
121 hitEdep = (hit.GetHitValue() * 1e3) * getSignalFraction(distanceFromXc, iChannelPerCell == 0);
122 // LOG(info) << " detId: " << detId << "-" << iChannelPerCell << " hitEdep: " << hitEdep << " distanceFromXc: " << distanceFromXc;
123 ++iChannelPerCell;
124 } else {
125 iChannelPerCell = 2; // not a ring 5 cell -> don't repeat the loop
126 }
127 Double_t const nPhotons = hitEdep * DP::N_PHOTONS_PER_MEV;
128 float const nPhE = SimulateLightYield(detId, nPhotons);
129 float const mipFraction = float(nPhE / FV0DigParam::Instance().avgNumberPhElectronPerMip);
130 Long64_t timeHit = hitTime;
131 timeHit += mIntRecord.getTimeNS();
132 o2::InteractionTimeRecord const irHit(timeHit);
133 std::array<o2::InteractionRecord, NBC2Cache> cachedIR;
134 int nCachedIR = 0;
135 for (int i = BCCacheMin; i < BCCacheMax + 1; i++) {
136 double const tNS = timeHit + o2::constants::lhc::LHCBunchSpacingNS * i;
137 cachedIR[nCachedIR].setFromNS(tNS);
138 if (tNS < 0 && cachedIR[nCachedIR] > irHit) {
139 continue; // don't go to negative BC/orbit (it will wrap)
140 }
141 // ensure existence of cached container
142 setBCCache(cachedIR[nCachedIR++]);
143 } // BCCache loop
144
145 createPulse(mipFraction, hit.GetTrackID(), hitTime, hit.GetPos().R(), cachedIR, nCachedIR, detId);
146
147 } //while loop
148 } //hitloop
149}
150
151void Digitizer::createPulse(float mipFraction, int parID, const double hitTime, const float hitR,
152 std::array<o2::InteractionRecord, NBC2Cache> const& cachedIR, int nCachedIR, const int detId)
153{
154
155 std::array<bool, NBC2Cache> added;
156 added.fill(false);
157
158 for (int ir = 0; ir < NBC2Cache; ir++) {
159 auto bcCache = getBCCache(cachedIR[ir]);
160 for (int ich = 0; ich < Constants::nFv0Channels; ich++) {
161 (*bcCache).mPmtChargeVsTime[ich].resize(mNTimeBinsPerBC);
162 }
163 }
164
165 // Subtract time-of-flight from hit time
166 const float timeOfFlight = hitR / o2::constants::physics::LightSpeedCm2NS;
167 Int_t const NBinShift = std::lround((hitTime - timeOfFlight + FV0DigParam::Instance().hitTimeOffset) / FV0DigParam::Instance().waveformBinWidth);
168
169 if (NBinShift >= 0 && NBinShift < FV0DigParam::Instance().waveformNbins) {
170 mPmtResponseTemp.resize(FV0DigParam::Instance().waveformNbins, 0.);
171 if (isRing5(detId)) {
172 std::memcpy(&mPmtResponseTemp[NBinShift], &mPmtResponseGlobalRing5[0],
173 sizeof(double) * (FV0DigParam::Instance().waveformNbins - NBinShift));
174 } else {
175 std::memcpy(&mPmtResponseTemp[NBinShift], &mPmtResponseGlobalRingA1ToA4[0],
176 sizeof(double) * (FV0DigParam::Instance().waveformNbins - NBinShift));
177 }
178 } else {
179 if (isRing5(detId)) {
180 mPmtResponseTemp = mPmtResponseGlobalRing5;
181 mPmtResponseTemp.erase(mPmtResponseTemp.begin(), mPmtResponseTemp.begin() + abs(NBinShift));
182 } else {
183 mPmtResponseTemp = mPmtResponseGlobalRingA1ToA4;
184 mPmtResponseTemp.erase(mPmtResponseTemp.begin(), mPmtResponseTemp.begin() + abs(NBinShift));
185 }
186
187 mPmtResponseTemp.resize(FV0DigParam::Instance().waveformNbins);
188 }
189
190 for (int ir = 0; ir < int(mPmtResponseTemp.size() / mNTimeBinsPerBC); ir++) {
191 auto bcCache = getBCCache(cachedIR[ir]);
192
193 for (int iBin = 0; iBin < mNTimeBinsPerBC; iBin++) {
194 (*bcCache).mPmtChargeVsTime[detId][iBin] += (mPmtResponseTemp[ir * mNTimeBinsPerBC + iBin] * mipFraction);
195 }
196 added[ir] = true;
197 }
199 for (int ir = 0; ir < nCachedIR; ir++) {
200 if (added[ir]) {
201 auto bcCache = getBCCache(cachedIR[ir]);
202 (*bcCache).labels.emplace_back(parID, mEventId, mSrcId, detId);
203 }
204 }
205}
206
207void Digitizer::flush(std::vector<o2::fv0::Digit>& digitsBC,
208 std::vector<o2::fv0::ChannelData>& digitsCh,
209 std::vector<o2::fv0::DetTrigInput>& digitsTrig,
211{
212 ++mEventId;
213 while (!mCache.empty()) {
214 auto const& bc = mCache.front();
215 if (mIntRecord.differenceInBC(bc) > NBC2Cache) { // Build events that are separated by NBC2Cache BCs from current BC
216 storeBC(bc, digitsBC, digitsCh, digitsTrig, labels);
217 mCache.pop_front();
218 } else {
219 return;
220 }
221 }
222}
223
224void Digitizer::storeBC(const BCCache& bc,
225 std::vector<o2::fv0::Digit>& digitsBC,
226 std::vector<o2::fv0::ChannelData>& digitsCh,
227 std::vector<o2::fv0::DetTrigInput>& digitsTrig,
229
230{
231 size_t const nBC = digitsBC.size(); // save before digitsBC is being modified
232 size_t const first = digitsCh.size(); // save before digitsCh is being modified
233 int8_t nTotFiredCells = 0;
234 int8_t nTrgFiredCells = 0; // number of fired cells, that follow additional trigger conditions (time gate)
235 int totalChargeAllRing = 0;
236 int32_t avgTime = 0;
237 double nSignalInner = 0;
238 double nSignalOuter = 0;
239
240 if (mLastBCCache.differenceInBC(bc) != 1) { // if the last buffered BC is not the one before the current BC
241 mLastBCCache.clear(); // clear the bufffer (mPmtChargeVsTime set to 0s)
242 mCfdStartIndex.fill(0); // reset all start indices to 0, i.e., to the beginning of the BC
243 }
244
245 for (int iPmt = 0; iPmt < Constants::nFv0Channels; iPmt++) {
246 // run the CFD: this updates the start index for the next BC in case the CFD dead time ends in the next BC
247 double cfdWithOffset = SimulateTimeCfd(mCfdStartIndex[iPmt], mLastBCCache.mPmtChargeVsTime[iPmt], bc.mPmtChargeVsTime[iPmt]);
248 double cfdZero = cfdWithOffset - FV0DigParam::Instance().avgCfdTimeForMip;
249
250 // Conditions to sum charge are: all participating channels must have time within +/- 2.5 ns, AND
251 // at least one channel must follow more strict conditions (see below)
252 if (cfdZero < -FV0DigParam::Instance().cfdCheckWindow || cfdZero > FV0DigParam::Instance().cfdCheckWindow) {
253 continue;
254 }
255
256 int iTotalCharge = std::lround(IntegrateCharge(bc.mPmtChargeVsTime[iPmt]) * DP::INV_CHARGE_PER_ADC); // convert Coulomb to adc;
257
258 uint8_t channelBits = FV0DigParam::Instance().defaultChainQtc;
259 if (std::rand() % 2) {
261 }
262 if (iTotalCharge > (FV0DigParam::Instance().maxCountInAdc) && FV0DigParam::Instance().useMaxChInAdc) {
263 iTotalCharge = FV0DigParam::Instance().maxCountInAdc; // max adc channel for one PMT
265 }
266
267 if (iTotalCharge < FV0DigParam::Instance().getCFDTrshInAdc()) {
268 continue;
269 }
270
271 int iCfdZero = std::lround(cfdZero * DP::INV_TIME_PER_TDCCHANNEL);
272 digitsCh.emplace_back(iPmt, iCfdZero, iTotalCharge, channelBits);
273 ++nTotFiredCells;
274
275 int triggerGate = FV0DigParam::Instance().mTime_trg_gate;
276 if (std::abs(iCfdZero) < triggerGate) {
277 ++nTrgFiredCells;
278 //---trigger---
279 totalChargeAllRing += iTotalCharge;
280 avgTime += iCfdZero;
281 if (iPmt < 24) {
282 nSignalInner++;
283 } else {
284 nSignalOuter++;
285 }
286 }
287 }
288 // save BC information for the CFD detector
289 mLastBCCache = bc;
290 if (nTotFiredCells < 1) {
291 return;
292 }
293 if (nTrgFiredCells > 0) {
294 avgTime /= nTrgFiredCells;
295 } else {
297 }
299 bool isA, isAIn, isAOut, isCen, isSCen;
300 isA = nTrgFiredCells > 0;
301 isAIn = nSignalInner > 0; // ring 1,2 and 3
302 isAOut = nSignalOuter > 0; // ring 4 and 5
303 isCen = totalChargeAllRing > FV0DigParam::Instance().adcChargeCenThr;
304 isSCen = totalChargeAllRing > FV0DigParam::Instance().adcChargeSCenThr;
305
306 Triggers triggers;
307 const int unusedCharge = o2::fit::Triggers::DEFAULT_AMP;
308 const int unusedTime = o2::fit::Triggers::DEFAULT_TIME;
309 const int unusedZero = o2::fit::Triggers::DEFAULT_ZERO;
310 const bool unusedBitsInSim = false; // bits related to laser and data validity
311 const bool bitDataIsValid = true;
312 triggers.setTriggers(isA, isAIn, isAOut, isCen, isSCen, nTrgFiredCells, (int8_t)unusedZero,
313 (int32_t)(0.125 * totalChargeAllRing), (int32_t)unusedCharge, (int16_t)avgTime, (int16_t)unusedTime, unusedBitsInSim, unusedBitsInSim, bitDataIsValid);
314 digitsBC.emplace_back(first, nTotFiredCells, bc, triggers, mEventId - 1);
315 digitsTrig.emplace_back(bc, isA, isAIn, isAOut, isCen, isSCen);
316 for (auto const& lbl : bc.labels) {
317 labels.addElement(nBC, lbl);
318 }
319}
320
321// -------------------------------------------------------------------------------
322// --- Internal helper methods related to conversion of energy-deposition into ---
323// --- photons -> photoelectrons -> electrical signal ---
324// -------------------------------------------------------------------------------
325Int_t Digitizer::SimulateLightYield(Int_t pmt, Int_t nPhot) const
326{
327 const Float_t epsilon = 0.0001f;
329 if ((fabs(1.0f - p) < epsilon) || nPhot == 0) {
330 return nPhot;
331 }
332 const Int_t n = Int_t(nPhot < 100
333 ? gRandom->Binomial(nPhot, p)
334 : gRandom->Gaus((p * nPhot) + 0.5, TMath::Sqrt(p * (1. - p) * nPhot)));
335 return n;
336}
337//---------------------------------------------------------------------------
338Float_t Digitizer::IntegrateCharge(const ChannelDigitF& pulse) const
339{
340 int const chargeIntMin = FV0DigParam::Instance().isIntegrateFull ? 0 : (FV0DigParam::Instance().avgCfdTimeForMip - 6.0) / mBinSize; //Charge integration offset (cfd mean time - 6 ns)
341 int const chargeIntMax = FV0DigParam::Instance().isIntegrateFull ? mNTimeBinsPerBC : (FV0DigParam::Instance().avgCfdTimeForMip + 14.0) / mBinSize; //Charge integration offset (cfd mean time + 14 ns)
342 if (chargeIntMin < 0 || chargeIntMin > mNTimeBinsPerBC || chargeIntMax > mNTimeBinsPerBC) {
343 LOG(fatal) << "invalid indicess: chargeInMin=" << chargeIntMin << " chargeIntMax=" << chargeIntMax;
344 }
345 Float_t totalCharge = 0.0f;
346 for (int iTimeBin = chargeIntMin; iTimeBin < chargeIntMax; iTimeBin++) {
347 totalCharge += pulse[iTimeBin];
348 }
349 return totalCharge;
350}
351//---------------------------------------------------------------------------
352Float_t Digitizer::SimulateTimeCfd(int& startIndex, const ChannelDigitF& pulseLast, const ChannelDigitF& pulse) const
353{
354 Float_t timeCfd = -1024.0f;
355
356 if (pulse.empty()) {
357 startIndex = 0;
358 return timeCfd;
359 }
360
361 Float_t const cfdThrInCoulomb = FV0DigParam::Instance().mCFD_trsh * 1e-3 / 50 * mBinSize * 1e-9; // convert mV into Coulomb assuming 50 Ohm
362
363 Int_t const binShift = TMath::Nint(FV0DigParam::Instance().timeShiftCfd / mBinSize);
364 Float_t sigPrev = 5 * pulseLast[mNTimeBinsPerBC - binShift - 1] - pulseLast[mNTimeBinsPerBC - 1]; // CFD output from the last bin of the last BC
365 for (Int_t iTimeBin = 0; iTimeBin < mNTimeBinsPerBC; ++iTimeBin) {
366 Float_t const sigCurrent = 5.0f * (iTimeBin >= binShift ? pulse[iTimeBin - binShift] : pulseLast[mNTimeBinsPerBC - binShift + iTimeBin]) - pulse[iTimeBin];
367 if (iTimeBin >= startIndex && std::abs(pulse[iTimeBin]) > cfdThrInCoulomb) { // enable
368 if (sigPrev < 0.0f && sigCurrent >= 0.0f) { // test for zero-crossing
369 timeCfd = Float_t(iTimeBin) * mBinSize;
370 startIndex = iTimeBin + std::lround(FV0DigParam::Instance().mCfdDeadTime / mBinSize); // update startIndex (CFD dead time)
371 if (startIndex < mNTimeBinsPerBC) {
372 startIndex = 0; // dead-time ends in same BC: no impact on the following BC
373 } else {
374 startIndex -= mNTimeBinsPerBC;
375 }
376 if (startIndex > mNTimeBinsPerBC) {
377 LOG(fatal) << "CFD dead-time was set to > 25 ns";
378 }
379 break; // only detects the 1st zero-crossing in the BC
380 }
381 }
382 sigPrev = sigCurrent;
383 }
384 return timeCfd;
385}
386
387float Digitizer::getDistFromCellCenter(UInt_t cellId, double hitx, double hity)
388{
390
391 // Parametrize the line (ax+by+c=0) that crosses the detector center and the cell's middle point
392 Point3Dsimple* pCell = &geo->getCellCenter(cellId);
393 float x0, y0, z0;
394 geo->getGlobalPosition(x0, y0, z0);
395 double a = -(y0 - pCell->y) / (x0 - pCell->x);
396 double b = 1;
397 double c = -(y0 - a * x0);
398 //Return the distance from hit to this line
399 return (a * hitx + b * hity + c) / TMath::Sqrt(a * a + b * b);
400}
401
402float Digitizer::getSignalFraction(float distanceFromXc, bool isFirstChannel)
403{
404 float const fraction = sigmoidPmtRing5(distanceFromXc);
405 if (distanceFromXc > 0) {
406 return isFirstChannel ? fraction : (1. - fraction);
407 } else {
408 return isFirstChannel ? (1. - fraction) : fraction;
409 }
410}
411
412//_____________________________________________________________________________
413o2::fv0::Digitizer::BCCache& Digitizer::setBCCache(const o2::InteractionRecord& ir)
414{
415 if (mCache.empty() || mCache.back() < ir) {
416 mCache.emplace_back();
417 auto& cb = mCache.back();
418 cb = ir;
419 return cb;
420 }
421 if (mCache.front() > ir) {
422 mCache.emplace_front();
423 auto& cb = mCache.front();
424 cb = ir;
425 return cb;
426 }
427 for (auto cb = mCache.begin(); cb != mCache.end(); cb++) {
428 if ((*cb) == ir) {
429 return *cb;
430 }
431 if (ir < (*cb)) {
432 auto cbnew = mCache.emplace(cb); // insert new element before cb
433 (*cbnew) = ir;
434 return (*cbnew);
435 }
436 }
437 return mCache.front();
438}
439//_____________________________________________________________________________
440o2::fv0::Digitizer::BCCache* Digitizer::getBCCache(const o2::InteractionRecord& ir)
441{
442 // get pointer on existing cache
443 for (auto cb = mCache.begin(); cb != mCache.end(); cb++) {
444 if ((*cb) == ir) {
445 return &(*cb);
446 }
447 }
448 return nullptr;
449}
450
451bool Digitizer::isRing5(int detID)
452{
453 if (detID > 31) {
454 return true;
455 } else {
456 return false;
457 }
458}
459
#define O2ParamImpl(classname)
General constants in FV0.
Base definition of FV0 geometry.
ClassImp(o2::fv0::Digitizer)
uint64_t bc
Definition RawEventData.h:5
Configurable digitization parameters.
int32_t i
std::ostringstream debug
A container to hold and manage MC truth information/labels.
void addElement(uint32_t dataindex, TruthElement const &element, bool noElement=false)
static const int16_t DEFAULT_AMP
Definition Triggers.h:51
static const int16_t DEFAULT_TIME
Definition Triggers.h:50
void setTriggers(uint8_t trgsig, uint8_t chanA, uint8_t chanC, int32_t aamplA, int32_t aamplC, int16_t atimeA, int16_t atimeC)
Definition Triggers.h:97
static const int16_t DEFAULT_ZERO
Definition Triggers.h:52
void flush(std::vector< o2::fv0::Digit > &digitsBC, std::vector< o2::fv0::ChannelData > &digitsCh, std::vector< o2::fv0::DetTrigInput > &digitsTrig, o2::dataformats::MCTruthContainer< o2::fv0::MCLabel > &labels)
void process(const std::vector< o2::fv0::Hit > &hits, std::vector< o2::fv0::Digit > &digitsBC, std::vector< o2::fv0::ChannelData > &digitsCh, std::vector< o2::fv0::DetTrigInput > &digitsTrig, o2::dataformats::MCTruthContainer< o2::fv0::MCLabel > &labels)
Definition Digitizer.cxx:83
FV0 Geometry.
Definition Geometry.h:51
static Geometry * instance(EGeoType initType=eUninitialized)
Point3Dsimple & getCellCenter(UInt_t cellId)
Definition Geometry.cxx:125
bool isRing5(UInt_t cellId)
Definition Geometry.cxx:135
void getGlobalPosition(float &x, float &y, float &z)
Utility functions to be accessed externally.
Definition Geometry.cxx:118
GLdouble n
Definition glcorearb.h:1982
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint * ids
Definition glcorearb.h:647
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLuint GLfloat x0
Definition glcorearb.h:5034
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLuint GLfloat GLfloat y0
Definition glcorearb.h:5034
constexpr double LHCBunchSpacingNS
constexpr float LightSpeedCm2NS
float sigmoidPmtRing5(float x)
Definition Digitizer.h:148
float float & c
Definition Utils.h:111
int64_t differenceInBC(const InteractionRecord &other) const
double getTimeNS() const
get time in ns from orbit=0/bc=0
void setFlag(uint8_t flag)
Definition ChannelData.h:55
static constexpr int nFv0Channels
Definition Constants.h:32
static constexpr float N_PHOTONS_PER_MEV
static constexpr float INV_CHARGE_PER_ADC
static constexpr float INV_TIME_PER_TDCCHANNEL
std::array< ChannelDigitF, Constants::nFv0Channels > mPmtChargeVsTime
Definition Digitizer.h:73
float getNormRingA1ToA4() const
Definition FV0DigParam.h:37
float getNormRing5() const
Definition FV0DigParam.h:45
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)