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;
70 if (mRespName ==
"APTS") {
73 mSimRespVDShift = mChipSimRespVD->getDepthMax();
76 }
else if (mRespName ==
"ALICE3") {
79 mSimRespVDShift = mChipSimRespVD->getDepthMax();
83 LOG(fatal) <<
"Unknown response name: " << mRespName;
86 mSimRespMLOTShift = mChipSimRespMLOT->getDepthMax() - thicknessMLOT / 2.f;
87 mSimRespOrientation =
false;
92 LOGP(info,
"TRK Digitizer is initialised.");
94 LOGP(info,
"VD shift = {} ; ML/OT shift = {} = {} - {}", mSimRespVDShift, mSimRespMLOTShift, mChipSimRespMLOT->getDepthMax(), thicknessMLOT / 2.f);
95 LOGP(info,
"VD pixel scale on x = {} ; z = {}", mSimRespVDScaleX, mSimRespVDScaleZ);
96 LOGP(info,
"ML/OT pixel scale on x = {} ; z = {}", mSimRespMLOTScaleX, mSimRespMLOTScaleZ);
97 LOGP(info,
"Response orientation: {}", mSimRespOrientation ?
"flipped" :
"normal");
104 if (mGeometry->getSubDetID(chipID) == 0) {
105 return mChipSimRespVD;
108 else if (mGeometry->getSubDetID(chipID) == 1) {
109 return mChipSimRespMLOT;
120 <<
") hits of entry " << evID <<
" from source " << srcID
121 <<
" at time " << mEventTime <<
" ROFrame= " << mNewROFrame <<
")"
123 <<
" Min/Max ROFrames " << mROFrameMin <<
"/" << mROFrameMax;
125 std::cout <<
"Printing segmentation info: " << std::endl;
129 if (mNewROFrame > mROFrameMin) {
133 int nHits = hits->size();
134 std::vector<int> hitIdx(nHits);
135 std::iota(std::begin(hitIdx), std::end(hitIdx), 0);
137 std::sort(hitIdx.begin(), hitIdx.end(),
138 [hits](
auto lhs,
auto rhs) {
139 return (*hits)[lhs].GetDetectorID() < (*hits)[rhs].GetDetectorID();
141 LOG(info) <<
"Processing " << nHits <<
" hits";
142 for (
int i : hitIdx) {
143 processHit((*hits)[
i], mROFrameMax, evID, srcID);
157 LOG(info) <<
"Setting event time ";
169 if (mCollisionTimeWrtROF < 0 && nbc > 0) {
175 LOG(
debug) <<
" NewROFrame " << mNewROFrame <<
" = " << nbc <<
"/" << mParams.
getROFrameLengthInBC() <<
" (nbc/mParams.getROFrameLengthInBC()";
183 if (mNewROFrame < mROFrameMin) {
184 LOG(error) <<
"New ROFrame " << mNewROFrame <<
" (" << irt <<
") precedes currently cashed " << mROFrameMin;
185 throw std::runtime_error(
"deduced ROFrame precedes already processed one");
188 if (mParams.
isContinuous() && mROFrameMax < mNewROFrame) {
189 mROFrameMax = mNewROFrame - 1;
197 if (frameLast > mROFrameMax) {
198 frameLast = mROFrameMax;
201 getExtraDigBuffer(mROFrameMax);
202 LOG(info) <<
"Filling " << mGeometry->
getName() <<
" digits output for RO frames " << mROFrameMin <<
":"
208 for (; mROFrameMin <= frameLast; mROFrameMin++) {
212 auto& extra = *(mExtraBuff.front().get());
213 for (
auto& chip : mChips) {
214 if (chip.isDisabled()) {
218 auto&
buffer = chip.getPreDigits();
222 auto itBeg =
buffer.begin();
224 ULong64_t maxKey = chip.getOrderingKey(mROFrameMin + 1, 0, 0) - 1;
225 for (; iter !=
buffer.end(); ++iter) {
226 if (iter->first > maxKey) {
229 auto& preDig = iter->second;
231 int digID = mDigits->size();
232 mDigits->emplace_back(chip.getChipIndex(), preDig.row, preDig.col, preDig.charge);
233 LOG(
debug) <<
"Adding digit ID: " << digID <<
" with chipID: " << chip.getChipIndex() <<
", row: " << preDig.row <<
", col: " << preDig.col <<
", charge: " << preDig.charge;
234 mMCLabels->
addElement(digID, preDig.labelRef.label);
235 auto& nextRef = preDig.labelRef;
236 while (nextRef.next >= 0) {
237 nextRef = extra[nextRef.next];
242 buffer.erase(itBeg, iter);
252 mROFRecords->push_back(rcROF);
256 mExtraBuff.emplace_back(mExtraBuff.front().release());
257 mExtraBuff.pop_front();
262void Digitizer::processHit(
const o2::trk::Hit& hit, uint32_t& maxFr,
int evID,
int srcID)
265 int subDetID = mGeometry->getSubDetID(chipID);
268 int disk = mGeometry->getDisk(chipID);
271 LOG(
debug) <<
"Skipping disk " << disk;
275 LOG(
debug) <<
"Processing hit for chip " << chipID;
276 auto& chip = mChips[chipID];
277 if (chip.isDisabled()) {
278 LOG(
debug) <<
"Skipping disabled chip " << chipID;
281 float timeInROF = hit.
GetTime() * sec2ns;
282 LOG(
debug) <<
"timeInROF: " << timeInROF;
283 if (timeInROF > 20e3) {
284 const int maxWarn = 10;
285 static int warnNo = 0;
286 if (warnNo < maxWarn) {
287 LOG(warning) <<
"Ignoring hit with time_in_event = " << timeInROF <<
" ns"
288 << ((++warnNo < maxWarn) ?
"" :
" (suppressing further warnings)");
293 timeInROF += mCollisionTimeWrtROF;
297 LOG(
debug) <<
"Ignoring hit with timeInROF = " << timeInROF;
310 int nFrames = roFrameRelMax + 1 - roFrameRel;
311 uint32_t roFrameMax = mNewROFrame + roFrameRelMax;
312 if (roFrameMax > maxFr) {
331 LOG(
debug) <<
"Called curved to flat: " << xyzLocS.x() <<
" -> " << xyFlatS.x() <<
", " << xyzLocS.y() <<
" -> " << xyFlatS.y();
333 xyzLocS.SetXYZ(xyFlatS.x(), xyFlatS.y(), xyzLocS.Z());
334 xyzLocE.SetXYZ(xyFlatE.x(), xyFlatE.y(), xyzLocE.Z());
352 LOG(
debug) <<
"Step into the sensitive volume: " <<
step <<
". Number of steps: " << nSteps;
353 int rowS = -1, colS = -1, rowE = -1, colE = -1, nSkip = 0;
358 if (++nSkip >= nSteps) {
359 LOG(
debug) <<
"Did not enter to sensitive matrix, " << nSkip <<
" >= " << nSteps;
367 if (++nSkip >= nSteps) {
368 LOG(
debug) <<
"Did not enter to sensitive matrix, " << nSkip <<
" >= " << nSteps;
379 std::swap(rowS, rowE);
382 std::swap(colS, colE);
400 int rowSpan = rowE - rowS + 1, colSpan = colE - colS + 1;
402 float respMatrix[rowSpan][colSpan];
403 std::fill(&respMatrix[0][0], &respMatrix[0][0] + rowSpan * colSpan, 0.f);
406 nElectrons *= nStepsInv;
411 int rowPrev = -1, colPrev = -1,
row,
col;
412 float cRowPix = 0.f, cColPix = 0.f;
423 xyzLocS.SetY(xyzLocS.Y() + ((subDetID == 0) ? mSimRespVDShift : mSimRespMLOTShift));
427 for (
int iStep = nSteps; iStep--;) {
430 if (
row != rowPrev ||
col != colPrev) {
437 bool flipCol =
false, flipRow =
false;
439 float rowMax{}, colMax{};
442 rowMax = 0.5f * Segmentation::PitchRowVD * mSimRespVDScaleX;
443 colMax = 0.5f * Segmentation::PitchColVD * mSimRespVDScaleZ;
444 rspmat = resp->
getResponse(mSimRespVDScaleX * (xyzLocS.X() - cRowPix), mSimRespVDScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
446 rowMax = 0.5f * Segmentation::PitchRowMLOT * mSimRespMLOTScaleX;
447 colMax = 0.5f * Segmentation::PitchColMLOT * mSimRespMLOTScaleZ;
448 rspmat = resp->
getResponse(mSimRespMLOTScaleX * (xyzLocS.X() - cRowPix), mSimRespMLOTScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
453 if (rspmat ==
nullptr) {
454 LOG(
debug) <<
"Error in rspmat for step " << iStep <<
" / " << nSteps;
463 if (rowDest < 0 || rowDest >= rowSpan) {
468 if (colDest < 0 || colDest >= colSpan) {
471 respMatrix[rowDest][colDest] += rspmat->getValue(irow, icol, mSimRespOrientation ? !flipRow : flipRow, !flipCol);
478 auto roFrameAbs = mNewROFrame + roFrameRel;
479 LOG(
debug) <<
"\nSpanning through rows and columns; rowspan = " << rowSpan <<
" colspan = " << colSpan <<
" = " << colE <<
" - " << colS <<
" +1 ";
480 for (
int irow = rowSpan; irow--;) {
481 uint16_t rowIS = irow + rowS;
482 for (
int icol = colSpan; icol--;) {
483 float nEleResp = respMatrix[irow][icol];
484 if (nEleResp <= 1.e-36) {
487 LOG(
debug) <<
"nEleResp: value " << nEleResp <<
" for pixel " << irow <<
" " << icol;
488 int nEle = gRandom->Poisson(nElectrons * nEleResp);
489 LOG(
debug) <<
"Charge detected in the pixel: " << nEle <<
" for pixel " << irow <<
" " << icol;
492 LOG(
debug) <<
"Ignoring pixel with nEle = " << nEle <<
" < min charge to account "
497 uint16_t colIS = icol + colS;
498 if (mNoiseMap && mNoiseMap->
isNoisy(chipID, rowIS, colIS)) {
501 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 " <<
key <<
" " << roFr <<
" " <<
row <<
" " <<
col <<
" " << nEleROF;
545 ExtraDig* extra = getExtraDigBuffer(roFr);
549 if ((*extra)[nxt].
label == lbl) {
553 nxt = (*extra)[nxt].next;
560 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)
static ULong64_t getOrderingKey(UInt_t roframe, UShort_t row, UShort_t col)
Get global ordering key made of readout frame, column and row.
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
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)
math_utils::Point3D< Float_t > GetPosStart() const
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
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"