39 mChips.resize(numOfChips);
40 for (
int i = numOfChips;
i--;) {
41 mChips[
i].setChipIndex(
i);
42 if (mDeadChanMap !=
nullptr) {
44 mChips[
i].setDeadChanMap(mDeadChanMap);
49 auto loadSetResponseFunc = [&](
const char*
name,
const char* fileIB,
const char* nameIB,
const char* fileOB,
const char* nameOB) {
50 LOGP(info,
"Loading response function for {}: IB={}:{} ; OB={}:{}",
name, nameIB, fileIB, nameOB, fileOB);
51 auto fIB = TFile::Open(fileIB,
"READ");
52 if (!fIB || fIB->IsZombie() || !fIB->IsOpen()) {
53 LOGP(fatal,
"Cannot open file {}", fileIB);
55 auto fOB = TFile::Open(fileOB,
"READ");
56 if (!fOB || fOB->IsZombie() || !fOB->IsOpen()) {
57 LOGP(fatal,
"Cannot open file {}", fileOB);
66 constexpr const char* responseFile =
"$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root";
67 loadSetResponseFunc(
"Alpide", responseFile,
"response0", responseFile,
"response1");
70 }
else if (
func ==
"APTS") {
71 constexpr const char* responseFileIB =
"$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/APTSResponseData.root";
72 constexpr const char* responseFileOB =
"$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root";
73 loadSetResponseFunc(
"APTS", responseFileIB,
"response1", responseFileOB,
"response1");
74 mSimRespIBShift = mSimRespIB->
getDepthMax() + (float)constants::pixelarray::pixels::apts::responseYShift;
78 mSimRespIBOrientation =
true;
80 LOGP(fatal,
"ResponseFunction '{}' not implemented!",
func);
84 LOGP(info,
"IBShift = {} ; OBShift = {}", mSimRespIBShift, mSimRespOBShift);
85 LOGP(info,
"IB-Scale: X={} ; Z={}", mSimRespIBScaleX, mSimRespIBScaleZ);
93 LOG(info) <<
"Digitizing " << mGeometry->
getName() <<
" hits of entry " << evID <<
" from source "
94 << srcID <<
" at time " << mEventTime <<
" ROFrame = " << mNewROFrame <<
")"
96 <<
" Min/Max ROFrames " << mROFrameMin <<
"/" << mROFrameMax;
99 if (mNewROFrame > mROFrameMin) {
103 int nHits = hits->size();
104 std::vector<int> hitIdx(nHits);
105 std::iota(std::begin(hitIdx), std::end(hitIdx), 0);
107 std::sort(hitIdx.begin(), hitIdx.end(),
108 [hits](
auto lhs,
auto rhs) {
109 return (*hits)[lhs].GetDetectorID() < (*hits)[rhs].GetDetectorID();
111 for (
int i : hitIdx) {
112 processHit((*hits)[
i], mROFrameMax, evID, srcID);
134 if (mCollisionTimeWrtROF < 0 && nbc > 0) {
144 if (mNewROFrame < mROFrameMin) {
145 LOG(error) <<
"New ROFrame " << mNewROFrame <<
" (" << irt <<
") precedes currently cashed " << mROFrameMin;
146 throw std::runtime_error(
"deduced ROFrame precedes already processed one");
149 if (mParams.
isContinuous() && mROFrameMax < mNewROFrame) {
150 mROFrameMax = mNewROFrame - 1;
157 if (frameLast > mROFrameMax) {
158 frameLast = mROFrameMax;
161 getExtraDigBuffer(mROFrameMax);
163 LOG(info) <<
"Filling " << mGeometry->
getName() <<
" digits output for RO frames " << mROFrameMin <<
":"
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];
179 chip.addNoise(mROFrameMin, mROFrameMin, &mParams);
181 auto&
buffer = chip.getPreDigits();
185 auto itBeg =
buffer.begin();
187 ULong64_t maxKey = chip.getOrderingKey(mROFrameMin + 1, 0, 0) - 1;
188 for (; iter !=
buffer.end(); ++iter) {
189 if (iter->first > maxKey) {
192 auto& preDig = iter->second;
194 int digID = mDigits->size();
195 mDigits->emplace_back(chip.getChipIndex(), preDig.row, preDig.col, preDig.charge);
196 mMCLabels->
addElement(digID, preDig.labelRef.label);
197 auto& nextRef = preDig.labelRef;
198 while (nextRef.next >= 0) {
199 nextRef = extra[nextRef.next];
204 buffer.erase(itBeg, iter);
213 if (mROFRecords !=
nullptr) {
214 mROFRecords->push_back(rcROF);
218 mExtraBuff.emplace_back(mExtraBuff.front().release());
219 mExtraBuff.pop_front();
223void Digitizer::processHit(
const o2::itsmft::Hit& hit, uint32_t& maxFr,
int evID,
int srcID)
227 auto& chip = mChips[chipID];
228 if (chip.isDisabled()) {
231 float timeInROF = hit.
GetTime() * sec2ns;
232 if (timeInROF > 20e3) {
233 const int maxWarn = 10;
234 static int warnNo = 0;
235 if (warnNo < maxWarn) {
236 LOG(warning) <<
"Ignoring hit with time_in_event = " << timeInROF <<
" ns"
237 << ((++warnNo < maxWarn) ?
"" :
" (suppressing further warnings)");
242 timeInROF += mCollisionTimeWrtROF;
253 int nFrames = roFrameRelMax + 1 - roFrameRel;
254 uint32_t roFrameMax = mNewROFrame + roFrameRelMax;
255 if (roFrameMax > maxFr) {
265 bool innerBarrel{
layer < 3};
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() + ((innerBarrel) ? 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, ((innerBarrel && 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);
439 for (
int i = 0;
i < nROF;
i++) {
440 uint32_t roFr = roFrame +
i;
448 if (roFr > mEventROFrameMax) {
449 mEventROFrameMax = roFr;
451 if (roFr < mEventROFrameMin) {
452 mEventROFrameMin = roFr;
463 ExtraDig* extra = getExtraDigBuffer(roFr);
467 if ((*extra)[nxt].
label == lbl) {
471 nxt = (*extra)[nxt].next;
478 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)
void setIBSimResponse(const o2::itsmft::AlpideSimResponse *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)
static constexpr float SensorLayerThickness
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
Container for similated points connected to a given chip.
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.
int getMinChargeToAccount() const
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 const GLchar * name
GLuint GLsizei const GLchar * label
GLenum GLuint GLint GLint layer
constexpr double LHCBunchSpacingNS
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"