2 * @defgroup pwglf_forward_trains Trains
6 * @ingroup pwglf_forward
10 * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
11 * @date Wed Mar 23 12:12:00 2011
15 * @ingroup pwglf_forward_trains
24 #include <TGridCollection.h>
32 #include <TObjString.h>
36 #include <TSystemDirectory.h>
37 #include <TSystemFile.h>
40 #include <AliAODHandler.h>
41 #include <AliAODInputHandler.h>
42 #include <AliAnalysisDataContainer.h>
43 #include <AliAnalysisManager.h>
44 #include <AliAnalysisAlien.h>
45 #include <AliESDInputHandler.h>
46 #include <AliMCEventHandler.h>
47 #include <AliVEventHandler.h>
48 #include <AliPhysicsSelection.h>
49 #include <AliCentralitySelectionTask.h>
53 class AliAnalysisManager;
56 class TSystemDirectory;
61 //====================================================================
63 * Generic set-up of an analysis train using the grid-handler (AliEn plugin).
65 * See also @ref train_setup_doc
67 * @ingroup pwglf_forward_trains
72 // Forward declaration
75 * Data type to process
78 /** Event Summary Data */
80 /** Analysis Object Data */
86 * How to run the analysis
92 /** In PROOF(-Lite) cluster */
98 * What stage of the analysis to run
102 /** Testing. Local processing, a single copied from Grid */
106 /** Submit to queue */
108 /** Merge and terminate */
112 /** Only intialize */
117 //__________________________________________________________________
118 virtual ~TrainSetup() {}
120 //__________________________________________________________________
124 * @param name Name of analysis (free-form)
126 TrainSetup(const char* name)
129 fRootVersion("v5-28-00a"),
130 fAliRootVersion("v4-21-18-AN"),
131 fAliEnAPIVersion("V1.1x"),
132 fProofServer("alicecaf.cern.ch"),
133 fDataDir("/alice/data/2010/LHC10c"),
135 fDataSet("/COMMON/COMMON/LHC09a4_run8100X#/esdTree"),
138 fAllowOverwrite(kFALSE),
146 fDatime(1995, 0, 0, 0, 0, 0),
155 fEscapedName = EscapeName(fName, fDatime);
157 //__________________________________________________________________
160 * @name Software environment
163 * Set ROOT version to use
165 * @param v Version string of ROOT
167 void SetROOTVersion(const char* v) { fRootVersion = v; }
169 * Set AliROOT version to use
171 * @param v Version string of AliROOT
173 void SetAliROOTVersion(const char* v) { fAliRootVersion = v; }
175 * Set the AliEn API version to use
177 * @param v AliEn API version
179 void SetAliEnAPIVersion(const char* v) { fAliEnAPIVersion = v; }
181 * Wether to use par files through-out. Mandetory and enforced in
182 * case of a PROOF job,
184 * @param usePar If true, use PAR files - even for base libraries
186 void SetUsePar(Bool_t usePar) { fUsePar = usePar; }
189 //__________________________________________________________________
195 * Set the GRID/Local data dir
197 * @param d Directory with data
199 void SetDataDir(const char* d) { fDataDir = d; }
201 * Set the glob pattern to search input files in - Grid only
203 * @param pattern Glob pattern
205 void SetDataPattern(const char* pattern) { fDataPattern = pattern; }
207 * Set the PROOF data set
209 * @param d PROOF registered data set
211 void SetDataSet(const char* d) { fDataSet = d; }
213 * Set the XML file to use
217 void SetXML(const char* x) { fXML = x; }
219 * Wether to assume the input comes from MC. If this is set to
220 * true, and the CreateMCHandler member function isn't overloaded to
221 * return null, then the files @c galice.root, @c Kinematics.root,
222 * and @c TrackRefs.root must be present for each input file (@c
223 * AliESDs.root or @c AliAOD.root)
225 * @param isMC If true, assume MC input
227 void SetMC(Bool_t isMC) { fMC = isMC; }
230 //__________________________________________________________________
233 * @name Grid storage and splitting
236 * Set how many replicas of the output we want
238 * @param n Number of replicas requested
240 void SetNReplica(Int_t n) { fNReplica = n; }
242 * Set the maximum number of files per sub-job.
244 * @param max Maximum number of files per sub-job
246 void SetMaxSplit(UShort_t max=50) { fMaxSplit = max; }
249 //__________________________________________________________________
252 * @name Name and local working directory
255 * Set whether to allow overwritting existing files/directories
257 * @param allow If true, allow overwritting files/directories
259 void SetAllowOverwrite(Bool_t allow) { fAllowOverwrite = allow; }
261 * Set the date and time
263 * @param year Year (>1994)
267 * @param minutes Minute
269 void SetDateTime(UShort_t year, UShort_t month, UShort_t day,
270 UShort_t hour, UShort_t minutes)
272 fDatime.Set((year<1995?1995:year), month, day, hour, minutes, 0);
273 fEscapedName = EscapeName(fName, fDatime);
276 * Set the date and time from a string.
278 * @param date Formatted like YYYY/MM/DD HH:MM:SS
280 void SetDateTime(const TString& date)
283 fDatime.Set(1985,0,0,0,0,0);
284 else if (date.EqualTo("now", TString::kIgnoreCase))
288 fEscapedName = EscapeName(fName, fDatime);
291 * Return the escaped name
293 * @return Escaped name
295 const TString& EscapedName() const
300 //__________________________________________________________________
303 * @name Execution parameters
306 * Set the PROOF server URL
308 * @param s PROOF server URL
310 void SetProofServer(const char* s) { fProofServer = s; }
312 * Set the type of analysis
314 * @param type AOD or ESD
316 void SetType(EType type) { fExecType = type; }
318 * Set the type of analysis
320 * @param type AOD or ESD
322 void SetType(const char* type) { SetType(ParseType(type)); }
324 * Set the execution mode of analysis
326 * @param mode LOCAL, PROOF, GRID
328 void SetMode(EMode mode) { fExecMode = mode; }
330 * Set the execution mode of analysis
332 * @param mode LOCAL, PROOF, GRID
334 void SetMode(const char* mode) { SetMode(ParseMode(mode)); }
336 * Set the execution operation of analysis
338 * @param oper FULL, TERMINATE, INIT
340 void SetOperation(EOper oper) { fExecOper = oper; }
342 * Set the execution operation of analysis
344 * @param oper FULL, TERMINATE, INIT
346 void SetOperation(const char* oper) { SetOperation(ParseOperation(oper)); }
348 * Use GDB to wrap PROOF slaves
350 * @param use Whether to use GDB or not
352 void SetUseGDB(Bool_t use=kTRUE) { fUseGDB = use; }
355 //__________________________________________________________________
358 * @name Stuff to upload
361 * Add a source file to be copied and byte compiled on slaves
364 * @param addToExtra If false, do not copy
366 void AddSource(const char* src, bool addToExtra=true)
368 fListOfSources.Add(new TObjString(src));
369 if (addToExtra) AddExtraFile(src); // Source code isn't copied!
372 * Add binary data to be uploaded to slaves
374 * @param lib Name of binary file
376 void AddLibrary(const char* lib) { fListOfLibraries.Add(new TObjString(lib));}
378 * Add an extra file to be uploaded to slave
380 * @param file Extra file to be uploaded
382 void AddExtraFile(const char* file)
384 if (!file || file[0] == '\0') return;
385 fListOfExtras.Add(new TObjString(file));
389 //__________________________________________________________________
395 * Add a run to be analysed
397 * @param run Run number
399 void AddRun(Int_t run)
401 Int_t i = fRunNumbers.fN; fRunNumbers.Set(i+1); fRunNumbers[i] = run;
404 * Read run numbers from a file
406 * @param filename File name
408 void ReadRunNumbers(const char* filename)
410 std::ifstream file(filename);
412 Fatal("ReadRunNumbers", "Cannot read from %s", filename);
414 while (!file.eof()) {
420 if (file.bad()) break;
425 * Set the runs to read from a string. The parts should be
426 * delimited by a character in the string @a delim. If a non-number
427 * part is seen, it is assumed to be the name of a file containing
430 * @param runs String of runs
431 * @param delim Delimiters
433 void SetRuns(const TString& runs, const char* delim=":, \t")
435 TIter next(runs.Tokenize(delim));
437 while ((os = static_cast<TObjString*>(next()))) {
438 TString s(os->String());
439 if (s.IsNull()) continue;
440 if (!s.IsDigit()) ReadRunNumbers(s);
441 else AddRun(s.Atoi());
445 * Whether final merge should be done over all runs (argument true),
446 * or for each run individually.
448 * @param perRun If true, do final merge over all runs
450 void SetPerRunMerge(Bool_t perRun) { fPerRunMerge = perRun; }
452 //__________________________________________________________________
460 * @return true on success, false otherwise
464 if (fExecMode == kProof) fUsePar = true;
466 // Info("Init", "Connecting in mode=%d", mode);
467 if (!Connect()) return false;
469 // --- Get current directory and set-up sub-directory ------------
470 TString cwd = gSystem->WorkingDirectory();
471 if (!SetupWorkingDirectory()) return false;
473 // --- Load the common libraries ---------------------------------
474 if (!LoadCommonLibraries()) return false;
476 // --- Create analysis manager -----------------------------------
477 AliAnalysisManager *mgr = new AliAnalysisManager(fName,"Analysis Train");
479 // In test mode, collect system information on every event
480 // if (oper == kTest) mgr->SetNSysInfo(1);
481 if (fVerbose > 0) mgr->SetDebugLevel(fVerbose);
482 if (fExecMode == kLocal) mgr->SetUseProgressBar(kTRUE, 100);
484 // --- ESD input handler ------------------------------------------
485 AliVEventHandler* inputHandler = CreateInputHandler(fExecType);
486 if (inputHandler) mgr->SetInputEventHandler(inputHandler);
488 // --- Monte-Carlo ------------------------------------------------
489 AliVEventHandler* mcHandler = CreateMCHandler(fExecType,fMC);
490 if (mcHandler) mgr->SetMCtruthEventHandler(mcHandler);
492 // --- AOD output handler -----------------------------------------
493 AliVEventHandler* outputHandler = CreateOutputHandler(fExecType);
494 if (outputHandler) mgr->SetOutputEventHandler(outputHandler);
496 // --- Include analysis macro path in search path ----------------
497 gROOT->SetMacroPath(Form("%s:%s:$ALICE_ROOT/ANALYSIS/macros",
498 cwd.Data(), gROOT->GetMacroPath()));
500 // --- Physics selction - only for ESD ---------------------------
501 if (fExecType == kESD) CreatePhysicsSelection(fMC, mgr);
503 // --- Create centrality task ------------------------------------
504 CreateCentralitySelection(fMC, mgr);
506 // --- Create tasks ----------------------------------------------
507 CreateTasks(fExecMode, fUsePar, mgr);
509 // --- Create Grid handler ----------------------------------------
510 // _must_ be done after all tasks has been added
511 AliAnalysisAlien* gridHandler = CreateGridHandler();
512 if (gridHandler) mgr->SetGridHandler(gridHandler);
514 // --- Set debug level on defined tasks --------------------------
516 TIter next(mgr->GetTasks());
517 AliAnalysisTask* sub = 0;
518 while ((sub = static_cast<AliAnalysisTask*>(next()))) {
519 AliAnalysisTaskSE* se = dynamic_cast<AliAnalysisTaskSE*>(sub);
521 se->SetDebugLevel(fVerbose);
525 // --- Print setup -----------------------------------------------
527 // if (mode == kProof) {
528 // Info("Run", "Exported environment variables to PROOF slaves:");
529 // TProof::GetEnvVars()->ls();
530 // Info("Run", "Environment variables for this session:");
531 // gSystem->Exec("printenv");
534 // --- Initialise the train --------------------------------------
535 if (!mgr->InitAnalysis()) {
536 gSystem->ChangeDirectory(cwd.Data());
537 Error("Run","Failed to initialise train");
541 // --- Show status -----------------------------------------------
546 //------------------------------------------------------------------
550 * @param nEvents Number of events to analyse
551 * @param r Possible runner object
552 * @param asShell Passed to SaveSetup
554 virtual void Run(Int_t nEvents, Runner* r=0, Bool_t asShell=false)
556 // Info("Exec", "Doing exec with type=%d, mode=%d, oper=%d, events=%d "
557 // "mc=%d, usePar=%d", type, mode, oper, nEvents, mc, usePar);
559 TString cwd = gSystem->WorkingDirectory();
562 Error("Run", "Failed to intialize the train");
565 if (r) SaveSetup(*r, nEvents, asShell);
566 if (fExecOper == kInitialize) return;
568 // --- Create the chain ------------------------------------------
569 TChain* chain = CreateChain();
570 if (fExecMode == kLocal) {
572 Error("Run", "No chain defined in local mode!");
575 if (chain->GetListOfFiles()->GetEntries() < 1) {
576 Error("Run", "Empty chain in local mode!");
581 // --- Get manager and execute -----------------------------------
582 AliAnalysisManager *mgr =AliAnalysisManager::GetAnalysisManager();
583 Long64_t ret = StartAnalysis(mgr, chain, nEvents);
585 // Make sure we go back
586 gSystem->ChangeDirectory(cwd.Data());
589 if (ret < 0) Error("Exec", "Analysis failed");
591 //------------------------------------------------------------------
596 virtual void Print() const
598 bool mc=AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler();
599 std::cout << fName << " train setup\n"
601 PrintField(std::cout, "Escaped name", fEscapedName);
602 PrintField(std::cout, "ROOT version", fRootVersion);
603 PrintField(std::cout, "AliROOT version", fAliRootVersion);
604 PrintField(std::cout, "AliEn API version", fAliEnAPIVersion);
605 PrintField(std::cout, "Name of proof server", fProofServer);
606 PrintField(std::cout, "Input directory", fDataDir);
607 PrintField(std::cout, "Data pattern", fDataPattern);
608 PrintField(std::cout, "Proof data set name", fDataSet);
609 PrintField(std::cout, "XML collection", fXML);
610 PrintField(std::cout, "Storage replication", fNReplica);
611 PrintField(std::cout, "Allow overwrite", fAllowOverwrite);
612 PrintField(std::cout, "Do GDB debugging", fUseGDB);
613 PrintField(std::cout, "Max # files per split", fMaxSplit);
614 PrintField(std::cout, "Monte-Carlo input", fMC);
615 PrintField(std::cout, "Monte-Carlo handler", mc);
616 PrintField(std::cout, "Per run merge", fPerRunMerge);
617 PrintFieldName(std::cout, "Run numbers");
618 for (Int_t i = 0; i < fRunNumbers.GetSize(); i++)
619 std::cout << (i == 0 ? "" : ", ") << fRunNumbers.At(i);
620 std::cout << std::endl;
622 PrintFieldList(std::cout, "PAR files", fListOfPARs);
623 PrintFieldList(std::cout, "Script sources", fListOfSources);
624 PrintFieldList(std::cout, "Libraries", fListOfLibraries);
625 PrintFieldList(std::cout, "Extras", fListOfExtras, "\n ");
627 std::cout << std::noboolalpha << std::endl;
629 AliAnalysisGrid* plugin =
630 AliAnalysisManager::GetAnalysisManager()->GetGridHandler();
635 * Whether to be verbosity level. 0 means no messages, while higher
636 * numbers increase the verbosity
638 * @param verb Verbosity level
640 void SetVerbose(Int_t verb) { fVerbose = verb; }
643 //__________________________________________________________________
651 * @param o Object to copy from
653 TrainSetup(const TrainSetup& o)
655 fEscapedName(o.fEscapedName),
656 fRootVersion(o.fRootVersion),
657 fAliRootVersion(o.fAliRootVersion),
658 fAliEnAPIVersion(o.fAliEnAPIVersion),
659 fProofServer(o.fProofServer),
660 fDataDir(o.fDataDir),
661 fDataPattern(o.fDataPattern),
662 fDataSet(o.fDataSet),
664 fNReplica(o.fNReplica),
665 fAllowOverwrite(o.fAllowOverwrite),
667 fMaxSplit(o.fMaxSplit),
668 fRunNumbers(o.fRunNumbers),
674 fExecType(o.fExecType),
675 fExecMode(o.fExecMode),
676 fExecOper(o.fExecOper),
679 fPerRunMerge(o.fPerRunMerge),
682 if (isdigit(fName[0])) {
683 Warning("TrainSetup", "Name starts with a digit, prepending 'a' to name");
684 fName = Form("a%s", fName.Data());
687 TIter nextPar(&o.fListOfPARs);
688 while ((obj = nextPar())) fListOfPARs.Add(obj->Clone());
689 TIter nextSrc(&o.fListOfSources);
690 while ((obj = nextSrc())) fListOfSources.Add(obj->Clone());
691 TIter nextLib(&o.fListOfLibraries);
692 while ((obj = nextLib())) fListOfLibraries.Add(obj->Clone());
693 TIter nextExa(&o.fListOfExtras);
694 while ((obj = nextExa())) fListOfExtras.Add(obj->Clone());
696 //------------------------------------------------------------------
698 * Assignment operator
700 * @param o Object to assign from
702 * @return Reference to this object.
704 TrainSetup& operator=(const TrainSetup& o)
707 fRootVersion = o.fRootVersion;
708 fAliRootVersion = o.fAliRootVersion;
709 fProofServer = o.fProofServer;
710 fDataDir = o.fDataDir;
711 fDataPattern = o.fDataPattern;
712 fDataSet = o.fDataSet;
714 fNReplica = o.fNReplica;
715 fRunNumbers = o.fRunNumbers;
717 TIter nextPar(&o.fListOfPARs);
718 while ((obj = nextPar())) fListOfPARs.Add(obj->Clone());
719 TIter nextSrc(&o.fListOfSources);
720 while ((obj = nextSrc())) fListOfSources.Add(obj->Clone());
721 TIter nextLib(&o.fListOfLibraries);
722 while ((obj = nextLib())) fListOfLibraries.Add(obj->Clone());
723 TIter nextExa(&o.fListOfExtras);
724 while ((obj = nextExa())) fListOfExtras.Add(obj->Clone());
730 //__________________________________________________________________
733 * @name Utility functions
736 * Escape bad elements of the name
738 * @param name Name to escape
739 * @param datime Date and Time
741 * @return escaped name
743 static TString EscapeName(const char* name, const TDatime& datime)
745 TString escaped = name;
746 char c[] = { ' ', '/', '@', 0 };
749 escaped.ReplaceAll(Form("%c", *p), "_");
752 if (datime.GetYear() <= 1995 ||
753 datime.GetMonth() == 0 ||
754 datime.GetDay() == 0) return escaped;
755 escaped.Append(Form("_%04d%02d%02d_%02d%02d",
760 datime.GetMinute()));
763 //------------------------------------------------------------------
764 static void PrintFieldName(std::ostream& o, const char* name)
766 o << " " << std::left << std::setw(25) << name << ": " << std::flush;
768 //------------------------------------------------------------------
769 static void PrintFieldList(std::ostream& o, const char* name,
770 const TCollection& c, const char* sep=", ")
772 PrintFieldName(o, name);
776 while ((obj = next())) {
777 o << (first ? "" : sep) << obj->GetName();
780 std::cout << std::endl;
782 //------------------------------------------------------------------
783 template <typename T>
784 static void PrintField(std::ostream& o, const char* name, T& value)
786 PrintFieldName(o, name);
787 o << value << std::endl;
789 //------------------------------------------------------------------
791 * Return a string that reflects the passed operation
793 * @param eOper Operation
795 * @return String representation of operation
797 static const char* OperString(EOper eOper)
800 case kTest: return "TEST";
801 case kOffline: return "OFFLINE";
802 case kSubmit: return "SUBMIT";
803 case kTerminate: return "TERMINATE";
804 case kFull: return "FULL";
805 case kInitialize: return "INIT";
809 //------------------------------------------------------------------
811 * Parse an operation string
813 * @param oper Operation
815 * @return An EOper value
817 static EOper ParseOperation(const char* oper)
822 if (sOper.Contains("TEST")) eOper = kTest;
823 else if (sOper.Contains("OFFLINE")) eOper = kOffline;
824 else if (sOper.Contains("SUBMIT")) eOper = kSubmit;
825 else if (sOper.Contains("TERMINATE")) eOper = kTerminate;
826 else if (sOper.Contains("FULL")) eOper = kFull;
827 else if (sOper.Contains("INIT")) eOper = kInitialize;
829 Fatal("Run", "unknown operation '%s'", oper);
832 //------------------------------------------------------------------
834 * Return a string that reflects the passed mode
836 * @param eType Type of analysis
838 * @return String representation of execution type
840 static const char* TypeString(EType eType)
843 case kESD: return "ESD";
844 case kAOD: return "AOD";
845 case kUser: return "USER";
849 //------------------------------------------------------------------
851 * Parse a string into a type enum
853 * @param type String to pass
855 * @return Enumaration value
857 static EType ParseType(const char* type)
863 // if (sType.Contains("MC")) mc = true;
864 if (sType.Contains("ESD")) eType = kESD;
865 else if (sType.Contains("AOD")) eType = kAOD;
867 Fatal("Run", "Unknown type '%s'", type);
871 //------------------------------------------------------------------
873 * Return a string that reflects the passed mode
877 * @return String representation of mode
879 static const char* ModeString(EMode eMode)
882 case kLocal: return "LOCAL";
883 case kProof: return "PROOF";
884 case kGrid: return "GRID";
888 //------------------------------------------------------------------
890 * Parse a string for mode specifier
892 * @param mode Mode string
894 * @return EMode value
896 static EMode ParseMode(const char* mode)
900 EMode eMode = kLocal;
901 if (sMode.Contains("LOCAL")) eMode = kLocal;
902 else if (sMode.Contains("PROOF")) eMode = kProof;
903 else if (sMode.Contains("GRID")) eMode = kGrid;
905 Fatal("Run", "Unknown mode '%s'", mode);
911 //__________________________________________________________________
914 * @name Overloadable creators
917 * Create a grid handler
919 * @return Grid handler
921 virtual AliAnalysisAlien*
924 if (fExecMode != kGrid) return 0;
926 TString name = EscapedName();
928 // Create the plug-in object, and set run mode
929 AliAnalysisAlien* plugin = new AliAnalysisAlien();
930 plugin->SetRunMode(OperString(fExecOper == kInitialize ?
933 // Production mode - not used here
934 // plugin->SetProductionMode();
936 // Do not test copying
937 plugin->SetCheckCopy(false);
939 // Set output to be per run
940 plugin->SetOutputToRunNo(true);
943 plugin->SetJobTag(fName);
945 // Set number of test files - used in test mode only
946 plugin->SetNtestFiles(1);
948 // Set name of generated analysis macro
949 plugin->SetAnalysisMacro(Form("%s.C", name.Data()));
951 // Maximum number of sub-jobs
952 // plugin->SetSplitMaxInputFileNumber(25);
954 // Set the Time-To-Live
955 plugin->SetTTL(70000);
957 // Re-submit failed jobs as long as the ratio of failed jobs is
958 // below this percentage.
959 plugin->SetMasterResubmitThreshold(95);
961 // Set the input format
962 plugin->SetInputFormat("xml-single");
964 // Set the name of the generated jdl
965 plugin->SetJDLName(Form("%s.jdl", name.Data()));
967 // Set the name of the generated executable
968 plugin->SetExecutable(Form("%s.sh", name.Data()));
970 // Set the job price !?
973 // Set whether to merge via JDL
974 plugin->SetMergeViaJDL(true);
977 plugin->SetFastReadOption(false);
979 // Whether to overwrite existing output
980 plugin->SetOverwriteMode(true);
982 // Set the executable binary name and options
983 plugin->SetExecutableCommand("aliroot -b -q -x");
985 // Split by storage element - must be lower case!
986 plugin->SetSplitMode("se");
987 plugin->SetSplitMaxInputFileNumber(fMaxSplit);
989 // Disable default outputs
990 plugin->SetDefaultOutputs(true);
993 plugin->SetMaxMergeFiles(20);
994 plugin->SetMergeExcludes("AliAOD.root "
996 "*event_stat*.root");
999 plugin->SetKeepLogs();
1001 // Set the working directory to be the trains name (with special
1002 // characters replaced by '_' and the date appended), and also set
1003 // the output directory (relative to working directory)
1004 plugin->SetGridWorkingDir(name.Data());
1005 plugin->SetGridOutputDir("output");
1007 // Set required version of software
1008 if (!fAliEnAPIVersion.IsNull()) plugin->SetAPIVersion(fAliEnAPIVersion);
1009 if (!fRootVersion.IsNull()) plugin->SetROOTVersion(fRootVersion);
1010 if (!fAliRootVersion.IsNull()) plugin->SetAliROOTVersion(fAliRootVersion);
1012 // Declare root of input data directory
1013 TString dataDir(fDataDir);
1014 if (dataDir.BeginsWith("alien://"))
1015 dataDir.ReplaceAll("alien://", "");
1016 plugin->SetGridDataDir(dataDir);
1018 // Data search patterns
1020 if (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler())
1021 plugin->SetRunPrefix("");
1023 plugin->SetRunPrefix("000");
1026 if (!pat.EndsWith("/")) pat.Append("/");
1027 pat.Append(Form("*%s.root", fExecType == kESD ? "ESDs" : "AOD"));
1028 plugin->SetDataPattern(pat);
1030 // Add the run numbers
1032 for (Int_t i = 0; i < fRunNumbers.fN; i++) {
1033 if (fRunNumbers[i] < 0) continue;
1034 plugin->AddRunNumber(fRunNumbers[i]);
1037 // Set number of runs per master - set to one to per run
1038 if (fPerRunMerge) plugin->SetNrunsPerMaster(1);
1039 else plugin->SetNrunsPerMaster(nRun+1);
1041 // Enable configured PARs
1042 TIter nextPar(&fListOfPARs);
1044 while ((parName = nextPar()))
1045 plugin->EnablePackage(parName->GetName());
1047 // Add sources that need to be compiled on the workers using
1049 TString addSources = SetupSources();
1050 if (!addSources.IsNull()) plugin->SetAnalysisSource(addSources.Data());
1052 // Add binary libraries that should be uploaded to the workers
1053 TString addLibs = SetupLibraries();
1054 if (!addLibs.IsNull()) plugin->SetAdditionalLibs(addLibs.Data());
1056 // Loop over defined containers in the analysis manager,
1057 // and declare these as outputs
1058 TString listOfAODs = "";
1059 TString listOfHists = "";
1060 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
1061 AliAnalysisDataContainer* cont = 0;
1062 TIter nextCont(mgr->GetOutputs());
1063 while ((cont = static_cast<AliAnalysisDataContainer*>(nextCont()))) {
1064 TString outName(cont->GetFileName());
1065 TString& list = (outName == "default" ? listOfAODs : listOfHists);
1066 if (outName == "default") {
1067 if (!mgr->GetOutputEventHandler()) continue;
1069 outName = mgr->GetOutputEventHandler()->GetOutputFileName();
1071 if (list.Contains(outName)) continue;
1072 if (!list.IsNull()) list.Append(",");
1073 list.Append(outName);
1075 if (!mgr->GetExtraFiles().IsNull()) {
1076 if (!listOfAODs.IsNull()) listOfAODs.Append("+");
1077 TString extra = mgr->GetExtraFiles();
1078 extra.ReplaceAll(" ", ",");
1079 listOfAODs.Append(extra);
1081 TString outArchive = Form("stderr, stdout@disk=%d", fNReplica);
1082 if (!listOfHists.IsNull())
1083 outArchive.Append(Form(" hist_archive.zip:%s@disk=%d",
1084 listOfHists.Data(), fNReplica));
1085 if (!listOfAODs.IsNull())
1086 outArchive.Append(Form(" aod_archive.zip:%s@disk=%d",
1087 listOfAODs.Data(), fNReplica));
1088 if (listOfAODs.IsNull() && listOfHists.IsNull())
1089 Fatal("CreateGridHandler", "No outputs defined");
1091 // plugin->SetOutputArchive(outArchive);
1096 //------------------------------------------------------------------
1098 * Create input handler
1104 virtual AliVEventHandler* CreateInputHandler(EType type)
1107 case kESD: return new AliESDInputHandler();
1108 case kAOD: return new AliAODInputHandler();
1109 case kUser: return 0;
1113 //------------------------------------------------------------------
1115 * Create input handler
1117 * @param type Run type (ESD or AOD)
1118 * @param mc Assume monte-carlo input
1122 virtual AliVEventHandler* CreateMCHandler(EType /*type*/, bool mc)
1125 // if (type != kESD) return 0;
1126 Info("CreateMCHandler", "Making MC handler");
1127 AliMCEventHandler* mcHandler = new AliMCEventHandler();
1128 mcHandler->SetReadTR(true);
1131 //------------------------------------------------------------------
1133 * Create output event handler
1139 virtual AliVEventHandler* CreateOutputHandler(EType type)
1141 AliAODHandler* ret = new AliAODHandler();
1144 ret->SetOutputFileName("AliAOD.root");
1147 ret->SetOutputFileName("AliAOD.pass2.root");
1155 //------------------------------------------------------------------
1157 * Create physics selection, and add to manager
1159 * @param mc Whether this is for MC
1160 * @param mgr Manager
1162 virtual void CreatePhysicsSelection(Bool_t mc,
1163 AliAnalysisManager* mgr)
1165 gROOT->Macro(Form("AddTaskPhysicsSelection.C(%d)", mc));
1166 mgr->RegisterExtraFile("event_stat.root");
1168 //------------------------------------------------------------------
1170 * Create centrality selection, and add to manager
1172 * @param mc Whether this is for MC
1173 * @param mgr Manager
1175 virtual void CreateCentralitySelection(Bool_t mc, AliAnalysisManager* mgr)
1177 gROOT->Macro("AddTaskCentrality.C");
1178 const char* name = "CentralitySelection";
1179 AliCentralitySelectionTask* ctask =
1180 dynamic_cast<AliCentralitySelectionTask*>(mgr->GetTask(name));
1182 if (mc) ctask->SetMCInput();
1184 //------------------------------------------------------------------
1186 * Create analysis tasks. Must be overloaded by sub-class
1188 * @param mode Run mode
1189 * @param mgr Manager
1190 * @param par Whether to use pars
1192 virtual void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)=0;
1195 //__________________________________________________________________
1198 * @name Library loading
1200 //------------------------------------------------------------------
1202 * Load common libraries
1204 * @return true on success
1206 Bool_t LoadCommonLibraries()
1208 if (!gSystem->Getenv("ALICE_ROOT")) {
1209 Error("LoadCommonLibraries", "Local AliROOT not available");
1212 gSystem->Load("libTree.so");
1213 gSystem->Load("libGeom.so");
1214 gSystem->Load("libVMC.so");
1215 gSystem->Load("libPhysics.so");
1216 gSystem->Load("libMinuit.so");
1217 if (fExecMode == kProof) {
1218 gProof->Exec("gSystem->Load(\"libTree.so\");");
1219 gProof->Exec("gSystem->Load(\"libGeom.so\");");
1220 gProof->Exec("gSystem->Load(\"libMinuit.so\");");
1221 gProof->Exec("gSystem->Load(\"libVMC.so\");");
1227 Bool_t basic = fExecMode == kGrid ? false : fUsePar;
1229 ret &= LoadLibrary("STEERBase", basic, false);
1230 ret &= LoadLibrary("ESD", basic, false);
1231 ret &= LoadLibrary("AOD", basic, false);
1232 ret &= LoadLibrary("ANALYSIS", basic, true);
1233 ret &= LoadLibrary("OADB", basic, true);
1234 ret &= LoadLibrary("ANALYSISalice", basic, true);
1238 //------------------------------------------------------------------
1242 * @param what What library to load
1243 * @param par If true, load as PAR
1244 * @param rec If true, also load on slaves
1246 * @return true on success
1248 Bool_t LoadLibrary(const char* what, Bool_t par, Bool_t rec=false)
1250 if (!what || what[0] == '\0') return true;
1252 TString module(what);
1253 TString libName(what);
1254 if (!libName.BeginsWith("lib")) {
1255 // Check if the library corresponds to a compiled macro
1256 if (!gSystem->AccessPathName(Form("%s_C.so", libName.Data()))) {
1257 libName.Append("_C");
1259 else if (!gSystem->AccessPathName(Form("../%s_C.so", libName.Data()))) {
1260 libName = Form("../%s_C", what);
1263 libName = Form("lib%s", libName.Data());
1265 if (!libName.EndsWith(".so")) libName.Append(".so");
1269 switch (fExecMode) {
1270 case kLocal: // Just load and exit
1271 if (gSystem->Load(libName.Data()) < 0) {
1272 Error("LoadLibrary", "Failed to load library %s", libName.Data());
1278 ret = SetupPAR(what) ? 0 : -1;
1279 if (rec) fListOfPARs.Add(new TObjString(what));
1281 ret = gSystem->Load(libName.Data());
1282 if (rec) fListOfLibraries.Add(new TObjString(libName));
1286 Info("LoadLibrary", "Uploading %s", what);
1287 ret = gProof->UploadPackage(what, TProof::kRemoveOld);
1289 ret = gProof->UploadPackage(gSystem->ExpandPathName(Form("../%s.par",
1293 gProof->UploadPackage(gSystem
1294 ->ExpandPathName(Form("$ALICE_ROOT/%s.par",
1297 Error("LoadLibrary",
1298 "Could not find module %s.par in current directory nor "
1299 "in $ALICE_ROOT", module.Data());
1304 Info("LoadLibrary", "Enabling package %s", what);
1305 ret = gProof->EnablePackage(what);
1309 Error("LoadLibrary", "Couldn't load %s", what);
1316 //__________________________________________________________________
1319 * @name PAR generation from script
1322 * Service function to make a PAR out of a script.
1324 * The script should contain can contain a sub-class of AliAnalysisTask.
1325 * The script will be compiled on the slaves before loading the
1326 * AliAnalysisManager. Parts to (not) be compiled can be protected like
1330 * // This will _only_ be compiled in the servers
1333 * // This will not be compiled in the servers
1337 * @param mode Execution mode (Grid, PROOF, Local)
1338 * @param script Script to upload and compile in the PAR
1339 * @param deps Dependency pars
1341 * @return true on success.
1343 static Bool_t MakeScriptPAR(EMode mode, const char* script, const char* deps)
1345 // Get the base name
1346 Info("MakeScriptPAR", "Making par file for %s", script);
1347 TString base(gSystem->BaseName(script));
1348 Int_t idx = base.Last('.');
1349 if (idx != kNPOS) base.Remove(idx);
1350 Bool_t retval = true;
1351 // Info("MakeScriptPAR", "script=%s, base=%s", script, base.Data());
1353 if (mode == kLocal) {
1354 if (gROOT->LoadMacro(Form("%s.C++g", base.Data())) < 0)
1359 TString tmpdir(gSystem->TempDirectory());
1360 int ltempl = tmpdir.Length() + 1 + 5 + 6 + 1;
1361 char* templ = new char[ltempl];
1362 snprintf(templ, ltempl, "%s/trainXXXXXX", tmpdir.Data());
1363 if (!mkdtemp(templ)) {
1364 Error("MakeScriptPAR",
1365 "Failed to generate temporary directory from template %s",
1371 // Check name of script file
1372 TString scr(script);
1374 if (scr.EndsWith(".C")) ext = "C";
1375 else if (scr.EndsWith(".cxx")) ext = "cxx";
1376 else { ext = "C"; scr.Append(".C"); }
1378 // Check if we can access the file
1379 TString path = TString::Format(".:%s", TROOT::GetMacroPath());
1380 char* loc = gSystem->Which(path, scr);
1381 if (!loc) throw TString::Format("Script %s not found in %s",
1382 scr.Data(), path.Data());
1385 TString dir = TString::Format("%s/%s", templ, base.Data());
1386 // Set-up directories
1387 if (gSystem->MakeDirectory(dir) < 0)
1388 throw TString::Format("Could not make directory '%s'", base.Data());
1390 if (gSystem->MakeDirectory(Form("%s/PROOF-INF", dir.Data())))
1391 throw TString::Format("Could not make directory %s/PROOF-INF",
1394 // Copy the script to the setup directory
1395 TString dest = TString::Format("%s/%s.%s", dir.Data(),
1396 base.Data(), ext.Data());
1397 Int_t ret = gSystem->CopyFile(full, dest, true);
1399 case -1: throw TString::Format("Couldn't open %s for copy", scr.Data());
1400 case -2: throw TString::Format("File %s exists", dest.Data());
1401 case -3: throw TString::Format("Error while copying %s", scr.Data());
1404 // Make our build file
1405 // Info("MakeScriptPAR", "Making build script %s/PROOF-INF/BUILD.sh", dir.Data());
1406 std::ofstream b(Form("%s/PROOF-INF/BUILD.sh", dir.Data()));
1408 throw TString::Format("Failed to open b shell script");
1410 << "echo BUILD.sh@`hostname`: Building " << base << "\n"
1411 << "root.exe -l -b -q PROOF-INF/BUILD.C 2>&1 | tee " << base << ".log\n"
1412 << "echo BUILD.sh@`hostname`: done: $?\n"
1415 if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", dir.Data()), 0755) != 0)
1416 throw TString::Format("Failed to set exectuable flags on "
1417 "%s/PROOF-INF/BUILD.sh", dir.Data());
1419 // Info("MakeScriptPAR", "Making utility script %s/PROOF-INF/UTIL.C", dir.Data());
1420 std::ofstream u(Form("%s/PROOF-INF/UTIL.C", dir.Data()));
1422 throw TString::Format("Failed to open utility script");
1423 u << "void LoadROOTLibs() {\n"
1424 << " gSystem->Load(\"libVMC\");\n"
1425 << " gSystem->Load(\"libNet\");\n"
1426 << " gSystem->Load(\"libTree\");\n"
1427 << " gSystem->Load(\"libPhysics\");\n"
1428 << " gSystem->Load(\"libMinuit\");\n"
1430 << "void AddAliROOT() {\n"
1431 << " TString val(gSystem->Getenv(\"ALICE_ROOT\"));\n"
1432 << " if (val.IsNull())\n"
1433 << " Warning(\"Add\",\"ALICE_ROOT not defined\");\n"
1435 << " gSystem->AddIncludePath(Form(\"-I%s/include\",val.Data()));\n"
1437 << "void AddDep(const char* env) {\n"
1438 << " TString val(gSystem->Getenv(Form(\"%s_INCLUDE\",env)));\n"
1439 << " if (val.IsNull())\n"
1440 << " Warning(\"Add\",\"%s_INCLUDE not defined\", env);\n"
1442 << " gSystem->AddIncludePath(Form(\"-I../%s\",val.Data()));\n"
1445 << "void LoadDep(const char* name) {\n"
1446 << " gSystem->AddDynamicPath(Form(\"../%s\",name));\n"
1447 << " char* full = gSystem->DynamicPathName(name,true);\n"
1449 << " full = gSystem->DynamicPathName(Form(\"lib%s\",name),true);\n"
1451 << " full = gSystem->DynamicPathName(Form(\"lib%s.so\",name),true);\n"
1452 << " if (!full) {\n"
1453 << " Warning(\"LoadDep\",\"Module %s not found\", name);\n"
1456 << " gSystem->Load(full);\n"
1461 // Info("MakeScriptPAR", "Making utility script %s/PROOF-INF/BUILD.C", dir.Data());
1462 std::ofstream cbuild(Form("%s/PROOF-INF/BUILD.C", dir.Data()));
1464 throw TString::Format("Failed to open build script");
1465 cbuild << "void BUILD() {\n"
1466 << " gSystem->AddIncludePath(\"-DBUILD_PAR=1\");\n"
1467 << " gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
1468 << " LoadROOTLibs();\n"
1469 << " AddAliROOT();\n";
1470 TObjArray* depList = TString(deps).Tokenize(",");
1471 TIter next(depList);
1473 while ((dep = next())) {
1474 cbuild << " AddDep(\"" << dep->GetName() << "\");\t"
1475 << " LoadDep(\"" << dep->GetName() << "\");\n";
1477 cbuild << " // gDebug = 5;\n"
1478 << " int ret = gROOT->LoadMacro(\""
1479 << base << "." << ext << "++g\");\n"
1480 << " if (ret != 0) Fatal(\"BUILD\",\"Failed to build\");\n"
1481 << " // else Info(\"BUILD\", \"Made " << base << "\");\n"
1486 // Make our set-up script
1487 // Info("MakeScriptPAR", "Making setup script %s/PROOF-INF/SETUP.C", dir.Data());
1488 std::ofstream setup(Form("%s/PROOF-INF/SETUP.C", dir.Data()));
1490 throw TString::Format("Failed to open setup script");
1491 setup << "void SETUP() {\n"
1492 << " gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
1493 << " LoadROOTLibs();\n"
1494 << " // Info(\"SETUP\",\"Loading libraries\");\n";
1497 while ((dep = next()))
1498 setup << " LoadDep(\"" << dep->GetName() << "\");\n";
1499 setup << " // gDebug = 5;\n"
1500 << " // Info(\"SETUP\",\"Loading " << base << "_" << ext << ".so\");\n"
1501 << " gSystem->Load(\"" << base << "_" << ext << ".so\");\n"
1502 << " // gDebug = 0;\n"
1503 << " gROOT->ProcessLine(\".include " << base << "\");\n"
1504 << " gSystem->Setenv(\"" << base << "_INCLUDE\",\""
1506 << " // Info(\"SETUP\", \"Done\");\n"
1511 // Info("MakeScriptPAR", "Packing up tar-archive");
1512 ret = gSystem->Exec(Form("(cd %s && tar -czf %s.par %s)",
1513 templ, base.Data(),base.Data()));
1515 throw TString::Format("Failed to create PAR file %s.PAR from %s",
1516 base.Data(), dir.Data());
1518 // Info("MakeScriptPAR", "Moving PAR archive");
1519 ret = gSystem->Exec(Form("mv -f %s/%s.par %s.par", templ, base.Data(),
1522 throw TString::Format("Failed to rename %s/%s.par to %s.par: %s",
1523 templ, base.Data(), base.Data(),
1524 gSystem->GetError());
1526 catch (TString& e) {
1527 Error("MakeScriptPAR", "%s", e.Data());
1530 // Info("MakeScriptPAR", "Removing temperary directory %s", templ);
1531 gSystem->Exec(Form("rm -rf %s", templ));
1536 //__________________________________________________________________
1539 * @name Execution implementation
1542 * Start the analysis
1544 * @param mgr Analysis manager
1545 * @param chain Input data (local and proof only)
1546 * @param nEvents Number of events to analyse
1548 Long64_t StartAnalysis(AliAnalysisManager* mgr,
1552 // --- Run the analysis ------------------------------------------
1553 TString mode = ModeString(fExecMode);
1554 switch (fExecMode) {
1557 Error("StartAnalysis", "No chain defined");
1560 if (nEvents < 0) nEvents = chain->GetEntries();
1561 return mgr->StartAnalysis(mode, chain, nEvents);
1563 if (fDataSet.IsNull()) {
1565 Error("StartAnalysis", "No chain defined");
1568 if (nEvents < 0) nEvents = chain->GetEntries();
1569 return mgr->StartAnalysis(mode, chain, nEvents);
1571 return mgr->StartAnalysis(mode, fDataSet);
1574 return mgr->StartAnalysis(mode);
1575 return mgr->StartAnalysis(mode, nEvents);
1577 // We should never get here
1580 //------------------------------------------------------------------
1582 * Connect to external services (Proof and/or grid)
1584 * @return true on success
1586 virtual Bool_t Connect()
1588 if (fExecMode == kLocal) return true;
1590 // --- Set-up connections to Proof cluster and alien -------------
1591 if (fExecMode == kProof) {
1592 Info("Connect", "Opening connection to proof server");
1593 // --- Find user name ------------------------------------------
1594 TString userName(gSystem->Getenv("alien_API_USER"));
1595 if (userName.IsNull()) {
1596 userName = gSystem->GetUserInfo()->fUser;
1598 "environment variable 'alien_API_USER' not set, using %s",
1602 // --- Set prefered GSI method ---------------------------------
1603 gEnv->SetValue("XSec.GSI.DelegProxy", "2");
1605 // --- Figure out some server settings -------------------------
1607 Bool_t lite = false;
1608 if (fProofServer.BeginsWith("workers=") || fProofServer.IsNull()) {
1610 serv = fProofServer;
1613 serv = Form("%s@%s", userName.Data(), fProofServer.Data());
1615 // --- Possibly debug slave sessions with GDB ------------------
1617 TString gdbCmd("/usr/bin/gdb --batch -ex run -ex bt --args");
1618 // TString gdbCmd("\"gdb --batch -ex run -ex bt --args\"");
1619 Info("Connect", "Using GDB to wrap slaves: %s", gdbCmd.Data());
1620 TProof::AddEnvVar("PROOF_WRAPPERCMD", gdbCmd);
1623 // --- Add ALICE_ROOT directory to search path for packages ----
1624 Info("Connect", "Set location of packages");
1625 gEnv->SetValue("Proof.GlobalPackageDirs",
1627 gEnv->GetValue("Proof.GlobalPackageDirs", "."),
1628 gSystem->Getenv("ALICE_ROOT")));
1630 // --- Set OADB path on workers --------------------------------
1631 const char* oadbPath = AliAnalysisManager::GetOADBPath();
1632 TProof::AddEnvVar("OADB_PATH", oadbPath);
1633 // if (lite) gSystem->Setenv("OADB_PATH", oadbPath);
1634 // Info("Connect", "OADB_PATH=%s", gSystem->Getenv("OADB_PATH"));
1636 // --- Now open connection to PROOF cluster --------------------
1639 Error("Connect", "Failed to connect to Proof cluster %s as %s",
1640 fProofServer.Data(), userName.Data());
1643 Info("Connect", "Now connected to Proof");
1644 // gProof->SetParameter("PROOF_LookupOpt", "all");
1645 if (lite) return true;
1648 // --- Open a connection to the grid -----------------------------
1650 TGrid::Connect("alien://");
1651 if (!gGrid || !gGrid->IsConnected()) {
1652 // This is only fatal in grid mode
1653 Error("Connect", "Failed to connect to AliEN");
1654 if (fExecMode == kGrid) return false;
1657 if (fExecMode == kGrid) return true;
1659 // --- Set and make output directory -----------------------------
1660 TString name = EscapedName();
1661 TString homeDir(gGrid->GetHomeDirectory());
1662 TString workDir(homeDir);
1663 workDir.Append("/");
1664 workDir.Append(name);
1666 // Make working directory
1667 if (!gGrid->Cd(workDir)) {
1669 if (gGrid->Mkdir(workDir)) {
1671 Info("Connect", "Directory %s created", workDir.Data());
1674 // Make output directory
1675 gGrid->Mkdir("proof_output");
1676 gGrid->Cd("proof_output");
1680 //------------------------------------------------------------------
1682 * Get the output directory (local or Grid)
1684 * @param mode Mode of execution
1686 * @return Path to output directory
1688 TString GetOutputDirectory(EMode mode) const
1690 TString ret(fEscapedName);
1691 if (mode != kGrid) return ret;
1693 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
1695 Warning("GetOutputDirectory", "No analysis manager defined yet");
1698 AliAnalysisGrid* ag = am->GetGridHandler();
1700 Warning("GetOutputDirectory", "No grid handler defined yet");
1703 AliAnalysisAlien* aa = dynamic_cast<AliAnalysisAlien*>(ag);
1705 Warning("GetOutputDirectory", "Grid handler isn't for AliEn");
1708 ret = aa->GetGridOutputDir();
1709 if (!ret.BeginsWith("/")) {
1711 ret = Form("%s/%s/%s", gGrid->GetHomeDirectory(),
1712 fEscapedName.Data(), aa->GetGridOutputDir());
1714 ret = Form("%s/%s", fEscapedName.Data(), aa->GetGridOutputDir());
1720 //__________________________________________________________________
1726 * Make our working directory if so requested
1728 * @return true on success
1730 Bool_t SetupWorkingDirectory()
1732 TString nam = EscapedName();
1733 //Info("Init","Current dir=%s, escaped name=%s",cwd.Data(),nam.Data());
1734 Bool_t exists = gSystem->AccessPathName(nam.Data()) == 0;
1735 if (fExecOper == kTerminate && !exists) {
1736 Error("SetupWorkingDirectory", "File/directory %s does not exists",
1742 if (!fAllowOverwrite && exists) {
1743 Error("SetupWorkingDirectory", "File/directory %s already exists",
1749 if (gSystem->MakeDirectory(nam.Data())) {
1750 Error("SetupWorkingDirectory", "Failed to make directory '%s'",
1756 if (!gSystem->ChangeDirectory(nam.Data())) {
1757 Error("SetupWorkingDirectory", "Failed to change directory to %s",
1761 Info("SetupWorkingDirectory", "Made subdirectory %s, and cd'ed there",
1765 //------------------------------------------------------------------
1769 * @param what PAR file
1771 * @return true on success
1773 Bool_t SetupPAR(const char* what)
1775 if (!what || what[0] == '\0') return -1;
1777 TString parFile(Form("%s.par", what));
1778 if (gSystem->AccessPathName(parFile.Data())) {
1779 if (gSystem->AccessPathName(Form("../%s.par", what))) {
1781 TString aliParFile =
1782 gSystem->ExpandPathName(Form("$(ALICE_ROOT)/%s.par", what));
1783 if (gSystem->AccessPathName(aliParFile.Data())) {
1784 Error("SetupPAR", "PAR file %s not found in current directory or "
1785 "$(ALICE_ROOT)", what);
1788 // Copy to current directory
1789 TFile::Cp(aliParFile, parFile);
1792 gSystem->Exec(Form("ln -s ../%s.par .", what));
1796 gSystem->Exec(Form("tar xzf %s", parFile.Data()));
1798 // Change directory into par archive
1799 TString cwd = gSystem->WorkingDirectory();
1801 if (!gSystem->ChangeDirectory(what)) {
1802 Error("SetupPAR", "Failed to change directory to %s", what);
1807 if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
1808 Info("SetupPar", "Building in PAR archive %s", what);
1809 if (gSystem->Exec("PROOF-INF/BUILD.sh")) {
1810 Error("SetupPar", "Failed to build in PAR directory %s", what);
1811 gSystem->ChangeDirectory(cwd.Data());
1816 // Check for setup script
1817 if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
1818 // Info("SetupPAR", "Setting up for PAR %s", what);
1819 gROOT->Macro("PROOF-INF/SETUP.C");
1821 if (!gSystem->ChangeDirectory(cwd.Data())) return false;
1825 //------------------------------------------------------------------
1827 * Set-up extra sources.
1829 * @return true on success
1831 TString SetupExtras()
1834 TIter next(&fListOfExtras);
1835 TObjString* obj = 0;
1836 while ((obj = static_cast<TObjString*>(next()))) {
1837 TString path = gSystem->ExpandPathName(obj->GetName());
1838 if (!path.BeginsWith("/"))
1839 // If not an absolute path, prepend to up-one
1840 path = Form("../%s", path.Data());
1841 if (gSystem->AccessPathName(path.Data())) {
1842 // File not accessible
1843 Warning("SetupExtras", "File %s not accessible", path.Data());
1846 ret.Append(Form("%s ", gSystem->BaseName(obj->GetName())));
1847 gSystem->Exec(Form("ln -s %s .", path.Data()));
1852 //------------------------------------------------------------------
1854 * Set-up sources for upload
1857 * @return String of sources
1859 TString SetupSources()
1861 TString nam = EscapedName();
1863 TIter next(&fListOfSources);
1865 while ((src = next())) {
1866 TString path = gSystem->ExpandPathName(src->GetName());
1867 if (!path.BeginsWith("/"))
1868 // If not an absolute path, prepend to up-one
1869 path = Form("../%s", path.Data());
1870 if (gSystem->AccessPathName(path.Data())) {
1871 // File not accessible
1872 Warning("SetupSources", "File %s not accessible", path.Data());
1875 ret.Append(Form("%s ", gSystem->BaseName(src->GetName())));
1876 gSystem->Exec(Form("ln -s %s .", path.Data()));
1881 //------------------------------------------------------------------
1883 * Set-up extra libraries to upload
1885 * @return String of libraries
1887 TString SetupLibraries()
1890 TIter next(&fListOfLibraries);
1892 while ((lib = next())) {
1893 ret.Append(lib->GetName());
1896 // Also add extra files to this variable
1897 ret.Append(SetupExtras());
1903 //__________________________________________________________________
1906 * @name Chain building
1909 * Check if we can add a file to the chain
1911 * @param path Full path to file
1912 * @param chain Chain
1914 * @return true on success, false otherwise
1916 Bool_t CheckFile(const TString& path, TChain* chain)
1918 TFile* test = TFile::Open(path, "READ");
1920 Warning("CheckFile", "Failed to open %s", path.Data());
1924 Bool_t ok = false; // Assume failure
1925 TObject* o = test->Get(chain->GetName());
1927 Warning("CheckFile", "The file %s does not contain the object %s",
1928 path.Data(), chain->GetName());
1929 else if (!dynamic_cast<TTree*>(o))
1930 Warning("CheckFile", "Object %s found in %s is not a TTree",
1931 o->GetName(), path.Data());
1935 if (ok) chain->AddFile(path);
1940 * Scan directory @a dir (possibly recursive) for tree files to add
1941 * to the chain. This does not follow sym-links
1943 * @param dir Directory to scan
1944 * @param chain Chain to add to
1945 * @param recursive Whether to scan recursively
1947 * @return true if any files where added
1949 Bool_t ScanDirectory(TSystemDirectory* dir, TChain* chain,
1953 switch (fExecType) {
1954 case kESD: fnPattern = "AliESD"; break;
1955 case kAOD: fnPattern = "AliAOD"; break;
1956 case kUser: fnPattern = ""; break;
1962 // Get list of files, and go back to old working directory
1963 TString oldDir(gSystem->WorkingDirectory());
1964 TList* files = dir->GetListOfFiles();
1965 if (!gSystem->ChangeDirectory(oldDir)) {
1966 Error("ScanDirectory", "Failed to go back to %s", oldDir.Data());
1969 if (!files) return false;
1973 Bool_t hasGAlice = (!(fMC || fExecType == kAOD) ? true : false);
1974 Bool_t hasKine = (!(fMC || fExecType == kAOD) ? true : false);
1975 Bool_t hasTrRef = (!(fMC || fExecType == kAOD) ? true : false);
1977 // Sort list of files and check if we should add it
1980 TSystemFile* file = 0;
1981 while ((file = static_cast<TSystemFile*>(next()))) {
1982 TString name(file->GetName());
1983 TString title(file->GetTitle());
1984 TString full(gSystem->ConcatFileName(file->GetTitle(), name.Data()));
1985 if (dynamic_cast<TSystemDirectory*>(file)) full = title;
1986 // Ignore special links
1987 if (name == "." || name == "..") {
1988 // Info("ScanDirectory", "Ignoring %s", name.Data());
1993 if (gSystem->GetPathInfo(full.Data(), fs)) {
1994 Warning("ScanDirectory", "Cannot stat %s (%s)", full.Data(),
1995 gSystem->WorkingDirectory());
1998 // Check if this is a directory
1999 if (file->IsDirectory(full)) {
2001 // if (title[0] == '/')
2002 TSystemDirectory* d = new TSystemDirectory(file->GetName(),
2004 if (ScanDirectory(d,chain,recursive))
2011 // If this is not a root file, ignore
2012 if (!name.EndsWith(".root")) continue;
2014 // If this file does not contain AliESDs, ignore
2015 if (!name.Contains(fnPattern)) {
2016 // Info("ScanDirectory", "%s does not match pattern %s",
2017 // name.Data(), fnPattern.Data());
2018 if (fMC && fExecType == kESD) {
2019 if (name.CompareTo("galice.root") == 0) hasGAlice = true;
2020 if (name.CompareTo("Kinematics.root") == 0) hasKine = true;
2021 if (name.CompareTo("TrackRefs.root") == 0) hasTrRef = true;
2027 // Info("ScanDirectory", "Adding %s", full.Data());
2028 toAdd.Add(new TObjString(full));
2031 if (fMC && fExecType == kESD && toAdd.GetEntries() > 0 &&
2032 (!hasGAlice || !hasKine || !hasTrRef)) {
2033 Warning("ScanDirectory",
2034 "one or more of {galice,Kinematics,TrackRefs}.root missing from "
2035 "%s, not adding anything from this directory",
2040 TIter nextAdd(&toAdd);
2043 while ((s = static_cast<TObjString*>(nextAdd()))) {
2044 // Info("ScanDirectory", "Adding %s", s->GetString().Data());
2045 TString fn = s->GetString();
2046 if (!CheckFile(fn, chain)) continue;
2050 if (added > 0) ret = true;
2052 gSystem->ChangeDirectory(oldDir);
2055 //------------------------------------------------------------------
2057 * Create a chain from an XML containing an collection
2059 * @param treeName Name of tree's
2060 * @param xmlFile XML collection
2062 * @return Newly allocated chain or null
2064 TChain* CreateChainFromXML(const char* treeName,
2065 const char* xmlFile)
2067 Long_t ret = gROOT->ProcessLine(Form("TAlienCollection(\"%s\")",
2070 Error("CreateChainFromXML", "Cannot create AliEn collection from "
2071 "XML file %s", xmlFile);
2075 TGridCollection* collection = reinterpret_cast<TGridCollection*>(ret);
2077 Error("CreateChainFromXML", "Cannot create AliEn collection from "
2078 "XML file %s", xmlFile);
2082 TChain* chain = new TChain(treeName);
2083 collection->Reset();
2084 while (collection->Next()) chain->Add(collection->GetTURL(""));
2088 //------------------------------------------------------------------
2090 * Create a chain of data
2092 * @return TChain of data
2094 TChain* CreateChain()
2097 switch (fExecType) {
2098 case kESD: treeName = "esdTree"; break;
2099 case kAOD: treeName = "aodTree"; break;
2100 case kUser: treeName = ""; break;
2104 switch (fExecMode) {
2106 if (!fDataSet.IsNull()) break;
2107 // Otherwise fall through
2109 if (fXML.IsNull()) {
2110 chain = new TChain(treeName.Data());
2111 TString dir(fDataDir);
2112 if (dir == ".") dir = "";
2113 if (!dir.BeginsWith("/")) dir = Form("../%s", dir.Data());
2115 gSystem->GetPathInfo(dir, stat);
2116 if (!R_ISDIR(stat.fMode)) { // A file, check it
2117 if (!CheckFile(dir, chain)) {
2123 TString savdir(gSystem->WorkingDirectory());
2124 TSystemDirectory d(gSystem->BaseName(dir.Data()), dir.Data());
2125 if (!ScanDirectory(&d, chain, true)) {
2129 gSystem->ChangeDirectory(savdir);
2132 chain = CreateChainFromXML(treeName.Data(), fXML.Data());
2134 case kGrid: break; // Do nothing - we use plugin
2137 if (chain && chain->GetNtrees() <= 0) {
2146 //====================================================================
2156 * @param name Option name
2157 * @param desc Option description
2158 * @param arg Option argument, if any
2160 Option(const char* name, const char* desc, const char* arg="")
2168 * Process an option string.
2170 * @param opt String to process
2172 * @return true, if this handled the option, false otherwise
2174 Bool_t Process(const TString& opt)
2176 // Info("Option::Process", "Option %s processing %s",
2177 // fName.Data(), opt.Data());
2178 if (!opt.BeginsWith(fName, TString::kIgnoreCase)) return false;
2180 // We've got a value
2183 // No argument options shouldn't set a value
2184 if (fArg.IsNull()) return true;
2187 Int_t eq = opt.Index("=");
2189 // Empty string is an OK value
2190 if (eq == kNPOS) return true;
2192 TString tmp = opt(eq+1,opt.Length()-eq-1);
2193 fValue = tmp.Strip();
2198 * Get option value as a string
2200 * @return Option value
2202 const TString& AsString() const { return fValue; }
2204 * Get option value as a double
2206 * @return Option value
2208 Double_t AsDouble() const { return fValue.Atof(); }
2210 * Get option value as an integer
2212 * @return Option value
2214 Int_t AsInt() const { return fValue.Atoi(); }
2216 * Get option value as a boolean
2218 * @return Option value
2220 Bool_t AsBool() const { return fIsSet; }
2222 * Test if the option has been set.
2224 * @return True if the option was given
2226 Bool_t IsSet() const { return fIsSet; }
2230 * @param o Stream to write on
2231 * @param prefix Prefix
2233 void PrintHelp(std::ostream& o, const char* prefix) const
2236 if (!fArg.IsNull()) arg.Append(Form("=%s", fArg.Data()));
2237 o << " " << (prefix ? prefix : "")
2238 << std::left << std::setw(30) << arg
2239 << " " << std::setw(30) << fDesc
2240 << " [" << std::right << fValue << "]" << std::endl;
2245 * @param o Stream to write on
2247 void PrintSettings(std::ostream& o) const
2249 o << " " << std::left << std::setw(30) << fName << ": ";
2250 if (fArg.IsNull()) o << (IsSet() ? "true" : "false");
2257 * @param str object nmae
2259 * @param o Stream to write on
2261 void Save(std::ostream& o, const char* str, bool val)
2264 if (str[0] == '-') {
2265 o << " " << str << fName << " \\" << std::endl;
2268 o << " " << str << ".Append(\"" << fName << ",\");" << std::endl;
2273 * @param str object nmae
2275 * @param o Stream to write on
2277 void Save(std::ostream& o, const char* str, Int_t val)
2279 if (str[0] == '-') {
2280 o << " " << str << fName << "=" << val << " \\" << std::endl;
2283 o << " " << str << ".Append(\"" << fName << "=" << val
2284 << ",\");" << std::endl;
2289 * @param str object nmae
2291 * @param o Stream to write on
2293 void Save(std::ostream& o, const char* str, Double_t val)
2295 if (str[0] == '-') {
2296 o << " " << str << fName << "=" << val << " \\" << std::endl;
2299 o << " " << str << ".Append(\"" << fName << "=" << val
2300 << ",\");" << std::endl;
2305 * @param str object nmae
2307 * @param o Stream to write on
2309 void Save(std::ostream& o, const char* str, const char* val)
2311 if (str[0] == '-') {
2313 sval.ReplaceAll(" ", "\\ ");
2314 o << " " << str << fName << "=" << sval << " \\" << std::endl;
2317 o << " " << str << ".Append(\"" << fName << "=" << val
2318 << ",\");" << std::endl;
2321 TString fName; // Name of the option
2322 TString fDesc; // Decription
2323 TString fArg; // Argument, if any
2324 Bool_t fIsSet; // Whether the option has been set.
2325 TString fValue; // Value of the option.
2327 //====================================================================
2337 * @param train Train to run
2338 * @param max Maximum number of options
2340 Runner(TrainSetup& train, UShort_t max=30)
2341 : fTrain(&train), fOptions(0), fN(0), fMax(max)
2343 fOptions = new Option*[fMax];
2344 for (Int_t i = 0; i < fMax; i++) fOptions[i] = 0;
2349 * @param opt Option to add
2351 void Add(Option* opt)
2354 Warning("AddOption", "No room for option %s", opt->fName.Data());
2357 fOptions[fN++] = opt;
2364 void Remove(const TString& name)
2366 Option** ptr = fOptions;
2369 if (name.EqualTo((*ptr)->fName)) {
2375 if (!tmp) // nothing found, returning
2391 * Parse option string
2393 * @param options Option string.
2394 * @param delim Delimiters
2396 * @return true on success.
2398 Bool_t Parse(const TString& options, const char* delim=",;")
2400 TObjArray* a = options.Tokenize(delim);
2408 * @return true on success
2410 Bool_t Parse(TObjArray& options)
2412 TIter next(&options);
2414 while ((os = static_cast<TObjString*>(next()))) {
2415 TString s(os->String());
2416 // Info("Runner::Parse", "Processing option %s", s.Data());
2417 if (s.IsNull()) continue;
2420 Option** ptr = fOptions;
2421 while (*ptr && !ok) {
2423 if (o->Process(s)) ok = true;
2428 Warning("Parse", "Unknown option %s", s.Data());
2433 * Check if we asked for help
2438 Bool_t IsHelpAsked() const
2440 Option* help = FindOption("help");
2441 return (help && help->IsSet());
2446 * @param out Stream to write on
2447 * @param prefix Prefix
2449 void PrintHelp(std::ostream& out, const char* prefix="") const
2451 Option** ptr = fOptions;
2452 if (fTrain) fTrain->SetOptionDefaults(const_cast<Runner&>(*this));
2454 (*ptr)->PrintHelp(out, prefix);
2459 * Print the settings
2461 * @param out Stream to write on.
2463 void PrintSettings(std::ostream& out) const
2465 Option** ptr = fOptions;
2467 (*ptr)->PrintSettings(out);
2472 * Find an option by name
2474 * @param name Name of option to find
2476 * @return Pointer to option, or null
2478 Option* FindOption(const TString& name) const
2480 Option** ptr = fOptions;
2482 if (name.EqualTo((*ptr)->fName)) return *ptr;
2488 * Initialize the train
2490 * @param options Execution options
2492 * @return true on success
2494 Bool_t Init(const TString& options)
2496 fTrain->MakeOptions(*this);
2497 if (!Parse(options)) return false;
2503 * @param runs Run numbers
2504 * @param nEvents Number of events
2505 * @param asShell Save set-up as shell script
2509 Bool_t Run(const TString& runs, Int_t nEvents, Bool_t asShell=false)
2511 PrintSettings(std::cout);
2513 fTrain->SetOptions(*this);
2514 fTrain->SetRuns(runs);
2515 // fTrain->SaveSetup(*this, nEvents, asShell);
2517 fTrain->Run(nEvents, this, asShell);
2522 Option** fOptions; // Our options
2523 UShort_t fN; // Current number of options
2524 UShort_t fMax; // Maximum number of options
2527 //__________________________________________________________________
2533 * Class name of this train setup. Sub-classes must define this.
2535 * @return Class name of this setup
2537 virtual const char* ClassName() const = 0;
2538 //------------------------------------------------------------------
2540 * Make the options for this train. Sub-classes can overload this
2541 * to define new options, or append to the set of default option.
2543 virtual void MakeOptions(Runner& r)
2545 r.Add(new Option("help", "Show this help"));
2546 r.Add(new Option("par", "Use PAR files (PROOF and Grid)"));
2547 r.Add(new Option("mc", "Assume simulation input"));
2548 r.Add(new Option("debug", "Execute in debugger"));
2549 r.Add(new Option("type", "Type of train", "AOD|ESD"));
2550 r.Add(new Option("mode", "Execution mode", "LOCAL|PROOF|GRID"));
2551 r.Add(new Option("oper", "Operation mode", "TEST|TERMINATE|FULL|INIT"));
2552 r.Add(new Option("date", "Set date string", "YYYY-MM-DD HH:MM:SS"));
2553 r.Add(new Option("cluster","PROOF cluster", "HOST"));
2554 r.Add(new Option("dataSet","Data set (PROOF only)", "NAME"));
2555 r.Add(new Option("dataDir","Data directory", "DIRECTORY"));
2556 r.Add(new Option("pattern","Data pattern (grid only)", "GLOB"));
2557 r.Add(new Option("verb", "Verbosity", "NUMBER"));
2558 r.Add(new Option("root", "ROOT version (Grid)", "TAG"));
2559 r.Add(new Option("aliroot","AliROOT version (Grid)","TAG"));
2560 r.Add(new Option("alien", "AliEn API version (Grid)","TAG"));
2561 r.Add(new Option("overwrite", "Allow overwrite"));
2562 r.Add(new Option("per-run", "Per run merge"));
2564 //------------------------------------------------------------------
2566 * Set the option values on the train. Sub-classes can overload
2567 * this to set custom options on the train.
2569 virtual void SetOptionDefaults(Runner& r)
2571 Option* debug = r.FindOption("debug");
2572 Option* date = r.FindOption("date");
2573 Option* cluster = r.FindOption("cluster");
2574 Option* dataSet = r.FindOption("dataSet");
2575 Option* dataDir = r.FindOption("dataDir");
2576 Option* pattern = r.FindOption("pattern");
2577 Option* par = r.FindOption("par");
2578 Option* type = r.FindOption("type");
2579 Option* mode = r.FindOption("mode");
2580 Option* oper = r.FindOption("oper");
2581 Option* mc = r.FindOption("mc");
2582 Option* verb = r.FindOption("verb");
2583 Option* root = r.FindOption("root");
2584 Option* aliroot = r.FindOption("aliroot");
2585 Option* alien = r.FindOption("alien");
2586 Option* overwrite = r.FindOption("overwrite");
2587 Option* run_merge = r.FindOption("per-run");
2589 if (date && !date->IsSet()) date->fValue = fDatime.AsString();
2590 if (cluster && !cluster->IsSet()) cluster->fValue = fProofServer;
2591 if (dataSet && !dataSet->IsSet()) dataSet->fValue = fDataSet;
2592 if (dataDir && !dataDir->IsSet()) dataDir->fValue = fDataSet;
2593 if (pattern && !pattern->IsSet()) pattern->fValue = fDataPattern;
2594 if (debug && !debug->IsSet()) debug->fValue = fUseGDB ? "1" : "";
2595 if (type && !type->IsSet()) type->fValue = TypeString(fExecType);
2596 if (mode && !mode->IsSet()) mode->fValue = ModeString(fExecMode);
2597 if (oper && !oper->IsSet()) oper->fValue = OperString(fExecOper);
2598 if (par && !par->IsSet()) par->fValue = fUsePar ? "1" : "";
2599 if (mc && !mc->IsSet()) mc->fValue = fMC ? "1" : "";
2600 if (verb && !verb->IsSet()) verb->fValue = Form("%d", fVerbose);
2601 if (root && !root->IsSet()) root->fValue = fRootVersion;
2602 if (aliroot && !aliroot->IsSet()) aliroot->fValue = fAliRootVersion;
2603 if (alien && !alien->IsSet()) alien->fValue = fAliEnAPIVersion;
2604 if (overwrite && !overwrite->IsSet())
2605 overwrite->fValue = fAllowOverwrite ? "1" : "";
2606 if (run_merge && !run_merge->IsSet())
2607 run_merge->fValue = fPerRunMerge ? "1" : "";
2610 * Set the option values on the train. Sub-classes can overload
2611 * this to set custom options on the train.
2613 virtual void SetOptions(Runner& r)
2615 Option* debug = r.FindOption("debug");
2616 Option* date = r.FindOption("date");
2617 Option* cluster = r.FindOption("cluster");
2618 Option* dataSet = r.FindOption("dataSet");
2619 Option* dataDir = r.FindOption("dataDir");
2620 Option* pattern = r.FindOption("pattern");
2621 Option* par = r.FindOption("par");
2622 Option* type = r.FindOption("type");
2623 Option* mode = r.FindOption("mode");
2624 Option* oper = r.FindOption("oper");
2625 Option* mc = r.FindOption("mc");
2626 Option* verb = r.FindOption("verb");
2627 Option* root = r.FindOption("root");
2628 Option* aliroot = r.FindOption("aliroot");
2629 Option* alien = r.FindOption("alien");
2630 Option* overwrite = r.FindOption("overwrite");
2631 Option* run_merge = r.FindOption("per-run");
2633 if (date && date->IsSet()) SetDateTime(date->AsString());
2634 if (cluster) SetProofServer(cluster->AsString());
2635 if (dataSet) SetDataSet(dataSet->AsString());
2636 if (dataDir) SetDataDir(dataDir->AsString());
2637 if (pattern) SetDataPattern(pattern->AsString());
2638 if (debug) SetUseGDB(debug->AsBool());
2639 if (type && type->IsSet()) SetType(type->AsString());
2640 if (mode && mode->IsSet()) SetMode(mode->AsString());
2641 if (oper && oper->IsSet()) SetOperation(oper->AsString());
2642 if (par) SetUsePar(par->AsBool());
2643 if (mc) SetMC(mc->AsBool());
2644 if (verb) SetVerbose(verb->AsInt());
2645 if (root) SetROOTVersion(root->AsString());
2646 if (aliroot) SetAliROOTVersion(aliroot->AsString());
2647 if (alien) SetAliEnAPIVersion(alien->AsString());
2648 if (overwrite) SetAllowOverwrite(overwrite->AsBool());
2649 if (run_merge) SetPerRunMerge(run_merge->AsBool());
2651 //------------------------------------------------------------------
2653 * Set the option values on the train. Sub-classes can overload
2654 * this to set custom options on the train.
2656 virtual void SaveOptions(std::ostream& o, const char* str, Runner& r)
2658 Option* debug = r.FindOption("debug");
2659 Option* date = r.FindOption("date");
2660 Option* cluster = r.FindOption("cluster");
2661 Option* dataSet = r.FindOption("dataSet");
2662 Option* dataDir = r.FindOption("dataDir");
2663 Option* pattern = r.FindOption("pattern");
2664 Option* par = r.FindOption("par");
2665 Option* type = r.FindOption("type");
2666 Option* mode = r.FindOption("mode");
2667 Option* oper = r.FindOption("oper");
2668 Option* mc = r.FindOption("mc");
2669 Option* verb = r.FindOption("verb");
2670 Option* root = r.FindOption("root");
2671 Option* aliroot = r.FindOption("aliroot");
2672 Option* alien = r.FindOption("alien");
2673 Option* overwrite = r.FindOption("overwrite");
2674 Option* run_merge = r.FindOption("per-run");
2676 if (date) date->Save(o, str,
2677 Form("%04d-%02d-%02d %02d:%02d:00",
2682 fDatime.GetMinute()));
2683 if (cluster) cluster->Save(o, str, fProofServer);
2684 if (dataSet) dataSet->Save(o, str, fDataSet);
2685 if (dataDir) dataDir->Save(o, str, fDataDir);
2686 if (pattern) pattern->Save(o, str, fDataPattern);
2687 if (debug) debug->Save(o, str, fUseGDB);
2688 if (type) type->Save(o, str, TypeString(fExecType));
2689 if (mode) mode->Save(o, str, ModeString(fExecMode));
2690 if (oper) oper->Save(o, str, OperString(fExecOper));
2691 if (par) par->Save(o, str, fUsePar);
2692 if (mc) mc->Save(o, str, fMC);
2693 if (verb) verb->Save(o, str, fVerbose);
2694 if (root) root->Save(o, str, fRootVersion);
2695 if (aliroot) aliroot->Save(o, str, fAliRootVersion);
2696 if (alien) alien->Save(o, str, fAliEnAPIVersion);
2697 if (overwrite)overwrite->Save(o, str, fAllowOverwrite);
2698 if (run_merge)run_merge->Save(o, str, fPerRunMerge);
2701 * Save the setup to file for later re-execution
2703 * @param r Runner object
2704 * @param nEvents Number of events
2705 * @param asShell If true, save as shell script - otherwise ROOT script
2707 virtual void SaveSetup(Runner& r, Int_t nEvents, Bool_t asShell=false)
2709 if (asShell) SaveSetupShell(r, nEvents);
2710 /* else */ SaveSetupROOT(r, nEvents);
2713 * Save the setup to shell script for later re-execution
2715 * @param r Runner object
2716 * @param nEvents Number of events
2718 virtual void SaveSetupShell(Runner& r, Int_t nEvents)
2720 std::ofstream o("rerun.sh");
2721 o << "#!/bin/bash\n\n"
2723 << "if test x$oper = x ; then oper=full ; fi \n\n"
2724 << "class=\"" << ClassName() << "\"\n"
2725 << "name=\"" << fName << "\"\n"
2726 << "nev=" << nEvents << "\n\n"
2727 << "opts=(--class=$class \\\n"
2728 << " --name=$name \\\n"
2729 << " --events=$nev \\" << std::endl;
2730 for (Int_t i = 0; i < fRunNumbers.GetSize(); i++)
2731 o << " --run=" << fRunNumbers.At(i) << " \\\n";
2732 SaveOptions(o, "--", r);
2733 o << " --oper=$oper)\n\n"
2734 << "echo \"Running runTrain ${opts[@]}\"\n"
2735 << "runTrain \"${opts[@]}\"\n\n"
2736 << "# EOF" << std::endl;
2738 gSystem->Exec("chmod a+x rerun.sh");
2741 * Save the setup to shell script for later re-execution
2743 * @param r Runner object
2744 * @param nEvents Number of events
2746 virtual void SaveSetupROOT(Runner& r, Int_t nEvents)
2748 std::ofstream o("rerun.C");
2749 o << "void rerun(bool terminate=false)\n"
2751 << " TString opts;" << std::endl;
2752 SaveOptions(o, "opts", r);
2754 o << " if (terminate) opts.Append(\"mode=terminate;\");\n\n"
2755 << " TString runs(\"";
2756 for (Int_t i = 0; i < fRunNumbers.GetSize(); i++)
2757 o << (i == 0 ? "" : ", ") << fRunNumbers.At(i);
2759 << " Int_t nEvents = " << nEvents << ";\n\n"
2760 << " gROOT->LoadMacro(\"$ALICE_ROOT/PWGLF/FORWARD/analysis2/trains/RunTrain.C\");\n"
2761 << " RunTrain(\"" << ClassName() << "\",\""
2762 << fName << "\",opts,runs,nEvents);\n"
2764 << "// EOF" << std::endl;
2769 //__________________________________________________________________
2770 TString fName; // Name of analysis
2771 TString fEscapedName; // Name escaped for special chars
2772 TString fRootVersion; // ROOT version to use
2773 TString fAliRootVersion; // AliROOT version to use
2774 TString fAliEnAPIVersion; // AliEn API version to use
2775 TString fProofServer; // Name of proof server
2776 TString fDataDir; // Grid Input directory
2777 TString fDataPattern; // Data directory pattern
2778 TString fDataSet; // Proof data set name
2779 TString fXML; // XML collection for local/proof mode
2780 Int_t fNReplica; // Storage replication
2781 Bool_t fAllowOverwrite; // Allow overwriting output dir
2782 Bool_t fUseGDB; // Wrap PROOF slaves in GDB
2783 Int_t fMaxSplit; // Maximum number of files per split
2784 TArrayI fRunNumbers; // List of run number
2785 TList fListOfPARs; // List of PAR files to use
2786 TList fListOfSources; // List of sources to upload and AcLIC
2787 TList fListOfLibraries; // List of libraries to load
2788 TList fListOfExtras; // List of extra files to upload
2789 TDatime fDatime; // Date and time
2790 EType fExecType; // Execution type (ESD, AOD)
2791 EMode fExecMode; // Execution mode (PROOF, local, Grid)
2792 EOper fExecOper; // Execution operation (full, terminate, ...)
2793 Bool_t fUsePar; // Wether to use PAR files
2794 Bool_t fMC; // Whether to assume MC input
2795 Bool_t fPerRunMerge; // Whether to merge per run or over-all
2796 Int_t fVerbose; // Verbosity level
2799 //____________________________________________________________________