Skip to content

Commit 5dbfcdf

Browse files
authored
Merge 89f314b into sapling-pr-archive-ktf
2 parents 9131a47 + 89f314b commit 5dbfcdf

14 files changed

Lines changed: 151 additions & 74 deletions

File tree

‎Detectors/Passive/src/FrameStructure.cxx‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1789,7 +1789,21 @@ void FrameStructure::ConstructGeometry()
17891789
ppgon[9] = ppgon[6];
17901790

17911791
vmc->Gsvolu("BBMO", "PGON", kAir, ppgon, 10);
1792-
vmc->Gsdvn("BBCE", "BBMO", 18, 2);
1792+
1793+
// The 18 sectors, placed one by one rather than made with a phi division.
1794+
// Geant4 has no faithful representation of a phi division of a polyhedra: it
1795+
// divides by the number of sides and ignores the requested width and offset,
1796+
// so the sector contents end up half a sector away from where TGeo puts them.
1797+
const int kNSectors = 18;
1798+
const float kSectorDphi = 360. / kNSectors;
1799+
TGeoPgon* shBBCE = new TGeoPgon(-kSectorDphi / 2., kSectorDphi, 1, 2);
1800+
shBBCE->DefineSection(0, -kBBMdz / 2., kBBMRin, kBBMRou);
1801+
shBBCE->DefineSection(1, kBBMdz / 2., kBBMRin, kBBMRou);
1802+
TGeoVolume* voBBCE = new TGeoVolume("BBCE", shBBCE, kMedAir);
1803+
TGeoVolume* voBBMO = gGeoManager->GetVolume("BBMO");
1804+
for (i = 0; i < kNSectors; i++) {
1805+
voBBMO->AddNode(voBBCE, i + 1, new TGeoRotation("", (i + 0.5) * kSectorDphi, 0., 0.));
1806+
}
17931807

17941808
// CBL ////////////////////////////////////////////////////////
17951809
//

‎Detectors/Upgrades/ALICE3/IOTOF/macros/CheckDigitsIOTOF.C‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ void addTLines(float pitch)
7575
gPad->Update();
7676
}
7777

