File indexing completed on 2025-08-06 08:11:53
0001
0002
0003
0004
0005
0006
0007
0008 #include <fstream>
0009 #include <string.h>
0010 #include "TChain.h"
0011 #include "TFile.h"
0012 #include "TH1.h"
0013 #include "TTree.h"
0014 #include "TKey.h"
0015 #include "Riostream.h"
0016
0017
0018
0019
0020 void MergeRootfile(TDirectory *target, TList *sourcelist);
0021
0022
0023
0024 void MergeFiles(const Int_t nFiles=100, const TString filelist= "file.list", const TString outputrootfiles ="test.root") {
0025
0026 ifstream files;
0027
0028 files.open(filelist);
0029
0030 char file_stm[800];
0031 int line=0;
0032
0033 TList *FileList;
0034 TFile *Target;
0035
0036
0037 TString filename_output;
0038 TString chain_;
0039 Int_t start_num = 0;
0040 Int_t end_num = 4;
0041
0042 Target = TFile::Open(outputrootfiles, "RECREATE");
0043 FileList = new TList();
0044
0045 while(files.good()) {
0046 files >> file_stm;
0047
0048
0049 if ((line + 1) > nFiles) {
0050 cout << "WARNING: Whoah there, tiger! Only need " << nFiles << " files!\n"
0051 << " Moving on to processing files."
0052 << endl;
0053 break;
0054 }
0055
0056
0057
0058 TFile f(file_stm);
0059
0060
0061
0062
0063 Bool_t fOk = f.IsZombie();
0064 cout<<"file# "<<line<<" "<< file_stm<<" zombi= "<<fOk<<endl;
0065
0066 if(!fOk)
0067 {
0068 FileList->Add(TFile::Open(file_stm));
0069 }
0070
0071
0072
0073 if (!files.good()) break;
0074 line++;
0075 }
0076 MergeRootfile( Target, FileList );
0077
0078
0079 }
0080
0081
0082
0083 void MergeRootfile( TDirectory *target, TList *sourcelist ) {
0084
0085
0086 TString path( (char*)strstr( target->GetPath(), ":" ) );
0087 path.Remove( 0, 2 );
0088
0089 TFile *first_source = (TFile*)sourcelist->First();
0090 first_source->cd( path );
0091 TDirectory *current_sourcedir = gDirectory;
0092
0093 Bool_t status = TH1::AddDirectoryStatus();
0094 TH1::AddDirectory(kFALSE);
0095
0096
0097 TChain *globChain = 0;
0098 TIter nextkey( current_sourcedir->GetListOfKeys() );
0099 TKey *key, *oldkey=0;
0100 while ( (key = (TKey*)nextkey())) {
0101
0102
0103 if (oldkey && !strcmp(oldkey->GetName(),key->GetName())) continue;
0104
0105
0106 first_source->cd( path );
0107 TObject *obj = key->ReadObj();
0108
0109 if ( obj->IsA()->InheritsFrom( TH1::Class() ) ) {
0110
0111
0112
0113 TH1 *h1 = (TH1*)obj;
0114
0115
0116
0117 TFile *nextsource = (TFile*)sourcelist->After( first_source );
0118 while ( nextsource ) {
0119
0120
0121 nextsource->cd( path );
0122 TKey *key2 = (TKey*)gDirectory->GetListOfKeys()->FindObject(h1->GetName());
0123 if (key2) {
0124 TH1 *h2 = (TH1*)key2->ReadObj();
0125 h1->Add( h2 );
0126 delete h2;
0127 }
0128
0129 nextsource = (TFile*)sourcelist->After( nextsource );
0130 }
0131 }
0132 else if ( obj->IsA()->InheritsFrom( TTree::Class() ) ) {
0133
0134
0135 const char* obj_name= obj->GetName();
0136
0137 globChain = new TChain(obj_name);
0138 globChain->Add(first_source->GetName());
0139 TFile *nextsource = (TFile*)sourcelist->After( first_source );
0140
0141
0142 while ( nextsource ) {
0143
0144 globChain->Add(nextsource->GetName());
0145 nextsource = (TFile*)sourcelist->After( nextsource );
0146 }
0147
0148 } else if ( obj->IsA()->InheritsFrom( TDirectory::Class() ) ) {
0149
0150
0151 cout << "Found subdirectory " << obj->GetName() << endl;
0152
0153
0154 target->cd();
0155 TDirectory *newdir = target->mkdir( obj->GetName(), obj->GetTitle() );
0156
0157
0158
0159
0160 MergeRootfile( newdir, sourcelist );
0161
0162 } else {
0163
0164
0165 cout << "Unknown object type, name: "
0166 << obj->GetName() << " title: " << obj->GetTitle() << endl;
0167 }
0168
0169
0170
0171
0172
0173 if ( obj ) {
0174 target->cd();
0175
0176
0177 if(obj->IsA()->InheritsFrom( TTree::Class() ))
0178 globChain->Merge(target->GetFile(),0,"keep");
0179 else
0180 obj->Write( key->GetName() );
0181 }
0182
0183 }
0184
0185
0186 target->SaveSelf(kTRUE);
0187 TH1::AddDirectory(status);
0188 }
0189
0190