Robustness of writing two TTree's to one TFile

Hi all,

Recently I encountered some problems writing multiple TTree’s to one TFile after parallel job submissions. In some Geant4 code I have two TTree’s (per parallel node), ROOTTree and ROOTTreeFoil, with corresponding TChain’s treeChain and treeChainFoil. At the end of the run, I need to collect up all the slave files generated from the parallelization and merge their TTree’s into a final output file. The following code snippet was working up until very recently:
[code]
TChain *treeChain = new TChain(“ROOTTree”);
TChain *treeChainFoil = new TChain(“ROOTTreeFoil”);

  std::vector<G4String>::iterator it;
  for(it = slaveFileNames.begin(); it != slaveFileNames.end(); it++)
  {
    treeChain->Add((*it).c_str());
    treeChainFoil->Add((*it).c_str());
  }

  treeChain->Merge(FinalFileName.c_str());
  treeChainFoil->Merge(FinalFileName.c_str());
  [/code]

However, I can no longer get both TChain’s to write to the TFile. The treeChainFoil->Merge() command seems to overwrite the initial treeChain->Merge(), and treeChain will only show up in the TFile if the second Merge is commented out. So, is there a more robust way of merging the data together, then writing the two final TTree’s to a TFile?

It appears that the problem occurs only when I run in parallel with MPI. Using a standard sequential build allows both TTree’s to be written to file…

One solution is to use ROOT’s hadd utility instead of TChain::Merge:

      std::vector<G4String>::iterator it;
      G4String targets = " ";
      for(it = slaveFileNames.begin(); it != slaveFileNames.end(); it++)
      {
        targets += (*it).c_str();
        targets += " ";
      }

      G4String haddCommand = "hadd -f " + FinalFileName + targets;
      system(haddCommand.c_str());

Hi,

Indeed the solution is to use hadd or its implementation class (TFileMerger) which will handle both TTree at the same time.
Using two sequential TChain::Merge (onto the same output file) will indeed result in overwrite.

Cheers,
Philippe.