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