26#include <fairlogger/Logger.h>
38 LOG(info) <<
"Initializing digitizer";
40 mChips.resize(mNumberOfChips);
41 for (
int i = mNumberOfChips;
i--;) {
42 mChips[
i].setChipIndex(
i);
44 mChips[
i].setNoiseMap(mNoiseMap);
48 mChips[
i].setDeadChanMap(mDeadChanMap);
54 mChipSimRespVD = mChipSimResp;
55 mChipSimRespMLOT = mChipSimResp;
60 LOG(info) <<
" Depth min VD: " << mChipSimRespVD->getDepthMin();
62 LOG(info) <<
" Depth max MLOT: " << mChipSimRespMLOT->getDepthMax();
63 LOG(info) <<
" Depth min MLOT: " << mChipSimRespMLOT->getDepthMin();
65 float thicknessVD = 0.0095;
68 LOG(info) <<
"Using response name: " << mRespName;
69 mSimRespOrientation =
false;
71 if (mRespName ==
"APTS") {
74 mSimRespVDShift = mChipSimRespVD->getDepthMax();
77 mSimRespOrientation =
true;
78 }
else if (mRespName ==
"ALICE3") {
81 mSimRespVDShift = mChipSimRespVD->getDepthMax();
85 LOG(fatal) <<
"Unknown response name: " << mRespName;
88 mSimRespMLOTShift = mChipSimRespMLOT->getDepthMax() - thicknessMLOT / 2.f;
93 LOGP(info,
"TRK Digitizer is initialised.");
95 LOGP(info,
"VD shift = {} ; ML/OT shift = {} = {} - {}", mSimRespVDShift, mSimRespMLOTShift, mChipSimRespMLOT->getDepthMax(), thicknessMLOT / 2.f);
96 LOGP(info,
"VD pixel scale on x = {} ; z = {}", mSimRespVDScaleX, mSimRespVDScaleZ);
97 LOGP(info,
"ML/OT pixel scale on x = {} ; z = {}", mSimRespMLOTScaleX, mSimRespMLOTScaleZ);
98 LOGP(info,
"Response orientation: {}", mSimRespOrientation ?
"flipped" :
"normal");
105 if (mGeometry->getSubDetID(chipID) == 0) {
106 return mChipSimRespVD;
109 else if (mGeometry->getSubDetID(chipID) == 1) {
110 return mChipSimRespMLOT;
120 LOG(info) <<
" Digitizing " << mGeometry->
getName() <<
" (ID: " << mGeometry->
getDetID()
121 <<
") hits of event " << evID <<
" from source " << srcID
122 <<
" at time " << mEventTime.
getTimeNS() <<
" ROFrame = " << mNewROFrame
124 <<
" Min/Max ROFrames " << mROFrameMin <<
"/" << mROFrameMax;
126 std::cout <<
"Printing segmentation info: " << std::endl;
130 if (mNewROFrame > mROFrameMin) {
134 int nHits = hits->size();
135 std::vector<int> hitIdx(nHits);
136 std::iota(std::begin(hitIdx), std::end(hitIdx), 0);
138 std::sort(hitIdx.begin(), hitIdx.end(),
139 [hits](
auto lhs,
auto rhs) {
140 return (*hits)[lhs].GetDetectorID() < (*hits)[rhs].GetDetectorID();
142 LOG(info) <<
"Processing " << nHits <<
" hits";
143 for (
int i : hitIdx) {
144 processHit((*hits)[
i], mROFrameMax, evID, srcID);
158 LOG(info) <<
"Setting event time to " << irt.
getTimeNS() <<
" ns after orbit 0 bc 0";
170 if (mCollisionTimeWrtROF < 0 && nbc > 0) {
176 LOG(
debug) <<
" NewROFrame " << mNewROFrame <<
" = " << nbc <<
"/" << mParams.
getROFrameLengthInBC() <<
" (nbc/mParams.getROFrameLengthInBC()";
184 if (mNewROFrame < mROFrameMin) {
185 LOG(error) <<
"New ROFrame " << mNewROFrame <<
" (" << irt <<
") precedes currently cashed " << mROFrameMin;
186 throw std::runtime_error(
"deduced ROFrame precedes already processed one");
189 if (mParams.
isContinuous() && mROFrameMax < mNewROFrame) {
190 mROFrameMax = mNewROFrame - 1;
198 if (frameLast > mROFrameMax) {
199 frameLast = mROFrameMax;
202 getExtraDigBuffer(mROFrameMax);
203 LOG(info) <<
"Filling " << mGeometry->
getName() <<
" digits output for RO frames " << mROFrameMin <<
":"
209 for (; mROFrameMin <= frameLast; mROFrameMin++) {
213 auto& extra = *(mExtraBuff.front().get());
214 for (
auto& chip : mChips) {
215 if (chip.isDisabled()) {
218 chip.addNoise(mROFrameMin, mROFrameMin, &mParams, mGeometry->getSubDetID(chip.getChipIndex()), mGeometry->
getLayer(chip.getChipIndex()));
219 auto&
buffer = chip.getPreDigits();
223 auto itBeg =
buffer.begin();
225 ULong64_t maxKey = chip.getOrderingKey(mROFrameMin + 1, 0, 0) - 1;
226 for (; iter !=
buffer.end(); ++iter) {
227 if (iter->first > maxKey) {
230 auto& preDig = iter->second;
232 int digID = mDigits->size();
233 mDigits->emplace_back(chip.getChipIndex(), preDig.row, preDig.col, preDig.charge);
234 LOG(
debug) <<
"Adding digit ID: " << digID <<
" with chipID: " << chip.getChipIndex() <<
", row: " << preDig.row <<
", col: " << preDig.col <<
", charge: " << preDig.charge;
235 mMCLabels->
addElement(digID, preDig.labelRef.label);
236 auto& nextRef = preDig.labelRef;
237 while (nextRef.next >= 0) {
238 nextRef = extra[nextRef.next];
243 buffer.erase(itBeg, iter);
253 mROFRecords->push_back(rcROF);
257 mExtraBuff.emplace_back(mExtraBuff.front().release());
258 mExtraBuff.pop_front();
263void Digitizer::processHit(
const o2::trk::Hit& hit, uint32_t& maxFr,
int evID,
int srcID)
266 int subDetID = mGeometry->getSubDetID(chipID);
269 int disk = mGeometry->getDisk(chipID);
272 LOG(
debug) <<
"Skipping disk " << disk;
276 LOG(
debug) <<
"Processing hit for chip " << chipID;
277 auto& chip = mChips[chipID];
278 if (chip.isDisabled()) {
279 LOG(
debug) <<
"Skipping disabled chip " << chipID;
282 float timeInROF = hit.
GetTime() * sec2ns;
283 LOG(
debug) <<
"Hit time: " << timeInROF <<
" ns";
284 if (timeInROF > 20e3) {
285 const int maxWarn = 10;
286 static int warnNo = 0;
287 if (warnNo < maxWarn) {
288 LOG(warning) <<
"Ignoring hit with time_in_event = " << timeInROF <<
" ns"
289 << ((++warnNo < maxWarn) ?
"" :
" (suppressing further warnings)");
294 timeInROF += mCollisionTimeWrtROF;
296 if (mIsBeforeFirstRO && timeInROF < 0) {
298 LOG(
debug) <<
"Ignoring hit with timeInROF = " << timeInROF;
311 int nFrames = roFrameRelMax + 1 - roFrameRel;
312 uint32_t roFrameMax = mNewROFrame + roFrameRelMax;
313 if (roFrameMax > maxFr) {
332 LOG(
debug) <<
"Called curved to flat: " << xyzLocS.x() <<
" -> " << xyFlatS.x() <<
", " << xyzLocS.y() <<
" -> " << xyFlatS.y();
334 xyzLocS.SetXYZ(xyFlatS.x(), xyFlatS.y(), xyzLocS.Z());
335 xyzLocE.SetXYZ(xyFlatE.x(), xyFlatE.y(), xyzLocE.Z());
353 LOG(
debug) <<
"Step into the sensitive volume: " <<
step <<
". Number of steps: " << nSteps;
354 int rowS = -1, colS = -1, rowE = -1, colE = -1, nSkip = 0;
359 if (++nSkip >= nSteps) {
360 LOG(
debug) <<
"Did not enter to sensitive matrix, " << nSkip <<
" >= " << nSteps;
368 if (++nSkip >= nSteps) {
369 LOG(
debug) <<
"Did not enter to sensitive matrix, " << nSkip <<
" >= " << nSteps;
380 std::swap(rowS, rowE);
383 std::swap(colS, colE);
401 int rowSpan = rowE - rowS + 1, colSpan = colE - colS + 1;
403 float respMatrix[rowSpan][colSpan];
404 std::fill(&respMatrix[0][0], &respMatrix[0][0] + rowSpan * colSpan, 0.f);
407 nElectrons *= nStepsInv;
412 int rowPrev = -1, colPrev = -1,
row,
col;
413 float cRowPix = 0.f, cColPix = 0.f;
424 xyzLocS.SetY(xyzLocS.Y() + ((subDetID == 0) ? mSimRespVDShift : mSimRespMLOTShift));
428 for (
int iStep = nSteps; iStep--;) {
431 if (
row != rowPrev ||
col != colPrev) {
438 bool flipCol =
false, flipRow =
false;
440 float rowMax{}, colMax{};
443 rowMax = 0.5f * Segmentation::PitchRowVD * mSimRespVDScaleX;
444 colMax = 0.5f * Segmentation::PitchColVD * mSimRespVDScaleZ;
445 rspmat = resp->
getResponse(mSimRespVDScaleX * (xyzLocS.X() - cRowPix), mSimRespVDScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
447 rowMax = 0.5f * Segmentation::PitchRowMLOT * mSimRespMLOTScaleX;
448 colMax = 0.5f * Segmentation::PitchColMLOT * mSimRespMLOTScaleZ;
449 rspmat = resp->
getResponse(mSimRespMLOTScaleX * (xyzLocS.X() - cRowPix), mSimRespMLOTScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
454 if (rspmat ==
nullptr) {
455 LOG(
debug) <<
"Error in rspmat for step " << iStep <<
" / " << nSteps;
464 if (rowDest < 0 || rowDest >= rowSpan) {
469 if (colDest < 0 || colDest >= colSpan) {
472 respMatrix[rowDest][colDest] += rspmat->getValue(irow, icol, mSimRespOrientation ? !flipRow : flipRow, flipCol);
479 auto roFrameAbs = mNewROFrame + roFrameRel;
480 LOG(
debug) <<
"\nSpanning through rows and columns; rowspan = " << rowSpan <<
" colspan = " << colSpan <<
" = " << colE <<
" - " << colS <<
" +1 ";
481 for (
int irow = rowSpan; irow--;) {
482 uint16_t rowIS = irow + rowS;
483 for (
int icol = colSpan; icol--;) {
484 float nEleResp = respMatrix[irow][icol];
485 if (nEleResp <= 1.e-36) {
488 LOG(
debug) <<
"nEleResp: value " << nEleResp <<
" for pixel " << irow <<
" " << icol;
489 int nEle = gRandom->Poisson(nElectrons * nEleResp);
490 LOG(
debug) <<
"Charge detected in the pixel: " << nEle <<
" for pixel " << irow <<
" " << icol;
493 LOG(
debug) <<
"Ignoring pixel with nEle = " << nEle <<
" < min charge to account "
498 uint16_t colIS = icol + colS;
499 if (mNoiseMap && mNoiseMap->
isNoisy(chipID, rowIS, colIS)) {
502 if (mDeadChanMap && mDeadChanMap->
isNoisy(chipID, rowIS, colIS)) {
505 registerDigits(chip, roFrameAbs, timeInROF, nFrames, rowIS, colIS, nEle, lbl);
517 LOG(
debug) <<
"Registering digits for chip " << chip.
getChipIndex() <<
" at ROFrame " << roFrame
518 <<
" row " <<
row <<
" col " <<
col <<
" nEle " << nEle <<
" label " << lbl;
520 for (
int i = 0;
i < nROF;
i++) {
521 uint32_t roFr = roFrame +
i;
529 if (roFr > mEventROFrameMax) {
530 mEventROFrameMax = roFr;
532 if (roFr < mEventROFrameMin) {
533 mEventROFrameMin = roFr;
539 LOG(
debug) <<
"Added digit with key: " <<
key <<
" ROF: " << roFr <<
" row: " <<
row <<
" col: " <<
col <<
" charge: " << nEleROF;
541 LOG(
debug) <<
"Added to pre-digit with key: " <<
key <<
" ROF: " << roFr <<
" row: " <<
row <<
" col: " <<
col <<
" charge: " << nEleROF;
546 ExtraDig* extra = getExtraDigBuffer(roFr);
550 if ((*extra)[nxt].
label == lbl) {
554 nxt = (*extra)[nxt].next;
561 extra->emplace_back(lbl);
Definition of the SegmentationChipclass.
Definition of the TRK digitizer.
math_utils::Point3D< T > GetPos() const
unsigned short GetDetectorID() const
static const DPLDigitizerParam< N > & Instance()
const char * getName() const
const o2::detectors::DetID & getDetID() const
const Mat3D & getMatrixL2G(int sensID) const
static int constexpr NPix
float getMaxDuration() const
float getCollectedCharge(float totalNEle, float tMin, float tMax) const
float getDepthMax() 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)
UShort_t getChipIndex() const
int getMinChargeToAccount() const
float getStrobeDelay(int layer=-1) const
const o2::itsmft::AlpideSimResponse * getAlpSimResponse() const
virtual void print() const
float getROFrameLengthInv(int layer=-1) const
const SignalShape & getSignalShape() const
float getStrobeLength(int layer=-1) const
float getEnergyToNElectrons() const
int getROFrameLengthInBC(int layer=-1) const
bool isContinuous() const
int getChargeThreshold() const
float getNSimStepsInv() const
float getROFrameLength(int layer=-1) const
void fillOutputContainer(uint32_t maxFrame=0xffffffff, int layer=-1)
auto getChipResponse(int chipID)
bool isContinuous() const
void setEventTime(const o2::InteractionTimeRecord &irt, int layer=-1)
void process(const std::vector< Hit > *hits, int evID, int srcID, int layer=-1)
Steer conversion of hits to digits.
virtual Int_t getLayer(Int_t index) const
Int_t getNumberOfChips() const
math_utils::Point3D< Float_t > GetPosStart() const
bool isFullChipMasked(int chip) const
bool isNoisy(int chip, int row, int col) const
const BCData & getBCData() const
void setFirstEntry(int idx)
int getFirstEntry() const
void setROFrame(ROFtype rof)
static bool localToDetector(float x, float z, int &iRow, int &iCol)
static bool detectorToLocal(L row, L col, T &xRow, T &zCol)
static ULong64_t getOrderingKey(UInt_t roframe, UShort_t row, UShort_t col)
Get global ordering key made of readout frame, column and row.
static constexpr float PitchColVD
static constexpr float PitchColMLOT
static constexpr float PitchRowMLOT
static void Print() noexcept
Print segmentation info.
static constexpr float PitchRowVD
static constexpr float SiliconThicknessMLOT
GLuint GLsizei const GLchar * label
GLenum GLuint GLint GLint layer
constexpr double LHCBunchSpacingNS
constexpr std::array< int, nLayers > nRows
int64_t differenceInBC(const InteractionRecord &other) const
void setFromLong(int64_t l)
double timeInBCNS
time in NANOSECONDS relative to orbit/bc
double getTimeNS() const
get time in ns from orbit=0/bc=0
int next
eventual next contribution to the same pixel
o2::MCCompLabel label
hit label
PreDigitLabelRef labelRef
label and reference to the next one
IR getFirstSampledTFIR() const
get TF and HB (abs) for this IR
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"