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
16
17#include "TCanvas.h"
18#include "TFile.h"
19#include "TH1F.h"
20#include "TH2F.h"
21#include "TLeaf.h"
22#include "TMath.h"
23#include "TProfile2D.h"
24#include "TRandom.h"
25#include <algorithm>
26#include <cassert>
27
28using namespace o2::tof;
29
31
32// How data acquisition works in real data
33/*
34 |<----------- 1 orbit ------------->|
35 ------|-----------|-----------|-----------|------
36 ^ ^ ^ ^ when triggers happen
37 |<--- latency ---|
38 |<- matching1->|
39 |<- matching2->|
40 |<- matching3->|
41 |<>| = overlap between two consecutive matching
42
43Norbit = number of orbits elapsed
44Nbunch = bunch in the current orbit (0:3563)
45Ntdc = number of tdc counts within the matching window --> for 1/3 orbit (0:3649535)
46
47raw time = trigger time (Norbit and Nbunch) - latency window + TDC(Ntdc)
48 */
49
50// What we implemented here (so far)
51/*
52 |<----------- 1 orbit ------------->|
53 ------|-----------|-----------|-----------|------
54 |<- matching1->|
55 |<- matching2->|
56 |<- matching3->|
57 |<>| = overlap between two consecutive matching windows
58
59- OVERLAP between two consecutive windows: implemented, to be extensively checked
60- NO LATENCY WINDOW (we manage it during raw encoding/decoding) then digits already corrected
61
62NBC = Number of bunch since timeframe beginning = Norbit*3564 + Nbunch
63Ntdc = here within the current BC -> (0:1023)
64
65digit time = NBC*1024 + Ntdc
66 */
67
69{
70
71 // set first readout window in MC production getting
72 // orbitFirstSampled corresponds to the start of the concrete timeframe (it is set in O2DPG productions)
74
75 // method to initialize the parameters neede to digitize and the array of strip objects containing
76 // the digits belonging to a strip
77
79
80 for (Int_t i = 0; i < Geo::NSTRIPS; i++) {
81 for (Int_t j = 0; j < MAXWINDOWS; j++) {
82 mStrips[j].emplace_back(i);
83 if (j < MAXWINDOWS - 1) {
84 mMCTruthContainerNext[j] = &(mMCTruthContainer[j + 1]);
85 // mStripsNext[j] = &(mStrips[j + 1]);
86 }
87 }
88 }
89}
90
91//______________________________________________________________________
92
93int Digitizer::process(const std::vector<HitType>* hits, std::vector<Digit>* digits)
94{
95 const double max_hit_time = TOFSimParams::Instance().max_hit_time;
96
97 // hits array of TOF hits for a given simulated event
98 // digits passed from external to be filled, in continuous readout mode we will push it on mDigitsPerTimeFrame vector of vectors of digits
99
100 // printf("process event time = %f with %ld hits\n",mEventTime.getTimeNS(),hits->size());
101
102 uint64_t readoutwindow = getReadoutWindow(mEventTime.getTimeNS());
103
104 // determines the maximal readout window difference to a preceding RO which can still affect the current readout window
105 int max_readout_diff = int(max_hit_time * Geo::READOUTWINDOW_INV) + 1;
106 // early return based on events happening earlier than MAX_READOUT_DIFF away from current RO frame
107 if (readoutwindow < mReadoutWindowCurrent && mReadoutWindowCurrent - readoutwindow > max_readout_diff) {
108 return 0;
109 }
110
111 if (mContinuous && readoutwindow > mReadoutWindowCurrent) { // if we are moving in future readout windows flush previous ones (only for continuous readout mode)
112 digits->clear();
113
114 for (; mReadoutWindowCurrent < readoutwindow;) { // mReadoutWindowCurrent incremented in fillOutputContainer!!!!
115 fillOutputContainer(*digits); // fill all windows which are before (not yet stored) of the new current one
116 checkIfReuseFutureDigits();
117 } // close loop readout window
118 } // close if continuous
119
120 for (auto& hit : *hits) {
121 // TODO: put readout window counting/selection
122 // neglect very slow particles (low energy neutrons)
123 if (hit.GetTime() > max_hit_time) { // 1 mus
124 continue;
125 }
126
127 // discard hits arriving before the minimum readout window
128 auto hit_ro_window = getReadoutWindow(double(hit.GetTime()) + mEventTime.getTimeNS() /*+ Geo::LATENCYWINDOW*/);
129
130 // discard hits arriving too early
131 if (hit_ro_window < mReadoutWindowCurrent) {
132 continue;
133 }
134
136 } // end loop over hits
137
138 if (!mContinuous) { // fill output container per event
139 digits->clear();
141 }
142
143 return 0;
144}
145
146//______________________________________________________________________
147
148Int_t Digitizer::processHit(const HitType& hit, Double_t event_time)
149{
150 mNLastHit = 0;
151
152 Float_t pos[3] = {hit.GetX(), hit.GetY(), hit.GetZ()};
153 Float_t deltapos[3];
154 Int_t detInd[5];
155 Int_t detIndOtherPad[5];
156
157 Geo::getPadDxDyDz(pos, detInd, deltapos); // Get DetId and residuals
158
159 detIndOtherPad[0] = detInd[0], detIndOtherPad[1] = detInd[1],
160 detIndOtherPad[2] = detInd[2]; // same sector, plate, strip
161
162 Int_t otherraw = 0;
163 if (detInd[3] == 0) {
164 otherraw = 1;
165 }
166
167 Int_t iZshift = otherraw ? 1 : -1;
168
169 Int_t channel = Geo::getIndex(detInd);
170
172 // NOTE: FROM NOW ON THE TIME IS IN PS ... AND NOT IN NS
173 Double_t time = getShowerTimeSmeared((double(hit.GetTime()) + event_time) * 1E3 + 0.5 * Geo::TDCBIN, charge);
174
175 Float_t xLocal = deltapos[0];
176 Float_t zLocal = deltapos[2];
177
178 // extract trackID
179 auto trackID = hit.GetTrackID();
180
181 // PadId - Pad Identifier
182 // E | F --> PadId = 5 | 6
183 // A | B --> PadId = 1 | 2
184 // C | D --> PadId = 3 | 4
185
186 Int_t ndigits = 0; //Number of digits added
187
188 UInt_t istrip = channel / Geo::NPADS;
189
190 // check the fired PAD 1 (A)
191 if (isFired(xLocal, zLocal, charge)) {
192 ndigits++;
193 mXLastShift[mNLastHit] = 0;
194 mZLastShift[mNLastHit] = 0;
195 addDigit(channel, istrip, time, xLocal, zLocal, charge, 0, 0, detInd[3], trackID, hit.GetTime(), event_time * 1E3);
196 }
197
198 // check PAD 2
199 detIndOtherPad[3] = otherraw;
200 detIndOtherPad[4] = detInd[4];
201 channel = Geo::getIndex(detIndOtherPad);
202 xLocal = deltapos[0]; // recompute local coordinates
203 if (otherraw) {
204 zLocal = deltapos[2] - Geo::ZPAD; // recompute local coordinates
205 } else {
206 zLocal = deltapos[2] + Geo::ZPAD;
207 }
208 if (isFired(xLocal, zLocal, charge)) {
209 ndigits++;
210 mXLastShift[mNLastHit] = 0;
211 mZLastShift[mNLastHit] = iZshift;
212 addDigit(channel, istrip, time, xLocal, zLocal, charge, 0, iZshift, detInd[3], trackID, hit.GetTime(), event_time * 1E3);
213 }
214
215 // check PAD 3
216 detIndOtherPad[3] = detInd[3];
217 detIndOtherPad[4] = detInd[4] - 1;
218 if (detIndOtherPad[4] >= 0) {
219 channel = Geo::getIndex(detIndOtherPad);
220 xLocal = deltapos[0] + Geo::XPAD; // recompute local coordinates
221 zLocal = deltapos[2]; // recompute local coordinates
222 if (isFired(xLocal, zLocal, charge)) {
223 ndigits++;
224 mXLastShift[mNLastHit] = -1;
225 mZLastShift[mNLastHit] = 0;
226 addDigit(channel, istrip, time, xLocal, zLocal, charge, -1, 0, detInd[3], trackID, hit.GetTime(), event_time * 1E3);
227 }
228 }
229
230 // check PAD 5
231 detIndOtherPad[3] = detInd[3];
232 detIndOtherPad[4] = detInd[4] + 1;
233 if (detIndOtherPad[4] < Geo::NPADX) {
234 channel = Geo::getIndex(detIndOtherPad);
235 xLocal = deltapos[0] - Geo::XPAD; // recompute local coordinates
236 zLocal = deltapos[2]; // recompute local coordinates
237 if (isFired(xLocal, zLocal, charge)) {
238 ndigits++;
239 mXLastShift[mNLastHit] = 1;
240 mZLastShift[mNLastHit] = 0;
241 addDigit(channel, istrip, time, xLocal, zLocal, charge, 1, 0, detInd[3], trackID, hit.GetTime(), event_time * 1E3);
242 }
243 }
244
245 // check PAD 4
246 detIndOtherPad[3] = otherraw;
247 detIndOtherPad[4] = detInd[4] - 1;
248 if (detIndOtherPad[4] >= 0) {
249 channel = Geo::getIndex(detIndOtherPad);
250 xLocal = deltapos[0] + Geo::XPAD; // recompute local coordinates
251 if (otherraw) {
252 zLocal = deltapos[2] - Geo::ZPAD; // recompute local coordinates
253 } else {
254 zLocal = deltapos[2] + Geo::ZPAD;
255 }
256 if (isFired(xLocal, zLocal, charge)) {
257 ndigits++;
258 mXLastShift[mNLastHit] = -1;
259 mZLastShift[mNLastHit] = iZshift;
260 addDigit(channel, istrip, time, xLocal, zLocal, charge, -1, iZshift, detInd[3], trackID, hit.GetTime(), event_time * 1E3);
261 }
262 }
263
264 // check PAD 6
265 detIndOtherPad[3] = otherraw;
266 detIndOtherPad[4] = detInd[4] + 1;
267 if (detIndOtherPad[4] < Geo::NPADX) {
268 channel = Geo::getIndex(detIndOtherPad);
269 xLocal = deltapos[0] - Geo::XPAD; // recompute local coordinates
270 if (otherraw) {
271 zLocal = deltapos[2] - Geo::ZPAD; // recompute local coordinates
272 } else {
273 zLocal = deltapos[2] + Geo::ZPAD;
274 }
275 if (isFired(xLocal, zLocal, charge)) {
276 ndigits++;
277 mXLastShift[mNLastHit] = 1;
278 mZLastShift[mNLastHit] = iZshift;
279 addDigit(channel, istrip, time, xLocal, zLocal, charge, 1, iZshift, detInd[3], trackID, hit.GetTime(), event_time * 1E3);
280 }
281 }
282 return ndigits;
283}
284
285//______________________________________________________________________
286void Digitizer::addDigit(Int_t channel, UInt_t istrip, Double_t time, Float_t x, Float_t z, Float_t charge, Int_t iX, Int_t iZ,
287 Int_t padZfired, Int_t trackID, float geanttime, double t0)
288{
289 // TOF digit requires: channel, time and time-over-threshold
290
291 if (mCalibApi->isOff(channel)) {
292 return;
293 }
294
295 time = getDigitTimeSmeared(time, x, z, charge); // add time smearing
296
298
299 // tot tuned to reproduce 0.8% of orphans tot(=0)
300 Float_t totf = gRandom->Gaus(12. * Geo::NTOTBIN_PER_NS, 1.5 * Geo::NTOTBIN_PER_NS); // time-over-threshold
301 if (totf < 172) {
302 totf = 0;
303 }
304 int tot = int(totf);
305
306 Float_t xborder = Geo::XPAD * 0.5 - std::abs(x);
307 Float_t zborder = Geo::ZPAD * 0.5 - std::abs(z);
308 Float_t border = TMath::Min(xborder, zborder);
309
310 Float_t timewalkX = x * mTimeWalkeSlope;
311 Float_t timewalkZ = (z - (padZfired - 0.5) * Geo::ZPAD) * mTimeWalkeSlope;
312
313 if (border < 0) { // keep the effect only if hit out of pad
314 border *= -1;
315 Float_t extraTimeSmear = border * mTimeSlope;
316 time += gRandom->Gaus(mTimeDelay, extraTimeSmear);
317 } else {
318 border = 1 - border;
319 // if(border > 0) printf("deltat =%f\n",mTimeDelay*border*border*border);
320 // else printf("deltat=0\n");
321 // getchar();
322 if (border > 0) {
323 time += mTimeDelay * border * border * border;
324 }
325 }
326 time += TMath::Sqrt(timewalkX * timewalkX + timewalkZ * timewalkZ) - mTimeDelayCorr - mTimeWalkeSlope * 2;
327
328 // Decalibrate
329 float tsCorr = mCalibApi->getTimeDecalibration(channel, tot * Geo::TOTBIN_NS);
330 if (std::abs(tsCorr) > 200E3) { // accept correction up to 200 ns
331 LOG(error) << "Wrong de-calibration correction for ch = " << channel << ", tot = " << tot << " (Skip it)";
332 return;
333 }
334
335 mTimeLastHit[mNLastHit] = time;
336 mTotLastHit[mNLastHit] = tot;
337 mNLastHit++;
338
339 time -= tsCorr; // TODO: to be checked that "-" is correct, and we did not need "+" instead :-)
340
341 // let's move from time to bc, tdc
342
343 uint64_t nbc = (uint64_t)(time * Geo::BC_TIME_INPS_INV); // time elapsed in number of bunch crossing
344 //Digit newdigit(time, channel, (time - Geo::BC_TIME_INPS * nbc) * Geo::NTDCBIN_PER_PS, tot * Geo::NTOTBIN_PER_NS, nbc);
345
346 int tdc = int((time - Geo::BC_TIME_INPS * nbc) * Geo::NTDCBIN_PER_PS);
347
348 static long firstlongbc = long(o2::raw::HBFUtils::Instance().orbitFirstSampled) * o2::constants::lhc::LHCMaxBunches;
349 // add orbit and bc
350 nbc += mEventTime.toLong();
352
353 // printf("orbit = %d -- bc = %d -- nbc = (%d) %d\n",mEventTime.orbit,mEventTime.bc, mEventTime.toLong(),nbc);
354
355 // printf("tdc = %d\n",tdc);
356
357 int lblCurrent = 0;
358
359 bool iscurrent = true; // if we are in the current readout window
360 Int_t isnext = -1;
361 Int_t isIfOverlap = -1;
362
363 if (mContinuous) {
366
367 if (isnext == isIfOverlap) {
368 isIfOverlap = -1;
369 } else if (isnext < 0 && isIfOverlap >= 0) {
370 isnext = isIfOverlap;
371 isIfOverlap = -1;
372 } else if (isnext >= MAXWINDOWS && isIfOverlap < MAXWINDOWS) {
373 isnext = isIfOverlap;
374 isIfOverlap = MAXWINDOWS;
375 }
376
377 if (isnext < 0) {
378 LOG(error) << "error: isnext =" << isnext << "(current window = " << mReadoutWindowCurrent << ")"
379 << " nbc = " << nbc << " -- event time = " << mEventTime.getTimeNS() << "\n";
380
381 return;
382 }
383
384 if (isnext < 0 || isnext >= MAXWINDOWS) {
385
386 lblCurrent = mFutureIevent.size(); // this is the size of mHeaderArray;
387 mFutureIevent.push_back(mEventID);
388 mFutureIsource.push_back(mSrcID);
389 mFutureItrackID.push_back(trackID);
390
391 // fill temporary digits array
392 insertDigitInFuture(channel, tdc, tot, nbc, lblCurrent);
393 return; // don't fill if doesn't match any available readout window
394 } else if (isIfOverlap == MAXWINDOWS) { // add in future digits but also in one of the current readout windows (beacuse of windows overlap)
395 lblCurrent = mFutureIevent.size();
396 mFutureIevent.push_back(mEventID);
397 mFutureIsource.push_back(mSrcID);
398 mFutureItrackID.push_back(trackID);
399
400 // fill temporary digits array
401 insertDigitInFuture(channel, tdc, tot, nbc, lblCurrent);
402 }
403
404 if (isnext) {
405 iscurrent = false;
406 }
407 }
408
409 //printf("add TOF digit c=%i n=%i\n",iscurrent,isnext);
410
411 std::vector<Strip>* strips;
413
414 if (iscurrent) {
415 strips = mStripsCurrent;
416 mcTruthContainer = mMCTruthContainerCurrent;
417 } else {
418 strips = mStripsNext[isnext - 1];
419 mcTruthContainer = mMCTruthContainerNext[isnext - 1];
420 }
421
422 fillDigitsInStrip(strips, mcTruthContainer, channel, tdc, tot, nbc, istrip, trackID, mEventID, mSrcID, geanttime, t0);
423
424 if (isIfOverlap > -1 && isIfOverlap < MAXWINDOWS) { // fill also a second readout window because of the overlap
425 if (!isIfOverlap) {
426 strips = mStripsCurrent;
427 mcTruthContainer = mMCTruthContainerCurrent;
428 } else {
429 strips = mStripsNext[isIfOverlap - 1];
430 mcTruthContainer = mMCTruthContainerNext[isIfOverlap - 1];
431 }
432
433 fillDigitsInStrip(strips, mcTruthContainer, channel, tdc, tot, nbc, istrip, trackID, mEventID, mSrcID, geanttime, t0);
434 }
435}
436//______________________________________________________________________
437void Digitizer::fillDigitsInStrip(std::vector<Strip>* strips, o2::dataformats::MCTruthContainer<o2::tof::MCLabel>* mcTruthContainer, int channel, int tdc, int tot, uint64_t nbc, UInt_t istrip, Int_t trackID, Int_t eventID, Int_t sourceID, float geanttime, double t0)
438{
439 int lblCurrent;
440 if (mcTruthContainer) {
441 lblCurrent = mcTruthContainer->getIndexedSize(); // this is the size of mHeaderArray;
442 }
443
444 Int_t lbl = (*strips)[istrip].addDigit(channel, tdc, tot, nbc, lblCurrent, 0, 0, geanttime, t0);
445
446 if (mcTruthContainer) {
447 if (lbl == lblCurrent) { // it means that the digit was a new one --> we have to add the info in the MC container
448 o2::tof::MCLabel label(trackID, eventID, sourceID, tdc);
449 mcTruthContainer->addElement(lbl, label);
450 } else {
451 o2::tof::MCLabel label(trackID, eventID, sourceID, tdc);
452 mcTruthContainer->addElementRandomAccess(lbl, label);
453
454 // sort the labels according to increasing tdc value
455 auto labels = mcTruthContainer->getLabels(lbl);
456 std::sort(labels.begin(), labels.end(),
457 [](o2::tof::MCLabel a, o2::tof::MCLabel b) { return a.getTDC() < b.getTDC(); });
458 }
459 }
460}
461//______________________________________________________________________
463{
464 // add the smearing common to all the digits belongin to the same shower
465 return time + gRandom->Gaus(0, mShowerResolution);
466}
467
468//______________________________________________________________________
470{
471 // add the smearing component which is indepedent for any digit even if belonging to the same shower (in case of
472 // multiple hits)
473 return time + gRandom->Gaus(0, mDigitResolution); // sqrt(33**2 + 50**2) ps = 60 ps
474}
475
476//______________________________________________________________________
478{
479 // transform deposited energy in collected charge
480 Float_t adcMean = 50;
481 Float_t adcRms = 25;
482
483 return gRandom->Landau(adcMean, adcRms);
484}
485
486//______________________________________________________________________
488{
489 if (std::abs(x) > Geo::XPAD * 0.5 + 0.3) {
490 return kFALSE;
491 }
492 if (std::abs(z) > Geo::ZPAD * 0.5 + 0.3) {
493 return kFALSE;
494 }
495
496 Float_t effX = getEffX(x);
497 Float_t effZ = getEffZ(z);
498
499 Float_t efficiency = TMath::Min(effX, effZ);
500
501 if (gRandom->Rndm() > efficiency) {
502 return kFALSE;
503 }
504
505 return kTRUE;
506}
507
508//______________________________________________________________________
510{
511 Float_t xborder = Geo::XPAD * 0.5 - std::abs(x);
512
513 if (xborder > 0) {
514 if (xborder > mBound1) {
515 return mEffCenter;
516 } else if (xborder > mBound2) {
517 return mEffBoundary1 + (mEffCenter - mEffBoundary1) * (xborder - mBound2) / (mBound1 - mBound2);
518 } else {
519 return mEffBoundary2 + (mEffBoundary1 - mEffBoundary2) * xborder / mBound2;
520 }
521 } else {
522 xborder *= -1;
523 if (xborder > mBound4) {
524 return 0;
525 } else if (xborder > mBound3) {
526 return mEffBoundary3 - mEffBoundary3 * (xborder - mBound3) / (mBound4 - mBound3);
527 } else {
528 return mEffBoundary2 + (mEffBoundary3 - mEffBoundary2) * xborder / mBound3;
529 }
530 }
531
532 return 0;
533}
534
535//______________________________________________________________________
537{
538 Float_t zborder = Geo::ZPAD * 0.5 - std::abs(z);
539
540 if (zborder > 0) {
541 if (zborder > mBound1) {
542 return mEffCenter;
543 } else if (zborder > mBound2) {
544 return mEffBoundary1 + (mEffCenter - mEffBoundary1) * (zborder - mBound2) / (mBound1 - mBound2);
545 } else {
546 return mEffBoundary2 + (mEffBoundary1 - mEffBoundary2) * zborder / mBound2;
547 }
548 } else {
549 zborder *= -1;
550 if (zborder > mBound4) {
551 return 0;
552 } else if (zborder > mBound3) {
553 return mEffBoundary3 - mEffBoundary3 * (zborder - mBound3) / (mBound4 - mBound3);
554 } else {
555 return mEffBoundary2 + (mEffBoundary3 - mEffBoundary2) * zborder / mBound3;
556 }
557 }
558
559 return 0;
560}
561
562//______________________________________________________________________
564//______________________________________________________________________
566{
567 mShowerResolution = 50; // smearing correlated for all digits of the same hit
568 if (mTOFresolution > mShowerResolution) {
569 mDigitResolution = TMath::Sqrt(mTOFresolution * mTOFresolution - mShowerResolution * mShowerResolution); // independent smearing for each digit
570 } else {
571 mShowerResolution = mTOFresolution;
572 mDigitResolution = 0;
573 }
574}
575//______________________________________________________________________
577{
578 // boundary references for interpolation of efficiency and resolution
579 mBound1 = 0.4; // distance from border when efficiency starts to decrese
580 mBound2 = 0.15; // second step in the fired pad
581 mBound3 = 0.55; // distance from border (not fired pad)
582 mBound4 = 0.9; // distance from border (not fired pad) when efficiency vanishes
583
584 // resolution parameters
585 mTOFresolution = TOFSimParams::Instance().time_resolution; // TOF global resolution in ps
587
588 mTimeSlope = 100; // ps/cm extra smearing if hit out of pad propto the distance from the border
589 mTimeDelay = 70; // time delay if hit out of pad
590 mTimeWalkeSlope = 40; // ps/cm
591
592 if (mMode == 0) {
593 mTimeSlope = 0;
594 mTimeDelay = 0;
595 mTimeWalkeSlope = 0;
596 }
597
598 mTimeDelayCorr = mTimeDelay / 3.5;
599 if (mShowerResolution > mTimeDelayCorr) {
600 mShowerResolution = TMath::Sqrt(mShowerResolution * mShowerResolution - mTimeDelayCorr * mTimeDelayCorr);
601 } else {
602 mShowerResolution = 0;
603 }
604
605 if (mShowerResolution > mTimeWalkeSlope * 0.8) {
606 mShowerResolution = TMath::Sqrt(mShowerResolution * mShowerResolution - mTimeWalkeSlope * mTimeWalkeSlope * 0.64);
607 } else {
608 mShowerResolution = 0;
609 }
610
611 // efficiency parameters
612 mEffCenter = TOFSimParams::Instance().eff_center; // efficiency in the center of the fired pad
613 mEffBoundary1 = TOFSimParams::Instance().eff_boundary1; // efficiency in mBound2
614 mEffBoundary2 = TOFSimParams::Instance().eff_boundary2; // efficiency in the pad border
615 mEffBoundary3 = TOFSimParams::Instance().eff_boundary3; // efficiency in mBound3
616}
617
618//______________________________________________________________________
620{
621 printf("Efficiency in the pad center = %f\n", mEffCenter);
622 printf("Efficiency in the pad border = %f\n", mEffBoundary2);
623 printf("Time resolution = %f ps (shower=%f, digit=%f)\n", mTOFresolution, mShowerResolution, mDigitResolution);
624 if (mTimeSlope > 0) {
625 printf("Degration resolution for pad with signal induced = %f ps/cm x border distance\n", mTimeSlope);
626 }
627 if (mTimeDelay > 0) {
628 printf("Time delay for pad with signal induced = %f ps\n", mTimeDelay);
629 }
630 if (mTimeWalkeSlope > 0) {
631 printf("Time walk ON = %f ps/cm\n", mTimeWalkeSlope);
632 }
633}
634//______________________________________________________________________
635void Digitizer::runFullTestExample(const char* geo)
636{
639 api->setTimeStamp(0);
640 api->readLHCphase();
642 setCalibApi(api);
643 test(geo);
644}
645//______________________________________________________________________
646void Digitizer::test(const char* geo)
647{
648 Int_t nhit = 1000000;
649
651
653
655
656 TH1F* h = new TH1F("hTime", "Time as from digitizer;time (ps);N", 100, -500, 500);
657 TH1F* h2 = new TH1F("hTot", "Tot as from digitizer;time (ns);N", 100, 0, 30);
658 TH1F* h3 = new TH1F("hNdig", "N_{digitis} distribution from one hit;N_{digits};N", 7, -0.5, 6.5);
659 TH1F* h4 = new TH1F("hTimeCorr", "Time correlation for double digits;#Deltat (ps)", 200, -1000, 1000);
660 TH1F* h5 = new TH1F("hTimeAv", "Time average for double digits;#Deltat (ps)", 200, -1000, 1000);
661
662 TH1F* hpad[3][3];
663 for (Int_t i = 0; i < 3; i++) {
664 for (Int_t j = 0; j < 3; j++) {
665 hpad[i][j] =
666 new TH1F(Form("hpad%i_%i", i, j), Form("Time as from digitizer, pad(%i,%i);time (ps);N", i, j), 100, -500, 500);
667 }
668 }
669
670 TProfile2D* hTimeWalk = new TProfile2D("hTimeWalk", "Time Walk;x (cm);z (cm)", 40, -1.25, 1.25, 40, -1.75, 1.75);
671
672 TH2F* hpadAll;
673 hpadAll = new TH2F("hpadAll", "all hits;x (cm);z (cm)", 40, -1.25, 1.25, 40, -1.75, 1.75);
674 TH2F* hpadHit[3][3];
675 TH2F* hpadEff[3][3];
676 for (Int_t i = 0; i < 3; i++) {
677 for (Int_t j = 0; j < 3; j++) {
678 hpadHit[i][j] = new TH2F(Form("hpadHit%i_%i", i, j), Form("pad(%i,%i) hits;x (cm);z (cm)", i - 1, 1 - j), 40,
679 -1.25, 1.25, 40, -1.75, 1.75);
680 hpadEff[i][j] = new TH2F(Form("hpadEff%i_%i", i, j), Form("pad(%i,%i) hits;x (cm);z (cm)", i - 1, 1 - j), 40,
681 -1.25, 1.25, 40, -1.75, 1.75);
682 }
683 }
684
685 Int_t det1[5] = {0, 0, 0, 1, 23};
686 Int_t det2[5] = {0, 0, 0, 0, 24};
687 Int_t det3[5] = {0, 0, 0, 1, 24};
688 Int_t det4[5] = {0, 0, 0, 0, 47};
689 Float_t pos[3], pos2[3], pos3[3], pos4[3];
690
692 o2::tof::Geo::getPos(det2, pos2);
693 o2::tof::Geo::getPos(det3, pos3);
694 o2::tof::Geo::getPos(det4, pos4);
695
696 // Get strip center
697 pos[0] += pos2[0];
698 pos[1] += pos2[1];
699 pos[2] += pos2[2];
700 pos[0] *= 0.5;
701 pos[1] *= 0.5;
702 pos[2] *= 0.5;
703
704 Float_t mod;
705 Float_t vx[3];
706 Float_t vz[3];
707
708 // Get z versor
709 pos3[0] -= pos2[0];
710 pos3[1] -= pos2[1];
711 pos3[2] -= pos2[2];
712 mod = TMath::Sqrt(pos3[0] * pos3[0] + pos3[1] * pos3[1] + pos3[2] * pos3[2]);
713 vz[0] = pos3[0] / mod;
714 vz[1] = pos3[1] / mod;
715 vz[2] = pos3[2] / mod;
716
717 // Get x versor
718 pos4[0] -= pos2[0];
719 pos4[1] -= pos2[1];
720 pos4[2] -= pos2[2];
721 mod = TMath::Sqrt(pos4[0] * pos4[0] + pos4[1] * pos4[1] + pos4[2] * pos4[2]);
722 vx[0] = pos4[0] / mod;
723 vx[1] = pos4[1] / mod;
724 vx[2] = pos4[2] / mod;
725
726 Float_t x[3], dx, dz, xlocal, zlocal;
727
728 for (Int_t i = 0; i < nhit; i++) {
729 dx = gRandom->Rndm() * 2.5 * 48;
730 dz = gRandom->Rndm() * 3.5 * 2;
731
732 xlocal = dx - Int_t(dx / 2.5) * 2.5 - 1.25;
733 zlocal = dz - Int_t(dz / 3.5) * 3.5 - 1.75;
734
735 dx -= 2.5 * 24;
736 dz -= 3.5;
737
738 x[0] = pos[0] + vx[0] * dx + vz[0] * dz;
739 x[1] = pos[1] + vx[1] * dx + vz[1] * dz;
740 x[2] = pos[2] + vx[2] * dx + vz[2] * dz;
741
742 Int_t detCur[5];
743 o2::tof::Geo::getDetID(x, detCur);
744
745 hit->SetTime(0); // t->GetLeaf("o2root.TOF.TOFHit.mTime")->GetValue(j));
746 hit->SetXYZ(x[0], x[1], x[2]);
747
748 hit->SetEnergyLoss(0.0001);
749
750 processHit(*hit, mEventTime.getTimeOffsetWrtBC());
751 Int_t ndigits = mNLastHit;
752
753 h3->Fill(ndigits);
754 hpadAll->Fill(xlocal, zlocal);
755 for (Int_t k = 0; k < ndigits; k++) {
756 if (k == 0) {
757 h->Fill(getTimeLastHit(k));
758 }
759 if (k == 0) {
760 h2->Fill(getTotLastHit(k));
761 }
762 if (k == 0 && getXshift(k) == 0 && getZshift(k) == 0) {
763 hTimeWalk->Fill(xlocal, zlocal * (0.5 - detCur[3]) * 2, getTimeLastHit(k));
764 }
765
766 hpad[getXshift(k) + 1][-getZshift(k) + 1]->Fill(getTimeLastHit(k));
767 hpadHit[getXshift(k) + 1][-getZshift(k) + 1]->Fill(xlocal, zlocal);
768 }
769
770 // check double digits case (time correlations)
771 if (ndigits == 2) {
772 h4->Fill(getTimeLastHit(0) - getTimeLastHit(1));
773 h5->Fill((getTimeLastHit(0) + getTimeLastHit(1)) * 0.5);
774 }
775 }
776
777 h->Draw();
778 new TCanvas();
779 h2->Draw();
780 new TCanvas();
781 h3->Draw();
782 new TCanvas();
783 h4->Draw();
784 new TCanvas();
785 h5->Draw();
786 new TCanvas();
787 hTimeWalk->Draw("SURF");
788
789 TCanvas* cpad = new TCanvas();
790 cpad->Divide(3, 3);
791 for (Int_t i = 0; i < 3; i++) {
792 for (Int_t j = 0; j < 3; j++) {
793 cpad->cd(j * 3 + i + 1);
794 hpad[i][j]->Draw();
795 }
796 }
797 TCanvas* cpadH = new TCanvas();
798 cpadH->Divide(3, 3);
799 for (Int_t i = 0; i < 3; i++) {
800 for (Int_t j = 0; j < 3; j++) {
801 cpadH->cd(j * 3 + i + 1);
802 hpadHit[i][j]->Draw("colz");
803 if (j != 1) {
804 hpadHit[i][j]->Scale(2);
805 }
806 hpadEff[i][j]->Divide(hpadHit[i][j], hpadAll, 1, 1, "B");
807 hpadEff[i][j]->Draw("surf");
808 hpadEff[i][j]->SetMaximum(1);
809 hpadEff[i][j]->SetMinimum(0);
810 hpadEff[i][j]->SetStats(0);
811 }
812 }
813
814 printf("\nEfficiency = %f\n", (h3->GetEntries() - h3->GetBinContent(1)) / h3->GetEntries());
815 printf("Multiple digits fraction = %f\n\n",
816 (h3->GetEntries() - h3->GetBinContent(1) - h3->GetBinContent(2)) / (h3->GetEntries() - h3->GetBinContent(1)));
817}
818
819//______________________________________________________________________
820void Digitizer::testFromHits(const char* geo, const char* hits)
821{
823
824 TFile* fHit = new TFile(hits);
825 fHit->ls();
826
827 TTree* t = (TTree*)fHit->Get("o2sim");
828 Int_t nev = t->GetEntriesFast();
829
831
833
834 TH1F* h = new TH1F("hTime", "Time as from digitizer;time (ps);N", 100, -500, 500);
835 TH1F* h2 = new TH1F("hTot", "Tot as from digitizer;time (ns);N", 100, 0, 30);
836 TH1F* h3 = new TH1F("hNdig", "N_{digitis} distribution from one hit;N_{digits};N", 7, -0.5, 6.5);
837
838 for (Int_t i = 0; i < nev; i++) {
839 t->GetEvent(i);
840 Int_t nhit = t->GetLeaf("o2root.TOF.TOFHit_")->GetLen();
841
842 for (Int_t j = 0; j < nhit; j++) {
843 hit->SetTime(0); // t->GetLeaf("o2root.TOF.TOFHit.mTime")->GetValue(j));
844 hit->SetXYZ(t->GetLeaf("o2root.TOF.TOFHit.mPos.fCoordinates.fX")->GetValue(j),
845 t->GetLeaf("o2root.TOF.TOFHit.mPos.fCoordinates.fY")->GetValue(j),
846 t->GetLeaf("o2root.TOF.TOFHit.mPos.fCoordinates.fZ")->GetValue(j));
847
848 hit->SetEnergyLoss(t->GetLeaf("o2root.TOF.TOFHit.mELoss")->GetValue(j));
849
850 Int_t ndigits = processHit(*hit, mEventTime.getTimeOffsetWrtBC());
851
852 h3->Fill(ndigits);
853 for (Int_t k = 0; k < ndigits; k++) {
854 h->Fill(getTimeLastHit(k));
855 h2->Fill(getTotLastHit(k));
856 }
857 }
858 }
859
860 h->Draw();
861 new TCanvas();
862 h2->Draw();
863 new TCanvas();
864 h3->Draw();
865}
866//______________________________________________________________________
867void Digitizer::fillOutputContainer(std::vector<Digit>& digits)
868{
869 if (mContinuous) {
870 digits.clear();
871 mMCTruthOutputContainer->clear();
872 } else { // for continuos filled below
873 // printf("TOF fill output container\n");
874 // filling the digit container doing a loop on all strips
875 for (auto& strip : *mStripsCurrent) {
876 strip.fillOutputContainer(digits);
877 if (strip.getNumberOfDigits()) {
878 LOG(debug) << "strip size = " << strip.getNumberOfDigits() << " - digit size = " << digits.size() << "\n";
879 }
880 }
881 }
882
883 if (mContinuous) {
884 int first = mDigitsPerTimeFrame.size();
885 //printf("%i) # TOF digits = %lu (%p)\n", mIcurrentReadoutWindow, digits.size(), mStripsCurrent);
887 int orbit_shift = mReadoutWindowData.size() / 3;
888 int bc_shift = (mReadoutWindowData.size() % 3) * Geo::BC_IN_WINDOW;
889 info.setBCData(mFirstIR.orbit + orbit_shift, mFirstIR.bc + bc_shift);
890 mDigitsPerTimeFrame.insert(mDigitsPerTimeFrame.end(), digits.begin(), digits.end());
891
892 // fill diagnostics
893 mCalibApi->resetTRMErrors();
894 float p = gRandom->Rndm();
895 if (mCalibApi->getEmptyTOFProb() > p) { // check empty TOF
896 for (int i = 0; i < Geo::kNCrate; i++) {
897 info.setEmptyCrate(i);
898 }
899 } else { // check empty crates when TOF is not empty
900 int itrmreached = -1;
901 bool isEmptyCrate[Geo::kNCrate];
902 const float* crateProb = mCalibApi->getEmptyCratesProb();
903 for (int i = 0; i < Geo::kNCrate; i++) {
904 p = gRandom->Rndm();
905 if (crateProb[i] > p) {
906 info.setEmptyCrate(i);
907 isEmptyCrate[i] = true;
908 } else { // check if filling diagnostic (noisy will be masked in clusterization, then skip here)
909 isEmptyCrate[i] = false;
910 int slotreached = -1;
911 const std::vector<std::pair<int, float>>& trmProg = mCalibApi->getTRMerrorProb();
912 const std::vector<int>& trmErr = mCalibApi->getTRMmask();
913 for (int itrm = itrmreached + 1; itrm < trmProg.size(); itrm++) { // trm ordered by crate and slot
914 int crate = trmProg[itrm].first / 100;
915 if (crate == i) {
916 int slot = trmProg[itrm].first % 100;
917 if (slot != slotreached) { // first diagnostic of this TRM, get the random value to be compared with probability
918 p = gRandom->Rndm();
919 slotreached = slot;
920 }
921 // add diagnostic if needed
922 if (trmProg[itrm].second > p) {
923 // fill diagnostic
924 mCalibApi->processError(crate, slot, trmErr[itrm]);
925 mPatterns.push_back(slot + 28); // add slot
926 info.addedDiagnostic(crate);
927 uint32_t cbit = 1;
928 for (int ibit = 0; ibit < 28; ibit++) {
929 if (trmErr[itrm] & cbit) {
930 mPatterns.push_back(ibit); // add bit error
931 info.addedDiagnostic(crate);
932 }
933 cbit <<= 1;
934 }
935
936 p = 10; // no other errors allowed for this slot
937 } else {
938 p -= trmProg[itrm].second; // reduce the error probability for this slot for the next error in the same slot (sum of prob for all errors <= 1)
939 }
940
941 itrmreached = itrm;
942 } else {
943 break; // move to next crate
944 }
945 }
946 }
947 }
948
949 // fill strip of non-empty crates
950 for (auto& strip : *mStripsCurrent) {
951 std::map<ULong64_t, o2::tof::Digit>& dmap = strip.getDigitMap();
952
953 std::vector<ULong64_t> keyToBeRemoved;
954
955 for (auto [key, dig] : dmap) {
956 int crate = Geo::getCrateFromECH(Geo::getECHFromCH(dig.getChannel()));
957
958 if (isEmptyCrate[crate] || mCalibApi->isChannelError(dig.getChannel())) {
959 // flag digits to be removed
960 keyToBeRemoved.push_back(key);
961 }
962 }
963 for (auto& key : keyToBeRemoved) {
964 dmap.erase(key);
965 }
966
967 strip.fillOutputContainer(digits);
968 }
969 }
970 info.setNEntries(digits.size());
971
972 if (digits.size()) {
973 mDigitsPerTimeFrame.insert(mDigitsPerTimeFrame.end(), digits.begin(), digits.end());
974 }
975
976 mReadoutWindowData.push_back(info);
977 }
978
979 // if(! digits.size()) return;
980
981 // copying the transient labels to the output labels (stripping the tdc information)
982 if (mMCTruthOutputContainer) {
983 // copy from transientTruthContainer to mMCTruthAray
984 // a brute force solution for the moment; should be handled by a dedicated API
985 for (int index = 0; index < mMCTruthContainerCurrent->getIndexedSize(); ++index) {
986 mMCTruthOutputContainer->addElements(index, mMCTruthContainerCurrent->getLabels(index));
987 }
988 }
989
990 if (mContinuous) {
991 mMCTruthOutputContainerPerTimeFrame.push_back(*mMCTruthOutputContainer);
992 }
993 mMCTruthContainerCurrent->clear();
994
995 // switch to next mStrip after flushing current readout window data
999 }
1001 mMCTruthContainerCurrent = &(mMCTruthContainer[mIcurrentReadoutWindow]);
1002 int k = mIcurrentReadoutWindow + 1;
1003 for (Int_t i = 0; i < MAXWINDOWS - 1; i++) {
1004 if (k >= MAXWINDOWS) {
1005 k = 0;
1006 }
1007 mMCTruthContainerNext[i] = &(mMCTruthContainer[k]);
1008 mStripsNext[i] = &(mStrips[k]);
1009 k++;
1010 }
1012}
1013//______________________________________________________________________
1015{ // flush all residual buffered data
1016 // TO be implemented
1017 if (!mContinuous) {
1019 } else {
1020 for (Int_t i = 0; i < MAXWINDOWS; i++) {
1021 fillOutputContainer(digits); // fill all windows which are before (not yet stored) of the new current one
1022 checkIfReuseFutureDigits();
1023 }
1024
1025 while (mFutureDigits.size()) {
1026 fillOutputContainer(digits); // fill all windows which are before (not yet stored) of the new current one
1027 checkIfReuseFutureDigits();
1028 }
1029
1030 for (Int_t i = 0; i < MAXWINDOWS; i++) {
1031 fillOutputContainer(digits); // fill last readout windows
1032 }
1033 }
1034
1035 // clear vector of label in future
1036 mFutureItrackID.clear();
1037 mFutureIsource.clear();
1038 mFutureIevent.clear();
1039}
1040//______________________________________________________________________
1041void Digitizer::checkIfReuseFutureDigits()
1042{
1043 uint64_t bclimit = 999999999999999999;
1044
1045 // check if digits stored very far in future match the new readout windows currently available
1046 int idigit = mFutureDigits.size() - 1;
1047
1048 for (std::vector<Digit>::reverse_iterator digit = mFutureDigits.rbegin(); digit != mFutureDigits.rend(); ++digit) {
1049 if (digit->getBC() > bclimit) {
1050 break;
1051 }
1052
1053 double timestamp = digit->getBC() * Geo::BC_TIME + digit->getTDC() * Geo::TDCBIN * 1E-3; // in ns
1054 int isnext = Int_t(timestamp * Geo::READOUTWINDOW_INV) - (mReadoutWindowCurrent + 1); // to be replaced with uncalibrated time
1055 int isIfOverlap = Int_t((timestamp - Geo::BC_TIME_INPS * Geo::OVERLAP_IN_BC * 1E-3) * Geo::READOUTWINDOW_INV) - (mReadoutWindowCurrent + 1); // to be replaced with uncalibrated time;
1056
1057 if (isnext == isIfOverlap) {
1058 isIfOverlap = -1;
1059 } else if (isnext < 0 && isIfOverlap >= 0) {
1060 isnext = isIfOverlap;
1061 isIfOverlap = -1;
1062 } else if (isnext >= MAXWINDOWS && isIfOverlap < MAXWINDOWS) {
1063 isnext = isIfOverlap;
1064 isIfOverlap = MAXWINDOWS;
1065 }
1066
1067 if (isnext < 0) { // we jump too ahead in future, digit will be not stored
1068 LOG(info) << "Digit lost because we jump too ahead in future. Current RO window=" << isnext << "\n";
1069
1070 // remove digit from array in the future
1071 int labelremoved = digit->getLabel();
1072 mFutureDigits.erase(mFutureDigits.begin() + idigit);
1073
1074 /* NOT TO REMOVE LABELS TO SAVE CPU TIME (clear of vector when flushing)
1075 // remove also the element from the buffers
1076 mFutureItrackID.erase(mFutureItrackID.begin() + digit->getLabel());
1077 mFutureIsource.erase(mFutureIsource.begin() + digit->getLabel());
1078 mFutureIevent.erase(mFutureIevent.begin() + digit->getLabel());
1079
1080 // adjust labels
1081 for (auto& digit2 : mFutureDigits) {
1082 if (digit2.getLabel() > labelremoved) {
1083 digit2.setLabel(digit2.getLabel() - 1);
1084 }
1085 }
1086 */
1087
1088 idigit--;
1089
1090 continue;
1091 }
1092
1093 if (isnext < MAXWINDOWS - 1) { // move from digit buffer array to the proper window
1094 std::vector<Strip>* strips = mStripsCurrent;
1095 o2::dataformats::MCTruthContainer<o2::tof::MCLabel>* mcTruthContainer = mMCTruthContainerCurrent;
1096
1097 if (isnext) {
1098 strips = mStripsNext[isnext - 1];
1099 mcTruthContainer = mMCTruthContainerNext[isnext - 1];
1100 }
1101
1102 int trackID = mFutureItrackID[digit->getLabel()];
1103 int sourceID = mFutureIsource[digit->getLabel()];
1104 int eventID = mFutureIevent[digit->getLabel()];
1105 fillDigitsInStrip(strips, mcTruthContainer, digit->getChannel(), digit->getTDC(), digit->getTOT(), digit->getBC(), digit->getChannel() / Geo::NPADS, trackID, eventID, sourceID, digit->getTgeant());
1106
1107 if (isIfOverlap < 0) { // if there is no overlap candidate
1108 // remove digit from array in the future
1109 int labelremoved = digit->getLabel();
1110 mFutureDigits.erase(mFutureDigits.begin() + idigit);
1111
1112 /* NOT TO REMOVE LABELS TO SAVE CPU TIME (clear of vector when flushing)
1113 // remove also the element from the buffers
1114 mFutureItrackID.erase(mFutureItrackID.begin() + digit->getLabel());
1115 mFutureIsource.erase(mFutureIsource.begin() + digit->getLabel());
1116 mFutureIevent.erase(mFutureIevent.begin() + digit->getLabel());
1117
1118 // adjust labels
1119 for (auto& digit2 : mFutureDigits) {
1120 if (digit2.getLabel() > labelremoved) {
1121 digit2.setLabel(digit2.getLabel() - 1);
1122 }
1123 }
1124 */
1125 }
1126 } else {
1127 bclimit = digit->getBC();
1128 }
1129
1130 idigit--; // go back to the next position in the reverse iterator
1131 } // close future digit loop
1132}
Definition of the GeometryManager class.
int16_t charge
Definition RawEventData.h:5
int16_t time
Definition RawEventData.h:4
int32_t i
uint16_t pos
Definition RawData.h:3
uint32_t j
Definition RawData.h:0
ClassImp(Digitizer)
std::ostringstream debug
StringRef key
Class for time synchronization of RawReader instances.
int GetTrackID() const
Definition BaseHits.h:30
V GetEnergyLoss() const
Definition BaseHits.h:103
void SetEnergyLoss(V val)
Definition BaseHits.h:104
void SetXYZ(T x, T y, T z)
Definition BaseHits.h:82
E GetTime() const
Definition BaseHits.h:71
void SetTime(E time)
Definition BaseHits.h:76
T GetZ() const
Definition BaseHits.h:66
T GetY() const
Definition BaseHits.h:65
T GetX() const
Definition BaseHits.h:64
static void loadGeometry(std::string_view geomFilePath="", bool applyMisalignment=false, bool preferAlignedFile=true)
A container to hold and manage MC truth information/labels.
gsl::span< TruthElement > getLabels(uint32_t dataindex)
void addElements(uint32_t dataindex, gsl::span< CompatibleLabel > elements)
void addElement(uint32_t dataindex, TruthElement const &element, bool noElement=false)
void addElementRandomAccess(uint32_t dataindex, TruthElement const &element)
bool isChannelError(int channel) const
const float * getEmptyCratesProb() const
Definition CalibTOFapi.h:96
const std::vector< std::pair< int, float > > & getTRMerrorProb() const
Definition CalibTOFapi.h:98
void setTimeStamp(long t)
Definition CalibTOFapi.h:58
float getEmptyTOFProb() const
Definition CalibTOFapi.h:95
void processError(int crate, int trm, int mask)
float getTimeDecalibration(int ich, float tot) const
const std::vector< int > & getTRMmask() const
Definition CalibTOFapi.h:99
int process(const std::vector< HitType > *hits, std::vector< Digit > *digits)
Definition Digitizer.cxx:93
Float_t getEffX(Float_t x)
void flushOutputContainer(std::vector< Digit > &digits)
Double_t getShowerTimeSmeared(Double_t time, Float_t charge)
void test(const char *geo="")
Int_t getXshift(Int_t idigit) const
Definition Digitizer.h:66
void fillOutputContainer(std::vector< Digit > &digits)
Float_t getEffZ(Float_t z)
void runFullTestExample(const char *geo="")
void testFromHits(const char *geo="", const char *hits="AliceO2_TGeant3.tof.mc_10_event.root")
Bool_t isFired(Float_t x, Float_t z, Float_t charge)
Double_t getDigitTimeSmeared(Double_t time, Float_t x, Float_t z, Float_t charge)
uint64_t getReadoutWindow(double timeNS) const
Definition Digitizer.h:88
Float_t getTotLastHit(Int_t idigit) const
Definition Digitizer.h:65
Float_t getCharge(Float_t eDep)
Float_t getTimeLastHit(Int_t idigit) const
Definition Digitizer.h:64
Int_t getZshift(Int_t idigit) const
Definition Digitizer.h:67
void setCalibApi(CalibApi *calibApi)
Definition Digitizer.h:41
Float_t getFractionOfCharge(Float_t x, Float_t z)
static constexpr Float_t ZPAD
Definition Geo.h:141
static constexpr Float_t XPAD
Definition Geo.h:139
static constexpr Double_t BC_TIME_INPS
Definition Geo.h:103
static constexpr Double_t BC_TIME_INPS_INV
Definition Geo.h:104
static constexpr Float_t NTOTBIN_PER_NS
Definition Geo.h:155
static constexpr Int_t NPADS
Definition Geo.h:110
static constexpr Float_t NTDCBIN_PER_PS
number of TDC bins in 1 ns
Definition Geo.h:151
static constexpr Double_t READOUTWINDOW_INV
Definition Geo.h:167
static Int_t getCrateFromECH(int ech)
Definition Geo.h:345
static void getPos(Int_t *det, Float_t *pos)
Definition Geo.cxx:491
static constexpr Int_t LATENCYWINDOW_IN_BC
Definition Geo.h:172
static constexpr Double_t BC_TIME
Definition Geo.h:101
@ kNCrate
Definition Geo.h:95
static constexpr Float_t TOTBIN_NS
Definition Geo.h:154
static Int_t getIndex(const Int_t *detId)
Definition Geo.cxx:563
static constexpr Float_t TDCBIN
TDC bin width [ps].
Definition Geo.h:150
static void getDetID(Float_t *pos, Int_t *det)
Definition Geo.cxx:507
static constexpr int BC_IN_WINDOW
Definition Geo.h:165
static void getPadDxDyDz(const Float_t *pos, Int_t *det, Float_t *DeltaPos, int sector=-1)
Definition Geo.cxx:835
static constexpr Int_t OVERLAP_IN_BC
Definition Geo.h:175
static constexpr Int_t NPADX
Definition Geo.h:107
static Int_t getECHFromCH(int chan)
Definition Geo.h:351
static constexpr int NWINDOW_IN_ORBIT
Definition Geo.h:163
static constexpr Double_t LATENCYWINDOW
Definition Geo.h:176
static constexpr Int_t NSTRIPS
Definition Geo.h:121
std::vector< Strip > mStrips[MAXWINDOWS]
static const int MAXWINDOWS
InteractionTimeRecord mEventTime
std::vector< Strip > * mStripsCurrent
std::vector< Strip > * mStripsNext[MAXWINDOWS - 1]
std::vector< uint8_t > mPatterns
std::vector< Digit > mDigitsPerTimeFrame
void insertDigitInFuture(Int_t channel, Int_t tdc, Int_t tot, uint64_t bc, Int_t label=0, uint32_t triggerorbit=0, uint16_t triggerbunch=0)
std::vector< Digit > mFutureDigits
std::vector< ReadoutWindowData > mReadoutWindowData
InteractionRecord mFirstIR
GLint GLint GLsizei GLint border
Definition glcorearb.h:275
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint index
Definition glcorearb.h:781
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
Definition glcorearb.h:5034
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
constexpr int LHCMaxBunches
FIXME: do not use data model tables.
uint32_t orbit
LHC orbit.
uint16_t bc
bunch crossing ID of interaction
double getTimeNS() const
get time in ns from orbit=0/bc=0
void setEmptyCrate(int crate)
Definition Digit.h:139
void setBCData(int orbit, int bc)
Definition Digit.h:152
void setNEntries(int ne)
Definition Digit.h:186
void addedDiagnostic(int crate)
Definition Digit.h:141
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits