46 mChips.resize(numOfChips);
47 for (
int i = numOfChips;
i--;) {
48 mChips[
i].setChipIndex(
i);
49 if (mDeadChanMap !=
nullptr) {
51 mChips[
i].setDeadChanMap(mDeadChanMap);
56 auto loadSetResponseFunc = [&](
const char* fileIB,
const char* nameIB,
const char* fileOB,
const char* nameOB) {
57 LOGP(info,
"Loading response function IB={}:{} ; OB={}:{}", nameIB, fileIB, nameOB, fileOB);
58 auto fIB = TFile::Open(fileIB,
"READ");
59 if (!fIB || fIB->IsZombie() || !fIB->IsOpen()) {
60 LOGP(fatal,
"Cannot open file {}", fileIB);
62 auto fOB = TFile::Open(fileOB,
"READ");
63 if (!fOB || fOB->IsZombie() || !fOB->IsOpen()) {
64 LOGP(fatal,
"Cannot open file {}", fileOB);
67 LOGP(fatal,
"Cannot create response function for IB");
70 LOGP(fatal,
"Cannot create response function for OB");
79 constexpr const char* responseFile =
"$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root";
80 loadSetResponseFunc(responseFile,
"response0", responseFile,
"response0");
83 }
else if (
func ==
"APTS") {
84 constexpr const char* responseFileIB =
"$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/APTSResponseData.root";
85 constexpr const char* responseFileOB =
"$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root";
86 loadSetResponseFunc(responseFileIB,
"response1", responseFileOB,
"response0");
89 mSimRespIBOrientation =
true;
91 LOGP(fatal,
"ResponseFunction '{}' not implemented!",
func);
98 LOGP(info,
"IB shift = {} ; OB shift = {}", mSimRespIBShift, mSimRespOBShift);
99 LOGP(info,
"IB pixel scale on x = {} ; z = {}", mSimRespIBScaleX, mSimRespIBScaleZ);
100 LOGP(info,
"IB response orientation: {}", mSimRespIBOrientation ?
"flipped" :
"normal");
108 LOG(info) <<
"Digitizing " << mGeometry->
getName() <<
" hits of entry " << evID <<
" from source "
109 << srcID <<
" at time " << mEventTime <<
" ROFrame = " << mNewROFrame <<
")"
111 <<
" Min/Max ROFrames " << mROFrameMin <<
"/" << mROFrameMax;
114 if (mNewROFrame > mROFrameMin) {
118 int nHits = hits->size();
119 std::vector<int> hitIdx(nHits);
120 std::iota(std::begin(hitIdx), std::end(hitIdx), 0);
122 std::sort(hitIdx.begin(), hitIdx.end(),
123 [hits](
auto lhs,
auto rhs) {
124 return (*hits)[lhs].GetDetectorID() < (*hits)[rhs].GetDetectorID();
126 for (
int i : hitIdx) {
127 processHit((*hits)[
i], mROFrameMax, evID, srcID);
149 if (mCollisionTimeWrtROF < 0 && nbc > 0) {
159 if (mNewROFrame < mROFrameMin) {
160 LOG(error) <<
"New ROFrame " << mNewROFrame <<
" (" << irt <<
") precedes currently cashed " << mROFrameMin;
161 throw std::runtime_error(
"deduced ROFrame precedes already processed one");
164 if (mParams.
isContinuous() && mROFrameMax < mNewROFrame) {
165 mROFrameMax = mNewROFrame - 1;
172 if (frameLast > mROFrameMax) {
173 frameLast = mROFrameMax;
176 getExtraDigBuffer(mROFrameMax);
178 LOG(info) <<
"Filling " << mGeometry->
getName() <<
" digits output for RO frames " << mROFrameMin <<
":"
184 for (; mROFrameMin <= frameLast; mROFrameMin++) {
188 auto& extra = *(mExtraBuff.front().get());
189 for (
size_t iChip{0}; iChip < mChips.size(); ++iChip) {
190 auto& chip = mChips[iChip];
191 chip.addNoise(mROFrameMin, mROFrameMin, &mParams);
192 auto&
buffer = chip.getPreDigits();
196 auto itBeg =
buffer.begin();
198 ULong64_t maxKey = chip.getOrderingKey(mROFrameMin + 1, 0, 0) - 1;
199 for (; iter !=
buffer.end(); ++iter) {
200 if (iter->first > maxKey) {
203 auto& preDig = iter->second;
205 int digID = mDigits->size();
206 mDigits->emplace_back(chip.getChipIndex(), preDig.row, preDig.col, preDig.charge);
207 mMCLabels->
addElement(digID, preDig.labelRef.label);
208 auto& nextRef = preDig.labelRef;
209 while (nextRef.next >= 0) {
210 nextRef = extra[nextRef.next];
215 buffer.erase(itBeg, iter);
224 if (mROFRecords !=
nullptr) {
225 mROFRecords->push_back(rcROF);
229 mExtraBuff.emplace_back(mExtraBuff.front().release());
230 mExtraBuff.pop_front();
234void Digitizer::processHit(
const o2::itsmft::Hit& hit, uint32_t& maxFr,
int evID,
int srcID)
238 auto& chip = mChips[chipID];
239 if (chip.isDisabled()) {
242 float timeInROF = hit.
GetTime() * sec2ns;
243 if (timeInROF > 20e3) {
244 const int maxWarn = 10;
245 static int warnNo = 0;
246 if (warnNo < maxWarn) {
247 LOG(warning) <<
"Ignoring hit with time_in_event = " << timeInROF <<
" ns"
248 << ((++warnNo < maxWarn) ?
"" :
" (suppressing further warnings)");
253 timeInROF += mCollisionTimeWrtROF;
264 int nFrames = roFrameRelMax + 1 - roFrameRel;
265 uint32_t roFrameMax = mNewROFrame + roFrameRelMax;
266 if (roFrameMax > maxFr) {
278 xyzLocE = matrix ^ (hit.
GetPos());
281 float xFlatE{0.f}, yFlatE{0.f}, xFlatS{0.f}, yFlatS{0.f};
282 mIBSegmentations[
layer].curvedToFlat(xyzLocS.X(), xyzLocS.Y(), xFlatS, yFlatS);
283 mIBSegmentations[
layer].curvedToFlat(xyzLocE.X(), xyzLocE.Y(), xFlatE, yFlatE);
285 xyzLocS.SetXYZ(xFlatS, yFlatS, xyzLocS.Z());
286 xyzLocE.SetXYZ(xFlatE, yFlatE, xyzLocE.Z());
296 int rowS = -1, colS = -1, rowE = -1, colE = -1, nSkip = 0;
299 while (!mIBSegmentations[
layer].localToDetector(xyzLocS.X(), xyzLocS.Z(), rowS, colS)) {
300 if (++nSkip >= nSteps) {
306 while (!mIBSegmentations[
layer].localToDetector(xyzLocE.X(), xyzLocE.Z(), rowE, colE)) {
307 if (++nSkip >= nSteps) {
315 if (++nSkip >= nSteps) {
322 if (++nSkip >= nSteps) {
331 std::swap(rowS, rowE);
334 std::swap(colS, colE);
336 rowS -= AlpideRespSimMat::NPix / 2;
337 rowE += AlpideRespSimMat::NPix / 2;
338 rowS = std::max(rowS, 0);
343 rowE = std::min(rowE, maxNrows - 1);
344 colS -= AlpideRespSimMat::NPix / 2;
345 colE += AlpideRespSimMat::NPix / 2;
346 colS = std::max(colS, 0);
347 colE = std::min(colE, maxNcols - 1);
349 int rowSpan = rowE - rowS + 1, colSpan = colE - colS + 1;
350 float respMatrix[rowSpan][colSpan];
351 std::fill(&respMatrix[0][0], &respMatrix[0][0] + rowSpan * colSpan, 0.f);
354 nElectrons *= nStepsInv;
359 int rowPrev = -1, colPrev = -1,
row,
col;
360 float cRowPix = 0.f, cColPix = 0.f;
365 xyzLocS.SetY(xyzLocS.Y() + ((chip.isIB()) ? mSimRespIBShift : mSimRespOBShift));
368 for (
int iStep = nSteps; iStep--;) {
371 mIBSegmentations[
layer].localToDetector(xyzLocS.X(), xyzLocS.Z(),
row,
col);
375 if (
row != rowPrev ||
col != colPrev) {
377 if (!mIBSegmentations[
layer].detectorToLocal(
row,
col, cRowPix, cColPix)) {
386 bool flipCol =
false, flipRow =
false;
388 float rowMax{}, colMax{};
393 rspmat = mSimRespIB->
getResponse(mSimRespIBScaleX * (xyzLocS.X() - cRowPix), mSimRespIBScaleZ * (xyzLocS.Z() - cColPix), xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
397 rspmat = mSimRespOB->
getResponse(xyzLocS.X() - cRowPix, xyzLocS.Z() - cColPix, xyzLocS.Y(), flipRow, flipCol, rowMax, colMax);
401 if (rspmat ==
nullptr) {
405 for (
int irow = AlpideRespSimMat::NPix; irow--;) {
406 int rowDest =
row + irow - AlpideRespSimMat::NPix / 2 - rowS;
407 if (rowDest < 0 || rowDest >= rowSpan) {
410 for (
int icol = AlpideRespSimMat::NPix; icol--;) {
411 int colDest =
col + icol - AlpideRespSimMat::NPix / 2 - colS;
412 if (colDest < 0 || colDest >= colSpan) {
415 respMatrix[rowDest][colDest] += rspmat->getValue(irow, icol, ((chip.isIB() && mSimRespIBOrientation) ? !flipRow : flipRow), flipCol);
422 auto roFrameAbs = mNewROFrame + roFrameRel;
423 for (
int irow = rowSpan; irow--;) {
424 uint16_t rowIS = irow + rowS;
425 for (
int icol = colSpan; icol--;) {
426 float nEleResp = respMatrix[irow][icol];
427 if (nEleResp <= 1.e-36) {
430 int nEle = gRandom->Poisson(nElectrons * nEleResp);
435 uint16_t colIS = icol + colS;
436 registerDigits(chip, roFrameAbs, timeInROF, nFrames, rowIS, colIS, nEle, lbl);
449 for (
int i = 0;
i < nROF;
i++) {
450 uint32_t roFr = roFrame +
i;
458 if (roFr > mEventROFrameMax) {
459 mEventROFrameMax = roFr;
461 if (roFr < mEventROFrameMin) {
462 mEventROFrameMin = roFr;
473 ExtraDig* extra = getExtraDigBuffer(roFr);
477 if ((*extra)[nxt].
label == lbl) {
481 nxt = (*extra)[nxt].next;
488 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
short GetDetectorID() const
static const ITS3Params & Instance()
const char * getName() const
const Mat3D & getMatrixL2G(int sensID) const
bool hasResponseFunctions() const
void setOBSimResponse(const o2::itsmft::AlpideSimResponse *response)
float getIBNSimStepsInv() const
int getIBChargeThreshold() const
int getIBNSimSteps() const
void setIBSimResponse(o2::its3::ChipSimResponse *response)
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"