1717// /
1818
1919#include " IOTOFSimulation/Digitizer.h"
20+ #include " IOTOFSimulation/DPLDigitizerParam.h"
2021#include " DetectorsRaw/HBFUtils.h"
2122
2223#include < TRandom.h>
@@ -30,7 +31,6 @@ namespace o2::iotof
3031{
3132
3233o2::iotof::Segmentation* Digitizer::sSegmentation = nullptr ;
33-
3434// _______________________________________________________________________
3535void Digitizer::init ()
3636{
@@ -117,6 +117,7 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, int evID, int srcID)
117117 return ;
118118 }
119119
120+
120121 // Get hit time and apply smearing
121122 // Hit time is in seconds, convert to ns and add event time
122123 double hitTime = hit.GetTime () * sec2ns; // convert to ns
@@ -125,28 +126,132 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, int evID, int srcID)
125126 double smearedTime = smearTime (absoluteTime); // apply detector resolution
126127
127128 if (chipID < 0 || chipID >= mGeometry ->getSize () || mGeometry ->getSize () < 1 ) {
129+
130+ // For now, use simple row/col mapping from detector ID
131+ // TODO: Implement proper segmentation when geometry is finalized
132+ uint16_t chipIndex = static_cast <uint16_t >(chipID);
133+
134+ if (chipID > mGeometry ->getSize () || mGeometry ->getSize () < 1 ) {
128135 LOG (debug) << " Invalid detector ID: " << chipID << " , geometry size: " << mGeometry ->getSize ();
129136 return ; // invalid detector ID
130137 }
131- const auto & matrix = mGeometry ->getMatrixL2G (hit.GetDetectorID ());
132138
139+ // stepping is called here
140+
141+ // Create the digit with time information
142+ 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+ for (int irow = rowSpan; irow--;) {
146+ uint16_t rowIS = irow + rowStart;
147+ for (int icol = colSpan; icol--;) {
148+ uint16_t colIS = icol + colStart;
149+ float nEleResp = respMatrix[irow][icol];
150+ if (!nEleResp) {
151+ continue ;
152+ }
153+ int nElectronsSampled = gRandom ->Poisson (electronsPerStep * nEleResp);
154+ // 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+ }
159+
160+ for (int irow = 0 ; irow < rowSpan; ++irow) {
161+ delete[] respMatrix[irow];
162+ }
163+ delete[] respMatrix;
164+
165+
166+
167+
168+ }
169+
170+ void Digitizer::stepping (const o2::itsmft::Hit& hit, float **& respMatrix)
171+ {
172+ const auto & matrix = mGeometry ->getMatrixL2G (hit.GetDetectorID ());
173+
133174 math_utils::Vector3D<float > xyzPositionStart (matrix ^ (hit.GetPosStart ())); // start position in sensor frame
134- // math_utils::Vector3D<float> xyzPositionEnd(matrix ^ (hit.GetPos())); // end 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 ();
178+ 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 ;
183+ 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?
185+ LOG (debug) << " Hit position out of bounds for detector ID " << chipID;
186+ return ; // hit is outside the active area
187+ }
188+ xyzPositionStart += stepVector;
189+ }
190+
191+ 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?
193+ LOG (debug) << " Hit position out of bounds for detector ID " << chipID;
194+ return ; // hit is outside the active area
195+ }
196+ xyzPositionEnd += stepVector;
197+ }
198+
199+ if (rowStart > rowEnd) {
200+ std::swap (rowStart, rowEnd);
201+ }
202+ if (colStart > colEnd) {
203+ std::swap (colStart, colEnd);
204+ }
205+
206+ // Expand the range to take into account the effects of charge sharing
207+ rowStart -= digitizerParams.responseMatrixSize / 2 ;
208+ rowEnd += digitizerParams.responseMatrixSize / 2 ;
209+ rowStart = std::max (rowStart, 0 );
210+ colStart = std::max (colStart, 0 );
135211
136- int row = 0 ; // Will be determined from start hit position
137- int col = 0 ; // Will be determined from start hit position
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 ;
138216
139- if (! sSegmentation -> localToDetector (xyzPositionStart. X (), xyzPositionStart. Z (), row, col, mGeometry -> getIOTOFLayer (chipID))) {
140- LOG (debug) << " Hit position out of bounds for detector ID " << chipID;
141- return ; // hit is outside the active area
217+ respMatrix = new float *[rowSpan];
218+ for ( int i = 0 ; i < rowSpan; ++i) {
219+ respMatrix[i] = new float [colSpan]();
142220 }
143221
144- // Create the digit with time information
145- o2::MCCompLabel label (hit.GetTrackID (), evID, srcID, false );
146- const int roFrameAbs = 0 ; // For now, we can set this to 0 or calculate based on time if needed
147- 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
222+ int rowPrev = -1 , colPrev = -1 , row, col;
223+ if (!respMatrix || rowSpan <= 0 || colSpan <= 0 ) continue ;
224+ if (nSkip) {
225+ nSteps -= nSkip;
226+ }
227+
228+ auto & currentPosLocal = xyzPositionStart;
229+ for (int iStep = nSteps; iStep--;) {
230+ segmentation->localToDetector (currentPosLocal.X (), currentPosLocal.Z (), row, col, subdetectorID);
231+ if (row != rowPrev || col != colPrev) {
232+ rowPrev = row;
233+ colPrev = col;
234+ }
235+
236+ currentPosLocal += stepVector; // Move to the next step position
237+
238+ for (int irow = digitizerParams.responseMatrixSize ; irow--;) {
239+ int rowDest = row + irow - (digitizerParams.responseMatrixSize / 2 ) - rowStart; // destination row in the respMatrix
240+ if (rowDest < 0 || rowDest >= rowSpan) {
241+ continue ;
242+ }
243+ 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) {
246+ continue ;
247+ }
248+ respMatrix[rowDest][colDest] += 1 .;
249+ }
250+ }
251+ }
148252
149- registerDigits (chip, roFrameAbs, smearedTime, nROF, static_cast <uint16_t >(row), static_cast <uint16_t >(col), charge, label);
253+
254+
150255}
151256
152257// _______________________________________________________________________
0 commit comments