Skip to content

Commit 98a5696

Browse files
sawenzelclaude
andcommitted
Let the TPC looper generator accept a timeframe without collisions
This fixes a problem in GenTPCLoopers::setFlatGas when the collision context of a timeframe is empty. - A timeframe holds no collision whenever the interaction rate is low enough, and the generator called exit(1) on it. - The extent of the timeframe now comes from HBFUtils in that case, which is where it is defined, instead of from the last collision. - With a single collision in the timeframe the mean interaction spacing was divided by zero; it is now taken from the interaction rate stored in the collision context. https://its.cern.ch/jira/browse/O2-7132 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 19866a3 commit 98a5696

1 file changed

Lines changed: 24 additions & 12 deletions

File tree

Generators/src/TPCLoopers.cxx

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -398,23 +398,35 @@ void GenTPCLoopers::setFlatGas(Bool_t flat, Int_t number, Int_t nloopers_orbit)
398398
mContextFile = std::filesystem::exists("collisioncontext.root") ? TFile::Open("collisioncontext.root") : nullptr;
399399
mCollisionContext = mContextFile ? (o2::steer::DigitizationContext*)mContextFile->Get("DigitizationContext") : nullptr;
400400
mInteractionTimeRecords = mCollisionContext ? mCollisionContext->getEventRecords() : std::vector<o2::InteractionTimeRecord>{};
401+
const auto& hbfUtils = o2::raw::HBFUtils::Instance();
401402
if (mInteractionTimeRecords.empty()) {
402-
LOG(error) << "Error: No interaction time records found in the collision context!";
403-
exit(1);
403+
// A timeframe can legitimately contain no collision at all when the interaction rate is
404+
// low. No event is transported in that case, so nothing below is ever used; take the
405+
// extent of the timeframe from HBFUtils rather than from the (absent) collisions.
406+
LOG(warn) << "No interaction time records in the collision context; this timeframe holds no collision";
407+
o2::InteractionRecord tfEndIR(0, hbfUtils.orbitFirstSampled + hbfUtils.nHBFPerTF);
408+
mTimeEnd = tfEndIR.bc2ns();
404409
} else {
405410
LOG(info) << "Interaction Time records has " << mInteractionTimeRecords.size() << " entries.";
406411
mCollisionContext->printCollisionSummary();
412+
for (int c = 0; c < (int)mInteractionTimeRecords.size() - 1; c++) {
413+
mIntTimeRecMean += mInteractionTimeRecords[c + 1].bc2ns() - mInteractionTimeRecords[c].bc2ns();
414+
}
415+
if (mInteractionTimeRecords.size() > 1) {
416+
mIntTimeRecMean /= (mInteractionTimeRecords.size() - 1); // Average interaction time record used as reference
417+
} else {
418+
// a single collision gives no spacing to average; use the one implied by the rate
419+
auto rate = mCollisionContext->getDigitizerInteractionRate();
420+
mIntTimeRecMean = rate > 0. ? 1.e9 / rate : (double)o2::constants::lhc::LHCOrbitNS;
421+
LOG(info) << "Only one collision in this timeframe; taking " << mIntTimeRecMean
422+
<< " ns as the mean interaction spacing from the interaction rate";
423+
}
424+
// Get the start time of the second orbit after the last interaction record
425+
const auto& lastIR = mInteractionTimeRecords.back();
426+
o2::InteractionRecord finalOrbitIR(0, lastIR.orbit + 2); // Final orbit, BC = 0
427+
mTimeEnd = finalOrbitIR.bc2ns();
428+
LOG(debug) << "Final orbit start time: " << mTimeEnd << " ns while last interaction record time is " << mInteractionTimeRecords.back().bc2ns() << " ns";
407429
}
408-
for (int c = 0; c < mInteractionTimeRecords.size() - 1; c++) {
409-
mIntTimeRecMean += mInteractionTimeRecords[c + 1].bc2ns() - mInteractionTimeRecords[c].bc2ns();
410-
}
411-
mIntTimeRecMean /= (mInteractionTimeRecords.size() - 1); // Average interaction time record used as reference
412-
const auto& hbfUtils = o2::raw::HBFUtils::Instance();
413-
// Get the start time of the second orbit after the last interaction record
414-
const auto& lastIR = mInteractionTimeRecords.back();
415-
o2::InteractionRecord finalOrbitIR(0, lastIR.orbit + 2); // Final orbit, BC = 0
416-
mTimeEnd = finalOrbitIR.bc2ns();
417-
LOG(debug) << "Final orbit start time: " << mTimeEnd << " ns while last interaction record time is " << mInteractionTimeRecords.back().bc2ns() << " ns";
418430
}
419431
} else {
420432
mFlatGasNumber = -1;

0 commit comments

Comments
 (0)