Changed scripts for new TrainSetup
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / trains / TrainSetup.C
CommitLineData
fdfd93b4 1/**
2 * @defgroup pwglf_forward_trains Trains
3 *
4 * Train specifications
5 *
6 * @ingroup pwglf_forward
7 */
8/**
9 * @file TrainSetup.C
10 * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
11 * @date Tue Oct 16 17:56:57 2012
12 *
13 * @brief Base classs for train specifications
14 *
15 * @ingroup pwglf_forward_trains
16 */
17#ifndef TRAINSETUP_C
18#define TRAINSETUP_C
19#ifndef __CINT__
20# include "Helper.C"
21# include "Option.C"
22# include <TDatime.h>
23# include <TUrl.h>
24# include <TString.h>
25# include <TApplication.h>
ddcc1bbd 26# include <TStopwatch.h>
fdfd93b4 27# include <AliAnalysisManager.h>
28# include <AliVEventHandler.h>
29# include <AliPhysicsSelection.h>
30# include <AliPhysicsSelectionTask.h>
31# include <AliCentralitySelectionTask.h>
32# include <AliESDInputHandler.h>
33# include <AliAODInputHandler.h>
34# include <AliAODHandler.h>
35# include <AliMCEventHandler.h>
46b25775 36# include <ctime>
fdfd93b4 37#else
38struct Helper;
39struct OptionList;
40class TDatime;
41class TUrl;
42class TString;
ddcc1bbd 43class TStopwatch;
fdfd93b4 44class AliVEventHandler;
45class AliAnalysisManager;
46class AliInputEventHandler;
47#endif
48
49//====================================================================
50/**
ddcc1bbd 51 * Generic set-up of an analysis train
fdfd93b4 52 *
53 * See also @ref train_setup_doc
54 *
55 * @ingroup pwglf_forward_trains
56 *
57 */
58struct TrainSetup
59{
60 /**
61 * Constructor
62 *
63 * @param name Name of the train
64 */
65 TrainSetup(const TString& name)
66 : fName(name),
67 fEscapedName(name),
46b25775 68 fOptions(),
fdfd93b4 69 fHelper(0)
70 {
71 fOptions.Add("help", "Show help");
72 fOptions.Add("date", "YYYY-MM-DD HH:MM", "Set date", "now");
fdfd93b4 73 fOptions.Add("bare-ps", "Use bare physics selection w/o task");
a80dde0d 74 fOptions.Add("verbose", "LEVEL", "Set verbosity level", 0);
75 fOptions.Add("url", "URL", "Job location & input URL");
fdfd93b4 76 fOptions.Add("overwrite", "Allow overwrite");
a80dde0d 77 fOptions.Add("events", "N", "Number of events to analyse", -1);
78 fOptions.Add("type", "ESD|AOD|USER", "Input data stype");
79 fOptions.Add("setup", "Only do the setup");
a54cc77b 80 fOptions.Add("branches", "Load only requested branches");
fdfd93b4 81 fEscapedName = EscapeName(fName, "");
82 }
46b25775 83 TrainSetup(const TrainSetup& o)
84 : fName(o.fName),
85 fEscapedName(o.fEscapedName),
86 fOptions(o.fOptions),
87 fHelper(o.fHelper)
88 {}
89 TrainSetup& operator=(const TrainSetup& o)
90 {
91 if (&o == this) return *this;
92 fName = o.fName;
93 fEscapedName = o.fEscapedName;
94 fOptions = o.fOptions;
95 fHelper = o.fHelper;
96 return *this;
97 }
98
fdfd93b4 99 /**
100 * Destructor
101 */
102 virtual ~TrainSetup() {}
103 /* @} */
104 //__________________________________________________________________
105 /**
106 * @{
107 * @name Execution
108 */
109 /**
110 * Initialize
111 *
112 * @return true on success
113 */
114 Bool_t Init()
115 {
116 // --- Create the helper -----------------------------------------
117 TString url = fOptions.Get("url");
118 Int_t verbose = fOptions.AsInt("verbose");
fdfd93b4 119
120 fHelper = Helper::Create(url.Data(), verbose);
121 if (!fHelper) {
122 Error("Init", "Failed to make the worker for URL %s", url.Data());
123 return false;
124 }
125
46b25775 126 // --- Check the type, if possible -------------------------------
fdfd93b4 127 UShort_t type = fHelper->InputType();
a54cc77b 128 Bool_t mc = fHelper->IsMC();
fdfd93b4 129 if (fOptions.Has("type")) {
130 const TString& it = fOptions.Get("type");
131 if (it.EqualTo("ESD",TString::kIgnoreCase)) type = Helper::kESD;
132 else if (it.EqualTo("AOD",TString::kIgnoreCase)) type = Helper::kAOD;
133 else if (it.EqualTo("user",TString::kIgnoreCase))
134 type = Helper::kUser;
135 }
136
46b25775 137 // --- Rewrite the escpaed name ----------------------------------
138 if (fOptions.Has("date")) {
139 TString date = fOptions.Get("date");
140 fEscapedName = EscapeName(fName, date);
141 }
142
fdfd93b4 143 // --- Get current directory and set-up sub-directory ------------
144 TString cwd = gSystem->WorkingDirectory();
145 if (!SetupWorkingDirectory()) return false;
146
147 // --- Do initial helper setup -----------------------------------
148 if (!fHelper->PreSetup()) return false;
149
150 // --- Load ROOT libraries ---------------------------------------
151 if (!fHelper->LoadROOT()) return false;
152
153 // --- Load AliROOT libraries ------------------------------------
154 if (!fHelper->LoadAliROOT()) return false;
155
156 // --- Create analysis manager -----------------------------------
a80dde0d 157 AliAnalysisManager *mgr = CreateAnalysisManager(fEscapedName);
fdfd93b4 158
159 // In test mode, collect system information on every event
160 // if (oper == kTest) mgr->SetNSysInfo(1);
161 if (verbose > 0) mgr->SetDebugLevel(verbose);
a54cc77b 162 mgr->SetAutoBranchLoading(!fOptions.Has("branches"));
fdfd93b4 163 if (fHelper->Mode() == Helper::kLocal)
164 mgr->SetUseProgressBar(kTRUE, 100);
165
166 // --- ESD input handler ------------------------------------------
167 AliVEventHandler* inputHandler = CreateInputHandler(type);
168 if (inputHandler) mgr->SetInputEventHandler(inputHandler);
169
170 // --- Monte-Carlo ------------------------------------------------
171 AliVEventHandler* mcHandler = CreateMCHandler(type,mc);
172 if (mcHandler) mgr->SetMCtruthEventHandler(mcHandler);
173
174 // --- AOD output handler -----------------------------------------
175 AliVEventHandler* outputHandler = CreateOutputHandler(type);
176 if (outputHandler) mgr->SetOutputEventHandler(outputHandler);
177
178 // --- Include analysis macro path in search path ----------------
179 gROOT->SetMacroPath(Form("%s:%s:$ALICE_ROOT/ANALYSIS/macros",
180 cwd.Data(), gROOT->GetMacroPath()));
181
182 // --- Physics selction - only for ESD ---------------------------
183 if (type == Helper::kESD) CreatePhysicsSelection(mc, mgr);
184
185 // --- Create centrality task ------------------------------------
186 CreateCentralitySelection(mc, mgr);
187
188 // --- Create tasks ----------------------------------------------
189 CreateTasks(mgr);
190
191 // --- Post set-up initialization of helper ----------------------
192 if (!fHelper->PostSetup()) return false;
193
194 // --- Set debug level on defined tasks --------------------------
195 if (verbose > 0) {
196 TIter next(mgr->GetTasks());
197 AliAnalysisTask* sub = 0;
198 while ((sub = static_cast<AliAnalysisTask*>(next()))) {
199 AliAnalysisTaskSE* se = dynamic_cast<AliAnalysisTaskSE*>(sub);
200 if (!se) continue;
201 se->SetDebugLevel(verbose);
202 }
203 }
204
205 // --- Print this setup ------------------------------------------
206 Print();
207
208 // --- Initialise the train --------------------------------------
209 if (!mgr->InitAnalysis()) {
210 gSystem->ChangeDirectory(cwd.Data());
211 Error("Init","Failed to initialise train");
212 return false;
213 }
214
215 // --- Enable progress bar ---------------------------------------
216 if (fHelper->Mode() != Helper::kGrid)
217 mgr->SetUseProgressBar(true, 100);
218
219 // --- Save setup to disk ----------------------------------------
220 SaveSetup(true);
221
ddcc1bbd 222 // --- Some information ------------------------------------------
fdfd93b4 223 mgr->PrintStatus();
ddcc1bbd 224 if (fHelper->Mode() != Helper::kLocal) {
225 TIter next(mgr->GetTasks());
226 AliAnalysisTask* sub = 0;
227 while ((sub = static_cast<AliAnalysisTask*>(next()))) {
228 sub->Print();
229 }
230 }
fdfd93b4 231 return true;
232 }
ddcc1bbd 233 void PrintTimer(TStopwatch& timer, const char* where)
234 {
235 timer.Stop();
236 Double_t t = timer.RealTime();
237 Int_t h = Int_t(t / 3600); t -= h * 3600;
238 Int_t m = Int_t(t / 60); t -= m * 60;
239 if (t < 0) t = 0;
240 Info(where, "took %4d:%02d:%06.3f", h, m, t);
241 }
242
a80dde0d 243 Bool_t Run()
fdfd93b4 244 {
245 TString cwd = gSystem->WorkingDirectory();
246 Bool_t status = false;
ddcc1bbd 247 TStopwatch timer;
248 timer.Start();
fdfd93b4 249 try {
250 if (!Init()) throw TString("Failed to intialize the train");
ddcc1bbd 251 PrintTimer(timer, "Initialization");
252 timer.Continue();
253
a80dde0d 254 // Check if we're asked to only do the setup
255 if (fOptions.Has("setup")) {
256 status = true;
257 throw TString("Only did setup, no running");
258 }
259
fdfd93b4 260 // if (r) SaveSetup(*r, nEvents, asShell);
261
262 Long64_t nEvents = fOptions.AsLong("events", -1);
263 Long64_t ret = fHelper->Run(nEvents);
ddcc1bbd 264 PrintTimer(timer, "Processing");
265 timer.Continue();
fdfd93b4 266
267 // Make sure we go back
268 gSystem->ChangeDirectory(cwd.Data());
269
270 // Return.
271 if (ret < 0) throw TString("Analysis failed");
272
273 status = true;
274 }
275 catch (TString& e) {
a54cc77b 276 if (status) Warning("Run", "%s", e.Data());
277 else Error("Run", "%s", e.Data());
ddcc1bbd 278 }
279 if (fOptions.Has("date")) {
280 TString escaped = EscapeName(fName, "");
281 gSystem->Exec(Form("rm -f last_%s", escaped.Data()));
282 gSystem->Exec(Form("ln -sf %s last_%s",
283 fEscapedName.Data(), escaped.Data()));
fdfd93b4 284 }
ddcc1bbd 285 PrintTimer(timer, "Finish");
286 timer.Continue();
a80dde0d 287 return status;
fdfd93b4 288 }
289 /**
290 * Get the options
291 *
292 *
293 * @return Reference ot the options
294 */
295 OptionList& Options() { return fOptions; }
296 /**
297 * Print information to standard output
298 *
299 */
300 void Print(Option_t* ="") const
301 {
302 std::cout << "Train: " << fName << " (" << fEscapedName << ")"
303 << std::endl;
304 fOptions.Show(std::cout);
305 if (fHelper) fHelper->Print();
306 }
307 /**
308 * Show the help
309 *
310 * @param o
311 *
312 * @return
313 */
314 Bool_t Help(std::ostream& o=std::cout, bool asProg=false)
315 {
316 if (!fOptions.Has("help")) return true;
317
318 if (asProg)
a80dde0d 319 o << "Usage: runTrain2 --name=NAME --class=CLASS [OPTIONS]";
fdfd93b4 320 else
321 o << "Usage: RunTrain(NAME, CLASS, OPTIONS)";
322
323 o << "\n\nOptions:\n\n";
324 if (asProg) {
325 OptionList tmp(fOptions);
326 tmp.Add("name", "STRING", "Name of train", fName);
327 tmp.Add("class", "NAME", "Name of setup class", "");
328 tmp.Help(o," --");
329 }
330 else
331 fOptions.Help(o, " ");
332
333 o << "\n";
334
335 if (!fHelper && fOptions.Has("url")) {
336 TString url = fOptions.Get("url");
337 fHelper = Helper::Create(url.Data());
338 }
339 if (fHelper) {
340 o << fHelper->Desc() << " URL form:\n\n"
341 << " " << fHelper->UrlHelp() << "\n\n"
342 << "Options:\n";
343 fHelper->Options().Help(o, " ");
344 o << "\n";
345 }
346 else {
347 o << "Possible URL forms:\n\n";
348 Helper::ShowUrlHelp("LocalHelper");
349 Helper::ShowUrlHelp("ProofHelper");
350 Helper::ShowUrlHelp("LiteHelper");
351 Helper::ShowUrlHelp("AAFHelper");
352 Helper::ShowUrlHelp("AAFPluginHelper");
353 Helper::ShowUrlHelp("GridHelper");
354 o << "\n";
355 }
356 return false;
357 }
358 /**
359 * Run train. This will AcLic compile the setup script, create
360 * an object of that type with the given name, and then pass the
361 * options to it. Then, it will run the setup.
362 *
363 * @param name Train name
364 * @param cls Class name
365 * @param opts Comma seperated list of options
366 *
367 * @return true on success
368 */
369 static Bool_t Main(const TString& name, const TString& cls,
370 const TCollection* opts,
371 Bool_t asProg=true)
372 {
a80dde0d 373 Bool_t ret = false;
374 try {
375 if (cls.IsNull())
376 throw TString("No class name specified");
377 if (name.IsNull())
378 throw TString("No train name specified");
fdfd93b4 379
a80dde0d 380 Int_t error = 0;
381 Int_t r1 = gROOT->LoadMacro(Form("%s.C++g", cls.Data()), &error);
382 if (r1 < 0 || error)
383 throw TString::Format("Failed to load setup %s: %d", cls.Data(), error);
384
385 // Make our object using the interpreter
386 TString create = TString::Format("new %s(\"%s\")",
387 cls.Data(), name.Data());
388 gROOT->ProcessLine("gSystem->RedirectOutput(\"/dev/null\",\"w\");");
389 Long_t retP = gROOT->ProcessLine(create, &error);
390 gROOT->ProcessLine("gSystem->RedirectOutput(0);");
391 if (!retP || error)
392 throw TString::Format("Failed to make object of class %s: "
393 "0x%08lx/%d\n\t%s",
394 cls.Data(), retP, error, create.Data());
395
396 TrainSetup* train = reinterpret_cast<TrainSetup*>(retP);
fdfd93b4 397
a80dde0d 398 // Now parse the options
399 if (!train->Options().Parse(opts))
400 throw TString("Failed to parse options");
fdfd93b4 401
a80dde0d 402 // Check if we got a help request
403 if (train->Options().Has("help")) {
404 train->Help(std::cout, asProg);
405 ret = true;
406 throw TString("");
407 }
408
409 // return train->Init();
410 ret = train->Run();
411 }
412 catch (TString& e) {
a54cc77b 413 if (!e.IsNull()) Error("Main", "%s", e.Data());
a80dde0d 414 }
415 if (gApplication && asProg) {
416 gSystem->Sleep(3);
417 gApplication->Terminate(ret ? 0 : 1);
fdfd93b4 418 }
a80dde0d 419 return ret;
fdfd93b4 420 }
421protected:
422 //__________________________________________________________________
423 /**
424 * @{
425 * @Name Overloadable behaviour
426 */
427 //------------------------------------------------------------------
428 /**
429 * Create the analysis manager
430 *
431 * @param name Name of the analysis
432 *
433 * @return Created analysis manager
434 */
435 virtual AliAnalysisManager* CreateAnalysisManager(const char* name)
436 {
437 return new AliAnalysisManager(name,"Analysis Train");
438 }
439 //------------------------------------------------------------------
440 /**
441 * Create input handler
442 *
443 * @param type
444 *
445 * @return
446 */
447 virtual AliVEventHandler* CreateInputHandler(UShort_t type)
448 {
449 switch (type) {
450 case Helper::kESD: return new AliESDInputHandler();
451 case Helper::kAOD: return new AliAODInputHandler();
452 case Helper::kUser: return 0;
453 }
454 return 0;
455 }
456 //------------------------------------------------------------------
457 /**
458 * Create MC input handler
459 *
460 * @param type Run type (ESD or AOD)
461 * @param mc Assume monte-carlo input
462 *
463 * @return
464 */
465 virtual AliVEventHandler* CreateMCHandler(UShort_t /*type*/, bool mc)
466 {
467 if (!mc) return 0;
468 AliMCEventHandler* mcHandler = new AliMCEventHandler();
469 mcHandler->SetReadTR(true);
470 return mcHandler;
471 }
472 //------------------------------------------------------------------
473 /**
474 * Create output event handler
475 *
476 * @param type
477 *
478 * @return
479 */
480 virtual AliVEventHandler* CreateOutputHandler(UShort_t type)
481 {
482 AliAODHandler* ret = new AliAODHandler();
483 switch (type) {
484 case Helper::kESD:
485 ret->SetOutputFileName("AliAOD.root");
486 break;
487 case Helper::kAOD:
488 ret->SetOutputFileName("AliAOD.pass2.root");
489 break;
490 case Helper::kUser:
491 break;
492 }
493
494 return ret;
495 }
496 //------------------------------------------------------------------
497 /**
498 * Create physics selection, and add to manager
499 *
500 * @param mc Whether this is for MC
501 * @param mgr Manager
502 */
503 virtual void CreatePhysicsSelection(Bool_t mc, AliAnalysisManager* mgr)
504 {
505 if (fOptions.Has("bare-ps")) {
506 AliInputEventHandler* input =
507 dynamic_cast<AliInputEventHandler*> (mgr->GetInputEventHandler());
508 if (!input) return;
509
510 AliPhysicsSelection* ps = new AliPhysicsSelection();
511 if (mc) ps->SetAnalyzeMC();
512
513 input->SetEventSelection(ps);
514
515 return;
516 }
517 gROOT->Macro(Form("AddTaskPhysicsSelection.C(%d)", mc));
518 mgr->RegisterExtraFile("event_stat.root");
519 }
520 //------------------------------------------------------------------
521 /**
522 * Create centrality selection, and add to manager
523 *
524 * @param mc Whether this is for MC
525 * @param mgr Manager
526 */
527 virtual void CreateCentralitySelection(Bool_t mc, AliAnalysisManager* mgr)
528 {
529 gROOT->Macro("AddTaskCentrality.C");
530 const char* name = "CentralitySelection";
531 AliCentralitySelectionTask* ctask =
532 dynamic_cast<AliCentralitySelectionTask*>(mgr->GetTask(name));
533 if (!ctask) return;
534 if (mc) ctask->SetMCInput();
535 }
536 //------------------------------------------------------------------
537 /**
538 * Create analysis tasks. Must be overloaded by sub-class
539 *
540 * @param mgr Manager
541 */
542 virtual void CreateTasks(AliAnalysisManager* mgr)=0;
543 virtual const Char_t* ClassName() const = 0;
544 /* @} */
545 //__________________________________________________________________
546 /**
547 * @{
548 * @name Utility functions
549 */
550 /**
551 * Escape bad elements of the name
552 *
553 * @param name Name to escape
554 * @param datime Date and Time
555 *
556 * @return escaped name
557 */
558 static TString EscapeName(const char* name, const TString& datimeStr)
559 {
560 TString escaped = name;
561 char c[] = { ' ', '/', '@', 0 };
562 char* p = c;
563 while (*p) {
46b25775 564 char tmp[] = { *p, '\0' };
565 escaped.ReplaceAll(tmp, "_");
fdfd93b4 566 p++;
567 }
568 if (!datimeStr.IsNull()) {
569 TDatime datime;
570 if (datimeStr.EqualTo("now", TString::kIgnoreCase))
571 datime.Set();
46b25775 572 else {
573 // Try various formats
574 struct tm t;
575 const char* formats[] = { "%Ec", // Locale
576 "%c", // Locale
577 "%Ex EX", // Locale
578 "%x %X", // Locale
a80dde0d 579 "%Y%m%d_%H%M", // YYYYMMDD_HHMM
46b25775 580 "%F %R", // ISO standard, no seconds
581 0 };
582 const char** f = formats;
583 Bool_t found = false;
584 while (*f && !found) {
585 // Reset needed fields
586 t.tm_year = 0;
587 t.tm_mon = 0;
588 t.tm_mday = 0;
589 t.tm_hour = 0;
590 t.tm_min = 0;
591 // Stop processing on first match
592 if (strptime(datimeStr.Data(), *f, &t) != 0) found = true;
593 f++;
594 }
a80dde0d 595 if (found) {
596 t.tm_mon += 1; // Return 0-based month
46b25775 597 datime.Set(t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, 0);
a80dde0d 598 }
46b25775 599 }
fdfd93b4 600 if (datime.GetYear() <= 1995 ||
601 datime.GetMonth() == 0 ||
602 datime.GetDay() == 0) return escaped;
603 escaped.Append(Form("_%04d%02d%02d_%02d%02d",
604 datime.GetYear(),
605 datime.GetMonth(),
606 datime.GetDay(),
607 datime.GetHour(),
608 datime.GetMinute()));
609 }
610 return escaped;
611 }
612 /**
613 * Make our working directory if so requested
614 *
615 * @return true on success
616 */
617 Bool_t SetupWorkingDirectory()
618 {
619 // Get the name of the target directory
620 TString& nam = fEscapedName;
621
622 // Check if the directory exists already
623 Bool_t exists = gSystem->AccessPathName(nam.Data()) == 0;
624 if (fHelper->Operation() == Helper::kTerminate && !exists) {
625 Error("SetupWorkingDirectory", "File/directory %s does not exists",
626 nam.Data());
627 return false;
628 }
629
630 Bool_t overwrite = fOptions.Has("overwrite");
631 // If we're not allowed to overwrite, then complain
632 if (!overwrite && exists) {
633 Error("SetupWorkingDirectory", "File/directory %s already exists",
634 nam.Data());
635 return false;
636 }
637
638 // Make the target directory if it doesn't exists
639 if (!exists) {
640 if (gSystem->MakeDirectory(nam.Data())) {
641 Error("SetupWorkingDirectory", "Failed to make directory '%s'",
642 nam.Data());
643 return false;
644 }
645 }
646
647 // Change directory to target directory
648 if (!gSystem->ChangeDirectory(nam.Data())) {
649 Error("SetupWorkingDirectory", "Failed to change directory to %s",
650 nam.Data());
651 return false;
652 }
653 Info("SetupWorkingDirectory", "Made subdirectory %s, and cd'ed there",
654 nam.Data());
655 return true;
656 }
657 /**
658 * Save the setup as a ROOT script and possibly also a shell script
659 *
660 * @param asShellScript If true, also save as shell script
661 */
662 virtual void SaveSetup(Bool_t asShellScript)
663 {
46b25775 664 OptionList tmp(fOptions);
a80dde0d 665 const OptionList* uopts = (fHelper ? &fHelper->Options() : 0);
46b25775 666 if (tmp.Find("overwrite")) tmp.Set("overwrite");
a80dde0d 667 if (tmp.Find("date") && fEscapedName.Length() > fName.Length()+1) {
668 Int_t n = fName.Length()+1;
669 tmp.Set("date", fEscapedName(n, fEscapedName.Length()-n));
670 }
fdfd93b4 671 if (asShellScript)
a80dde0d 672 SaveSetupShell("rerun", ClassName(), fName, tmp, uopts);
673 SaveSetupROOT("ReRun", ClassName(), fName, tmp, uopts);
674 if (fHelper) fHelper->AuxSave(fEscapedName, asShellScript);
fdfd93b4 675 }
676 /**
677 * Save a setup as a shell script
678 *
679 * @param out Output name of shell script
680 * @param cls Class of the train
681 * @param name Name of the train
682 * @param opts Option list
683 */
684 static void SaveSetupShell(const TString& out, const TString& cls,
a80dde0d 685 const TString& name, const OptionList& opts,
686 const OptionList* uopts)
fdfd93b4 687 {
688 std::ofstream o(Form("%s.sh", out.Data()));
689 o << "#!/bin/bash\n\n"
690 << "class=\"" << cls << "\"\n"
691 << "name=\"" << name << "\"\n\n"
692 << "# Available options\n"
693 << "# \n";
694 opts.Help(o, "# --");
a80dde0d 695 if (uopts) {
696 o << "#\n"
697 << "# Available URI options\n"
698 << "# \n";
699 uopts->Help(o, "# ");
700 }
fdfd93b4 701 o << "#\n"
702 << "opts=(--class=$class \\\n"
703 << " --name=$name";
704 opts.Store(o, " \\\n --", "", true);
705 o << ")\n\n"
92f304b1 706 << "echo \"Running runTrain ${opts[@]} $@\"\n"
707 << "runTrain \"${opts[@]}\" $@\n\n"
fdfd93b4 708 << "# EOF" << std::endl;
709 o.close();
710 gSystem->Exec(Form("chmod a+x %s.sh", out.Data()));
711 }
712 /**
713 * Save a setup as a ROOT script
714 *
715 * @param out Output name of shell script
716 * @param cls Class of the train
717 * @param name Name of the train
718 * @param opts Option list
719 */
720 static void SaveSetupROOT(const TString& out, const TString& cls,
a80dde0d 721 const TString& name, const OptionList& opts,
722 const OptionList* uopts)
fdfd93b4 723 {
724 OptionList tmp(opts);
725 tmp.Remove("url");
a80dde0d 726
fdfd93b4 727 std::ofstream o(Form("%s.C", out.Data()));
a80dde0d 728 o << "// Available options:\n"
729 << "// \n";
730 tmp.Help(o, "// ");
731 if (uopts) {
732 o << "// \n"
733 << "// Available URI options\n";
734 uopts->Help(o, "// ");
735 }
736 o << "//\n"
737 << "Bool_t " << out << "()\n"
fdfd93b4 738 << "{\n"
739 << " TString name(\"" << name << "\");\n"
740 << " TString cls(\"" << cls << "\");\n"
a80dde0d 741 << " TUrl uri(\"" << opts.Get("url") << "\");\n"
742 << " \n"
fdfd93b4 743 << " TString opts(";
744 tmp.Store(o, "\"", ",\"\n ", false);
745 o << ");\n\n"
46b25775 746 << " TString path(";
747 TString path(gROOT->GetMacroPath());
748 TObjArray* elements = path.Tokenize(":");
749 TObjString* element = 0;
750 TIter next(elements);
751 while ((element = static_cast<TObjString*>(next()))) {
752 if (element->String().IsNull()) continue;
753 o << "\n \"" << element->GetName() << ":\"";
754 }
755 elements->Delete();
756 o << ");\n"
757 << " path.Append(\"$ALICE_ROOT/PWGLF/FORWARD/trains\");\n"
758 << " gROOT->SetMacroPath(path);\n\n"
fdfd93b4 759 << " gROOT->LoadMacro(\"RunTrain.C\");\n\n"
760 << " return RunTrain(name, cls, uri, opts);\n"
761 << "}\n"
762 << "//\n"
763 << "// EOF\n"
764 << "//" << std::endl;
765 o.close();
766 }
767 /* @} */
768 TString fName;
769 TString fEscapedName;
770 OptionList fOptions;
771 Helper* fHelper;
772};
773#endif