78-
void CheckDigitsIOTOF(std::string digifile = "tf3digits.root", std::string hitfile = "o2sim_HitsTF3.root", std::string inputGeom = "o2sim_geometry.root")
78+
void CheckDigitsIOTOF(std::string digifile = "tf3digits.root", std::string hitfile = "o2sim_HitsTF3.root", std::string inputGeom = "o2sim_geometry.root",
79+
std::string cfgStr = "IOTOFBase.segmentedInnerTOF=true;IOTOFBase.segmentedOuterTOF=true;IOTOFBase.enableForwardTOF=false;IOTOFBase.enableBackwardTOF=false;")
7980
{
8081
gStyle->SetPalette(55);
8182

@@ -85,7 +86,7 @@ void CheckDigitsIOTOF(std::string digifile = "tf3digits.root", std::string hitfi
8586
using o2::iotof::Digit;
8687
using o2::itsmft::Hit;
8788

88-
o2::conf::ConfigurableParam::updateFromString("IOTOFBase.segmentedInnerTOF=true;IOTOFBase.segmentedOuterTOF=true;IOTOFBase.enableForwardTOF=false;IOTOFBase.enableBackwardTOF=false");
89+
o2::conf::ConfigurableParam::updateFromString(cfgStr);
8990

9091
auto seg = o2::iotof::Segmentation::Instance();
9192

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ struct DPLDigitizerParam : public o2::conf::ConfigurableParamHelper<DPLDigitizer
3434
///< The efficiency map is currently available at /alice/cern.ch/user/g/glucia/ALICE3/IOTOF/pixelEfficiency/PixelEfficiencyMap_TH2.root. FIXME to be removed once switch to CCDBFetcher
3535
int chargeThreshold = 100; ///< charge threshold in Nelectrons
3636
int minChargeToAccount = 7; ///< minimum charge contribution to account
37-
int nSimSteps = 1; ///< number of steps in response simulation
37+
int nSimSteps = 10; ///< number of steps in response simulation
3838
float energyToNElectrons = 1. / 3.6e-9; // conversion of eloss to Nelectrons
3939
int responseMatrixSize = 1; ///< size of the response matrix (odd number)
4040

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class Digitizer : public TObject
8383
void registerDigits(Chip& chip, uint32_t roFrame, double time, int nROF,
8484
uint16_t row, uint16_t col, int nElectrons, o2::MCCompLabel& label);
8585

86-
void stepping(const o2::itsmft::Hit& hit, float**& respMatrix, int& rowStart, int& colStart, int& rowSpan, int& colSpan);
86+
void stepping(const o2::itsmft::Hit& hit, float**& respMatrix, float**& avgHitLocalX, float**& avgHitLocalZ, int& rowStart, int& colStart, int& rowSpan, int& colSpan);
8787

8888
/// Apply time smearing to simulate detector resolution
8989
double smearTime(double time) const;

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

Lines changed: 63 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -104,32 +104,18 @@ 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";
110116
return;
111117
}
112118

113-
// middle position of the hit in the sensor frame
114-
const auto& matrix = mGeometry->getMatrixL2G(chipID);
115-
auto xyzPositionStart = matrix ^ hit.GetPosStart();
116-
auto xyzPositionEnd = matrix ^ hit.GetPos();
117-
const auto xMid = 0.5f * (xyzPositionStart.X() + xyzPositionEnd.X());
118-
const auto zMid = 0.5f * (xyzPositionStart.Z() + xyzPositionEnd.Z());
119-
// move this to the local pixel coordinates for the efficiency map
120-
int row, col;
121-
float xPixelCenter, zPixelCenter;
122-
if (!sSegmentation->localToDetector(xMid, zMid, row, col, mGeometry->getIOTOFLayer(chipID))) {
123-
LOG(debug) << "Hit rejected because position (" << xMid << ", " << zMid << ") is outside the active area of chip " << chipID;
124-
return; // hit is outside the active area
125-
}
126-
sSegmentation->detectorToLocalUnchecked(row, col, xPixelCenter, zPixelCenter, mGeometry->getIOTOFLayer(chipID));
127-
128-
if (!isEfficient(xMid - xPixelCenter, zMid - zPixelCenter)) {
129-
LOG(debug) << "Hit rejected by efficiency cut";
130-
return;
131-
}
132-
133119
// Convert energy loss to charge (number of electrons)
134120
float energyLoss = hit.GetEnergyLoss(); // in GeV
135121
int charge = energyToCharge(energyLoss);
@@ -149,20 +135,18 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, int evID, int srcID)
149135
double hitTimeWrtBC = hitTime + eventTimeInBC; // hit time wrt bc
150136
double smearedTime = smearTime(hitTimeWrtBC);
151137

152-
if (chipID < 0 || chipID >= mGeometry->getSize() || mGeometry->getSize() < 1) {
153-
LOG(debug) << "Invalid detector ID: " << chipID << ", geometry size: " << mGeometry->getSize();
154-
return; // invalid detector ID
155-
}
156-
157138
// Create the digit with time information
158139
o2::MCCompLabel label(hit.GetTrackID(), evID, srcID, false);
159140
const int roFrameAbs = 0; // For now, we can set this to 0 or calculate based on time if needed
160141
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
161142

162143
float** respMatrix = nullptr;
144+
float** avgHitLocalX = nullptr;
145+
float** avgHitLocalZ = nullptr;
163146
int rowStart = 0, colStart = 0, rowSpan = 0, colSpan = 0;
164-
stepping(hit, respMatrix, rowStart, colStart, rowSpan, colSpan);
147+
stepping(hit, respMatrix, avgHitLocalX, avgHitLocalZ, rowStart, colStart, rowSpan, colSpan);
165148

149+
float xPixelCenter = 0.0f, zPixelCenter = 0.0f;
166150
for (int irow = rowSpan; irow--;) {
167151
uint16_t rowIS = irow + rowStart;
168152
for (int icol = colSpan; icol--;) {
@@ -171,6 +155,14 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, int evID, int srcID)
171155
if (!nEleResp) {
172156
continue;
173157
}
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;
163+
continue;
164+
}
165+
174166
const int nElectronsSampled = gRandom->Poisson(electronsPerStep * nEleResp);
175167
// Noise can be added here if needed
176168

