Histo Merging in TDirectory structure

From: Dirk Geppert (Dirk.Geppert@cern.ch)
Date: Fri Nov 12 1999 - 16:06:49 MET


Hello Rooters,

below you can find a modified version of examples/hadd.C
'How to Merge files with histograms and trees'
with the additional facility to merge histograms in a 
TDirectory structure recursively.

Maybe it could be useful for some of you or one of the root 
developers could take the idea to implement it's functionality
in the quoted HowTo.

Dirk


//----------------------------------------------------------------------
gROOT->Reset();

//______________________________________________________________________
// give the list of files below. Last file must be a NULL string
const char *cfiles[] = {
  "file1.root",
  "file2.root",
  ""};
const char *outfile="../../file.root";
//______________________________________________________________________

TFile   *fnew;
TList   *flist;
TFile   *afile, *file1;

TH1     *h1, *h2;
TTree   *t1, *t2;
TObject *obj;
TKey    *key;

void AddRecursive(TDirectory *root,TDirectory* node); 
//______________________________________________________________________
//
//
//  
//______________________________________________________________________
void hadd() {

  // create the result file
  fnew = new TFile(outfile,"RECREATE");
  
  //create a support list for the input files
  flist = new TList();
  
  //open all input files and insert them in the list of files
  Int_t nfiles = 0;
  while (strlen(cfiles[nfiles])) {
    afile = new TFile(cfiles[nfiles]);
    flist->Add(afile);
    nfiles++;
  }
  
  //Get a pointer to the first file
  afile = file1 = (TFile*)flist->First();

  AddRecursive(fnew,file1);
  
  cout<<"Done, clean up"<<endl;
  fnew->ls();
  fnew->Write();
  fnew->Close();
  delete fnew;
  flist->Delete();
  delete flist;
}

//______________________________________________________________________
//
//
//  
//______________________________________________________________________
void AddRecursive(TDirectory *root,TDirectory* node) {

  static TDirectory *dact;

  //We create an iterator to loop on all objects(keys) of first file
  TIter nextkey(node->GetListOfKeys());
  while (key = (TKey*)nextkey()) {
    node->cd();
    obj = key->ReadObj();
    if (obj->IsA()->InheritsFrom("TTree")) { //case of a TTree or TNtuple
      t1 = (TTree*)obj;
      // this part still to be implemented
      // use TChain::Merge instead
    } elseif(obj->IsA()->InheritsFrom("TH1")) { //case of TH1 or TProfile
      h1 = (TH1*)obj;
      afile = (TFile*)flist->After(node);
      while (afile) { //loop on all files starting at second file
	h2 = (TH1*)afile->Get(h1->GetName());
	if (h2) { // here we should check that we can add
	  h1->Add(h2);
	  delete h2;
	}
	afile = (TFile*)flist->After(afile);
      }
    } elseif(obj->IsA()->InheritsFrom("TDirectory")) { //case of TDirectory
      root->cd();
      dact=root->mkdir(obj->GetName(),obj->GetTitle());
      dact->cd();
      AddRecursive(dact,(TDirectory*)obj);
    } else { //another object
      printf("anotherobjname=%s, title=%s\n",obj->GetName(),obj->GetTitle());
    }

    // write node object, modified or not into fnew
    if (obj) {
      root->cd();
      obj->Write(key->GetName());
      delete obj;
      obj=NULL; 
    }
  }
  root->cd();
}
//______________________________________________________________________ 



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:42 MET