]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/trains/Helper.C
Mega commit of many changes to PWGLFforward
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / trains / Helper.C
CommitLineData
fdfd93b4 1/**
2 * @defgroup pwglf_forward_trains_helper Analysis helpers
3 *
4 * @ingroup pwglf_forward_trains
5 *
6 *
7 */
8/**
9 * @file Helper.C
10 * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
11 * @date Tue Oct 16 19:00:17 2012
12 *
13 * @brief Base class for analysis helpers
14 *
15 * @ingroup pwglf_forward_trains_helper
16 *
17 */
18#ifndef TRAIN_HELPER_C
19#define TRAIN_HELPER_C
20#ifndef __CINT__
21# include "Option.C"
22# include <TUrl.h>
23# include <TString.h>
24# include <TMap.h>
25# include <TObjString.h>
26# include <TSystem.h>
27# include <TROOT.h>
28# include <TError.h>
29# include <TObjArray.h>
ddcc1bbd 30# include <TFile.h>
fdfd93b4 31# include <AliAnalysisManager.h>
32# include <iostream>
33#else
34class TString;
35class TUrl;
36class TMap;
37class Option;
38class OptionList;
39#endif
40
41/**
42 * Helper class to set-up an analysis using a train
43 *
44 * @ingroup pwglf_forward_trains_helper
45 */
46struct Helper
47{
48 enum EMode {
49 kLocal,
50 kProof,
51 kGrid
52 };
53 enum EOperation {
54 kTest,
55 kOffline,
56 kSubmit,
57 kTerminate,
58 kFull
59 };
60 enum EInput {
61 kESD,
62 kAOD,
63 kUser
64 };
65 Helper(const Helper& o)
66 : fUrl(o.fUrl), fOptions(o.fOptions), fVerbose(o.fVerbose)
67 {}
68 Helper& operator=(const Helper&) { return *this; }
69 /**
70 * Create a helper object.
33438b4c 71 *
72 * @param verbose Verbosity
fdfd93b4 73 * @param url Url describing the job.
74 *
75 * - Local mode:
76 *
77 * @code
78 * local://<path>[#<treeName>][?[recursive[&]]]
79 * @endcode
80 *
81 * &lt;path&gt; can be a single ROOT file, a text file with one
82 * entry per file to add to the chain, or a directory containing the
83 * files. If &lt;path&gt; does not start with a '/' then it is
84 * interpreted as a relative path.
85 *
86 * - Grid mode:
87 *
88 * @code
89 * alien:///<path>#<pattern>
90 * @endcode
91 *
92 * - PROOF mode:
93 *
94 * Several options
95 *
96 * @code
97 * lite:///<path>[?[recursive[&]][workers=<n>]][#treeName]
98 * proof:///<path>[?[recursive[&]][workers=<n>]][#treeName]
99 * @endcode
100 *
101 * @code
102 * proof://<host>/<dsname>[?[workers=<n>[&]][dsname[=<outname>]]][#treeName]
103 * @endcode
104 *
105 * Note, if &lt;host&gt; is recognised as an Alice Analysis
106 * Facility, then the Grid handler (AliAnalysisAlien) is used unless
107 * the option <tt>plain</tt> was given.
108 *
109 * @return Newly allocated helper or null
110 */
111 static Helper* Create(const TUrl& url, Int_t verbose=0);
112 /**
113 * Load a library
114 *
115 * @param name Name of library
116 * @param slave If true also load on slaves
117 *
118 * @return true on success, false otherwise
119 */
120 virtual Bool_t LoadLibrary(const TString& name,
121 Bool_t slave=true) = 0;
122 /**
123 * Load a source file, and compile it
124 *
125 * @param name Name of the source file
ddcc1bbd 126 * @param copy Copy rather than link
fdfd93b4 127 *
128 * @return true on success
129 */
ddcc1bbd 130 virtual Bool_t LoadSource(const TString& name, bool copy=false)
fdfd93b4 131 {
ddcc1bbd 132 if (!AuxFile(name, copy)) return false;
fdfd93b4 133 TString base(gSystem->BaseName(name));
73b32206 134 gROOT->ProcessLine("gSystem->RedirectOutput(\"build.log\",\"a\");");
fdfd93b4 135 gROOT->LoadMacro(Form("%s++g", base.Data()));
73b32206 136 gROOT->ProcessLine("gSystem->RedirectOutput(0);");
fdfd93b4 137 return true;
138 }
139 /**
140 * Load auxillary file - not compiled or sourced. Just copied to
141 * working directory
142 *
143 * @param name Extra file name
ddcc1bbd 144 * @param copy Copy rather than link
fdfd93b4 145 *
146 * @return true on success
147 */
ddcc1bbd 148 virtual Bool_t LoadAux(const TString& name, Bool_t copy=false)
fdfd93b4 149 {
ddcc1bbd 150 if (!AuxFile(name, copy)) return false;
fdfd93b4 151 return true;
152 }
153
154 /**
155 * Load needed ROOT libaries
156 */
157 virtual Bool_t LoadROOT()
158 {
159 if (gSystem->Load("libTree.so") < 0) return false;
160 if (gSystem->Load("libGeom.so") < 0) return false;
161 if (gSystem->Load("libVMC.so") < 0) return false;
162 if (gSystem->Load("libPhysics.so") < 0) return false;
163 if (gSystem->Load("libMinuit.so") < 0) return false;
164 return true;
165 }
166 /**
167 * Set-up to load the AliROOT libraries
168 *
fdfd93b4 169 * @return true on success
170 */
171 virtual Bool_t LoadAliROOT()
172 {
173 if (!gSystem->Getenv("ALICE_ROOT")) {
174 Error("Helper::LoadAliROOT", "Local AliROOT not available");
175 return false;
176 }
177 if (!LoadLibrary("STEERBase")) return false;
178 if (!LoadLibrary("ESD")) return false;
179 if (!LoadLibrary("AOD")) return false;
180 if (!LoadLibrary("ANALYSIS")) return false;
181 if (!LoadLibrary("OADB")) return false;
182 if (!LoadLibrary("ANALYSISalice")) return false;
183 return true;
184 }
185 /**
186 * Get the execution mode
187 *
188 * @return Execution mode set in set-up URL
189 */
190 virtual UShort_t Mode() const = 0;
024ec5ac 191 /**
192 * Get the mode string used for AliAnalysisManager::StartAnalysis
193 */
194 virtual const char* ModeString() const { return "unknown"; }
fdfd93b4 195 /**
196 * Get the operation - this only makes sense for Grid jobs
197 *
198 * @return Operation type
199 */
200 virtual UShort_t Operation() const { return kFull; }
201 /**
202 * Get the input data type
203 *
204 * @return Input data type
205 */
206 virtual Short_t InputType() const
207 {
208 UShort_t ret = DeduceType(fUrl.GetAnchor());
209 if (ret != kUser) return ret;
210
211 if (fOptions.Has("pattern")) ret = DeduceType(fOptions.Get("pattern"));
212 if (ret != kUser) return ret;
213
214 ret = DeduceType(fUrl.GetFile());
215 return ret;
216 }
a54cc77b 217 /**
218 * Check if the MC option was set
219 *
220 * @return true if the MC option was given
221 */
222 virtual Bool_t IsMC() const { return fOptions.Has("mc"); }
fdfd93b4 223 /**
224 * The file part of tehe output URL - overwritten by derived classes.
225 *
226 *
227 * @return File part of output URL
228 */
229 virtual TString OutputPath() const { return ""; }
230 /**
231 * Get the location of the output data. Use ful to define second pass
232 * scripts, etc.
233 *
234 *
235 * @return Url string
236 */
237 virtual TString OutputLocation() const
238 {
239 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
240 if (!mgr || !mgr->GetOutputEventHandler()) return "";
241
242 TString path(OutputPath());
243 if (path.IsNull()) {
244 path = gSystem->WorkingDirectory();
245 // mgr->GetName();
246 }
247
248 TUrl u(fUrl);
249 u.SetFile(path);
250 u.SetAnchor("aodTree");
251 TString opt(u.GetOptions());
252 opt.ReplaceAll("AliESDs", "AliAOD");
253 u.SetOptions(opt);
254
255 return u.GetUrl();
256 }
257 /**
258 * Set-up done before task setup
259 *
260 * @return true on success
261 */
262 virtual Bool_t PreSetup() = 0;
263 /**
264 * Set-up done after task setup
265 *
266 * @return true on success
267 */
268 virtual Bool_t PostSetup() = 0;
269 /**
270 * Run the analysis
271 *
272 * @param nEvents Number of events to analyse
273 *
274 * @return The return value of AliAnalysisManager::StartAnalysis
275 */
276 virtual Long64_t Run(Long64_t nEvents=-1) = 0;
277 /**
278 * Print information to standard output
279 *
fdfd93b4 280 * @return
281 */
282 virtual void Print(Option_t* ="") const
283 {
284 std::cout << "Url: " << fUrl.GetUrl() << std::endl;
285 fOptions.Show(std::cout);
286 }
287 /**
288 * @return URL help string
289 */
290 virtual const Char_t* UrlHelp() const = 0;
291 /**
292 * @return Short description string
293 */
294 virtual const char* Desc() const = 0;
295 /**
296 * Get the input URL
297 *
298 * @return Input URL
299 */
300 const TUrl& Url() const { return fUrl; }
301 /**
302 * Get the list of options
303 *
304 * @return Reference to list of options
305 */
306 const OptionList& Options() const { return fOptions; }
a80dde0d 307 /**
308 * Write auxillary ROOT (and possible shell) script for more
309 * (post-)processing e.g., terminate
310 *
a80dde0d 311 */
312 virtual void AuxSave(const TString& /*escaped*/,
313 Bool_t /*asShellScript*/) {}
fdfd93b4 314 /**
315 * Create an instance of a helper class
316 */
317 static Helper* CreateObject(const TString& cl,
318 const TUrl& url,
319 Int_t verbose=0)
320 {
73b32206 321 if (verbose < 3) gSystem->RedirectOutput("/dev/null","w");
fdfd93b4 322 if (cl.Contains("proof", TString::kIgnoreCase) ||
323 cl.Contains("lite", TString::kIgnoreCase) ||
324 cl.Contains("aaf", TString::kIgnoreCase)) {
325 gSystem->Load("libProof");
326 gSystem->Load("libProofPlayer");
327 }
8449e3e0 328 // (Always) recompile and with debug symbols
329 gROOT->LoadMacro(Form("%s.C+g",cl.Data()));
fdfd93b4 330 Long_t ptr = gROOT->ProcessLine(Form("new %s(\"%s\", %d);",
331 cl.Data(), url.GetUrl(), verbose));
73b32206 332 if (verbose < 3) gSystem->RedirectOutput(0);
fdfd93b4 333 if (!ptr) {
334 Warning("Helper::CreateObject", "Failed to instantize a %s", cl.Data());
335 return 0;
336 }
337 Helper* h = reinterpret_cast<Helper*>(ptr);
338 return h;
339 }
340 /**
341 * Show help on URL using the interpreter
342 *
343 * @param cl Helper class
344 */
345 static void ShowUrlHelp(const TString& cl)
346 {
347 Helper* h = CreateObject(cl, "", true);
348 if (!h) return;
349
350 std::cout << " " << h->UrlHelp() << std::endl;
351 }
352 /**
353 * Show help on URL and options using the interpreter
354 *
355 * @param cl Helper class
356 */
357 static void ShowFullHelp(const TString& cl)
358 {
359 Helper* h = CreateObject(cl, "", true);
360 if (!h) return;
361
362 std::cout << h->Desc() << ":\n"
363 << "==============\n"
364 << " " << h->UrlHelp() << "\n\n"
365 << "Options: " << std::endl;
366 h->Options().Help(std::cout);
367 std::cout << std::endl;
368 }
369protected:
370 /**
371 * Constructor
372 *
373 * @param url Set-up URL
33438b4c 374 * @param verbose Verbosity level
fdfd93b4 375 */
376 Helper(const TUrl& url, Int_t verbose)
377 : fUrl(url), fOptions(), fVerbose(verbose)
378 {
a54cc77b 379 fOptions.Add("mc", "Assume simulation input");
fdfd93b4 380 }
381
382 virtual Bool_t ParseOptions()
383 {
024ec5ac 384 //std::cout << "Url options: \"" << fUrl.GetOptions() << "\"" << std::endl;
fdfd93b4 385 return fOptions.Parse(fUrl.GetOptions(), "&");
386 }
387 /**
388 * Destructor
389 */
390 virtual ~Helper()
391 {
392 }
393 /**
394 * Normalize a library name
395 *
396 * @param name
397 *
398 * @return
399 */
400 const TString& MakeLibraryName(const TString& name)
401 {
402 static TString libName;
403
404 libName = name;
405
406 if (!libName.BeginsWith("lib")) {
407 // Check if the library corresponds to a compiled macro
408 if (!gSystem->AccessPathName(Form("%s_C.so", libName.Data())))
409 libName.Append("_C");
410 else if (!gSystem->AccessPathName(Form("../%s_C.so", libName.Data())))
411 libName = Form("../%s_C", libName.Data());
412 else
413 libName = Form("lib%s", libName.Data());
414 }
415 if (!libName.EndsWith(".so")) libName.Append(".so");
416
417 return libName;
418 }
419 /**
420 * Link an auxilary file to working directory
421 *
422 * @param name Name of the file
33438b4c 423 * @param copy Copy rather than link
ddcc1bbd 424 *
fdfd93b4 425 * @return true on success
426 */
ddcc1bbd 427 virtual Bool_t AuxFile(const TString& name, bool copy=false)
fdfd93b4 428 {
429 TString path(gSystem->ExpandPathName(name.Data()));
430 // If not absolute, prepend up-one
431 if (!path.BeginsWith("/")) path.Prepend("../");
432 if (gSystem->AccessPathName(path.Data())) {
433 // File not accessible
46b25775 434 Warning("Helper::AuxFile", "File %s not accessible", path.Data());
fdfd93b4 435 return false;
436 }
46b25775 437 TString base(gSystem->BaseName(path.Data()));
438 if (gSystem->AccessPathName(base.Data()) == 0) {
439 // File or link exists - remove it
440 if (gSystem->Unlink(base) != 0) {
441 Error("Helper::AuxFile", "Failed to remove old %s", base.Data());
442 return false;
443 }
444 }
ddcc1bbd 445 if (copy)
446 TFile::Cp(path, base);
447 else
448 gSystem->Exec(Form("ln -s %s .", path.Data()));
fdfd93b4 449 return true;
450 }
451 /**
452 * Deduce the top of job from a string
453 *
454 * @param str String
455 *
456 * @return Job type
457 */
458 static UShort_t DeduceType(const TString& str)
459 {
460 if (str.IsNull()) return kUser;
461 if (str.Contains("aod", TString::kIgnoreCase)) return kAOD;
462 if (str.Contains("esd", TString::kIgnoreCase)) return kESD;
463 return kUser;
464 }
465 // --- Data members ------------------------------------------------
466 TUrl fUrl; // The URI
467 OptionList fOptions;
468 Int_t fVerbose;
469};
470
471
472
473
474// ===================================================================
475Helper*
476Helper::Create(const TUrl& url, Int_t verbose)
477{
478 if (!url.IsValid()) {
479 Warning("Helper::Create", "URL is invalid");
480 return 0;
481 }
482
483 TString prot(url.GetProtocol());
484 prot.ToLower();
485
486 TUrl tmp(url);
487 TString opts(tmp.GetOptions());
488 TString host(url.GetHost());
489 TString cl = "";
490 if (prot.EqualTo("alien")) {
491 // Create an AliEn helper
492 cl = "GridHelper";
493 }
494 else if (prot.EqualTo("local")) {
495 // Create Lite helper
496 cl = "LocalHelper";
497 }
498 else if (prot.EqualTo("proof")) {
499 // Create a Proof helper
500 if (host.IsNull())
501 cl = "LiteHelper";
502 else if (host.BeginsWith("alice-caf")) {
503 // AAF
504 cl = opts.Contains("plugin") ? "AAFPluginHelper" : "AAFHelper";
505 }
506 else
507 cl = "ProofHelper";
508 }
509 else if (prot.EqualTo("lite")) {
510 // Create a Proof helper
511 cl = "LiteHelper";
512 }
513 else if (prot.EqualTo("help")) {
514 // Special HELP protocol
515 if (host.Contains("options")) {
516 std::cout << "Possible URL types and options are:" << std::endl;
517 ShowFullHelp("LocalHelper");
518 ShowFullHelp("ProofHelper");
519 ShowFullHelp("LiteHelper");
520 ShowFullHelp("AAFHelper");
521 ShowFullHelp("AAFPluginHelper");
522 ShowFullHelp("GridHelper");
523 return 0;
524 }
525 std::cout << "Possible URL types are:" << std::endl;
526 ShowUrlHelp("LocalHelper");
527 ShowUrlHelp("ProofHelper");
528 ShowUrlHelp("LiteHelper");
529 ShowUrlHelp("AAFHelper");
530 ShowUrlHelp("AAFPluginHelper");
531 ShowUrlHelp("GridHelper");
532 return 0;
533 }
534 // --- Check if we got a scheme ------------------------------------
535 if (cl.IsNull()) {
536 Error("Helper::Create", "Unknown scheme: %s", prot.Data());
537 return 0;
538 }
539
540 // --- Use interpreter to make our object --------------------------
541 Helper* helper = CreateObject(cl, url, verbose);
542 if (!helper) {
543 Error("Helper::Create", "Failed to make object of class %s", cl.Data());
544 return 0;
545 }
546
547 // --- Parse options -----------------------------------------------
548 if (!helper->ParseOptions()) {
549 delete helper;
550 helper = 0;
551 }
552
553 return helper;
554}
555
556#endif