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
14
17#include "ITS3Base/ITS3Params.h"
18#include "MathUtils/Cartesian.h"
21#include "ITS3Base/SpecsV2.h"
22#include "Framework/Logger.h"
23
24#include <TRandom.h>
25#include <algorithm>
26#include <vector>
27#include <numeric>
28
29using o2::itsmft::Hit;
33
34using namespace o2::its3;
35
37{
38 const int numOfChips = mGeometry->getNumberOfChips();
39 mChips.resize(numOfChips);
40 for (int i = numOfChips; i--;) {
41 mChips[i].setChipIndex(i);
42 if (mDeadChanMap != nullptr) {
43 mChips[i].disable(mDeadChanMap->isFullChipMasked(i));
44 mChips[i].setDeadChanMap(mDeadChanMap);
45 }
46 }
47
48 if (!mParams.hasResponseFunctions()) {
49 auto loadSetResponseFunc = [&](const char* name, const char* fileIB, const char* nameIB, const char* fileOB, const char* nameOB) {
50 LOGP(info, "Loading response function for {}: IB={}:{} ; OB={}:{}", name, nameIB, fileIB, nameOB, fileOB);
51 auto fIB = TFile::Open(fileIB, "READ");
52 if (!fIB || fIB->IsZombie() || !fIB->IsOpen()) {
53 LOGP(fatal, "Cannot open file {}", fileIB);
54 }
55 auto fOB = TFile::Open(fileOB, "READ");
56 if (!fOB || fOB->IsZombie() || !fOB->IsOpen()) {
57 LOGP(fatal, "Cannot open file {}", fileOB);
58 }
59 mParams.setIBSimResponse(mSimRespIB = fIB->Get<o2::itsmft::AlpideSimResponse>(nameIB));
60 mParams.setOBSimResponse(mSimRespOB = fOB->Get<o2::itsmft::AlpideSimResponse>(nameOB));
61 fIB->Close();
62 fOB->Close();
63 };
64
65 if (const auto& func = ITS3Params::Instance().chipResponseFunction; func == "Alpide") {
66 constexpr const char* responseFile = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root";
67 loadSetResponseFunc("Alpide", responseFile, "response0", responseFile, "response1");
68 mSimRespIBShift = mSimRespIB->getDepthMax() - SegmentationMosaix::SensorLayerThickness / 2.f + 10.e-4f;
69 mSimRespOBShift = mSimRespOB->getDepthMax() - SegmentationAlpide::SensorLayerThickness / 2.f;
70 } else if (func == "APTS") {
71 constexpr const char* responseFileIB = "$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/APTSResponseData.root";
72 constexpr const char* responseFileOB = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root";
73 loadSetResponseFunc("APTS", responseFileIB, "response1", responseFileOB, "response1");
74 mSimRespIBShift = mSimRespIB->getDepthMax() + (float)constants::pixelarray::pixels::apts::responseYShift;
75 mSimRespOBShift = mSimRespOB->getDepthMax() - SegmentationAlpide::SensorLayerThickness / 2.f;
76 mSimRespIBScaleX = 0.5f * constants::pixelarray::pixels::apts::pitchX / SegmentationMosaix::PitchRow;
77 mSimRespIBScaleZ = 0.5f * constants::pixelarray::pixels::apts::pitchZ / SegmentationMosaix::PitchCol;
78 mSimRespIBOrientation = true;
79 } else {
80 LOGP(fatal, "ResponseFunction '{}' not implemented!", func);
81 }
82 }
83 mParams.print();
84 LOGP(info, "IBShift = {} ; OBShift = {}", mSimRespIBShift, mSimRespOBShift);
85 LOGP(info, "IB-Scale: X={} ; Z={}", mSimRespIBScaleX, mSimRespIBScaleZ);
87}
88
89void Digitizer::process(const std::vector<itsmft::Hit>* hits, int evID, int srcID)
90{
91 // digitize single event, the time must have been set beforehand
92
93 LOG(info) << "Digitizing " << mGeometry->getName() << " hits of entry " << evID << " from source "
94 << srcID << " at time " << mEventTime << " ROFrame = " << mNewROFrame << ")"
95 << " cont.mode: " << isContinuous()
96 << " Min/Max ROFrames " << mROFrameMin << "/" << mROFrameMax;
97
98 // is there something to flush ?
99 if (mNewROFrame > mROFrameMin) {
100 fillOutputContainer(mNewROFrame - 1); // flush out all frame preceding the new one
101 }
102
103 int nHits = hits->size();
104 std::vector<int> hitIdx(nHits);
105 std::iota(std::begin(hitIdx), std::end(hitIdx), 0);
106 // sort hits to improve memory access
107 std::sort(hitIdx.begin(), hitIdx.end(),
108 [hits](auto lhs, auto rhs) {
109 return (*hits)[lhs].GetDetectorID() < (*hits)[rhs].GetDetectorID();
110 });
111 for (int i : hitIdx) {
112 processHit((*hits)[i], mROFrameMax, evID, srcID);
113 }
114 // in the triggered mode store digits after every MC event
115 // TODO: in the real triggered mode this will not be needed, this is actually for the
116 // single event processing only
117 if (!mParams.isContinuous()) {
118 fillOutputContainer(mROFrameMax);
119 }
120}
121
123{
124 // assign event time in ns
125 mEventTime = irt;
126 if (!mParams.isContinuous()) {
127 mROFrameMin = 0; // in triggered mode reset the frame counters
128 mROFrameMax = 0;
129 }
130 // RO frame corresponding to provided time
131 mCollisionTimeWrtROF = mEventTime.timeInBCNS; // in triggered mode the ROF starts at BC (is there a delay?)
132 if (mParams.isContinuous()) {
133 auto nbc = mEventTime.differenceInBC(mIRFirstSampledTF);
134 if (mCollisionTimeWrtROF < 0 && nbc > 0) {
135 nbc--;
136 }
137 mNewROFrame = nbc / mParams.getROFrameLengthInBC();
138 // in continuous mode depends on starts of periodic readout frame
139 mCollisionTimeWrtROF += (nbc % mParams.getROFrameLengthInBC()) * o2::constants::lhc::LHCBunchSpacingNS;
140 } else {
141 mNewROFrame = 0;
142 }
143
144 if (mNewROFrame < mROFrameMin) {
145 LOG(error) << "New ROFrame " << mNewROFrame << " (" << irt << ") precedes currently cashed " << mROFrameMin;
146 throw std::runtime_error("deduced ROFrame precedes already processed one");
147 }
148
149 if (mParams.isContinuous() && mROFrameMax < mNewROFrame) {
150 mROFrameMax = mNewROFrame - 1; // all frames up to this are finished
151 }
152}
153
154void Digitizer::fillOutputContainer(uint32_t frameLast)
155{
156 // fill output with digits from min.cached up to requested frame, generating the noise beforehand
157 if (frameLast > mROFrameMax) {
158 frameLast = mROFrameMax;
159 }
160 // make sure all buffers for extra digits are created up to the maxFrame
161 getExtraDigBuffer(mROFrameMax);
162
163 LOG(info) << "Filling " << mGeometry->getName() << " digits output for RO frames " << mROFrameMin << ":"
164 << frameLast;
165
167
168 // we have to write chips in RO increasing order, therefore have to loop over the frames here
169 for (; mROFrameMin <= frameLast; mROFrameMin++) {
170 rcROF.setROFrame(mROFrameMin);
171 rcROF.setFirstEntry(mDigits->size()); // start of current ROF in digits
172
173 auto& extra = *(mExtraBuff.front().get());
174 for (size_t iChip{0}; iChip < mChips.size(); ++iChip) {
175 auto& chip = mChips[iChip];
176 if (constants::detID::isDetITS3(iChip)) { // Check if this is a chip of ITS3
177 chip.addNoise(mROFrameMin, mROFrameMin, &mParams, SegmentationMosaix::NRows, SegmentationMosaix::NCols);
178 } else {
179 chip.addNoise(mROFrameMin, mROFrameMin, &mParams);
180 }
181 auto& buffer = chip.getPreDigits();
182 if (buffer.empty()) {
183 continue;
184 }
185 auto itBeg = buffer.begin();
186 auto iter = itBeg;
187 ULong64_t maxKey = chip.getOrderingKey(mROFrameMin + 1, 0, 0) - 1; // fetch digits with key below that
188 for (; iter != buffer.end(); ++iter) {
189 if (iter->first > maxKey) {
190 break; // is the digit ROFrame from the key > the max requested frame
191 }
192 auto& preDig = iter->second; // preDigit
193 if (preDig.charge >= mParams.getChargeThreshold()) {
194 int digID = mDigits->size();
195 mDigits->emplace_back(chip.getChipIndex(), preDig.row, preDig.col, preDig.charge);
196 mMCLabels->addElement(digID, preDig.labelRef.label);
197 auto& nextRef = preDig.labelRef; // extra contributors are in extra array
198 while (nextRef.next >= 0) {
199 nextRef = extra[nextRef.next];
200 mMCLabels->addElement(digID, nextRef.label);
201 }
202 }
203 }
204 buffer.erase(itBeg, iter);
205 }
206 // finalize ROF record
207 rcROF.setNEntries(mDigits->size() - rcROF.getFirstEntry()); // number of digits
208 if (isContinuous()) {
209 rcROF.getBCData().setFromLong(mIRFirstSampledTF.toLong() + mROFrameMin * mParams.getROFrameLengthInBC());
210 } else {
211 rcROF.getBCData() = mEventTime; // RS TODO do we need to add trigger delay?
212 }
213 if (mROFRecords != nullptr) {
214 mROFRecords->push_back(rcROF);
215 }
216 extra.clear(); // clear container for extra digits of the mROFrameMin ROFrame
217 // and move it as a new slot in the end
218 mExtraBuff.emplace_back(mExtraBuff.front().release());
219 mExtraBuff.pop_front();
220 }
221}
222
223void Digitizer::processHit(const o2::itsmft::Hit& hit, uint32_t& maxFr, int evID, int srcID)
224{
225 // convert single hit to digits
226 int chipID = hit.GetDetectorID();
227 auto& chip = mChips[chipID];
228 if (chip.isDisabled()) {
229 return;
230 }
231 float timeInROF = hit.GetTime() * sec2ns;
232 if (timeInROF > 20e3) {
233 const int maxWarn = 10;
234 static int warnNo = 0;
235 if (warnNo < maxWarn) {
236 LOG(warning) << "Ignoring hit with time_in_event = " << timeInROF << " ns"
237 << ((++warnNo < maxWarn) ? "" : " (suppressing further warnings)");
238 }
239 return;
240 }
241 if (isContinuous()) {
242 timeInROF += mCollisionTimeWrtROF;
243 }
244 // calculate RO Frame for this hit
245 if (timeInROF < 0) {
246 timeInROF = 0.;
247 }
248 float tTot = mParams.getSignalShape().getMaxDuration();
249 // frame of the hit signal start wrt event ROFrame
250 int roFrameRel = int(timeInROF * mParams.getROFrameLengthInv());
251 // frame of the hit signal end wrt event ROFrame: in the triggered mode we read just 1 frame
252 uint32_t roFrameRelMax = mParams.isContinuous() ? (timeInROF + tTot) * mParams.getROFrameLengthInv() : roFrameRel;
253 int nFrames = roFrameRelMax + 1 - roFrameRel;
254 uint32_t roFrameMax = mNewROFrame + roFrameRelMax;
255 if (roFrameMax > maxFr) {
256 maxFr = roFrameMax; // if signal extends beyond current maxFrame, increase the latter
257 }
258
259 // here we start stepping in the depth of the sensor to generate charge diffision
260 float nStepsInv = mParams.getNSimStepsInv();
261 int nSteps = mParams.getNSimSteps();
262 int detID{hit.GetDetectorID()};
263 int layer = mGeometry->getLayer(detID);
264 const auto& matrix = mGeometry->getMatrixL2G(detID);
265 bool innerBarrel{layer < 3};
266 math_utils::Vector3D<float> xyzLocS, xyzLocE;
267 xyzLocS = matrix ^ (hit.GetPosStart()); // Global hit coordinates to local detector coordinates
268 xyzLocE = matrix ^ (hit.GetPos());
269 if (innerBarrel) {
270 // transform the point on the curved surface to a flat one
271 float xFlatE{0.f}, yFlatE{0.f}, xFlatS{0.f}, yFlatS{0.f};
272 mIBSegmentations[layer].curvedToFlat(xyzLocS.X(), xyzLocS.Y(), xFlatS, yFlatS);
273 mIBSegmentations[layer].curvedToFlat(xyzLocE.X(), xyzLocE.Y(), xFlatE, yFlatE);
274 // update the local coordinates with the flattened ones
275 xyzLocS.SetXYZ(xFlatS, yFlatS, xyzLocS.Z());
276 xyzLocE.SetXYZ(xFlatE, yFlatE, xyzLocE.Z());
277 }
278
280 step -= xyzLocS;
281 step *= nStepsInv; // position increment at each step
282 // the electrons will be injected in the middle of each step
283 math_utils::Vector3D<float> stepH(step * 0.5);
284 xyzLocS += stepH; // Adjust start position to the middle of the first step
285 xyzLocE -= stepH; // Adjust end position to the middle of the last step
286 int rowS = -1, colS = -1, rowE = -1, colE = -1, nSkip = 0;
287 if (innerBarrel) {
288 // get entrance pixel row and col
289 while (!mIBSegmentations[layer].localToDetector(xyzLocS.X(), xyzLocS.Z(), rowS, colS)) { // guard-ring ?
290 if (++nSkip >= nSteps) {
291 return; // did not enter to sensitive matrix
292 }
293 xyzLocS += step;
294 }
295 // get exit pixel row and col
296 while (!mIBSegmentations[layer].localToDetector(xyzLocE.X(), xyzLocE.Z(), rowE, colE)) { // guard-ring ?
297 if (++nSkip >= nSteps) {
298 return; // did not enter to sensitive matrix
299 }
300 xyzLocE -= step;
301 }
302 } else {
303 // get entrance pixel row and col
304 while (!SegmentationAlpide::localToDetector(xyzLocS.X(), xyzLocS.Z(), rowS, colS)) { // guard-ring ?
305 if (++nSkip >= nSteps) {
306 return; // did not enter to sensitive matrix
307 }
308 xyzLocS += step;
309 }
310 // get exit pixel row and col
311 while (!SegmentationAlpide::localToDetector(xyzLocE.X(), xyzLocE.Z(), rowE, colE)) { // guard-ring ?
312 if (++nSkip >= nSteps) {
313 return; // did not enter to sensitive matrix
314 }
315 xyzLocE -= step;
316 }
317 }
318
319 // estimate the limiting min/max row and col where the non-0 response is possible
320 if (rowS > rowE) {
321 std::swap(rowS, rowE);
322 }
323 if (colS > colE) {
324 std::swap(colS, colE);
325 }
326 rowS -= AlpideRespSimMat::NPix / 2;
327 rowE += AlpideRespSimMat::NPix / 2;
328 rowS = std::max(rowS, 0);
329
330 const int maxNrows{innerBarrel ? SegmentationMosaix::NRows : SegmentationAlpide::NRows};
331 const int maxNcols{innerBarrel ? SegmentationMosaix::NCols : SegmentationAlpide::NCols};
332
333 rowE = std::min(rowE, maxNrows - 1);
334 colS -= AlpideRespSimMat::NPix / 2;
335 colE += AlpideRespSimMat::NPix / 2;
336 colS = std::max(colS, 0);
337 colE = std::min(colE, maxNcols - 1);
338
339 int rowSpan = rowE - rowS + 1, colSpan = colE - colS + 1; // size of plaquet where some response is expected
340 float respMatrix[rowSpan][colSpan]; // response accumulated here
341 std::fill(&respMatrix[0][0], &respMatrix[0][0] + rowSpan * colSpan, 0.f);
342
343 float nElectrons = hit.GetEnergyLoss() * mParams.getEnergyToNElectrons(); // total number of deposited electrons
344 nElectrons *= nStepsInv; // N electrons injected per step
345 if (nSkip != 0) {
346 nSteps -= nSkip;
347 }
348 //
349 int rowPrev = -1, colPrev = -1, row, col;
350 float cRowPix = 0.f, cColPix = 0.f; // local coordinated of the current pixel center
351
352 // take into account that the AlpideSimResponse depth defintion has different min/max boundaries
353 // although the max should coincide with the surface of the epitaxial layer, which in the chip
354 // local coordinates has Y = +SensorLayerThickness/2
355 xyzLocS.SetY(xyzLocS.Y() + ((innerBarrel) ? mSimRespIBShift : mSimRespOBShift));
356
357 // collect charge in evey pixel which might be affected by the hit
358 for (int iStep = nSteps; iStep--;) {
359 // Get the pixel ID
360 if (innerBarrel) {
361 mIBSegmentations[layer].localToDetector(xyzLocS.X(), xyzLocS.Z(), row, col);
362 } else {
363 SegmentationAlpide::localToDetector(xyzLocS.X(), xyzLocS.Z(), row, col);
364 }
365 if (row != rowPrev || col != colPrev) { // update pixel and coordinates of its center
366 if (innerBarrel) {
367 if (!mIBSegmentations[layer].detectorToLocal(row, col, cRowPix, cColPix)) {
368 continue;
369 }
370 } else if (!SegmentationAlpide::detectorToLocal(row, col, cRowPix, cColPix)) {
371 continue; // should not happen
372 }
373 rowPrev = row;
374 colPrev = col;
375 }
376 bool flipCol = false, flipRow = false;
377 // note that response needs coordinates along column row (locX) (locZ) then depth (locY)
378 float rowMax{}, colMax{};
379 const AlpideRespSimMat* rspmat{nullptr};
380 if (innerBarrel) {
381 rowMax = 0.5f * SegmentationMosaix::PitchRow;
382 colMax = 0.5f * SegmentationMosaix::PitchCol;
383 rspmat = mSimRespIB->getResponse(mSimRespIBScaleX * (xyzLocS.X() - cRowPix), mSimRespIBScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
384 } else {
385 rowMax = 0.5f * SegmentationAlpide::PitchRow;
386 colMax = 0.5f * SegmentationAlpide::PitchCol;
387 rspmat = mSimRespOB->getResponse(xyzLocS.X() - cRowPix, xyzLocS.Z() - cColPix, xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
388 }
389
390 xyzLocS += step;
391 if (rspmat == nullptr) {
392 continue;
393 }
394
395 for (int irow = AlpideRespSimMat::NPix; irow--;) {
396 int rowDest = row + irow - AlpideRespSimMat::NPix / 2 - rowS; // destination row in the respMatrix
397 if (rowDest < 0 || rowDest >= rowSpan) {
398 continue;
399 }
400 for (int icol = AlpideRespSimMat::NPix; icol--;) {
401 int colDest = col + icol - AlpideRespSimMat::NPix / 2 - colS; // destination column in the respMatrix
402 if (colDest < 0 || colDest >= colSpan) {
403 continue;
404 }
405 respMatrix[rowDest][colDest] += rspmat->getValue(irow, icol, ((innerBarrel && mSimRespIBOrientation) ? !flipRow : flipRow), flipCol);
406 }
407 }
408 }
409
410 // fire the pixels assuming Poisson(n_response_electrons)
411 o2::MCCompLabel lbl(hit.GetTrackID(), evID, srcID, false);
412 auto roFrameAbs = mNewROFrame + roFrameRel;
413 for (int irow = rowSpan; irow--;) {
414 uint16_t rowIS = irow + rowS;
415 for (int icol = colSpan; icol--;) {
416 float nEleResp = respMatrix[irow][icol];
417 if (nEleResp <= 1.e-36) {
418 continue;
419 }
420 int nEle = gRandom->Poisson(nElectrons * nEleResp); // total charge in given pixel
421 // ignore charge which have no chance to fire the pixel
422 if (nEle < mParams.getMinChargeToAccount()) {
423 continue;
424 }
425 uint16_t colIS = icol + colS;
426 registerDigits(chip, roFrameAbs, timeInROF, nFrames, rowIS, colIS, nEle, lbl);
427 }
428 }
429}
430
431void Digitizer::registerDigits(o2::itsmft::ChipDigitsContainer& chip, uint32_t roFrame, float tInROF, int nROF,
432 uint16_t row, uint16_t col, int nEle, o2::MCCompLabel& lbl)
433{
434 // Register digits for given pixel, accounting for the possible signal contribution to
435 // multiple ROFrame. The signal starts at time tInROF wrt the start of provided roFrame
436 // In every ROFrame we check the collected signal during strobe
437
438 float tStrobe = mParams.getStrobeDelay() - tInROF; // strobe start wrt signal start
439 for (int i = 0; i < nROF; i++) {
440 uint32_t roFr = roFrame + i;
441 int nEleROF = mParams.getSignalShape().getCollectedCharge(nEle, tStrobe, tStrobe + mParams.getStrobeLength());
442 tStrobe += mParams.getROFrameLength(); // for the next ROF
443
444 // discard too small contributions, they have no chance to produce a digit
445 if (nEleROF < mParams.getMinChargeToAccount()) {
446 continue;
447 }
448 if (roFr > mEventROFrameMax) {
449 mEventROFrameMax = roFr;
450 }
451 if (roFr < mEventROFrameMin) {
452 mEventROFrameMin = roFr;
453 }
454 auto key = chip.getOrderingKey(roFr, row, col);
455 PreDigit* pd = chip.findDigit(key);
456 if (pd == nullptr) {
457 chip.addDigit(key, roFr, row, col, nEleROF, lbl);
458 } else { // there is already a digit at this slot, account as PreDigitExtra contribution
459 pd->charge += nEleROF;
460 if (pd->labelRef.label == lbl) { // don't store the same label twice
461 continue;
462 }
463 ExtraDig* extra = getExtraDigBuffer(roFr);
464 int& nxt = pd->labelRef.next;
465 bool skip = false;
466 while (nxt >= 0) {
467 if ((*extra)[nxt].label == lbl) { // don't store the same label twice
468 skip = true;
469 break;
470 }
471 nxt = (*extra)[nxt].next;
472 }
473 if (skip) {
474 continue;
475 }
476 // new predigit will be added in the end of the chain
477 nxt = extra->size();
478 extra->emplace_back(lbl);
479 }
480 }
481}
int32_t i
Definition of a container to keep Monte Carlo truth external to simulation objects.
uint32_t col
Definition RawData.h:4
Definition of the SegmentationAlpide class.
Definition of the ITS digitizer.
StringRef key
int GetTrackID() const
Definition BaseHits.h:30
V GetEnergyLoss() const
Definition BaseHits.h:103
math_utils::Point3D< T > GetPos() const
Definition BaseHits.h:67
E GetTime() const
Definition BaseHits.h:71
short GetDetectorID() const
Definition BaseHits.h:73
void addElement(uint32_t dataindex, TruthElement const &element, bool noElement=false)
const char * getName() const
const Mat3D & getMatrixL2G(int sensID) const
bool hasResponseFunctions() const
Definition DigiParams.h:32
void setOBSimResponse(const o2::itsmft::AlpideSimResponse *response)
Definition DigiParams.h:27
void setIBSimResponse(const o2::itsmft::AlpideSimResponse *response)
Definition DigiParams.h:30
void print() const final
bool isContinuous() const
Definition Digitizer.h:63
void setEventTime(const o2::InteractionTimeRecord &irt)
void process(const std::vector< itsmft::Hit > *hits, int evID, int srcID)
Steer conversion of hits to digits.
Definition Digitizer.cxx:89
void fillOutputContainer(uint32_t maxFrame=0xffffffff)
static constexpr float SensorLayerThickness
static constexpr float PitchCol
static constexpr float PitchRow
int getLayer(int index) const
Get chip layer, from 0.
float getCollectedCharge(float totalNEle, float tMin, float tMax) const
bool getResponse(float vRow, float vCol, float cDepth, AlpideRespSimMat &dest) const
Container for similated points connected to a given chip.
void addDigit(ULong64_t key, UInt_t roframe, UShort_t row, UShort_t col, int charge, o2::MCCompLabel lbl)
o2::itsmft::PreDigit * findDigit(ULong64_t key)
static ULong64_t getOrderingKey(UInt_t roframe, UShort_t row, UShort_t col)
Get global ordering key made of readout frame, column and row.
int getMinChargeToAccount() const
Definition DigiParams.h:82
float getROFrameLengthInv() const
Definition DigiParams.h:59
const SignalShape & getSignalShape() const
Definition DigiParams.h:96
float getEnergyToNElectrons() const
Definition DigiParams.h:85
int getROFrameLengthInBC() const
Definition DigiParams.h:54
float getStrobeDelay() const
Definition DigiParams.h:62
bool isContinuous() const
Definition DigiParams.h:52
int getChargeThreshold() const
Definition DigiParams.h:81
float getNSimStepsInv() const
Definition DigiParams.h:84
float getROFrameLength() const
Definition DigiParams.h:58
int getNSimSteps() const
Definition DigiParams.h:83
float getStrobeLength() const
Definition DigiParams.h:65
Int_t getNumberOfChips() const
math_utils::Point3D< Float_t > GetPosStart() const
Definition Hit.h:60
bool isFullChipMasked(int chip) const
Definition NoiseMap.h:186
void setNEntries(int n)
Definition ROFRecord.h:48
const BCData & getBCData() const
Definition ROFRecord.h:58
void setFirstEntry(int idx)
Definition ROFRecord.h:47
int getFirstEntry() const
Definition ROFRecord.h:63
void setROFrame(ROFtype rof)
Definition ROFRecord.h:45
static constexpr float SensorLayerThickness
static bool localToDetector(float x, float z, int &iRow, int &iCol)
static constexpr float PitchCol
static constexpr float PitchRow
static bool detectorToLocal(L row, L col, T &xRow, T &zCol)
GLenum func
Definition glcorearb.h:778
GLuint buffer
Definition glcorearb.h:655
GLuint const GLchar * name
Definition glcorearb.h:781
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
constexpr double LHCBunchSpacingNS
bool isDetITS3(T detID)
Definition SpecsV2.h:211
value_T step
Definition TrackUtils.h:42
int64_t differenceInBC(const InteractionRecord &other) const
void setFromLong(int64_t l)
double timeInBCNS
time in NANOSECONDS relative to orbit/bc
int next
eventual next contribution to the same pixel
Definition PreDigit.h:36
o2::MCCompLabel label
hit label
Definition PreDigit.h:35
int charge
N electrons.
Definition PreDigit.h:46
PreDigitLabelRef labelRef
label and reference to the next one
Definition PreDigit.h:47
IR getFirstSampledTFIR() const
get TF and HB (abs) for this IR
Definition HBFUtils.h:74
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< int > row