@@ -100,7 +100,7 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, int evID, int srcID)
100100 }
101101
102102 // Get detector element ID
103- int chipID = hit.GetDetectorID ();
103+ const int chipID = hit.GetDetectorID ();
104104 auto & chip = mChips [chipID];
105105 if (chip.isDisabled ()) {
106106 LOG (debug) << " Hit rejected because chip " << chipID << " is disabled" ;
@@ -110,92 +110,95 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, int evID, int srcID)
110110 // Convert energy loss to charge (number of electrons)
111111 float energyLoss = hit.GetEnergyLoss (); // in GeV
112112 int charge = energyToCharge (energyLoss);
113+ const auto & digitizerParams = o2::iotof::DPLDigitizerParam::Instance ();
114+ int electronsPerStep = static_cast <int >(charge / digitizerParams.nSimSteps );
113115
114116 // Apply charge threshold
115117 if (charge < mChargeThreshold ) {
116118 LOG (debug) << " Hit rejected by charge threshold: " << charge << " < " << mChargeThreshold ;
117119 return ;
118120 }
119121
120-
121122 // Get hit time and apply smearing
122123 // Hit time is in seconds, convert to ns and add event time
123124 double hitTime = hit.GetTime () * sec2ns; // convert to ns
124125 double eventTimeNS = mEventTime .getTimeNS (); // event time since orbit 0
125126 double absoluteTime = hitTime + eventTimeNS; // absolute time
126127 double smearedTime = smearTime (absoluteTime); // apply detector resolution
127128
128- if (chipID < 0 || chipID >= mGeometry ->getSize () || mGeometry ->getSize () < 1 ) {
129-
130129 // For now, use simple row/col mapping from detector ID
131130 // TODO: Implement proper segmentation when geometry is finalized
132131 uint16_t chipIndex = static_cast <uint16_t >(chipID);
133-
134- if (chipID > mGeometry ->getSize () || mGeometry ->getSize () < 1 ) {
132+
133+ if (chipID < 0 || chipID >= mGeometry ->getSize () || mGeometry ->getSize () < 1 ) {
135134 LOG (debug) << " Invalid detector ID: " << chipID << " , geometry size: " << mGeometry ->getSize ();
136135 return ; // invalid detector ID
137136 }
138137
139138 // stepping is called here
140-
139+ float ** respMatrix = nullptr ;
140+ int rowStart = 0 , colStart = 0 , rowSpan = 0 , colSpan = 0 ;
141+ stepping (hit, respMatrix, rowStart, colStart, rowSpan, colSpan);
142+
141143 // Create the digit with time information
142144 o2::MCCompLabel label (hit.GetTrackID (), evID, srcID, false );
143- const int roFrameAbs = 0 ; // For now, we can set this to 0 or calculate based on time if needed
144- const int nROF = 1 ; // For now, we can assume the signal is contained in one ROF, this can be extended to multiple ROFs based on the time
145+ const int roFrameAbs = 0 ; // For now, we can set this to 0 or calculate based on time if needed
146+ const int nROF = 1 ; // For now, we can assume the signal is contained in one ROF, this can be extended to multiple ROFs based on the time
145147 for (int irow = rowSpan; irow--;) {
146148 uint16_t rowIS = irow + rowStart;
147149 for (int icol = colSpan; icol--;) {
148150 uint16_t colIS = icol + colStart;
149151 float nEleResp = respMatrix[irow][icol];
150152 if (!nEleResp) {
151- continue ;
153+ continue ;
152154 }
153155 int nElectronsSampled = gRandom ->Poisson (electronsPerStep * nEleResp);
154156 // Noise can be added here if needed
155-
156- registerDigits (chip, roFrameAbs, smearedTime, nROF, static_cast <uint16_t >(row), static_cast <uint16_t >(col), nElectronsSampled, label);
157+
158+ registerDigits (chip, roFrameAbs, smearedTime, nROF,
159+ static_cast <uint16_t >(rowIS), static_cast <uint16_t >(colIS), nElectronsSampled, label);
157160 }
158161 }
159162
160163 for (int irow = 0 ; irow < rowSpan; ++irow) {
161164 delete[] respMatrix[irow];
162165 }
163166 delete[] respMatrix;
164-
165-
166-
167-
168167}
169168
170- void Digitizer::stepping (const o2::itsmft::Hit& hit, float **& respMatrix)
169+ void Digitizer::stepping (const o2::itsmft::Hit& hit, float **& respMatrix, int & rowStart, int & colStart, int & rowSpan, int & colSpan )
171170{
172171 const auto & matrix = mGeometry ->getMatrixL2G (hit.GetDetectorID ());
173-
174- math_utils::Vector3D<float > xyzPositionStart (matrix ^ (hit.GetPosStart ())); // start position in sensor frame
175- math_utils::Vector3D<float > xyzPositionEnd (matrix ^ (hit.GetPos ())); // end position in sensor frame
176-
177- const auto & digitizerParams = DPLDigitizerParam::Instance ();
172+ const int chipID = hit.GetDetectorID ();
173+ const int subdetectorID = mGeometry ->getIOTOFLayer ();
174+
175+ auto xyzPositionStart (matrix ^ (hit.GetPosStart ())); // start position in sensor frame
176+ auto xyzPositionEnd (matrix ^ (hit.GetPos ())); // end position in sensor frame
177+
178+ const auto & digitizerParams = o2::iotof::DPLDigitizerParam::Instance ();
178179 const auto stepVector = (xyzPositionEnd - xyzPositionStart) / digitizerParams.nSimSteps ;
179- xyzPositionStart = xyzPositionStart + stepVector * 0 .5f ; // center the start position in the middle of the step
180- xyzPositionEnd = xyzPositionEnd - stepVector * 0 .5f ; // center the end position in the middle of the step
181-
182- int rowStart = -1 , colStart = -1 , rowEnd = -1 , colEnd = -1 , nSkip = 0 ;
180+ xyzPositionStart = xyzPositionStart + stepVector * 0 .5f ; // center the start position in the middle of the step
181+ xyzPositionEnd = xyzPositionEnd - stepVector * 0 .5f ; // center the end position in the middle of the step
182+
183+ rowStart = -1 ;
184+ colStart = -1 ;
185+ int rowEnd = -1 , colEnd = -1 , nSkip = 0 , nSteps = digitizerParams.nSimSteps ;
183186 while (!sSegmentation ->localToDetector (xyzPositionStart.X (), xyzPositionStart.Z (), rowStart, colStart, mGeometry ->getIOTOFLayer (chipID))) {
184- if (++nSkip > digitizerParams.nSimSteps ) { // additional check to add: should we exclude something?
187+ if (++nSkip > digitizerParams.nSimSteps ) { // additional check to add: should we exclude something?
185188 LOG (debug) << " Hit position out of bounds for detector ID " << chipID;
186189 return ; // hit is outside the active area
187190 }
188191 xyzPositionStart += stepVector;
189192 }
190-
193+
191194 while (!sSegmentation ->localToDetector (xyzPositionEnd.X (), xyzPositionEnd.Z (), rowEnd, colEnd, mGeometry ->getIOTOFLayer (chipID))) {
192- if (++nSkip > digitizerParams.nSimSteps ) { // additional check to add: should we exclude something?
195+ if (++nSkip > digitizerParams.nSimSteps ) { // additional check to add: should we exclude something?
193196 LOG (debug) << " Hit position out of bounds for detector ID " << chipID;
194197 return ; // hit is outside the active area
195198 }
196199 xyzPositionEnd += stepVector;
197200 }
198-
201+
199202 if (rowStart > rowEnd) {
200203 std::swap (rowStart, rowEnd);
201204 }
@@ -209,49 +212,48 @@ void Digitizer::stepping(const o2::itsmft::Hit& hit, float**& respMatrix)
209212 rowStart = std::max (rowStart, 0 );
210213 colStart = std::max (colStart, 0 );
211214
212- rowEnd = std::min (rowEnd, mGeometry -> getNumberOfRows (chipID ) - 1 );
213- colEnd = std::min (colEnd, mGeometry -> getNumberOfColumns (chipID ) - 1 );
214- int rowSpan = rowEnd - rowStart + 1 ;
215- int colSpan = colEnd - colStart + 1 ;
215+ rowEnd = std::min (rowEnd, (subdetectorID == 0 ? sSegmentation -> mITofSpecsConfig . NRows : sSegmentation -> mOTofSpecsConfig . NRows ) - 1 );
216+ colEnd = std::min (colEnd, (subdetectorID == 0 ? sSegmentation -> mITofSpecsConfig . NCols : sSegmentation -> mOTofSpecsConfig . NCols ) - 1 );
217+ rowSpan = rowEnd - rowStart + 1 ;
218+ colSpan = colEnd - colStart + 1 ;
216219
217220 respMatrix = new float *[rowSpan];
218221 for (int i = 0 ; i < rowSpan; ++i) {
219222 respMatrix[i] = new float [colSpan]();
220223 }
221224
222- int rowPrev = -1 , colPrev = -1 , row, col;
223- if (!respMatrix || rowSpan <= 0 || colSpan <= 0 ) continue ;
225+ int rowPrev = -1 , colPrev = -1 , row = 0 , col = 0 ;
226+ if (!respMatrix || rowSpan <= 0 || colSpan <= 0 ) {
227+ return ;
228+ }
224229 if (nSkip) {
225230 nSteps -= nSkip;
226231 }
227232
228233 auto & currentPosLocal = xyzPositionStart;
229234 for (int iStep = nSteps; iStep--;) {
230- segmentation ->localToDetector (currentPosLocal.X (), currentPosLocal.Z (), row, col, subdetectorID);
235+ sSegmentation ->localToDetector (currentPosLocal.X (), currentPosLocal.Z (), row, col, subdetectorID);
231236 if (row != rowPrev || col != colPrev) {
232- rowPrev = row;
233- colPrev = col;
237+ rowPrev = row;
238+ colPrev = col;
234239 }
235-
240+
236241 currentPosLocal += stepVector; // Move to the next step position
237242
238243 for (int irow = digitizerParams.responseMatrixSize ; irow--;) {
239244 int rowDest = row + irow - (digitizerParams.responseMatrixSize / 2 ) - rowStart; // destination row in the respMatrix
240245 if (rowDest < 0 || rowDest >= rowSpan) {
241- continue ;
246+ continue ;
242247 }
243248 for (int icol = digitizerParams.responseMatrixSize ; icol--;) {
244- int colDest = col + icol - (digitizerParams.responseMatrixSize / 2 ) - colStart; // destination column in the respMatrix
245- if (colDest < 0 || colDest >= colSpan) {
249+ int colDest = col + icol - (digitizerParams.responseMatrixSize / 2 ) - colStart; // destination column in the respMatrix
250+ if (colDest < 0 || colDest >= colSpan) {
246251 continue ;
247- }
248- respMatrix[rowDest][colDest] += 1 .;
252+ }
253+ respMatrix[rowDest][colDest] += 1 .;
249254 }
250255 }
251256 }
252-
253-
254-
255257}
256258
257259// _______________________________________________________________________
@@ -305,10 +307,9 @@ void Digitizer::fillOutputContainer()
305307 auto & chipDigits = chip.getDigits ();
306308 for (const auto & [key, digit] : chipDigits) {
307309
308- // / Charge threshold not implemented yet
309- // / if (digit.getCharge() < mChargeThreshold) {
310- // / continue; // skip digits below threshold
311- // / }
310+ if (digit.getCharge () < mChargeThreshold ) {
311+ continue ; // skip digits below threshold
312+ }
312313
313314 int digitID = mDigits ->size ();
314315 mDigits ->emplace_back (digit.getChipIndex (), digit.getRow (), digit.getColumn (), digit.getCharge (), digit.getTime ());
0 commit comments