void WriteMergeObjects( TFile *target ) { cout << "Writing the merged data." << endl; TIterator *nextobj = MergeObjects.MakeIterator(); TObjString *pathname_obj; while( (pathname_obj = (TObjString *)nextobj->Next()) ) { TString path,name; SplitPathName(pathname_obj->String(),&path,&name); TObject *obj = MergeObjects.GetValue(pathname_obj); target->cd(path); obj->Write( name ); delete obj; } MergeObjects.Clear(); target->Write(); // Temporarily let multiple root files remain if > 2GB // Prevent Target_1.root Target_2.root, ... from happening. // long long max_tree_size = 200000000000LL; // 200 GB // if(TTree::GetMaxTreeSize() < max_tree_size ) { // TTree::SetMaxTreeSize(max_tree_size); // } nextobj = MergeChains.MakeIterator(); TObjString *pathname_obj; while( (pathname_obj = (TObjString *)nextobj->Next()) ) { TString path,name; SplitPathName(pathname_obj->String(),&path,&name); TChain *ch = (TChain *)MergeChains.GetValue(pathname_obj); target->cd(path); ch->Merge(target,0,"KEEP"); delete ch; // in case of multiple objects with same pathname, must remove // this one from the list so we don't get the same (deleted) // one next time we look up the same name MergeChains.Remove(pathname_obj); } MergeChains.Clear(); InitializedMergeObjects = false; }
void MergeRootfile( TDirectory *target, TString source_name ) { TFile *source = NULL; if( !InitializedMergeObjects ) { InitializedMergeObjects = true; source = TFile::Open(source_name); cout << "Initializing merge objects from " << source_name << endl; InitMergeObjects( target, source ); delete source; return; } // loop over all objects to be merged TIterator *nextobj = MergeObjects.MakeIterator(); TObjString *pathname_obj; while( (pathname_obj = (TObjString *)nextobj->Next()) ) { TString path,name; SplitPathName(pathname_obj->String(),&path,&name); TObject *obj = MergeObjects.GetValue(pathname_obj); if ( obj->IsA()->InheritsFrom( "TH1" ) ) { // descendant of TH1 -> merge it TH1 *h1 = (TH1*)obj; if( !source ) { source = TFile::Open(source_name); } // make sure we are at the correct directory level by cd'ing to path source->cd( path ); TH1 *h2 = (TH1*)gDirectory->Get( h1->GetName() ); if ( h2 ) { h1->Add( h2 ); delete h2; } } } delete nextobj; nextobj = NULL; // loop over all chains to be merged nextobj = MergeChains.MakeIterator(); TObjString *pathname_obj; while( (pathname_obj = (TObjString *)nextobj->Next()) ) { TString path,name; SplitPathName(pathname_obj->String(),&path,&name); TChain *ch = (TChain *)MergeChains.GetValue(pathname_obj); ch->Add(source_name); } delete nextobj; nextobj = NULL; if( source ) { delete source; } }