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;
70 mSimRespVDShift = mChipSimRespVD->getDepthMax();
73 mSimRespMLOTShift = mChipSimRespMLOT->getDepthMax() - thicknessMLOT / 2.f;
74 mSimRespOrientation =
false;
79 LOGP(info,
"TRK Digitizer is initialised.");
81 LOGP(info,
"VD shift = {} ; ML/OT shift = {} = {} - {}", mSimRespVDShift, mSimRespMLOTShift, mChipSimRespMLOT->getDepthMax(), thicknessMLOT / 2.f);
82 LOGP(info,
"VD pixel scale on x = {} ; z = {}", mSimRespVDScaleX, mSimRespVDScaleZ);
83 LOGP(info,
"ML/OT pixel scale on x = {} ; z = {}", mSimRespMLOTScaleX, mSimRespMLOTScaleZ);
84 LOGP(info,
"Response orientation: {}", mSimRespOrientation ?
"flipped" :
"normal");
91 if (mGeometry->getSubDetID(chipID) == 0) {
92 return mChipSimRespVD;
95 else if (mGeometry->getSubDetID(chipID) == 1) {
96 return mChipSimRespMLOT;
106 LOG(info) <<
" Digitizing " << mGeometry->
getName() <<
" (ID: " << mGeometry->
getDetID()
107 <<
") hits of entry " << evID <<
" from source " << srcID
108 <<
" at time " << mEventTime <<
" ROFrame= " << mNewROFrame <<
")"
110 <<
" Min/Max ROFrames " << mROFrameMin <<
"/" << mROFrameMax;
112 std::cout <<
"Printing segmentation info: " << std::endl;
116 if (mNewROFrame > mROFrameMin) {
120 int nHits = hits->size();
121 std::vector<int> hitIdx(nHits);
122 std::iota(std::begin(hitIdx), std::end(hitIdx), 0);
124 std::sort(hitIdx.begin(), hitIdx.end(),
125 [hits](
auto lhs,
auto rhs) {
126 return (*hits)[lhs].GetDetectorID() < (*hits)[rhs].GetDetectorID();
128 LOG(info) <<
"Processing " << nHits <<
" hits";
129 for (
int i : hitIdx) {
130 processHit((*hits)[
i], mROFrameMax, evID, srcID);
144 LOG(info) <<
"Setting event time ";
156 if (mCollisionTimeWrtROF < 0 && nbc > 0) {
162 LOG(info) <<
" NewROFrame " << mNewROFrame <<
" = " << nbc <<
"/" << mParams.
getROFrameLengthInBC() <<
" (nbc/mParams.getROFrameLengthInBC()";
170 if (mNewROFrame < mROFrameMin) {
171 LOG(error) <<
"New ROFrame " << mNewROFrame <<
" (" << irt <<
") precedes currently cashed " << mROFrameMin;
172 throw std::runtime_error(
"deduced ROFrame precedes already processed one");
175 if (mParams.
isContinuous() && mROFrameMax < mNewROFrame) {
176 mROFrameMax = mNewROFrame - 1;
184 if (frameLast > mROFrameMax) {
185 frameLast = mROFrameMax;
188 getExtraDigBuffer(mROFrameMax);
189 LOG(info) <<
"Filling " << mGeometry->
getName() <<
" digits output for RO frames " << mROFrameMin <<
":"
195 for (; mROFrameMin <= frameLast; mROFrameMin++) {
199 auto& extra = *(mExtraBuff.front().get());
200 for (
auto& chip : mChips) {
201 if (chip.isDisabled()) {
205 auto&
buffer = chip.getPreDigits();
209 auto itBeg =
buffer.begin();
211 ULong64_t maxKey = chip.getOrderingKey(mROFrameMin + 1, 0, 0) - 1;
212 for (; iter !=
buffer.end(); ++iter) {
213 if (iter->first > maxKey) {
216 auto& preDig = iter->second;
218 int digID = mDigits->size();
219 mDigits->emplace_back(chip.getChipIndex(), preDig.row, preDig.col, preDig.charge);
220 LOG(
debug) <<
"Adding digit ID: " << digID <<
" with chipID: " << chip.getChipIndex() <<
", row: " << preDig.row <<
", col: " << preDig.col <<
", charge: " << preDig.charge;
221 mMCLabels->
addElement(digID, preDig.labelRef.label);
222 auto& nextRef = preDig.labelRef;
223 while (nextRef.next >= 0) {
224 nextRef = extra[nextRef.next];
229 buffer.erase(itBeg, iter);
239 mROFRecords->push_back(rcROF);
243 mExtraBuff.emplace_back(mExtraBuff.front().release());
244 mExtraBuff.pop_front();
249void Digitizer::processHit(
const o2::trk::Hit& hit, uint32_t& maxFr,
int evID,
int srcID)
252 int subDetID = mGeometry->getSubDetID(chipID);
254 int layer = mGeometry->getLayer(chipID);
255 int disk = mGeometry->getDisk(chipID);
258 LOG(
debug) <<
"Skipping disk " << disk;
262 LOG(
debug) <<
"Processing hit for chip " << chipID;
263 auto& chip = mChips[chipID];
264 if (chip.isDisabled()) {
265 LOG(
debug) <<
"Skipping disabled chip " << chipID;
268 float timeInROF = hit.
GetTime() * sec2ns;
269 LOG(
debug) <<
"timeInROF: " << timeInROF;
270 if (timeInROF > 20e3) {
271 const int maxWarn = 10;
272 static int warnNo = 0;
273 if (warnNo < maxWarn) {
274 LOG(warning) <<
"Ignoring hit with time_in_event = " << timeInROF <<
" ns"
275 << ((++warnNo < maxWarn) ?
"" :
" (suppressing further warnings)");
280 timeInROF += mCollisionTimeWrtROF;
284 LOG(
debug) <<
"Ignoring hit with timeInROF = " << timeInROF;
297 int nFrames = roFrameRelMax + 1 - roFrameRel;
298 uint32_t roFrameMax = mNewROFrame + roFrameRelMax;
299 if (roFrameMax > maxFr) {
318 LOG(
debug) <<
"Called curved to flat: " << xyzLocS.x() <<
" -> " << xyFlatS.x() <<
", " << xyzLocS.y() <<
" -> " << xyFlatS.y();
320 xyzLocS.SetXYZ(xyFlatS.x(), xyFlatS.y(), xyzLocS.Z());
321 xyzLocE.SetXYZ(xyFlatE.x(), xyFlatE.y(), xyzLocE.Z());
339 LOG(
debug) <<
"Step into the sensitive volume: " <<
step <<
". Number of steps: " << nSteps;
340 int rowS = -1, colS = -1, rowE = -1, colE = -1, nSkip = 0;
345 if (++nSkip >= nSteps) {
346 LOG(
debug) <<
"Did not enter to sensitive matrix, " << nSkip <<
" >= " << nSteps;
354 if (++nSkip >= nSteps) {
355 LOG(
debug) <<
"Did not enter to sensitive matrix, " << nSkip <<
" >= " << nSteps;
366 std::swap(rowS, rowE);
369 std::swap(colS, colE);
387 int rowSpan = rowE - rowS + 1, colSpan = colE - colS + 1;
389 float respMatrix[rowSpan][colSpan];
390 std::fill(&respMatrix[0][0], &respMatrix[0][0] + rowSpan * colSpan, 0.f);
393 nElectrons *= nStepsInv;
398 int rowPrev = -1, colPrev = -1,
row,
col;
399 float cRowPix = 0.f, cColPix = 0.f;
410 xyzLocS.SetY(xyzLocS.Y() + ((subDetID == 0) ? mSimRespVDShift : mSimRespMLOTShift));
414 for (
int iStep = nSteps; iStep--;) {
417 if (
row != rowPrev ||
col != colPrev) {
424 bool flipCol =
false, flipRow =
false;
426 float rowMax{}, colMax{};
429 rowMax = 0.5f * Segmentation::PitchRowVD * mSimRespVDScaleX;
430 colMax = 0.5f * Segmentation::PitchColVD * mSimRespVDScaleZ;
431 rspmat = resp->
getResponse(mSimRespVDScaleX * (xyzLocS.X() - cRowPix), mSimRespVDScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
433 rowMax = 0.5f * Segmentation::PitchRowMLOT * mSimRespMLOTScaleX;
434 colMax = 0.5f * Segmentation::PitchColMLOT * mSimRespMLOTScaleZ;
435 rspmat = resp->
getResponse(mSimRespMLOTScaleX * (xyzLocS.X() - cRowPix), mSimRespMLOTScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
440 if (rspmat ==
nullptr) {
441 LOG(
debug) <<
"Error in rspmat for step " << iStep <<
" / " << nSteps;
450 if (rowDest < 0 || rowDest >= rowSpan) {
455 if (colDest < 0 || colDest >= colSpan) {
458 respMatrix[rowDest][colDest] += rspmat->getValue(irow, icol, mSimRespOrientation ? !flipRow : flipRow, !flipCol);
465 auto roFrameAbs = mNewROFrame + roFrameRel;
466 LOG(
debug) <<
"\nSpanning through rows and columns; rowspan = " << rowSpan <<
" colspan = " << colSpan <<
" = " << colE <<
" - " << colS <<
" +1 ";
467 for (
int irow = rowSpan; irow--;) {
468 uint16_t rowIS = irow + rowS;
469 for (
int icol = colSpan; icol--;) {
470 float nEleResp = respMatrix[irow][icol];
471 if (nEleResp <= 1.e-36) {
474 LOG(
debug) <<
"nEleResp: value " << nEleResp <<
" for pixel " << irow <<
" " << icol;
475 int nEle = gRandom->Poisson(nElectrons * nEleResp);
476 LOG(
debug) <<
"Charge detected in the pixel: " << nEle <<
" for pixel " << irow <<
" " << icol;
479 LOG(
debug) <<
"Ignoring pixel with nEle = " << nEle <<
" < min charge to account "
484 uint16_t colIS = icol + colS;
485 if (mNoiseMap && mNoiseMap->
isNoisy(chipID, rowIS, colIS)) {
488 if (mDeadChanMap && mDeadChanMap->
isNoisy(chipID, rowIS, colIS)) {
492 registerDigits(chip, roFrameAbs, timeInROF, nFrames, rowIS, colIS, nEle, lbl);
504 LOG(
debug) <<
"Registering digits for chip " << chip.
getChipIndex() <<
" at ROFrame " << roFrame
505 <<
" row " <<
row <<
" col " <<
col <<
" nEle " << nEle <<
" label " << lbl;
507 for (
int i = 0;
i < nROF;
i++) {
508 uint32_t roFr = roFrame +
i;
516 if (roFr > mEventROFrameMax) {
517 mEventROFrameMax = roFr;
519 if (roFr < mEventROFrameMin) {
520 mEventROFrameMin = roFr;
526 LOG(
debug) <<
"Added digit " <<
key <<
" " << roFr <<
" " <<
row <<
" " <<
col <<
" " << nEleROF;
532 ExtraDig* extra = getExtraDigBuffer(roFr);
536 if ((*extra)[nxt].
label == lbl) {
540 nxt = (*extra)[nxt].next;
547 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
const o2::itsmft::AlpideSimResponse * getAlpSimResponse() const
float getROFrameLengthInv() const
virtual void print() const
const SignalShape & getSignalShape() const
float getEnergyToNElectrons() const
int getROFrameLengthInBC() const
float getStrobeDelay() const
bool isContinuous() const
int getChargeThreshold() const
float getNSimStepsInv() const
float getROFrameLength() const
float getStrobeLength() const
void setEventTime(const o2::InteractionTimeRecord &irt)
auto getChipResponse(int chipID)
bool isContinuous() const
void process(const std::vector< Hit > *hits, int evID, int srcID)
Steer conversion of hits to digits.
void fillOutputContainer(uint32_t maxFrame=0xffffffff)
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"