]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/trains/GridRailway.C
Merge branch 'feature-movesplit'
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / trains / GridRailway.C
CommitLineData
fdfd93b4 1/**
ba144d92 2 * @file GridRailway.C
fdfd93b4 3 * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
4 * @date Tue Oct 16 19:01:27 2012
5 *
ba144d92 6 * @brief Grid Analysis Railway
fdfd93b4 7 *
8 * @ingroup pwglf_forward_trains_helper
9 *
10 */
11#ifndef GRIDHELPER_C
12#define GRIDHELPER_C
ba144d92 13#include "PluginRailway.C"
fdfd93b4 14#ifndef __CINT__
15# include <TUrl.h>
16# include <TString.h>
17# include <TGrid.h>
18# include <AliAnalysisManager.h>
19# include <AliAnalysisAlien.h>
20#else
21class TUrl;
22class AliAnalysisAlien;
23#endif
24
25// ===================================================================
26/**
27 * Handle analysis on an the Grid
28 *
29 * This helper is triggered by a URL of the form
30 *
31 * @code
32 * alien:///<directory>[?<options>][#<pattern>]
33 * @endcode
34 * where
35 * <dl>
33438b4c 36 * <dt>&lt;directory&gt;</dt>
fdfd93b4 37 * <dd>Grid directory that holds the data</dd>
33438b4c 38 * <dt>&lt;treeName&gt;</dt>
fdfd93b4 39 * <dd>Tree to loop over</dd>
33438b4c 40 * <dt>&lt;options&gt;</dt>
fdfd93b4 41 * <dd>List of options separated by an &amp;
42 * <dl>
43 * <dt><tt>storage=&lt;url&gt;</tt></dt>
44 * <dd>Specify a non-default storage location for special output
45 * (e.g., AOD trees). &lt;url&gt; should be a valid XRootd
46 * server URI accessible to the slaves - e.g.,
47 * <tt>root://lxplus.cern.ch:10930//tmp</tt>.</dd>
48 * <dt><tt>mode=[default,rec,sim,train,custom]</tt></dt>
49 * <dd>Set the AliROOT mode. If not specified <tt>default</tt>
33438b4c 50 * is assumed. See also CreateAliROOTPar</dd>
fdfd93b4 51 * <dt><tt>par</tt></dt>
52 * <dd> Use PAR files</dd>
53 * <dt><tt>runs=[list or file]</tt></dt>
54 * <dd>Comma separated list of run numbers, or file(s) containing
55 * run numbers</dd>
56 * <dt><tt>oper=[FULL,TERMINATE,SUBMIT,OFFLINE,TEST]</tt></dt>
57 * <dd>How to run the analysis</dd>
58 * <dt><tt>split=&lt;N&gt;</tt></dt>
59 * <dd>Maximum number of files per split</dd>
60 * <dt><tt>merge=&lt;N&gt;</tt></dt>
61 * <dd>Maximum number of files per merger</dd>
62 * <dt><tt>mc</tt></dt>
63 * <dd>Scan also for MC files (<tt>galice.root</tt>,
64 * <tt>Kinematics.root</tt>, and <tt>TrackRefs.root</tt>) when
65 * scanning &lt;datadir&gt;</dd>
66 * <dt><tt>pattern=&lt;GLOB&gt;</tt></dt>
67 * <dd>Shell glob pattern that files must check when scanning
68 * &lt;datadir&gt;</dd>
69 * </dl>
70 * </dd>
71 * </dl>
72 *
73 * @ingroup pwglf_forward_trains_helper
74 */
ba144d92 75struct GridRailway : public PluginRailway
fdfd93b4 76{
77 /**
78 * Constructor
79 *
80 * @param url Url
33438b4c 81 * @param verbose Verbosity level
fdfd93b4 82 */
ba144d92 83 GridRailway(const TUrl& url, Int_t verbose)
84 : PluginRailway(url, verbose), fRuns()
fdfd93b4 85 {
b3489b40 86 // Note, split, merge, and ttl are by default set to values
87 // optimized for AOD production on real PbPb data.
88 //
89 // TTL shouldn't be much smaller than 4h10m. Split and merge
90 // shouldn't be much larger than 75, but probably not smaller than
91 // 50.
fdfd93b4 92 fOptions.Add("oper", "FULL|TERMINATE|SUBMIT", "Analysis operation", "FULL");
b3489b40 93 fOptions.Add("split", "N|max", "Max number of files before split","50");
94 fOptions.Add("merge", "N|max", "Max number of files for merge", "50");
91aef4e8 95 fOptions.Add("run", "RUNS", "Range, list, and/or file of runs", "");
a80dde0d 96 fOptions.Add("alien", "VERSION","Alien API version", "V1.1x");
b3489b40 97 fOptions.Add("ttl", "N|max", "Time to live", "6h");
98 fOptions.Add("pattern","GLOB", "File/directory name pattern", "");
a80dde0d 99 fOptions.Add("concat", "Concatenate all runs");
56039ab4 100 fOptions.Add("exclude", "GLOB","Comma separated list of merge excludes","");
fdfd93b4 101 }
ba144d92 102 GridRailway(const GridRailway& o)
103 : PluginRailway(o), fRuns()
9201c66b 104 {}
ba144d92 105 GridRailway& operator=(const GridRailway& o)
9201c66b 106 {
107 if (&o == this) return *this;
ba144d92 108 PluginRailway::operator=(o);
9201c66b 109 return *this;
110 }
ba144d92 111 virtual ~GridRailway() {}
fdfd93b4 112 /**
113 * Get the mode identifier
114 *
115 * @return Always kProof
116 */
117 virtual UShort_t Mode() const { return kGrid; }
118 /**
119 * Get the mode string used for AliAnalysisManager::StartAnalysis
120 */
121 virtual const char* ModeString() const { return "grid"; }
122 /**
123 * Set-up done before task set-ups
124 *
125 * @return true on success
126 */
127 virtual UShort_t Operation() const
128 {
129 if (!fOptions.Has("oper")) return kFull;
130 const TString& oper = fOptions.Get("oper");
131 if (oper.EqualTo("FULL", TString::kIgnoreCase)) return kFull;
132 else if (oper.EqualTo("OFFLINE", TString::kIgnoreCase)) return kOffline;
133 else if (oper.EqualTo("SUBMIT", TString::kIgnoreCase)) return kSubmit;
134 else if (oper.EqualTo("TERMINATE", TString::kIgnoreCase)) return kTerminate;
135 else if (oper.EqualTo("TEST", TString::kIgnoreCase)) return kTest;
136 return kFull;
137 }
9201c66b 138 void StoreRun(Int_t r)
139 {
140 TObject* o = new TObject;
141 o->SetUniqueID(r);
142 fRuns.Add(o);
143 }
fdfd93b4 144 /**
145 * Read run numbers
146 *
147 * @return Number of registered runs
148 */
149 virtual Int_t RegisterRuns()
150 {
151 if (!fOptions.Find("run")) {
ba144d92 152 Error("GridRailway::RegisterRuns", "No runs specified");
fdfd93b4 153 return -1;
154 }
155 Int_t nRuns = 0;
a80dde0d 156 TString runs = fOptions.Get("run");
024ec5ac 157 TObjArray* tokens = runs.Tokenize(",+:");
fdfd93b4 158 TObjString* part = 0;
159 TIter next(tokens);
160 Bool_t range = false;
161 Bool_t individual = false;
ba144d92 162 // Info("GridRailway::RegisterRuns", "Runs specified are %s", runs.Data());
fdfd93b4 163 while ((part = static_cast<TObjString*>(next()))) {
164 TString& s = part->String();
165 if (s.Contains("-")) { // Run range
166 if (range) {
ba144d92 167 Warning("GridRailway::RegisterRuns", "Run range already specified, "
fdfd93b4 168 "ignoring %s", s.Data());
169 continue;
170 }
171 if (individual) {
ba144d92 172 Warning("GridRailway::RegisterRuns",
fdfd93b4 173 "Run ranges and individual run specs do not mix, "
174 "ignoring %s", s.Data());
175 continue;
176 }
177 TObjArray* ranges = s.Tokenize("-");
178 if (ranges->GetEntriesFast() > 2) {
ba144d92 179 Warning("GridRailway::RegisterRuns", "Invalid run range: %s",
fdfd93b4 180 s.Data());
181 ranges->Delete();
182 continue;
183 }
184 Int_t first = static_cast<TObjString*>(ranges->At(0))->String().Atoi();
185 Int_t last = static_cast<TObjString*>(ranges->At(1))->String().Atoi();
186 nRuns = last-first+1;
ba144d92 187 // Info("GridRailway::RegisterRuns", "Run range %d -> %d", first, last);
fdfd93b4 188 fHandler->SetRunRange(first, last);
189 ranges->Delete();
190 range = true;
9201c66b 191 for (Int_t r = first; r <= last; r++) StoreRun(r);
fdfd93b4 192 continue;
193 }
194 if (s.IsDigit()) { // single run
195 if (range) {
ba144d92 196 Warning("GridRailway::RegisterRuns",
fdfd93b4 197 "Run ranges and individual run specs do not mix, "
198 "ignoring %s", s.Data());
199 continue;
200 }
85f21ab4 201 // Info("GridHandler::RegisterRuns", "Adding run %s", s.Data());
9201c66b 202 fHandler->AddRunNumber(s.Atoi());
203 StoreRun(s.Atoi());
fdfd93b4 204 nRuns++;
205 individual = true;
206 continue;
207 }
a80dde0d 208 if (range) {
ba144d92 209 Warning("GridRailway::RegisterRuns", "Run ranges and list file "
a80dde0d 210 "do not mix, ignoring %s", s.Data());
211 continue;
212 }
fdfd93b4 213
214 // We assume this part is a file
ba144d92 215 // Info("GridRailway::RegisterRuns", "Reading runs from %s", s.Data());
fdfd93b4 216 std::ifstream in(s.Data());
217 if (!in) {
a54cc77b 218 s.Prepend("../");
219 in.open(s.Data());
220 if (!in) {
ba144d92 221 Warning("GridRailway::RegisterRuns", "Failed to open %s", s.Data());
a54cc77b 222 continue;
223 }
fdfd93b4 224 }
024ec5ac 225 while (!in.eof()) {
226 TString lne;
227 lne.ReadLine(in);
228
229 TString bare = lne.Strip(TString::kBoth);
230 if (bare[0] == '#') continue;
231
232 TObjArray* ltokens = bare.Tokenize(" \t,");
233 TIter lnext(ltokens);
234 TObjString* str = 0;
235 while ((str = static_cast<TObjString*>(lnext()))) {
236 const TString& token = str->String();
237 if (!token.IsDigit()) continue;
238
239 int r = token.Atoi();
240 fHandler->AddRunNumber(r);
241 StoreRun(r);
242 nRuns++;
243 }
244 ltokens->Delete();
245 }
246#if 0
fdfd93b4 247 while (!in.eof()) {
248 Int_t r;
249 in >> r;
ba144d92 250 // Info("GridRailway::RegisterRuns", "Read %d, adding", r);
fdfd93b4 251 fHandler->AddRunNumber(r);
9201c66b 252 StoreRun(r);
fdfd93b4 253 nRuns++;
254 Char_t c;
255 in >> c;
256 if (in.bad()) break;
257 }
024ec5ac 258#endif
fdfd93b4 259 individual = true;
260 in.close();
261 }
262 return nRuns;
263 }
264 /**
265 * Executed before setting up tasks
266 *
267 * @return true on success
268 */
269 virtual Bool_t PreSetup()
270 {
ba144d92 271 if (!PluginRailway::PreSetup()) return false;
a80dde0d 272
273 // --- Add system library dir to load path -----------------------
274 gSystem->AddDynamicPath("/usr/lib");
fdfd93b4 275
276 // --- Open a connection to the grid -----------------------------
a80dde0d 277 if (!TGrid::Connect(Form("%s://", fUrl.GetProtocol()))) {
ba144d92 278 Error("GridRailway::PreSetup", "Failed to connect to AliEN");
a80dde0d 279 return false;
280 }
fdfd93b4 281 if (!gGrid || !gGrid->IsConnected()) {
ba144d92 282 Error("GridRailway::PreSetup", "Failed to connect to AliEN");
fdfd93b4 283 return false;
284 }
285
286 return true;
287 }
288 /**
289 * Set-up done after the task set-ups
290 *
291 * @return true on success
292 */
293 virtual Bool_t PostSetup()
294 {
ba144d92 295 // Info("GridRailway::PostSetup", "Calling super.PostSetup");
296 if (!PluginRailway::PostSetup()) return false;
fdfd93b4 297
a80dde0d 298 // --- API version -----------------------------------------------
299 fHandler->SetAPIVersion(fOptions.Get("alien"));
300
301 // --- Get the name ----------------------------------------------
ba144d92 302 // Info("GridRailway", "Proceeding with plugin setup");
fdfd93b4 303 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
304 TString name(mgr->GetName());
305
306 // --- Set the operation to do (TEST, SUBMIT, TERMINATE, FULL) ---
307 TString operation("FULL");
308 if (fOptions.Has("oper")) operation = fOptions.Get("oper");
309 fHandler->SetRunMode(operation);
310
a80dde0d 311 // --- Add the run numbers ---------------------------------------
a54cc77b 312 fHandler->SetRunPrefix(fOptions.Has("mc") ? "%d" : "%09d");
a80dde0d 313 Int_t nRun = RegisterRuns();
314
fdfd93b4 315 // --- Do not test copying ---------------------------------------
316 fHandler->SetCheckCopy(false);
317
318 // --- Set output to be per run ----------------------------------
319 fHandler->SetOutputToRunNo(true);
320
321 // --- Set the job tag -------------------------------------------
322 fHandler->SetJobTag(name);
323
324 // --- Set number of test files - used in test mode only ---------
325 fHandler->SetNtestFiles(1);
326
327 // --- Set the Time-To-Live --------------------------------------
b7a63753 328 if (fOptions.Has("ttl")) {
8449e3e0 329 TString sttl = fOptions.Get("ttl");
330 if (!sttl.EqualTo("max")) {
331 Int_t ttl = 0;
332 if (sttl.IsDigit()) ttl = sttl.Atoi();
333 else {
334 // Parse string of the form <DAYS>d<HOURS>h<MINUTES>m<SECONDS>s
335 Int_t id = sttl.Index("d", 0);
336 if (id == kNPOS) id = -1;
337 else {
338 TString sdays(sttl(0,id));
339 ttl += 24 * 60 * 60 * sdays.Atoi();
340 }
341 Int_t ih = sttl.Index("h", id+1);
342 if (ih == kNPOS) ih = id;
343 else {
344 TString shour(sttl(id+1,ih-id-1));
345 ttl += 60 * 60 * shour.Atoi();
346 }
347 Int_t im = sttl.Index("m", ih+1);
348 if (im == kNPOS) im = ih;
349 else {
350 TString smin(sttl(ih+1, im-ih-1));
351 ttl += 60 * smin.Atoi();
352 }
353 Int_t is = sttl.Index("s", im+1);
354 if (is != kNPOS) {
355 TString ssec(sttl(im+1, is-im-1));
356 ttl += ssec.Atoi();
357 }
358 }
359 if (ttl != 0) fHandler->SetTTL(ttl);
360 else
361 Warning("", "Option ttl given but no value found");
b7a63753 362 }
363 }
fdfd93b4 364
365 // --- Re-submit failed jobs as long as the ratio of failed jobs -
366 // --- is this percentage.
367 fHandler->SetMasterResubmitThreshold(95);
368
369 // --- Set the input format --------------------------------------
370 fHandler->SetInputFormat("xml-single");
371
372 // --- Set names of generated files ------------------------------
373 fHandler->SetAnalysisMacro(Form("%s.C", name.Data()));
374 fHandler->SetJDLName(Form("%s.jdl", name.Data()));
375 fHandler->SetExecutable(Form("%s.sh", name.Data()));
376
377 // ---- Set the job price !? -------------------------------------
378 fHandler->SetPrice(1);
379
380 // --- Set whether to merge via JDL ------------------------------
381 fHandler->SetMergeViaJDL(true);
382
383 // --- Fast read otion -------------------------------------------
384 fHandler->SetFastReadOption(false);
385
386 // --- Whether to overwrite existing output ----------------------
387 fHandler->SetOverwriteMode(true);
388
389 // --- Set the executable binary name and options ----------------
390 fHandler->SetExecutableCommand("aliroot -b -q -x");
391
392 // --- Split by storage element - must be lower case! ------------
393 fHandler->SetSplitMode("se");
394
395 // --- How much to split -----------------------------------------
396 if (fOptions.Has("split")) {
397 if (!fOptions.Get("split").EqualTo("max")) {
a80dde0d 398 fHandler->SetSplitMaxInputFileNumber(fOptions.AsInt("split"));
fdfd93b4 399 }
400 }
fdfd93b4 401 // --- Merge parameters ------------------------------------------
402 if (fOptions.Has("merge")) {
403 if (!fOptions.Get("merge").EqualTo("max")) {
a80dde0d 404 fHandler->SetMaxMergeFiles(fOptions.AsInt("merge"));
fdfd93b4 405 }
406 }
56039ab4 407 TString exclude="AliAOD.root *EventStat*.root *event_stat*.root";
408 if (fOptions.Has("exclude")) {
409 TString exOpt = fOptions.Get("exclude");
410 exOpt.ReplaceAll(",", " ");
411 exclude.Append(" ");
412 exclude.Append(exOpt);
413 }
414 fHandler->SetMergeExcludes(exclude);
a80dde0d 415
416 // --- Set number of runs per master - 1 or all ------------------
417 fHandler->SetNrunsPerMaster(fOptions.Has("concat") ? nRun+1 : 1);
418
419
420 // --- Enable default outputs ------------------------------------
421 fHandler->SetDefaultOutputs(true);
fdfd93b4 422
423 // --- Keep log files ------------------------------------------
424 fHandler->SetKeepLogs();
425
426 // --- Set the working directory to be the trains name (with -----
427 // --- special characters replaced by '_' and the date appended),
428 // --- and also set the output directory (relative to working
429 // --- directory)
430 fHandler->SetGridWorkingDir(name.Data());
431 fHandler->SetGridOutputDir("output");
432 fHandler->SetGridDataDir(fUrl.GetFile());
433
434 // --- Get the tree name and set the file pattern ----------------
435 TString pattern;
436 if (fOptions.Has("pattern")) pattern = fOptions.Get("pattern");
437 else {
438 TString treeName(fUrl.GetAnchor());
439 if (treeName.IsNull()) {
ba144d92 440 Warning("GridRailway::PreSetup", "No tree name specified, assuming T");
fdfd93b4 441 treeName = "T";
442 }
443 if (treeName.EqualTo("esdTree")) pattern = "AliESD";
444 else if (treeName.EqualTo("aodTree")) pattern = "AliAOD";
445 }
446 fHandler->SetDataPattern(pattern);
fdfd93b4 447
448 // --- Loop over defined containers in the analysis manager, and -
449 // --- declare these as outputs
450 TString listOfAODs = "";
451 TString listOfHists = "";
85f21ab4 452 TString listOfTerms = "";
fdfd93b4 453
85f21ab4 454 TObjArray* outs[] = { mgr->GetOutputs(), mgr->GetParamOutputs(), 0 };
455 TObjArray** out = outs;
456 while (*out) {
457 AliAnalysisDataContainer* cont = 0;
458 TIter nextCont(*out);
459 while ((cont = static_cast<AliAnalysisDataContainer*>(nextCont()))) {
460 TString outName(cont->GetFileName());
461 Bool_t term = (*out == outs[1]);
462 TString& list = (outName == "default" ? listOfAODs :
463 !term ? listOfHists : listOfTerms);
464 if (outName == "default") {
465 if (!mgr->GetOutputEventHandler()) continue;
466
467 outName = mgr->GetOutputEventHandler()->GetOutputFileName();
468 }
85f21ab4 469 if (list.Contains(outName)) continue;
470 if (!list.IsNull()) list.Append(",");
471 list.Append(outName);
fdfd93b4 472 }
85f21ab4 473 out++;
fdfd93b4 474 }
85f21ab4 475 TString extra = mgr->GetExtraFiles();
476 if (!extra.IsNull()) {
fdfd93b4 477 if (!listOfAODs.IsNull()) listOfAODs.Append("+");
fdfd93b4 478 extra.ReplaceAll(" ", ",");
479 listOfAODs.Append(extra);
480 }
481
08275d05 482#if 0
fdfd93b4 483 Int_t nReplica = 2;
484 TString outArchive = Form("stderr, stdout@disk=%d", nReplica);
485 if (!listOfHists.IsNull())
486 outArchive.Append(Form(" hist_archive.zip:%s@disk=%d",
487 listOfHists.Data(), nReplica));
488 if (!listOfAODs.IsNull())
489 outArchive.Append(Form(" aod_archive.zip:%s@disk=%d",
490 listOfAODs.Data(), nReplica));
08275d05 491 // Disabled for now
492 // plugin->SetOutputArchive(outArchive);
493#endif
494
fdfd93b4 495 if (listOfAODs.IsNull() && listOfHists.IsNull())
496 Fatal("PostSetup", "No outputs defined");
85f21ab4 497 if (!listOfTerms.IsNull())
498 fHandler->SetTerminateFiles(listOfTerms);
fdfd93b4 499
500 return true;
501 };
502 /**
503 * Start the analysis
504 *
505 * @param nEvents Number of events to analyse
506 *
507 * @return The return value of AliAnalysisManager::StartAnalysis
508 */
509 virtual Long64_t Run(Long64_t nEvents=-1)
510 {
511 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
85f21ab4 512 if (nEvents == 0) return 0;
513 Long64_t ret = mgr->StartAnalysis("grid", nEvents);
08275d05 514
33438b4c 515#if 1
08275d05 516 std::ofstream outJobs(Form("%s.jobid", mgr->GetName()));
33438b4c 517 outJobs << fHandler->GetGridJobIDs() << std::endl;
08275d05 518 outJobs.close();
519
520 std::ofstream outStages(Form("%s.stage", mgr->GetName()));
33438b4c 521 outStages << fHandler->GetGridStages() << std::endl;
08275d05 522 outStages.close();
a4923b29 523#endif
85f21ab4 524 return ret;
fdfd93b4 525 }
526 /**
527 * Link an auxilary file to working directory
528 *
529 * @param name Name of the file
33438b4c 530 * @param copy Whether to copy or not
fdfd93b4 531 *
532 * @return true on success
533 */
ddcc1bbd 534 virtual Bool_t AuxFile(const TString& name, bool copy=false)
fdfd93b4 535 {
ba144d92 536 if (!Railway::AuxFile(name, copy)) return false;
fdfd93b4 537 // We need to add this file as an additional 'library', so that the
538 // file is uploaded to the users Grid working directory.
539 fHandler->AddAdditionalLibrary(gSystem->BaseName(name.Data()));
540 return true;
541 }
542 /**
543 * Get the output (directory)
544 *
545 */
546 virtual TString OutputPath() const
547 {
548 TString ret;
549 if (!fHandler) {
ba144d92 550 Warning("GridRailway::OutputLocation", "No AliEn handler");
fdfd93b4 551 return ret;
552 }
553 ret = fHandler->GetGridOutputDir();
554 if (ret.BeginsWith("/")) return ret;
555
556 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
557 if (!mgr) {
ba144d92 558 Warning("GridRailway::OutputLocation", "No analysis manager");
fdfd93b4 559 return ret;
560 }
561 ret.Prepend(Form("%s/", mgr->GetName()));
562 if (gGrid)
563 ret.Prepend(Form("%s/", gGrid->GetHomeDirectory()));
564
565 return ret;
566 }
567 /**
568 * @return URL help string
569 */
570 virtual const Char_t* UrlHelp() const
571 {
572 return "alien:///<datadir>[?<options>][#<treeName>]";
573 }
574 /**
575 * @return Short description
576 */
577 virtual const char* Desc() const { return "AliEn"; }
a80dde0d 578 /**
579 * Write auxillary ROOT (and possible shell) script for more
580 * (post-)processing e.g., terminate
581 *
582 * @param escaped Escaped name
a80dde0d 583 */
584 void AuxSave(const TString& escaped,
08275d05 585 Bool_t /*asShellScript*/)
a80dde0d 586 {
587 // Write plug-in to file
588 TFile* plug = TFile::Open(Form("%s_plugin.root", escaped.Data()),
589 "RECREATE");
590 fHandler->Write("plugin");
591 plug->Close();
592
85f21ab4 593 TIter nextLib(&fExtraLibs);
594 TObjString* lib = 0;
595 TString libs;
596 while ((lib = static_cast<TObjString*>(nextLib()))) {
597 if (!libs.IsNull()) libs.Append(" ");
598 libs.Append(lib->String());
599 }
600 TIter nextPar(&fExtraPars);
601 TObjString* par = 0;
602 TString pars;
603 while ((par = static_cast<TObjString*>(nextPar()))) {
604 if (!pars.IsNull()) pars.Append(" ");
605 pars.Append(par->String());
606 }
607 TIter nextSrc(&fExtraSrcs);
608 TObjString* src = 0;
609 TString srcs;
610 while ((src = static_cast<TObjString*>(nextSrc()))) {
611 if (!srcs.IsNull()) srcs.Append(" ");
612 srcs.Append(src->String());
613 }
614 TString macDir("$ALICE_ROOT/PWGLF/FORWARD/trains");
9201c66b 615 std::ofstream t("Terminate.C");
616 if (!t) {
ba144d92 617 Error("GridRailway::AuxSave", "Failed to make terminate ROOT script");
a80dde0d 618 return;
619 }
85f21ab4 620
ba144d92 621 t << "// Generated by GridRailway\n"
8449e3e0 622 << "Bool_t Terminate(Bool_t localMerge=false)\n"
85f21ab4 623 << "{\n"
624 << " TString name = \"" << escaped << "\";\n"
625 << " TString libs = \"" << libs << "\";\n"
626 << " TString pars = \"" << pars << "\";\n"
627 << " TString srcs = \"" << srcs << "\";\n\n"
8449e3e0 628 << " gSystem->Load(\"libANALYSIS\");\n"
629 << " gSystem->Load(\"libANALYSISalice\");\n"
630 << " gSystem->AddIncludePath(\"-I$ALICE_ROOT/include\");\n\n"
631 << " gROOT->LoadMacro(\"" << macDir << "/GridTerminate.C+g\");\n\n"
632 << " return GridTerminate(name,libs,pars,srcs,localMerge);\n"
85f21ab4 633 << "}\n"
634 << "// EOF\n"
635 << std::endl;
636 t.close();
637
638 TString runs;
639 TString format(fOptions.Has("mc") ? "%d" : "%09d");
640 if (fOptions.Has("concat")) {
641 Int_t first = fRuns.First()->GetUniqueID();
642 Int_t last = fRuns.Last()->GetUniqueID();
643 TString fmt(format);
644 fmt.Append("_");
645 fmt.Append(format);
646 if (!runs.IsNull()) runs.Append(" ");
647 runs.Append(TString::Format(fmt, first, last));
648 }
649 else {
650 TIter next(&fRuns);
651 TObject* o = 0;
652 while ((o = next())) {
653 if (!runs.IsNull()) runs.Append(" ");
654 runs.Append(Form(format, o->GetUniqueID()));
655 }
656 }
657
658 std::ofstream d("Download.C");
659 if (!d) {
ba144d92 660 Error("GridRailway::AuxSave", "Failed to make ROOT script Download.C");
85f21ab4 661 return;
662 }
ba144d92 663 d << "// Generated by GridRailway\n"
aeab3a4e 664 << "void Download(Bool_t unpack=true)\n"
85f21ab4 665 << "{\n"
666 << " TString base = \"" << fUrl.GetProtocol() << "://"
667 << OutputPath() << "\";\n"
668 << " TString runs = \"" << runs << "\";\n\n"
669 << " gROOT->LoadMacro(\"" << macDir << "/GridDownload.C\");\n\n"
aeab3a4e 670 << " GridDownload(base, runs, unpack);\n"
85f21ab4 671 << "}\n"
672 << "// EOF\n"
673 << std::endl;
674 d.close();
08275d05 675
676 std::ofstream w("Watch.C");
677 if (!w) {
ba144d92 678 Error("GridRailway::AuxSave", "Failed to make ROOT script Watch.C");
85f21ab4 679 return;
680 }
ba144d92 681 w << "// Generated by GridRailway\n"
8449e3e0 682 << "void Watch(Bool_t batch=false, Int_t delay=5*60)\n"
a80dde0d 683 << "{\n"
08275d05 684 << " TString name = \"" << escaped << "\";\n"
685 << " gROOT->LoadMacro(\"" << macDir << "/GridWatch.C+g\");\n\n"
8449e3e0 686 << " GridWatch(name,batch,delay);\n"
a80dde0d 687 << "}\n"
a80dde0d 688 << "// EOF\n"
85f21ab4 689 << std::endl;
08275d05 690 w.close();
85f21ab4 691
a80dde0d 692 }
9201c66b 693 TList fRuns;
fdfd93b4 694};
695#endif
696//
697// EOF
698//