@@ -104,6 +104,12 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, int evID, int srcID)
104104
105105 // Get detector element ID
106106 const int chipID = hit.GetDetectorID ();
107+ if (chipID < 0 || chipID >= mGeometry ->getSize () || mGeometry ->getSize () < 1 ) {
108+ LOG (debug) << " Invalid detector ID: " << chipID << " , geometry size: " << mGeometry ->getSize ();
109+ return ; // invalid detector ID
110+ }
111+ const int subdetectorID = mGeometry ->getIOTOFLayer (chipID);
112+
107113 auto & chip = mChips [chipID];
108114 if (chip.isDisabled ()) {
109115 LOG (debug) << " Hit rejected because chip " << chipID << " is disabled" ;
@@ -116,27 +122,31 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, int evID, int srcID)
116122 const auto & digitizerParams = o2::iotof::DPLDigitizerParam::Instance ();
117123 int electronsPerStep = static_cast <int >(charge / digitizerParams.nSimSteps );
118124
125+ // Apply charge threshold
126+ if (charge < digitizerParams.chargeThreshold ) {
127+ LOG (debug) << " Hit rejected by charge threshold: " << charge << " < " << digitizerParams.chargeThreshold ;
128+ return ;
129+ }
130+
119131 // Get hit time and apply smearing
120132 // Hit time is in seconds, convert to ns and add event time
121133 double hitTime = hit.GetTime () * sec2ns; // convert to ns
122134 double eventTimeInBC = mEventTime .getTimeOffsetWrtBC (); // event time wrt bc
123135 double hitTimeWrtBC = hitTime + eventTimeInBC; // hit time wrt bc
124136 double smearedTime = smearTime (hitTimeWrtBC);
125137
126- if (chipID < 0 || chipID >= mGeometry ->getSize () || mGeometry ->getSize () < 1 ) {
127- LOG (debug) << " Invalid detector ID: " << chipID << " , geometry size: " << mGeometry ->getSize ();
128- return ; // invalid detector ID
129- }
130-
131138 // Create the digit with time information
132139 o2::MCCompLabel label (hit.GetTrackID (), evID, srcID, false );
133140 const int roFrameAbs = 0 ; // For now, we can set this to 0 or calculate based on time if needed
134141 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
135142
136143 float ** respMatrix = nullptr ;
144+ float ** avgHitLocalX = nullptr ;
145+ float ** avgHitLocalZ = nullptr ;
137146 int rowStart = 0 , colStart = 0 , rowSpan = 0 , colSpan = 0 ;
138- stepping (hit, respMatrix, rowStart, colStart, rowSpan, colSpan);
147+ stepping (hit, respMatrix, avgHitLocalX, avgHitLocalZ, rowStart, colStart, rowSpan, colSpan);
139148
149+ float xPixelCenter = 0 .0f , zPixelCenter = 0 .0f ;
140150 for (int irow = rowSpan; irow--;) {
141151 uint16_t rowIS = irow + rowStart;
142152 for (int icol = colSpan; icol--;) {
@@ -145,12 +155,15 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, int evID, int srcID)
145155 if (!nEleResp) {
146156 continue ;
147157 }
148- const int nElectronsSampled = gRandom ->Poisson (electronsPerStep * nEleResp);
149- // Apply charge threshold cut taking into account fraction of charge in the pixel
150- if (nElectronsSampled < digitizerParams.chargeThreshold ) {
151- LOG (debug) << " Hit rejected by charge threshold: " << nElectronsSampled << " < " << digitizerParams.chargeThreshold ;
158+
159+ // Apply efficiency cut based on the hit segment mean position relative to the pixel center
160+ sSegmentation ->detectorToLocal (rowIS, colIS, xPixelCenter, zPixelCenter, subdetectorID);
161+ if (!isEfficient (avgHitLocalX[irow][icol] - xPixelCenter, avgHitLocalZ[irow][icol] - zPixelCenter)) {
162+ LOG (debug) << " Hit rejected by efficiency cut at pixel (" << rowIS << " , " << colIS << " ) in chip " << chipID;
152163 continue ;
153164 }
165+
166+ const int nElectronsSampled = gRandom ->Poisson (electronsPerStep * nEleResp);
154167 // Noise can be added here if needed
155168
156169 registerDigits (chip, roFrameAbs, smearedTime, nROF,
@@ -160,12 +173,17 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, int evID, int srcID)
160173
161174 for (int irow = 0 ; irow < rowSpan; ++irow) {
162175 delete[] respMatrix[irow];
176+ delete[] avgHitLocalX[irow];
177+ delete[] avgHitLocalZ[irow];
163178 }
164179 delete[] respMatrix;
180+ delete[] avgHitLocalX;
181+ delete[] avgHitLocalZ;
165182}
166183
167- void Digitizer::stepping (const o2::itsmft::Hit& hit, float **& respMatrix, int & rowStart, int & colStart, int & rowSpan, int & colSpan)
184+ void Digitizer::stepping (const o2::itsmft::Hit& hit, float **& respMatrix, float **& avgHitLocalX, float **& avgHitLocalZ, int & rowStart, int & colStart, int & rowSpan, int & colSpan)
168185{
186+ LOG (debug) << " \n\n Performing stepping" ;
169187 const int chipID = hit.GetDetectorID ();
170188 const auto & matrix = mGeometry ->getMatrixL2G (chipID);
171189 const int subdetectorID = mGeometry ->getIOTOFLayer (chipID);
@@ -217,49 +235,53 @@ void Digitizer::stepping(const o2::itsmft::Hit& hit, float**& respMatrix, int& r
217235 colSpan = colEnd - colStart + 1 ;
218236
219237 respMatrix = new float *[rowSpan];
238+ avgHitLocalX = new float *[rowSpan];
239+ avgHitLocalZ = new float *[rowSpan];
220240 for (int i = 0 ; i < rowSpan; ++i) {
221241 respMatrix[i] = new float [colSpan]();
242+ avgHitLocalX[i] = new float [colSpan]();
243+ avgHitLocalZ[i] = new float [colSpan]();
222244 }
223245
224- if (!respMatrix || rowSpan <= 0 || colSpan <= 0 ) {
246+ if (!respMatrix || !avgHitLocalX || !avgHitLocalZ
247+ || rowSpan <= 0 || colSpan <= 0 ) {
225248 return ;
226249 }
227250 if (nSkip) {
228251 nSteps -= nSkip;
229252 }
230253
231254 int rowPrev = -1 , colPrev = -1 , row = 0 , col = 0 ;
232- auto & currentPosLocal = xyzPositionStart;
233- float xPixelCenter, zPixelCenter ;
255+ auto pixelCurrentPosLocal = xyzPositionStart;
256+ auto pixelStartPosLocal = xyzPositionStart ;
234257 for (int iStep = nSteps; iStep--;) {
235258
236- // Check whether the mid-position of the step is within the active area of the chip
237- if (!sSegmentation ->localToDetector (currentPosLocal .X (), currentPosLocal .Z (), row, col, subdetectorID)) {
238- LOG (debug) << " Step is in passive area: (" << currentPosLocal .X () << " , " << currentPosLocal .Z () << " ) is outside the active area of chip " << subdetectorID;
239- currentPosLocal += stepVector;
259+ // Step does not contribute if it is in the passive area
260+ if (!sSegmentation ->localToDetector (pixelCurrentPosLocal .X (), pixelCurrentPosLocal .Z (), row, col, subdetectorID)) {
261+ LOG (debug) << " Step is in passive area: (" << pixelCurrentPosLocal .X () << " , " << pixelCurrentPosLocal .Z () << " ) is outside the active area of chip " << subdetectorID;
262+ pixelCurrentPosLocal += stepVector;
240263 continue ;
241264 }
242265
243- // Update the pixel center coordinates if the row or column has changed
266+ // The step has reached another pixel, compute mean hit segment positions
267+ // for pixel efficiency evaluation and reset the start position for the next pixel
244268 if (row != rowPrev || col != colPrev) {
245- if (!sSegmentation ->detectorToLocal (row, col, xPixelCenter, zPixelCenter, subdetectorID)) {
246- LOG (debug) << " Failed to get pixel center for row " << row << " , col " << col << " , chip " << chipID;
247- currentPosLocal += stepVector;
248- continue ;
269+
270+ // Finalize the previous pixel
271+ if (rowPrev != -1 && colPrev != -1 ) {
272+ const int irow = rowPrev - rowStart;
273+ const int icol = colPrev - colStart;
274+ avgHitLocalX[irow][icol] = 0 .5f * (pixelStartPosLocal.X () + pixelCurrentPosLocal.X () - stepVector.X ());
275+ avgHitLocalZ[irow][icol] = 0 .5f * (pixelStartPosLocal.Z () + pixelCurrentPosLocal.Z () - stepVector.Z ());
249276 }
277+
278+ // Start the new pixel
250279 rowPrev = row;
251280 colPrev = col;
281+ pixelStartPosLocal = pixelCurrentPosLocal;
252282 }
253283
254- // Apply efficiency cut based on the step position relative to the pixel center
255- if (!isEfficient (currentPosLocal.X () - xPixelCenter, currentPosLocal.Z () - zPixelCenter)) {
256- LOG (debug) << " Step rejected by efficiency cut" ;
257- currentPosLocal += stepVector;
258- continue ;
259- }
260-
261- LOG (debug) << " Step accepted: (" << currentPosLocal.X () << " , " << currentPosLocal.Z () << " ) in chip " << subdetectorID;
262- currentPosLocal += stepVector; // Move to the next step position
284+ pixelCurrentPosLocal += stepVector; // Move to the next step position
263285
264286 for (int irow = digitizerParams.responseMatrixSize ; irow--;) {
265287 int rowDest = row + irow - (digitizerParams.responseMatrixSize / 2 ) - rowStart; // destination row in the respMatrix
@@ -275,6 +297,14 @@ void Digitizer::stepping(const o2::itsmft::Hit& hit, float**& respMatrix, int& r
275297 }
276298 }
277299 }
300+
301+ // Finalize the last pixel
302+ if (rowPrev != -1 && colPrev != -1 ) {
303+ const int irow = rowPrev - rowStart;
304+ const int icol = colPrev - colStart;
305+ avgHitLocalX[irow][icol] = 0 .5f * (pixelStartPosLocal.X () + pixelCurrentPosLocal.X () - stepVector.X ());
306+ avgHitLocalZ[irow][icol] = 0 .5f * (pixelStartPosLocal.Z () + pixelCurrentPosLocal.Z () - stepVector.Z ());
307+ }
278308}
279309
280310// _______________________________________________________________________
0 commit comments