Skip to content

Commit dabbfd9

Browse files
sawenzelclaude
andcommitted
Check for the end of the tree where the reader specs asserted it
This replaces a disabled assert with a real check in 36 ROOT-tree reader specs, so that a timeframe whose tree has no entry ends the stream instead of reading past the end. - Every one of them carried the same two lines: assert(ent < mTree->GetEntries()) with the comment "this should not happen", followed by mTree->GetEntry(ent). - ENABLE_CASSERT defaults to OFF, so the assert is compiled out of every production build and the reader then publishes branch addresses that GetEntry never filled. - A timeframe holds no collision whenever the interaction rate is low enough, which is when the trees come out empty. - The readers now end the stream, which the consumers downstream already handle. - Detectors/Upgrades/ALICE3/IOTOF is left alone: it has no ControlService. https://its.cern.ch/jira/browse/O2-7132 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 847ce5b commit dabbfd9

36 files changed

Lines changed: 360 additions & 36 deletions

Detectors/CPV/workflow/src/ClusterReaderSpec.cxx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,16 @@ void ClusterReader::init(InitContext& ic)
4141
void ClusterReader::run(ProcessingContext& pc)
4242
{
4343
auto ent = mTree->GetReadEntry() + 1;
44-
assert(ent < mTree->GetEntries()); // this should not happen
44+
if (ent >= mTree->GetEntries()) {
45+
// A timeframe holds no collision at all whenever the interaction rate is low enough, and
46+
// the tree then has no entry to read. End the stream instead of reading past the end and
47+
// publishing branch addresses that GetEntry has not filled. This was an assert, which is
48+
// compiled out of every production build since ENABLE_CASSERT defaults to OFF.
49+
LOG(info) << "no entry to read, ending the stream";
50+
pc.services().get<ControlService>().endOfStream();
51+
pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
52+
return;
53+
}
4554
mTree->GetEntry(ent);
4655
LOG(info) << "Pushing " << mClusters.size() << " Clusters in " << mTRs.size() << " TriggerRecords at entry " << ent;
4756
pc.outputs().snapshot(Output{mOrigin, "CLUSTERS", 0}, mClusters);

Detectors/CPV/workflow/src/DigitReaderSpec.cxx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,16 @@ void DigitReader::init(InitContext& ic)
4141
void DigitReader::run(ProcessingContext& pc)
4242
{
4343
auto ent = mTree->GetReadEntry() + 1;
44-
assert(ent < mTree->GetEntries()); // this should not happen
44+
if (ent >= mTree->GetEntries()) {
45+
// A timeframe holds no collision at all whenever the interaction rate is low enough, and
46+
// the tree then has no entry to read. End the stream instead of reading past the end and
47+
// publishing branch addresses that GetEntry has not filled. This was an assert, which is
48+
// compiled out of every production build since ENABLE_CASSERT defaults to OFF.
49+
LOG(info) << "no entry to read, ending the stream";
50+
pc.services().get<ControlService>().endOfStream();
51+
pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
52+
return;
53+
}
4554
mTree->GetEntry(ent);
4655
LOG(info) << "Pushing " << mDigits.size() << " Digits in " << mTRs.size() << " TriggerRecords at entry " << ent;
4756
pc.outputs().snapshot(Output{mOrigin, "DIGITS", 0}, mDigits);

Detectors/CTP/workflowIO/src/DigitReaderSpec.cxx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,16 @@ void DigitReader::run(ProcessingContext& pc)
8686
auto ent = mTree->GetReadEntry();
8787
if (!mUseIRFrames) {
8888
ent++;
89-
assert(ent < mTree->GetEntries()); // this should not happen
89+
if (ent >= mTree->GetEntries()) {
90+
// A timeframe holds no collision at all whenever the interaction rate is low enough, and
91+
// the tree then has no entry to read. End the stream instead of reading past the end and
92+
// publishing branch addresses that GetEntry has not filled. This was an assert, which is
93+
// compiled out of every production build since ENABLE_CASSERT defaults to OFF.
94+
LOG(info) << "no entry to read, ending the stream";
95+
pc.services().get<ControlService>().endOfStream();
96+
pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
97+
return;
98+
}
9099
mTree->GetEntry(ent);
91100
LOG(info) << "DigitReader pushes " << mDigits.size() << " digits at entry " << ent;
92101
pc.outputs().snapshot(Output{"CTP", "DIGITS", 0}, mDigits);

Detectors/FIT/FDD/workflow/src/DigitReaderSpec.cxx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,16 @@ void DigitReader::run(ProcessingContext& pc)
7777
}
7878
}
7979
auto ent = mTree->GetReadEntry() + 1;
80-
assert(ent < mTree->GetEntries()); // this should not happen
80+
if (ent >= mTree->GetEntries()) {
81+
// A timeframe holds no collision at all whenever the interaction rate is low enough, and
82+
// the tree then has no entry to read. End the stream instead of reading past the end and
83+
// publishing branch addresses that GetEntry has not filled. This was an assert, which is
84+
// compiled out of every production build since ENABLE_CASSERT defaults to OFF.
85+
LOG(info) << "no entry to read, ending the stream";
86+
pc.services().get<ControlService>().endOfStream();
87+
pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
88+
return;
89+
}
8190
mTree->GetEntry(ent);
8291

8392
LOG(info) << "FDD DigitReader pushes " << digitsBC->size() << " digits";

Detectors/FIT/FDD/workflow/src/RecPointReaderSpec.cxx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,16 @@ void RecPointReader::init(InitContext& ic)
4545
void RecPointReader::run(ProcessingContext& pc)
4646
{
4747
auto ent = mTree->GetReadEntry() + 1;
48-
assert(ent < mTree->GetEntries()); // this should not happen
48+
if (ent >= mTree->GetEntries()) {
49+
// A timeframe holds no collision at all whenever the interaction rate is low enough, and
50+
// the tree then has no entry to read. End the stream instead of reading past the end and
51+
// publishing branch addresses that GetEntry has not filled. This was an assert, which is
52+
// compiled out of every production build since ENABLE_CASSERT defaults to OFF.
53+
LOG(info) << "no entry to read, ending the stream";
54+
pc.services().get<ControlService>().endOfStream();
55+
pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
56+
return;
57+
}
4958
mTree->GetEntry(ent);
5059

5160
LOG(info) << "FDD RecPointReader pushes " << mRecPoints->size() << " recpoints with " << mChannelData->size() << " channels at entry " << ent;

Detectors/FIT/FT0/workflow/src/DigitReaderSpec.cxx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,16 @@ void DigitReader::run(ProcessingContext& pc)
6161
mTree->SetBranchAddress("FT0DIGITSMCTR", &plabels);
6262
}
6363
auto ent = mTree->GetReadEntry() + 1;
64-
assert(ent < mTree->GetEntries()); // this should not happen
64+
if (ent >= mTree->GetEntries()) {
65+
// A timeframe holds no collision at all whenever the interaction rate is low enough, and
66+
// the tree then has no entry to read. End the stream instead of reading past the end and
67+
// publishing branch addresses that GetEntry has not filled. This was an assert, which is
68+
// compiled out of every production build since ENABLE_CASSERT defaults to OFF.
69+
LOG(info) << "no entry to read, ending the stream";
70+
pc.services().get<ControlService>().endOfStream();
71+
pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
72+
return;
73+
}
6574
mTree->GetEntry(ent);
6675
LOG(debug) << "FT0DigitReader pushed " << channels.size() << " channels in " << digits.size() << " digits";
6776
pc.outputs().snapshot(Output{"FT0", "DIGITSBC", 0}, digits);

Detectors/FIT/FT0/workflow/src/RecPointReaderSpec.cxx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,16 @@ void RecPointReader::init(InitContext& ic)
4545
void RecPointReader::run(ProcessingContext& pc)
4646
{
4747
auto ent = mTree->GetReadEntry() + 1;
48-
assert(ent < mTree->GetEntries()); // this should not happen
48+
if (ent >= mTree->GetEntries()) {
49+
// A timeframe holds no collision at all whenever the interaction rate is low enough, and
50+
// the tree then has no entry to read. End the stream instead of reading past the end and
51+
// publishing branch addresses that GetEntry has not filled. This was an assert, which is
52+
// compiled out of every production build since ENABLE_CASSERT defaults to OFF.
53+
LOG(info) << "no entry to read, ending the stream";
54+
pc.services().get<ControlService>().endOfStream();
55+
pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
56+
return;
57+
}
4958
mTree->GetEntry(ent);
5059

5160
LOG(debug) << "FT0 RecPointReader pushes " << mRecPoints->size() << " recpoints with " << mChannelData->size() << " channels at entry " << ent;

Detectors/FIT/FV0/workflow/src/DigitReaderSpec.cxx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,16 @@ void DigitReader::run(ProcessingContext& pc)
6262
mTree->SetBranchAddress("FV0DigitLabels", &plabels);
6363
}
6464
auto ent = mTree->GetReadEntry() + 1;
65-
assert(ent < mTree->GetEntries()); // this should not happen
65+
if (ent >= mTree->GetEntries()) {
66+
// A timeframe holds no collision at all whenever the interaction rate is low enough, and
67+
// the tree then has no entry to read. End the stream instead of reading past the end and
68+
// publishing branch addresses that GetEntry has not filled. This was an assert, which is
69+
// compiled out of every production build since ENABLE_CASSERT defaults to OFF.
70+
LOG(info) << "no entry to read, ending the stream";
71+
pc.services().get<ControlService>().endOfStream();
72+
pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
73+
return;
74+
}
6675
mTree->GetEntry(ent);
6776
LOG(debug) << "FV0DigitReader pushed " << channels.size() << " channels in " << digits.size() << " digits";
6877
pc.outputs().snapshot(Output{"FV0", "DIGITSBC", 0}, digits);

Detectors/FIT/FV0/workflow/src/RecPointReaderSpec.cxx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,16 @@ void RecPointReader::init(InitContext& ic)
4545
void RecPointReader::run(ProcessingContext& pc)
4646
{
4747
auto ent = mTree->GetReadEntry() + 1;
48-
assert(ent < mTree->GetEntries()); // this should not happen
48+
if (ent >= mTree->GetEntries()) {
49+
// A timeframe holds no collision at all whenever the interaction rate is low enough, and
50+
// the tree then has no entry to read. End the stream instead of reading past the end and
51+
// publishing branch addresses that GetEntry has not filled. This was an assert, which is
52+
// compiled out of every production build since ENABLE_CASSERT defaults to OFF.
53+
LOG(info) << "no entry to read, ending the stream";
54+
pc.services().get<ControlService>().endOfStream();
55+
pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
56+
return;
57+
}
4958
mTree->GetEntry(ent);
5059

5160
LOG(debug) << "FV0 RecPointReader pushes " << mRecPoints->size() << " recpoints with " << mChannelData->size() << " channels at entry " << ent;

Detectors/Filtering/src/FilteredTFReaderSpec.cxx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,16 @@ void FilteredTFReader::run(ProcessingContext& pc)
4040
// FIXME: fill all output headers by TF specific info (extend findMessageHeaderStack)
4141

4242
auto ent = mTree->GetReadEntry() + 1;
43-
assert(ent < mTree->GetEntries()); // this should not happen
43+
if (ent >= mTree->GetEntries()) {
44+
// A timeframe holds no collision at all whenever the interaction rate is low enough, and
45+
// the tree then has no entry to read. End the stream instead of reading past the end and
46+
// publishing branch addresses that GetEntry has not filled. This was an assert, which is
47+
// compiled out of every production build since ENABLE_CASSERT defaults to OFF.
48+
LOG(info) << "no entry to read, ending the stream";
49+
pc.services().get<ControlService>().endOfStream();
50+
pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
51+
return;
52+
}
4453
mTree->GetEntry(ent);
4554

4655
LOG(info) << "Pushing filtered TF: " << mFiltTF.header.asString();

0 commit comments

Comments
 (0)