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
13
14#include <TGeoManager.h>
15#include <TRandom.h>
16
17#include <fairlogger/Logger.h>
19
20#include "DataFormatsTRD/Hit.h"
21
22#include "TRDBase/Geometry.h"
24#include "TRDBase/PadPlane.h"
25#include "TRDBase/PadResponse.h"
27
28#include <cmath>
29
30#ifdef WITH_OPENMP
31#include <omp.h>
32#endif
33
34using namespace o2::trd;
35using namespace o2::trd::constants;
36using namespace o2::math_utils;
37
38// init method for late initialization
40{
41 mGeo = Geometry::instance();
42 mGeo->createClusterMatrixArray(); // Requiered for chamberInGeometry()
43
44 mSimParam.cacheMagField();
45
46 // obtain the number of threads from configuration
47#ifdef WITH_OPENMP
48 int askedthreads = TRDSimParams::Instance().digithreads;
49 int maxthreads = omp_get_max_threads();
50 if (askedthreads < 0) {
51 mNumThreads = maxthreads;
52 } else {
53 mNumThreads = std::min(maxthreads, askedthreads);
54 }
55 LOG(info) << "TRD: Digitizing with " << mNumThreads << " threads ";
56#endif
57
58 // initialize structures that we need per thread
59 mGausRandomRings.resize(mNumThreads);
60 mFlatRandomRings.resize(mNumThreads);
61 mLogRandomRings.resize(mNumThreads);
62 for (int i = 0; i < mNumThreads; ++i) {
63 mGausRandomRings[i].initialize(RandomRing<>::RandomType::Gaus);
64 mFlatRandomRings[i].initialize(RandomRing<>::RandomType::Flat);
65 mLogRandomRings[i].initialize([]() -> float { return std::log(gRandom->Rndm()); });
66 mDriftEstimators.emplace_back(mSimParam.getGasMixture(), mSimParam.getCachedField());
67 }
68
69 setSimulationParameters();
70}
71
72void Digitizer::setSimulationParameters()
73{
74 mNpad = mSimParam.getNumberOfPadsInPadResponse(); // Number of pads included in the pad response
75 if (mSimParam.trfOn()) {
76 mTimeBinTRFend = ((int)(mSimParam.getTRFhi() * mSimParam.getSamplingFrequency())) - 1;
77 }
78 mMaxTimeBins = TIMEBINS; // for signals, usually set at 30 tb = 3 microseconds
79 mMaxTimeBinsTRAP = TIMEBINS; // for adcs; should be read from the CCDB or the TRAP config
80 mSamplingRate = mSimParam.getSamplingFrequency();
81 mElAttachProp = mSimParam.getElAttachProp() / 100;
82}
83
85{
86 if (mPileupSignals.size() > 0) {
87 // Add the signals, all chambers are keept in the same signal container
88 SignalContainer smc = addSignalsFromPileup();
89 if (smc.size() > 0) {
90 bool status = convertSignalsToADC(smc, digits);
91 if (!status) {
92 LOG(warn) << "TRD conversion of signals to digits failed";
93 }
94 dumpLabels(smc, labels);
95 }
96 } else {
97 // since we don't have any pileup signals just flush the signals for each chamber
98 // we avoid flattening the array<map, ndets> to a single map
99 for (auto& smc : mSignalsMapCollection) {
100 bool status = convertSignalsToADC(smc, digits);
101 if (!status) {
102 LOG(warn) << "TRD conversion of signals to digits failed";
103 }
104 dumpLabels(smc, labels);
105 }
106 }
107 clearContainers();
108}
109
111{
112 for (const auto& iter : smc) {
113 if (iter.second.isDigit) {
114 labels.addElements(labels.getIndexedSize(), iter.second.labels);
115 if (iter.second.isShared) {
116 labels.addElements(labels.getIndexedSize(), iter.second.labels); // shared digit is a copy of the previous one, need to add the same labels again
117 }
118 }
119 }
120}
121
122SignalContainer Digitizer::addSignalsFromPileup()
123{
124 return pileupTool.addSignals(mPileupSignals, mCurrentTriggerTime);
125}
126
128{
129 mPileupSignals.push_back(mSignalsMapCollection);
130 clearContainers();
131}
132
133void Digitizer::clearContainers()
134{
135 for (auto& sm : mSignalsMapCollection) {
136 sm.clear();
137 }
138}
139
140void Digitizer::process(std::vector<Hit> const& hits)
141{
142
143 // Get the a hit container for all the hits in a given detector then call convertHits for a given detector (0 - 539)
144 std::array<std::vector<Hit>, MAXCHAMBER> hitsPerDetector;
145 getHitContainerPerDetector(hits, hitsPerDetector);
146
147#ifdef WITH_OPENMP
148// Loop over all TRD detectors (in a parallel fashion)
149#pragma omp parallel for schedule(dynamic) num_threads(mNumThreads)
150#endif
151 for (int det = 0; det < MAXCHAMBER; ++det) {
152#ifdef WITH_OPENMP
153 const int threadid = omp_get_thread_num();
154#else
155 const int threadid = 0;
156#endif
157 auto& signalsMap = mSignalsMapCollection[det];
158 // Jump to the next detector if the detector is
159 // switched off, not installed, etc
160 // In the chamber Fed status, 3 corresponds to good chamber
161 if (getFedChamberStatus(det) != 3) {
162 continue;
163 }
164 if (!mGeo->chamberInGeometry(det)) {
165 continue;
166 }
167
168 // Go to the next detector if there are no hits
169 if (hitsPerDetector[det].size() == 0) {
170 continue;
171 }
172
173 if (!convertHits(det, hitsPerDetector[det], signalsMap, threadid)) {
174 LOG(warn) << "TRD conversion of hits failed for detector " << det;
175 continue; // go to the next chamber
176 }
177 }
178}
179
180void Digitizer::getHitContainerPerDetector(const std::vector<Hit>& hits, std::array<std::vector<Hit>, MAXCHAMBER>& hitsPerDetector)
181{
182 //
183 // Fill an array of size MAXCHAMBER (540)
184 // The i-element of the array contains the hit collection for the i-detector
185 // To be called once, before doing the loop over all detectors and process the hits
186 //
187 for (const auto& hit : hits) {
188 hitsPerDetector[hit.GetDetectorID()].push_back(hit);
189 }
190}
191
192bool Digitizer::convertHits(const int det, const std::vector<Hit>& hits, SignalContainer& signalMapCont, int thread)
193{
194 //
195 // Convert the detector-wise sorted hits to detector signals
196 //
197
198 double padSignal[mNpad];
199
200 const double calExBDetValue = mCalVdriftExB->getExB(det, true); // T * V/cm (check units)
201 const PadPlane* padPlane = mGeo->getPadPlane(det);
202 const int layer = mGeo->getLayer(det);
203 const float rowEndROC = padPlane->getRowEndROC();
204 const float row0 = padPlane->getRow0ROC();
205 const int nColMax = padPlane->getNcols();
206
207 // Loop over hits
208 for (const auto& hit : hits) {
209 const int qTotal = hit.GetCharge();
210 /*
211 Now the real local coordinate system of the ROC
212 column direction: locC
213 row direction: locR
214 time direction: locT
215 locR and locC are identical to the coordinates of the corresponding
216 volumina of the drift or amplification region.
217 locT is defined relative to the wire plane (i.e. middle of amplification
218 region), meaning locT = 0, and is negative for hits coming from the
219 drift region.
220 */
221 double locC = hit.getLocalC(); // col direction in amplification or drift volume
222 double locR = hit.getLocalR(); // row direction in amplification or drift volume
223 double locT = hit.getLocalT(); // time direction in amplification or drift volume
224 const double driftLength = -1 * locT; // The drift length in cm without diffusion
225 // Patch to take care of TR photons that are absorbed
226 // outside the chamber volume. A real fix would actually need
227 // a more clever implementation of the TR hit generation
228 if (qTotal < 0) {
229 if ((locR < rowEndROC) || (locR > row0)) {
230 continue;
231 }
232 if ((driftLength < DrMin) || (driftLength > DrMax)) {
233 continue;
234 }
235 }
236
237 int rowE = padPlane->getPadRowNumberROC(locR);
238 if (rowE < 0) {
239 continue;
240 }
241
242 double rowOffset = padPlane->getPadRowOffsetROC(rowE, locR);
243 double offsetTilt = padPlane->getTiltOffset(rowE, rowOffset);
244 int colE = padPlane->getPadColNumber(locC + offsetTilt);
245 if (colE < 0) {
246 continue;
247 }
248
249 double absDriftLength = std::fabs(driftLength); // Normalized drift length
250 if (mSimParam.isExBOn()) {
251 absDriftLength /= std::sqrt(1 / (1 + calExBDetValue * calExBDetValue));
252 }
253
254 float driftVelocity = constants::VDRIFTDEFAULT; // The default drift velocity
255 if (TMath::Abs(mCalVdriftExB->getVdrift(det, true) - constants::VDRIFTDEFAULT) > 1e-6) {
256 driftVelocity = mCalVdriftExB->getVdrift(det, true) * constants::VDRIFTDEFAULT / mSimParam.getEffVdriftDefault(); // If they are available in the CCDB, we anchor the vdrift variations
257 }
258 float t0 = mSimParam.getT0(); // The T0 velocity
259
260 // Loop over all created electrons
261 const int nElectrons = std::fabs(qTotal);
262 for (int el = 0; el < nElectrons; ++el) {
263 // Electron attachment
264 if (mSimParam.elAttachOn()) {
265 if (mFlatRandomRings[thread].getNextValue() < absDriftLength * mElAttachProp) {
266 continue;
267 }
268 }
269 // scoped diffused coordinates for each electron
270 double locRd{locR}, locCd{locC}, locTd{locT};
271
272 // Apply diffusion smearing
273 if (mSimParam.diffusionOn()) {
274 if (!diffusion(driftVelocity, absDriftLength, calExBDetValue, locR, locC, locT, locRd, locCd, locTd, thread)) {
275 continue;
276 }
277 }
278
279 // Apply E x B effects
280 if (mSimParam.isExBOn()) {
281 // minus sign is necessary to be compatible with how Vdrift and ExB are calibrated
282 locCd = locCd - TMath::Tan(calExBDetValue) * driftLength;
283 }
284 // The electron position after diffusion and ExB in pad coordinates.
285 rowE = padPlane->getPadRowNumberROC(locRd);
286 if (rowE < 0) {
287 continue;
288 }
289 rowOffset = padPlane->getPadRowOffsetROC(rowE, locRd);
290 // The pad column (rphi-direction)
291 offsetTilt = padPlane->getTiltOffset(rowE, rowOffset);
292 colE = padPlane->getPadColNumber(locCd + offsetTilt);
293 if (colE < 0) {
294 continue;
295 }
296 const double colOffset = padPlane->getPadColOffset(colE, locCd + offsetTilt);
297 // Convert the position to drift time [mus], using either constant drift velocity or
298 // time structure of drift cells (non-isochronity, GARFIELD calculation).
299 // Also add absolute time of hits to take pile-up events into account properly
300 double driftTime;
301 if (mSimParam.timeStructOn()) {
302 // Get z-position with respect to anode wire
303 double zz = row0 - locRd + padPlane->getAnodeWireOffset();
304 zz -= ((int)(2 * zz)) * 0.5;
305 if (zz > 0.25) {
306 zz = 0.5 - zz;
307 }
308 // Use drift time map (GARFIELD)
309 driftTime = mDriftEstimators[thread].timeStruct(driftVelocity, 0.5 * AmWidth - 1.0 * locTd, zz, &(mFlagVdriftOutOfRange[det])) + hit.GetTime();
310 } else {
311 // Use constant drift velocity
312 driftTime = std::fabs(locTd) / driftVelocity + hit.GetTime(); // drift time in microseconds
313 }
314
315 // Apply the gas gain including fluctuations
316 double timeDepGainFactor = mCalGain->getMPVdEdx(det, true) / constants::MPVDEDXDEFAULT;
317 const double signal = -(mSimParam.getGasGain()) * timeDepGainFactor * mLogRandomRings[thread].getNextValue();
318
319 // Apply the pad response
320 if (mSimParam.prfOn()) {
321 // The distance of the electron to the center of the pad in units of pad width
322 double dist = (colOffset - 0.5 * padPlane->getColSize(colE)) / padPlane->getColSize(colE);
323 // ********************************************************************************
324 // This is a fixed parametrization, i.e. not dependent on calibration values !
325 // ********************************************************************************
326 if (!(mPRF.getPRF(signal, dist, layer, padSignal))) {
327 continue;
328 }
329 } else {
330 padSignal[0] = 0;
331 padSignal[1] = signal;
332 padSignal[2] = 0;
333 }
334
335 // The time bin (always positive), with t0 distortion
336 double timeBinIdeal = (driftTime + t0) * mSamplingRate;
337 // Protection
338 if (std::fabs(timeBinIdeal) > (2 * mMaxTimeBins)) { // OS: why 2*mMaxTimeBins?
339 timeBinIdeal = 2 * mMaxTimeBins;
340 }
341 int timeBinTruncated = ((int)timeBinIdeal);
342 // The distance of the position to the middle of the timebin
343 double timeOffset = ((float)timeBinTruncated + 0.5 - timeBinIdeal) / mSamplingRate;
344 // Sample the time response inside the drift region + additional time bins before and after.
345 // The sampling is done always in the middle of the time bin
346 const int firstTimeBin = std::max(timeBinTruncated, 0);
347 const int lastTimeBin = std::min(timeBinTruncated + mTimeBinTRFend, mMaxTimeBins);
348
349 // loop over pads first then over timebins for better cache friendliness
350 // and less access to signalMapCont
351 for (int pad = 0; pad < mNpad; ++pad) {
352 int colPos = colE + pad - 1;
353 if (colPos < 0) {
354 continue;
355 }
356 if (colPos >= nColMax) {
357 break;
358 }
359
360 const int key = calculateKey(det, rowE, colPos);
361 auto& currentSignalData = signalMapCont[key]; // Get the old signal or make a new one if it doesn't exist
362 auto& currentSignal = currentSignalData.signals;
363 auto& trackIds = currentSignalData.trackIds;
364 auto& labels = currentSignalData.labels;
365 currentSignalData.firstTBtime = mTime;
366 addLabel(hit.GetTrackID(), labels, trackIds); // add a label record only if needed
367
368 // add signal with crosstalk for the non-central pads only
369 if (colPos != colE) {
370 for (int tb = firstTimeBin; tb < lastTimeBin; ++tb) {
371 const double t = (tb - timeBinTruncated) / mSamplingRate + timeOffset;
372 const double timeResponse = mSimParam.trfOn() ? mSimParam.timeResponse(t) : 1;
373 const double crossTalk = mSimParam.ctOn() ? mSimParam.crossTalk(t) : 0;
374 currentSignal[tb] += padSignal[pad] * (timeResponse + crossTalk);
375 } // end of loop time bins
376 } else {
377 for (int tb = firstTimeBin; tb < lastTimeBin; ++tb) {
378 const double t = (tb - timeBinTruncated) / mSamplingRate + timeOffset;
379 const double timeResponse = mSimParam.trfOn() ? mSimParam.timeResponse(t) : 1;
380 currentSignal[tb] += padSignal[pad] * timeResponse;
381 } // end of loop time bins
382 }
383 } // end of loop over pads
384 } // end of loop over electrons
385 } // end of loop over hits
386 return true;
387}
388
389void Digitizer::addLabel(const int& trackId, std::vector<o2::MCCompLabel>& labels, std::unordered_set<int>& trackIds)
390{
391 if (trackIds.count(trackId) == 0) {
392 trackIds.insert(trackId);
393 MCLabel label(trackId, getEventID(), getSrcID());
394 labels.push_back(label);
395 }
396}
397
398float drawGaus(o2::math_utils::RandomRing<>& normaldistRing, float mu, float sigma)
399{
400 // this is using standard normally distributed random numbers and rescaling to make
401 // them gaussian distributed with general mu and sigma
402 return mu + sigma * normaldistRing.getNextValue();
403}
404
405bool Digitizer::convertSignalsToADC(SignalContainer& signalMapCont, DigitContainer& digits, int thread)
406{
407 //
408 // Converts the sampled electron signals to ADC values for a given chamber
409 //
410
411 constexpr double kEl2fC = 1.602e-19 * 1.0e15; // Converts number of electrons to fC
412 double coupling = mSimParam.getPadCoupling() * mSimParam.getTimeCoupling(); // Coupling factor
413 double convert = kEl2fC * mSimParam.getChipGain(); // Electronics conversion factor
414 double adcConvert = mSimParam.getADCoutRange() / mSimParam.getADCinRange(); // ADC conversion factor
415 double baseline = mSimParam.getADCbaseline() / adcConvert; // The electronics baseline in mV
416 double baselineEl = baseline / convert; // The electronics baseline in electrons
417
418 for (auto& signalMapIter : signalMapCont) {
419 const auto key = signalMapIter.first;
420 const int det = getDetectorFromKey(key);
421 const int row = getRowFromKey(key);
422 const int col = getColFromKey(key);
423 // halfchamber masking
424 int mcm = (int)(col / 18); // current group of 18 col pads
425 int halfchamberside = (mcm > 3) ? 1 : 0; // 0=Aside, 1=Bside
426
427 // Check whether pad is masked
428 // Bridged pads are not considered yet!!!
429 if (mPadStatus->isMasked(det, col, row) || mPadStatus->isNotConnected(det, col, row)) {
430 continue;
431 }
432
433 float padgain = std::fabs(mLocalGainFactor->getValue(det, col, row)); // The gain factor
434 if (padgain <= 0) {
435 LOG(fatal) << "Not a valid gain " << padgain << ", " << det << ", " << col << ", " << row;
436 }
437
438 signalMapIter.second.isDigit = true; // flag the signal as digit
439 // Loop over the all timebins in the ADC array
440 const auto& signalArray = signalMapIter.second.signals;
441 ArrayADC adcs{};
442 for (int tb = 0; tb < mMaxTimeBinsTRAP; ++tb) {
443 float signalAmp = (float)signalArray[tb]; // The signal amplitude
444 signalAmp *= coupling; // Pad and time coupling
445 signalAmp *= padgain; // Gain factors
446 // Add the noise, starting from minus ADC baseline in electrons
447 signalAmp = std::max((double)drawGaus(mGausRandomRings[thread], signalAmp, mSimParam.getNoise()), -baselineEl);
448 signalAmp *= convert; // Convert to mV
449 signalAmp += baseline; // Add ADC baseline in mV
450 // Convert to ADC counts
451 // Set the overflow-bit fADCoutRange if the signal is larger than fADCinRange
452 ADC_t adc = 0;
453 if (signalAmp >= mSimParam.getADCinRange()) {
454 adc = ((ADC_t)mSimParam.getADCoutRange());
455 } else {
456 adc = std::lround(signalAmp * adcConvert);
457 }
458 // update the adc array value
459 adcs[tb] = adc;
460 } // loop over timebins
461 // Convert the map to digits here, and push them to the container
462 digits.emplace_back(det, row, col, adcs);
463 if (mCreateSharedDigits) {
464 auto digit = digits.back();
465 if ((digit.getChannel() == 2) && !((digit.getROB() % 2 != 0) && (digit.getMCM() % NMCMROBINCOL == 3))) {
466 // shared left, if not leftmost MCM of left ROB of chamber
467 int robShared = (digit.getMCM() % NMCMROBINCOL == 3) ? digit.getROB() + 1 : digit.getROB(); // for the leftmost MCM on a ROB the shared digit is added to the neighbouring ROB
468 int mcmShared = (robShared == digit.getROB()) ? digit.getMCM() + 1 : digit.getMCM() - 3;
469 digits.emplace_back(det, robShared, mcmShared, NADCMCM - 1, adcs);
470 signalMapIter.second.isShared = true;
471 } else if ((digit.getChannel() == 18 || digit.getChannel() == 19) && !((digit.getROB() % 2 == 0) && (digit.getMCM() % NMCMROBINCOL == 0))) {
472 // shared right, if not rightmost MCM of right ROB of chamber
473 int robShared = (digit.getMCM() % NMCMROBINCOL == 0) ? digit.getROB() - 1 : digit.getROB(); // for the rightmost MCM on a ROB the shared digit is added to the neighbouring ROB
474 int mcmShared = (robShared == digit.getROB()) ? digit.getMCM() - 1 : digit.getMCM() + 3;
475 digits.emplace_back(det, robShared, mcmShared, digit.getChannel() - NCOLMCM, adcs);
476 signalMapIter.second.isShared = true;
477 }
478 }
479 } // loop over digits
480 return true;
481}
482
483bool Digitizer::diffusion(float vdrift, float absdriftlength, float exbvalue,
484 float lRow0, float lCol0, float lTime0,
485 double& lRow, double& lCol, double& lTime, int thread)
486{
487 //
488 // Applies the diffusion smearing to the position of a single electron.
489 // Depends on absolute drift length.
490 //
491 float diffL = 0.0;
492 float diffT = 0.0;
493 if (mDriftEstimators[thread].getDiffCoeff(diffL, diffT, vdrift)) {
494 float driftSqrt = std::sqrt(absdriftlength);
495 float sigmaT = driftSqrt * diffT;
496 float sigmaL = driftSqrt * diffL;
497 lRow = drawGaus(mGausRandomRings[thread], lRow0, sigmaT);
498 if (mSimParam.isExBOn()) {
499 const float exbfactor = 1.f / (1.f + exbvalue * exbvalue);
500 lCol = drawGaus(mGausRandomRings[thread], lCol0, sigmaT * exbfactor);
501 lTime = drawGaus(mGausRandomRings[thread], lTime0, sigmaL * exbfactor);
502 } else {
503 lCol = drawGaus(mGausRandomRings[thread], lCol0, sigmaT);
504 lTime = drawGaus(mGausRandomRings[thread], lTime0, sigmaL);
505 }
506 return true;
507 } else {
508 return false;
509 }
510}
511
513{
514 std::string retVal = "";
515 for (int iDet = 0; iDet < MAXCHAMBER; ++iDet) {
516 if (mFlagVdriftOutOfRange[iDet]) {
517 retVal += std::to_string(iDet);
518 retVal += ", ";
519 }
520 }
521 if (!retVal.empty()) {
522 retVal.erase(retVal.size() - 2);
523 }
524 return retVal;
525}
uint16_t mcm
Definition of the GeometryManager class.
int32_t i
int32_t retVal
std::vector< o2::MCCompLabel > labels
uint32_t col
Definition RawData.h:4
float drawGaus(o2::math_utils::RandomRing<> &normaldistRing, float mu, float sigma)
StringRef key
A container to hold and manage MC truth information/labels.
float getMPVdEdx(int iDet, bool defaultAvg=true) const
Definition CalGain.h:36
float getExB(int iDet, bool defaultAvg=true) const
float getVdrift(int iDet, bool defaultAvg=true) const
void process(std::vector< Hit > const &)
void dumpLabels(const SignalContainer &, o2::dataformats::MCTruthContainer< MCLabel > &)
void flush(DigitContainer &, o2::dataformats::MCTruthContainer< MCLabel > &)
Definition Digitizer.cxx:84
int getFedChamberStatus(int det)
Definition Digitizer.h:83
int getSrcID() const
Definition Digitizer.h:81
std::string dumpFlaggedChambers() const
int getEventID() const
Definition Digitizer.h:80
bool createClusterMatrixArray()
static Geometry * instance()
Definition Geometry.h:33
bool chamberInGeometry(int det) const
T getValue(int roc, int col, int row) const
int getPRF(double, double, int, double *) const
bool isNotConnected(int roc, int col, int row) const
bool isMasked(int roc, int col, int row) const
float getADCoutRange() const
Definition SimParam.h:74
bool timeStructOn() const
Definition SimParam.h:86
float getCachedField() const
Definition SimParam.cxx:48
float getGasGain() const
Definition SimParam.h:71
float getEffVdriftDefault() const
Definition SimParam.h:70
double timeResponse(double) const
Definition SimParam.cxx:58
float getNoise() const
Definition SimParam.h:72
float getT0() const
Definition SimParam.h:69
double crossTalk(double) const
Definition SimParam.cxx:75
bool isExBOn() const
Definition SimParam.h:91
bool trfOn() const
Definition SimParam.h:84
GasMixture getGasMixture() const
Definition SimParam.h:94
float getTRFhi() const
Definition SimParam.h:78
bool ctOn() const
Definition SimParam.h:85
bool diffusionOn() const
Definition SimParam.h:81
bool prfOn() const
Definition SimParam.h:87
float getADCinRange() const
Definition SimParam.h:75
float getPadCoupling() const
Definition SimParam.h:79
int getADCbaseline() const
Definition SimParam.h:76
bool elAttachOn() const
Definition SimParam.h:82
float getTimeCoupling() const
Definition SimParam.h:80
float getElAttachProp() const
Definition SimParam.h:83
float getSamplingFrequency() const
Definition SimParam.h:95
int getNumberOfPadsInPadResponse() const
Definition SimParam.h:88
float getChipGain() const
Definition SimParam.h:73
GLsizeiptr size
Definition glcorearb.h:659
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
Definition glcorearb.h:5034
uint8_t int statusCode int
constexpr double VDRIFTDEFAULT
default value for vDrift
Definition Constants.h:81
std::uint16_t ADC_t
Definition Digit.h:31
std::unordered_map< int, SignalArray > SignalContainer
Definition Digitizer.h:47
std::vector< Digit > DigitContainer
Definition Digitizer.h:46
std::array< ADC_t, constants::TIMEBINS > ArrayADC
Definition Digit.h:32
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
SignalContainer addSignals(std::deque< std::array< SignalContainer, constants::MAXCHAMBER > > &, const double &)
int digithreads
number of digitizer threads
std::vector< uint64_t > convert(gsl::span< const uint64_t > page)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits
std::vector< int > row
ArrayADC adc