Skip to content

Preserve StreamerInfos when reopening output files in UPDATE mode#567

Open
cmargalejo wants to merge 2 commits into
masterfrom
cris_preserve_streamerinfos
Open

Preserve StreamerInfos when reopening output files in UPDATE mode#567
cmargalejo wants to merge 2 commits into
masterfrom
cris_preserve_streamerinfos

Conversation

@cmargalejo

@cmargalejo cmargalejo commented Jun 12, 2026

Copy link
Copy Markdown
Member

cmargalejo Ok: 56 Powered by Pull Request Badge

Fixes #568

The problem

When a ROOT file is closed, TFile::WriteStreamerInfo() replaces the file's
StreamerInfo record, keeping only the infos of the classes streamed during that
session. TRestRun::MergeToOutputFile merges the threads' output files (which
preserves the infos), but then reopens the merged file in UPDATE mode to write
the metadata: closing that session wipes the StreamerInfos of all event classes,
keeping only the metadata classes.

As a consequence, no restManager output file contains event-class
StreamerInfos
, which silently breaks ROOT schema evolution whenever an event
class definition changes. This is what made files written before the
TRestDetectorSignal vector<Float_t>vector<Double_t> change unreadable
(rest-for-physics/detectorlib#125): without the on-disk layout description,
ROOT misreads the float payload as doubles and allocates GBs of garbage.

(restG4 files are unaffected: they are written in a single session.)

The fix

New TRestTools::PreserveStreamerInfos(TFile*): called right after opening a
file in UPDATE mode, it re-tags every StreamerInfo already stored in the file
(same marking as the deprecated TStreamerInfo::TagFile) so that
TFile::WriteStreamerInfo writes them out again on close. Called at the UPDATE
sessions that write into REST data files:

  • TRestRun::MergeToOutputFile (the main restManager output path)
  • TRestRun::UpdateOutputFile
  • TRestProcessRunner split-file metadata update of the main file
  • TRestDataSet::Export

Verification

Merging two files containing TRestDetectorSignalEvent trees via
TRestRun::MergeToOutputFile: without the fix the merged file keeps only
TRestRun/TRestMetadata infos; with it, TRestDetectorSignalEvent,
TRestEvent and TRestDetectorSignal survive the metadata session and the
file reads back correctly.

Note: this protects files written from now on. Existing files have already
lost their StreamerInfos; for the detector signal case the data is recoverable
with the tool in #566.

When a ROOT file is closed, TFile::WriteStreamerInfo() replaces the
file's StreamerInfo record with only the infos of the classes streamed
during that session. TRestRun::MergeToOutputFile merges the threads'
output files (which preserves the infos) but then reopens the merged
file in UPDATE mode to write the metadata: closing that session wiped
the StreamerInfos of all event classes, keeping only the metadata
classes.

As a consequence no restManager output file contains event-class
StreamerInfos, which breaks ROOT schema evolution whenever an event
class definition changes. This is what made files written before the
TRestDetectorSignal vector<Float_t> -> vector<Double_t> change
unreadable (rest-for-physics/detectorlib#125): without the on-disk
layout description, ROOT misreads the float payload as doubles.

Add TRestTools::PreserveStreamerInfos(TFile*), which re-tags every
StreamerInfo already stored in a file opened in UPDATE mode so that
TFile::WriteStreamerInfo writes them out again on close (same marking
as the deprecated TStreamerInfo::TagFile). Call it at the UPDATE
sessions that write into REST data files:

- TRestRun::MergeToOutputFile (the main restManager output path)
- TRestRun::UpdateOutputFile
- TRestProcessRunner split-file metadata update of the main file
- TRestDataSet::Export

Verified by merging two files containing TRestDetectorSignalEvent
trees via TRestRun::MergeToOutputFile: the event-class StreamerInfos
now survive the metadata session and the merged file reads back
correctly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The validation workflows cache the build with key BRANCH_NAME-sha, so
a re-run cannot pick up the restG4 fix (rest-for-physics/restG4#148);
only a new commit invalidates the cache.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Output files lose event-class StreamerInfos (UPDATE session on close wipes them)

1 participant