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