Skip to content

Commit c58b43a

Browse files
added segmentation to the digitization
1 parent 44cd1ea commit c58b43a

4 files changed

Lines changed: 60 additions & 56 deletions

File tree

Detectors/Upgrades/ALICE3/IOTOF/base/include/IOTOFBase/GeometryTGeo.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,29 +39,29 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache
3939
static const char* getIOTOFVolPattern() { return sIOTOFVolumeName.c_str(); }
4040

4141
// Inner TOF
42-
const int getITOFNumberOfChips() { return mNumberOfChipsIOTOF[0]; }
42+
const int getITOFNumberOfChips() const { return mNumberOfChipsIOTOF[0]; }
4343
static const char* getITOFLayerPattern() { return sITOFLayerName.c_str(); }
4444
static const char* getITOFStavePattern() { return sITOFStaveName.c_str(); }
4545
static const char* getITOFModulePattern() { return sITOFModuleName.c_str(); }
4646
static const char* getITOFChipPattern() { return sITOFChipName.c_str(); }
4747
static const char* getITOFSensorPattern() { return sITOFSensorName.c_str(); }
4848

4949
// Outer TOF
50-
const int getOTOFNumberOfChips() { return mNumberOfChipsIOTOF[1]; }
50+
const int getOTOFNumberOfChips() const { return mNumberOfChipsIOTOF[1]; }
5151
static const char* getOTOFLayerPattern() { return sOTOFLayerName.c_str(); }
5252
static const char* getOTOFStavePattern() { return sOTOFStaveName.c_str(); }
5353
static const char* getOTOFModulePattern() { return sOTOFModuleName.c_str(); }
5454
static const char* getOTOFChipPattern() { return sOTOFChipName.c_str(); }
5555
static const char* getOTOFSensorPattern() { return sOTOFSensorName.c_str(); }
5656

5757
// Forward TOF
58-
const int getFTOFNumberOfChips() { return mNumberOfChipsFTOF; }
58+
const int getFTOFNumberOfChips() const { return mNumberOfChipsFTOF; }
5959
static const char* getFTOFLayerPattern() { return sFTOFLayerName.c_str(); }
6060
static const char* getFTOFChipPattern() { return sFTOFChipName.c_str(); }
6161
static const char* getFTOFSensorPattern() { return sFTOFSensorName.c_str(); }
6262

6363
// Backward TOF
64-
const int getBTOFNumberOfChips() { return mNumberOfChipsBTOF; }
64+
const int getBTOFNumberOfChips() const { return mNumberOfChipsBTOF; }
6565
static const char* getBTOFLayerPattern() { return sBTOFLayerName.c_str(); }
6666
static const char* getBTOFChipPattern() { return sBTOFChipName.c_str(); }
6767
static const char* getBTOFSensorPattern() { return sBTOFSensorName.c_str(); }

Detectors/Upgrades/ALICE3/IOTOF/simulation/include/IOTOFSimulation/DPLDigitizerParam.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ struct DPLDigitizerParam : public o2::conf::ConfigurableParamHelper<DPLDigitizer
3131
int minChargeToAccount = 7; ///< minimum charge contribution to account
3232
int nSimSteps = 475; ///< number of steps in response simulation
3333
float energyToNElectrons = 1. / 3.6e-9; // conversion of eloss to Nelectrons
34+
int responseMatrixSize = 1; ///< size of the response matrix (odd number)
3435

3536
std::string noiseFilePath{}; ///< optional noise masks file path. FIXME to be removed once switch to CCDBFetcher
3637

Detectors/Upgrades/ALICE3/IOTOF/simulation/include/IOTOFSimulation/Digitizer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ class Digitizer : public TObject
9393
void registerDigits(Chip& chip, uint32_t roFrame, double time, int nROF,
9494
uint16_t row, uint16_t col, int nElectrons, o2::MCCompLabel& label);
9595

96+
void stepping(const o2::itsmft::Hit& hit, float**& respMatrix, int& rowStart, int& colStart, int& rowSpan, int& colSpan);
97+
9698
/// Apply time smearing to simulate detector resolution
9799
double smearTime(double time) const;
98100

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

Lines changed: 53 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)