]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/trains/ProofHelper.C
/home/abercuci/usr/AliRoot/REF/.git/COMMIT_EDITMSG
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / trains / ProofHelper.C
CommitLineData
fdfd93b4 1/**
2 * @file ProofHelper.C
3 * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
4 * @date Tue Oct 16 18:58:37 2012
5 *
6 * @brief
7 *
8 *
9 * @ingroup pwglf_forward_trains_helper
10 *
11 */
12#ifndef PROOFHELPER_C
13#define PROOFHELPER_C
14#include "Helper.C"
15#ifndef __CINT__
16# include "OutputUtilities.C"
17# include "ParUtilities.C"
18# include "ChainBuilder.C"
19# include <TUrl.h>
20# include <TString.h>
21# include <TProof.h>
22# include <TProofLog.h>
23# include <TProofDebug.h>
24# include <AliAnalysisManager.h>
25# include <TEnv.h>
26# include <TChain.h>
8449e3e0 27// For SendFile
28# include <TSystem.h>
29# include <TSlave.h>
30# include <TSocket.h>
31# include <cerrno>
fdfd93b4 32#else
33class TUrl;
34class TChain;
35#endif
36
37// ===================================================================
38/**
39 * Handle analysis on a Proof farm.
40 *
41 * This helper is triggered by URIs of the form
42 *
43 * @code
44 * proof://[<user>@]<host>[:<port>]/<dsname>[?<options>][#<treename>]
45 * @endcode
46 * where
47 * <dl>
33438b4c 48 * <dt>&lt;user&gt;</dt>
fdfd93b4 49 * <dd>Optional user name</dd>
33438b4c 50 * <dt>&lt;host&gt;</dt>
fdfd93b4 51 * <dd>PROOF cluster master host</dd>
33438b4c 52 * <dt>&lt;port&gt;</dt>
fdfd93b4 53 * <dd>Optional PROOF cluster port on master host</dd>
33438b4c 54 * <dt>&lt;dsname&gt;</dt>
fdfd93b4 55 * <dd>Data set name</dd>
33438b4c 56 * <dt>&lt;treename&gt;</dt>
fdfd93b4 57 * <dd>Optional tree name in data set, often <tt>esdTree</tt> or
58 * <tt>aodTree</tt></dd>
33438b4c 59 * <dt>&lt;options&gt;</dt>
fdfd93b4 60 * <dd>List of options separated by an &amp;
61 * <dl>
62 * <dt><tt>workers=N[x]</tt></dt>
63 * <dd>Set the number of workers to use. If <tt>x</tt> is appended,
64 * then it's maximum number of workers per slave</dd>
65 * <dt><tt>dsname</tt>[=&lt;output dataset&gt;]</dt>
66 * <dd>Register tree output (e.g., AOD) as a new data set on the
67 * PROOF cluster. If &lt;output dataset&gt; is not specified, take
68 * the name of the train.</dd>
69 * <dt><tt>par[=all]</tt></dt>
70 * <dd>Use PAR files. If the value <tt>all</tt> is given, then also
71 * PAR files of STEERBase, ESD, AOD, ANALYSIS, OADB, ANALYSISalice
72 * are used. </dd>
73 * <dt><tt>mode=[default,rec,sim,train,custom]</tt></dt>
74 * <dd>Set the AliROOT mode. If not specified <tt>default</tt>
33438b4c 75 * is assumed. See also CreateAliROOTPar</dd>
fdfd93b4 76 * <dt><tt>storage=&lt;url&gt;</tt></dt>
77 * <dd>Specify a non-default storage location for special output
78 * (e.g., AOD trees). &lt;url&gt; should be a valid XRootd
79 * server URI accessible to the slaves - e.g.,
80 * <tt>root://lxplus.cern.ch:10930//tmp</tt>.</dd>
81 * </dl>
82 * </dd>
83 * </dl>
84 *
85 * @ingroup pwglf_forward_trains_helper
86 */
87struct ProofHelper : public Helper
88{
89 /**
90 * Constructor
91 *
92 * @param url Url
33438b4c 93 * @param verbose Verbosity level
fdfd93b4 94 */
95 ProofHelper(const TUrl& url, Int_t verbose)
96 : Helper(url, verbose),
46b25775 97 fExtraLibs(""),
98 fExtraPars(""),
99 fExtraSrcs(""),
fdfd93b4 100 fUsePars(false),
8449e3e0 101 fBasePars(false),
102 fAuxFiles()
fdfd93b4 103 {
c7625069 104 fOptions.Add("workers", "N[x]", "Number of workers to use", 0);
91aef4e8 105 fOptions.Add("dsname", "NAME", "Make output dataset", "");
fdfd93b4 106 fOptions.Add("par", "tasks|all", "Use par files", "tasks");
107 fOptions.Add("mode", "default|rec|sim", "AliROOT mode", "default");
91aef4e8 108 fOptions.Add("storage", "URL", "Location for external storage", "");
109 fOptions.Add("wrapper", "CMD", "Wrapper command", "");
110 fOptions.Add("clear", "PKGS", "Clear packages ','-separated", "");
46b25775 111 fOptions.Add("reset", "soft|hard", "Reset cluster", "hard");
6ee074b7 112 fOptions.Add("feedback", "Enable feedback mechanism");
fdfd93b4 113 if (!fUrl.GetUser() || fUrl.GetUser()[0] == '\0')
114 fUrl.SetUser(gSystem->GetUserInfo()->fUser);
8449e3e0 115 fAuxFiles.SetOwner();
116 }
117 ProofHelper(const ProofHelper& o)
118 : Helper(o),
119 fExtraLibs(""),
120 fExtraPars(""),
121 fExtraSrcs(""),
122 fUsePars(false),
123 fBasePars(false),
124 fAuxFiles()
125 {}
126 ProofHelper& operator=(const ProofHelper& o)
127 {
128 if (&o == this) return *this;
129 Helper::operator=(o);
130 fExtraLibs = o.fExtraLibs;
131 fExtraPars = o.fExtraPars;
132 fExtraSrcs = o.fExtraSrcs;
133 fUsePars = o.fUsePars;
134 fBasePars = o.fBasePars;
135 // fAuxFiles;
136 return *this;
fdfd93b4 137 }
46b25775 138 /**
139 * Destructor
140 */
fdfd93b4 141 virtual ~ProofHelper() {}
142 /**
143 * Load a library/PAR/script
144 *
145 * @param name Name
fdfd93b4 146 * @param slaves If true, also load on slaves
147 *
148 * @return true on success
149 */
150 virtual Bool_t LoadLibrary(const TString& name,
151 Bool_t slaves=true)
152 {
bfab35d9 153 Bool_t isBase = false;
154 if (!fBasePars) {
155 if (name.EqualTo("STEERBase") ||
156 name.EqualTo("ESD") ||
157 name.EqualTo("AOD") ||
158 name.EqualTo("ANALYSIS") ||
159 name.EqualTo("OADB") ||
6ee074b7 160 name.EqualTo("ANALYSISalice"))
bfab35d9 161 isBase = true;
162 }
bfab35d9 163 if (!fUsePars || isBase) {
fdfd93b4 164 Int_t ret = gSystem->Load(MakeLibraryName(name));
165 if (ret < 0) return false;
166 if (slaves) fExtraLibs.Append(Form(":%s", name.Data()));
167 }
168 else {
169 if (!ParUtilities::Find(name)) {
170 Error("ProofHelper::LoadLibrary", "Failed to find PAR file %s",
171 name.Data());
172 return false;
173 }
174 if (!ParUtilities::Build(name)) {
175 Error("ProofHelper::LoadLibrary", "Failed to build PAR file %s",
176 name.Data());
177 return false;
178 }
179 if (gProof->UploadPackage(name.Data(), TProof::kRemoveOld) < 0) {
180 Error("ProofHelper::LoadLibrary", "Failed to upload PAR file %s",
181 name.Data());
182 return false;
183 }
184 fExtraPars.Append(Form(":%s", name.Data()));
185 }
186 return true;
187 }
188 /**
189 * Load a source file, and compile it
190 *
191 * @param name Name of the source file
33438b4c 192 * @param copy If true, copy not link
fdfd93b4 193 *
194 * @return true on success
195 */
ddcc1bbd 196 virtual Bool_t LoadSource(const TString& name, bool copy=false)
fdfd93b4 197 {
ddcc1bbd 198 if (!Helper::LoadSource(name, copy)) return false;
fdfd93b4 199 fExtraSrcs.Append(Form(":%s", gSystem->BaseName(name.Data())));
200 return true;
201 }
202 /**
203 * Set-up to load the AliROOT libraries
204 *
fdfd93b4 205 * @return true on success
206 */
207 virtual Bool_t LoadAliROOT()
208 {
209 if (!gSystem->Getenv("ALICE_ROOT")) {
210 Error("ProofHelper::LoadAliROOT", "Local AliROOT not available");
211 return false;
212 }
213
214 Bool_t tmp = fUsePars;
215 fUsePars = fBasePars;
216 if (!LoadLibrary("STEERBase")) return false;
217 if (!LoadLibrary("ESD")) return false;
218 if (!LoadLibrary("AOD")) return false;
219 if (!LoadLibrary("ANALYSIS")) return false;
220 if (!LoadLibrary("OADB")) return false;
221 if (!LoadLibrary("ANALYSISalice")) return false;
222 fUsePars = tmp;
223
224 return CreateAliROOTPar();
225 }
226 /**
227 * Get the name of the AliROOT par file to use
228 *
229 * @return String
230 */
231 virtual const char* AliROOTParName() const
232 {
233 return "ALIROOT";
234 }
235 /**
236 * Create an AliROOT par file from the executing AliROOT. This PAR
237 * file basically uses the environment of the client - that is, we
238 * assume that the used AliROOT is accessible on the slaves - e.g.,
239 * via an NFS export.
240 *
241 * Note, the SETUP.C script take one argument - a TList of TNamed
242 * parameters. Parameters processed are
243 *
244 * - ALIROOT_MODE=[default,aliroot,rec,sim,train]
245 * - default: Load base analysis libraries
246 * - aliroot: Load $ALICE_ROOT/macros/loadlibs.C
247 * - rec: Load $ALICE_ROOT/macros/loadlibsrec.C
248 * - sim: Load $ALICE_ROOT/macros/loadlibssim.C
249 * - ALIROOT_EXTRA_LIBS Colon separated list of additional (Ali)ROOT
250 * libraries to load on the slaves.
251 *
252 * The generated PAR file is uploaded but not enabled until we have
253 * populated fExtraLibs. The enabling takes place at the end of the
254 * set-up.
255 *
256 * @return true on success, false otherwise. */
257 virtual Bool_t CreateAliROOTPar()
258 {
259 if (fBasePars) return true;
260
261 TString parName(AliROOTParName());
46b25775 262 TString parFile(Form("%s.par", parName.Data()));
263
264 // --- Check if we have the drirectory already -------------------
265 if (gSystem->AccessPathName(parName.Data()) == 0) {
266 // Let's remove it to get a clean slate
267 if (gSystem->Exec(Form("rm -rf %s", parName.Data())) != 0) {
268 Error("ProofHelper", "Failed to remove %s", parName.Data());
269 return false;
270 }
271 }
272 // --- Check if the PAR file is there, and remove it if so -------
273 if (gSystem->AccessPathName(parFile.Data()) == 0) {
274 if (gSystem->Unlink(parFile.Data()) != 0) {
275 Error("ProofHelper::CreateAliROOTPar", "Failed to remove %s",
276 parFile.Data());
277 return false;
278 }
279 }
280
281
fdfd93b4 282 // Set-up directories
283 if (gSystem->MakeDirectory(parName) < 0) {
284 Error("ProofHelper::CreateAliROOTPar", "Could not make directory '%s'",
285 parName.Data());
286 return false;
287 }
288
289 if (gSystem->MakeDirectory(Form("%s/PROOF-INF", parName.Data()))) {
290 Error("ProofHelper::CreateAliROOTPar",
291 "Could not make directory %s/PROOF-INF",
292 parName.Data());
293 return false;
294 }
295
296 std::ofstream b(Form("%s/PROOF-INF/BUILD.sh",parName.Data()));
297 if (!b) {
298 Error("ProofHelper::CreateAliROOTPar",
299 "Failed to make BUILD.sh shell script");
300 return false;
301 }
302 b << "#!/bin/sh\n\n"
303 << "# echo Nothing to do\n"
304 << "exit 0\n"
305 << std::endl;
306 b.close();
307 gSystem->Exec(Form("chmod a+x %s/PROOF-INF/BUILD.sh",parName.Data()));
308
309 std::ofstream s(Form("%s/PROOF-INF/SETUP.C", parName.Data()));
310 if (!s) {
311 Error("ProofHelper::CreateAliROOTPar",
312 "Failed to make SETUP.C ROOT script");
313 return false;
314 }
315 s << "void SETUP(TList* opts) {\n"
316 << " gSystem->Setenv(\"ALICE\",\""
317 << gSystem->Getenv("ALICE") << "\");\n"
318 << " gSystem->Setenv(\"ALICE_ROOT\",\""
319 << gSystem->Getenv("ALICE_ROOT") << "\");\n"
320 << " gSystem->Setenv(\"ALICE_TARGET\",\""
321 << gSystem->Getenv("ALICE_TARGET") << "\");\n"
322 << " gSystem->AddDynamicPath("
323 << "\"$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET)\");\n";
324 if (gSystem->Getenv("OADB_PATH"))
325 s << " gSystem->Setenv(\"OADB_PATH\",\""
326 << gSystem->Getenv("OADB_PATH") << "\");\n";
327 s << " \n"
328 << " // Info(\"SETUP\",\"Loading ROOT libraries\");\n"
329 << " gSystem->Load(\"libTree\");\n"
330 << " gSystem->Load(\"libGeom\");\n"
331 << " gSystem->Load(\"libVMC\");\n"
332 << " gSystem->Load(\"libPhysics\");\n"
333 << " gSystem->Load(\"libMinuit\");\n"
334 << " \n";
335 s << " // Info(\"SETUP\",\"Parameter list:\");\n"
336 << " if (!opts) return;\n"
337 << " //opts->ls();\n"
338 << " \n";
339 s << " TObject* par = opts->FindObject(\"ALIROOT_MODE\");\n"
340 << " if (par) {\n"
341 << " // Info(\"SETUP\",\"ALIROOT mode: %s\", par->GetTitle());\n"
342 << " TString mode(par->GetTitle());\n"
343 << " if (mode.EqualTo(\"default\",TString::kIgnoreCase)) {\n"
344 << " gSystem->Load(\"libSTEERBase\");\n"
345 << " gSystem->Load(\"libESD\");\n"
346 << " gSystem->Load(\"libAOD\");\n"
347 << " gSystem->Load(\"libANALYSIS\");\n"
348 << " gSystem->Load(\"libOADB\");\n"
349 << " gSystem->Load(\"libANALYSISalice\");\n"
350 << " }\n"
351 << " else if (mode.EqualTo(\"aliroot\",TString::kIgnoreCase)) \n"
352 << " gROOT->Macro(\"$ALICE_ROOT/macros/loadlibs.C\");\n"
353 << " else if (mode.EqualTo(\"rec\",TString::kIgnoreCase)) \n"
354 << " gROOT->Macro(\"$ALICE_ROOT/macros/loadlibsrec.C\");\n"
355 << " else if (mode.EqualTo(\"sim\",TString::kIgnoreCase)) \n"
356 << " gROOT->Macro(\"$ALICE_ROOT/macros/loadlibssim.C\");\n"
357 << " else if (mode.EqualTo(\"train\",TString::kIgnoreCase)) \n"
358 << " gROOT->Macro(\"$ALICE_ROOT/macros/loadlibstrain.C\");\n"
359 << " else if (mode.EqualTo(\"custom\",TString::kIgnoreCase)) \n"
360 << " gROOT->Macro(\"$ALICE_ROOT/macros/loadlibstrain.C\");\n"
361 << " }\n"
362 << " \n";
363 s << " par = opts->FindObject(\"ALIROOT_EXTRA_LIBS\");\n"
364 << " if (par) {\n"
365 << " Info(\"SETUP\",\"Libaries to load: %s\n\",par->GetTitle());\n"
366 << " TString tit(par->GetTitle());\n"
367 << " TObjArray* tokens = tit.Tokenize(\":\");\n"
368 << " TObject* lib = 0;\n"
369 << " TIter next(tokens);\n"
370 << " while ((lib = next())) {\n"
371 << " TString libName(lib->GetName());\n"
372 << " if (!libName.BeginsWith(\"lib\")) libName.Prepend(\"lib\");\n"
373 << " // Info(\"SETUP\",\"Loading %s ...\",libName.Data());\n"
374 << " gSystem->Load(Form(\"lib%s\",lib->GetName()));\n"
375 << " }\n"
376 << " }\n"
377 << "}\n"
378 << std::endl;
379 s.close();
380
46b25775 381 Int_t ret = gSystem->Exec(Form("tar -czf %s %s",
382 parFile.Data(), parName.Data()));
fdfd93b4 383 if (ret != 0) {
46b25775 384 Error("ProofHelper::CreateAliROOTPar", "Failed to pack up PAR file %s",
385 parFile.Data());
fdfd93b4 386 return false;
387 }
388
46b25775 389 ret = gProof->UploadPackage(parFile.Data(),TProof::kRemoveOld);
fdfd93b4 390 if (ret != 0) {
391 Error("ProofHelper::CreateAliROOTPar",
392 "Failed to upload the AliROOT PAR file");
393 return false;
394 }
395 // Note, the PAR isn't enabled until much later when we've
396 // collected all the needed libraries in fExtraLibs
397 return true;
398 }
399 /**
400 * Get the mode identifier
401 *
402 * @return Always kProof
403 */
404 virtual UShort_t Mode() const { return kProof; }
405 /**
406 * Get the mode string used for AliAnalysisManager::StartAnalysis
407 */
408 virtual const char* ModeString() const { return "proof"; }
409 /**
410 * Set-up done before task set-ups
411 *
412 * @return true on success
413 */
414 virtual Bool_t PreSetup()
415 {
416 // --- Set prefered GSI method ---------------------------------
417 gEnv->SetValue("XSec.GSI.DelegProxy", "2");
418
46b25775 419 // --- Add ALICE_ROOT directory to search path for packages ----
420 // Info("ProofHelper::PreSetup", "Set location of packages");
fdfd93b4 421 gEnv->SetValue("Proof.GlobalPackageDirs",
422 Form("%s:%s",
423 gEnv->GetValue("Proof.GlobalPackageDirs", "."),
424 gSystem->Getenv("ALICE_ROOT")));
425
46b25775 426 // --- Forming the URI we use to connect with --------------------
427 TUrl connect(fUrl);
428 connect.SetAnchor("");
429 connect.SetFile("");
430 connect.SetOptions("");
431
432 // --- Check if we need to reset first ---------------------------
433 if (fOptions.Has("reset")) {
434 TString reset = fOptions.Get("reset");
435 Bool_t hard = (reset.IsNull() ||
436 reset.EqualTo("hard", TString::kIgnoreCase));
437 Info("ProofHelper::PreSetup", "Doing a %s reset of %s",
438 hard ? "hard" : "soft", connect.GetUrl());
439 TProof::Reset(connect.GetUrl(), hard);
440 Int_t secs = 3;
441 Info("ProofHelper::PreSetup",
442 "Waiting for %d second%s for things to settle", secs,
443 secs > 1 ? "s" : "");
444 gSystem->Sleep(1000*secs);
445 }
446
447 // --- Check if we're using a wrapper ----------------------------
448 if (fOptions.Has("wrapper")) {
449 TString wrapper = fOptions.Get("wrapper");
450 if (wrapper.IsNull())
451 // In case of no argument, use GDB
452 // Just run and backtrace
453 wrapper = "/usr/bin/gdb --batch -ex run -ex bt --args";
454 Info("ProofHelper::PreSetup", "Using wrapper command: %s",
455 wrapper.Data());
456 TProof::AddEnvVar("PROOF_WRAPPERCMD", wrapper);
457 }
458
fdfd93b4 459 // --- PAR parameters --------------------------------------------
460 fUsePars = fOptions.Has("par");
461 fBasePars = (fUsePars &&
462 fOptions.Get("par").EqualTo("all",TString::kIgnoreCase));
463
464 // --- Connect to the cluster ------------------------------------
fdfd93b4 465 TString opts;
466 if (fOptions.Has("workers"))
467 opts.Append(Form("workers=%s", fOptions.Get("workers").Data()));
468
469 Info("ProofHelper::PreSetup", "Connecting to %s with %soptions %s",
470 connect.GetUrl(),
471 opts.IsNull() ? "no " : "",
472 opts.Data());
473 TString proto(connect.GetProtocol());
474 if (proto.BeginsWith("lite") && fOptions.Has("workers"))
475 TProof::Open(opts);
476 else
477 TProof::Open(connect.GetUrl(), opts);
478 // TProof::Open(connect.GetHost(), opts);
479 if (!gProof) {
480 Error("ProofHelper::PreSetup", "Failed to open Proof connection %s",
481 connect.GetUrl());
482 return false;
483 }
46b25775 484
485 // --- Check if we need to clear packages ------------------------
486 if (fOptions.Has("clear")) {
487 TString pkgs = fOptions.Get("clear");
488 if (pkgs.IsNull() || pkgs.EqualTo("all", TString::kIgnoreCase)) {
489 // No value given, clear all
490 if (gProof->ClearPackages() != 0)
491 Warning("ProofHelper::PreSetup", "Failed to lear all packages");
492 }
493 else {
494 // Tokenize on ',' and clear each package
495 TObjArray* pars = pkgs.Tokenize(",");
496 TObject* pkg = 0;
497 TIter next(pars);
498 while ((pkg = next())) {
499 if (gProof->ClearPackage(pkg->GetName()) != 0)
500 Warning("ProofHelper::PreSetup", "Failed to clear package %s",
501 pkg->GetName());
502 }
503 pars->Delete();
504 }
505 }
fdfd93b4 506 return true;
507 }
508 /**
509 * Set-up done after the task set-ups
510 *
511 * @return true on success
512 */
513 virtual Bool_t PostSetup()
514 {
515 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
516 if (!mgr) {
517 Error("ProofHelper::PostSetup", "No analysis manager defined");
518 return false;
519 }
520
521 // --- Check for output ------------------------------------------
522 if (fOptions.Has("dsname"))
523 OutputUtilities::RegisterDataset(fOptions.Get("dsname"));
524 if (fOptions.Has("storage"))
525 OutputUtilities::RegisterStorage(fOptions.Get("storage"));
526
6ee074b7 527 // --- Check for feedback mechanism ------------------------------
528 if (!fOptions.Has("feedback"))
529 gProof->ClearFeedback();
530
fdfd93b4 531 // --- If we are not using PARs for Base, enable special PAR -----
532 if (!fBasePars) {
533 TString tmp(fExtraLibs.Strip(TString::kBoth,':'));
534 TList* params = new TList;
535 params->SetOwner(true);
536 params->Add(new TNamed("ALIROOT_EXTRA_LIBS", tmp.Data()));
537 if (fOptions.Has("mode"))
538 params->Add(new TNamed("ALIROOT_MODE", fOptions.Get("mode").Data()));
539 else
540 params->Add(new TNamed("ALIROOT_MODE", "default"));
541 Int_t ret = gProof->EnablePackage(AliROOTParName(), params, true);
542 if (ret < 0) {
543 Error("ProofHelper::EnableAliROOT", "Failed to enable AliROOT PAR %s",
544 AliROOTParName());
545 return false;
546 }
547 }
8449e3e0 548
549 // --- Make PAR file of Aux Files --------------------------------
550 if (fAuxFiles.GetEntries() > 0) {
551 TString name = TString::Format("%s_auxfiles", mgr->GetName());
552 ParUtilities::MakeAuxFilePAR(fAuxFiles, name);
553
554 if (gProof->UploadPackage(name.Data(), TProof::kRemoveOld) < 0)
555 Error("ProofHelper::PostSetup", "Failed to upload PAR file %s",
556 name.Data());
557 else
558 fExtraPars.Append(Form(":%s", name.Data()));
559 }
fdfd93b4 560
561 // --- Load par files --------------------------------------------
562 TString tmp = fExtraPars.Strip(TString::kBoth,':');
563 TObjArray* pars = tmp.Tokenize(":");
564 TObject* obj = 0;
565 TIter next(pars);
566 while ((obj = next())) {
46b25775 567 // Enable the package, but do not build on client - already done
568 Int_t ret = gProof->EnablePackage(obj->GetName(), true);
fdfd93b4 569 if (ret < 0) {
570 Error("ProofHelper::PostSetup", "Failed to enable PAR %s",
571 obj->GetName());
572 return false;
573 }
574 }
575
576 // --- Load extra sources ----------------------------------------
577 TString tmp2 = fExtraSrcs.Strip(TString::kBoth, ':');
578 TObjArray* srcs = tmp2.Tokenize(":");
579 TIter next2(srcs);
580 while ((obj = next())) {
581 Int_t ret = gProof->Load(Form("%s++g", obj->GetName()), true);
582 if (ret < 0) {
583 Error("ProofHelper::PostSetup", "Failed to compile %s", obj->GetName());
584 return false;
585 }
586 }
587 return true;
588 }
589 /**
590 * Start the analysis
591 *
592 * @param nEvents Number of events to analyse
593 *
594 * @return The return value of AliAnalysisManager::StartAnalysis
595 */
596 virtual Long64_t Run(Long64_t nEvents=-1)
597 {
598 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
599 gProof->SetLogLevel(TMath::Max(fVerbose-2,0),
600 /* TProofDebug::kPacketizer| */
601 TProofDebug::kLoop|
602 /* TProofDebug::kSelector|
603 TProofDebug::kOutput|
604 TProofDebug::kInput|
605 TProofDebug::kGlobal|*/
606 TProofDebug::kPackage);
607 TString dsName(fUrl.GetFile());
608 // if (fUrl.GetAnchor() && fUrl.GetAnchor()[0] != '\0')
609 // dsName.Append(Form("#%s", fUrl.GetAnchor()));
6ee074b7 610 Info("Run", "Output objects registered with PROOF:");
611 gProof->GetOutputList()->ls();
fdfd93b4 612 Long64_t ret = mgr->StartAnalysis(fUrl.GetProtocol(), dsName, nEvents);
613
46b25775 614 if (fVerbose > 10)
fdfd93b4 615 TProof::Mgr(fUrl.GetUrl())->GetSessionLogs()->Save("*","proof.log");
616 return ret;
617 }
6ee074b7 618#if 0
619 Bool_t AddMonitor(const TString& path)
620 {
621 if (path.IsNull()) return true;
622
623 TObjArray* tokens = path.Tokenize("/");
624 Int_t nTokens = tokens->GetEntries();
625 if (nTokens < 2) {
626 Error("AddMonitor", "Monitors must be of the form:\n"
627 " <task>[:<slot>]/<name>\n"
628 " <task>[:<slot>]/<path>/<name>");
629 return false;
630 }
631 // --- Get the manager
632 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
633
634 // --- Extract task and possibly slot number
635 TString& sTask = static_cast<TObjString*>(tokens->At(0))->String();
636 Int_t slotNo = 0;
637 Ssiz_t colon = sTask.Index(":");
638 if (colon != kNPOS) {
639 TString sSlot = sTask(colon+1, sTask.Length()-colon-1);
640 if (!sSlot.IsNull()) slotNo = sSlot.Atoi();
641 sTask.Remove(colon, sTask.Length()-colon);
642 }
643
644 AliAnalysisTask* task = mgr->GetTask(sTask);
645 if (!task) {
646 Error("AddMonitor", "Task \"%s\" not registered with manager",
647 sTask.Data());
648 return false;
649 }
650 AliAnalysisDataSlot* slot = task->GetOutputSlot(slotNo);
651 if (!slot) {
652 Error("AddMonitor", "Task \"%s\" does not have an output slot at %d",
653 task->GetName(), slotNo);
654 return false;
655 }
656 AliAnalysisDataContainer* cont = slot->GetContainer();
657 if (!cont) {
658 Error("AddMonitor", "Output slot %d of task \"%s\" has no container",
659 slotNo, task->GetName());
660 return false;
661 }
662 Int_t idx = 1;
663 TString& first = static_cast<TObjString*>(tokens->At(idx))->String();
664 if (first.EqualTo(cont->GetName())) {
665 idx++;
666 }
667 TObject* data = cont->GetData();
668 TObject* obj = data;
669 for (; idx < nTokens; idx++) {
670 }
671 return true;
672 }
673#endif
fdfd93b4 674 /**
675 * Print information to standard output
676 *
677 * @param option
678 */
679 virtual void Print(Option_t* option="") const
680 {
681 Helper::Print(option);
682 std::cout << std::boolalpha
683 << " --- Other settings -------\n"
684 << " Extra libraries : " << fExtraLibs << "\n"
685 << " Extra PARs : " << fExtraPars << "\n"
686 << " Extra sources : " << fExtraSrcs << "\n"
687 << " Use PARs of tasks: " << fUsePars << "\n"
688 << " Use PARs of base : " << fBasePars
689 << std::noboolalpha << std::endl;
690 }
8449e3e0 691 /**
692 * Link an auxilary file to working directory
693 *
694 * @param name Name of the file
695 * @param copy Copy rather than link
696 *
697 * @return true on success
698 */
699 virtual Bool_t AuxFile(const TString& name, bool copy=false)
700 {
701 Bool_t ret = Helper::AuxFile(name, copy);
702 if (!name.BeginsWith("/")) {
703 fAuxFiles.Add(new TObjString(name));
704 }
705#if 0
706 if (ret && name.EndsWith(".root")) {
707 TFile* file = TFile::Open(name, "READ");
708 if (file) {
709 Info("AuxFile", "Adding input file %s", name.Data());
710 gProof->AddInputData(file, true);
711 }
712 }
713#endif
714 return ret;
715 }
716 Int_t SendFile(const TString& fileName)
717 {
718 Int_t bufSize = 32768;
719 Char_t buf[bufSize];
720 Long64_t size = 0;
721 Long_t id = 0, flags = 0, modtime = 0;
722 if (gSystem->GetPathInfo(fileName.Data(), &id, &size, &flags, &modtime)==1
723 || size <= 0) {
724 Error("SendFile", "Cannot stat %s", fileName.Data());
725 return -1;
726 }
727 TString fn(gSystem->BaseName(fileName.Data()));
728 TList* slaves = 0; // gProof->GetListOfActiveSlaves(); - protected
729 TIter next(slaves);
730 TSlave* sl = 0;
731 Int_t ret = 0;
732 Int_t fd = open(fileName.Data(), O_RDONLY);
733 while ((sl = static_cast<TSlave*>(next()))) {
734 if (!sl->IsValid()) continue;
735 if (sl->GetSlaveType() != TSlave::kSlave) continue;
736
737 // Always binary (first 1), never forward (last 0).
738 snprintf(buf,bufSize,"%s %d %lld %d", fn.Data(), 1, size, 0);
739 if (sl->GetSocket()->Send(buf, kPROOF_SENDFILE) == -1) {
740 Warning("SendFile", "Could not send kPROOF_SENDFILE request");
741 continue;
742 }
743
744 // Go to the beginning of the file
745 lseek(fd, 0, SEEK_SET);
746 Int_t len = 0;
747 do {
748 while ((len = read(fd, buf, bufSize)) < 0 &&
749 TSystem::GetErrno() == EINTR)
750 TSystem::ResetErrno();
751 if (len < 0) {
752 Error("SendFile", "error reading input");
753 close(fd);
754 return -1;
755 }
756 if (len > 0 && sl->GetSocket()->SendRaw(buf, len) == -1) {
757 Error("SendFile", "error writing to slave");
758 sl = 0;
759 break;
760 }
761 } while (len > 0);
762 ret ++;
763
764 // Wait for slave - private
765 // if (sl) gProof->Collect(sl,gEnv->GetValue("Proof.CollectTimeout",-1));
766 }
767
768 // Close the file
769 close(fd);
770
771 return ret;
772 }
fdfd93b4 773 /**
774 * Path of output
775 *
776 * @return Path to output - possibly a data set
777 */
778 virtual TString OutputPath() const
779 {
780 TString ret;
781 if (fOptions.Has("dsname")) {
782 ret = Form("/%s/%s/", gProof->GetGroup(), gProof->GetUser());
783 ret.Append(OutputUtilities::RegisteredDataset());
784 }
785 return ret;
786 }
787 /**
788 * @return URL help string
789 */
790 virtual const Char_t* UrlHelp() const
791 {
792 return "proof://<host>[:<port>]/[<dataset>|<path>][?<options>][#<treeName>]";
793 }
794 /**
795 * @return Short description
796 */
797 virtual const char* Desc() const { return "PROOF"; }
798 TString fExtraLibs;
799 TString fExtraPars;
800 TString fExtraSrcs;
801 Bool_t fUsePars;
802 Bool_t fBasePars;
8449e3e0 803 TList fAuxFiles;
fdfd93b4 804};
805#endif
806//
807// EOF
808//