hooks for PMD flow analysis
[u/mrichter/AliRoot.git] / PWG2 / FLOW / macros / mergeOutputOnGrid.C
1 // Macro mergeOutputOnGrid.C is used to merge output files "AnalysisResults.root" 
2 // from the AliEn file catalog. Remarks:
3 //  1.) It uses your local AliRoot version - try to have locally the same AliRoot
4 //      version as the one you have specified for the analysis on Grid, otherwise
5 //      strange things might happen ....  
6 //  2.) It produces the merged, large statistics file "mergedAnalysisResults.root" 
7 //      in the directory <dir> from which the macro was launched. Results stored 
8 //      in merged file are WRONG because after merging the results from small 
9 //      statistics files are trivially summed up in all histograms. To get the 
10 //      final correct flow estimates for the large statistics file copy in <dir> 
11 //      and execute macro redoFinish.C (see comments in redoFinish.C). 
12
13 // Name of the output files to be merged:
14 TString outputFileName = "AnalysisResults.root";
15 // Name of the merged, large statistics file:
16 TString mergedFileName = "mergedAnalysisResults.root";
17 // Optionally set maximum number of files to be merged:
18 Int_t maxNoOfFiles = -1; // -1 = ignore
19 // For a large number of output files merging is done in cycles and this is the cycle period: 
20 const Int_t cycle = 25;
21
22 void mergeOutputOnGrid(const char* gridPath = "/alice/cern.ch/user/a/abilandz/sim/LHC10e16/default/output/*") 
23 {
24  // Cross-check user settings before starting:
25  CrossCheckUserSettings(); 
26  // Time: 
27  TStopwatch timer;
28  timer.Start();
29  // Load needed flow libraries:
30  gSystem->AddIncludePath("-I$ROOTSYS/include");
31  gSystem->AddIncludePath("-I$ALICE_ROOT/include");
32  gSystem->Load("libPWG2flowCommon");
33  //cerr<<"Library \"libPWG2flowCommon\" loaded ...."<<endl;
34  // Connect to the GRID:
35  TGrid::Connect("alien://");  
36  // Query the file catalog and get a TGridResult:
37  TString queryPattern = outputFileName;
38  TGridResult *result = gGrid->Query(gridPath,queryPattern.Data());
39  Int_t nEntries = result->GetEntries();
40  Printf("\n Found %d files \"%s\" in subdirectories of directory \n %s \n Let the merging begins! \n",nEntries,outputFileName.Data(),gridPath);   
41  gSystem->Sleep(4400); // in ms
42  // Create a TFileMerger:
43  TFileMerger *fileMerger = new TFileMerger(); 
44  Int_t fileCounter = 0;
45  TString *baseDirPath = new TString(gSystem->pwd());
46  // Loop over the TGridResult's entries and add the files to the TFileMerger:
47  TString alienUrl;
48  for(Int_t i=0;i<nEntries;i++) 
49  {
50   alienUrl = result->GetKey(i,"turl");
51   //Printf("%s",alienUrl.Data());  
52   if(gROOT->GetVersionDate()>=20100404) // to be improved - removed eventually (this is temporary protection)
53   { 
54    Bool_t success = fileMerger->AddFile(alienUrl.Data(),kFALSE); // kFALSE switches off cp printout (not supported in older Root)
55    if(success){fileCounter++;}
56   } else 
57     {
58      Bool_t success = fileMerger->AddFile(alienUrl.Data());
59      if(success){fileCounter++;}
60     }     
61   // Merging in cycles:
62   if(fileCounter % cycle == 0)
63   {
64    // If the merged output from previous cycle exists add it to TFileMerger:
65    TString *mergedFileForPreviousCycle = new TString("mergedCycle"); 
66    (*mergedFileForPreviousCycle)+=(fileCounter/cycle - 1);
67    (*mergedFileForPreviousCycle)+=".root";
68    if(!(gSystem->AccessPathName(mergedFileForPreviousCycle->Data(),kFileExists)))
69    {
70     if(gROOT->GetVersionDate()>=20100404) // to be improved - removed eventually (this is temporary protection)
71      {  
72       fileMerger->AddFile(mergedFileForPreviousCycle->Data(),kFALSE); // kFALSE switches off cp printout (not supported in older Root)
73      } else
74        {
75         fileMerger->AddFile(mergedFileForPreviousCycle->Data());
76        }
77     // Delete merged output from previous cycle:
78     TSystemFile *file = new TSystemFile(mergedFileForPreviousCycle->Data(),baseDirPath->Data());
79     file->Delete();
80     delete file;
81    }    
82    // Create merged output for current cycle:
83    TString *mergedFileForCurrentCycle = new TString("mergedCycle"); 
84    (*mergedFileForCurrentCycle)+=(fileCounter/cycle);
85    (*mergedFileForCurrentCycle)+=".root";    
86    fileMerger->OutputFile(mergedFileForCurrentCycle->Data());
87    fileMerger->Merge();
88    Int_t percentage = 0;
89    if(maxNoOfFiles > 0)
90    {
91     percentage = (Int_t)100.*fileCounter/maxNoOfFiles;
92    } else
93      {
94       percentage = (Int_t)100.*fileCounter/nEntries;   
95      }   
96    Int_t max = 0;
97    if(maxNoOfFiles > 0)
98    {
99     max = maxNoOfFiles;
100    } else
101      {
102       max = nEntries;
103      }     
104    if(max-fileCounter > 0)
105    {  
106     cout<<endl;
107     cout<<" .... merged "<<percentage<<"% requested files so far, marching on ....                       "<<endl;   
108     cout<<endl;
109    }  
110    fileMerger->Reset();    
111    delete mergedFileForPreviousCycle;
112    delete mergedFileForCurrentCycle;
113   } // end of if(fileCounter % cycle == 0) 
114   if(fileCounter==maxNoOfFiles){break;}
115  } // end of for(Int_t i=0;i<nEntries;i++) 
116
117  //================================================================================================= 
118  
119  // Final merging at the end of the day (3 distinct cases):
120  gSystem->cd(baseDirPath->Data());
121  if(fileCounter < cycle)
122  {
123   fileMerger->OutputFile(mergedFileName.Data());
124   fileMerger->Merge();
125  } else if(fileCounter % cycle == 0)
126    {
127     TString *mergedFileForPreviousCycle = new TString("mergedCycle"); 
128     (*mergedFileForPreviousCycle)+=(fileCounter/cycle);
129     (*mergedFileForPreviousCycle)+=".root";    
130     if(!(gSystem->AccessPathName(mergedFileForPreviousCycle->Data(),kFileExists)))
131     {
132      gSystem->Rename(mergedFileForPreviousCycle->Data(),mergedFileName.Data());
133     }     
134    } else
135      {
136       TString *mergedFileForPreviousCycle = new TString("mergedCycle"); 
137       (*mergedFileForPreviousCycle)+=((Int_t)fileCounter/cycle);
138       (*mergedFileForPreviousCycle)+=".root";         
139       if(gROOT->GetVersionDate()>=20100404) // to be improved - removed eventually (this is temporary protection)
140       {  
141        fileMerger->AddFile(mergedFileForPreviousCycle->Data(),kFALSE);
142       } else
143         {
144          fileMerger->AddFile(mergedFileForPreviousCycle->Data());      
145         }      
146       // Delete merged output from previous cycle:
147       TSystemFile *file = new TSystemFile(mergedFileForPreviousCycle->Data(),baseDirPath->Data());
148       file->Delete();
149       delete file;
150       fileMerger->OutputFile(mergedFileName.Data());
151       fileMerger->Merge();
152       delete mergedFileForPreviousCycle;
153      }
154  delete fileMerger;
155  delete baseDirPath;
156  
157  if(!(gSystem->AccessPathName(mergedFileName.Data(),kFileExists)) && fileCounter > 0)
158  {
159   cout<<endl;
160   cout<<" Merging went successfully: "<<fileCounter<<" files \""<<outputFileName.Data()<<"\" were"<<endl;
161   cout<<" merged into the newly created file \""<<mergedFileName.Data()<<"\"."<<endl;
162   cout<<endl;
163   cout<<" Launch now macro redoFinish.C to get the correct final results."<<endl;
164  } else
165    {
166     cout<<" WARNING: Merging failed miserably !!!!"<<endl;
167    }   
168    
169  cout<<endl;
170  timer.Stop();
171  timer.Print(); 
172  cout<<endl;
173
174 } // end of void mergeOutputOnGrid(const char* gridPath = "...")
175
176 // ===================================================================================
177
178 void CrossCheckUserSettings()
179 {
180  // Cross-check user settings before starting:
181  
182  if(cycle>100)
183  {
184   cout<<endl;
185   cout<<" WARNING: Cycle is too big !!!!"<<endl; 
186   cout<<"          Set \"const Int_t cycle\" to smaller value in the macro."<<endl;
187   cout<<endl;
188   exit(0);
189  }
190
191 } // void CrossCheckUserSettings()