42 mChips.resize(numOfChips);
43 for (
int i = numOfChips;
i--;) {
44 mChips[
i].setChipIndex(
i);
45 if (mDeadChanMap !=
nullptr) {
47 mChips[
i].setDeadChanMap(mDeadChanMap);
52 LOGP(fatal,
"No response functions set!");
57 }
else if (
func ==
"APTS") {
60 mSimRespIBOrientation =
true;
62 LOGP(fatal,
"ResponseFunction '{}' not implemented!",
func);
70 LOGP(info,
"IB shift = {} ; OB shift = {}", mSimRespIBShift, mSimRespOBShift);
71 LOGP(info,
"IB pixel scale on x = {} ; z = {}", mSimRespIBScaleX, mSimRespIBScaleZ);
72 LOGP(info,
"IB response orientation: {}", mSimRespIBOrientation ?
"flipped" :
"normal");
80 LOG(
debug) <<
"Digitizing " << mGeometry->
getName() <<
":" <<
layer <<
" hits of entry " << evID <<
" from source "
81 << srcID <<
" at time " << mEventTime <<
" ROFrame = " << mNewROFrame <<
")"
83 <<
" Min/Max ROFrames " << mROFrameMin <<
"/" << mROFrameMax;
86 if (mNewROFrame > mROFrameMin) {
90 int nHits = hits->size();
91 std::vector<int> hitIdx(nHits);
92 std::iota(std::begin(hitIdx), std::end(hitIdx), 0);
94 std::sort(hitIdx.begin(), hitIdx.end(),
95 [hits](
auto lhs,
auto rhs) {
96 return (*hits)[lhs].GetDetectorID() < (*hits)[rhs].GetDetectorID();
98 for (
int i : hitIdx | std::views::filter([&](
int idx) {
102 return mGeometry->
getLayer((*hits)[idx].GetDetectorID()) ==
layer;
104 processHit((*hits)[
i], mROFrameMax, evID, srcID,
layer);
126 if (mCollisionTimeWrtROF < 0 && nbc > 0) {
134 mIsBeforeFirstRO =
true;
137 mIsBeforeFirstRO =
false;
139 LOG(
debug) <<
" NewROFrame " << mNewROFrame <<
" nbc " << nbc;
147 if (mNewROFrame < mROFrameMin) {
148 LOG(error) <<
"New ROFrame " << mNewROFrame <<
" (" << irt <<
") precedes currently cashed " << mROFrameMin;
149 throw std::runtime_error(
"deduced ROFrame precedes already processed one");
152 if (mParams.
isContinuous() && mROFrameMax < mNewROFrame) {
153 mROFrameMax = mNewROFrame - 1;
160 frameLast = std::min(frameLast, mROFrameMax);
162 getExtraDigBuffer(mROFrameMax);
164 LOG(info) <<
"Filling IT3 digits output on layer " <<
layer <<
" for RO frames " << mROFrameMin <<
":" << frameLast;
169 for (; mROFrameMin <= frameLast; mROFrameMin++) {
173 auto& extra = *(mExtraBuff.front().get());
174 for (
size_t iChip{0}; iChip < mChips.size(); ++iChip) {
175 auto& chip = mChips[iChip];
176 if (chip.isDisabled() || (
layer >= 0 && mGeometry->
getLayer(chip.getChipIndex()) !=
layer)) {
179 chip.addNoise(mROFrameMin, mROFrameMin, &mParams);
180 auto&
buffer = chip.getPreDigits();
184 auto itBeg =
buffer.begin();
186 ULong64_t maxKey = chip.getOrderingKey(mROFrameMin + 1, 0, 0) - 1;
187 for (; iter !=
buffer.end(); ++iter) {
188 if (iter->first > maxKey) {
191 auto& preDig = iter->second;
193 int digID = mDigits->size();
194 mDigits->emplace_back(chip.getChipIndex(), preDig.row, preDig.col, preDig.charge);
195 mMCLabels->
addElement(digID, preDig.labelRef.label);
196 auto& nextRef = preDig.labelRef;
197 while (nextRef.next >= 0) {
198 nextRef = extra[nextRef.next];
203 buffer.erase(itBeg, iter);
212 if (mROFRecords !=
nullptr) {
213 mROFRecords->push_back(rcROF);
217 mExtraBuff.emplace_back(mExtraBuff.front().release());
218 mExtraBuff.pop_front();
222void Digitizer::processHit(
const o2::itsmft::Hit& hit, uint32_t& maxFr,
int evID,
int srcID,
int lay)
226 auto& chip = mChips[chipID];
227 if (chip.isDisabled()) {
230 float timeInROF = hit.
GetTime() * sec2ns;
231 if (timeInROF > 20e3) {
232 const int maxWarn = 10;
233 static int warnNo = 0;
234 if (warnNo < maxWarn) {
235 LOG(warning) <<
"Ignoring hit with time_in_event = " << timeInROF <<
" ns"
236 << ((++warnNo < maxWarn) ?
"" :
" (suppressing further warnings)");
241 timeInROF += mCollisionTimeWrtROF;
243 if (mIsBeforeFirstRO && timeInROF < 0) {
257 int nFrames = roFrameRelMax + 1 - roFrameRel;
258 uint32_t roFrameMax = mNewROFrame + roFrameRelMax;
259 maxFr = std::max(roFrameMax, maxFr);
268 xyzLocE = matrix ^ (hit.
GetPos());
271 float xFlatE{0.f}, yFlatE{0.f}, xFlatS{0.f}, yFlatS{0.f};
272 mIBSegmentations[
layer].curvedToFlat(xyzLocS.X(), xyzLocS.Y(), xFlatS, yFlatS);
273 mIBSegmentations[
layer].curvedToFlat(xyzLocE.X(), xyzLocE.Y(), xFlatE, yFlatE);
275 xyzLocS.SetXYZ(xFlatS, yFlatS, xyzLocS.Z());
276 xyzLocE.SetXYZ(xFlatE, yFlatE, xyzLocE.Z());
286 int rowS = -1, colS = -1, rowE = -1, colE = -1, nSkip = 0;
289 while (!mIBSegmentations[
layer].localToDetector(xyzLocS.X(), xyzLocS.Z(), rowS, colS)) {
290 if (++nSkip >= nSteps) {
296 while (!mIBSegmentations[
layer].localToDetector(xyzLocE.X(), xyzLocE.Z(), rowE, colE)) {
297 if (++nSkip >= nSteps) {
305 if (++nSkip >= nSteps) {
312 if (++nSkip >= nSteps) {
321 std::swap(rowS, rowE);
324 std::swap(colS, colE);
326 rowS -= AlpideRespSimMat::NPix / 2;
327 rowE += AlpideRespSimMat::NPix / 2;
328 rowS = std::max(rowS, 0);
333 rowE = std::min(rowE, maxNrows - 1);
334 colS -= AlpideRespSimMat::NPix / 2;
335 colE += AlpideRespSimMat::NPix / 2;
336 colS = std::max(colS, 0);
337 colE = std::min(colE, maxNcols - 1);
339 int rowSpan = rowE - rowS + 1, colSpan = colE - colS + 1;
340 float respMatrix[rowSpan][colSpan];
341 std::fill(&respMatrix[0][0], &respMatrix[0][0] + rowSpan * colSpan, 0.f);
344 nElectrons *= nStepsInv;
349 int rowPrev = -1, colPrev = -1,
row,
col;
350 float cRowPix = 0.f, cColPix = 0.f;
355 xyzLocS.SetY(xyzLocS.Y() + ((chip.isIB()) ? mSimRespIBShift : mSimRespOBShift));
358 for (
int iStep = nSteps; iStep--;) {
361 mIBSegmentations[
layer].localToDetector(xyzLocS.X(), xyzLocS.Z(),
row,
col);
365 if (
row != rowPrev ||
col != colPrev) {
367 if (!mIBSegmentations[
layer].detectorToLocal(
row,
col, cRowPix, cColPix)) {
376 bool flipCol =
false, flipRow =
false;
378 float rowMax{}, colMax{};
383 rspmat = mSimRespIB->
getResponse(mSimRespIBScaleX * (xyzLocS.X() - cRowPix), mSimRespIBScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
387 rspmat = mSimRespOB->
getResponse(xyzLocS.X() - cRowPix, xyzLocS.Z() - cColPix, xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
391 if (rspmat ==
nullptr) {
395 for (
int irow = AlpideRespSimMat::NPix; irow--;) {
396 int rowDest =
row + irow - AlpideRespSimMat::NPix / 2 - rowS;
397 if (rowDest < 0 || rowDest >= rowSpan) {
400 for (
int icol = AlpideRespSimMat::NPix; icol--;) {
401 int colDest =
col + icol - AlpideRespSimMat::NPix / 2 - colS;
402 if (colDest < 0 || colDest >= colSpan) {
405 respMatrix[rowDest][colDest] += rspmat->getValue(irow, icol, ((chip.isIB() && mSimRespIBOrientation) ? !flipRow : flipRow), flipCol);
412 auto roFrameAbs = mNewROFrame + roFrameRel;
413 for (
int irow = rowSpan; irow--;) {
414 uint16_t rowIS = irow + rowS;
415 for (
int icol = colSpan; icol--;) {
416 float nEleResp = respMatrix[irow][icol];
417 if (nEleResp <= 1.e-36) {
420 int nEle = gRandom->Poisson(nElectrons * nEleResp);
425 uint16_t colIS = icol + colS;
426 registerDigits(chip, roFrameAbs, timeInROF, nFrames, rowIS, colIS, nEle, lbl, lay);
439 for (
int i = 0;
i < nROF;
i++) {
440 uint32_t roFr = roFrame +
i;
448 mEventROFrameMax = std::max(roFr, mEventROFrameMax);
449 mEventROFrameMin = std::min(roFr, mEventROFrameMin);
459 ExtraDig* extra = getExtraDigBuffer(roFr);
463 if ((*extra)[nxt].
label == lbl) {
467 nxt = (*extra)[nxt].next;
474 extra->emplace_back(lbl);
Definition of a container to keep Monte Carlo truth external to simulation objects.
Definition of the SegmentationAlpide class.
Definition of the ITS digitizer.
math_utils::Point3D< T > GetPos() const
unsigned short GetDetectorID() const
static const ITS3Params & Instance()
const char * getName() const
const Mat3D & getMatrixL2G(int sensID) const
o2::its3::ChipSimResponse * getIBSimResponse() const
bool hasResponseFunctions() const
float getIBNSimStepsInv() const
const o2::itsmft::AlpideSimResponse * getOBSimResponse() const
int getIBChargeThreshold() const
int getIBNSimSteps() const
void fillOutputContainer(uint32_t maxFrame=0xffffffff, int layer=-1)
bool isContinuous() const
void process(const std::vector< itsmft::Hit > *hits, int evID, int srcID, int layer)
Steer conversion of hits to digits.
void setEventTime(const o2::InteractionTimeRecord &irt, int layer)
Segmentation and response for pixels in ITS3 upgrade.
static constexpr float PitchCol
static constexpr int NRows
static constexpr int NCols
static constexpr float PitchRow
int getLayer(int index) const final
Get chip layer, from 0.
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.
float getStrobeDelay(int layer=-1) 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
Int_t getNumberOfChips() const
math_utils::Point3D< Float_t > GetPosStart() const
bool isFullChipMasked(int chip) const
const BCData & getBCData() const
void setFirstEntry(int idx)
int getFirstEntry() const
void setROFrame(ROFtype rof)
static constexpr float SensorLayerThickness
static bool localToDetector(float x, float z, int &iRow, int &iCol)
static constexpr float PitchCol
static constexpr int NRows
static constexpr int NCols
static constexpr float PitchRow
static bool detectorToLocal(L row, L col, T &xRow, T &zCol)
GLuint GLsizei const GLchar * label
GLenum GLuint GLint GLint layer
constexpr double LHCBunchSpacingNS
constexpr double thickness
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"