]>
Commit | Line | Data |
---|---|---|
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 | |
21 | class TUrl; | |
22 | class 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><directory></dt> |
fdfd93b4 | 37 | * <dd>Grid directory that holds the data</dd> |
33438b4c | 38 | * <dt><treeName></dt> |
fdfd93b4 | 39 | * <dd>Tree to loop over</dd> |
33438b4c | 40 | * <dt><options></dt> |
fdfd93b4 | 41 | * <dd>List of options separated by an & |
42 | * <dl> | |
43 | * <dt><tt>storage=<url></tt></dt> | |
44 | * <dd>Specify a non-default storage location for special output | |
45 | * (e.g., AOD trees). <url> 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=<N></tt></dt> | |
59 | * <dd>Maximum number of files per split</dd> | |
60 | * <dt><tt>merge=<N></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 <datadir></dd> | |
66 | * <dt><tt>pattern=<GLOB></tt></dt> | |
67 | * <dd>Shell glob pattern that files must check when scanning | |
68 | * <datadir></dd> | |
69 | * </dl> | |
70 | * </dd> | |
71 | * </dl> | |
72 | * | |
73 | * @ingroup pwglf_forward_trains_helper | |
74 | */ | |
ba144d92 | 75 | struct 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 | // |