]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/analysis2/trains/TrainSetup.C
Fixed references from PWG2 -> PWGLF - very efficiently done using ETags.
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / trains / TrainSetup.C
CommitLineData
56199f2b 1/**
bd6f5206 2 * @defgroup pwglf_forward_trains Trains
56199f2b 3 *
bd6f5206 4 * @ingroup pwglf_forward
56199f2b 5 */
1d86b7ca 6/**
7 * @file TrainSetup.C
8 * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
9 * @date Wed Mar 23 12:12:00 2011
10 *
11 * @brief
12 *
bd6f5206 13 * @ingroup pwglf_forward_trains
1d86b7ca 14 *
15 */
16
17#ifndef __CINT__
18#include <fstream>
19#include <iostream>
20
21#include <TAlienCollection.h>
22#include <TArrayI.h>
23#include <TChain.h>
24#include <TDatime.h>
25#include <TEnv.h>
26#include <TFile.h>
27#include <TGrid.h>
28#include <TList.h>
29#include <TObjString.h>
30#include <TProof.h>
31#include <TString.h>
32#include <TSystem.h>
33#include <TSystemDirectory.h>
34#include <TSystemFile.h>
35#include <TROOT.h>
36
37#include <AliAODHandler.h>
38#include <AliAODInputHandler.h>
39#include <AliAnalysisDataContainer.h>
40#include <AliAnalysisManager.h>
41#include <AliAnalysisAlien.h>
42#include <AliESDInputHandler.h>
43#include <AliMCEventHandler.h>
44#include <AliVEventHandler.h>
45#include <AliPhysicsSelection.h>
46#include <AliCentralitySelectionTask.h>
47#else
48class TArrayI;
49class TChain;
50class AliAnalysisManager;
51#endif
52
53//====================================================================
54/**
55 * Generic set-up of an analysis train using the grid-handler (AliEn plugin).
56 *
57 * Users should define a class that derives from this. The class
58 * should implement the member function CreateTasks to add needed
59 * tasks to the train
60 *
61 * @code
62 * // MyTrain.C
63 * class MyTrain : public TrainSetup
64 * {
65 * public:
66 * MyTrain(Bool_t dateTime = false,
67 * UShort_t year = 0,
68 * UShort_t month = 0,
69 * UShort_t day = 0,
70 * UShort_t hour = 0,
71 * UShort_t min = 0)
72 * : TrainSetup("My train", dateTime, year, month, day, hour, min)
73 * {}
74 * void Run(const char* type, const char* mode, const char* oper,
75 * Int_t nEvents=-1, Bool_t mc=false,
76 * Bool_t usePar=false)
77 * {
78 * Exec(type, mode, oper, nEvents, mc, usePar);
79 * }
80 * protected:
81 * void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)
82 * {
83 * AliAnalysisManager::SetCommonFileName("my_analysis.root");
84 * LoadLibrary("MyAnalysis", mode, par, true);
85 * Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
86 * gROOT->Macro("MyAnalysis.C");
87 * }
88 * };
89 * @endcode
90 *
91 * This can then be run like
92 *
93 * @verbatim
94 * > aliroot
95 * Root> .L TrainSetup.C
96 * Root> .L MyTrain.C
97 * Root> MyTrain t;
98 * Root> t.Run();
99 * @endverbatim
100 *
101 * or as a script
102 *
103 * @code
104 * {
105 * gROOT->LoadMacro("TrainSetup.C");
106 * gROOT->LoadMacro("MyTrain.C");
107 * MyTrain t;
108 * t.Run();
109 * }
110 * @endcode
111 *
112 * To byte compile this, you need to
113 * - load the ROOT AliEn library
114 * - load the analysis libraries
115 * - add $ALICE_ROOT/include to header search
116 * first
117 *
118 * @verbatim
119 * > aliroot
bd6f5206 120 * Root> gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGLF/FORWARD/analysis2:"
1d86b7ca 121 * Root> "$ALICE_ROOT/ANALYSIS/macros",
122 * Root> gROOT->GetMacroPath()));
123 * Root> gSystem->AddIncludePath("-I${ALICE_ROOT}/include");
124 * Root> gSystem->Load("libRAliEn");
125 * Root> gSystem->Load("libANALYSIS");
126 * Root> gSystem->Load("libANALYSISalice");
127 * Root> gROOT->LoadMacro("TrainSetup.C+");
128 * @endverbatim
129 *
56199f2b 130 *
bd6f5206 131 * @ingroup pwglf_forward_trains
1d86b7ca 132 *
133 */
134struct TrainSetup
135{
136 /**
137 * Data type to process
138 */
139 enum EType {
140 /** Event Summary Data */
141 kESD,
142 /** Analysis Object Data */
143 kAOD
144 };
145 /**
146 * How to run the analysis
147 *
148 */
149 enum EMode {
150 /** Locally */
151 kLocal = 1,
152 /** In PROOF(-Lite) cluster */
153 kProof,
154 /** On the Grid */
155 kGrid
156 };
157 /**
158 * What stage of the analysis to run
159 *
160 */
161 enum EOper {
162 /** Testing. Local processing, a single copied from Grid */
163 kTest,
164 /** Off-line */
165 kOffline,
166 /** Submit to queue */
167 kSubmit,
168 /** Merge and terminate */
169 kTerminate,
170 /** Full run */
171 kFull
172 };
173
174 //__________________________________________________________________
175 /**
176 * Constructor
177 *
178 * @param name Name of analysis (free-form)
179 * @param useDateTime Whether to append date and time to the name
180 * @param year Year - if not specified, taken from current date
181 * @param month Month - if not specified, taken from current date
182 * @param day Day - if not specified, taken from current date
183 * @param hour Hour - if not specified, taken from current time
184 * @param min Minute - if not specified, taken from current time
185 */
186 TrainSetup(const char* name, Bool_t useDateTime=true,
187 UShort_t year=0, UShort_t month=0,
188 UShort_t day=0, UShort_t hour=0, UShort_t min=0)
189 : fName(name),
190 fRootVersion("v5-28-00a"),
191 fAliRootVersion("v4-21-18-AN"),
192 fAliEnAPIVersion("V1.1x"),
193 fProofServer("alicecaf.cern.ch"),
194 fDataDir("/alice/data/2010/LHC10c"),
195 fDataSet("/COMMON/COMMON/LHC09a4_run8100X#/esdTree"),
196 fXML(""),
197 fRunNumbers(0),
198 fListOfPARs(),
199 fListOfSources(),
200 fListOfLibraries(),
201 fListOfExtras(),
202 fNReplica(4),
203 fESDPass(3),
204 fPassPostfix(""),
205 fEscapedName(name),
871a9ac1 206 fAllowOverwrite(kFALSE),
207 fUseGDB(kFALSE)
1d86b7ca 208 {
209 char c[] = { ' ', '/', '@', 0 };
210 char* p = c;
211 while (*p) {
212 fEscapedName.ReplaceAll(Form("%c", *p), "_");
213 p++;
214 }
215
216 if (useDateTime) {
217 if (year == 0 || month == 0 || day == 0) {
218 TDatime now;
219 year = now.GetYear();
220 month = now.GetMonth();
221 day = now.GetDay();
222 hour = now.GetHour();
223 min = now.GetMinute();
224 }
225 fEscapedName.Append(Form("_%04d%02d%02d_%02d%02d",
226 year, month, day, hour, min));
227 }
228
229 }
230
231 //__________________________________________________________________
232 /**
233 * Parse a string into a type enum
234 *
235 * @param type String to pass
236 *
237 * @return Enumaration value
238 */
239 static EType ParseType(const char* type, Bool_t& /*mc*/)
240 {
241 // mc = false;
242 TString sType(type);
243 sType.ToUpper();
244 EType eType = kESD;
245 // if (sType.Contains("MC")) mc = true;
246 if (sType.Contains("ESD")) eType = kESD;
247 else if (sType.Contains("AOD")) eType = kAOD;
248 else
249 Fatal("Run", "Unknown type '%s'", type);
250
251 return eType;
252 }
253 //__________________________________________________________________
254 /**
255 * Return a string that reflects the passed mode
256 *
257 * @param eMode Mode
258 *
259 * @return String representation of mode
260 */
261 static const char* ModeString(EMode eMode)
262 {
263 switch (eMode) {
264 case kLocal: return "LOCAL";
265 case kProof: return "PROOF";
266 case kGrid: return "GRID";
267 }
268 return 0;
269 }
270 //__________________________________________________________________
271 /**
272 * Parse a string for mode specifier
273 *
274 * @param mode Mode string
275 *
276 * @return EMode value
277 */
278 static EMode ParseMode(const char* mode)
279 {
280 TString sMode(mode);
281 sMode.ToUpper();
282 EMode eMode = kLocal;
283 if (sMode == "LOCAL") eMode = kLocal;
284 else if (sMode == "PROOF") eMode = kProof;
285 else if (sMode == "GRID") eMode = kGrid;
286 else
287 Fatal("Run", "Unknown mode '%s'", mode);
288 return eMode;
289 }
290
291 //__________________________________________________________________
292 /**
293 * Return a string that reflects the passed operation
294 *
295 * @param eOper Operation
296 *
297 * @return String representation of operation
298 */
299 static const char* OperString(EOper eOper)
300 {
301 switch (eOper) {
302 case kTest: return "TEST";
303 case kOffline: return "OFFLINE";
304 case kSubmit: return "SUBMIT";
305 case kTerminate: return "TERMINATE";
306 case kFull: return "FULL";
307 }
308 return 0;
309 }
310 //__________________________________________________________________
311 /**
312 * Parse an operation string
313 *
314 * @param oper Operation
315 *
316 * @return An EOper value
317 */
318 static EOper ParseOperation(const char* oper)
319 {
320 TString sOper(oper);
321 sOper.ToUpper();
322 EOper eOper = kFull;
323 if (sOper == "TEST") eOper = kTest;
324 else if (sOper == "OFFLINE") eOper = kOffline;
325 else if (sOper == "SUBMIT") eOper = kSubmit;
326 else if (sOper == "TERMINATE") eOper = kTerminate;
327 else if (sOper == "FULL") eOper = kFull;
328 else
329 Fatal("Run", "unknown operation '%s'", oper);
330 return eOper;
331 }
332
333 //__________________________________________________________________
334 /**
335 * Set ROOT version to use
336 *
337 * @param v Version string of ROOT
338 */
339 void SetROOTVersion(const char* v) { fRootVersion = v; }
340 //__________________________________________________________________
341 /**
342 * Set AliROOT version to use
343 *
344 * @param v Version string of AliROOT
345 */
346 void SetAliROOTVersion(const char* v) { fAliRootVersion = v; }
347 //__________________________________________________________________
348 /**
349 * Set the PROOF server URL
350 *
351 * @param s PROOF server URL
352 */
353 void SetProofServer(const char* s) { fProofServer = s; }
354 //__________________________________________________________________
355 /**
356 * Set the GRID/Local data dir
357 *
358 * @param d Directory with data
359 */
360 void SetDataDir(const char* d) { fDataDir = d; }
361 //__________________________________________________________________
362 /**
363 * Set the PROOF data set
364 *
365 * @param d PROOF registered data set
366 */
367 void SetDataSet(const char* d) { fDataSet = d; }
368 //__________________________________________________________________
369 /**
370 * Set the XML file to use
371 *
372 * @param x XML file
373 */
374 void SetXML(const char* x) { fXML = x; }
375 //__________________________________________________________________
376 /**
377 * Set how many replicas of the output we want
378 *
379 * @param n Number of replicas requested
380 */
381 void SetNReplica(Int_t n) { fNReplica = n; }
382 /**
383 * Set the ESD pass to use
384 *
385 * @param pass Pass number
386 */
387 void SetESDPass(Int_t pass) { fESDPass = pass; }
388 /**
389 * Set the ESD pass to use
390 *
391 * @param postfix Post fix to pass number
392 */
393 void SetPassPostfix(const char* postfix) { fPassPostfix = postfix; }
394 //__________________________________________________________________
871a9ac1 395 /**
396 * Use GDB to wrap PROOF slaves
397 *
398 * @param use Whether to use GDB or not
399 */
400 void SetUseGDB(Bool_t use=kTRUE) { fUseGDB = use; }
401 //__________________________________________________________________
1d86b7ca 402 /**
403 * Add a source file to be copied and byte compiled on slaves
404 *
405 * @param src Sources
406 * @param addToExtra If false, do not copy
407 */
408 void AddSource(const char* src, bool addToExtra=true)
409 {
410 fListOfSources.Add(new TObjString(src));
411 if (addToExtra) AddExtraFile(src); // Source code isn't copied!
412 }
413 //__________________________________________________________________
414 /**
415 * Add binary data to be uploaded to slaves
416 *
417 * @param lib Name of binary file
418 */
419 void AddLibrary(const char* lib) { fListOfLibraries.Add(new TObjString(lib));}
420 //__________________________________________________________________
421 /**
422 * Add a run to be analysed
423 *
424 * @param run Run number
425 */
426 void AddRun(Int_t run)
427 {
428 Int_t i = fRunNumbers.fN; fRunNumbers.Set(i+1); fRunNumbers[i] = run;
429 }
430 //__________________________________________________________________
431 /**
432 * Read run numbers from a file
433 *
434 * @param filename File name
435 */
436 void ReadRunNumbers(const char* filename)
437 {
438 std::ifstream file(filename);
439 if (!file)
440 Fatal("ReadRunNumbers", "Cannot read from %s", filename);
441
442 while (!file.eof()) {
443 Int_t run;
444 file >> run;
445 AddRun(run);
446 Char_t c;
447 file >> c;
448 if (file.bad()) break;
449 }
450 file.close();
451 }
452 //__________________________________________________________________
453 /**
454 * Add an extra file to be uploaded to slave
455 *
456 * @param file Extra file to be uploaded
457 */
458 void AddExtraFile(const char* file)
459 {
460 if (!file || file[0] == '\0') return;
461 fListOfExtras.Add(new TObjString(file));
462 }
463 //__________________________________________________________________
464 /**
465 * Set whether to allow overwritting existing files/directories
466 *
467 * @param allow If true, allow overwritting files/directories
468 */
469 void SetAllowOverwrite(Bool_t allow) { fAllowOverwrite = allow; }
470 //__________________________________________________________________
d23503ee 471 /**
472 * Service function to make a PAR out of a script.
473 *
474 * The script should contain can contain a sub-class of AliAnalysisTask.
475 * The script will be compiled on the slaves before loading the
476 * AliAnalysisManager. Parts to (not) be compiled can be protected like
477 *
478 * @code
479 * #ifdef BUILD_PAR
480 * // This will _only_ be compiled in the servers
481 * #endif
482 * #ifndef BUILD_PAR
483 * // This will not be compiled in the servers
484 * #endif
485 * @endcode
486 *
487 * @param script Script to upload and compile in the PAR
488 * @param deps Dependency pars
489 *
490 * @return true on success.
491 */
492 static Bool_t MakeScriptPAR(const char* script, const char* deps)
493 {
494 // Get the base name
495 TString base(gSystem->BaseName(script));
496 Int_t idx = base.Last('.');
497 if (idx != kNPOS) base.Remove(idx);
498 Bool_t retval = true;
499 Info("MakeScriptPAR", "script=%s, base=%s", script, base.Data());
500
501 try {
502 // Check name of script file
503 TString scr(script);
504 TString ext;
505 if (scr.EndsWith(".C")) ext = "C";
506 else if (scr.EndsWith(".cxx")) ext = "cxx";
507 else { ext = "C"; scr.Append(".C"); }
508
509 // Check if we can access the file
510 TString path = TString::Format(".:%s", TROOT::GetMacroPath());
511 char* loc = gSystem->Which(path, scr);
512 if (!loc) throw TString::Format("Script %s not found in %s",
513 scr.Data(), path.Data());
514 TString full(loc);
515
516
517 // Set-up directories
518 if (gSystem->MakeDirectory(base) < 0) {
519 base = "";
520 throw TString::Format("Could not make directory '%s'", base.Data());
521 }
522
523 if (gSystem->MakeDirectory(Form("%s/PROOF-INF", base.Data())))
524 throw TString::Format("Could not make directory %s/PROOF-INF",
525 base.Data());
526
527 // Copy the script to the setup directory
528 TString dest = TString::Format("%s/%s.%s", base.Data(),
529 base.Data(), ext.Data());
530 Int_t ret = gSystem->CopyFile(full, dest, true);
531 switch (ret) {
532 case -1: throw TString::Format("Couldn't open %s for copy", scr.Data());
533 case -2: throw TString::Format("File %s exists", dest.Data());
534 case -3: throw TString::Format("Error while copying %s", scr.Data());
535 }
536
537 // Make our build file
538 std::ofstream build(Form("%s/PROOF-INF/BUILD.sh", base.Data()));
539 if (!build)
540 throw TString::Format("Failed to open build shell script");
541 build << "#!/bin/sh\n"
542 << "echo BUILD.sh@`hostname`: Building " << base << "\n"
543 << "root.exe -l -b -q PROOF-INF/BUILD.C 2>&1 | tee " << base << ".log\n"
544 << "echo BUILD.sh@`hostname`: done: $?\n"
545 << std::endl;
546 build.close();
547 if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", base.Data()), 0755) != 0)
548 throw TString::Format("Failed to set exectuable flags on "
549 "%s/PROOF-INF/BUILD.sh", base.Data());
550
551 std::ofstream util(Form("%s/PROOF-INF/UTIL.C", base.Data()));
552 if (!util)
553 throw TString::Format("Failed to open utility script");
554 util << "void LoadROOTLibs() {\n"
555 << " gSystem->Load(\"libVMC\");\n"
556 << " gSystem->Load(\"libNet\");\n"
557 << " gSystem->Load(\"libTree\");\n"
558 << " gSystem->Load(\"libPhysics\");\n"
559 << " gSystem->Load(\"libMinuit\");\n"
560 << "}\n\n"
561 << "void AddDep(const char* env) {\n"
562 << " TString val(gSystem->Getenv(Form(\"%s_INCLUDE\",env)));\n"
563 << " if (val.IsNull())\n"
564 << " Warning(\"Add\",\"%s_INCLUDE not defined\", env);\n"
565 << " else {\n"
566 << " gSystem->AddIncludePath(Form(\"-I../%s\",val.Data()));\n"
567 << " }\n"
568 << "}\n\n"
569 << "void LoadDep(const char* name) {\n"
570 << " gSystem->AddDynamicPath(Form(\"../%s\",name));\n"
571 << " char* full = gSystem->DynamicPathName(name,true);\n"
572 << " if (!full) \n"
573 << " full = gSystem->DynamicPathName(Form(\"lib%s\",name),true);\n"
574 << " if (!full) \n"
575 << " full = gSystem->DynamicPathName(Form(\"lib%s.so\",name),true);\n"
576 << " if (!full) {\n"
577 << " Warning(\"LoadDep\",\"Module %s not found\", name);\n"
578 << " return;\n"
579 << " }\n"
580 << " gSystem->Load(full);\n"
581 << "}\n"
582 << std::endl;
583
584 std::ofstream cbuild(Form("%s/PROOF-INF/BUILD.C", base.Data()));
585 if (!cbuild)
586 throw TString::Format("Failed to open build script");
587 cbuild << "void BUILD() {\n"
588 << " gSystem->AddIncludePath(\"-DBUILD_PAR=1\");\n"
589 << " gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
590 << " LoadROOTLibs();\n";
591 TObjArray* depList = TString(deps).Tokenize(",");
592 TIter next(depList);
593 TObject* dep = 0;
594 while ((dep = next())) {
595 cbuild << " AddDep(\"" << dep->GetName() << "\");\t"
596 << " LoadDep(\"" << dep->GetName() << "\");\n";
597 }
598 cbuild << " // gDebug = 5;\n"
599 << " int ret = gROOT->LoadMacro(\""
600 << base << "." << ext << "++g\");\n"
601 << " if (ret != 0) Fatal(\"BUILD\",\"Failed to build\");\n"
602 << " else Info(\"BUILD\", \"Made " << base << "\");\n"
603 << "}\n"
604 << std::endl;
605 cbuild.close();
606
607 // Make our set-up script
608 std::ofstream setup(Form("%s/PROOF-INF/SETUP.C", base.Data()));
609 if (!build)
610 throw TString::Format("Failed to open setup script");
611 setup << "void SETUP() {\n"
612 << " gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
613 << " LoadROOTLibs();\n"
614 << " Info(\"SETUP\",\"Loading libraries\");\n";
615 next.Reset();
616 dep = 0;
617 while ((dep = next()))
618 setup << " LoadDep(\"" << dep->GetName() << "\");\n";
619 setup << " gDebug = 5;\n"
620 << " gSystem->Load(\"" << base << "_" << ext << ".so\");\n"
621 << " gDebug = 0;\n"
622 << " gROOT->ProcessLine(\".include " << base << "\");\n"
623 << " gSystem->Setenv(\"" << base << "_INCLUDE\",\""
624 << base << "\");\n"
625 << " Info(\"SETUP\", \"Done\");\n"
626 << "}\n"
627 << std::endl;
628 setup.close();
629
630 ret = gSystem->Exec(Form("tar -czvf %s.par %s", base.Data(),base.Data()));
631 if (ret != 0)
632 throw TString::Format("Failed to create PAR file %s.PAR", base.Data());
633 }
634 catch (TString& e) {
635 Error("MakeScriptPAR", e.Data());
636 retval = false;
637 }
638 if (!base.IsNull())
639 gSystem->Exec(Form("rm -vrf %s", base.Data()));
640 return retval;
641 }
642 //__________________________________________________________________
1d86b7ca 643 /**
644 * Print the setup
645 *
646 */
647 void Print() const
648 {
649 bool mc = AliAnalysisManager::GetAnalysisManager()
650 ->GetMCtruthEventHandler();
651 std::cout << fName << " train setup\n"
652 << std::boolalpha
653 << " ROOT version: " << fRootVersion << "\n"
654 << " AliROOT version: " << fAliRootVersion << "\n"
655 << " Name of proof server: " << fProofServer << "\n"
656 << " Grid Input directory: " << fDataDir << "\n"
657 << " Proof data set name: " << fDataSet << "\n"
658 << " XML collection: " << fXML << "\n"
659 << " Monte-Carlo input: " << mc << "\n"
660 << " Storage replication: " << fNReplica << "\n"
661 << " Run numbers: " << std::flush;
662 for (Int_t i = 0; i < fRunNumbers.GetSize(); i++)
663 std::cout << (i == 0 ? "" : ", ") << fRunNumbers.At(i);
664
665 std::cout << "\n"
666 << " PAR files: " << std::flush;
667 Bool_t first = true;
668 TObject* obj = 0;
669 TIter nextPar(&fListOfPARs);
670 while ((obj = nextPar())) {
671 std::cout << (first ? "" : ", ") << obj->GetName();
672 first = false;
673 }
674
675 std::cout << "\n"
676 << " Script sources: " << std::flush;
677 first = true;
678 TIter nextSrc(&fListOfSources);
679 while ((obj = nextSrc())) {
680 std::cout << (first ? "" : ", ") << obj->GetName();
681 first = false;
682 }
683
684 std::cout << "\n"
685 << " Libraries to load: " << std::flush;
686 first = true;
687 TIter nextLib(&fListOfLibraries);
688 while ((obj = nextLib())) {
689 std::cout << (first ? "" : ", ") << obj->GetName();
690 first = false;
691 }
692 std::cout << std::noboolalpha << std::endl;
693
694 AliAnalysisGrid* plugin =
695 AliAnalysisManager::GetAnalysisManager()->GetGridHandler();
696 if (!plugin) return;
697
698 }
699
700protected:
701 //__________________________________________________________________
702 /**
703 * Copy constructor
704 *
705 * @param o Object to copy from
706 */
707 TrainSetup(const TrainSetup& o)
708 : fName(o.fName),
709 fRootVersion(o.fRootVersion),
710 fAliRootVersion(o.fAliRootVersion),
711 fProofServer(o.fProofServer),
712 fDataDir(o.fDataDir),
713 fDataSet(o.fDataSet),
714 fXML(o.fXML),
715 fRunNumbers(o.fRunNumbers),
716 fListOfPARs(),
717 fListOfSources(),
718 fListOfLibraries(),
719 fListOfExtras(),
720 fNReplica(o.fNReplica),
721 fESDPass(o.fESDPass)
722 {
723 if (isdigit(fName[0])) {
724 Warning("TrainSetup", "Name starts with a digit, prepending 'a' to name");
725 fName = Form("a%s", fName.Data());
726 }
727 TObject* obj = 0;
728 TIter nextPar(&o.fListOfPARs);
729 while ((obj = nextPar())) fListOfPARs.Add(obj->Clone());
730 TIter nextSrc(&o.fListOfSources);
731 while ((obj = nextSrc())) fListOfSources.Add(obj->Clone());
732 TIter nextLib(&o.fListOfLibraries);
733 while ((obj = nextLib())) fListOfLibraries.Add(obj->Clone());
734 TIter nextExa(&o.fListOfExtras);
735 while ((obj = nextExa())) fListOfExtras.Add(obj->Clone());
736 }
737 //__________________________________________________________________
738 /**
739 * Assignment operator
740 *
741 * @param o Object to assign from
742 *
743 * @return Reference to this object.
744 */
745 TrainSetup& operator=(const TrainSetup& o)
746 {
747 fName = o.fName;
748 fRootVersion = o.fRootVersion;
749 fAliRootVersion = o.fAliRootVersion;
750 fProofServer = o.fProofServer;
751 fDataDir = o.fDataDir;
752 fDataSet = o.fDataSet;
753 fXML = o.fXML;
754 fNReplica = o.fNReplica;
755 fESDPass = o.fESDPass;
756 fRunNumbers = o.fRunNumbers;
757 TObject* obj = 0;
758 TIter nextPar(&o.fListOfPARs);
759 while ((obj = nextPar())) fListOfPARs.Add(obj->Clone());
760 TIter nextSrc(&o.fListOfSources);
761 while ((obj = nextSrc())) fListOfSources.Add(obj->Clone());
762 TIter nextLib(&o.fListOfLibraries);
763 while ((obj = nextLib())) fListOfLibraries.Add(obj->Clone());
764 TIter nextExa(&o.fListOfExtras);
765 while ((obj = nextExa())) fListOfExtras.Add(obj->Clone());
766
767 return *this;
768 }
769
770 //__________________________________________________________________
771 /**
772 * Run this analysis
773 *
774 * @param type Type of input for analysis (kESD, kAOD)
775 * @param mode Mode of job (kLocal, kProof, kGrid)
776 * @param oper Operation
777 * @param nEvents Number of events to analyse (<0 means all)
778 * @param mc Whether to connect MC data
779 * @param usePar Whether to use PARs
780 * @param dbg Debug level
781 */
782 void Exec(const char* type,
783 const char* mode="GRID",
784 const char* oper="FULL",
785 Int_t nEvents=-1,
786 Bool_t mc=false,
787 Bool_t usePar=false,
788 Int_t dbg=0)
789 {
790 Info("Exec", "Doing exec with type=%s, mode=%s, oper=%s, events=%d "
791 "mc=%d, usePar=%d", type, mode, oper, nEvents, mc, usePar);
792 EType eType = ParseType(type, mc);
793 EMode eMode = ParseMode(mode);
794 EOper eOper = ParseOperation(oper);
795
796 Exec(eType, eMode, eOper, nEvents, mc, usePar, dbg);
797 }
798
799 //__________________________________________________________________
800 /**
801 * Run this analysis
802 *
803 * @param type Type of input for analysis (kESD, kAOD)
804 * @param mode Mode of job (kLocal, kProof, kGrid)
805 * @param oper Operation
806 * @param nEvents Number of events to analyse (<0 means all)
807 * @param mc Whether to connect MC data
808 * @param usePar Whether to use PARs
809 * @param dbg Debug level
810 */
811 void Exec(EType type,
812 EMode mode,
813 EOper oper,
814 Int_t nEvents,
815 Bool_t mc,
816 Bool_t usePar,
817 Int_t dbg=0)
818 {
819 Info("Exec", "Doing exec with type=%d, mode=%d, oper=%d, events=%d "
820 "mc=%d, usePar=%d", type, mode, oper, nEvents, mc, usePar);
821
822 if (mode == kProof) usePar = true;
823
d23503ee 824 Info("Exec", "Connecting in mode=%d", mode);
1d86b7ca 825 if (!Connect(mode)) return;
826
827 TString cwd = gSystem->WorkingDirectory();
828 TString nam = EscapedName();
d23503ee 829 Info("Exec", "Current directory=%s, escaped name=%s",
830 cwd.Data(), nam.Data());
1d86b7ca 831 if (oper != kTerminate) {
832 if (!fAllowOverwrite && !gSystem->AccessPathName(nam.Data())) {
833 Error("Exec", "File/directory %s already exists", nam.Data());
834 return;
835 }
836 if (gSystem->AccessPathName(nam.Data())) {
837 if (gSystem->MakeDirectory(nam.Data())) {
d23503ee 838 Error("Exec", "Failed to make directory '%s'", nam.Data());
1d86b7ca 839 return;
840 }
841 }
842 }
843 else {
844 if (gSystem->AccessPathName(nam.Data())) {
845 Error("Exec", "File/directory %s does not exists", nam.Data());
846 return;
847 }
848 }
849
850 if (!gSystem->ChangeDirectory(nam.Data())) {
851 Error("Exec", "Failed to change directory to %s", nam.Data());
852 return;
853 }
854 Info("Exec", "Made subdirectory %s, and cd'ed there", nam.Data());
855
856 if (!LoadCommonLibraries(mode, usePar)) return;
857
858 // --- Create analysis manager -----------------------------------
859 AliAnalysisManager *mgr = new AliAnalysisManager(fName,"Analysis Train");
860
861 // In test mode, collect system information on every event
862 // if (oper == kTest) mgr->SetNSysInfo(1);
863 if (dbg > 0) mgr->SetDebugLevel(dbg);
864 if (mode == kLocal) mgr->SetUseProgressBar(kTRUE, 100);
865
866 // --- ESD input handler ------------------------------------------
867 AliVEventHandler* inputHandler = CreateInputHandler(type);
868 if (inputHandler) mgr->SetInputEventHandler(inputHandler);
869
870 // --- Monte-Carlo ------------------------------------------------
871 AliVEventHandler* mcHandler = CreateMCHandler(type,mc);
872 if (mcHandler) mgr->SetMCtruthEventHandler(mcHandler);
873
874 // --- AOD output handler -----------------------------------------
875 AliVEventHandler* outputHandler = CreateOutputHandler(type);
876 if (outputHandler) mgr->SetOutputEventHandler(outputHandler);
877
878 // --- Include analysis macro path in search path ----------------
879 gROOT->SetMacroPath(Form("%s:%s:$ALICE_ROOT/ANALYSIS/macros",
880 cwd.Data(), gROOT->GetMacroPath()));
881
882 // --- Physics selction - only for ESD ---------------------------
883 if (type == kESD) CreatePhysicsSelection(mc, mgr);
884
885 // --- Create centrality task ------------------------------------
886 CreateCentralitySelection(mc, mgr);
887
888 // --- Create tasks ----------------------------------------------
889 CreateTasks(mode, usePar, mgr);
890
891 // --- Create Grid handler ----------------------------------------
892 // _must_ be done after all tasks has been added
893 AliAnalysisAlien* gridHandler = CreateGridHandler(type, mode, oper);
894 if (gridHandler) mgr->SetGridHandler(gridHandler);
895
896 // --- Create the chain ------------------------------------------
897 TChain* chain = CreateChain(type, mode, oper, mc);
898 if (mode == kLocal && !chain) {
899 Error("Exec", "No chain defined in local mode!");
900 return;
901 }
902
903 // --- Print setup -----------------------------------------------
904 Print();
36619b75 905 // if (mode == kProof) {
906 // Info("Run", "Exported environment variables to PROOF slaves:");
907 // TProof::GetEnvVars()->ls();
908 // Info("Run", "Environment variables for this session:");
909 // gSystem->Exec("printenv");
910 // }
1d86b7ca 911
912 // --- Initialise the train --------------------------------------
913 if (!mgr->InitAnalysis()) {
914 gSystem->ChangeDirectory(cwd.Data());
915 Error("Run","Failed to initialise train");
916 return;
917 }
918
919 // --- Show status -----------------------------------------------
920 mgr->PrintStatus();
921
922 Long64_t ret = StartAnalysis(mgr, mode, chain, nEvents);
923
924 // Make sure we go back
925 gSystem->ChangeDirectory(cwd.Data());
926
927 if (ret < 0) Error("Exec", "Analysis failed");
928 }
929 //__________________________________________________________________
930 /**
931 * Start the analysis
932 *
933 * @param mgr Analysis manager
934 * @param mode Run mode
935 * @param chain Input data (local and proof only)
936 * @param nEvents Number of events to analyse
937 */
938 Long64_t StartAnalysis(AliAnalysisManager* mgr,
939 EMode mode,
940 TChain* chain,
941 Int_t nEvents)
942 {
943 // --- Run the analysis ------------------------------------------
944 switch (mode) {
945 case kLocal:
946 if (!chain) {
947 Error("StartAnalysis", "No chain defined");
948 return -1;
949 }
950 if (nEvents < 0) nEvents = chain->GetEntries();
951 return mgr->StartAnalysis(ModeString(mode), chain, nEvents);
952 case kProof:
953 if (fDataSet.IsNull()) {
954 if (!chain) {
955 Error("StartAnalysis", "No chain defined");
956 return -1;
957 }
958 if (nEvents < 0) nEvents = chain->GetEntries();
959 return mgr->StartAnalysis(ModeString(mode), chain, nEvents);
960 }
961 return mgr->StartAnalysis(ModeString(mode), fDataSet);
962 case kGrid:
963 if (nEvents < 0)
964 return mgr->StartAnalysis(ModeString(mode));
965 return mgr->StartAnalysis(ModeString(mode), nEvents);
966 }
967 // We should never get here
968 return -1;
969 }
970 //__________________________________________________________________
971 /**
972 * Return the escaped name
973 *
974 *
975 * @return Escaped name
976 */
977 const TString& EscapedName() const
978 {
979 return fEscapedName;
980 }
981 //__________________________________________________________________
982 /**
983 * Create a grid handler
984 *
985 * @param type Data type
986 * @param mode Run mode
987 * @param oper Operation
988 *
989 * @return Grid handler
990 */
991 virtual AliAnalysisAlien*
992 CreateGridHandler(EType type, EMode mode, EOper oper)
993 {
994 if (mode != kGrid) return 0;
995
996 TString name = EscapedName();
997
998 // Create the plug-in object, and set run mode
999 AliAnalysisAlien* plugin = new AliAnalysisAlien();
1000 plugin->SetRunMode(OperString(oper));
1001
1002 // Production mode - not used here
1003 // plugin->SetProductionMode();
1004
1005 // Set output to be per run
1006 plugin->SetOutputToRunNo();
1007
1008 // Set the job tag
1009 plugin->SetJobTag(fName);
1010
1011 // Set number of test files - used in test mode only
1012 plugin->SetNtestFiles(1);
1013
1014 // Set required version of software
1015 plugin->SetAPIVersion(fAliEnAPIVersion);
1016 plugin->SetROOTVersion(fRootVersion);
1017 plugin->SetAliROOTVersion(fAliRootVersion);
1018
1019 // Keep log files
1020 plugin->SetKeepLogs();
1021
1022 // Declare root of input data directory
1023 plugin->SetGridDataDir(fDataDir);
1024
1025 // Data search patterns
1026 TString pat;
1027 if (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()) {
1028 pat = "*/";
1029 plugin->SetRunPrefix("");
1030 }
1031 else {
1032 pat = Form("*ESDs/pass%d%s/*/", fESDPass, fPassPostfix.Data());
1033 plugin->SetRunPrefix("000");
1034 }
1035 pat.Append(Form("*%s.root", type == kESD ? "ESDs" : "AOD"));
1036 plugin->SetDataPattern(pat);
1037
1038 // Add the run numbers
1039 for (Int_t i = 0; i < fRunNumbers.fN; i++) {
1040 if (fRunNumbers[i] < 0) continue;
1041 plugin->AddRunNumber(fRunNumbers[i]);
1042 }
1043
1044 // Set the working directory to be the trains name (with special
1045 // characters replaced by '_' and the date appended), and also set
1046 // the output directory (relative to working directory)
1047 plugin->SetGridWorkingDir(name.Data());
1048 plugin->SetGridOutputDir("output");
1049
1050 // Enable configured PARs
1051 TIter nextPar(&fListOfPARs);
1052 TObject* parName;
1053 while ((parName = nextPar()))
1054 plugin->EnablePackage(parName->GetName());
1055
1056 // Add sources that need to be compiled on the workers using
1057 // AcLIC.
1058 TString addSources = SetupSources();
1059 if (!addSources.IsNull()) plugin->SetAnalysisSource(addSources.Data());
1060
1061 // Add binary libraries that should be uploaded to the workers
1062 TString addLibs = SetupLibraries();
1063 if (!addLibs.IsNull()) plugin->SetAdditionalLibs(addLibs.Data());
1064
1065 // Disable default outputs
1066 plugin->SetDefaultOutputs(true);
1067
1068 // Merge parameters
1069 plugin->SetMaxMergeFiles(20);
1070 plugin->SetMergeExcludes("AliAOD.root "
1071 "*EventStat*.root "
1072 "*event_stat*.root");
1073
1074 // Set number of runs per master - set to one to per run
1075 plugin->SetNrunsPerMaster(1);
1076
1077 // Loop over defined containers in the analysis manager,
1078 // and declare these as outputs
1079 TString listOfAODs = "";
1080 TString listOfHists = "";
1081 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
1082 AliAnalysisDataContainer* cont = 0;
1083 TIter nextCont(mgr->GetOutputs());
1084 while ((cont = static_cast<AliAnalysisDataContainer*>(nextCont()))) {
1085 TString outName(cont->GetFileName());
1086 TString& list = (outName == "default" ? listOfAODs : listOfHists);
1087 if (outName == "default") {
1088 if (!mgr->GetOutputEventHandler()) continue;
1089
1090 outName = mgr->GetOutputEventHandler()->GetOutputFileName();
1091 }
1092 if (list.Contains(outName)) continue;
1093 if (!list.IsNull()) list.Append(",");
1094 list.Append(outName);
1095 }
1096 if (!mgr->GetExtraFiles().IsNull()) {
1097 if (!listOfAODs.IsNull()) listOfAODs.Append("+");
1098 TString extra = mgr->GetExtraFiles();
1099 extra.ReplaceAll(" ", ",");
1100 listOfAODs.Append(extra);
1101 }
1102 TString outArchive = Form("stderr, stdout@disk=%d", fNReplica);
1103 if (!listOfHists.IsNull())
1104 outArchive.Append(Form(" hist_archive.zip:%s@disk=%d",
1105 listOfHists.Data(), fNReplica));
1106 if (!listOfAODs.IsNull())
1107 outArchive.Append(Form(" aod_archive.zip:%s@disk=%d",
1108 listOfAODs.Data(), fNReplica));
1109 if (listOfAODs.IsNull() && listOfHists.IsNull())
1110 Fatal("CreateGridHandler", "No outputs defined");
1111 // Disabled for now
1112 // plugin->SetOutputArchive(outArchive);
1113
1114 // Set name of generated analysis macro
1115 plugin->SetAnalysisMacro(Form("%s.C", name.Data()));
1116
1117 // Maximum number of sub-jobs
1118 // plugin->SetSplitMaxInputFileNumber(25);
1119
1120 // Set the Time-To-Live
1121 plugin->SetTTL(70000);
1122
1123 // Re-submit failed jobs as long as the ratio of failed jobs is
1124 // below this percentage.
1125 plugin->SetMasterResubmitThreshold(95);
1126
1127 // Set the input format
1128 plugin->SetInputFormat("xml-single");
1129
1130 // Set the name of the generated jdl
1131 plugin->SetJDLName(Form("%s.jdl", name.Data()));
1132
1133 // Set the name of the generated executable
1134 plugin->SetExecutable(Form("%s.sh", name.Data()));
1135
1136 // Set the job price !?
1137 plugin->SetPrice(1);
1138
1139 // Set whether to merge via JDL
1140 plugin->SetMergeViaJDL(true);
1141
1142 // Fast read otion
1143 plugin->SetFastReadOption(false);
1144
1145 // Whether to overwrite existing output
1146 plugin->SetOverwriteMode(true);
1147
1148 // Set the executable binary name and options
1149 plugin->SetExecutableCommand("aliroot -b -q -x");
1150
1151 // Split by storage element - must be lower case!
1152 plugin->SetSplitMode("se");
1153
1154 return plugin;
1155 }
1156 //__________________________________________________________________
1157 /**
1158 * Create input handler
1159 *
1160 * @param type
1161 *
1162 * @return
1163 */
1164 virtual AliVEventHandler* CreateInputHandler(EType type)
1165 {
1166 switch (type) {
1167 case kESD: return new AliESDInputHandler();
1168 case kAOD: return new AliAODInputHandler();
1169 }
1170 return 0;
1171 }
1172 //__________________________________________________________________
1173 /**
1174 * Create input handler
1175 *
1176 * @param type Run type (ESD or AOD)
1177 * @param mc Assume monte-carlo input
1178 *
1179 * @return
1180 */
1181 virtual AliVEventHandler* CreateMCHandler(EType type, bool mc)
1182 {
1183 if (!mc) return 0;
1184 if (type != kESD) return 0;
1185 Info("CreateMCHandler", "Making MC handler");
1186 AliMCEventHandler* mcHandler = new AliMCEventHandler();
1187 mcHandler->SetReadTR(true);
1188 return mcHandler;
1189 }
1190 //__________________________________________________________________
1191 /**
1192 * Create output event handler
1193 *
1194 * @param type
1195 *
1196 * @return
1197 */
1198 virtual AliVEventHandler* CreateOutputHandler(EType type)
1199 {
1200 AliAODHandler* ret = new AliAODHandler();
1201 switch (type) {
1202 case kESD:
1203 ret->SetOutputFileName("AliAOD.root");
1204 break;
1205 case kAOD:
1206 ret->SetOutputFileName("AliAOD.pass2.root");
1207 break;
1208 }
1209 return ret;
1210 }
1211 //__________________________________________________________________
1212 /**
1213 * Create physics selection , and add to manager
1214 *
1215 * @param mc Whether this is for MC
1216 * @param mgr Manager
1217 */
1218 virtual void CreatePhysicsSelection(Bool_t mc,
1219 AliAnalysisManager* mgr)
1220 {
1221 gROOT->Macro(Form("AddTaskPhysicsSelection.C(%d)", mc));
1222 mgr->RegisterExtraFile("event_stat.root");
1223 }
1224 //__________________________________________________________________
1225 /**
1226 * Create physics selection , and add to manager
1227 *
1228 * @param mc Whether this is for MC
1229 * @param mgr Manager
1230 */
1231 virtual void CreateCentralitySelection(Bool_t mc, AliAnalysisManager* mgr)
1232 {
1233 gROOT->Macro("AddTaskCentrality.C");
1234 AliCentralitySelectionTask* ctask =
1235 dynamic_cast<AliCentralitySelectionTask*>(mgr->GetTask("CentralitySelection"));
1236 if (!ctask) return;
d23503ee 1237 // ctask->SetPass(fESDPass);
1d86b7ca 1238 if (mc) ctask->SetMCInput();
1239 }
1240 //__________________________________________________________________
1241 /**
1242 * Create analysis tasks
1243 *
1244 * @param mode Run mode
1245 * @param mgr Manager
1246 * @param par Whether to use pars
1247 */
1248 virtual void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)=0;
1249 //__________________________________________________________________
1250 /**
1251 * Connect to external services (Proof and/or grid)
1252 *
1253 * @param mode Running mode
1254 *
1255 * @return true on success
1256 */
1257 virtual Bool_t Connect(EMode mode)
1258 {
1259 if (mode == kLocal) return true;
1260
1261 // --- Set-up connections to Proof cluster and alien -------------
1262 if (mode == kProof) {
d23503ee 1263 Info("Connect", "Opening connection to proof server");
1d86b7ca 1264 // --- Find user name ------------------------------------------
1265 TString userName(gSystem->Getenv("alien_API_USER"));
1266 if (userName.IsNull()) {
1267 userName = gSystem->GetUserInfo()->fUser;
1268 Warning("Connect",
1269 "environment variable 'alien_API_USER' not set, using %s",
1270 userName.Data());
1271 }
1272
1273 // --- Set prefered GSI method ---------------------------------
1274 gEnv->SetValue("XSec.GSI.DelegProxy", "2");
36619b75 1275
1276 // --- Figure out some server settings -------------------------
1d86b7ca 1277 TString serv = "";
1278 Bool_t lite = false;
1279 if (fProofServer.BeginsWith("workers=") || fProofServer.IsNull()) {
1280 lite = true;
1281 serv = fProofServer;
1282 }
1283 else
1284 serv = Form("%s@%s", userName.Data(), fProofServer.Data());
36619b75 1285
1286 // --- Possibly debug slave sessions with GDB ------------------
1287 if (fUseGDB) {
1288 TString gdbCmd("\"gdb --batch -ex run -ex bt --args\"");
1289 Info("Connect", "Using GDB to wrap slaves: %s", gdbCmd.Data());
1290 TProof::AddEnvVar("PROOF_WRAPPERCMD", gdbCmd);
1291 }
1292
1293 // --- Add ALICE_ROOT directory to search path for packages ----
d23503ee 1294 Info("Connect", "Set location of packages");
36619b75 1295 gEnv->SetValue("Proof.GlobalPackageDirs",
1296 Form("%s:%s",
1297 gEnv->GetValue("Proof.GlobalPackageDirs", "."),
1298 gSystem->Getenv("ALICE_ROOT")));
1299
1300 // --- Set OADB path on workers --------------------------------
1301 const char* oadbPath = AliAnalysisManager::GetOADBPath();
1302 TProof::AddEnvVar("OADB_PATH", oadbPath);
1303 // if (lite) gSystem->Setenv("OADB_PATH", oadbPath);
1304 // Info("Connect", "OADB_PATH=%s", gSystem->Getenv("OADB_PATH"));
1305
1306 // --- Now open connection to PROOF cluster --------------------
1d86b7ca 1307 TProof::Open(serv);
1308 if (!gProof) {
1309 Error("Connect", "Failed to connect to Proof cluster %s as %s",
1310 fProofServer.Data(), userName.Data());
1311 return false;
1312 }
d23503ee 1313 Info("Connect", "Now connected to Proof");
1314 // gProof->SetParameter("PROOF_LookupOpt", "all");
1d86b7ca 1315 if (lite) return true;
1316 }
1317
1318 // --- Open a connection to the grid -----------------------------
d23503ee 1319#if 0
1d86b7ca 1320 TGrid::Connect("alien://");
1321 if (!gGrid || !gGrid->IsConnected()) {
1322 // This is only fatal in grid mode
1323 Error("Connect", "Failed to connect to AliEN");
1324 if (mode == kGrid) return false;
1325 return true;
1326 }
1327 if (mode == kGrid) return true;
1328
1329
1330 // --- Set and make output directory -----------------------------
1331 TString name = EscapedName();
1332 TString homeDir(gGrid->GetHomeDirectory());
1333 TString workDir(homeDir);
1334 workDir.Append("/");
1335 workDir.Append(name);
1336
1337 // Make working directory
1338 if (!gGrid->Cd(workDir)) {
1339 gGrid->Cd(homeDir);
1340 if (gGrid->Mkdir(workDir)) {
1341 gGrid->Cd(name);
1342 Info("Connect", "Directory %s created", workDir.Data());
1343 }
1344 }
1345 // Make output directory
1346 gGrid->Mkdir("proof_output");
1347 gGrid->Cd("proof_output");
d23503ee 1348#endif
1d86b7ca 1349 return true;
1350 }
1351 //__________________________________________________________________
1352 /**
1353 * Load common libraries
1354 *
1355 * @param mode Running mode
1356 * @param par If true, load as PARs
1357 *
1358 * @return true on success
1359 */
1360 Bool_t LoadCommonLibraries(EMode mode, Bool_t par)
1361 {
1362 if (!gSystem->Getenv("ALICE_ROOT")) {
1363 Error("LoadCommonLibraries", "Local AliROOT not available");
1364 return false;
1365 }
1366 gSystem->Load("libTree.so");
1367 gSystem->Load("libGeom.so");
1368 gSystem->Load("libVMC.so");
1369 gSystem->Load("libPhysics.so");
1370 gSystem->Load("libMinuit.so");
36619b75 1371 if (mode == kProof) {
1372 gProof->Exec("gSystem->Load(\"libTree.so\");");
1373 gProof->Exec("gSystem->Load(\"libGeom.so\");");
1374 gProof->Exec("gSystem->Load(\"libMinuit.so\");");
1375 gProof->Exec("gSystem->Load(\"libVMC.so\");");
1376
1377
1378 }
1d86b7ca 1379
d23503ee 1380#if 0
1381 // We need to activate the workers here in case
1382 // we have dynamic slaves - otherwise they won't get
1383 // the packages
1384 if (mode == kProof) {
1385 Info("LoadCommonLibraries", "Starting slaves");
1386 if (!gProof->StartSlaves()) {
1387 Error("LoadCommonLibraries", "Failed to start slaves");
1388 return false;
1389 }
1390 Info("LoadCommonLibraries", "Slaves started");
1391 }
1392#endif
1393
1d86b7ca 1394 Bool_t ret = true;
1395 Bool_t basic = mode == kGrid ? false : par;
1396
1397 ret &= LoadLibrary("STEERBase", mode, basic, false);
1398 ret &= LoadLibrary("ESD", mode, basic, false);
1399 ret &= LoadLibrary("AOD", mode, basic, false);
1400 ret &= LoadLibrary("ANALYSIS", mode, basic, true);
36619b75 1401 ret &= LoadLibrary("OADB", mode, basic, true);
1d86b7ca 1402 ret &= LoadLibrary("ANALYSISalice", mode, basic, true);
1403
1404 return ret;
1405 }
1406 //__________________________________________________________________
1407 /**
1408 * Load a library
1409 *
1410 * @param what What library to load
1411 * @param mode Mode (local, proof, grid)
1412 * @param par If true, load as PAR
1413 * @param rec If true, also load on slaves
1414 *
1415 * @return true on success
1416 */
1417 Bool_t LoadLibrary(const char* what, EMode mode, Bool_t par, Bool_t rec=false)
1418 {
1419 if (!what || what[0] == '\0') return true;
1420
1421 TString module(what);
1422 TString libName(what);
1423 if (!libName.BeginsWith("lib")) libName = Form("lib%s", libName.Data());
1424 if (!libName.EndsWith(".so")) libName.Append(".so");
1425
1426 Int_t ret = 0;
1427
1428 switch (mode) {
1429 case kLocal: // Just load and exit
1430 gSystem->Load(libName.Data());
1431 break;
1432 case kGrid:
1433 if (par) {
1434 ret = SetupPAR(what) ? 0 : -1;
1435 if (rec) fListOfPARs.Add(new TObjString(what));
1436 } else {
1437 ret = gSystem->Load(libName.Data());
1438 if (rec) fListOfLibraries.Add(new TObjString(libName));
1439 }
1440 break;
1441 case kProof:
d23503ee 1442 Info("LoadLibrary", "Uploading %s", what);
1443 ret = gProof->UploadPackage(what, TProof::kRemoveOld);
1d86b7ca 1444 if (ret < 0) {
1445 ret = gProof->UploadPackage(gSystem->ExpandPathName(Form("../%s.par",
1446 what)));
1447 if (ret < 0) {
1448 ret =
1449 gProof->UploadPackage(gSystem
1450 ->ExpandPathName(Form("$ALICE_ROOT/%s.par",
1451 what)));
1452 if (ret < 0) {
1453 Error("LoadLibrary",
1454 "Could not find module %s.par in current directory nor "
1455 "in $ALICE_ROOT", module.Data());
1456 return false;
1457 }
1458 }
1459 }
d23503ee 1460 Info("LoadLibrary", "Enabling package %s", what);
1d86b7ca 1461 ret = gProof->EnablePackage(what);
1462 break;
1463 }
1464 if (ret < 0) {
1465 Error("LoadLibrary", "Couldn't load %s", what);
1466 return false;
1467 }
1468 return true;
1469 }
1470
1471 //__________________________________________________________________
1472 Bool_t SetupPAR(const char* what)
1473 {
1474 if (!what || what[0] == '\0') return -1;
1475
1476 TString parFile(Form("%s.par", what));
1477 if (gSystem->AccessPathName(parFile.Data())) {
1478 if (gSystem->AccessPathName(Form("../%s.par", what))) {
1479 // If not found
1480 TString aliParFile =
1481 gSystem->ExpandPathName(Form("$(ALICE_ROOT)/%s.par", what));
1482 if (gSystem->AccessPathName(aliParFile.Data())) {
1483 Error("SetupPAR", "PAR file %s not found in current directory or "
1484 "$(ALICE_ROOT)", what);
1485 return false;
1486 }
1487 // Copy to current directory
1488 TFile::Cp(aliParFile, parFile);
1489 }
1490 else
1491 gSystem->Exec(Form("ln -s ../%s.par .", what));
1492 }
1493
1494 // Extract archive
1495 gSystem->Exec(Form("tar xvzf %s", parFile.Data()));
1496
1497 // Change directory into par archive
1498 TString cwd = gSystem->WorkingDirectory();
1499
1500 if (!gSystem->ChangeDirectory(what)) {
1501 Error("SetupPAR", "Failed to change directory to %s", what);
1502 return false;
1503 }
1504
1505 // Test the build
1506 if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
1507 Info("SetupPar", "Building in PAR archive %s", what);
1508 if (gSystem->Exec("PROOF-INF/BUILD.sh")) {
1509 Error("SetupPar", "Failed to build in PAR directory %s", what);
1510 gSystem->ChangeDirectory(cwd.Data());
1511 return false;
1512 }
1513 }
1514
1515 // Check for setup script
1516 if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
1517 Info("SetupPAR", "Setting up for PAR %s", what);
1518 gROOT->Macro("PROOF-INF/SETUP.C");
1519 }
1520 if (!gSystem->ChangeDirectory(cwd.Data())) return false;
1521
1522 return true;
1523 }
1524 //__________________________________________________________________
1525 TString SetupExtras()
1526 {
1527 TString ret;
1528 TIter next(&fListOfExtras);
1529 TObjString* obj = 0;
1530 while ((obj = static_cast<TObjString*>(next()))) {
1531 TString path = gSystem->ExpandPathName(obj->GetName());
1532 if (!path.BeginsWith("/"))
1533 // If not an absolute path, prepend to up-one
1534 path = Form("../%s", path.Data());
1535 if (gSystem->AccessPathName(path.Data())) {
1536 // File not accessible
1537 Warning("SetupExtras", "File %s not accessible", path.Data());
1538 continue;
1539 }
1540 ret.Append(Form("%s ", gSystem->BaseName(obj->GetName())));
1541 gSystem->Exec(Form("ln -s %s .", path.Data()));
1542 }
1543 ret = ret.Strip();
1544 return ret;
1545 }
1546 //__________________________________________________________________
1547 TString SetupSources()
1548 {
1549 TString nam = EscapedName();
1550 TString ret;
1551 TIter next(&fListOfSources);
1552 TObject* src;
1553 while ((src = next())) {
1554 TString path = gSystem->ExpandPathName(src->GetName());
1555 if (!path.BeginsWith("/"))
1556 // If not an absolute path, prepend to up-one
1557 path = Form("../%s", path.Data());
1558 if (gSystem->AccessPathName(path.Data())) {
1559 // File not accessible
1560 Warning("SetupSources", "File %s not accessible", path.Data());
1561 continue;
1562 }
1563 ret.Append(Form("%s ", gSystem->BaseName(src->GetName())));
1564 gSystem->Exec(Form("ln -s %s .", path.Data()));
1565 }
1566 ret = ret.Strip();
1567 return ret;
1568 }
1569 //__________________________________________________________________
1570 TString SetupLibraries()
1571 {
1572 TString ret;
1573 TIter next(&fListOfLibraries);
1574 TObject* lib;
1575 while ((lib = next())) {
1576 ret.Append(lib->GetName());
1577 ret.Append(" ");
1578 }
1579 // Also add extra files to this variable
1580 ret.Append(SetupExtras());
1581 ret = ret.Strip();
1582 return ret;
1583 }
1584 //__________________________________________________________________
1585 /**
1586 * Scan directory @a dir (possibly recursive) for tree files to add
1587 * to the chain. This does not follow sym-links
1588 *
1589 * @param dir Directory to scan
1590 * @param chain Chain to add to
1591 * @param type Type of tree (ESD or AOD)
1592 * @param recursive Whether to scan recursively
1593 * @param mc Look also for MC files if true
1594 *
1595 * @return true if any files where added
1596 */
1597 Bool_t ScanDirectory(TSystemDirectory* dir, TChain* chain,
1598 EType type, bool recursive, bool mc)
1599 {
1600 TString fnPattern;
1601 switch (type) {
1602 case kESD: fnPattern = "AliESD"; break;
1603 case kAOD: fnPattern = "AliAOD"; break;
1604 }
1605
1606 // Assume failure
1607 Bool_t ret = false;
1608
1609 // Get list of files, and go back to old working directory
1610 TString oldDir(gSystem->WorkingDirectory());
1611 TList* files = dir->GetListOfFiles();
1612 if (!gSystem->ChangeDirectory(oldDir)) {
1613 Error("ScanDirectory", "Failed to go back to %s", oldDir.Data());
1614 return false;
1615 }
1616 if (!files) return false;
1617
1618 TList toAdd;
1619 toAdd.SetOwner();
1620 Bool_t hasGAlice = (!mc ? true : false);
1621 Bool_t hasKine = (!mc ? true : false);
1622 Bool_t hasTrRef = (!mc ? true : false);
1623
1624 // Sort list of files and check if we should add it
1625 files->Sort();
1626 TIter next(files);
1627 TSystemFile* file = 0;
1628 while ((file = static_cast<TSystemFile*>(next()))) {
1629 TString name(file->GetName());
1630 TString title(file->GetTitle());
1631 TString full(gSystem->ConcatFileName(file->GetTitle(), name.Data()));
1632 if (dynamic_cast<TSystemDirectory*>(file)) full = title;
1633 // Ignore special links
1634 if (name == "." || name == "..") {
1635 // Info("ScanDirectory", "Ignoring %s", name.Data());
1636 continue;
1637 }
1638
1639 FileStat_t fs;
1640 if (gSystem->GetPathInfo(full.Data(), fs)) {
1641 Warning("ScanDirectory", "Cannot stat %s (%s)", full.Data(),
1642 gSystem->WorkingDirectory());
1643 continue;
1644 }
1645 // Check if this is a directory
1646 if (file->IsDirectory(full)) {
1647 if (recursive) {
1648 // if (title[0] == '/')
1649 TSystemDirectory* d = new TSystemDirectory(file->GetName(),
1650 full.Data());
1651 if (ScanDirectory(d,chain,type,recursive,mc))
1652 ret = true;
1653 delete d;
1654 }
1655 continue;
1656 }
1657
1658 // If this is not a root file, ignore
1659 if (!name.EndsWith(".root")) continue;
1660
1661 // If this file does not contain AliESDs, ignore
1662 if (!name.Contains(fnPattern)) {
1663 // Info("ScanDirectory", "%s does not match pattern %s",
1664 // name.Data(), fnPattern.Data());
1665 if (mc) {
1666 if (name.CompareTo("galice.root") == 0) hasGAlice = true;
1667 if (name.CompareTo("Kinematics.root") == 0) hasKine = true;
1668 if (name.CompareTo("TrackRefs.root") == 0) hasTrRef = true;
1669 }
1670 continue;
1671 }
1672
1673 // Add
1674 // Info("ScanDirectory", "Adding %s", full.Data());
1675 toAdd.Add(new TObjString(full));
1676 }
1677
1678 if (mc && toAdd.GetEntries() > 0 &&
1679 (!hasGAlice || !hasKine || !hasTrRef)) {
1680 Warning("ScanDirectory",
1681 "one or more of {galice,Kinematics,TrackRefs}.root missing from "
1682 "%s, not adding anything from this directory",
1683 dir->GetTitle());
1684 toAdd.Delete();
1685 }
1686
1687 TIter nextAdd(&toAdd);
1688 TObjString* s = 0;
1689 while ((s = static_cast<TObjString*>(nextAdd()))) {
1690 // Info("ScanDirectory", "Adding %s", s->GetString().Data());
1691 chain->Add(s->GetString());
1692 }
1693 if (toAdd.GetEntries() > 0) ret = true;
1694
1695 gSystem->ChangeDirectory(oldDir);
1696 return ret;
1697 }
1698 //__________________________________________________________________
1699 /**
1700 * Create a chain from an XML containing an collection
1701 *
1702 * @param treeName Name of tree's
1703 * @param xmlFile XML collection
1704 *
1705 * @return Newly allocated chain or null
1706 */
1707 TChain* CreateChainFromXML(const char* treeName,
1708 const char* xmlFile)
1709 {
1710 TGridCollection* collection = TAlienCollection::Open(xmlFile);
1711 if (!collection) {
1712 Error("CreateChainFromXML", "Cannot create AliEn collection from "
1713 "XML file %s", xmlFile);
1714 return 0;
1715 }
1716
1717 TChain* chain = new TChain(treeName);
1718 collection->Reset();
1719 while (collection->Next()) chain->Add(collection->GetTURL(""));
1720
1721 return chain;
1722 }
1723 //__________________________________________________________________
1724 /**
1725 * Create a chain of data
1726 *
1727 * @param type Type of data
1728 * @param mode Operation mode
1729 * @param mc Assume MC input if true
1730 *
1731 * @return TChain of data
1732 */
1733 TChain* CreateChain(EType type, EMode mode, EOper /* oper */, Bool_t mc)
1734 {
1735 TString treeName;
1736 switch (type) {
1737 case kESD: treeName = "esdTree"; break;
1738 case kAOD: treeName = "aodTree"; break;
1739 }
1740
1741 TChain* chain = 0;
1742 switch (mode) {
1743 case kProof:
1744 if (!fDataSet.IsNull()) break;
1745 // Otherwise fall through
1746 case kLocal:
1747 if (fXML.IsNull()) {
1748 chain = new TChain(treeName.Data());
1749 TString dir(fDataDir);
1750 if (dir == ".") dir = "";
1751 if (!dir.BeginsWith("/")) dir = Form("../%s", dir.Data());
1752 TString savdir(gSystem->WorkingDirectory());
1753 TSystemDirectory d(gSystem->BaseName(dir.Data()), dir.Data());
1754 if (!ScanDirectory(&d, chain, type, true, mc)) {
1755 delete chain;
1756 chain = 0;
1757 }
1758 gSystem->ChangeDirectory(savdir);
1759 }
1760 else
1761 chain = CreateChainFromXML(treeName.Data(), fXML.Data());
1762 break;
1763 case kGrid: break; // Do nothing - we use plugin
1764 }
1765
1766 if (chain && chain->GetNtrees() <= 0) {
1767 delete chain;
1768 return 0;
1769 }
1770 return chain;
1771 }
1772 //__________________________________________________________________
1773 TString fName; // Name of analysis
1774 TString fRootVersion; // ROOT version to use
1775 TString fAliRootVersion; // AliROOT version to use
1776 TString fAliEnAPIVersion; // AliEn API version to use
1777 TString fProofServer; // Name of proof server
1778 TString fDataDir; // Grid Input directory
1779 TString fDataSet; // Proof data set name
1780 TString fXML; // XML collection for local/proof mode
1781 TArrayI fRunNumbers; // List of run number
1782 TList fListOfPARs; // List of PAR files to use
1783 TList fListOfSources; // List of sources to upload and AcLIC
1784 TList fListOfLibraries; // List of libraries to load
1785 TList fListOfExtras; // List of extra files to upload
1786 Int_t fNReplica; // Storage replication
871a9ac1 1787 Int_t fESDPass; // ESD pass number
1d86b7ca 1788 TString fPassPostfix; // Possible pass postfix
871a9ac1 1789 TString fEscapedName; // Name escaped for special chars
1790 Bool_t fAllowOverwrite; // Allow overwriting output dir
1791 Bool_t fUseGDB; // Wrap PROOF slaves in GDB
1d86b7ca 1792};
1793
1794
1795void
1796BuildTrainSetup()
1797{
bd6f5206 1798 gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGLF/FORWARD/analysis2:"
1d86b7ca 1799 "$ALICE_ROOT/ANALYSIS/macros",
1800 gROOT->GetMacroPath()));
1801 gSystem->AddIncludePath("-I${ALICE_ROOT}/include");
1802 gSystem->Load("libRAliEn");
1803 gSystem->Load("libANALYSIS");
1804 gSystem->Load("libANALYSISalice");
1805 TString path = gSystem->Which(gROOT->GetMacroPath(), "TrainSetup.C");
1806 Info("BuildTrainSetup", "Path=%s", path.Data());
1807 TString tmp("TrainSetup");
1808 FILE* fp = gSystem->TempFileName(tmp, ".");
1809 fclose(fp);
1810 gSystem->Unlink(tmp);
1811 tmp.Append(".C");
1812 Info("BuildTrainSetup", "Copy %s -> %s", path.Data(), tmp.Data());
1813 gSystem->CopyFile(path, tmp);
1814 gROOT->LoadMacro(Form("%s+g", tmp.Data()));
1815 gSystem->Unlink(tmp);
1816 tmp.ReplaceAll(".C", "_C.so");
1817 gSystem->Unlink(tmp);
1818 tmp.ReplaceAll("_C.so", "_C.d");
1819 gSystem->Unlink(tmp);
1820}
1821
1822
1823//____________________________________________________________________
1824//
1825// EOF
1826//