00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifdef __CINT__
00013
00014 #else
00015 # include "TDirIter.h"
00016 # include "StFileIter.h"
00017 # include "TFileIter.h"
00018 # include "TFile.h"
00019 # include "TTree.h"
00020 # include "TH1.h"
00021 # include "TStopwatch.h"
00022 #endif
00023
00024
00025 void MergeSimpleHistogramFile( const Char_t *TargetName=0, const Char_t *inputFilesPattern=0)
00026 {
00027
00028 if (TargetName && TargetName[0] && inputFilesPattern && inputFilesPattern[0] ) {
00029 TStopwatch time;
00030 Int_t fileCounter = 0;
00031 Int_t histogramCounter = 0;
00032
00033 TFile *outFile = TFile::Open(TargetName,"RECREATE");
00034 TDirIter listOfFiles(inputFilesPattern);
00035 const char *fileName = 0;
00036 while ( (fileName = listOfFiles.NextFile() ) ) {
00037 printf(".");
00038 fileCounter++;
00039 TFileIter file(fileName);
00040 TObject *obj = 0;
00041 while ( (obj = *file) ) {
00042 if ( obj->IsA()->InheritsFrom( "TH1" ) ) {
00043
00044
00045
00046 TH1 *h1 = (TH1*)obj;
00047 TH1 *dstHistogram = 0;
00048
00049 if ( (dstHistogram = (TH1 *)outFile->FindObject(h1->GetName()))) {
00050
00051 dstHistogram->Add(h1);
00052 delete h1;
00053 printf("+");
00054 } else {
00055
00056 h1->SetDirectory(outFile);
00057 printf(" The new Histogram found: %s \n", h1->GetName() );
00058 histogramCounter++;
00059 }
00060 } else {
00061
00062 }
00063 ++file;
00064 }
00065
00066 }
00067 printf("\n Finishing . . . \n");
00068 outFile->ls();
00069 outFile->Write();
00070 outFile->Close();
00071 delete outFile;
00072 printf(" Total files merged: %d \n", fileCounter);
00073 printf(" Total histograms merged: %d \n", histogramCounter);
00074 time.Print("Merge");
00075 } else {
00076 printf("\nUsage: root MergeHistogramFile.C(\"DestinationFileName\",\"InputFilesPattern\",kTRUE)\n");
00077 printf("------ where InputFilesPattern ::= <regexp_pattern_for_the_input_files>|@indirect_file_list\n");
00078 printf(" indirect_file_list ::= a text file with the list of the files\n");
00079 printf(" indirect_file_list can be create by the shell command:\n");
00080 printf(" ls -1 --color=never *.root>indirect_file_list \n\n");
00081 }
00082 }
00083
00084
00085 void MergeComplexHistogramFile( const Char_t *TargetName=0, const Char_t *inputFilesPattern=0)
00086 {
00087 if (TargetName && TargetName[0] && inputFilesPattern && inputFilesPattern[0] ) {
00088 printf(" An experimental version of macro.\n");
00089 TStopwatch time;
00090 Int_t fileCounter = 0;
00091 Int_t dirCounter = 0;
00092 Int_t treeCounter = 0;
00093 Int_t histogramCounter = 0;
00094
00095 TFile *outFile = TFile::Open(TargetName,"RECREATE");
00096 TDirectory *outDir = outFile;
00097 TDirIter listOfFiles(inputFilesPattern);
00098 const char *fileName = 0;
00099 while ( (fileName = listOfFiles.NextFile() ) ) {
00100 Int_t currentDirDepth = 0;
00101 printf(".");
00102 fileCounter++;
00103 StFileIter file(fileName);
00104 TObject *obj = 0;
00105 while ( (obj = *file) ) {
00106 Int_t depth = file.GetDepth();
00107 while (depth < currentDirDepth) {
00108 outDir = outDir->GetMotherDir();
00109 currentDirDepth--;
00110 }
00111 if ( obj->IsA()->InheritsFrom(TH1::Class()) ) {
00112
00113
00114
00115 TH1 *h1 = (TH1*)obj;
00116 TH1 *dstHistogram = 0;
00117
00118 if ( (dstHistogram = (TH1 *)outDir->FindObject(h1->GetName()))) {
00119
00120 dstHistogram->Add(h1);
00121 delete h1;
00122 printf("h");
00123 } else {
00124
00125 h1->SetDirectory(outDir);
00126 printf(" The new Histogram found: %s \n", h1->GetName() );
00127 histogramCounter++;
00128 }
00129 } else if ( obj->IsA()->InheritsFrom(TTree::Class()) ) {
00130
00131
00132 TTree *tree = (TTree*)obj;
00133 TTree *dstTree = 0;
00134
00135 if ( (dstTree = (TTree *)outDir->FindObject(tree->GetName()))) {
00136
00137
00138
00139 TList *nextTree = new TList(); nextTree->Add(tree);
00140 dstTree->Merge(nextTree);
00141 delete tree;
00142 delete nextTree;
00143 printf("t");
00144 } else {
00145
00146 TDirectory *saveDir = 0;
00147 if (outDir != gDirectory) {
00148 saveDir = gDirectory;
00149 outDir->cd();
00150 }
00151 TList *nextTree = new TList(); nextTree->Add(tree);
00152 dstTree = TTree::MergeTrees(nextTree);
00153 if (saveDir) saveDir->cd();
00154
00155
00156 delete tree;
00157 delete nextTree;
00158 treeCounter++;
00159 }
00160 } else if ( obj->IsA()->InheritsFrom(TDirectory::Class()) ) {
00161 printf("The input sub-TDirectory object: %s depth=%d\n",obj->GetName(), depth);
00162 TDirectory *d = (TDirectory *)outDir->FindObject(obj->GetName());
00163 if (!d) {
00164 d = outDir->mkdir(obj->GetName());
00165 dirCounter++;
00166 printf("The new TDirectory object: %s depth=%d\n",d->GetPathStatic(), depth);
00167 }
00168 if (d) {
00169 outDir = d;
00170 printf("The output sub-TDirectory object: %s depth=%d\n",outDir->GetPathStatic(), depth);
00171
00172 }
00173 } else {
00174 printf("I have no idea how to merge the %s objects of the %s class. Skipping .... \n",obj->GetName(), obj->ClassName() );
00175 }
00176 ++file;
00177 }
00178
00179 }
00180 printf("\n Finishing . . . \n");
00181 outFile->Write();
00182 outFile->Close();
00183 delete outFile;
00184 if (fileCounter) printf(" Total files merged: %d \n", fileCounter);
00185 if (dirCounter) printf(" Total TDirectory objects merged: %d \n", dirCounter);
00186 if (histogramCounter) printf(" Total histograms merged: %d \n", histogramCounter);
00187 if (treeCounter) printf(" Total TTree\'s merged: %d \n",treeCounter);
00188 if (dirCounter || treeCounter) printf(" You have used the experimental version of the program. Please check the output file\n");
00189
00190 time.Print("Merge");
00191 } else {
00192 printf("\nUsage: root MergeHistogramFile.C(\"DestinationFileName\",\"InputFilesPattern\")\n");
00193 printf("------ where InputFilesPattern ::= <regexp_pattern_for_the_input_files>|@indirect_file_list\n");
00194 printf(" indirect_file_list ::= a text file with the list of the files\n");
00195 printf(" indirect_file_list can be create by the shell command:\n");
00196 printf(" ls -1 *.root>indirect_file_list \n\n");
00197 }
00198 }
00199
00200
00201
00202
00203 void MergeHistogramFile( const Char_t *TargetName=0, const Char_t *inputFilesPattern=0, Bool_t simple=kFALSE)
00204 {
00205 if (TargetName && TargetName[0] && inputFilesPattern && inputFilesPattern[0] ) {
00206
00207 Long64_t maxsize = 100000000;
00208 maxsize *= 100;
00209 TTree::SetMaxTreeSize(maxsize);
00210 if (simple) {
00211
00212 MergeSimpleHistogramFile(TargetName, inputFilesPattern);
00213 } else {
00214 #ifdef __CINT__
00215 gSystem->Load("St_base");
00216 #endif
00217 MergeComplexHistogramFile(TargetName, inputFilesPattern);
00218 }
00219 } else {
00220 printf("\nUsage: root MergeHistogramFile.C(\"DestinationFileName\",\"InputFilesPattern\",kTRUE)\n");
00221 printf("------ where InputFilesPattern ::= <regexp_pattern_for_the_input_files>|@indirect_file_list\n");
00222 printf(" indirect_file_list ::= a text file with the list of the files\n");
00223 printf(" indirect_file_list can be create by the shell command:\n\n");
00224 printf(" ls -1 --color=never *.root>indirect_file_list \n\n");
00225 printf(" The last parameter defines whether one wants to merge the \"simple\" ROOT files\n");
00226 printf(" The \"simple\" ROOT files are those with no sub-TDirectrory objects inside and with no TTree/TNtuples\n");
00227 printf(" This is the default option and it can be omitted\n");
00228 printf(" To merge the ROOT files with sub-TDirectory or / and TTree pass the kFALSE as the third macro parameter\n\n");
00229 printf("------------- To use with ACliC - load the \"St_base.so\" shared library first\n");
00230
00231 }
00232 }