]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/trains/GridHelper.C
updates from Redmer to protect redoFinish from classes not loaded and updates for...
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / trains / GridHelper.C
CommitLineData
fdfd93b4 1/**
2 * @file GridHelper.C
3 * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
4 * @date Tue Oct 16 19:01:27 2012
5 *
6 * @brief Grid Analysis Helper
7 *
8 * @ingroup pwglf_forward_trains_helper
9 *
10 */
11#ifndef GRIDHELPER_C
12#define GRIDHELPER_C
13#include "PluginHelper.C"
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>
36 * <dt>&lt;directory@gt;</dt>
37 * <dd>Grid directory that holds the data</dd>
38 * <dt>&lt;treeName@gt;</dt>
39 * <dd>Tree to loop over</dd>
40 * <dt>&lt;options@gt;</dt>
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>
50 * is assumed</tt>. See also CreateAliROOTPar</dd>
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 */
75struct GridHelper : public PluginHelper
76{
77 /**
78 * Constructor
79 *
80 * @param url Url
81 * @param opts Options
82 */
83 GridHelper(const TUrl& url, Int_t verbose)
84 : PluginHelper(url, verbose)
85 {
86 fOptions.Add("oper", "FULL|TERMINATE|SUBMIT", "Analysis operation", "FULL");
a80dde0d 87 fOptions.Add("split", "N|max", "Max number of files before split","max");
88 fOptions.Add("merge", "N|max", "Max number of files for merge", "max");
89 fOptions.Add("run", "RUNS", "Range, list, and/or file of runs");
90 fOptions.Add("pattern","GLOB", "File/directory name pattern");
91 fOptions.Add("alien", "VERSION","Alien API version", "V1.1x");
92 fOptions.Add("concat", "Concatenate all runs");
93 fOptions.Add("mc", "Assume MC input");
fdfd93b4 94 }
95 virtual ~GridHelper() {}
96 /**
97 * Get the mode identifier
98 *
99 * @return Always kProof
100 */
101 virtual UShort_t Mode() const { return kGrid; }
102 /**
103 * Get the mode string used for AliAnalysisManager::StartAnalysis
104 */
105 virtual const char* ModeString() const { return "grid"; }
106 /**
107 * Set-up done before task set-ups
108 *
109 * @return true on success
110 */
111 virtual UShort_t Operation() const
112 {
113 if (!fOptions.Has("oper")) return kFull;
114 const TString& oper = fOptions.Get("oper");
115 if (oper.EqualTo("FULL", TString::kIgnoreCase)) return kFull;
116 else if (oper.EqualTo("OFFLINE", TString::kIgnoreCase)) return kOffline;
117 else if (oper.EqualTo("SUBMIT", TString::kIgnoreCase)) return kSubmit;
118 else if (oper.EqualTo("TERMINATE", TString::kIgnoreCase)) return kTerminate;
119 else if (oper.EqualTo("TEST", TString::kIgnoreCase)) return kTest;
120 return kFull;
121 }
122 /**
123 * Read run numbers
124 *
125 * @return Number of registered runs
126 */
127 virtual Int_t RegisterRuns()
128 {
129 if (!fOptions.Find("run")) {
130 Error("GridHelper::RegisterRuns", "No runs specified");
131 return -1;
132 }
133 Int_t nRuns = 0;
a80dde0d 134 TString runs = fOptions.Get("run");
fdfd93b4 135 TObjArray* tokens = runs.Tokenize(",");
136 TObjString* part = 0;
137 TIter next(tokens);
138 Bool_t range = false;
139 Bool_t individual = false;
a80dde0d 140 Info("GridHelper::RegisterRuns", "Runs specified are %s", runs.Data());
fdfd93b4 141 while ((part = static_cast<TObjString*>(next()))) {
142 TString& s = part->String();
143 if (s.Contains("-")) { // Run range
144 if (range) {
145 Warning("GridHelper::RegisterRuns", "Run range already specified, "
146 "ignoring %s", s.Data());
147 continue;
148 }
149 if (individual) {
150 Warning("GridHelper::RegisterRuns",
151 "Run ranges and individual run specs do not mix, "
152 "ignoring %s", s.Data());
153 continue;
154 }
155 TObjArray* ranges = s.Tokenize("-");
156 if (ranges->GetEntriesFast() > 2) {
157 Warning("GridHelper::RegisterRuns", "Invalid run range: %s",
158 s.Data());
159 ranges->Delete();
160 continue;
161 }
162 Int_t first = static_cast<TObjString*>(ranges->At(0))->String().Atoi();
163 Int_t last = static_cast<TObjString*>(ranges->At(1))->String().Atoi();
164 nRuns = last-first+1;
a80dde0d 165 Info("GridHelper::RegisterRuns", "Run range %d -> %d",
166 first, last);
fdfd93b4 167 fHandler->SetRunRange(first, last);
168 ranges->Delete();
169 range = true;
170 continue;
171 }
172 if (s.IsDigit()) { // single run
173 if (range) {
174 Warning("GridHelper::RegisterRuns",
175 "Run ranges and individual run specs do not mix, "
176 "ignoring %s", s.Data());
177 continue;
178 }
a80dde0d 179 Info("GridHandler::RegisterRuns", "Adding run %s", s.Data());
fdfd93b4 180 fHandler->AddRunNumber(s.Data());
181 nRuns++;
182 individual = true;
183 continue;
184 }
a80dde0d 185 if (range) {
186 Warning("GridHelper::RegisterRuns", "Run ranges and list file "
187 "do not mix, ignoring %s", s.Data());
188 continue;
189 }
fdfd93b4 190
191 // We assume this part is a file
a80dde0d 192 Info("GridHelper::RegisterRuns", "Reading runs from %s", s.Data());
fdfd93b4 193 std::ifstream in(s.Data());
194 if (!in) {
195 Warning("GridHelper::RegisterRuns", "Failed to open %s", s.Data());
196 continue;
197 }
198 while (!in.eof()) {
199 Int_t r;
200 in >> r;
a80dde0d 201 Info("GridHelper::RegisterRuns", "Read %d, adding", r);
fdfd93b4 202 fHandler->AddRunNumber(r);
203 nRuns++;
204 Char_t c;
205 in >> c;
206 if (in.bad()) break;
207 }
208 individual = true;
209 in.close();
210 }
211 return nRuns;
212 }
213 /**
214 * Executed before setting up tasks
215 *
216 * @return true on success
217 */
218 virtual Bool_t PreSetup()
219 {
220 if (!PluginHelper::PreSetup()) return false;
a80dde0d 221
222 // --- Add system library dir to load path -----------------------
223 gSystem->AddDynamicPath("/usr/lib");
fdfd93b4 224
225 // --- Open a connection to the grid -----------------------------
a80dde0d 226 if (!TGrid::Connect(Form("%s://", fUrl.GetProtocol()))) {
227 Error("GridHelper::PreSetup", "Failed to connect to AliEN");
228 return false;
229 }
fdfd93b4 230 if (!gGrid || !gGrid->IsConnected()) {
231 Error("GridHelper::PreSetup", "Failed to connect to AliEN");
232 return false;
233 }
234
235 return true;
236 }
237 /**
238 * Set-up done after the task set-ups
239 *
240 * @return true on success
241 */
242 virtual Bool_t PostSetup()
243 {
a80dde0d 244 Info("GridHelper::PostSetup", "Calling super.PostSetup");
fdfd93b4 245 if (!PluginHelper::PostSetup()) return false;
246
a80dde0d 247 // --- API version -----------------------------------------------
248 fHandler->SetAPIVersion(fOptions.Get("alien"));
249
250 // --- Get the name ----------------------------------------------
251 Info("GridHandler", "Proceeding with plugin setup");
fdfd93b4 252 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
253 TString name(mgr->GetName());
254
255 // --- Set the operation to do (TEST, SUBMIT, TERMINATE, FULL) ---
256 TString operation("FULL");
257 if (fOptions.Has("oper")) operation = fOptions.Get("oper");
258 fHandler->SetRunMode(operation);
259
a80dde0d 260 // --- Add the run numbers ---------------------------------------
261 fHandler->SetRunPrefix(mgr->GetMCtruthEventHandler() ? "%d" : "%09d");
262 Int_t nRun = RegisterRuns();
263
fdfd93b4 264 // --- Do not test copying ---------------------------------------
265 fHandler->SetCheckCopy(false);
266
267 // --- Set output to be per run ----------------------------------
268 fHandler->SetOutputToRunNo(true);
269
270 // --- Set the job tag -------------------------------------------
271 fHandler->SetJobTag(name);
272
273 // --- Set number of test files - used in test mode only ---------
274 fHandler->SetNtestFiles(1);
275
276 // --- Set the Time-To-Live --------------------------------------
277 fHandler->SetTTL(70000);
278
279 // --- Re-submit failed jobs as long as the ratio of failed jobs -
280 // --- is this percentage.
281 fHandler->SetMasterResubmitThreshold(95);
282
283 // --- Set the input format --------------------------------------
284 fHandler->SetInputFormat("xml-single");
285
286 // --- Set names of generated files ------------------------------
287 fHandler->SetAnalysisMacro(Form("%s.C", name.Data()));
288 fHandler->SetJDLName(Form("%s.jdl", name.Data()));
289 fHandler->SetExecutable(Form("%s.sh", name.Data()));
290
291 // ---- Set the job price !? -------------------------------------
292 fHandler->SetPrice(1);
293
294 // --- Set whether to merge via JDL ------------------------------
295 fHandler->SetMergeViaJDL(true);
296
297 // --- Fast read otion -------------------------------------------
298 fHandler->SetFastReadOption(false);
299
300 // --- Whether to overwrite existing output ----------------------
301 fHandler->SetOverwriteMode(true);
302
303 // --- Set the executable binary name and options ----------------
304 fHandler->SetExecutableCommand("aliroot -b -q -x");
305
306 // --- Split by storage element - must be lower case! ------------
307 fHandler->SetSplitMode("se");
308
309 // --- How much to split -----------------------------------------
310 if (fOptions.Has("split")) {
311 if (!fOptions.Get("split").EqualTo("max")) {
a80dde0d 312 fHandler->SetSplitMaxInputFileNumber(fOptions.AsInt("split"));
fdfd93b4 313 }
314 }
fdfd93b4 315 // --- Merge parameters ------------------------------------------
316 if (fOptions.Has("merge")) {
317 if (!fOptions.Get("merge").EqualTo("max")) {
a80dde0d 318 fHandler->SetMaxMergeFiles(fOptions.AsInt("merge"));
fdfd93b4 319 }
320 }
321 fHandler->SetMergeExcludes("AliAOD.root *EventStat*.root "
322 "*event_stat*.root");
a80dde0d 323
324 // --- Set number of runs per master - 1 or all ------------------
325 fHandler->SetNrunsPerMaster(fOptions.Has("concat") ? nRun+1 : 1);
326
327
328 // --- Enable default outputs ------------------------------------
329 fHandler->SetDefaultOutputs(true);
fdfd93b4 330
331 // --- Keep log files ------------------------------------------
332 fHandler->SetKeepLogs();
333
334 // --- Set the working directory to be the trains name (with -----
335 // --- special characters replaced by '_' and the date appended),
336 // --- and also set the output directory (relative to working
337 // --- directory)
338 fHandler->SetGridWorkingDir(name.Data());
339 fHandler->SetGridOutputDir("output");
340 fHandler->SetGridDataDir(fUrl.GetFile());
341
342 // --- Get the tree name and set the file pattern ----------------
343 TString pattern;
344 if (fOptions.Has("pattern")) pattern = fOptions.Get("pattern");
345 else {
346 TString treeName(fUrl.GetAnchor());
347 if (treeName.IsNull()) {
348 Warning("GridHelper::PreSetup", "No tree name specified, assuming T");
349 treeName = "T";
350 }
351 if (treeName.EqualTo("esdTree")) pattern = "AliESD";
352 else if (treeName.EqualTo("aodTree")) pattern = "AliAOD";
353 }
354 fHandler->SetDataPattern(pattern);
fdfd93b4 355
356 // --- Loop over defined containers in the analysis manager, and -
357 // --- declare these as outputs
358 TString listOfAODs = "";
359 TString listOfHists = "";
360
361 AliAnalysisDataContainer* cont = 0;
362 TIter nextCont(mgr->GetOutputs());
363 while ((cont = static_cast<AliAnalysisDataContainer*>(nextCont()))) {
364 TString outName(cont->GetFileName());
365 TString& list = (outName == "default" ? listOfAODs : listOfHists);
366 if (outName == "default") {
367 if (!mgr->GetOutputEventHandler()) continue;
368
369 outName = mgr->GetOutputEventHandler()->GetOutputFileName();
370 }
371 if (list.Contains(outName)) continue;
372 if (!list.IsNull()) list.Append(",");
373 list.Append(outName);
374 }
375 if (!mgr->GetExtraFiles().IsNull()) {
376 if (!listOfAODs.IsNull()) listOfAODs.Append("+");
377 TString extra = mgr->GetExtraFiles();
378 extra.ReplaceAll(" ", ",");
379 listOfAODs.Append(extra);
380 }
381
382 Int_t nReplica = 2;
383 TString outArchive = Form("stderr, stdout@disk=%d", nReplica);
384 if (!listOfHists.IsNull())
385 outArchive.Append(Form(" hist_archive.zip:%s@disk=%d",
386 listOfHists.Data(), nReplica));
387 if (!listOfAODs.IsNull())
388 outArchive.Append(Form(" aod_archive.zip:%s@disk=%d",
389 listOfAODs.Data(), nReplica));
390 if (listOfAODs.IsNull() && listOfHists.IsNull())
391 Fatal("PostSetup", "No outputs defined");
392
393 return true;
394 };
395 /**
396 * Start the analysis
397 *
398 * @param nEvents Number of events to analyse
399 *
400 * @return The return value of AliAnalysisManager::StartAnalysis
401 */
402 virtual Long64_t Run(Long64_t nEvents=-1)
403 {
404 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
405
406 return mgr->StartAnalysis("grid", nEvents);
407 }
408 /**
409 * Link an auxilary file to working directory
410 *
411 * @param name Name of the file
412 *
413 * @return true on success
414 */
415 virtual Bool_t AuxFile(const TString& name)
416 {
417 if (!Helper::AuxFile(name)) return false;
418 // We need to add this file as an additional 'library', so that the
419 // file is uploaded to the users Grid working directory.
420 fHandler->AddAdditionalLibrary(gSystem->BaseName(name.Data()));
421 return true;
422 }
423 /**
424 * Get the output (directory)
425 *
426 */
427 virtual TString OutputPath() const
428 {
429 TString ret;
430 if (!fHandler) {
431 Warning("GridHelper::OutputLocation", "No AliEn handler");
432 return ret;
433 }
434 ret = fHandler->GetGridOutputDir();
435 if (ret.BeginsWith("/")) return ret;
436
437 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
438 if (!mgr) {
439 Warning("GridHelper::OutputLocation", "No analysis manager");
440 return ret;
441 }
442 ret.Prepend(Form("%s/", mgr->GetName()));
443 if (gGrid)
444 ret.Prepend(Form("%s/", gGrid->GetHomeDirectory()));
445
446 return ret;
447 }
448 /**
449 * @return URL help string
450 */
451 virtual const Char_t* UrlHelp() const
452 {
453 return "alien:///<datadir>[?<options>][#<treeName>]";
454 }
455 /**
456 * @return Short description
457 */
458 virtual const char* Desc() const { return "AliEn"; }
a80dde0d 459 /**
460 * Write auxillary ROOT (and possible shell) script for more
461 * (post-)processing e.g., terminate
462 *
463 * @param escaped Escaped name
464 * @param asShellScript also save as shell script
465 */
466 void AuxSave(const TString& escaped,
467 Bool_t asShellScript)
468 {
469 // Write plug-in to file
470 TFile* plug = TFile::Open(Form("%s_plugin.root", escaped.Data()),
471 "RECREATE");
472 fHandler->Write("plugin");
473 plug->Close();
474
475 std::ofstream o("Terminate.C");
476 if (!o) {
477 Error("GridHelper::AuxSave", "Failed to make terminate ROOT script");
478 return;
479 }
480
481 o << "// Generated by GridHelper\n"
482 << "Bool_t LoadLib(const char* libName)\n"
483 << "{\n"
484 << " if (gSystem->Load(libName) < 0) {\n"
485 << " Error(\"Terminate\", \"Failed to load library %s\",libName);\n"
486 << " return false;\n"
487 << " }\n"
488 << " Info(\"Terminate\",\"Loaded library %s\",libName);\n"
489 << " return true;\n"
490 << "}\n\n"
491 << "Bool_t LoadPar(const char* parName)\n"
492 << "{\n"
493 << " if (!AliAnalysisAlien::SetupPar(parName)) {\n"
494 << " Error(\"Terminate\",\"Failed to load PAR %s\",parName);\n"
495 << " return false;\n"
496 << " }\n"
497 << " Info(\"Terminate\",\"Loaded package %s\",parName);\n"
498 << " return true;\n"
499 << "}\n\n"
500 << "Bool_t Terminate()\n"
501 << "{\n"
502 << " // Name of job\n"
503 << " TString name = \"" << escaped << "\";\n\n"
504 << " // Load basic ROOT libraries\n"
505 << " gSystem->AddDynamicPath(\"/usr/lib\");\n"
506 << " if (gSystem->Load(\"libTree.so\") < 0) return false;\n"
507 << " if (gSystem->Load(\"libGeom.so\") < 0) return false;\n"
508 << " if (gSystem->Load(\"libVMC.so\") < 0) return false;\n"
509 << " if (gSystem->Load(\"libPhysics.so\") < 0) return false;\n"
510 << " if (gSystem->Load(\"libMinuit.so\") < 0) return false;\n\n"
511 << " // Load basic AliROOT libraries\n"
512 << " if (gSystem->Load(\"libSTEERBase\") < 0) return false;\n"
513 << " if (gSystem->Load(\"libESD\") < 0) return false;\n"
514 << " if (gSystem->Load(\"libAOD\") < 0) return false;\n"
515 << " if (gSystem->Load(\"libANALYSIS\") < 0) return false;\n"
516 << " if (gSystem->Load(\"libOADB\") < 0) return false;\n"
517 << " if (gSystem->Load(\"libANALYSISalice\") < 0) return false;\n\n";
518 // Now load libraries
519 o << " // Load libraries\n";
520 TIter nextLib(&fExtraLibs);
521 TObjString* lib = 0;
522 while ((lib = static_cast<TObjString*>(nextLib()))) {
523 const TString& libName = lib->String();
524 if (libName.Contains("libSTEERBase") ||
525 libName.Contains("libESD") ||
526 libName.Contains("libAOD") ||
527 libName.Contains("libANALYSIS") ||
528 libName.Contains("libOADB") ||
529 libName.Contains("libANALYSISalice")) continue;
530 if (libName.Contains(".so")) continue;
531 o << " if(!LoadLib(\"" << libName << "\")) return false;\n";
532 }
533 // Now load PARs
534 o << "\n"
535 << " // Load packages\n";
536 TIter nextPar(&fExtraPars);
537 TObjString* par = 0;
538 while ((par = static_cast<TObjString*>(nextPar()))) {
539 TString parName(par->String());
540 if (parName.EndsWith(".par")) parName.ReplaceAll(".par", "");
541 if (parName.Contains("STEERBase") ||
542 parName.Contains("ESD") ||
543 parName.Contains("AOD") ||
544 parName.Contains("ANALYSIS") ||
545 parName.Contains("OADB") ||
546 parName.Contains("ANALYSISalice")) continue;
547 o << " if (!LoadPar(\"" << parName << "\")) return false;\n";
548 }
549 // Now load scripts
550 o << "\n"
551 << " // Load sources\n";
552 TIter nextSrc(&fExtraSrcs);
553 TObjString* src = 0;
554 while ((src = static_cast<TObjString*>(nextSrc()))) {
555 const TString& srcName = src->String();
556 o << " gROOT->ProcessLine(\".L " << srcName << "+g\");\n";
557 }
558
559 // We're ready to load the analysis manager.
560 o << " \n"
561 << " // Load the analysis manager from file\n"
562 << " TString base(name);\n"
563 << " base.Append(\".root\");\n"
564 << " if (gSystem->AccessPathName(base.Data())) {\n"
565 << " // Couldn't read from current directory, try sub-dir\n"
566 << " TString sub(gSystem->ConcatFileName(name, base));\n"
567 << " if (gSystem->AccessPathName(sub)) {\n"
568 << " Error(\"Terminate\",\"Couldn't find manager file %s\","
569 << "base.Data());\n"
570 << " return false;\n"
571 << " }\n"
572 << " base = sub;\n"
573 << " }\n"
574 << " AliAnalysisManager* mgr= "
575 << "AliAnalysisAlien::LoadAnalysisManager(base);\n"
576 << " if (!mgr) {\n"
577 << " Error(\"Terminate\", \"Failed to load manager from %s\","
578 << "base.Data());\n"
579 << " return false;\n"
580 << " }\n"
581 << " if (!name.EqualTo(mgr->GetName())) {\n"
582 << " Error(\"Terminate\",\"Read manager %s is not %s\","
583 << "mgr->GetName(),name.Data());\n"
584 << " return false;\n"
585 << " }\n"
586 << " Info(\"Terminate\",\"Loaded analysis manager\");\n\n"
587 << " // Load plugin\n"
588 << " TFile* plug = TFile::Open(Form(\"%s_plugin.root\",name.Data()),"
589 << "\"READ\");\n"
590 << " if (!plug) {\n"
591 << " Error(\"Terminate\",\"Failed to open %s_plugin.root\","
592 << "name.Data());\n"
593 << " return false;\n"
594 << " }\n"
595 << " AliAnalysisAlien* handler = "
596 << "static_cast<AliAnalysisAlien*>(plug->Get(\"plugin\"));\n"
597 << " if (!handler) {\n"
598 << " Error(\"Terminate\",\"Failed to load plugin\");\n"
599 << " return false;\n"
600 << " }\n"
601 << " Info(\"Terminate\",\"Setting grid handler\");\n"
602 << " handler->SetRunMode(\"terminate\");\n"
603 << " mgr->SetGridHandler(handler);\n\n"
604 << " // Run the terminate job\n"
605 << " Info(\"Terminate\",\"Starting terminate job\");\n"
606 << " if (mgr->StartAnalysis(\"grid\") < 0) return false;\n"
607 << " return true;\n"
608 << "}\n"
609 << "// \n"
610 << "// EOF\n"
611 << "//\n"
612 << std::endl;
613 o.close();
614
615 if (!asShellScript) return;
616
617 std::ofstream s("terminate.sh");
618 if (!s) {
619 Error("GridHelper::AuxSave", "Failed to make terminate shell script");
620 return;
621 }
622 s << "#!/bin/sh\n"
623 << "# Generated by GridHelper\n"
624 << "nam=" << escaped << "\n"
625 << "scr=Terminate.C\n"
626 << "mgr=$name.root\n"
627 << "\n"
628 << "if test ! -f $scr || test ! -f $mgr ; then\n"
629 << " if test ! -d $nam ; then\n"
630 << " echo \"Directory $nam not found\"\n"
631 << " exit 1\n"
632 << " fi\n\n"
633 << " if test ! -f $nam/$scr || test -f $nam/$scr ; then\n"
634 << " echo \"Script $nam/$scr, manager $nam/$scr not found\"\n"
635 << " exit 1\n"
636 << " fi\n\n"
637 << " (cd $nam && aliroot -l $scr)\n"
638 << "fi\n\n"
639 << " aliroot -l $scr\n"
640 << "#\n"
641 << "# EOF\n"
642 << "#\n"
643 << std::endl;
644 s.close();
645 gSystem->Exec("chmod a+x terminate.sh");
646 }
fdfd93b4 647};
648#endif
649//
650// EOF
651//