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