Skip to content

Commit 44cd1ea

Browse files
adding stepping in digitization
1 parent 16b6488 commit 44cd1ea

1 file changed

Lines changed: 118 additions & 13 deletions

File tree

Detectors/Upgrades/ALICE3/IOTOF/simulation/src/Digitizer.cxx

Lines changed: 118 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
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

3233
o2::iotof::Segmentation* Digitizer::sSegmentation = nullptr;
33-
3434
//_______________________________________________________________________
3535
void 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

Comments
 (0)