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 // Set output to be per run
937 plugin->SetOutputToRunNo(true);
940 plugin->SetJobTag(fName);
942 // Set number of test files - used in test mode only
943 plugin->SetNtestFiles(1);
945 // Set name of generated analysis macro
946 plugin->SetAnalysisMacro(Form("%s.C", name.Data()));
948 // Maximum number of sub-jobs
949 // plugin->SetSplitMaxInputFileNumber(25);
951 // Set the Time-To-Live
952 plugin->SetTTL(70000);
954 // Re-submit failed jobs as long as the ratio of failed jobs is
955 // below this percentage.
956 plugin->SetMasterResubmitThreshold(95);
958 // Set the input format
959 plugin->SetInputFormat("xml-single");
961 // Set the name of the generated jdl
962 plugin->SetJDLName(Form("%s.jdl", name.Data()));
964 // Set the name of the generated executable
965 plugin->SetExecutable(Form("%s.sh", name.Data()));
967 // Set the job price !?
970 // Set whether to merge via JDL
971 plugin->SetMergeViaJDL(true);
974 plugin->SetFastReadOption(false);
976 // Whether to overwrite existing output
977 plugin->SetOverwriteMode(true);
979 // Set the executable binary name and options
980 plugin->SetExecutableCommand("aliroot -b -q -x");
982 // Split by storage element - must be lower case!
983 plugin->SetSplitMode("se");
984 plugin->SetSplitMaxInputFileNumber(fMaxSplit);
986 // Disable default outputs
987 plugin->SetDefaultOutputs(true);
990 plugin->SetMaxMergeFiles(20);
991 plugin->SetMergeExcludes("AliAOD.root "
993 "*event_stat*.root");
996 plugin->SetKeepLogs();
998 // Set the working directory to be the trains name (with special
999 // characters replaced by '_' and the date appended), and also set
1000 // the output directory (relative to working directory)
1001 plugin->SetGridWorkingDir(name.Data());
1002 plugin->SetGridOutputDir("output");
1004 // Set required version of software
1005 if (!fAliEnAPIVersion.IsNull()) plugin->SetAPIVersion(fAliEnAPIVersion);
1006 if (!fRootVersion.IsNull()) plugin->SetROOTVersion(fRootVersion);
1007 if (!fAliRootVersion.IsNull()) plugin->SetAliROOTVersion(fAliRootVersion);
1009 // Declare root of input data directory
1010 TString dataDir(fDataDir);
1011 if (dataDir.BeginsWith("alien://"))
1012 dataDir.ReplaceAll("alien://", "");
1013 plugin->SetGridDataDir(dataDir);
1015 // Data search patterns
1017 if (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler())
1018 plugin->SetRunPrefix("");
1020 plugin->SetRunPrefix("000");
1023 if (!pat.EndsWith("/")) pat.Append("/");
1024 pat.Append(Form("*%s.root", fExecType == kESD ? "ESDs" : "AOD"));
1025 plugin->SetDataPattern(pat);
1027 // Add the run numbers
1029 for (Int_t i = 0; i < fRunNumbers.fN; i++) {
1030 if (fRunNumbers[i] < 0) continue;
1031 plugin->AddRunNumber(fRunNumbers[i]);
1034 // Set number of runs per master - set to one to per run
1035 if (fPerRunMerge) plugin->SetNrunsPerMaster(1);
1036 else plugin->SetNrunsPerMaster(nRun+1);
1038 // Enable configured PARs
1039 TIter nextPar(&fListOfPARs);
1041 while ((parName = nextPar()))
1042 plugin->EnablePackage(parName->GetName());
1044 // Add sources that need to be compiled on the workers using
1046 TString addSources = SetupSources();
1047 if (!addSources.IsNull()) plugin->SetAnalysisSource(addSources.Data());
1049 // Add binary libraries that should be uploaded to the workers
1050 TString addLibs = SetupLibraries();
1051 if (!addLibs.IsNull()) plugin->SetAdditionalLibs(addLibs.Data());
1053 // Loop over defined containers in the analysis manager,
1054 // and declare these as outputs
1055 TString listOfAODs = "";
1056 TString listOfHists = "";
1057 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
1058 AliAnalysisDataContainer* cont = 0;
1059 TIter nextCont(mgr->GetOutputs());
1060 while ((cont = static_cast<AliAnalysisDataContainer*>(nextCont()))) {
1061 TString outName(cont->GetFileName());
1062 TString& list = (outName == "default" ? listOfAODs : listOfHists);
1063 if (outName == "default") {
1064 if (!mgr->GetOutputEventHandler()) continue;
1066 outName = mgr->GetOutputEventHandler()->GetOutputFileName();
1068 if (list.Contains(outName)) continue;
1069 if (!list.IsNull()) list.Append(",");
1070 list.Append(outName);
1072 if (!mgr->GetExtraFiles().IsNull()) {
1073 if (!listOfAODs.IsNull()) listOfAODs.Append("+");
1074 TString extra = mgr->GetExtraFiles();
1075 extra.ReplaceAll(" ", ",");
1076 listOfAODs.Append(extra);
1078 TString outArchive = Form("stderr, stdout@disk=%d", fNReplica);
1079 if (!listOfHists.IsNull())
1080 outArchive.Append(Form(" hist_archive.zip:%s@disk=%d",
1081 listOfHists.Data(), fNReplica));
1082 if (!listOfAODs.IsNull())
1083 outArchive.Append(Form(" aod_archive.zip:%s@disk=%d",
1084 listOfAODs.Data(), fNReplica));
1085 if (listOfAODs.IsNull() && listOfHists.IsNull())
1086 Fatal("CreateGridHandler", "No outputs defined");
1088 // plugin->SetOutputArchive(outArchive);
1093 //------------------------------------------------------------------
1095 * Create input handler
1101 virtual AliVEventHandler* CreateInputHandler(EType type)
1104 case kESD: return new AliESDInputHandler();
1105 case kAOD: return new AliAODInputHandler();
1106 case kUser: return 0;
1110 //------------------------------------------------------------------
1112 * Create input handler
1114 * @param type Run type (ESD or AOD)
1115 * @param mc Assume monte-carlo input
1119 virtual AliVEventHandler* CreateMCHandler(EType /*type*/, bool mc)
1122 // if (type != kESD) return 0;
1123 Info("CreateMCHandler", "Making MC handler");
1124 AliMCEventHandler* mcHandler = new AliMCEventHandler();
1125 mcHandler->SetReadTR(true);
1128 //------------------------------------------------------------------
1130 * Create output event handler
1136 virtual AliVEventHandler* CreateOutputHandler(EType type)
1138 AliAODHandler* ret = new AliAODHandler();
1141 ret->SetOutputFileName("AliAOD.root");
1144 ret->SetOutputFileName("AliAOD.pass2.root");
1152 //------------------------------------------------------------------
1154 * Create physics selection, and add to manager
1156 * @param mc Whether this is for MC
1157 * @param mgr Manager
1159 virtual void CreatePhysicsSelection(Bool_t mc,
1160 AliAnalysisManager* mgr)
1162 gROOT->Macro(Form("AddTaskPhysicsSelection.C(%d)", mc));
1163 mgr->RegisterExtraFile("event_stat.root");
1165 //------------------------------------------------------------------
1167 * Create centrality selection, and add to manager
1169 * @param mc Whether this is for MC
1170 * @param mgr Manager
1172 virtual void CreateCentralitySelection(Bool_t mc, AliAnalysisManager* mgr)
1174 gROOT->Macro("AddTaskCentrality.C");
1175 const char* name = "CentralitySelection";
1176 AliCentralitySelectionTask* ctask =
1177 dynamic_cast<AliCentralitySelectionTask*>(mgr->GetTask(name));
1179 if (mc) ctask->SetMCInput();
1181 //------------------------------------------------------------------
1183 * Create analysis tasks. Must be overloaded by sub-class
1185 * @param mode Run mode
1186 * @param mgr Manager
1187 * @param par Whether to use pars
1189 virtual void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)=0;
1192 //__________________________________________________________________
1195 * @name Library loading
1197 //------------------------------------------------------------------
1199 * Load common libraries
1201 * @return true on success
1203 Bool_t LoadCommonLibraries()
1205 if (!gSystem->Getenv("ALICE_ROOT")) {
1206 Error("LoadCommonLibraries", "Local AliROOT not available");
1209 gSystem->Load("libTree.so");
1210 gSystem->Load("libGeom.so");
1211 gSystem->Load("libVMC.so");
1212 gSystem->Load("libPhysics.so");
1213 gSystem->Load("libMinuit.so");
1214 if (fExecMode == kProof) {
1215 gProof->Exec("gSystem->Load(\"libTree.so\");");
1216 gProof->Exec("gSystem->Load(\"libGeom.so\");");
1217 gProof->Exec("gSystem->Load(\"libMinuit.so\");");
1218 gProof->Exec("gSystem->Load(\"libVMC.so\");");
1224 Bool_t basic = fExecMode == kGrid ? false : fUsePar;
1226 ret &= LoadLibrary("STEERBase", basic, false);
1227 ret &= LoadLibrary("ESD", basic, false);
1228 ret &= LoadLibrary("AOD", basic, false);
1229 ret &= LoadLibrary("ANALYSIS", basic, true);
1230 ret &= LoadLibrary("OADB", basic, true);
1231 ret &= LoadLibrary("ANALYSISalice", basic, true);
1235 //------------------------------------------------------------------
1239 * @param what What library to load
1240 * @param par If true, load as PAR
1241 * @param rec If true, also load on slaves
1243 * @return true on success
1245 Bool_t LoadLibrary(const char* what, Bool_t par, Bool_t rec=false)
1247 if (!what || what[0] == '\0') return true;
1249 TString module(what);
1250 TString libName(what);
1251 if (!libName.BeginsWith("lib")) {
1252 // Check if the library corresponds to a compiled macro
1253 if (!gSystem->AccessPathName(Form("%s_C.so", libName.Data()))) {
1254 libName.Append("_C");
1256 else if (!gSystem->AccessPathName(Form("../%s_C.so", libName.Data()))) {
1257 libName = Form("../%s_C", what);
1260 libName = Form("lib%s", libName.Data());
1262 if (!libName.EndsWith(".so")) libName.Append(".so");
1266 switch (fExecMode) {
1267 case kLocal: // Just load and exit
1268 if (gSystem->Load(libName.Data()) < 0) {
1269 Error("LoadLibrary", "Failed to load library %s", libName.Data());
1275 ret = SetupPAR(what) ? 0 : -1;
1276 if (rec) fListOfPARs.Add(new TObjString(what));
1278 ret = gSystem->Load(libName.Data());
1279 if (rec) fListOfLibraries.Add(new TObjString(libName));
1283 Info("LoadLibrary", "Uploading %s", what);
1284 ret = gProof->UploadPackage(what, TProof::kRemoveOld);
1286 ret = gProof->UploadPackage(gSystem->ExpandPathName(Form("../%s.par",
1290 gProof->UploadPackage(gSystem
1291 ->ExpandPathName(Form("$ALICE_ROOT/%s.par",
1294 Error("LoadLibrary",
1295 "Could not find module %s.par in current directory nor "
1296 "in $ALICE_ROOT", module.Data());
1301 Info("LoadLibrary", "Enabling package %s", what);
1302 ret = gProof->EnablePackage(what);
1306 Error("LoadLibrary", "Couldn't load %s", what);
1313 //__________________________________________________________________
1316 * @name PAR generation from script
1319 * Service function to make a PAR out of a script.
1321 * The script should contain can contain a sub-class of AliAnalysisTask.
1322 * The script will be compiled on the slaves before loading the
1323 * AliAnalysisManager. Parts to (not) be compiled can be protected like
1327 * // This will _only_ be compiled in the servers
1330 * // This will not be compiled in the servers
1334 * @param mode Execution mode (Grid, PROOF, Local)
1335 * @param script Script to upload and compile in the PAR
1336 * @param deps Dependency pars
1338 * @return true on success.
1340 static Bool_t MakeScriptPAR(EMode mode, const char* script, const char* deps)
1342 // Get the base name
1343 Info("MakeScriptPAR", "Making par file for %s", script);
1344 TString base(gSystem->BaseName(script));
1345 Int_t idx = base.Last('.');
1346 if (idx != kNPOS) base.Remove(idx);
1347 Bool_t retval = true;
1348 // Info("MakeScriptPAR", "script=%s, base=%s", script, base.Data());
1350 if (mode == kLocal) {
1351 if (gROOT->LoadMacro(Form("%s.C++g", base.Data())) < 0)
1356 TString tmpdir(gSystem->TempDirectory());
1357 int ltempl = tmpdir.Length() + 1 + 5 + 6 + 1;
1358 char* templ = new char[ltempl];
1359 snprintf(templ, ltempl, "%s/trainXXXXXX", tmpdir.Data());
1360 if (!mkdtemp(templ)) {
1361 Error("MakeScriptPAR",
1362 "Failed to generate temporary directory from template %s",
1368 // Check name of script file
1369 TString scr(script);
1371 if (scr.EndsWith(".C")) ext = "C";
1372 else if (scr.EndsWith(".cxx")) ext = "cxx";
1373 else { ext = "C"; scr.Append(".C"); }
1375 // Check if we can access the file
1376 TString path = TString::Format(".:%s", TROOT::GetMacroPath());
1377 char* loc = gSystem->Which(path, scr);
1378 if (!loc) throw TString::Format("Script %s not found in %s",
1379 scr.Data(), path.Data());
1382 TString dir = TString::Format("%s/%s", templ, base.Data());
1383 // Set-up directories
1384 if (gSystem->MakeDirectory(dir) < 0)
1385 throw TString::Format("Could not make directory '%s'", base.Data());
1387 if (gSystem->MakeDirectory(Form("%s/PROOF-INF", dir.Data())))
1388 throw TString::Format("Could not make directory %s/PROOF-INF",
1391 // Copy the script to the setup directory
1392 TString dest = TString::Format("%s/%s.%s", dir.Data(),
1393 base.Data(), ext.Data());
1394 Int_t ret = gSystem->CopyFile(full, dest, true);
1396 case -1: throw TString::Format("Couldn't open %s for copy", scr.Data());
1397 case -2: throw TString::Format("File %s exists", dest.Data());
1398 case -3: throw TString::Format("Error while copying %s", scr.Data());
1401 // Make our build file
1402 // Info("MakeScriptPAR", "Making build script %s/PROOF-INF/BUILD.sh", dir.Data());
1403 std::ofstream b(Form("%s/PROOF-INF/BUILD.sh", dir.Data()));
1405 throw TString::Format("Failed to open b shell script");
1407 << "echo BUILD.sh@`hostname`: Building " << base << "\n"
1408 << "root.exe -l -b -q PROOF-INF/BUILD.C 2>&1 | tee " << base << ".log\n"
1409 << "echo BUILD.sh@`hostname`: done: $?\n"
1412 if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", dir.Data()), 0755) != 0)
1413 throw TString::Format("Failed to set exectuable flags on "
1414 "%s/PROOF-INF/BUILD.sh", dir.Data());
1416 // Info("MakeScriptPAR", "Making utility script %s/PROOF-INF/UTIL.C", dir.Data());
1417 std::ofstream u(Form("%s/PROOF-INF/UTIL.C", dir.Data()));
1419 throw TString::Format("Failed to open utility script");
1420 u << "void LoadROOTLibs() {\n"
1421 << " gSystem->Load(\"libVMC\");\n"
1422 << " gSystem->Load(\"libNet\");\n"
1423 << " gSystem->Load(\"libTree\");\n"
1424 << " gSystem->Load(\"libPhysics\");\n"
1425 << " gSystem->Load(\"libMinuit\");\n"
1427 << "void AddAliROOT() {\n"
1428 << " TString val(gSystem->Getenv(\"ALICE_ROOT\"));\n"
1429 << " if (val.IsNull())\n"
1430 << " Warning(\"Add\",\"ALICE_ROOT not defined\");\n"
1432 << " gSystem->AddIncludePath(Form(\"-I%s/include\",val.Data()));\n"
1434 << "void AddDep(const char* env) {\n"
1435 << " TString val(gSystem->Getenv(Form(\"%s_INCLUDE\",env)));\n"
1436 << " if (val.IsNull())\n"
1437 << " Warning(\"Add\",\"%s_INCLUDE not defined\", env);\n"
1439 << " gSystem->AddIncludePath(Form(\"-I../%s\",val.Data()));\n"
1442 << "void LoadDep(const char* name) {\n"
1443 << " gSystem->AddDynamicPath(Form(\"../%s\",name));\n"
1444 << " char* full = gSystem->DynamicPathName(name,true);\n"
1446 << " full = gSystem->DynamicPathName(Form(\"lib%s\",name),true);\n"
1448 << " full = gSystem->DynamicPathName(Form(\"lib%s.so\",name),true);\n"
1449 << " if (!full) {\n"
1450 << " Warning(\"LoadDep\",\"Module %s not found\", name);\n"
1453 << " gSystem->Load(full);\n"
1458 // Info("MakeScriptPAR", "Making utility script %s/PROOF-INF/BUILD.C", dir.Data());
1459 std::ofstream cbuild(Form("%s/PROOF-INF/BUILD.C", dir.Data()));
1461 throw TString::Format("Failed to open build script");
1462 cbuild << "void BUILD() {\n"
1463 << " gSystem->AddIncludePath(\"-DBUILD_PAR=1\");\n"
1464 << " gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
1465 << " LoadROOTLibs();\n"
1466 << " AddAliROOT();\n";
1467 TObjArray* depList = TString(deps).Tokenize(",");
1468 TIter next(depList);
1470 while ((dep = next())) {
1471 cbuild << " AddDep(\"" << dep->GetName() << "\");\t"
1472 << " LoadDep(\"" << dep->GetName() << "\");\n";
1474 cbuild << " // gDebug = 5;\n"
1475 << " int ret = gROOT->LoadMacro(\""
1476 << base << "." << ext << "++g\");\n"
1477 << " if (ret != 0) Fatal(\"BUILD\",\"Failed to build\");\n"
1478 << " // else Info(\"BUILD\", \"Made " << base << "\");\n"
1483 // Make our set-up script
1484 // Info("MakeScriptPAR", "Making setup script %s/PROOF-INF/SETUP.C", dir.Data());
1485 std::ofstream setup(Form("%s/PROOF-INF/SETUP.C", dir.Data()));
1487 throw TString::Format("Failed to open setup script");
1488 setup << "void SETUP() {\n"
1489 << " gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
1490 << " LoadROOTLibs();\n"
1491 << " // Info(\"SETUP\",\"Loading libraries\");\n";
1494 while ((dep = next()))
1495 setup << " LoadDep(\"" << dep->GetName() << "\");\n";
1496 setup << " // gDebug = 5;\n"
1497 << " // Info(\"SETUP\",\"Loading " << base << "_" << ext << ".so\");\n"
1498 << " gSystem->Load(\"" << base << "_" << ext << ".so\");\n"
1499 << " // gDebug = 0;\n"
1500 << " gROOT->ProcessLine(\".include " << base << "\");\n"
1501 << " gSystem->Setenv(\"" << base << "_INCLUDE\",\""
1503 << " // Info(\"SETUP\", \"Done\");\n"
1508 // Info("MakeScriptPAR", "Packing up tar-archive");
1509 ret = gSystem->Exec(Form("(cd %s && tar -czf %s.par %s)",
1510 templ, base.Data(),base.Data()));
1512 throw TString::Format("Failed to create PAR file %s.PAR from %s",
1513 base.Data(), dir.Data());
1515 // Info("MakeScriptPAR", "Moving PAR archive");
1516 ret = gSystem->Exec(Form("mv -f %s/%s.par %s.par", templ, base.Data(),
1519 throw TString::Format("Failed to rename %s/%s.par to %s.par: %s",
1520 templ, base.Data(), base.Data(),
1521 gSystem->GetError());
1523 catch (TString& e) {
1524 Error("MakeScriptPAR", "%s", e.Data());
1527 // Info("MakeScriptPAR", "Removing temperary directory %s", templ);
1528 gSystem->Exec(Form("rm -rf %s", templ));
1533 //__________________________________________________________________
1536 * @name Execution implementation
1539 * Start the analysis
1541 * @param mgr Analysis manager
1542 * @param chain Input data (local and proof only)
1543 * @param nEvents Number of events to analyse
1545 Long64_t StartAnalysis(AliAnalysisManager* mgr,
1549 // --- Run the analysis ------------------------------------------
1550 TString mode = ModeString(fExecMode);
1551 switch (fExecMode) {
1554 Error("StartAnalysis", "No chain defined");
1557 if (nEvents < 0) nEvents = chain->GetEntries();
1558 return mgr->StartAnalysis(mode, chain, nEvents);
1560 if (fDataSet.IsNull()) {
1562 Error("StartAnalysis", "No chain defined");
1565 if (nEvents < 0) nEvents = chain->GetEntries();
1566 return mgr->StartAnalysis(mode, chain, nEvents);
1568 return mgr->StartAnalysis(mode, fDataSet);
1571 return mgr->StartAnalysis(mode);
1572 return mgr->StartAnalysis(mode, nEvents);
1574 // We should never get here
1577 //------------------------------------------------------------------
1579 * Connect to external services (Proof and/or grid)
1581 * @return true on success
1583 virtual Bool_t Connect()
1585 if (fExecMode == kLocal) return true;
1587 // --- Set-up connections to Proof cluster and alien -------------
1588 if (fExecMode == kProof) {
1589 Info("Connect", "Opening connection to proof server");
1590 // --- Find user name ------------------------------------------
1591 TString userName(gSystem->Getenv("alien_API_USER"));
1592 if (userName.IsNull()) {
1593 userName = gSystem->GetUserInfo()->fUser;
1595 "environment variable 'alien_API_USER' not set, using %s",
1599 // --- Set prefered GSI method ---------------------------------
1600 gEnv->SetValue("XSec.GSI.DelegProxy", "2");
1602 // --- Figure out some server settings -------------------------
1604 Bool_t lite = false;
1605 if (fProofServer.BeginsWith("workers=") || fProofServer.IsNull()) {
1607 serv = fProofServer;
1610 serv = Form("%s@%s", userName.Data(), fProofServer.Data());
1612 // --- Possibly debug slave sessions with GDB ------------------
1614 TString gdbCmd("/usr/bin/gdb --batch -ex run -ex bt --args");
1615 // TString gdbCmd("\"gdb --batch -ex run -ex bt --args\"");
1616 Info("Connect", "Using GDB to wrap slaves: %s", gdbCmd.Data());
1617 TProof::AddEnvVar("PROOF_WRAPPERCMD", gdbCmd);
1620 // --- Add ALICE_ROOT directory to search path for packages ----
1621 Info("Connect", "Set location of packages");
1622 gEnv->SetValue("Proof.GlobalPackageDirs",
1624 gEnv->GetValue("Proof.GlobalPackageDirs", "."),
1625 gSystem->Getenv("ALICE_ROOT")));
1627 // --- Set OADB path on workers --------------------------------
1628 const char* oadbPath = AliAnalysisManager::GetOADBPath();
1629 TProof::AddEnvVar("OADB_PATH", oadbPath);
1630 // if (lite) gSystem->Setenv("OADB_PATH", oadbPath);
1631 // Info("Connect", "OADB_PATH=%s", gSystem->Getenv("OADB_PATH"));
1633 // --- Now open connection to PROOF cluster --------------------
1636 Error("Connect", "Failed to connect to Proof cluster %s as %s",
1637 fProofServer.Data(), userName.Data());
1640 Info("Connect", "Now connected to Proof");
1641 // gProof->SetParameter("PROOF_LookupOpt", "all");
1642 if (lite) return true;
1645 // --- Open a connection to the grid -----------------------------
1647 TGrid::Connect("alien://");
1648 if (!gGrid || !gGrid->IsConnected()) {
1649 // This is only fatal in grid mode
1650 Error("Connect", "Failed to connect to AliEN");
1651 if (fExecMode == kGrid) return false;
1654 if (fExecMode == kGrid) return true;
1656 // --- Set and make output directory -----------------------------
1657 TString name = EscapedName();
1658 TString homeDir(gGrid->GetHomeDirectory());
1659 TString workDir(homeDir);
1660 workDir.Append("/");
1661 workDir.Append(name);
1663 // Make working directory
1664 if (!gGrid->Cd(workDir)) {
1666 if (gGrid->Mkdir(workDir)) {
1668 Info("Connect", "Directory %s created", workDir.Data());
1671 // Make output directory
1672 gGrid->Mkdir("proof_output");
1673 gGrid->Cd("proof_output");
1677 //------------------------------------------------------------------
1679 * Get the output directory (local or Grid)
1681 * @param mode Mode of execution
1683 * @return Path to output directory
1685 TString GetOutputDirectory(EMode mode) const
1687 TString ret(fEscapedName);
1688 if (mode != kGrid) return ret;
1690 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
1692 Warning("GetOutputDirectory", "No analysis manager defined yet");
1695 AliAnalysisGrid* ag = am->GetGridHandler();
1697 Warning("GetOutputDirectory", "No grid handler defined yet");
1700 AliAnalysisAlien* aa = dynamic_cast<AliAnalysisAlien*>(ag);
1702 Warning("GetOutputDirectory", "Grid handler isn't for AliEn");
1705 ret = aa->GetGridOutputDir();
1706 if (!ret.BeginsWith("/")) {
1708 ret = Form("%s/%s/%s", gGrid->GetHomeDirectory(),
1709 fEscapedName.Data(), aa->GetGridOutputDir());
1711 ret = Form("%s/%s", fEscapedName.Data(), aa->GetGridOutputDir());
1717 //__________________________________________________________________
1723 * Make our working directory if so requested
1725 * @return true on success
1727 Bool_t SetupWorkingDirectory()
1729 TString nam = EscapedName();
1730 //Info("Init","Current dir=%s, escaped name=%s",cwd.Data(),nam.Data());
1731 Bool_t exists = gSystem->AccessPathName(nam.Data()) == 0;
1732 if (fExecOper == kTerminate && !exists) {
1733 Error("SetupWorkingDirectory", "File/directory %s does not exists",
1739 if (!fAllowOverwrite && exists) {
1740 Error("SetupWorkingDirectory", "File/directory %s already exists",
1746 if (gSystem->MakeDirectory(nam.Data())) {
1747 Error("SetupWorkingDirectory", "Failed to make directory '%s'",
1753 if (!gSystem->ChangeDirectory(nam.Data())) {
1754 Error("SetupWorkingDirectory", "Failed to change directory to %s",
1758 Info("SetupWorkingDirectory", "Made subdirectory %s, and cd'ed there",
1762 //------------------------------------------------------------------
1766 * @param what PAR file
1768 * @return true on success
1770 Bool_t SetupPAR(const char* what)
1772 if (!what || what[0] == '\0') return -1;
1774 TString parFile(Form("%s.par", what));
1775 if (gSystem->AccessPathName(parFile.Data())) {
1776 if (gSystem->AccessPathName(Form("../%s.par", what))) {
1778 TString aliParFile =
1779 gSystem->ExpandPathName(Form("$(ALICE_ROOT)/%s.par", what));
1780 if (gSystem->AccessPathName(aliParFile.Data())) {
1781 Error("SetupPAR", "PAR file %s not found in current directory or "
1782 "$(ALICE_ROOT)", what);
1785 // Copy to current directory
1786 TFile::Cp(aliParFile, parFile);
1789 gSystem->Exec(Form("ln -s ../%s.par .", what));
1793 gSystem->Exec(Form("tar xzf %s", parFile.Data()));
1795 // Change directory into par archive
1796 TString cwd = gSystem->WorkingDirectory();
1798 if (!gSystem->ChangeDirectory(what)) {
1799 Error("SetupPAR", "Failed to change directory to %s", what);
1804 if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
1805 Info("SetupPar", "Building in PAR archive %s", what);
1806 if (gSystem->Exec("PROOF-INF/BUILD.sh")) {
1807 Error("SetupPar", "Failed to build in PAR directory %s", what);
1808 gSystem->ChangeDirectory(cwd.Data());
1813 // Check for setup script
1814 if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
1815 // Info("SetupPAR", "Setting up for PAR %s", what);
1816 gROOT->Macro("PROOF-INF/SETUP.C");
1818 if (!gSystem->ChangeDirectory(cwd.Data())) return false;
1822 //------------------------------------------------------------------
1824 * Set-up extra sources.
1826 * @return true on success
1828 TString SetupExtras()
1831 TIter next(&fListOfExtras);
1832 TObjString* obj = 0;
1833 while ((obj = static_cast<TObjString*>(next()))) {
1834 TString path = gSystem->ExpandPathName(obj->GetName());
1835 if (!path.BeginsWith("/"))
1836 // If not an absolute path, prepend to up-one
1837 path = Form("../%s", path.Data());
1838 if (gSystem->AccessPathName(path.Data())) {
1839 // File not accessible
1840 Warning("SetupExtras", "File %s not accessible", path.Data());
1843 ret.Append(Form("%s ", gSystem->BaseName(obj->GetName())));
1844 gSystem->Exec(Form("ln -s %s .", path.Data()));
1849 //------------------------------------------------------------------
1851 * Set-up sources for upload
1854 * @return String of sources
1856 TString SetupSources()
1858 TString nam = EscapedName();
1860 TIter next(&fListOfSources);
1862 while ((src = next())) {
1863 TString path = gSystem->ExpandPathName(src->GetName());
1864 if (!path.BeginsWith("/"))
1865 // If not an absolute path, prepend to up-one
1866 path = Form("../%s", path.Data());
1867 if (gSystem->AccessPathName(path.Data())) {
1868 // File not accessible
1869 Warning("SetupSources", "File %s not accessible", path.Data());
1872 ret.Append(Form("%s ", gSystem->BaseName(src->GetName())));
1873 gSystem->Exec(Form("ln -s %s .", path.Data()));
1878 //------------------------------------------------------------------
1880 * Set-up extra libraries to upload
1882 * @return String of libraries
1884 TString SetupLibraries()
1887 TIter next(&fListOfLibraries);
1889 while ((lib = next())) {
1890 ret.Append(lib->GetName());
1893 // Also add extra files to this variable
1894 ret.Append(SetupExtras());
1900 //__________________________________________________________________
1903 * @name Chain building
1906 * Check if we can add a file to the chain
1908 * @param path Full path to file
1909 * @param chain Chain
1911 * @return true on success, false otherwise
1913 Bool_t CheckFile(const TString& path, TChain* chain)
1915 TFile* test = TFile::Open(path, "READ");
1917 Warning("CheckFile", "Failed to open %s", path.Data());
1921 Bool_t ok = false; // Assume failure
1922 TObject* o = test->Get(chain->GetName());
1924 Warning("CheckFile", "The file %s does not contain the object %s",
1925 path.Data(), chain->GetName());
1926 else if (!dynamic_cast<TTree*>(o))
1927 Warning("CheckFile", "Object %s found in %s is not a TTree",
1928 o->GetName(), path.Data());
1932 if (ok) chain->AddFile(path);
1937 * Scan directory @a dir (possibly recursive) for tree files to add
1938 * to the chain. This does not follow sym-links
1940 * @param dir Directory to scan
1941 * @param chain Chain to add to
1942 * @param recursive Whether to scan recursively
1944 * @return true if any files where added
1946 Bool_t ScanDirectory(TSystemDirectory* dir, TChain* chain,
1950 switch (fExecType) {
1951 case kESD: fnPattern = "AliESD"; break;
1952 case kAOD: fnPattern = "AliAOD"; break;
1953 case kUser: fnPattern = ""; break;
1959 // Get list of files, and go back to old working directory
1960 TString oldDir(gSystem->WorkingDirectory());
1961 TList* files = dir->GetListOfFiles();
1962 if (!gSystem->ChangeDirectory(oldDir)) {
1963 Error("ScanDirectory", "Failed to go back to %s", oldDir.Data());
1966 if (!files) return false;
1970 Bool_t hasGAlice = (!(fMC || fExecType == kAOD) ? true : false);
1971 Bool_t hasKine = (!(fMC || fExecType == kAOD) ? true : false);
1972 Bool_t hasTrRef = (!(fMC || fExecType == kAOD) ? true : false);
1974 // Sort list of files and check if we should add it
1977 TSystemFile* file = 0;
1978 while ((file = static_cast<TSystemFile*>(next()))) {
1979 TString name(file->GetName());
1980 TString title(file->GetTitle());
1981 TString full(gSystem->ConcatFileName(file->GetTitle(), name.Data()));
1982 if (dynamic_cast<TSystemDirectory*>(file)) full = title;
1983 // Ignore special links
1984 if (name == "." || name == "..") {
1985 // Info("ScanDirectory", "Ignoring %s", name.Data());
1990 if (gSystem->GetPathInfo(full.Data(), fs)) {
1991 Warning("ScanDirectory", "Cannot stat %s (%s)", full.Data(),
1992 gSystem->WorkingDirectory());
1995 // Check if this is a directory
1996 if (file->IsDirectory(full)) {
1998 // if (title[0] == '/')
1999 TSystemDirectory* d = new TSystemDirectory(file->GetName(),
2001 if (ScanDirectory(d,chain,recursive))
2008 // If this is not a root file, ignore
2009 if (!name.EndsWith(".root")) continue;
2011 // If this file does not contain AliESDs, ignore
2012 if (!name.Contains(fnPattern)) {
2013 // Info("ScanDirectory", "%s does not match pattern %s",
2014 // name.Data(), fnPattern.Data());
2015 if (fMC && fExecType == kESD) {
2016 if (name.CompareTo("galice.root") == 0) hasGAlice = true;
2017 if (name.CompareTo("Kinematics.root") == 0) hasKine = true;
2018 if (name.CompareTo("TrackRefs.root") == 0) hasTrRef = true;
2024 // Info("ScanDirectory", "Adding %s", full.Data());
2025 toAdd.Add(new TObjString(full));
2028 if (fMC && fExecType == kESD && toAdd.GetEntries() > 0 &&
2029 (!hasGAlice || !hasKine || !hasTrRef)) {
2030 Warning("ScanDirectory",
2031 "one or more of {galice,Kinematics,TrackRefs}.root missing from "
2032 "%s, not adding anything from this directory",
2037 TIter nextAdd(&toAdd);
2040 while ((s = static_cast<TObjString*>(nextAdd()))) {
2041 // Info("ScanDirectory", "Adding %s", s->GetString().Data());
2042 TString fn = s->GetString();
2043 if (!CheckFile(fn, chain)) continue;
2047 if (added > 0) ret = true;
2049 gSystem->ChangeDirectory(oldDir);
2052 //------------------------------------------------------------------
2054 * Create a chain from an XML containing an collection
2056 * @param treeName Name of tree's
2057 * @param xmlFile XML collection
2059 * @return Newly allocated chain or null
2061 TChain* CreateChainFromXML(const char* treeName,
2062 const char* xmlFile)
2064 Long_t ret = gROOT->ProcessLine(Form("TAlienCollection(\"%s\")",
2067 Error("CreateChainFromXML", "Cannot create AliEn collection from "
2068 "XML file %s", xmlFile);
2072 TGridCollection* collection = reinterpret_cast<TGridCollection*>(ret);
2074 Error("CreateChainFromXML", "Cannot create AliEn collection from "
2075 "XML file %s", xmlFile);
2079 TChain* chain = new TChain(treeName);
2080 collection->Reset();
2081 while (collection->Next()) chain->Add(collection->GetTURL(""));
2085 //------------------------------------------------------------------
2087 * Create a chain of data
2089 * @return TChain of data
2091 TChain* CreateChain()
2094 switch (fExecType) {
2095 case kESD: treeName = "esdTree"; break;
2096 case kAOD: treeName = "aodTree"; break;
2097 case kUser: treeName = ""; break;
2101 switch (fExecMode) {
2103 if (!fDataSet.IsNull()) break;
2104 // Otherwise fall through
2106 if (fXML.IsNull()) {
2107 chain = new TChain(treeName.Data());
2108 TString dir(fDataDir);
2109 if (dir == ".") dir = "";
2110 if (!dir.BeginsWith("/")) dir = Form("../%s", dir.Data());
2112 gSystem->GetPathInfo(dir, stat);
2113 if (!R_ISDIR(stat.fMode)) { // A file, check it
2114 if (!CheckFile(dir, chain)) {
2120 TString savdir(gSystem->WorkingDirectory());
2121 TSystemDirectory d(gSystem->BaseName(dir.Data()), dir.Data());
2122 if (!ScanDirectory(&d, chain, true)) {
2126 gSystem->ChangeDirectory(savdir);
2129 chain = CreateChainFromXML(treeName.Data(), fXML.Data());
2131 case kGrid: break; // Do nothing - we use plugin
2134 if (chain && chain->GetNtrees() <= 0) {
2143 //====================================================================
2153 * @param name Option name
2154 * @param desc Option description
2155 * @param arg Option argument, if any
2157 Option(const char* name, const char* desc, const char* arg="")
2165 * Process an option string.
2167 * @param opt String to process
2169 * @return true, if this handled the option, false otherwise
2171 Bool_t Process(const TString& opt)
2173 // Info("Option::Process", "Option %s processing %s",
2174 // fName.Data(), opt.Data());
2175 if (!opt.BeginsWith(fName, TString::kIgnoreCase)) return false;
2177 // We've got a value
2180 // No argument options shouldn't set a value
2181 if (fArg.IsNull()) return true;
2184 Int_t eq = opt.Index("=");
2186 // Empty string is an OK value
2187 if (eq == kNPOS) return true;
2189 TString tmp = opt(eq+1,opt.Length()-eq-1);
2190 fValue = tmp.Strip();
2195 * Get option value as a string
2197 * @return Option value
2199 const TString& AsString() const { return fValue; }
2201 * Get option value as a double
2203 * @return Option value
2205 Double_t AsDouble() const { return fValue.Atof(); }
2207 * Get option value as an integer
2209 * @return Option value
2211 Int_t AsInt() const { return fValue.Atoi(); }
2213 * Get option value as a boolean
2215 * @return Option value
2217 Bool_t AsBool() const { return fIsSet; }
2219 * Test if the option has been set.
2221 * @return True if the option was given
2223 Bool_t IsSet() const { return fIsSet; }
2227 * @param o Stream to write on
2228 * @param prefix Prefix
2230 void PrintHelp(std::ostream& o, const char* prefix) const
2233 if (!fArg.IsNull()) arg.Append(Form("=%s", fArg.Data()));
2234 o << " " << (prefix ? prefix : "")
2235 << std::left << std::setw(30) << arg
2236 << " " << fDesc << std::endl;
2241 * @param o Stream to write on
2243 void PrintSettings(std::ostream& o) const
2245 o << " " << std::left << std::setw(30) << fName << ": ";
2246 if (fArg.IsNull()) o << (IsSet() ? "true" : "false");
2253 * @param str object nmae
2255 * @param o Stream to write on
2257 void Save(std::ostream& o, const char* str, bool val)
2260 if (str[0] == '-') {
2261 o << " " << str << fName << " \\" << std::endl;
2264 o << " " << str << ".Append(\"" << fName << ",\");" << std::endl;
2269 * @param str object nmae
2271 * @param o Stream to write on
2273 void Save(std::ostream& o, const char* str, Int_t val)
2275 if (str[0] == '-') {
2276 o << " " << str << fName << "=" << val << " \\" << std::endl;
2279 o << " " << str << ".Append(\"" << fName << "=" << val
2280 << ",\");" << std::endl;
2285 * @param str object nmae
2287 * @param o Stream to write on
2289 void Save(std::ostream& o, const char* str, Double_t val)
2291 if (str[0] == '-') {
2292 o << " " << str << fName << "=" << val << " \\" << std::endl;
2295 o << " " << str << ".Append(\"" << fName << "=" << val
2296 << ",\");" << std::endl;
2301 * @param str object nmae
2303 * @param o Stream to write on
2305 void Save(std::ostream& o, const char* str, const char* val)
2307 if (str[0] == '-') {
2309 sval.ReplaceAll(" ", "\\ ");
2310 o << " " << str << fName << "=" << sval << " \\" << std::endl;
2313 o << " " << str << ".Append(\"" << fName << "=" << val
2314 << ",\");" << std::endl;
2317 TString fName; // Name of the option
2318 TString fDesc; // Decription
2319 TString fArg; // Argument, if any
2320 Bool_t fIsSet; // Whether the option has been set.
2321 TString fValue; // Value of the option.
2323 //====================================================================
2333 * @param train Train to run
2334 * @param max Maximum number of options
2336 Runner(TrainSetup& train, UShort_t max=30)
2337 : fTrain(&train), fOptions(0), fN(0), fMax(max)
2339 fOptions = new Option*[fMax];
2340 for (Int_t i = 0; i < fMax; i++) fOptions[i] = 0;
2345 * @param opt Option to add
2347 void Add(Option* opt)
2350 Warning("AddOption", "No room for option %s", opt->fName.Data());
2353 fOptions[fN++] = opt;
2360 void Remove(const TString& name)
2362 Option** ptr = fOptions;
2365 if (name.EqualTo((*ptr)->fName)) {
2371 if (!tmp) // nothing found, returning
2387 * Parse option string
2389 * @param options Option string.
2390 * @param delim Delimiters
2392 * @return true on success.
2394 Bool_t Parse(const TString& options, const char* delim=",;")
2396 TObjArray* a = options.Tokenize(delim);
2404 * @return true on success
2406 Bool_t Parse(TObjArray& options)
2408 TIter next(&options);
2410 while ((os = static_cast<TObjString*>(next()))) {
2411 TString s(os->String());
2412 // Info("Runner::Parse", "Processing option %s", s.Data());
2413 if (s.IsNull()) continue;
2416 Option** ptr = fOptions;
2417 while (*ptr && !ok) {
2419 if (o->Process(s)) ok = true;
2424 Warning("Parse", "Unknown option %s", s.Data());
2429 * Check if we asked for help
2434 Bool_t IsHelpAsked() const
2436 Option* help = FindOption("help");
2437 return (help && help->IsSet());
2442 * @param out Stream to write on
2443 * @param prefix Prefix
2445 void PrintHelp(std::ostream& out, const char* prefix="") const
2447 Option** ptr = fOptions;
2449 (*ptr)->PrintHelp(out, prefix);
2454 * Print the settings
2456 * @param out Stream to write on.
2458 void PrintSettings(std::ostream& out) const
2460 Option** ptr = fOptions;
2462 (*ptr)->PrintSettings(out);
2467 * Find an option by name
2469 * @param name Name of option to find
2471 * @return Pointer to option, or null
2473 Option* FindOption(const TString& name) const
2475 Option** ptr = fOptions;
2477 if (name.EqualTo((*ptr)->fName)) return *ptr;
2483 * Initialize the train
2485 * @param options Execution options
2487 * @return true on success
2489 Bool_t Init(const TString& options)
2491 fTrain->MakeOptions(*this);
2492 if (!Parse(options)) return false;
2498 * @param runs Run numbers
2499 * @param nEvents Number of events
2500 * @param asShell Save set-up as shell script
2504 Bool_t Run(const TString& runs, Int_t nEvents, Bool_t asShell=false)
2506 PrintSettings(std::cout);
2508 fTrain->SetOptions(*this);
2509 fTrain->SetRuns(runs);
2510 // fTrain->SaveSetup(*this, nEvents, asShell);
2512 fTrain->Run(nEvents, this, asShell);
2517 Option** fOptions; // Our options
2518 UShort_t fN; // Current number of options
2519 UShort_t fMax; // Maximum number of options
2522 //__________________________________________________________________
2528 * Class name of this train setup. Sub-classes must define this.
2530 * @return Class name of this setup
2532 virtual const char* ClassName() const = 0;
2533 //------------------------------------------------------------------
2535 * Make the options for this train. Sub-classes can overload this
2536 * to define new options, or append to the set of default option.
2538 virtual void MakeOptions(Runner& r)
2540 r.Add(new Option("help", "Show this help"));
2541 r.Add(new Option("par", "Use PAR files (PROOF and Grid)"));
2542 r.Add(new Option("mc", "Assume simulation input"));
2543 r.Add(new Option("debug", "Execute in debugger"));
2544 r.Add(new Option("type", "Type of train", "AOD|ESD"));
2545 r.Add(new Option("mode", "Execution mode", "LOCAL|PROOF|GRID"));
2546 r.Add(new Option("oper", "Operation mode", "TEST|TERMINATE|FULL|INIT"));
2547 r.Add(new Option("date", "Set date string", "YYYY-MM-DD HH:MM:SS"));
2548 r.Add(new Option("cluster","PROOF cluster", "HOST"));
2549 r.Add(new Option("dataSet","Data set (PROOF only)", "NAME"));
2550 r.Add(new Option("dataDir","Data directory", "DIRECTORY"));
2551 r.Add(new Option("pattern","Data pattern (grid only)", "GLOB"));
2552 r.Add(new Option("verb", "Verbosity", "NUMBER"));
2553 r.Add(new Option("root", "ROOT version (Grid)", "TAG"));
2554 r.Add(new Option("aliroot","AliROOT version (Grid)","TAG"));
2555 r.Add(new Option("alien", "AliEn API version (Grid)","TAG"));
2556 r.Add(new Option("overwrite", "Allow overwrite"));
2557 r.Add(new Option("per-run", "Per run merge"));
2559 //------------------------------------------------------------------
2561 * Set the option values on the train. Sub-classes can overload
2562 * this to set custom options on the train.
2564 virtual void SetOptions(Runner& r)
2566 Option* debug = r.FindOption("debug");
2567 Option* date = r.FindOption("date");
2568 Option* cluster = r.FindOption("cluster");
2569 Option* dataSet = r.FindOption("dataSet");
2570 Option* dataDir = r.FindOption("dataDir");
2571 Option* pattern = r.FindOption("pattern");
2572 Option* par = r.FindOption("par");
2573 Option* type = r.FindOption("type");
2574 Option* mode = r.FindOption("mode");
2575 Option* oper = r.FindOption("oper");
2576 Option* mc = r.FindOption("mc");
2577 Option* verb = r.FindOption("verb");
2578 Option* root = r.FindOption("root");
2579 Option* aliroot = r.FindOption("aliroot");
2580 Option* alien = r.FindOption("alien");
2581 Option* overwrite = r.FindOption("overwrite");
2582 Option* run_merge = r.FindOption("per-run");
2584 if (date && date->IsSet()) SetDateTime(date->AsString());
2585 if (cluster) SetProofServer(cluster->AsString());
2586 if (dataSet) SetDataSet(dataSet->AsString());
2587 if (dataDir) SetDataDir(dataDir->AsString());
2588 if (pattern) SetDataPattern(pattern->AsString());
2589 if (debug) SetUseGDB(debug->AsBool());
2590 if (type && type->IsSet()) SetType(type->AsString());
2591 if (mode && mode->IsSet()) SetMode(mode->AsString());
2592 if (oper && oper->IsSet()) SetOperation(oper->AsString());
2593 if (par) SetUsePar(par->AsBool());
2594 if (mc) SetMC(mc->AsBool());
2595 if (verb) SetVerbose(verb->AsInt());
2596 if (root) SetROOTVersion(root->AsString());
2597 if (aliroot) SetAliROOTVersion(aliroot->AsString());
2598 if (alien) SetAliEnAPIVersion(alien->AsString());
2599 if (overwrite) SetAllowOverwrite(overwrite->AsBool());
2600 if (run_merge) SetPerRunMerge(run_merge->AsBool());
2602 //------------------------------------------------------------------
2604 * Set the option values on the train. Sub-classes can overload
2605 * this to set custom options on the train.
2607 virtual void SaveOptions(std::ostream& o, const char* str, Runner& r)
2609 Option* debug = r.FindOption("debug");
2610 Option* date = r.FindOption("date");
2611 Option* cluster = r.FindOption("cluster");
2612 Option* dataSet = r.FindOption("dataSet");
2613 Option* dataDir = r.FindOption("dataDir");
2614 Option* pattern = r.FindOption("pattern");
2615 Option* par = r.FindOption("par");
2616 Option* type = r.FindOption("type");
2617 Option* mode = r.FindOption("mode");
2618 Option* oper = r.FindOption("oper");
2619 Option* mc = r.FindOption("mc");
2620 Option* verb = r.FindOption("verb");
2621 Option* root = r.FindOption("root");
2622 Option* aliroot = r.FindOption("aliroot");
2623 Option* alien = r.FindOption("alien");
2624 Option* overwrite = r.FindOption("overwrite");
2625 Option* run_merge = r.FindOption("per-run");
2627 if (date) date->Save(o, str,
2628 Form("%04d-%02d-%02d %02d:%02d:00",
2633 fDatime.GetMinute()));
2634 if (cluster) cluster->Save(o, str, fProofServer);
2635 if (dataSet) dataSet->Save(o, str, fDataSet);
2636 if (dataDir) dataDir->Save(o, str, fDataDir);
2637 if (pattern) pattern->Save(o, str, fDataPattern);
2638 if (debug) debug->Save(o, str, fUseGDB);
2639 if (type) type->Save(o, str, TypeString(fExecType));
2640 if (mode) mode->Save(o, str, ModeString(fExecMode));
2641 if (oper) oper->Save(o, str, OperString(fExecOper));
2642 if (par) par->Save(o, str, fUsePar);
2643 if (mc) mc->Save(o, str, fMC);
2644 if (verb) verb->Save(o, str, fVerbose);
2645 if (root) root->Save(o, str, fRootVersion);
2646 if (aliroot) aliroot->Save(o, str, fAliRootVersion);
2647 if (alien) alien->Save(o, str, fAliEnAPIVersion);
2648 if (overwrite)overwrite->Save(o, str, fAllowOverwrite);
2649 if (run_merge)run_merge->Save(o, str, fPerRunMerge);
2652 * Save the setup to file for later re-execution
2654 * @param r Runner object
2655 * @param nEvents Number of events
2656 * @param asShell If true, save as shell script - otherwise ROOT script
2658 virtual void SaveSetup(Runner& r, Int_t nEvents, Bool_t asShell=false)
2660 if (asShell) SaveSetupShell(r, nEvents);
2661 /* else */ SaveSetupROOT(r, nEvents);
2664 * Save the setup to shell script for later re-execution
2666 * @param r Runner object
2667 * @param nEvents Number of events
2669 virtual void SaveSetupShell(Runner& r, Int_t nEvents)
2671 std::ofstream o("rerun.sh");
2672 o << "#!/bin/bash\n\n"
2674 << "if test x$oper = x ; then oper=full ; fi \n\n"
2675 << "class=\"" << ClassName() << "\"\n"
2676 << "name=\"" << fName << "\"\n"
2677 << "nev=" << nEvents << "\n\n"
2678 << "opts=(--class=$class \\\n"
2679 << " --name=$name \\\n"
2680 << " --events=$nev \\" << std::endl;
2681 for (Int_t i = 0; i < fRunNumbers.GetSize(); i++)
2682 o << " --run=" << fRunNumbers.At(i) << " \\\n";
2683 SaveOptions(o, "--", r);
2684 o << " --oper=$oper)\n\n"
2685 << "echo \"Running runTrain ${opts[@]}\"\n"
2686 << "runTrain \"${opts[@]}\"\n\n"
2687 << "# EOF" << std::endl;
2689 gSystem->Exec("chmod a+x rerun.sh");
2692 * Save the setup to shell script for later re-execution
2694 * @param r Runner object
2695 * @param nEvents Number of events
2697 virtual void SaveSetupROOT(Runner& r, Int_t nEvents)
2699 std::ofstream o("rerun.C");
2700 o << "void rerun(bool terminate=false)\n"
2702 << " TString opts;" << std::endl;
2703 SaveOptions(o, "opts", r);
2705 o << " if (terminate) opts.Append(\"mode=terminate;\");\n\n"
2706 << " TString runs(\"";
2707 for (Int_t i = 0; i < fRunNumbers.GetSize(); i++)
2708 o << (i == 0 ? "" : ", ") << fRunNumbers.At(i);
2710 << " Int_t nEvents = " << nEvents << ";\n\n"
2711 << " gROOT->LoadMacro(\"$ALICE_ROOT/PWGLF/FORWARD/analysis2/trains/RunTrain.C\");\n"
2712 << " RunTrain(\"" << ClassName() << "\",\""
2713 << fName << "\",opts,runs,nEvents);\n"
2715 << "// EOF" << std::endl;
2720 //__________________________________________________________________
2721 TString fName; // Name of analysis
2722 TString fEscapedName; // Name escaped for special chars
2723 TString fRootVersion; // ROOT version to use
2724 TString fAliRootVersion; // AliROOT version to use
2725 TString fAliEnAPIVersion; // AliEn API version to use
2726 TString fProofServer; // Name of proof server
2727 TString fDataDir; // Grid Input directory
2728 TString fDataPattern; // Data directory pattern
2729 TString fDataSet; // Proof data set name
2730 TString fXML; // XML collection for local/proof mode
2731 Int_t fNReplica; // Storage replication
2732 Bool_t fAllowOverwrite; // Allow overwriting output dir
2733 Bool_t fUseGDB; // Wrap PROOF slaves in GDB
2734 Int_t fMaxSplit; // Maximum number of files per split
2735 TArrayI fRunNumbers; // List of run number
2736 TList fListOfPARs; // List of PAR files to use
2737 TList fListOfSources; // List of sources to upload and AcLIC
2738 TList fListOfLibraries; // List of libraries to load
2739 TList fListOfExtras; // List of extra files to upload
2740 TDatime fDatime; // Date and time
2741 EType fExecType; // Execution type (ESD, AOD)
2742 EMode fExecMode; // Execution mode (PROOF, local, Grid)
2743 EOper fExecOper; // Execution operation (full, terminate, ...)
2744 Bool_t fUsePar; // Wether to use PAR files
2745 Bool_t fMC; // Whether to assume MC input
2746 Bool_t fPerRunMerge; // Whether to merge per run or over-all
2747 Int_t fVerbose; // Verbosity level
2750 //____________________________________________________________________