40 mChips.resize(numOfChips);
41 for (
int i = numOfChips;
i--;) {
42 mChips[
i].setChipIndex(
i);
43 if (mDeadChanMap !=
nullptr) {
45 mChips[
i].setDeadChanMap(mDeadChanMap);
50 auto loadSetResponseFunc = [&](
const char* fileIB,
const char* nameIB,
const char* fileOB,
const char* nameOB) {
51 LOGP(info,
"Loading response function IB={}:{} ; OB={}:{}", nameIB, fileIB, nameOB, fileOB);
52 auto fIB = TFile::Open(fileIB,
"READ");
53 if (!fIB || fIB->IsZombie() || !fIB->IsOpen()) {
54 LOGP(fatal,
"Cannot open file {}", fileIB);
56 auto fOB = TFile::Open(fileOB,
"READ");
57 if (!fOB || fOB->IsZombie() || !fOB->IsOpen()) {
58 LOGP(fatal,
"Cannot open file {}", fileOB);
67 constexpr const char* responseFile =
"$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root";
68 loadSetResponseFunc(responseFile,
"response0", responseFile,
"response0");
71 }
else if (
func ==
"APTS") {
72 constexpr const char* responseFileIB =
"$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/APTSResponseData.root";
73 constexpr const char* responseFileOB =
"$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root";
74 loadSetResponseFunc(responseFileIB,
"response1", responseFileOB,
"response0");
77 mSimRespIBOrientation =
true;
79 LOGP(fatal,
"ResponseFunction '{}' not implemented!",
func);
86 LOGP(info,
"IB shift = {} ; OB shift = {}", mSimRespIBShift, mSimRespOBShift);
87 LOGP(info,
"IB pixel scale on x = {} ; z = {}", mSimRespIBScaleX, mSimRespIBScaleZ);
88 LOGP(info,
"IB response orientation: {}", mSimRespIBOrientation ?
"flipped" :
"normal");
96 LOG(info) <<
"Digitizing " << mGeometry->
getName() <<
" hits of entry " << evID <<
" from source "
97 << srcID <<
" at time " << mEventTime <<
" ROFrame = " << mNewROFrame <<
")"
99 <<
" Min/Max ROFrames " << mROFrameMin <<
"/" << mROFrameMax;
102 if (mNewROFrame > mROFrameMin) {
106 int nHits = hits->size();
107 std::vector<int> hitIdx(nHits);
108 std::iota(std::begin(hitIdx), std::end(hitIdx), 0);
110 std::sort(hitIdx.begin(), hitIdx.end(),
111 [hits](
auto lhs,
auto rhs) {
112 return (*hits)[lhs].GetDetectorID() < (*hits)[rhs].GetDetectorID();
114 for (
int i : hitIdx) {
115 processHit((*hits)[
i], mROFrameMax, evID, srcID);
137 if (mCollisionTimeWrtROF < 0 && nbc > 0) {
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 if (frameLast > mROFrameMax) {
161 frameLast = mROFrameMax;
164 getExtraDigBuffer(mROFrameMax);
166 LOG(info) <<
"Filling " << mGeometry->
getName() <<
" digits output for RO frames " << mROFrameMin <<
":"
172 for (; mROFrameMin <= frameLast; mROFrameMin++) {
176 auto& extra = *(mExtraBuff.front().get());
177 for (
size_t iChip{0}; iChip < mChips.size(); ++iChip) {
178 auto& chip = mChips[iChip];
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)
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;
252 int nFrames = roFrameRelMax + 1 - roFrameRel;
253 uint32_t roFrameMax = mNewROFrame + roFrameRelMax;
254 if (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);
437 for (
int i = 0;
i < nROF;
i++) {
438 uint32_t roFr = roFrame +
i;
446 if (roFr > mEventROFrameMax) {
447 mEventROFrameMax = roFr;
449 if (roFr < mEventROFrameMin) {
450 mEventROFrameMin = roFr;
461 ExtraDig* extra = getExtraDigBuffer(roFr);
465 if ((*extra)[nxt].
label == lbl) {
469 nxt = (*extra)[nxt].next;
476 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"