00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <string.h>
00028 #include "TChain.h"
00029 #include "TFile.h"
00030 #include "TH1.h"
00031 #include "TTree.h"
00032 #include "TKey.h"
00033 #include "Riostream.h"
00034
00035 TList *FileList;
00036 TFile *Target;
00037
00038 void MergeRootfile( TDirectory *target, TList *sourcelist );
00039
00040
00041 void hadd() {
00042
00043
00044
00045
00046
00047 Target = TFile::Open( "result.root", "RECREATE" );
00048
00049 FileList = new TList();
00050 FileList->Add( TFile::Open("hsimple1.root") );
00051 FileList->Add( TFile::Open("hsimple2.root") );
00052
00053 MergeRootfile( Target, FileList );
00054
00055 }
00056
00057 void MergeRootfile( TDirectory *target, TList *sourcelist ) {
00058
00059
00060 TString path( (char*)strstr( target->GetPath(), ":" ) );
00061 path.Remove( 0, 2 );
00062
00063 TFile *first_source = (TFile*)sourcelist->First();
00064 first_source->cd( path );
00065 TDirectory *current_sourcedir = gDirectory;
00066
00067 Bool_t status = TH1::AddDirectoryStatus();
00068 TH1::AddDirectory(kFALSE);
00069
00070
00071 TChain *globChain = 0;
00072 TIter nextkey( current_sourcedir->GetListOfKeys() );
00073 TKey *key, *oldkey=0;
00074 while ( (key = (TKey*)nextkey())) {
00075
00076
00077 if (oldkey && !strcmp(oldkey->GetName(),key->GetName())) continue;
00078
00079
00080 first_source->cd( path );
00081 TObject *obj = key->ReadObj();
00082
00083 if ( obj->IsA()->InheritsFrom( TH1::Class() ) ) {
00084
00085
00086
00087 TH1 *h1 = (TH1*)obj;
00088
00089
00090
00091 TFile *nextsource = (TFile*)sourcelist->After( first_source );
00092 while ( nextsource ) {
00093
00094
00095 nextsource->cd( path );
00096 TKey *key2 = (TKey*)gDirectory->GetListOfKeys()->FindObject(h1->GetName());
00097 if (key2) {
00098 TH1 *h2 = (TH1*)key2->ReadObj();
00099 h1->Add( h2 );
00100 delete h2;
00101 }
00102
00103 nextsource = (TFile*)sourcelist->After( nextsource );
00104 }
00105 }
00106 else if ( obj->IsA()->InheritsFrom( TTree::Class() ) ) {
00107
00108
00109 const char* obj_name= obj->GetName();
00110
00111 globChain = new TChain(obj_name);
00112 globChain->Add(first_source->GetName());
00113 TFile *nextsource = (TFile*)sourcelist->After( first_source );
00114
00115
00116 while ( nextsource ) {
00117
00118 globChain->Add(nextsource->GetName());
00119 nextsource = (TFile*)sourcelist->After( nextsource );
00120 }
00121
00122 } else if ( obj->IsA()->InheritsFrom( TDirectory::Class() ) ) {
00123
00124
00125 cout << "Found subdirectory " << obj->GetName() << endl;
00126
00127
00128 target->cd();
00129 TDirectory *newdir = target->mkdir( obj->GetName(), obj->GetTitle() );
00130
00131
00132
00133
00134 MergeRootfile( newdir, sourcelist );
00135
00136 } else {
00137
00138
00139 cout << "Unknown object type, name: "
00140 << obj->GetName() << " title: " << obj->GetTitle() << endl;
00141 }
00142
00143
00144
00145
00146
00147 if ( obj ) {
00148 target->cd();
00149
00150
00151 if(obj->IsA()->InheritsFrom( TTree::Class() ))
00152 globChain->Merge(target->GetFile(),0,"keep");
00153 else
00154 obj->Write( key->GetName() );
00155 }
00156
00157 }
00158
00159
00160 target->SaveSelf(kTRUE);
00161 TH1::AddDirectory(status);
00162 }