27#include <fairlogger/Logger.h>
39 LOG(info) <<
"Initializing digitizer";
41 mChips.resize(mNumberOfChips);
42 for (
int i = mNumberOfChips;
i--;) {
43 mChips[
i].setChipIndex(
i);
45 mChips[
i].setNoiseMap(mNoiseMap);
49 mChips[
i].setDeadChanMap(mDeadChanMap);
54 mChipSimResp = mParams.getResponse();
55 mChipSimRespVD = mChipSimResp;
56 mChipSimRespMLOT = mChipSimResp;
60 LOG(info) <<
" Depth max VD: " << mChipSimRespVD->getDepthMax();
61 LOG(info) <<
" Depth min VD: " << mChipSimRespVD->getDepthMin();
63 LOG(info) <<
" Depth max MLOT: " << mChipSimRespMLOT->getDepthMax();
64 LOG(info) <<
" Depth min MLOT: " << mChipSimRespMLOT->getDepthMin();
66 float thicknessVD = 0.0095;
69 LOG(info) <<
"Using response name: " << mRespName;
70 mSimRespOrientation =
false;
72 if (mRespName ==
"APTS") {
75 mSimRespVDShift = mChipSimRespVD->getDepthMax();
78 mSimRespOrientation =
true;
79 }
else if (mRespName ==
"ALICE3") {
82 mSimRespVDShift = mChipSimRespVD->getDepthMax();
86 LOG(fatal) <<
"Unknown response name: " << mRespName;
89 mSimRespMLOTShift = mChipSimRespMLOT->getDepthMax() - thicknessMLOT / 2.f;
94 LOGP(info,
"TRK Digitizer is initialised.");
96 LOGP(info,
"VD shift = {} ; ML/OT shift = {} = {} - {}", mSimRespVDShift, mSimRespMLOTShift, mChipSimRespMLOT->getDepthMax(), thicknessMLOT / 2.f);
97 LOGP(info,
"VD pixel scale on x = {} ; z = {}", mSimRespVDScaleX, mSimRespVDScaleZ);
98 LOGP(info,
"ML/OT pixel scale on x = {} ; z = {}", mSimRespMLOTScaleX, mSimRespMLOTScaleZ);
99 LOGP(info,
"Response orientation: {}", mSimRespOrientation ?
"flipped" :
"normal");
106 if (mGeometry->getSubDetID(chipID) == 0) {
107 return mChipSimRespVD;
110 else if (mGeometry->getSubDetID(chipID) == 1) {
111 return mChipSimRespMLOT;
121 LOG(info) <<
" Digitizing " << mGeometry->
getName() <<
" (ID: " << mGeometry->
getDetID()
122 <<
") hits of event " << evID <<
" from source " << srcID
123 <<
" 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";
147 return mGeometry->getLayerTRK((*hits)[idx].GetDetectorID()) ==
layer;
149 processHit((*hits)[
i], mROFrameMax, evID, srcID,
layer);
156 LOG(info) <<
"Setting event time to " << irt.
getTimeNS() <<
" ns after orbit 0 bc 0";
163 if (mCollisionTimeWrtROF < 0 && nbc > 0) {
174 LOG(
debug) <<
" NewROFrame " << mNewROFrame <<
" nbc " << nbc <<
" ROFsWrtFirstRO " << mROFsWrtFirstRO;
179 if (mNewROFrame < mROFrameMin) {
180 LOG(error) <<
"New ROFrame " << mNewROFrame <<
" (" << irt <<
") precedes currently cashed " << mROFrameMin;
181 throw std::runtime_error(
"deduced ROFrame precedes already processed one");
184 if (mROFrameMax < mNewROFrame) {
185 mROFrameMax = mNewROFrame - 1;
193 if (frameLast > mROFrameMax) {
194 frameLast = mROFrameMax;
197 getExtraDigBuffer(mROFrameMax);
198 LOG(info) <<
"Filling " << mGeometry->
getName() <<
" digits output for RO frames " << mROFrameMin <<
":"
204 for (; mROFrameMin <= frameLast; mROFrameMin++) {
208 auto& extra = *(mExtraBuff.front().get());
209 for (
auto& chip : mChips) {
210 if (chip.isDisabled() || (
layer >= 0 && mGeometry->getLayerTRK(chip.getChipIndex()) !=
layer)) {
213 chip.addNoise(mROFrameMin, mROFrameMin, &mParams, mGeometry->getSubDetID(chip.getChipIndex()), mGeometry->
getLayer(chip.getChipIndex()));
214 auto&
buffer = chip.getPreDigits();
218 auto itBeg =
buffer.begin();
220 ULong64_t maxKey = chip.getOrderingKey(mROFrameMin + 1, 0, 0) - 1;
221 for (; iter !=
buffer.end(); ++iter) {
222 if (iter->first > maxKey) {
225 auto& preDig = iter->second;
227 int digID = mDigits->size();
228 mDigits->emplace_back(chip.getChipIndex(), preDig.row, preDig.col, preDig.charge);
229 LOG(
debug) <<
"Adding digit ID: " << digID <<
" with chipID: " << chip.getChipIndex() <<
", row: " << preDig.row <<
", col: " << preDig.col <<
", charge: " << preDig.charge;
230 mMCLabels->
addElement(digID, preDig.labelRef.label);
231 auto& nextRef = preDig.labelRef;
232 while (nextRef.next >= 0) {
233 nextRef = extra[nextRef.next];
238 buffer.erase(itBeg, iter);
244 mROFRecords->push_back(rcROF);
248 mExtraBuff.emplace_back(mExtraBuff.front().release());
249 mExtraBuff.pop_front();
254void Digitizer::processHit(
const o2::trk::Hit& hit, uint32_t& maxFr,
int evID,
int srcID,
int rofLayer)
257 int subDetID = mGeometry->getSubDetID(chipID);
260 int disk = mGeometry->getDisk(chipID);
263 LOG(
debug) <<
"Skipping disk " << disk;
267 LOG(
debug) <<
"Processing hit for chip " << chipID;
268 auto& chip = mChips[chipID];
269 if (chip.isDisabled()) {
270 LOG(
debug) <<
"Skipping disabled chip " << chipID;
273 float timeInROF = hit.
GetTime() * sec2ns;
274 LOG(
debug) <<
"Hit time: " << timeInROF <<
" ns";
275 if (timeInROF > 20e3) {
276 const int maxWarn = 10;
277 static int warnNo = 0;
278 if (warnNo < maxWarn) {
279 LOG(warning) <<
"Ignoring hit with time_in_event = " << timeInROF <<
" ns"
280 << ((++warnNo < maxWarn) ?
"" :
" (suppressing further warnings)");
284 timeInROF += mCollisionTimeWrtROF;
285 if (mROFsWrtFirstRO < -1 || (mROFsWrtFirstRO == -1 && timeInROF < 0)) {
287 LOG(
debug) <<
"Ignoring hit with timeInROF = " << timeInROF;
300 int nFrames = roFrameRelMax + 1 - roFrameRel;
301 uint32_t roFrameMax = mNewROFrame + roFrameRelMax;
302 if (roFrameMax > maxFr) {
321 LOG(
debug) <<
"Called curved to flat: " << xyzLocS.x() <<
" -> " << xyFlatS.x() <<
", " << xyzLocS.y() <<
" -> " << xyFlatS.y();
323 xyzLocS.SetXYZ(xyFlatS.x(), xyFlatS.y(), xyzLocS.Z());
324 xyzLocE.SetXYZ(xyFlatE.x(), xyFlatE.y(), xyzLocE.Z());
342 LOG(
debug) <<
"Step into the sensitive volume: " <<
step <<
". Number of steps: " << nSteps;
343 int rowS = -1, colS = -1, rowE = -1, colE = -1, nSkip = 0;
348 if (++nSkip >= nSteps) {
349 LOG(
debug) <<
"Did not enter to sensitive matrix, " << nSkip <<
" >= " << nSteps;
357 if (++nSkip >= nSteps) {
358 LOG(
debug) <<
"Did not enter to sensitive matrix, " << nSkip <<
" >= " << nSteps;
369 std::swap(rowS, rowE);
372 std::swap(colS, colE);
390 int rowSpan = rowE - rowS + 1, colSpan = colE - colS + 1;
392 float respMatrix[rowSpan][colSpan];
393 std::fill(&respMatrix[0][0], &respMatrix[0][0] + rowSpan * colSpan, 0.f);
396 nElectrons *= nStepsInv;
401 int rowPrev = -1, colPrev = -1,
row,
col;
402 float cRowPix = 0.f, cColPix = 0.f;
413 xyzLocS.SetY(xyzLocS.Y() + ((subDetID == 0) ? mSimRespVDShift : mSimRespMLOTShift));
417 for (
int iStep = nSteps; iStep--;) {
420 if (
row != rowPrev ||
col != colPrev) {
427 bool flipCol =
false, flipRow =
false;
429 float rowMax{}, colMax{};
432 rowMax = 0.5f * Segmentation::PitchRowVD * mSimRespVDScaleX;
433 colMax = 0.5f * Segmentation::PitchColVD * mSimRespVDScaleZ;
434 rspmat = resp->
getResponse(mSimRespVDScaleX * (xyzLocS.X() - cRowPix), mSimRespVDScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
436 rowMax = 0.5f * Segmentation::PitchRowMLOT * mSimRespMLOTScaleX;
437 colMax = 0.5f * Segmentation::PitchColMLOT * mSimRespMLOTScaleZ;
438 rspmat = resp->
getResponse(mSimRespMLOTScaleX * (xyzLocS.X() - cRowPix), mSimRespMLOTScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
443 if (rspmat ==
nullptr) {
444 LOG(
debug) <<
"Error in rspmat for step " << iStep <<
" / " << nSteps;
453 if (rowDest < 0 || rowDest >= rowSpan) {
458 if (colDest < 0 || colDest >= colSpan) {
461 respMatrix[rowDest][colDest] += rspmat->getValue(irow, icol, mSimRespOrientation ? !flipRow : flipRow, flipCol);
468 auto roFrameAbs = mNewROFrame + roFrameRel;
469 LOG(
debug) <<
"\nSpanning through rows and columns; rowspan = " << rowSpan <<
" colspan = " << colSpan <<
" = " << colE <<
" - " << colS <<
" +1 ";
470 for (
int irow = rowSpan; irow--;) {
471 uint16_t rowIS = irow + rowS;
472 for (
int icol = colSpan; icol--;) {
473 float nEleResp = respMatrix[irow][icol];
474 if (nEleResp <= 1.e-36) {
477 LOG(
debug) <<
"nEleResp: value " << nEleResp <<
" for pixel " << irow <<
" " << icol;
478 int nEle = gRandom->Poisson(nElectrons * nEleResp);
479 LOG(
debug) <<
"Charge detected in the pixel: " << nEle <<
" for pixel " << irow <<
" " << icol;
482 LOG(
debug) <<
"Ignoring pixel with nEle = " << nEle <<
" < min charge to account "
487 uint16_t colIS = icol + colS;
488 if (mNoiseMap && mNoiseMap->
isNoisy(chipID, rowIS, colIS)) {
491 if (mDeadChanMap && mDeadChanMap->
isNoisy(chipID, rowIS, colIS)) {
494 registerDigits(chip, roFrameAbs, timeInROF, nFrames, rowIS, colIS, nEle, lbl, rofLayer);
506 LOG(
debug) <<
"Registering digits for chip " << chip.
getChipIndex() <<
" at ROFrame " << roFrame
507 <<
" row " <<
row <<
" col " <<
col <<
" nEle " << nEle <<
" label " << lbl;
509 for (
int i = 0;
i < nROF;
i++) {
510 uint32_t roFr = roFrame +
i;
518 if (roFr > mEventROFrameMax) {
519 mEventROFrameMax = roFr;
521 if (roFr < mEventROFrameMin) {
522 mEventROFrameMin = roFr;
528 LOG(
debug) <<
"Added digit with key: " <<
key <<
" ROF: " << roFr <<
" row: " <<
row <<
" col: " <<
col <<
" charge: " << nEleROF;
530 LOG(
debug) <<
"Added to pre-digit with key: " <<
key <<
" ROF: " << roFr <<
" row: " <<
row <<
" col: " <<
col <<
" charge: " << nEleROF;
535 ExtraDig* extra = getExtraDigBuffer(roFr);
539 if ((*extra)[nxt].
label == lbl) {
543 nxt = (*extra)[nxt].next;
550 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
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
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
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)
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
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
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"