MC-RECO: Ability to process empty timeframes (Part 2) - #15714
Conversation
This fixes a crash in the ITS, MFT, MCH and MID digit readers when the digit tree of a timeframe has no entry. - A timeframe holds no collision at all whenever the interaction rate is low enough, and the digitiser then writes a valid tree with zero entries. - The ITS/MFT reader guarded this with an assert, which is compiled out of every production build because ENABLE_CASSERT defaults to OFF, and then dereferenced branch addresses that GetEntry had not filled. - The MCH and MID readers threw on the failed TTreeReader::Next(). - All four now send empty output and end the stream. - The two asserts in the ITS/MFT connectTree become real errors for the same reason. https://its.cern.ch/jira/browse/O2-7132 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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>
dabbfd9 to
dc8f978
Compare
shahor02
left a comment
There was a problem hiding this comment.
For a few readers:
https://github.com/AliceO2Group/AliceO2/pull/15714/changes#diff-3654ea38b43dd2b5f05e4ab99b0f5dc2bb89cad480e6a365ab259a82be7eaf9f
https://github.com/AliceO2Group/AliceO2/pull/15714/changes#diff-75dcdcc9f329167ed627abeef73469da9ad9503840d9bce79658514198299d82
https://github.com/AliceO2Group/AliceO2/pull/15714/changes#diff-a1e131747a717c9df39d29e7dd5d7076e24a187166e9235fa23d0fb5e62c0608
you push an empty output before issuing the EOS, while in the rest you just call the EOS.
Why?
If I understand the logic of your changes, the TFs w/o collisions will still have digits etc. trees with 1 empty entry, so the mTree->GetEntries()==0 should not happen.
But if does, should not the policy be the same for all, i.e. push a dummy output and call EOS?
|
Just to confirm what Ruben said but from TOF side. If there are no hits/clusters the size of the vector will be zero but the number of entries in the tree will be always 1. |
This makes the reader specs follow one policy for a tree without an entry: publish empty output and then end the stream. - 36 readers ended the stream without sending anything, while the ITS/MFT, MCH and MID digit readers sent empty output first. - A reader that ends the stream without publishing leaves its own writer with a zero-entry tree, which recreates the same condition in the next step. - Readers whose branch data lives in owned members now skip only the GetEntry; the ones binding ROOT-allocated pointers publish an explicit empty container, since those pointers are null before the first GetEntry. - The TPC track reader called accumulate(), which reads the entry, before the check. https://its.cern.ch/jira/browse/O2-7132 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This lets the detector publishers built on RootTreeReader follow the same policy as the hand-written reader specs, and guards the consumer that broke once they do. - RootTreeReader published nothing when its tree had no entry, so the EMCAL cells never reached the AOD producer and no AOD was written for a timeframe without collisions. - It now publishes one default-constructed object per branch and then stops. The object is real, so a registered publishing hook still works. - Looping over a tree without entries published nothing forever; it now ends. - SVertexer took vtxRefs.size() - 1 as the number of vertices, which wrapped around once the primary vertex reader sent an empty vector. https://its.cern.ch/jira/browse/O2-7132 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
@shahor02 @noferini : You are right. The PR has been amended and we now push empty output and then call EOS. I prefer that over EOS alone because reconstruction runs as separate steps: a reader that ends the stream without publishing leaves its own writer with a zero-entry tree, recreating the condition in the next step. Together with #15705, the following reproducer: which only has ~1.42 events per timeframe of 32 orbits and can have many empty timeframes now runs successfully to the end (instead of crashing). |
Allows reconstruction to handle empty-timeframes sanely instead of crashing.