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) {
137 LOG(
debug) <<
" NewROFrame " << mNewROFrame <<
" nbc " << nbc <<
" ROFsWrtFirstRO " << mROFsWrtFirstRO;
145 if (mNewROFrame < mROFrameMin) {
146 LOG(error) <<
"New ROFrame " << mNewROFrame <<
" (" << irt <<
") precedes currently cashed " << mROFrameMin;
147 throw std::runtime_error(
"deduced ROFrame precedes already processed one");
150 if (mParams.
isContinuous() && mROFrameMax < mNewROFrame) {
151 mROFrameMax = mNewROFrame - 1;
158 frameLast = std::min(frameLast, mROFrameMax);
160 getExtraDigBuffer(mROFrameMax);
162 LOG(info) <<
"Filling IT3 digits output on layer " <<
layer <<
" for RO frames " << mROFrameMin <<
":" << frameLast;
167 for (; mROFrameMin <= frameLast; mROFrameMin++) {
171 auto& extra = *(mExtraBuff.front().get());
172 for (
size_t iChip{0}; iChip < mChips.size(); ++iChip) {
173 auto& chip = mChips[iChip];
174 if (chip.isDisabled() || (
layer >= 0 && mGeometry->
getLayer(chip.getChipIndex()) !=
layer)) {
177 chip.addNoise(mROFrameMin, mROFrameMin, &mParams);
178 auto&
buffer = chip.getPreDigits();
182 auto itBeg =
buffer.begin();
184 ULong64_t maxKey = chip.getOrderingKey(mROFrameMin + 1, 0, 0) - 1;
185 for (; iter !=
buffer.end(); ++iter) {
186 if (iter->first > maxKey) {
189 auto& preDig = iter->second;
191 int digID = mDigits->size();
192 mDigits->emplace_back(chip.getChipIndex(), preDig.row, preDig.col, preDig.charge);
193 mMCLabels->
addElement(digID, preDig.labelRef.label);
194 auto& nextRef = preDig.labelRef;
195 while (nextRef.next >= 0) {
196 nextRef = extra[nextRef.next];
201 buffer.erase(itBeg, iter);
210 if (mROFRecords !=
nullptr) {
211 mROFRecords->push_back(rcROF);
215 mExtraBuff.emplace_back(mExtraBuff.front().release());
216 mExtraBuff.pop_front();
220void Digitizer::processHit(
const o2::itsmft::Hit& hit, uint32_t& maxFr,
int evID,
int srcID,
int lay)
224 auto& chip = mChips[chipID];
225 if (chip.isDisabled()) {
228 float timeInROF = hit.
GetTime() * sec2ns;
229 if (timeInROF > 20e3) {
230 const int maxWarn = 10;
231 static int warnNo = 0;
232 if (warnNo < maxWarn) {
233 LOG(warning) <<
"Ignoring hit with time_in_event = " << timeInROF <<
" ns"
234 << ((++warnNo < maxWarn) ?
"" :
" (suppressing further warnings)");
239 timeInROF += mCollisionTimeWrtROF;
241 if (mROFsWrtFirstRO < -1 || (mROFsWrtFirstRO == -1 && timeInROF < 0)) {
255 int nFrames = roFrameRelMax + 1 - roFrameRel;
256 uint32_t roFrameMax = mNewROFrame + roFrameRelMax;
257 maxFr = std::max(roFrameMax, maxFr);
266 xyzLocE = matrix ^ (hit.
GetPos());
269 float xFlatE{0.f}, yFlatE{0.f}, xFlatS{0.f}, yFlatS{0.f};
270 mIBSegmentations[
layer].curvedToFlat(xyzLocS.X(), xyzLocS.Y(), xFlatS, yFlatS);
271 mIBSegmentations[
layer].curvedToFlat(xyzLocE.X(), xyzLocE.Y(), xFlatE, yFlatE);
273 xyzLocS.SetXYZ(xFlatS, yFlatS, xyzLocS.Z());
274 xyzLocE.SetXYZ(xFlatE, yFlatE, xyzLocE.Z());
284 int rowS = -1, colS = -1, rowE = -1, colE = -1, nSkip = 0;
287 while (!mIBSegmentations[
layer].localToDetector(xyzLocS.X(), xyzLocS.Z(), rowS, colS)) {
288 if (++nSkip >= nSteps) {
294 while (!mIBSegmentations[
layer].localToDetector(xyzLocE.X(), xyzLocE.Z(), rowE, colE)) {
295 if (++nSkip >= nSteps) {
303 if (++nSkip >= nSteps) {
310 if (++nSkip >= nSteps) {
319 std::swap(rowS, rowE);
322 std::swap(colS, colE);
324 rowS -= AlpideRespSimMat::NPix / 2;
325 rowE += AlpideRespSimMat::NPix / 2;
326 rowS = std::max(rowS, 0);
331 rowE = std::min(rowE, maxNrows - 1);
332 colS -= AlpideRespSimMat::NPix / 2;
333 colE += AlpideRespSimMat::NPix / 2;
334 colS = std::max(colS, 0);
335 colE = std::min(colE, maxNcols - 1);
337 int rowSpan = rowE - rowS + 1, colSpan = colE - colS + 1;
338 float respMatrix[rowSpan][colSpan];
339 std::fill(&respMatrix[0][0], &respMatrix[0][0] + rowSpan * colSpan, 0.f);
342 nElectrons *= nStepsInv;
347 int rowPrev = -1, colPrev = -1,
row,
col;
348 float cRowPix = 0.f, cColPix = 0.f;
353 xyzLocS.SetY(xyzLocS.Y() + ((chip.isIB()) ? mSimRespIBShift : mSimRespOBShift));
356 for (
int iStep = nSteps; iStep--;) {
359 mIBSegmentations[
layer].localToDetector(xyzLocS.X(), xyzLocS.Z(),
row,
col);
363 if (
row != rowPrev ||
col != colPrev) {
365 if (!mIBSegmentations[
layer].detectorToLocal(
row,
col, cRowPix, cColPix)) {
374 bool flipCol =
false, flipRow =
false;
376 float rowMax{}, colMax{};
381 rspmat = mSimRespIB->
getResponse(mSimRespIBScaleX * (xyzLocS.X() - cRowPix), mSimRespIBScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
385 rspmat = mSimRespOB->
getResponse(xyzLocS.X() - cRowPix, xyzLocS.Z() - cColPix, xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
389 if (rspmat ==
nullptr) {
393 for (
int irow = AlpideRespSimMat::NPix; irow--;) {
394 int rowDest =
row + irow - AlpideRespSimMat::NPix / 2 - rowS;
395 if (rowDest < 0 || rowDest >= rowSpan) {
398 for (
int icol = AlpideRespSimMat::NPix; icol--;) {
399 int colDest =
col + icol - AlpideRespSimMat::NPix / 2 - colS;
400 if (colDest < 0 || colDest >= colSpan) {
403 respMatrix[rowDest][colDest] += rspmat->getValue(irow, icol, ((chip.isIB() && mSimRespIBOrientation) ? !flipRow : flipRow), flipCol);
410 auto roFrameAbs = mNewROFrame + roFrameRel;
411 for (
int irow = rowSpan; irow--;) {
412 uint16_t rowIS = irow + rowS;
413 for (
int icol = colSpan; icol--;) {
414 float nEleResp = respMatrix[irow][icol];
415 if (nEleResp <= 1.e-36) {
418 int nEle = gRandom->Poisson(nElectrons * nEleResp);
423 uint16_t colIS = icol + colS;
424 registerDigits(chip, roFrameAbs, timeInROF, nFrames, rowIS, colIS, nEle, lbl, lay);
437 for (
int i = 0;
i < nROF;
i++) {
438 uint32_t roFr = roFrame +
i;
446 mEventROFrameMax = std::max(roFr, mEventROFrameMax);
447 mEventROFrameMin = std::min(roFr, mEventROFrameMin);
457 ExtraDig* extra = getExtraDigBuffer(roFr);
461 if ((*extra)[nxt].
label == lbl) {
465 nxt = (*extra)[nxt].next;
472 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"