hooks for PMD flow analysis
[u/mrichter/AliRoot.git] / PWG2 / FLOW / macros / mergeOutput.C
CommitLineData
57340a27 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:
ad87ae62 4// 1.) In directory <dir> there are subdirectories <subdir1>, <subdir2>, ...;
57340a27 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>;
ad87ae62 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.
021fb870 16// 5.) REMARK 1: To see plots for some of results use macro compareFlowResults.C. This macro
ad87ae62 17// accesses file "AnalysisResults.root" and produces couple of predefined example plots.
021fb870 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.
20
21// Name of the output files to be merged (sitting in <subdir1>, <subdir2>, ...):
22TString outputFileName = "AnalysisResults.root";
23// Name of the merged, large statistics file (to be saved in <dir>):
24TString mergedFileName = "mergedAnalysisResults.root";
25// Optionally set maximum number of files to be merged:
26Int_t maxNoOfFiles = -1; // -1 = ignore
27// For a large number of output files merging is done in cycles and this is the cycle period:
28const Int_t cycle = 50;
ad87ae62 29
23965fa2 30enum libModes {mLocal,mLocalSource};
31
32void mergeOutput(Int_t mode=mLocal)
fe11f681 33{
021fb870 34 // Mode: if mode = mLocal: analyze data on your computer using aliroot
23965fa2 35 // if mode = mLocalSource: analyze data on your computer using root + source files
021fb870 36
37 // Cross-check user settings before starting:
38 CrossCheckUserSettings();
39
23965fa2 40 // Load needed flow libraries:
41 LoadLibrariesMO(mode);
021fb870 42
57340a27 43 // Standard magic:
9455e15e 44 TString *baseDirPath = new TString(gSystem->pwd());
ad87ae62 45 TSystemDirectory *baseDir = new TSystemDirectory(".",baseDirPath->Data());
46 TList *listOfFilesInBaseDir = baseDir->GetListOfFiles();
57340a27 47 TStopwatch timer;
48 timer.Start();
021fb870 49 //listOfFilesInBaseDir->Print();
50
51 // Count number of files to be merged:
52 CountNumberOfFilesToBeMerged(baseDirPath,listOfFilesInBaseDir);
53
54 // Loop over all files and from each subdirectory add file <outputFileName> to TFileMerger:
9455e15e 55 Int_t nFiles = listOfFilesInBaseDir->GetEntries();
ad87ae62 56 Int_t fileCounter = 0;
57340a27 57 TFileMerger *fileMerger = new TFileMerger();
021fb870 58 cout<<" .... merging in progress, silence please ...."<<"\r"<<flush;
9455e15e 59 for(Int_t iFile=0;iFile<nFiles;iFile++)
fe11f681 60 {
57340a27 61 TSystemFile *currentFile = (TSystemFile*)listOfFilesInBaseDir->At(iFile);
62 // Consider only subdirectories:
63 if(!currentFile ||
64 !currentFile->IsDirectory() ||
65 strcmp(currentFile->GetName(), ".") == 0 ||
021fb870 66 strcmp(currentFile->GetName(), "..") == 0){continue;}
67 // Accessing the output file <outputFileName> in current subdirectory:
57340a27 68 TString currentSubDirName = baseDirPath->Data();
69 (currentSubDirName+="/")+=currentFile->GetName();
70 currentSubDirName+="/";
71 TString fileName = currentSubDirName;
ad87ae62 72 fileName+=outputFileName.Data();
ad87ae62 73 if(!(gSystem->AccessPathName(fileName.Data(),kFileExists)))
947cc449 74 {
021fb870 75 if(gROOT->GetVersionDate()>=20100404) // to be improved - removed eventually (this is temporary protection)
76 {
77 Bool_t success = fileMerger->AddFile(fileName.Data(),kFALSE); // kFALSE switches off cp printout (not supported in older Root)
78 if(success){fileCounter++;}
79 } else
80 {
81 Bool_t success = fileMerger->AddFile(fileName.Data());
82 if(success){fileCounter++;}
83 }
57340a27 84 // Merging in cycles:
ad87ae62 85 if(fileCounter % cycle == 0)
9455e15e 86 {
57340a27 87 // If the merged output from previous cycle exists add it to TFileMerger:
88 TString *mergedFileForPreviousCycle = new TString("mergedCycle");
ad87ae62 89 (*mergedFileForPreviousCycle)+=(fileCounter/cycle - 1);
90 (*mergedFileForPreviousCycle)+=".root";
ad87ae62 91 if(!(gSystem->AccessPathName(mergedFileForPreviousCycle->Data(),kFileExists)))
9455e15e 92 {
021fb870 93 if(gROOT->GetVersionDate()>=20100404) // to be improved - removed eventually (this is temporary protection)
94 {
95 fileMerger->AddFile(mergedFileForPreviousCycle->Data(),kFALSE); // kFALSE switches off cp printout (not supported in older Root)
96 } else
97 {
98 fileMerger->AddFile(mergedFileForPreviousCycle->Data());
99 }
57340a27 100 // Delete merged output from previous cycle:
101 TSystemFile *file = new TSystemFile(mergedFileForPreviousCycle->Data(),baseDirPath->Data());
9455e15e 102 file->Delete();
103 delete file;
57340a27 104 }
021fb870 105 // Create merged output for the current cycle:
57340a27 106 TString *mergedFileForCurrentCycle = new TString("mergedCycle");
ad87ae62 107 (*mergedFileForCurrentCycle)+=(fileCounter/cycle);
57340a27 108 (*mergedFileForCurrentCycle)+=".root";
ad87ae62 109 fileMerger->OutputFile(mergedFileForCurrentCycle->Data());
110 fileMerger->Merge();
021fb870 111 cout<<" .... merged "<<fileCounter<<" files so far, marching on .... "<<"\r"<<flush;
57340a27 112 fileMerger->Reset();
ad87ae62 113 delete mergedFileForPreviousCycle;
114 delete mergedFileForCurrentCycle;
115 } // end of if(fileCounter % cycle == 0)
116 } // end of if(!(gSystem->AccessPathName(fileName.Data(),kFileExists)))
021fb870 117 if(fileCounter==maxNoOfFiles){break;}
9455e15e 118 } // end of for(Int_t iFile=0;iFile<nFiles;iFile++)
fe11f681 119
9455e15e 120 //=================================================================================================
121
57340a27 122 // Final merging at the end of the day (3 distinct cases):
9455e15e 123 gSystem->cd(baseDirPath->Data());
ad87ae62 124 if(fileCounter < cycle)
125 {
57340a27 126 fileMerger->OutputFile(mergedFileName.Data());
ad87ae62 127 fileMerger->Merge();
57340a27 128 } else if(fileCounter % cycle == 0)
ad87ae62 129 {
57340a27 130 TString *mergedFileForPreviousCycle = new TString("mergedCycle");
ad87ae62 131 (*mergedFileForPreviousCycle)+=(fileCounter/cycle);
132 (*mergedFileForPreviousCycle)+=".root";
133 if(!(gSystem->AccessPathName(mergedFileForPreviousCycle->Data(),kFileExists)))
134 {
57340a27 135 gSystem->Rename(mergedFileForPreviousCycle->Data(),mergedFileName.Data());
136 }
9455e15e 137 } else
138 {
57340a27 139 TString *mergedFileForPreviousCycle = new TString("mergedCycle");
ad87ae62 140 (*mergedFileForPreviousCycle)+=((Int_t)fileCounter/cycle);
57340a27 141 (*mergedFileForPreviousCycle)+=".root";
021fb870 142 if(gROOT->GetVersionDate()>=20100404) // to be improved - removed eventually (this is temporary protection)
143 {
144 fileMerger->AddFile(mergedFileForPreviousCycle->Data(),kFALSE);
145 } else
146 {
147 fileMerger->AddFile(mergedFileForPreviousCycle->Data());
148 }
57340a27 149 // Delete merged output from previous cycle:
150 TSystemFile *file = new TSystemFile(mergedFileForPreviousCycle->Data(),baseDirPath->Data());
9455e15e 151 file->Delete();
152 delete file;
57340a27 153 fileMerger->OutputFile(mergedFileName.Data());
ad87ae62 154 fileMerger->Merge();
ad87ae62 155 delete mergedFileForPreviousCycle;
9455e15e 156 }
ad87ae62 157 delete fileMerger;
9455e15e 158 delete baseDirPath;
159 delete baseDir;
021fb870 160
161 if(!(gSystem->AccessPathName(mergedFileName.Data(),kFileExists)) && fileCounter > 0)
57340a27 162 {
021fb870 163 cout<<" Merging went successfully: "<<fileCounter<<" files \""<<outputFileName.Data()<<"\" were"<<endl;
164 cout<<" merged into the newly created file \""<<mergedFileName.Data()<<"\"."<<endl;
57340a27 165 cout<<endl;
021fb870 166 cout<<" Launch now macro redoFinish.C to get the correct final results."<<endl;
57340a27 167 } else
168 {
021fb870 169 cout<<" WARNING: Merging failed miserably !!!!"<<endl;
170 }
57340a27 171 cout<<endl;
021fb870 172 timer.Stop();
173 timer.Print();
174 cout<<endl;
175
23965fa2 176} // End of void mergeOutput(Int_t mode=mLocal)
177
021fb870 178// ===================================================================================
179
180void CrossCheckUserSettings()
181{
182 // Cross-check user settings before starting:
183
184 if(cycle>100)
185 {
186 cout<<endl;
187 cout<<" WARNING: Cycle is too big !!!!"<<endl;
188 cout<<" Set \"const Int_t cycle\" to smaller value in the macro."<<endl;
189 cout<<endl;
190 exit(0);
191 }
192
193} // void CrossCheckUserSettings()
194
195// ===================================================================================
196
197void CountNumberOfFilesToBeMerged(TString *baseDirPath,TList *listOfFilesInBaseDir)
198{
199 // Count number of files to be merged and print info on the screen.
200
201 if(!(baseDirPath && listOfFilesInBaseDir))
202 {
203 cout<<endl;
204 cout<<" WARNING: baseDirPath||listOfFilesInBaseDir is NULL in CountNumberOfFilesToBeMerged(...) !!!!"<<endl;
205 cout<<endl;
206 exit(0);
207 }
208
209 Int_t nFiles = listOfFilesInBaseDir->GetEntries();
210 Int_t fileCounter = 0;
211 for(Int_t iFile=0;iFile<nFiles;iFile++)
212 {
213 TSystemFile *currentFile = (TSystemFile*)listOfFilesInBaseDir->At(iFile);
214 // Consider only subdirectories:
215 if(!currentFile ||
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)))
226 {
227 fileCounter++;
228 }
229 } // end of for(Int_t iFile=0;iFile<nFiles;iFile++)
230
231 // Print info on the screen:
232 if(fileCounter>0)
233 {
234 cout<<endl;
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;
238 cout<<endl;
239 }
240 else if(fileCounter==0)
241 {
242 cout<<endl;
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;
246 cout<<endl;
247 exit(0);
248 }
249
250 return;
251
252} // void CountNumberOfFilesToBeMerged(TString *dirName,TList *listOfAllFiles)
253
254// ===================================================================================
23965fa2 255
256void LoadLibrariesMO(const libModes mode) {
257
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");
266
267 //----------------------------------------------------------
268 // >>>>>>>>>>> Local mode <<<<<<<<<<<<<<
269 //----------------------------------------------------------
270 if (mode==mLocal) {
271 //--------------------------------------------------------
272 // If you want to use already compiled libraries
273 // in the aliroot distribution
274 //--------------------------------------------------------
275
276 //==================================================================================
277 //load needed libraries:
278 gSystem->AddIncludePath("-I$ROOTSYS/include");
279 //gSystem->Load("libTree");
280
281 // for AliRoot
282 gSystem->AddIncludePath("-I$ALICE_ROOT/include");
283 gSystem->Load("libANALYSIS");
284 gSystem->Load("libPWG2flowCommon");
285 //cerr<<"libPWG2flowCommon loaded ..."<<endl;
286
287 }
288
289 else if (mode==mLocalSource) {
290
291 // In root inline compile
292
293 // Constants
294 gROOT->LoadMacro("AliFlowCommon/AliFlowCommonConstants.cxx+");
295 gROOT->LoadMacro("AliFlowCommon/AliFlowLYZConstants.cxx+");
23965fa2 296
297 // Flow event
298 gROOT->LoadMacro("AliFlowCommon/AliFlowVector.cxx+");
5062cb0f 299 gROOT->LoadMacro("AliFlowCommon/AliFlowTrackSimple.cxx+");
23965fa2 300 gROOT->LoadMacro("AliFlowCommon/AliFlowTrackSimpleCuts.cxx+");
5062cb0f 301 gROOT->LoadMacro("AliFlowCommon/AliFlowEventSimple.cxx+");
23965fa2 302
303 // Output histosgrams
304 gROOT->LoadMacro("AliFlowCommon/AliFlowCommonHist.cxx+");
305 gROOT->LoadMacro("AliFlowCommon/AliFlowCommonHistResults.cxx+");
306 gROOT->LoadMacro("AliFlowCommon/AliFlowLYZHist1.cxx+");
307 gROOT->LoadMacro("AliFlowCommon/AliFlowLYZHist2.cxx+");
308
309 cout << "finished loading macros!" << endl;
310
311 } // end of else if (mode==mLocalSource)
312
313} // end of void LoadLibrariesMO(const libModes mode)
314