]>
Commit | Line | Data |
---|---|---|
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>, ...): | |
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; | |
ad87ae62 | 29 | |
23965fa2 | 30 | enum libModes {mLocal,mLocalSource}; |
31 | ||
32 | void 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 | ||
180 | void 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 | ||
197 | void 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 | |
256 | void 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"); | |
2e311896 | 284 | gSystem->Load("libPWGflowBase"); |
285 | //cerr<<"libPWGflowBase loaded ..."<<endl; | |
23965fa2 | 286 | |
287 | } | |
288 | ||
289 | else if (mode==mLocalSource) { | |
290 | ||
291 | // In root inline compile | |
292 | ||
293 | // Constants | |
2e311896 | 294 | gROOT->LoadMacro("BaseAliFlowCommonConstants.cxx+"); |
295 | gROOT->LoadMacro("BaseAliFlowLYZConstants.cxx+"); | |
23965fa2 | 296 | |
297 | // Flow event | |
2e311896 | 298 | gROOT->LoadMacro("BaseAliFlowVector.cxx+"); |
299 | gROOT->LoadMacro("BaseAliFlowTrackSimple.cxx+"); | |
300 | gROOT->LoadMacro("BaseAliFlowTrackSimpleCuts.cxx+"); | |
301 | gROOT->LoadMacro("BaseAliFlowEventSimple.cxx+"); | |
23965fa2 | 302 | |
303 | // Output histosgrams | |
2e311896 | 304 | gROOT->LoadMacro("BaseAliFlowCommonHist.cxx+"); |
305 | gROOT->LoadMacro("BaseAliFlowCommonHistResults.cxx+"); | |
306 | gROOT->LoadMacro("BaseAliFlowLYZHist1.cxx+"); | |
307 | gROOT->LoadMacro("BaseAliFlowLYZHist2.cxx+"); | |
23965fa2 | 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 |