]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/FORWARD/analysis2/trains/runMain.cxx
579dc5319d7d6ca1550b83a1d1a525edca66c6d5
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / trains / runMain.cxx
1 /**
2  * @file   runMain.cxx
3  * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
4  * @date   Fri Jun  1 13:56:29 2012
5  * 
6  * @brief  
7  * 
8  * @ingroup pwglf_forward_trains
9  * 
10  */
11 /** 
12  * @defgroup pwglf_forward_trains_run Execute train
13  *
14  * Code for program to run trains 
15  *
16  * @ingroup pwglf_forward_trains
17  */
18 #include "FORWARD/analysis2/trains/TrainSetup.C"
19 #include <TSystem.h>
20 #include <TROOT.h>
21 #include <TString.h>
22 #include <TApplication.h>
23
24 /** 
25  * Build the train setup script 
26  * 
27  * @param script Script name 
28  * @param useTmp Whether to use temporary directory
29  * @param useDbg Build class with debug symbols
30  * 
31  * @return true on success
32  * 
33  * @ingroup pwglf_forward_trains_run
34  */
35 Bool_t BuildTrain(const char* script, 
36                   Bool_t useTmp=false,
37                   Bool_t useDbg=false)
38 {
39   // --- Load needed libraries ---------------------------------------
40   gROOT->LoadClass("TAlien",               "libRAliEn");
41   gROOT->LoadClass("TVirtualMC",           "libVMC");
42   gROOT->LoadClass("AliVEvent",            "libSTEERBase");
43   gROOT->LoadClass("AliESDEvent",          "libESD");
44   gROOT->LoadClass("AliAODEvent",          "libAOD");
45   gROOT->LoadClass("AliAnalysisManager",   "libANALYSIS");
46   gROOT->LoadClass("AliAnalysisTaskSE",    "libANALYSISalice");
47
48   // --- Setup script path -------------------------------------------
49   const char* aliPath   = gSystem->ExpandPathName("$ALICE_ROOT");
50   const char* fwd2Path  = 
51     gSystem->ExpandPathName("$ALICE_ROOT/PWGLF/FORWARD/analysis2");
52   const char* macroPath = gROOT->GetMacroPath();
53   gROOT->SetMacroPath(Form(".:%s:%s/trains:%s/scripts",
54                            macroPath,fwd2Path,fwd2Path));
55   
56   // --- Setup include path ------------------------------------------
57   gSystem->AddIncludePath(Form("-I%s", fwd2Path));
58   gSystem->AddIncludePath(Form("-I%s/trains", fwd2Path));
59   gSystem->AddIncludePath(Form("-I%s", aliPath));
60   gSystem->AddIncludePath(Form("-I%s/include", aliPath));
61
62   // --- Check that we can find the script ---------------------------
63   TString path = gSystem->Which(gROOT->GetMacroPath(), script);
64   if (path.IsNull()) { 
65     path = gSystem->Which(gROOT->GetMacroPath(), Form("%s.C", script));
66     if (path.IsNull()) { 
67       Error("BuildTrain", "Cannot find script %s or %s.C in %s", 
68             script, script, gROOT->GetMacroPath());
69       return false;
70     }
71   }
72   // --- Possibly make a temporary copy ------------------------------
73   if (useTmp) { 
74     TString tmp("Train");
75     FILE*   fp = gSystem->TempFileName(tmp, ".");
76     fclose(fp);
77     gSystem->Unlink(tmp);
78     tmp.Append(".C");
79     
80     gSystem->CopyFile(path, tmp);
81     path = tmp;
82   }
83
84   // --- Now compile the thing ---------------------------------------
85   // Info("BuildTrain", "Building macro %s (ACLiC mode: +%s)", path.Data(),
86   //      useDbg ? "+g" : "");
87   Int_t ret = gROOT->LoadMacro(Form("%s+%s", path.Data(), useDbg ? "+g" : ""));
88
89   // --- If we did a temporary file, remove stuff --------------------
90   if (useTmp) {
91     gSystem->Unlink(path);
92     path.ReplaceAll(".C",   "_C.d");  gSystem->Unlink(path);
93     path.ReplaceAll("_C.d", "_C.so"); gSystem->Unlink(path);
94   }
95
96   // --- Warning in case of problems ---------------------------------
97   if (ret != 0) 
98     Warning("BuildTrain", "Failed to build %s (%s)", path.Data(), script);
99
100   return ret == 0;  
101 }
102 /** 
103  * Make the train setup object 
104  * 
105  * @param trainClass Class-name of the train setup 
106  * @param trainName  Name of the train. 
107  * 
108  * @return Newly allocated object or null
109  * 
110  * @ingroup pwglf_forward_trains_run
111  */
112 TrainSetup* MakeTrain(const char* trainClass, const char* trainName)
113 {
114   // Info("MakeTrain", "Making an object of class %s named '%s'", 
115   //      trainClass, trainName);
116   Long_t ret = gROOT->ProcessLine(Form("new %s(\"%s\")",trainClass,trainName));
117   if (!ret) 
118     Warning("MakeTrain", "Failed to make object of class %s", trainClass);
119
120   return reinterpret_cast<TrainSetup*>(ret);
121 }
122
123 /** 
124  * Append an element to a list 
125  * 
126  * @param str String to append to 
127  * @param val Value to append
128  * @param sep Separator
129  * 
130  * @ingroup pwglf_forward_trains_run
131  */
132 void AppendTo(TString& str, const TString& val, const char* sep=",")
133 {
134   if (!str.IsNull()) str.Append(sep);
135   // Info("", "Appending %s to %s", val.Data(), str.Data());
136   str.Append(val);
137 }
138 /** 
139  * Append directory to header and script search path
140  * 
141  * @param dir Directory
142  * 
143  * @ingroup pwglf_forward_trains_run
144  */
145 void AppendPath(const char* dir)
146 {
147   gROOT->SetMacroPath(Form("%s:%s",gROOT->GetMacroPath(), dir));
148   gSystem->AddIncludePath(Form("-I%s", dir));
149 }
150 /** 
151  * Print a fake option description.  Used for options specific to this
152  * program.
153  * 
154  * @param o    Output stream 
155  * @param opt  Option (including meta argument)
156  * @param desc Option description.
157  * 
158  * @ingroup pwglf_forward_trains_run
159  */
160 void PrintFakeOption(std::ostream& o, const char* opt, const char* desc)
161 {
162   o << "  --" << std::left << std::setw(30) << opt << " " << desc << std::endl;
163 }
164
165 /** 
166  * Print usage information 
167  * 
168  * @param progname Program name 
169  * @param o        Output stream
170  * @param r        Optional runner. 
171  * 
172  * @ingroup pwglf_forward_trains_run
173  */
174 void Usage(const char* progname, std::ostream& o, TrainSetup::Runner* r)
175 {
176   o << "Usage: " << progname << " --class=CLASS --name=NAME [OPTIONS]\n\n"
177     << "PROGRAM OPTIONS:\n";
178   PrintFakeOption(o, "class=CLASS", "Train class");
179   PrintFakeOption(o, "name=NAME",   "Name of train");
180   PrintFakeOption(o, "events=NUMBER", "Max number of events to analyse");
181   PrintFakeOption(o, "run=RUN",       "Comma separated list of runs");
182   PrintFakeOption(o, "tmp",           "Copy code to temporary directory");
183   PrintFakeOption(o, "debug",         "Create debugging symbols");
184   PrintFakeOption(o, "include=DIRECTORY", "Append dir to macro/header path");
185   PrintFakeOption(o, "gui",           "Enable graphics");
186   if (!r) { 
187     o << "\n"
188       << "Additional options may be defined by the specific train setup\n"
189       << std::endl;
190     return;
191   }
192   o << "\nTRAIN OPTIONS:" << std::endl;
193   r->PrintHelp(o, "--");
194   o << "\n"
195     << "The options --run and --include may be passed multiple times\n"
196     << "Options --debug and --tmp toggle, so pass only once\n"
197     << "For any other option, the last value passed is used\n"
198     << std::endl;
199 }    
200
201 /** 
202  * Run a given analysis train 
203  * 
204  * @verbatim
205 Usage: runTrain --class=CLASS --name=NAME [OPTIONS]
206
207 OPTIONS:
208   --class=CLASS                    Train class
209   --name=NAME                      Name of train
210   --run=RUN                        Comma separated list of runs
211   --tmp                            Copy class script to temporary directory
212   --help                           Show this help
213   --par                            Use PAR files (PROOF and Grid)
214   --mc                             Assume simulation input
215   --debug                          Execute in debugger
216   --type=AOD|ESD                   Type of train
217   --mode=LOCAL|PROOF|GRID          Execution mode
218   --oper=TEST|TERMINATE|FULL|INIT  Operation mode
219   --date=YYYY-MM-DD HH:MM:SS       Set date string
220   --cluster=HOST                   PROOF cluster
221   --dataSet=NAME                   Data set (PROOF only)
222   --dataDir=DIRECTORY              Data directory
223   --pass=NUMBER                    ESD Pass (grid only)
224   --verb=NUMBER                    Verbosity
225   --root=TAG                       ROOT version (Grid)
226   --aliroot=TAG                    AliROOT version (Grid)
227   --alien=TAG                      AliEn API version (Grid)
228   --overwrite                      Allow overwrite
229   --include=DIRECTORY              Append dir to macro/header path
230   @endverbatim
231  * 
232  * Individual classes derived from TrainSetup may define additional
233  * (or less) options.  Pass the option @b --help to see the list of
234  * available options
235  *
236  * Usually, the train defines the execution mode (ESD or AOD) and the
237  * option @b --type should not be given
238  *
239  * If a date is set (option @b --date) either to a string of the form 
240  * @c YYYY-MM-DD HH:MM:SS or to the string @c now, then the date will be 
241  * appended to the job name. 
242  * 
243  * A sub-directory named according to the name passed will be made,
244  * and relevant files will copied there.
245  * 
246  * @param argc Count of command line arguments, including program name
247  * @param argv Vector of command line arguments, including program name
248  *  
249  * @return 0 on success, 1 otherwise 
250  * 
251  * @ingroup pwglf_forward_trains_run
252  */
253 int main(int argc, char** argv)
254 {
255   TString trainOpts;
256   TString trainClass;
257   TString trainName; 
258   TString trainRuns; 
259   Int_t   trainEvents = -1;
260   Bool_t  trainTmp = false;
261   Bool_t  trainDbg = false;
262   Bool_t  progHelp = false;
263   Bool_t  gui      = false;
264
265   for (int i = 1; i < argc; i++) { 
266     // std::cout << "Arg # " << i << ": \"" << argv[i] << "\"" << std::endl;
267     if (argv[i][0] == '-') { 
268       if (argv[i][1] == '-') { // Long options 
269         TString arg(argv[i]);
270         arg.ReplaceAll("\"'", "");
271         Int_t   eq = arg.Index("=");
272         TString val;
273         if (eq != kNPOS) val = arg(eq+1,arg.Length()-eq-1);
274         if      (arg.BeginsWith("--class"))   trainClass  = val;
275         else if (arg.BeginsWith("--name"))    trainName   = val;
276         else if (arg.BeginsWith("--events"))  trainEvents = val.Atoi();
277         else if (arg.BeginsWith("--run"))     AppendTo(trainRuns, val);
278         else if (arg.BeginsWith("--tmp"))     trainTmp = !trainTmp;
279         else if (arg.BeginsWith("--debug"))   trainDbg = !trainDbg;
280         else if (arg.BeginsWith("--include")) AppendPath(val);
281         else if (arg.BeginsWith("--help"))    progHelp=true; 
282         else if (arg.BeginsWith("--gui"))     gui=true;
283         else    AppendTo(trainOpts, arg(2,arg.Length()-2)); 
284       }
285       else {
286         switch (argv[i][1]) { 
287         case 'h': progHelp    = true; break;
288         case 'c': trainClass  = argv[++i]; break;
289         case 'n': trainName   = argv[++i]; break;
290         case 'N': trainEvents = strtol(argv[++i],  NULL, 0); break;
291         case 't': trainTmp    = !trainTmp; break;
292         case 'd': trainDbg    = !trainDbg; break;
293         case 'r': AppendTo(trainRuns, argv[++i]); break;
294         case 'I': AppendPath(argv[++i]); break;
295         case 'g': gui         = true; break;
296         default: 
297           Error("runMain", "Unknown option %s", argv[i]);
298           return 1;
299         } // switch 
300       } // Long options 
301     } // Options 
302   }
303
304   if (trainClass.IsNull() || trainName.IsNull()) { 
305     if (progHelp) {
306       Usage(argv[0], std::cout, 0);
307       return 0;
308     }
309     Error(argv[0], "No train-setup class name or train name given");
310     return 1;
311   }
312   if (trainDbg) AppendTo(trainOpts, "debug");
313   if (progHelp) AppendTo(trainOpts, "help");
314
315   // Make an application 
316   TApplication* app = 0;
317   if (gui) {
318     Info("", "Making an application and initializing graphics");
319     gROOT->SetBatch(false);
320     app = new TApplication("runtrain", 0, 0);
321     app->InitializeGraphics();
322   }
323   
324   // Build the code 
325   if (!BuildTrain(trainClass, trainTmp, trainDbg)) return 1;
326   
327   // Make our object 
328   TrainSetup* trainSetup = MakeTrain(trainClass, trainName);
329   if (!trainSetup) return 1;
330
331   TrainSetup::Runner r(*trainSetup);
332   if (!r.Init(trainOpts)) return 1;
333   if (r.IsHelpAsked()) { 
334     Usage(argv[0], std::cout, &r);
335     return 0;
336   }
337
338   return r.Run(trainRuns, trainEvents, true) ? 0 : 1;
339 }
340 //
341 // EOF
342 //
343
344   
345   
346