@@ -181,12 +173,17 @@ void Digitizer::processHit(const o2::itsmft::Hit& hit, int evID, int srcID)
181173

182174
for (int irow = 0; irow < rowSpan; ++irow) {
183175
delete[] respMatrix[irow];
176+
delete[] avgHitLocalX[irow];
177+
delete[] avgHitLocalZ[irow];
184178
}
185179
delete[] respMatrix;
180+
delete[] avgHitLocalX;
181+
delete[] avgHitLocalZ;
186182
}
187183

188-
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)
189185
{
186+
LOG(debug) << "\n\nPerforming stepping";
190187
const int chipID = hit.GetDetectorID();
191188
const auto& matrix = mGeometry->getMatrixL2G(chipID);
192189
const int subdetectorID = mGeometry->getIOTOFLayer(chipID);
@@ -238,27 +235,52 @@ void Digitizer::stepping(const o2::itsmft::Hit& hit, float**& respMatrix, int& r
238235
colSpan = colEnd - colStart + 1;
239236

240237
respMatrix = new float*[rowSpan];
238+
avgHitLocalX = new float*[rowSpan];
239+
avgHitLocalZ = new float*[rowSpan];
241240
for (int i = 0; i < rowSpan; ++i) {
242241
respMatrix[i] = new float[colSpan]();
242+
avgHitLocalX[i] = new float[colSpan]();
243+
avgHitLocalZ[i] = new float[colSpan]();
243244
}
244245

245-
int rowPrev = -1, colPrev = -1, row = 0, col = 0;
246-
if (!respMatrix || rowSpan <= 0 || colSpan <= 0) {
246+
if (!respMatrix || !avgHitLocalX || !avgHitLocalZ || rowSpan <= 0 || colSpan <= 0) {
247247
return;
248248
}
249249
if (nSkip) {
250250
nSteps -= nSkip;
251251
}
252252

253-
auto& currentPosLocal = xyzPositionStart;
253+
int rowPrev = -1, colPrev = -1, row = 0, col = 0;
254+
auto pixelCurrentPosLocal = xyzPositionStart;
255+
auto pixelStartPosLocal = xyzPositionStart;
254256
for (int iStep = nSteps; iStep--;) {
255-
sSegmentation->localToDetector(currentPosLocal.X(), currentPosLocal.Z(), row, col, subdetectorID);
257+
258+
// Step does not contribute if it is in the passive area
259+
if (!sSegmentation->localToDetector(pixelCurrentPosLocal.X(), pixelCurrentPosLocal.Z(), row, col, subdetectorID)) {
260+
LOG(debug) << "Step is in passive area: (" << pixelCurrentPosLocal.X() << ", " << pixelCurrentPosLocal.Z() << ") is outside the active area of chip " << subdetectorID;
261+
pixelCurrentPosLocal += stepVector;
262+
continue;
263+
}
264+
265+
// The step has reached another pixel, compute mean hit segment positions
266+
// for pixel efficiency evaluation and reset the start position for the next pixel
256267
if (row != rowPrev || col != colPrev) {
268+
269+
// Finalize the previous pixel
270+
if (rowPrev != -1 && colPrev != -1) {
271+
const int irow = rowPrev - rowStart;
272+
const int icol = colPrev - colStart;
273+
avgHitLocalX[irow][icol] = 0.5f * (pixelStartPosLocal.X() + pixelCurrentPosLocal.X() - stepVector.X());
274+
avgHitLocalZ[irow][icol] = 0.5f * (pixelStartPosLocal.Z() + pixelCurrentPosLocal.Z() - stepVector.Z());
275+
}
276+
277+
// Start the new pixel
257278
rowPrev = row;
258279
colPrev = col;
280+
pixelStartPosLocal = pixelCurrentPosLocal;
259281
}
260282

261-
currentPosLocal += stepVector; // Move to the next step position
283+
pixelCurrentPosLocal += stepVector; // Move to the next step position
262284

263285
for (int irow = digitizerParams.responseMatrixSize; irow--;) {
264286
int rowDest = row + irow - (digitizerParams.responseMatrixSize / 2) - rowStart; // destination row in the respMatrix
@@ -274,6 +296,14 @@ void Digitizer::stepping(const o2::itsmft::Hit& hit, float**& respMatrix, int& r
274296
}
275297
}
276298
}
299+
300+
// Finalize the last pixel
301+
if (rowPrev != -1 && colPrev != -1) {
302+
const int irow = rowPrev - rowStart;
303+
const int icol = colPrev - colStart;
304+
avgHitLocalX[irow][icol] = 0.5f * (pixelStartPosLocal.X() + pixelCurrentPosLocal.X() - stepVector.X());
305+
avgHitLocalZ[irow][icol] = 0.5f * (pixelStartPosLocal.Z() + pixelCurrentPosLocal.Z() - stepVector.Z());
306+
}
277307
}
278308

279309
//_______________________________________________________________________
@@ -407,7 +437,7 @@ void Digitizer::registerDigits(Chip& chip, uint32_t roFrame, double time, int nR
407437
int tdc = int((time - nbc * o2::constants::lhc::LHCBunchSpacingNS) / digitizerParams.tdcBin);
408438
nbc += mEventTime.toLong();
409439

410-
LOG(debug) << nbc << "\t" << tdc;
440+
LOG(debug) << "nbc: " << nbc << "\ttdc: " << tdc;
411441
double absoluteTime = tdc * digitizerParams.tdcBin * 1.e-9 + nbc * o2::constants::lhc::LHCBunchSpacingNS;
412442

413443
auto key = o2::iotof::Digit::getOrderingKey(nbc, row, col);

‎Framework/AnalysisSupport/src/AODJAlienReaderHelpers.cxx‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "Framework/EndOfStreamContext.h"
3333
#include "Framework/DeviceSpec.h"
3434
#include "Framework/RawDeviceService.h"
35+
#include "Framework/RuntimeError.h"
3536
#include "Framework/DataSpecUtils.h"
3637
#include "Framework/MessageContext.h"
3738
#include "Framework/Signpost.h"
@@ -131,7 +132,9 @@ static std::string describeException(std::exception const& exception)
131132
try {
132133
std::rethrow_if_nested(exception);
133134
} catch (std::exception const& nested) {
134-
description += ": " + describeException(nested);
135+
description += fmt::format(": {}", describeException(nested));
136+
} catch (RuntimeErrorRef const& ref) {
137+
description += fmt::format(": {}", error_from_ref(ref).what);
135138
} catch (...) {
136139
description += ": unknown exception";
137140
}
@@ -275,6 +278,7 @@ AlgorithmSpec AODJAlienReaderHelpers::rootFileReaderCallback(ConfigContext const
275278
auto skippedTimeframes = ++totalInvalidReadSkipped;
276279
LOGP(error, "Invalid AOD read for table {}: fileCounter {}, timeFrame {}. Skipping timeframe (skipped timeframes: {}). Reason: {}",
277280
concrete.origin.as<std::string>(), fcnt, ntf, skippedTimeframes, describeException(e));
281+
clean_all_runtime_errors();
278282
didir->markTimeFrameSkipped(header::DataHeader(concrete.description, concrete.origin, concrete.subSpec), ntf);
279283
arrowContext.clear();
280284
messageContext.discard();

‎Framework/AnalysisSupport/src/DataInputDirector.cxx‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,9 @@ bool DataInputDescriptor::readTree(DataAllocator& outputs, header::DataHeader dh
574574
}
575575

576576
auto schemaOpt = format->Inspect(fullpath);
577+
if (!schemaOpt.ok()) {
578+
throw InvalidAODReadError(fmt::format("Unable to inspect tree {}: {}", treename, schemaOpt.status().ToString()));
579+
}
577580
auto physicalSchema = schemaOpt;
578581
std::vector<std::shared_ptr<arrow::Field>> fields;
579582
for (auto& original : (*schemaOpt)->fields()) {

0 commit comments

Comments
 (0)