1 // Macro mergeOutput.C is used to merge output files "AnalysisResults.root" locally.
2 // (To merge output files "AnalysisResults.root" on Grid use macro mergeOutputOnGrid.C.)
3 // Its usage relies on the following directory structure and naming conventions:
4 // 1.) In directory <dir> there are subdirectories <subdir1>, <subdir2>, ...;
5 // 2.) In subdirectory <subdir*> there is a file named "AnalysisResults.root";
6 // 3.) Copy macro mergeOutput.C in directory <dir> and launch it. It will automatically
7 // access from each subdirectory a file "AnalysisResults.root" and by making use of
8 // TFileMerger utility it will produce a merged file "mergedAnalysisResults.root"
9 // and save it in directory <dir>;
10 // 4.) IMPORTANT: Macro mergeOutput.C must be used in a combination with macro redoFinish.C
11 // in order to get the analysis done on merged, large statistics sample. In particular,
12 // after you got the file "mergedAnalysisResults.root", copy macro redoFinish.C in
13 // directory <dir> and launch it. This macro will access "mergedAnalysisResults.root"
14 // and produce the output file "AnalysisResults.root" in directory <dir>. This file will
15 // hold the final results for merged, large statistics sample.
16 // 5.) REMARK 1: To see plots for some of results use macro compareFlowResults.C. This macro
17 // accesses file "AnalysisResults.root" and produces couple of predefined example plots.
18 // 6.) REMARK 2: To use this macro for merging of other root files (having other name than
19 // the default "AnalysisResults.root") modify the declaration of TString outputFileName.
21 // Name of the output files to be merged (sitting in <subdir1>, <subdir2>, ...):
22 TString outputFileName = "AnalysisResults.root";
23 // Name of the merged, large statistics file (to be saved in <dir>):
24 TString mergedFileName = "mergedAnalysisResults.root";
25 // Optionally set maximum number of files to be merged:
26 Int_t maxNoOfFiles = -1; // -1 = ignore
27 // For a large number of output files merging is done in cycles and this is the cycle period:
28 const Int_t cycle = 50;
30 enum libModes {mLocal,mLocalSource};
32 void mergeOutput(Int_t mode=mLocal)
34 // Mode: if mode = mLocal: analyze data on your computer using aliroot
35 // if mode = mLocalSource: analyze data on your computer using root + source files
37 // Cross-check user settings before starting:
38 CrossCheckUserSettings();
40 // Load needed flow libraries:
41 LoadLibrariesMO(mode);
44 TString *baseDirPath = new TString(gSystem->pwd());
45 TSystemDirectory *baseDir = new TSystemDirectory(".",baseDirPath->Data());
46 TList *listOfFilesInBaseDir = baseDir->GetListOfFiles();
49 //listOfFilesInBaseDir->Print();
51 // Count number of files to be merged:
52 CountNumberOfFilesToBeMerged(baseDirPath,listOfFilesInBaseDir);
54 // Loop over all files and from each subdirectory add file <outputFileName> to TFileMerger:
55 Int_t nFiles = listOfFilesInBaseDir->GetEntries();
56 Int_t fileCounter = 0;
57 TFileMerger *fileMerger = new TFileMerger();
58 cout<<" .... merging in progress, silence please ...."<<"\r"<<flush;
59 for(Int_t iFile=0;iFile<nFiles;iFile++)
61 TSystemFile *currentFile = (TSystemFile*)listOfFilesInBaseDir->At(iFile);
62 // Consider only subdirectories:
64 !currentFile->IsDirectory() ||
65 strcmp(currentFile->GetName(), ".") == 0 ||
66 strcmp(currentFile->GetName(), "..") == 0){continue;}
67 // Accessing the output file <outputFileName> in current subdirectory:
68 TString currentSubDirName = baseDirPath->Data();
69 (currentSubDirName+="/")+=currentFile->GetName();
70 currentSubDirName+="/";
71 TString fileName = currentSubDirName;
72 fileName+=outputFileName.Data();
73 if(!(gSystem->AccessPathName(fileName.Data(),kFileExists)))
75 if(gROOT->GetVersionDate()>=20100404) // to be improved - removed eventually (this is temporary protection)
77 Bool_t success = fileMerger->AddFile(fileName.Data(),kFALSE); // kFALSE switches off cp printout (not supported in older Root)
78 if(success){fileCounter++;}
81 Bool_t success = fileMerger->AddFile(fileName.Data());
82 if(success){fileCounter++;}
85 if(fileCounter % cycle == 0)
87 // If the merged output from previous cycle exists add it to TFileMerger:
88 TString *mergedFileForPreviousCycle = new TString("mergedCycle");
89 (*mergedFileForPreviousCycle)+=(fileCounter/cycle - 1);
90 (*mergedFileForPreviousCycle)+=".root";
91 if(!(gSystem->AccessPathName(mergedFileForPreviousCycle->Data(),kFileExists)))
93 if(gROOT->GetVersionDate()>=20100404) // to be improved - removed eventually (this is temporary protection)
95 fileMerger->AddFile(mergedFileForPreviousCycle->Data(),kFALSE); // kFALSE switches off cp printout (not supported in older Root)
98 fileMerger->AddFile(mergedFileForPreviousCycle->Data());
100 // Delete merged output from previous cycle:
101 TSystemFile *file = new TSystemFile(mergedFileForPreviousCycle->Data(),baseDirPath->Data());
105 // Create merged output for the current cycle:
106 TString *mergedFileForCurrentCycle = new TString("mergedCycle");
107 (*mergedFileForCurrentCycle)+=(fileCounter/cycle);
108 (*mergedFileForCurrentCycle)+=".root";
109 fileMerger->OutputFile(mergedFileForCurrentCycle->Data());
111 cout<<" .... merged "<<fileCounter<<" files so far, marching on .... "<<"\r"<<flush;
113 delete mergedFileForPreviousCycle;
114 delete mergedFileForCurrentCycle;
115 } // end of if(fileCounter % cycle == 0)
116 } // end of if(!(gSystem->AccessPathName(fileName.Data(),kFileExists)))
117 if(fileCounter==maxNoOfFiles){break;}
118 } // end of for(Int_t iFile=0;iFile<nFiles;iFile++)
120 //=================================================================================================
122 // Final merging at the end of the day (3 distinct cases):
123 gSystem->cd(baseDirPath->Data());
124 if(fileCounter < cycle)
126 fileMerger->OutputFile(mergedFileName.Data());
128 } else if(fileCounter % cycle == 0)
130 TString *mergedFileForPreviousCycle = new TString("mergedCycle");
131 (*mergedFileForPreviousCycle)+=(fileCounter/cycle);
132 (*mergedFileForPreviousCycle)+=".root";
133 if(!(gSystem->AccessPathName(mergedFileForPreviousCycle->Data(),kFileExists)))
135 gSystem->Rename(mergedFileForPreviousCycle->Data(),mergedFileName.Data());
139 TString *mergedFileForPreviousCycle = new TString("mergedCycle");
140 (*mergedFileForPreviousCycle)+=((Int_t)fileCounter/cycle);
141 (*mergedFileForPreviousCycle)+=".root";
142 if(gROOT->GetVersionDate()>=20100404) // to be improved - removed eventually (this is temporary protection)
144 fileMerger->AddFile(mergedFileForPreviousCycle->Data(),kFALSE);
147 fileMerger->AddFile(mergedFileForPreviousCycle->Data());
149 // Delete merged output from previous cycle:
150 TSystemFile *file = new TSystemFile(mergedFileForPreviousCycle->Data(),baseDirPath->Data());
153 fileMerger->OutputFile(mergedFileName.Data());
155 delete mergedFileForPreviousCycle;
161 if(!(gSystem->AccessPathName(mergedFileName.Data(),kFileExists)) && fileCounter > 0)
163 cout<<" Merging went successfully: "<<fileCounter<<" files \""<<outputFileName.Data()<<"\" were"<<endl;
164 cout<<" merged into the newly created file \""<<mergedFileName.Data()<<"\"."<<endl;
166 cout<<" Launch now macro redoFinish.C to get the correct final results."<<endl;
169 cout<<" WARNING: Merging failed miserably !!!!"<<endl;
176 } // End of void mergeOutput(Int_t mode=mLocal)
178 // ===================================================================================
180 void CrossCheckUserSettings()
182 // Cross-check user settings before starting:
187 cout<<" WARNING: Cycle is too big !!!!"<<endl;
188 cout<<" Set \"const Int_t cycle\" to smaller value in the macro."<<endl;
193 } // void CrossCheckUserSettings()
195 // ===================================================================================
197 void CountNumberOfFilesToBeMerged(TString *baseDirPath,TList *listOfFilesInBaseDir)
199 // Count number of files to be merged and print info on the screen.
201 if(!(baseDirPath && listOfFilesInBaseDir))
204 cout<<" WARNING: baseDirPath||listOfFilesInBaseDir is NULL in CountNumberOfFilesToBeMerged(...) !!!!"<<endl;
209 Int_t nFiles = listOfFilesInBaseDir->GetEntries();
210 Int_t fileCounter = 0;
211 for(Int_t iFile=0;iFile<nFiles;iFile++)
213 TSystemFile *currentFile = (TSystemFile*)listOfFilesInBaseDir->At(iFile);
214 // Consider only subdirectories:
216 !currentFile->IsDirectory() ||
217 strcmp(currentFile->GetName(), ".") == 0 ||
218 strcmp(currentFile->GetName(), "..") == 0) continue;
219 // Accessing the output file <outputFileName> in current subdirectory:
220 TString currentSubDirName = baseDirPath->Data();
221 (currentSubDirName+="/")+=currentFile->GetName();
222 currentSubDirName+="/";
223 TString fileName = currentSubDirName;
224 fileName+=outputFileName.Data();
225 if(!(gSystem->AccessPathName(fileName.Data(),kFileExists)))
229 } // end of for(Int_t iFile=0;iFile<nFiles;iFile++)
231 // Print info on the screen:
235 cout<<" In subdirectores of directory "<<baseDirPath->Data()<<endl;
236 cout<<" there are "<<fileCounter<<" files \""<<outputFileName.Data()<<"\" to be merged."<<endl;
237 cout<<" Let the merging begins!"<<endl;
240 else if(fileCounter==0)
243 cout<<" TFileMerger wasn't lucky :'( "<<endl;
244 cout<<" Couldn't find a single file \""<<outputFileName.Data()<<"\" to merge"<<endl;
245 cout<<" in subdirectories of directory "<<baseDirPath->Data()<<" !!!!"<<endl;
252 } // void CountNumberOfFilesToBeMerged(TString *dirName,TList *listOfAllFiles)
254 // ===================================================================================
256 void LoadLibrariesMO(const libModes mode) {
258 //--------------------------------------
259 // Load the needed libraries most of them already loaded by aliroot
260 //--------------------------------------
261 //gSystem->Load("libTree");
262 gSystem->Load("libGeom");
263 gSystem->Load("libVMC");
264 gSystem->Load("libXMLIO");
265 gSystem->Load("libPhysics");
267 //----------------------------------------------------------
268 // >>>>>>>>>>> Local mode <<<<<<<<<<<<<<
269 //----------------------------------------------------------
271 //--------------------------------------------------------
272 // If you want to use already compiled libraries
273 // in the aliroot distribution
274 //--------------------------------------------------------
276 //==================================================================================
277 //load needed libraries:
278 gSystem->AddIncludePath("-I$ROOTSYS/include");
279 //gSystem->Load("libTree");
282 gSystem->AddIncludePath("-I$ALICE_ROOT/include");
283 gSystem->Load("libANALYSIS");
284 gSystem->Load("libPWGflowBase");
285 //cerr<<"libPWGflowBase loaded ..."<<endl;
289 else if (mode==mLocalSource) {
291 // In root inline compile
294 gROOT->LoadMacro("BaseAliFlowCommonConstants.cxx+");
295 gROOT->LoadMacro("BaseAliFlowLYZConstants.cxx+");
298 gROOT->LoadMacro("BaseAliFlowVector.cxx+");
299 gROOT->LoadMacro("BaseAliFlowTrackSimple.cxx+");
300 gROOT->LoadMacro("BaseAliFlowTrackSimpleCuts.cxx+");
301 gROOT->LoadMacro("BaseAliFlowEventSimple.cxx+");
303 // Output histosgrams
304 gROOT->LoadMacro("BaseAliFlowCommonHist.cxx+");
305 gROOT->LoadMacro("BaseAliFlowCommonHistResults.cxx+");
306 gROOT->LoadMacro("BaseAliFlowLYZHist1.cxx+");
307 gROOT->LoadMacro("BaseAliFlowLYZHist2.cxx+");
309 cout << "finished loading macros!" << endl;
311 } // end of else if (mode==mLocalSource)
313 } // end of void LoadLibrariesMO(const libModes mode)