41 mChips.resize(numOfChips);
42 for (
int i = numOfChips;
i--;) {
43 mChips[
i].setChipIndex(
i);
44 if (mDeadChanMap !=
nullptr) {
46 mChips[
i].setDeadChanMap(mDeadChanMap);
51 LOGP(fatal,
"No response functions set!");
56 }
else if (
func ==
"APTS") {
59 mSimRespIBOrientation =
true;
61 LOGP(fatal,
"ResponseFunction '{}' not implemented!",
func);
69 LOGP(info,
"IB shift = {} ; OB shift = {}", mSimRespIBShift, mSimRespOBShift);
70 LOGP(info,
"IB pixel scale on x = {} ; z = {}", mSimRespIBScaleX, mSimRespIBScaleZ);
71 LOGP(info,
"IB response orientation: {}", mSimRespIBOrientation ?
"flipped" :
"normal");
79 LOG(info) <<
"Digitizing " << mGeometry->
getName() <<
" hits of entry " << evID <<
" from source "
80 << srcID <<
" at time " << mEventTime <<
" ROFrame = " << mNewROFrame <<
")"
82 <<
" Min/Max ROFrames " << mROFrameMin <<
"/" << mROFrameMax;
85 if (mNewROFrame > mROFrameMin) {
89 int nHits = hits->size();
90 std::vector<int> hitIdx(nHits);
91 std::iota(std::begin(hitIdx), std::end(hitIdx), 0);
93 std::sort(hitIdx.begin(), hitIdx.end(),
94 [hits](
auto lhs,
auto rhs) {
95 return (*hits)[lhs].GetDetectorID() < (*hits)[rhs].GetDetectorID();
97 for (
int i : hitIdx) {
98 processHit((*hits)[
i], mROFrameMax, evID, srcID);
120 if (mCollisionTimeWrtROF < 0 && nbc > 0) {
130 if (mNewROFrame < mROFrameMin) {
131 LOG(error) <<
"New ROFrame " << mNewROFrame <<
" (" << irt <<
") precedes currently cashed " << mROFrameMin;
132 throw std::runtime_error(
"deduced ROFrame precedes already processed one");
135 if (mParams.
isContinuous() && mROFrameMax < mNewROFrame) {
136 mROFrameMax = mNewROFrame - 1;
143 if (frameLast > mROFrameMax) {
144 frameLast = mROFrameMax;
147 getExtraDigBuffer(mROFrameMax);
149 LOG(info) <<
"Filling " << mGeometry->
getName() <<
" digits output for RO frames " << mROFrameMin <<
":"
155 for (; mROFrameMin <= frameLast; mROFrameMin++) {
159 auto& extra = *(mExtraBuff.front().get());
160 for (
size_t iChip{0}; iChip < mChips.size(); ++iChip) {
161 auto& chip = mChips[iChip];
162 chip.addNoise(mROFrameMin, mROFrameMin, &mParams);
163 auto&
buffer = chip.getPreDigits();
167 auto itBeg =
buffer.begin();
169 ULong64_t maxKey = chip.getOrderingKey(mROFrameMin + 1, 0, 0) - 1;
170 for (; iter !=
buffer.end(); ++iter) {
171 if (iter->first > maxKey) {
174 auto& preDig = iter->second;
176 int digID = mDigits->size();
177 mDigits->emplace_back(chip.getChipIndex(), preDig.row, preDig.col, preDig.charge);
178 mMCLabels->
addElement(digID, preDig.labelRef.label);
179 auto& nextRef = preDig.labelRef;
180 while (nextRef.next >= 0) {
181 nextRef = extra[nextRef.next];
186 buffer.erase(itBeg, iter);
195 if (mROFRecords !=
nullptr) {
196 mROFRecords->push_back(rcROF);
200 mExtraBuff.emplace_back(mExtraBuff.front().release());
201 mExtraBuff.pop_front();
205void Digitizer::processHit(
const o2::itsmft::Hit& hit, uint32_t& maxFr,
int evID,
int srcID)
209 auto& chip = mChips[chipID];
210 if (chip.isDisabled()) {
213 float timeInROF = hit.
GetTime() * sec2ns;
214 if (timeInROF > 20e3) {
215 const int maxWarn = 10;
216 static int warnNo = 0;
217 if (warnNo < maxWarn) {
218 LOG(warning) <<
"Ignoring hit with time_in_event = " << timeInROF <<
" ns"
219 << ((++warnNo < maxWarn) ?
"" :
" (suppressing further warnings)");
224 timeInROF += mCollisionTimeWrtROF;
235 int nFrames = roFrameRelMax + 1 - roFrameRel;
236 uint32_t roFrameMax = mNewROFrame + roFrameRelMax;
237 if (roFrameMax > maxFr) {
249 xyzLocE = matrix ^ (hit.
GetPos());
252 float xFlatE{0.f}, yFlatE{0.f}, xFlatS{0.f}, yFlatS{0.f};
253 mIBSegmentations[
layer].curvedToFlat(xyzLocS.X(), xyzLocS.Y(), xFlatS, yFlatS);
254 mIBSegmentations[
layer].curvedToFlat(xyzLocE.X(), xyzLocE.Y(), xFlatE, yFlatE);
256 xyzLocS.SetXYZ(xFlatS, yFlatS, xyzLocS.Z());
257 xyzLocE.SetXYZ(xFlatE, yFlatE, xyzLocE.Z());
267 int rowS = -1, colS = -1, rowE = -1, colE = -1, nSkip = 0;
270 while (!mIBSegmentations[
layer].localToDetector(xyzLocS.X(), xyzLocS.Z(), rowS, colS)) {
271 if (++nSkip >= nSteps) {
277 while (!mIBSegmentations[
layer].localToDetector(xyzLocE.X(), xyzLocE.Z(), rowE, colE)) {
278 if (++nSkip >= nSteps) {
286 if (++nSkip >= nSteps) {
293 if (++nSkip >= nSteps) {
302 std::swap(rowS, rowE);
305 std::swap(colS, colE);
307 rowS -= AlpideRespSimMat::NPix / 2;
308 rowE += AlpideRespSimMat::NPix / 2;
309 rowS = std::max(rowS, 0);
314 rowE = std::min(rowE, maxNrows - 1);
315 colS -= AlpideRespSimMat::NPix / 2;
316 colE += AlpideRespSimMat::NPix / 2;
317 colS = std::max(colS, 0);
318 colE = std::min(colE, maxNcols - 1);
320 int rowSpan = rowE - rowS + 1, colSpan = colE - colS + 1;
321 float respMatrix[rowSpan][colSpan];
322 std::fill(&respMatrix[0][0], &respMatrix[0][0] + rowSpan * colSpan, 0.f);
325 nElectrons *= nStepsInv;
330 int rowPrev = -1, colPrev = -1,
row,
col;
331 float cRowPix = 0.f, cColPix = 0.f;
336 xyzLocS.SetY(xyzLocS.Y() + ((chip.isIB()) ? mSimRespIBShift : mSimRespOBShift));
339 for (
int iStep = nSteps; iStep--;) {
342 mIBSegmentations[
layer].localToDetector(xyzLocS.X(), xyzLocS.Z(),
row,
col);
346 if (
row != rowPrev ||
col != colPrev) {
348 if (!mIBSegmentations[
layer].detectorToLocal(
row,
col, cRowPix, cColPix)) {
357 bool flipCol =
false, flipRow =
false;
359 float rowMax{}, colMax{};
364 rspmat = mSimRespIB->
getResponse(mSimRespIBScaleX * (xyzLocS.X() - cRowPix), mSimRespIBScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
368 rspmat = mSimRespOB->
getResponse(xyzLocS.X() - cRowPix, xyzLocS.Z() - cColPix, xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
372 if (rspmat ==
nullptr) {
376 for (
int irow = AlpideRespSimMat::NPix; irow--;) {
377 int rowDest =
row + irow - AlpideRespSimMat::NPix / 2 - rowS;
378 if (rowDest < 0 || rowDest >= rowSpan) {
381 for (
int icol = AlpideRespSimMat::NPix; icol--;) {
382 int colDest =
col + icol - AlpideRespSimMat::NPix / 2 - colS;
383 if (colDest < 0 || colDest >= colSpan) {
386 respMatrix[rowDest][colDest] += rspmat->getValue(irow, icol, ((chip.isIB() && mSimRespIBOrientation) ? !flipRow : flipRow), flipCol);
393 auto roFrameAbs = mNewROFrame + roFrameRel;
394 for (
int irow = rowSpan; irow--;) {
395 uint16_t rowIS = irow + rowS;
396 for (
int icol = colSpan; icol--;) {
397 float nEleResp = respMatrix[irow][icol];
398 if (nEleResp <= 1.e-36) {
401 int nEle = gRandom->Poisson(nElectrons * nEleResp);
406 uint16_t colIS = icol + colS;
407 registerDigits(chip, roFrameAbs, timeInROF, nFrames, rowIS, colIS, nEle, lbl);
420 for (
int i = 0;
i < nROF;
i++) {
421 uint32_t roFr = roFrame +
i;
429 if (roFr > mEventROFrameMax) {
430 mEventROFrameMax = roFr;
432 if (roFr < mEventROFrameMin) {
433 mEventROFrameMin = roFr;
444 ExtraDig* extra = getExtraDigBuffer(roFr);
448 if ((*extra)[nxt].
label == lbl) {
452 nxt = (*extra)[nxt].next;
459 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
bool isContinuous() const
void setEventTime(const o2::InteractionTimeRecord &irt)
void process(const std::vector< itsmft::Hit > *hits, int evID, int srcID)
Steer conversion of hits to digits.
void fillOutputContainer(uint32_t maxFrame=0xffffffff)
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
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 getROFrameLengthInv() 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
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"