Appending to file opened in UPDATE mode corrupts file

The lack of TFileMerger documentation makes using the class problematic. I tried it, and it appears to execute:

  G4String workfile = "work_" + filename;

  // Rename the output file to the temporary work file name.                                                                      
  gSystem->Rename(filename,workfile);

  TFileMerger* merger = new TFileMerger(kFALSE);
  merger->AddFile(workfile);
  merger->OutputFile(filename);
  merger->Merge();

  // Remove the work file; it just wastes disk space at this point.                                                               
  gSystem->Unlink(workfile);

The status message appears in the program output:

[TFile::Cp] Total 5.09 MB	|====================| 100.00 % [146.4 MB/s]

But all the ntuples in the output file are now corrupted:

root [0] 
Attaching file gramsg4.root as _file0...
(TFile *) 0x5632e50c04b0
root [1] TrackInfo->Scan()
Error in <TBufferFile::ReadClassBuffer>: Could not find the StreamerInfo for version 5 of the class TTree, object skipped at offset 77
Error in <TBufferFile::CheckByteCount>: object of class TTree read too few bytes: 2 instead of 9348

There’s probably some enum or boolean I have to set somewhere, but it’s not clear what it should be.

A practical use can be found at ROOT: main/src/hadd.cxx Source File

Try

 merger->Merge(TFileMerger::kIncremental | TFileMerger::kAll);

Cheers,
Philippe

Same error.

From my perspective, the source code of hadd is a mass of uncommented code. It must somehow do what I want it to do, since just using hadd gives the results I want, but I can’t even tell what the default options to TFileMerger are supposed to be.

I guessed an answer that worked:

  G4String workfile = "work_" + filename;
  // Rename the output file to the temporary work file name.                                                                      
  gSystem->Rename(filename,workfile);

  TFileMerger* merger = new TFileMerger(kFALSE,kFALSE);
  auto input = TFile::Open(workfile);
  auto compression = input->GetCompressionSettings();
  merger->AddFile(input);
  merger->OutputFile(filename,"RECREATE",compression);
  merger->Merge();
  gSystem->Unlink(workfile);

It was setting the compression settings of the output file to be the same as the input file.