Short version: A file with ntuples was written and closed. In the same program, I open the file again in UPDATE mode, then close it. After that, the first ntuple in the file is corrupted (though the remaining ntuples and objects are fine).
Details:
I’m running a Geant4 simulation (4.11, though I don’t think that matters here). The program uses Geant4’s G4AnalysisManager to manage and write n-tuples. At the end of main program, after the G4RunManager is closed, I want to append the detector geometry as a TGeoManager in the ROOT output file.
(The idea is that even if a user fails to keep a good record of which detector version they used to run the simulation, the TGeoManager description will be in the file as a reference. Our detector model takes up ~70K of space, which is nothing compared to the ~50M of our typical simulation output file.)
I have verified that, before the following code is executed, the value of gFile is 0 (i.e., no ROOT file is open). The value of gDirectory->GetName() is /root
. This is the current version of the code that corrupts the output file:
auto geoManager = gGeoManager->Import("parsed.gdml");
std::shared_ptr<TFile> outputFile ( TFile::Open(g4job.root,"UPDATE") );
geoManager->Write("DetectorGeometry");
outputFile->Close();
parsed.gdml
is the result of G4GDMLparser::Write
earlier in the program. I create this file separately because this output is ROOT-compatible (whereas the GDML input to the G4 program is not, since it contains formulas and loops). I’ve verified via independent programs that there’s nothing problematic about the contents of parsed.gdml
.
The TGeoManager structure DetectorGeometry
is being appended to the file g4job.root
. I can examine the file with TBrowser, draw the detector, etc.
The problem is when I try to access the first ntuple/TTree in the file:
root g4job.root
root [0]
Attaching file g4job.root as _file0...
(TFile *) 0x56337037d900
root [1] FirstNtuple->Scan()
************************************************************************************************************
* Row * Run.Run * Event.Eve * TrackID.T * PDGCode.P * numPhoton * energy.en * tStart.tS * xStart.xS *
************************************************************************************************************
Warning in <TBasket::ReadBasketBuffers>: basket: has fNevBuf=1801810947 but fEntryOffset=0, pos=166, len=5035, fNbytes=1895623809, fObjlen=0, trying to repair
Error in <TBranch::GetBasket>: File: gramsg4.root at byte:0, branch:Run, entry:0, badread=0, nerrors=1, basketnumber=0
* 0 * 0 * 0 * 1 * 22 * 2 * 1.462e-05 * 6.6710802 * 0.1178747 *
Warning in <TBasket::ReadBasketBuffers>: basket: has fNevBuf=1801810947 but fEntryOffset=0, pos=166, len=5035, fNbytes=1895623809, fObjlen=0, trying to repair
Error in <TBranch::GetBasket>: File: gramsg4.root at byte:0, branch:Run, entry:1, badread=0, nerrors=2, basketnumber=0
* 1 * 0 * 0 * 1 * 22 * 160 * 0.0031776 * 7.0527228 * -5.057142 *
Warning in <TBasket::ReadBasketBuffers>: basket: has fNevBuf=1801810947 but fEntryOffset=0, pos=166, len=5035, fNbytes=1895623809, fObjlen=0, trying to repair
Error in <TBranch::GetBasket>: File: gramsg4.root at byte:0, branch:Run, entry:2, badread=0, nerrors=3, basketnumber=0
* 2 * 0 * 0 * 1 * 22 * 14 * 0.0002494 * 7.5646246 * -1.809136 *
Warning in <TBasket::ReadBasketBuffers>: basket: has fNevBuf=1801810947 but fEntryOffset=0, pos=166, len=5035, fNbytes=1895623809, fObjlen=0, trying to repair
Error in <TBranch::GetBasket>: File: gramsg4.root at byte:0, branch:Run, entry:3, badread=0, nerrors=4, basketnumber=0
… and so on. Only the first ntuple has this problem.
I’ve tried doing the TGeoManager::Import both before and after opening the output file in UPDATE mode. The results are the same.
I know from other forum posts that this means that the g4job.root
has become corrupted. If I comment out the TGeoManager::Write line, the g4job.root
file still shows the same problem. This suggests that simply opening and closing g4job.root
in UPDATE mode is what’s corrupting the file.
If I comment out that entire block of code that contains the TFile::Open, everything is fine:
root [0]
Attaching file g4job.root as _file0...
(TFile *) 0x5632a3e7d850
root [1] FirstNtuple->Scan()
************************************************************************************************************
* Row * Run.Run * Event.Eve * TrackID.T * PDGCode.P * numPhoton * energy.en * tStart.tS * xStart.xS *
************************************************************************************************************
* 0 * 0 * 0 * 1 * 22 * 2 * 1.462e-05 * 6.6710802 * 0.1178747 *
* 1 * 0 * 0 * 1 * 22 * 160 * 0.0031776 * 7.0527228 * -5.057142 *
* 2 * 0 * 0 * 1 * 22 * 14 * 0.0002494 * 7.5646246 * -1.809136 *
* 3 * 0 * 0 * 1 * 22 * 2 * 1.462e-05 * 7.8422709 * -5.057142 *
* 4 * 0 * 0 * 1 * 22 * 13 * 0.0002494 * 8.1213327 * -10.39429 *
* 5 * 0 * 0 * 1 * 22 * 5 * 0.0002494 * 8.1247158 * -10.43015 *
* 6 * 0 * 0 * 1 * 22 * 161 * 0.0031776 * 8.1846038 * -11.03238 *
* 7 * 0 * 0 * 9 * 11 * 220 * 0.0042875 * 8.3723247 * -6.236709 *
* 8 * 0 * 0 * 9 * 11 * 673 * 0.0129153 * 8.3723765 * -6.235956 *
* 9 * 0 * 0 * 9 * 11 * 911 * 0.0183359 * 8.3725065 * -6.234133 *
* 10 * 0 * 0 * 9 * 11 * 1485 * 0.0293105 * 8.3726141 * -6.234505 *
It was my understanding that opening a file in UPDATE mode was not supposed to interfere with the existing contents of a file. Did I mis-understand? Is there something special about files containing ntuples that I should compensate for? Or am I missing something else?
ROOT Version: 6.28/04
Platform: CentOS 7
Compiler: 12.3.0