2 * @defgroup pwg2_forward_trains Trains
4 * @ingroup pwg2_forward
8 * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
9 * @date Wed Mar 23 12:12:00 2011
13 * @ingroup pwg2_forward_trains
21 #include <TAlienCollection.h>
29 #include <TObjString.h>
33 #include <TSystemDirectory.h>
34 #include <TSystemFile.h>
37 #include <AliAODHandler.h>
38 #include <AliAODInputHandler.h>
39 #include <AliAnalysisDataContainer.h>
40 #include <AliAnalysisManager.h>
41 #include <AliAnalysisAlien.h>
42 #include <AliESDInputHandler.h>
43 #include <AliMCEventHandler.h>
44 #include <AliVEventHandler.h>
45 #include <AliPhysicsSelection.h>
46 #include <AliCentralitySelectionTask.h>
50 class AliAnalysisManager;
53 //====================================================================
55 * Generic set-up of an analysis train using the grid-handler (AliEn plugin).
57 * Users should define a class that derives from this. The class
58 * should implement the member function CreateTasks to add needed
63 * class MyTrain : public TrainSetup
66 * MyTrain(Bool_t dateTime = false,
72 * : TrainSetup("My train", dateTime, year, month, day, hour, min)
74 * void Run(const char* type, const char* mode, const char* oper,
75 * Int_t nEvents=-1, Bool_t mc=false,
76 * Bool_t usePar=false)
78 * Exec(type, mode, oper, nEvents, mc, usePar);
81 * void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)
83 * AliAnalysisManager::SetCommonFileName("my_analysis.root");
84 * LoadLibrary("MyAnalysis", mode, par, true);
85 * Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
86 * gROOT->Macro("MyAnalysis.C");
91 * This can then be run like
95 * Root> .L TrainSetup.C
105 * gROOT->LoadMacro("TrainSetup.C");
106 * gROOT->LoadMacro("MyTrain.C");
112 * To byte compile this, you need to
113 * - load the ROOT AliEn library
114 * - load the analysis libraries
115 * - add $ALICE_ROOT/include to header search
120 * Root> gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2:"
121 * Root> "$ALICE_ROOT/ANALYSIS/macros",
122 * Root> gROOT->GetMacroPath()));
123 * Root> gSystem->AddIncludePath("-I${ALICE_ROOT}/include");
124 * Root> gSystem->Load("libRAliEn");
125 * Root> gSystem->Load("libANALYSIS");
126 * Root> gSystem->Load("libANALYSISalice");
127 * Root> gROOT->LoadMacro("TrainSetup.C+");
131 * @ingroup pwg2_forward_trains
137 * Data type to process
140 /** Event Summary Data */
142 /** Analysis Object Data */
146 * How to run the analysis
152 /** In PROOF(-Lite) cluster */
158 * What stage of the analysis to run
162 /** Testing. Local processing, a single copied from Grid */
166 /** Submit to queue */
168 /** Merge and terminate */
174 //__________________________________________________________________
178 * @param name Name of analysis (free-form)
179 * @param useDateTime Whether to append date and time to the name
180 * @param year Year - if not specified, taken from current date
181 * @param month Month - if not specified, taken from current date
182 * @param day Day - if not specified, taken from current date
183 * @param hour Hour - if not specified, taken from current time
184 * @param min Minute - if not specified, taken from current time
186 TrainSetup(const char* name, Bool_t useDateTime=true,
187 UShort_t year=0, UShort_t month=0,
188 UShort_t day=0, UShort_t hour=0, UShort_t min=0)
190 fRootVersion("v5-28-00a"),
191 fAliRootVersion("v4-21-18-AN"),
192 fAliEnAPIVersion("V1.1x"),
193 fProofServer("alicecaf.cern.ch"),
194 fDataDir("/alice/data/2010/LHC10c"),
195 fDataSet("/COMMON/COMMON/LHC09a4_run8100X#/esdTree"),
206 fAllowOverwrite(kFALSE),
209 char c[] = { ' ', '/', '@', 0 };
212 fEscapedName.ReplaceAll(Form("%c", *p), "_");
217 if (year == 0 || month == 0 || day == 0) {
219 year = now.GetYear();
220 month = now.GetMonth();
222 hour = now.GetHour();
223 min = now.GetMinute();
225 fEscapedName.Append(Form("_%04d%02d%02d_%02d%02d",
226 year, month, day, hour, min));
231 //__________________________________________________________________
233 * Parse a string into a type enum
235 * @param type String to pass
237 * @return Enumaration value
239 static EType ParseType(const char* type, Bool_t& /*mc*/)
245 // if (sType.Contains("MC")) mc = true;
246 if (sType.Contains("ESD")) eType = kESD;
247 else if (sType.Contains("AOD")) eType = kAOD;
249 Fatal("Run", "Unknown type '%s'", type);
253 //__________________________________________________________________
255 * Return a string that reflects the passed mode
259 * @return String representation of mode
261 static const char* ModeString(EMode eMode)
264 case kLocal: return "LOCAL";
265 case kProof: return "PROOF";
266 case kGrid: return "GRID";
270 //__________________________________________________________________
272 * Parse a string for mode specifier
274 * @param mode Mode string
276 * @return EMode value
278 static EMode ParseMode(const char* mode)
282 EMode eMode = kLocal;
283 if (sMode == "LOCAL") eMode = kLocal;
284 else if (sMode == "PROOF") eMode = kProof;
285 else if (sMode == "GRID") eMode = kGrid;
287 Fatal("Run", "Unknown mode '%s'", mode);
291 //__________________________________________________________________
293 * Return a string that reflects the passed operation
295 * @param eOper Operation
297 * @return String representation of operation
299 static const char* OperString(EOper eOper)
302 case kTest: return "TEST";
303 case kOffline: return "OFFLINE";
304 case kSubmit: return "SUBMIT";
305 case kTerminate: return "TERMINATE";
306 case kFull: return "FULL";
310 //__________________________________________________________________
312 * Parse an operation string
314 * @param oper Operation
316 * @return An EOper value
318 static EOper ParseOperation(const char* oper)
323 if (sOper == "TEST") eOper = kTest;
324 else if (sOper == "OFFLINE") eOper = kOffline;
325 else if (sOper == "SUBMIT") eOper = kSubmit;
326 else if (sOper == "TERMINATE") eOper = kTerminate;
327 else if (sOper == "FULL") eOper = kFull;
329 Fatal("Run", "unknown operation '%s'", oper);
333 //__________________________________________________________________
335 * Set ROOT version to use
337 * @param v Version string of ROOT
339 void SetROOTVersion(const char* v) { fRootVersion = v; }
340 //__________________________________________________________________
342 * Set AliROOT version to use
344 * @param v Version string of AliROOT
346 void SetAliROOTVersion(const char* v) { fAliRootVersion = v; }
347 //__________________________________________________________________
349 * Set the PROOF server URL
351 * @param s PROOF server URL
353 void SetProofServer(const char* s) { fProofServer = s; }
354 //__________________________________________________________________
356 * Set the GRID/Local data dir
358 * @param d Directory with data
360 void SetDataDir(const char* d) { fDataDir = d; }
361 //__________________________________________________________________
363 * Set the PROOF data set
365 * @param d PROOF registered data set
367 void SetDataSet(const char* d) { fDataSet = d; }
368 //__________________________________________________________________
370 * Set the XML file to use
374 void SetXML(const char* x) { fXML = x; }
375 //__________________________________________________________________
377 * Set how many replicas of the output we want
379 * @param n Number of replicas requested
381 void SetNReplica(Int_t n) { fNReplica = n; }
383 * Set the ESD pass to use
385 * @param pass Pass number
387 void SetESDPass(Int_t pass) { fESDPass = pass; }
389 * Set the ESD pass to use
391 * @param postfix Post fix to pass number
393 void SetPassPostfix(const char* postfix) { fPassPostfix = postfix; }
394 //__________________________________________________________________
396 * Use GDB to wrap PROOF slaves
398 * @param use Whether to use GDB or not
400 void SetUseGDB(Bool_t use=kTRUE) { fUseGDB = use; }
401 //__________________________________________________________________
403 * Add a source file to be copied and byte compiled on slaves
406 * @param addToExtra If false, do not copy
408 void AddSource(const char* src, bool addToExtra=true)
410 fListOfSources.Add(new TObjString(src));
411 if (addToExtra) AddExtraFile(src); // Source code isn't copied!
413 //__________________________________________________________________
415 * Add binary data to be uploaded to slaves
417 * @param lib Name of binary file
419 void AddLibrary(const char* lib) { fListOfLibraries.Add(new TObjString(lib));}
420 //__________________________________________________________________
422 * Add a run to be analysed
424 * @param run Run number
426 void AddRun(Int_t run)
428 Int_t i = fRunNumbers.fN; fRunNumbers.Set(i+1); fRunNumbers[i] = run;
430 //__________________________________________________________________
432 * Read run numbers from a file
434 * @param filename File name
436 void ReadRunNumbers(const char* filename)
438 std::ifstream file(filename);
440 Fatal("ReadRunNumbers", "Cannot read from %s", filename);
442 while (!file.eof()) {
448 if (file.bad()) break;
452 //__________________________________________________________________
454 * Add an extra file to be uploaded to slave
456 * @param file Extra file to be uploaded
458 void AddExtraFile(const char* file)
460 if (!file || file[0] == '\0') return;
461 fListOfExtras.Add(new TObjString(file));
463 //__________________________________________________________________
465 * Set whether to allow overwritting existing files/directories
467 * @param allow If true, allow overwritting files/directories
469 void SetAllowOverwrite(Bool_t allow) { fAllowOverwrite = allow; }
470 //__________________________________________________________________
477 bool mc = AliAnalysisManager::GetAnalysisManager()
478 ->GetMCtruthEventHandler();
479 std::cout << fName << " train setup\n"
481 << " ROOT version: " << fRootVersion << "\n"
482 << " AliROOT version: " << fAliRootVersion << "\n"
483 << " Name of proof server: " << fProofServer << "\n"
484 << " Grid Input directory: " << fDataDir << "\n"
485 << " Proof data set name: " << fDataSet << "\n"
486 << " XML collection: " << fXML << "\n"
487 << " Monte-Carlo input: " << mc << "\n"
488 << " Storage replication: " << fNReplica << "\n"
489 << " Run numbers: " << std::flush;
490 for (Int_t i = 0; i < fRunNumbers.GetSize(); i++)
491 std::cout << (i == 0 ? "" : ", ") << fRunNumbers.At(i);
494 << " PAR files: " << std::flush;
497 TIter nextPar(&fListOfPARs);
498 while ((obj = nextPar())) {
499 std::cout << (first ? "" : ", ") << obj->GetName();
504 << " Script sources: " << std::flush;
506 TIter nextSrc(&fListOfSources);
507 while ((obj = nextSrc())) {
508 std::cout << (first ? "" : ", ") << obj->GetName();
513 << " Libraries to load: " << std::flush;
515 TIter nextLib(&fListOfLibraries);
516 while ((obj = nextLib())) {
517 std::cout << (first ? "" : ", ") << obj->GetName();
520 std::cout << std::noboolalpha << std::endl;
522 AliAnalysisGrid* plugin =
523 AliAnalysisManager::GetAnalysisManager()->GetGridHandler();
529 //__________________________________________________________________
533 * @param o Object to copy from
535 TrainSetup(const TrainSetup& o)
537 fRootVersion(o.fRootVersion),
538 fAliRootVersion(o.fAliRootVersion),
539 fProofServer(o.fProofServer),
540 fDataDir(o.fDataDir),
541 fDataSet(o.fDataSet),
543 fRunNumbers(o.fRunNumbers),
548 fNReplica(o.fNReplica),
551 if (isdigit(fName[0])) {
552 Warning("TrainSetup", "Name starts with a digit, prepending 'a' to name");
553 fName = Form("a%s", fName.Data());
556 TIter nextPar(&o.fListOfPARs);
557 while ((obj = nextPar())) fListOfPARs.Add(obj->Clone());
558 TIter nextSrc(&o.fListOfSources);
559 while ((obj = nextSrc())) fListOfSources.Add(obj->Clone());
560 TIter nextLib(&o.fListOfLibraries);
561 while ((obj = nextLib())) fListOfLibraries.Add(obj->Clone());
562 TIter nextExa(&o.fListOfExtras);
563 while ((obj = nextExa())) fListOfExtras.Add(obj->Clone());
565 //__________________________________________________________________
567 * Assignment operator
569 * @param o Object to assign from
571 * @return Reference to this object.
573 TrainSetup& operator=(const TrainSetup& o)
576 fRootVersion = o.fRootVersion;
577 fAliRootVersion = o.fAliRootVersion;
578 fProofServer = o.fProofServer;
579 fDataDir = o.fDataDir;
580 fDataSet = o.fDataSet;
582 fNReplica = o.fNReplica;
583 fESDPass = o.fESDPass;
584 fRunNumbers = o.fRunNumbers;
586 TIter nextPar(&o.fListOfPARs);
587 while ((obj = nextPar())) fListOfPARs.Add(obj->Clone());
588 TIter nextSrc(&o.fListOfSources);
589 while ((obj = nextSrc())) fListOfSources.Add(obj->Clone());
590 TIter nextLib(&o.fListOfLibraries);
591 while ((obj = nextLib())) fListOfLibraries.Add(obj->Clone());
592 TIter nextExa(&o.fListOfExtras);
593 while ((obj = nextExa())) fListOfExtras.Add(obj->Clone());
598 //__________________________________________________________________
602 * @param type Type of input for analysis (kESD, kAOD)
603 * @param mode Mode of job (kLocal, kProof, kGrid)
604 * @param oper Operation
605 * @param nEvents Number of events to analyse (<0 means all)
606 * @param mc Whether to connect MC data
607 * @param usePar Whether to use PARs
608 * @param dbg Debug level
610 void Exec(const char* type,
611 const char* mode="GRID",
612 const char* oper="FULL",
618 Info("Exec", "Doing exec with type=%s, mode=%s, oper=%s, events=%d "
619 "mc=%d, usePar=%d", type, mode, oper, nEvents, mc, usePar);
620 EType eType = ParseType(type, mc);
621 EMode eMode = ParseMode(mode);
622 EOper eOper = ParseOperation(oper);
624 Exec(eType, eMode, eOper, nEvents, mc, usePar, dbg);
627 //__________________________________________________________________
631 * @param type Type of input for analysis (kESD, kAOD)
632 * @param mode Mode of job (kLocal, kProof, kGrid)
633 * @param oper Operation
634 * @param nEvents Number of events to analyse (<0 means all)
635 * @param mc Whether to connect MC data
636 * @param usePar Whether to use PARs
637 * @param dbg Debug level
639 void Exec(EType type,
647 Info("Exec", "Doing exec with type=%d, mode=%d, oper=%d, events=%d "
648 "mc=%d, usePar=%d", type, mode, oper, nEvents, mc, usePar);
650 if (mode == kProof) usePar = true;
652 if (!Connect(mode)) return;
654 TString cwd = gSystem->WorkingDirectory();
655 TString nam = EscapedName();
656 if (oper != kTerminate) {
657 if (!fAllowOverwrite && !gSystem->AccessPathName(nam.Data())) {
658 Error("Exec", "File/directory %s already exists", nam.Data());
661 if (gSystem->AccessPathName(nam.Data())) {
662 if (gSystem->MakeDirectory(nam.Data())) {
663 Error("Exec", "Failed to make directory %s", nam.Data());
669 if (gSystem->AccessPathName(nam.Data())) {
670 Error("Exec", "File/directory %s does not exists", nam.Data());
675 if (!gSystem->ChangeDirectory(nam.Data())) {
676 Error("Exec", "Failed to change directory to %s", nam.Data());
679 Info("Exec", "Made subdirectory %s, and cd'ed there", nam.Data());
681 if (!LoadCommonLibraries(mode, usePar)) return;
683 // --- Create analysis manager -----------------------------------
684 AliAnalysisManager *mgr = new AliAnalysisManager(fName,"Analysis Train");
686 // In test mode, collect system information on every event
687 // if (oper == kTest) mgr->SetNSysInfo(1);
688 if (dbg > 0) mgr->SetDebugLevel(dbg);
689 if (mode == kLocal) mgr->SetUseProgressBar(kTRUE, 100);
691 // --- ESD input handler ------------------------------------------
692 AliVEventHandler* inputHandler = CreateInputHandler(type);
693 if (inputHandler) mgr->SetInputEventHandler(inputHandler);
695 // --- Monte-Carlo ------------------------------------------------
696 AliVEventHandler* mcHandler = CreateMCHandler(type,mc);
697 if (mcHandler) mgr->SetMCtruthEventHandler(mcHandler);
699 // --- AOD output handler -----------------------------------------
700 AliVEventHandler* outputHandler = CreateOutputHandler(type);
701 if (outputHandler) mgr->SetOutputEventHandler(outputHandler);
703 // --- Include analysis macro path in search path ----------------
704 gROOT->SetMacroPath(Form("%s:%s:$ALICE_ROOT/ANALYSIS/macros",
705 cwd.Data(), gROOT->GetMacroPath()));
707 // --- Physics selction - only for ESD ---------------------------
708 if (type == kESD) CreatePhysicsSelection(mc, mgr);
710 // --- Create centrality task ------------------------------------
711 CreateCentralitySelection(mc, mgr);
713 // --- Create tasks ----------------------------------------------
714 CreateTasks(mode, usePar, mgr);
716 // --- Create Grid handler ----------------------------------------
717 // _must_ be done after all tasks has been added
718 AliAnalysisAlien* gridHandler = CreateGridHandler(type, mode, oper);
719 if (gridHandler) mgr->SetGridHandler(gridHandler);
721 // --- Create the chain ------------------------------------------
722 TChain* chain = CreateChain(type, mode, oper, mc);
723 if (mode == kLocal && !chain) {
724 Error("Exec", "No chain defined in local mode!");
728 // --- Print setup -----------------------------------------------
730 // if (mode == kProof) {
731 // Info("Run", "Exported environment variables to PROOF slaves:");
732 // TProof::GetEnvVars()->ls();
733 // Info("Run", "Environment variables for this session:");
734 // gSystem->Exec("printenv");
737 // --- Initialise the train --------------------------------------
738 if (!mgr->InitAnalysis()) {
739 gSystem->ChangeDirectory(cwd.Data());
740 Error("Run","Failed to initialise train");
744 // --- Show status -----------------------------------------------
747 Long64_t ret = StartAnalysis(mgr, mode, chain, nEvents);
749 // Make sure we go back
750 gSystem->ChangeDirectory(cwd.Data());
752 if (ret < 0) Error("Exec", "Analysis failed");
754 //__________________________________________________________________
758 * @param mgr Analysis manager
759 * @param mode Run mode
760 * @param chain Input data (local and proof only)
761 * @param nEvents Number of events to analyse
763 Long64_t StartAnalysis(AliAnalysisManager* mgr,
768 // --- Run the analysis ------------------------------------------
772 Error("StartAnalysis", "No chain defined");
775 if (nEvents < 0) nEvents = chain->GetEntries();
776 return mgr->StartAnalysis(ModeString(mode), chain, nEvents);
778 if (fDataSet.IsNull()) {
780 Error("StartAnalysis", "No chain defined");
783 if (nEvents < 0) nEvents = chain->GetEntries();
784 return mgr->StartAnalysis(ModeString(mode), chain, nEvents);
786 return mgr->StartAnalysis(ModeString(mode), fDataSet);
789 return mgr->StartAnalysis(ModeString(mode));
790 return mgr->StartAnalysis(ModeString(mode), nEvents);
792 // We should never get here
795 //__________________________________________________________________
797 * Return the escaped name
800 * @return Escaped name
802 const TString& EscapedName() const
806 //__________________________________________________________________
808 * Create a grid handler
810 * @param type Data type
811 * @param mode Run mode
812 * @param oper Operation
814 * @return Grid handler
816 virtual AliAnalysisAlien*
817 CreateGridHandler(EType type, EMode mode, EOper oper)
819 if (mode != kGrid) return 0;
821 TString name = EscapedName();
823 // Create the plug-in object, and set run mode
824 AliAnalysisAlien* plugin = new AliAnalysisAlien();
825 plugin->SetRunMode(OperString(oper));
827 // Production mode - not used here
828 // plugin->SetProductionMode();
830 // Set output to be per run
831 plugin->SetOutputToRunNo();
834 plugin->SetJobTag(fName);
836 // Set number of test files - used in test mode only
837 plugin->SetNtestFiles(1);
839 // Set required version of software
840 plugin->SetAPIVersion(fAliEnAPIVersion);
841 plugin->SetROOTVersion(fRootVersion);
842 plugin->SetAliROOTVersion(fAliRootVersion);
845 plugin->SetKeepLogs();
847 // Declare root of input data directory
848 plugin->SetGridDataDir(fDataDir);
850 // Data search patterns
852 if (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()) {
854 plugin->SetRunPrefix("");
857 pat = Form("*ESDs/pass%d%s/*/", fESDPass, fPassPostfix.Data());
858 plugin->SetRunPrefix("000");
860 pat.Append(Form("*%s.root", type == kESD ? "ESDs" : "AOD"));
861 plugin->SetDataPattern(pat);
863 // Add the run numbers
864 for (Int_t i = 0; i < fRunNumbers.fN; i++) {
865 if (fRunNumbers[i] < 0) continue;
866 plugin->AddRunNumber(fRunNumbers[i]);
869 // Set the working directory to be the trains name (with special
870 // characters replaced by '_' and the date appended), and also set
871 // the output directory (relative to working directory)
872 plugin->SetGridWorkingDir(name.Data());
873 plugin->SetGridOutputDir("output");
875 // Enable configured PARs
876 TIter nextPar(&fListOfPARs);
878 while ((parName = nextPar()))
879 plugin->EnablePackage(parName->GetName());
881 // Add sources that need to be compiled on the workers using
883 TString addSources = SetupSources();
884 if (!addSources.IsNull()) plugin->SetAnalysisSource(addSources.Data());
886 // Add binary libraries that should be uploaded to the workers
887 TString addLibs = SetupLibraries();
888 if (!addLibs.IsNull()) plugin->SetAdditionalLibs(addLibs.Data());
890 // Disable default outputs
891 plugin->SetDefaultOutputs(true);
894 plugin->SetMaxMergeFiles(20);
895 plugin->SetMergeExcludes("AliAOD.root "
897 "*event_stat*.root");
899 // Set number of runs per master - set to one to per run
900 plugin->SetNrunsPerMaster(1);
902 // Loop over defined containers in the analysis manager,
903 // and declare these as outputs
904 TString listOfAODs = "";
905 TString listOfHists = "";
906 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
907 AliAnalysisDataContainer* cont = 0;
908 TIter nextCont(mgr->GetOutputs());
909 while ((cont = static_cast<AliAnalysisDataContainer*>(nextCont()))) {
910 TString outName(cont->GetFileName());
911 TString& list = (outName == "default" ? listOfAODs : listOfHists);
912 if (outName == "default") {
913 if (!mgr->GetOutputEventHandler()) continue;
915 outName = mgr->GetOutputEventHandler()->GetOutputFileName();
917 if (list.Contains(outName)) continue;
918 if (!list.IsNull()) list.Append(",");
919 list.Append(outName);
921 if (!mgr->GetExtraFiles().IsNull()) {
922 if (!listOfAODs.IsNull()) listOfAODs.Append("+");
923 TString extra = mgr->GetExtraFiles();
924 extra.ReplaceAll(" ", ",");
925 listOfAODs.Append(extra);
927 TString outArchive = Form("stderr, stdout@disk=%d", fNReplica);
928 if (!listOfHists.IsNull())
929 outArchive.Append(Form(" hist_archive.zip:%s@disk=%d",
930 listOfHists.Data(), fNReplica));
931 if (!listOfAODs.IsNull())
932 outArchive.Append(Form(" aod_archive.zip:%s@disk=%d",
933 listOfAODs.Data(), fNReplica));
934 if (listOfAODs.IsNull() && listOfHists.IsNull())
935 Fatal("CreateGridHandler", "No outputs defined");
937 // plugin->SetOutputArchive(outArchive);
939 // Set name of generated analysis macro
940 plugin->SetAnalysisMacro(Form("%s.C", name.Data()));
942 // Maximum number of sub-jobs
943 // plugin->SetSplitMaxInputFileNumber(25);
945 // Set the Time-To-Live
946 plugin->SetTTL(70000);
948 // Re-submit failed jobs as long as the ratio of failed jobs is
949 // below this percentage.
950 plugin->SetMasterResubmitThreshold(95);
952 // Set the input format
953 plugin->SetInputFormat("xml-single");
955 // Set the name of the generated jdl
956 plugin->SetJDLName(Form("%s.jdl", name.Data()));
958 // Set the name of the generated executable
959 plugin->SetExecutable(Form("%s.sh", name.Data()));
961 // Set the job price !?
964 // Set whether to merge via JDL
965 plugin->SetMergeViaJDL(true);
968 plugin->SetFastReadOption(false);
970 // Whether to overwrite existing output
971 plugin->SetOverwriteMode(true);
973 // Set the executable binary name and options
974 plugin->SetExecutableCommand("aliroot -b -q -x");
976 // Split by storage element - must be lower case!
977 plugin->SetSplitMode("se");
981 //__________________________________________________________________
983 * Create input handler
989 virtual AliVEventHandler* CreateInputHandler(EType type)
992 case kESD: return new AliESDInputHandler();
993 case kAOD: return new AliAODInputHandler();
997 //__________________________________________________________________
999 * Create input handler
1001 * @param type Run type (ESD or AOD)
1002 * @param mc Assume monte-carlo input
1006 virtual AliVEventHandler* CreateMCHandler(EType type, bool mc)
1009 if (type != kESD) return 0;
1010 Info("CreateMCHandler", "Making MC handler");
1011 AliMCEventHandler* mcHandler = new AliMCEventHandler();
1012 mcHandler->SetReadTR(true);
1015 //__________________________________________________________________
1017 * Create output event handler
1023 virtual AliVEventHandler* CreateOutputHandler(EType type)
1025 AliAODHandler* ret = new AliAODHandler();
1028 ret->SetOutputFileName("AliAOD.root");
1031 ret->SetOutputFileName("AliAOD.pass2.root");
1036 //__________________________________________________________________
1038 * Create physics selection , and add to manager
1040 * @param mc Whether this is for MC
1041 * @param mgr Manager
1043 virtual void CreatePhysicsSelection(Bool_t mc,
1044 AliAnalysisManager* mgr)
1046 gROOT->Macro(Form("AddTaskPhysicsSelection.C(%d)", mc));
1047 mgr->RegisterExtraFile("event_stat.root");
1049 //__________________________________________________________________
1051 * Create physics selection , and add to manager
1053 * @param mc Whether this is for MC
1054 * @param mgr Manager
1056 virtual void CreateCentralitySelection(Bool_t mc, AliAnalysisManager* mgr)
1058 gROOT->Macro("AddTaskCentrality.C");
1059 AliCentralitySelectionTask* ctask =
1060 dynamic_cast<AliCentralitySelectionTask*>(mgr->GetTask("CentralitySelection"));
1062 ctask->SetPass(fESDPass);
1063 if (mc) ctask->SetMCInput();
1065 //__________________________________________________________________
1067 * Create analysis tasks
1069 * @param mode Run mode
1070 * @param mgr Manager
1071 * @param par Whether to use pars
1073 virtual void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)=0;
1074 //__________________________________________________________________
1076 * Connect to external services (Proof and/or grid)
1078 * @param mode Running mode
1080 * @return true on success
1082 virtual Bool_t Connect(EMode mode)
1084 if (mode == kLocal) return true;
1086 // --- Set-up connections to Proof cluster and alien -------------
1087 if (mode == kProof) {
1088 // --- Find user name ------------------------------------------
1089 TString userName(gSystem->Getenv("alien_API_USER"));
1090 if (userName.IsNull()) {
1091 userName = gSystem->GetUserInfo()->fUser;
1093 "environment variable 'alien_API_USER' not set, using %s",
1097 // --- Set prefered GSI method ---------------------------------
1098 gEnv->SetValue("XSec.GSI.DelegProxy", "2");
1100 // --- Figure out some server settings -------------------------
1102 Bool_t lite = false;
1103 if (fProofServer.BeginsWith("workers=") || fProofServer.IsNull()) {
1105 serv = fProofServer;
1108 serv = Form("%s@%s", userName.Data(), fProofServer.Data());
1110 // --- Possibly debug slave sessions with GDB ------------------
1112 TString gdbCmd("\"gdb --batch -ex run -ex bt --args\"");
1113 Info("Connect", "Using GDB to wrap slaves: %s", gdbCmd.Data());
1114 TProof::AddEnvVar("PROOF_WRAPPERCMD", gdbCmd);
1117 // --- Add ALICE_ROOT directory to search path for packages ----
1118 gEnv->SetValue("Proof.GlobalPackageDirs",
1120 gEnv->GetValue("Proof.GlobalPackageDirs", "."),
1121 gSystem->Getenv("ALICE_ROOT")));
1123 // --- Set OADB path on workers --------------------------------
1124 const char* oadbPath = AliAnalysisManager::GetOADBPath();
1125 TProof::AddEnvVar("OADB_PATH", oadbPath);
1126 // if (lite) gSystem->Setenv("OADB_PATH", oadbPath);
1127 // Info("Connect", "OADB_PATH=%s", gSystem->Getenv("OADB_PATH"));
1129 // --- Now open connection to PROOF cluster --------------------
1132 Error("Connect", "Failed to connect to Proof cluster %s as %s",
1133 fProofServer.Data(), userName.Data());
1136 if (lite) return true;
1139 // --- Open a connection to the grid -----------------------------
1140 TGrid::Connect("alien://");
1141 if (!gGrid || !gGrid->IsConnected()) {
1142 // This is only fatal in grid mode
1143 Error("Connect", "Failed to connect to AliEN");
1144 if (mode == kGrid) return false;
1147 if (mode == kGrid) return true;
1150 // --- Set and make output directory -----------------------------
1151 TString name = EscapedName();
1152 TString homeDir(gGrid->GetHomeDirectory());
1153 TString workDir(homeDir);
1154 workDir.Append("/");
1155 workDir.Append(name);
1157 // Make working directory
1158 if (!gGrid->Cd(workDir)) {
1160 if (gGrid->Mkdir(workDir)) {
1162 Info("Connect", "Directory %s created", workDir.Data());
1165 // Make output directory
1166 gGrid->Mkdir("proof_output");
1167 gGrid->Cd("proof_output");
1171 //__________________________________________________________________
1173 * Load common libraries
1175 * @param mode Running mode
1176 * @param par If true, load as PARs
1178 * @return true on success
1180 Bool_t LoadCommonLibraries(EMode mode, Bool_t par)
1182 if (!gSystem->Getenv("ALICE_ROOT")) {
1183 Error("LoadCommonLibraries", "Local AliROOT not available");
1186 gSystem->Load("libTree.so");
1187 gSystem->Load("libGeom.so");
1188 gSystem->Load("libVMC.so");
1189 gSystem->Load("libPhysics.so");
1190 gSystem->Load("libMinuit.so");
1191 if (mode == kProof) {
1192 gProof->Exec("gSystem->Load(\"libTree.so\");");
1193 gProof->Exec("gSystem->Load(\"libGeom.so\");");
1194 gProof->Exec("gSystem->Load(\"libMinuit.so\");");
1195 gProof->Exec("gSystem->Load(\"libVMC.so\");");
1201 Bool_t basic = mode == kGrid ? false : par;
1203 ret &= LoadLibrary("STEERBase", mode, basic, false);
1204 ret &= LoadLibrary("ESD", mode, basic, false);
1205 ret &= LoadLibrary("AOD", mode, basic, false);
1206 ret &= LoadLibrary("ANALYSIS", mode, basic, true);
1207 ret &= LoadLibrary("OADB", mode, basic, true);
1208 ret &= LoadLibrary("ANALYSISalice", mode, basic, true);
1212 //__________________________________________________________________
1216 * @param what What library to load
1217 * @param mode Mode (local, proof, grid)
1218 * @param par If true, load as PAR
1219 * @param rec If true, also load on slaves
1221 * @return true on success
1223 Bool_t LoadLibrary(const char* what, EMode mode, Bool_t par, Bool_t rec=false)
1225 if (!what || what[0] == '\0') return true;
1227 TString module(what);
1228 TString libName(what);
1229 if (!libName.BeginsWith("lib")) libName = Form("lib%s", libName.Data());
1230 if (!libName.EndsWith(".so")) libName.Append(".so");
1235 case kLocal: // Just load and exit
1236 gSystem->Load(libName.Data());
1240 ret = SetupPAR(what) ? 0 : -1;
1241 if (rec) fListOfPARs.Add(new TObjString(what));
1243 ret = gSystem->Load(libName.Data());
1244 if (rec) fListOfLibraries.Add(new TObjString(libName));
1248 ret = gProof->UploadPackage(what);
1250 ret = gProof->UploadPackage(gSystem->ExpandPathName(Form("../%s.par",
1254 gProof->UploadPackage(gSystem
1255 ->ExpandPathName(Form("$ALICE_ROOT/%s.par",
1258 Error("LoadLibrary",
1259 "Could not find module %s.par in current directory nor "
1260 "in $ALICE_ROOT", module.Data());
1265 ret = gProof->EnablePackage(what);
1269 Error("LoadLibrary", "Couldn't load %s", what);
1275 //__________________________________________________________________
1276 Bool_t SetupPAR(const char* what)
1278 if (!what || what[0] == '\0') return -1;
1280 TString parFile(Form("%s.par", what));
1281 if (gSystem->AccessPathName(parFile.Data())) {
1282 if (gSystem->AccessPathName(Form("../%s.par", what))) {
1284 TString aliParFile =
1285 gSystem->ExpandPathName(Form("$(ALICE_ROOT)/%s.par", what));
1286 if (gSystem->AccessPathName(aliParFile.Data())) {
1287 Error("SetupPAR", "PAR file %s not found in current directory or "
1288 "$(ALICE_ROOT)", what);
1291 // Copy to current directory
1292 TFile::Cp(aliParFile, parFile);
1295 gSystem->Exec(Form("ln -s ../%s.par .", what));
1299 gSystem->Exec(Form("tar xvzf %s", parFile.Data()));
1301 // Change directory into par archive
1302 TString cwd = gSystem->WorkingDirectory();
1304 if (!gSystem->ChangeDirectory(what)) {
1305 Error("SetupPAR", "Failed to change directory to %s", what);
1310 if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
1311 Info("SetupPar", "Building in PAR archive %s", what);
1312 if (gSystem->Exec("PROOF-INF/BUILD.sh")) {
1313 Error("SetupPar", "Failed to build in PAR directory %s", what);
1314 gSystem->ChangeDirectory(cwd.Data());
1319 // Check for setup script
1320 if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
1321 Info("SetupPAR", "Setting up for PAR %s", what);
1322 gROOT->Macro("PROOF-INF/SETUP.C");
1324 if (!gSystem->ChangeDirectory(cwd.Data())) return false;
1328 //__________________________________________________________________
1329 TString SetupExtras()
1332 TIter next(&fListOfExtras);
1333 TObjString* obj = 0;
1334 while ((obj = static_cast<TObjString*>(next()))) {
1335 TString path = gSystem->ExpandPathName(obj->GetName());
1336 if (!path.BeginsWith("/"))
1337 // If not an absolute path, prepend to up-one
1338 path = Form("../%s", path.Data());
1339 if (gSystem->AccessPathName(path.Data())) {
1340 // File not accessible
1341 Warning("SetupExtras", "File %s not accessible", path.Data());
1344 ret.Append(Form("%s ", gSystem->BaseName(obj->GetName())));
1345 gSystem->Exec(Form("ln -s %s .", path.Data()));
1350 //__________________________________________________________________
1351 TString SetupSources()
1353 TString nam = EscapedName();
1355 TIter next(&fListOfSources);
1357 while ((src = next())) {
1358 TString path = gSystem->ExpandPathName(src->GetName());
1359 if (!path.BeginsWith("/"))
1360 // If not an absolute path, prepend to up-one
1361 path = Form("../%s", path.Data());
1362 if (gSystem->AccessPathName(path.Data())) {
1363 // File not accessible
1364 Warning("SetupSources", "File %s not accessible", path.Data());
1367 ret.Append(Form("%s ", gSystem->BaseName(src->GetName())));
1368 gSystem->Exec(Form("ln -s %s .", path.Data()));
1373 //__________________________________________________________________
1374 TString SetupLibraries()
1377 TIter next(&fListOfLibraries);
1379 while ((lib = next())) {
1380 ret.Append(lib->GetName());
1383 // Also add extra files to this variable
1384 ret.Append(SetupExtras());
1388 //__________________________________________________________________
1390 * Scan directory @a dir (possibly recursive) for tree files to add
1391 * to the chain. This does not follow sym-links
1393 * @param dir Directory to scan
1394 * @param chain Chain to add to
1395 * @param type Type of tree (ESD or AOD)
1396 * @param recursive Whether to scan recursively
1397 * @param mc Look also for MC files if true
1399 * @return true if any files where added
1401 Bool_t ScanDirectory(TSystemDirectory* dir, TChain* chain,
1402 EType type, bool recursive, bool mc)
1406 case kESD: fnPattern = "AliESD"; break;
1407 case kAOD: fnPattern = "AliAOD"; break;
1413 // Get list of files, and go back to old working directory
1414 TString oldDir(gSystem->WorkingDirectory());
1415 TList* files = dir->GetListOfFiles();
1416 if (!gSystem->ChangeDirectory(oldDir)) {
1417 Error("ScanDirectory", "Failed to go back to %s", oldDir.Data());
1420 if (!files) return false;
1424 Bool_t hasGAlice = (!mc ? true : false);
1425 Bool_t hasKine = (!mc ? true : false);
1426 Bool_t hasTrRef = (!mc ? true : false);
1428 // Sort list of files and check if we should add it
1431 TSystemFile* file = 0;
1432 while ((file = static_cast<TSystemFile*>(next()))) {
1433 TString name(file->GetName());
1434 TString title(file->GetTitle());
1435 TString full(gSystem->ConcatFileName(file->GetTitle(), name.Data()));
1436 if (dynamic_cast<TSystemDirectory*>(file)) full = title;
1437 // Ignore special links
1438 if (name == "." || name == "..") {
1439 // Info("ScanDirectory", "Ignoring %s", name.Data());
1444 if (gSystem->GetPathInfo(full.Data(), fs)) {
1445 Warning("ScanDirectory", "Cannot stat %s (%s)", full.Data(),
1446 gSystem->WorkingDirectory());
1449 // Check if this is a directory
1450 if (file->IsDirectory(full)) {
1452 // if (title[0] == '/')
1453 TSystemDirectory* d = new TSystemDirectory(file->GetName(),
1455 if (ScanDirectory(d,chain,type,recursive,mc))
1462 // If this is not a root file, ignore
1463 if (!name.EndsWith(".root")) continue;
1465 // If this file does not contain AliESDs, ignore
1466 if (!name.Contains(fnPattern)) {
1467 // Info("ScanDirectory", "%s does not match pattern %s",
1468 // name.Data(), fnPattern.Data());
1470 if (name.CompareTo("galice.root") == 0) hasGAlice = true;
1471 if (name.CompareTo("Kinematics.root") == 0) hasKine = true;
1472 if (name.CompareTo("TrackRefs.root") == 0) hasTrRef = true;
1478 // Info("ScanDirectory", "Adding %s", full.Data());
1479 toAdd.Add(new TObjString(full));
1482 if (mc && toAdd.GetEntries() > 0 &&
1483 (!hasGAlice || !hasKine || !hasTrRef)) {
1484 Warning("ScanDirectory",
1485 "one or more of {galice,Kinematics,TrackRefs}.root missing from "
1486 "%s, not adding anything from this directory",
1491 TIter nextAdd(&toAdd);
1493 while ((s = static_cast<TObjString*>(nextAdd()))) {
1494 // Info("ScanDirectory", "Adding %s", s->GetString().Data());
1495 chain->Add(s->GetString());
1497 if (toAdd.GetEntries() > 0) ret = true;
1499 gSystem->ChangeDirectory(oldDir);
1502 //__________________________________________________________________
1504 * Create a chain from an XML containing an collection
1506 * @param treeName Name of tree's
1507 * @param xmlFile XML collection
1509 * @return Newly allocated chain or null
1511 TChain* CreateChainFromXML(const char* treeName,
1512 const char* xmlFile)
1514 TGridCollection* collection = TAlienCollection::Open(xmlFile);
1516 Error("CreateChainFromXML", "Cannot create AliEn collection from "
1517 "XML file %s", xmlFile);
1521 TChain* chain = new TChain(treeName);
1522 collection->Reset();
1523 while (collection->Next()) chain->Add(collection->GetTURL(""));
1527 //__________________________________________________________________
1529 * Create a chain of data
1531 * @param type Type of data
1532 * @param mode Operation mode
1533 * @param mc Assume MC input if true
1535 * @return TChain of data
1537 TChain* CreateChain(EType type, EMode mode, EOper /* oper */, Bool_t mc)
1541 case kESD: treeName = "esdTree"; break;
1542 case kAOD: treeName = "aodTree"; break;
1548 if (!fDataSet.IsNull()) break;
1549 // Otherwise fall through
1551 if (fXML.IsNull()) {
1552 chain = new TChain(treeName.Data());
1553 TString dir(fDataDir);
1554 if (dir == ".") dir = "";
1555 if (!dir.BeginsWith("/")) dir = Form("../%s", dir.Data());
1556 TString savdir(gSystem->WorkingDirectory());
1557 TSystemDirectory d(gSystem->BaseName(dir.Data()), dir.Data());
1558 if (!ScanDirectory(&d, chain, type, true, mc)) {
1562 gSystem->ChangeDirectory(savdir);
1565 chain = CreateChainFromXML(treeName.Data(), fXML.Data());
1567 case kGrid: break; // Do nothing - we use plugin
1570 if (chain && chain->GetNtrees() <= 0) {
1576 //__________________________________________________________________
1577 TString fName; // Name of analysis
1578 TString fRootVersion; // ROOT version to use
1579 TString fAliRootVersion; // AliROOT version to use
1580 TString fAliEnAPIVersion; // AliEn API version to use
1581 TString fProofServer; // Name of proof server
1582 TString fDataDir; // Grid Input directory
1583 TString fDataSet; // Proof data set name
1584 TString fXML; // XML collection for local/proof mode
1585 TArrayI fRunNumbers; // List of run number
1586 TList fListOfPARs; // List of PAR files to use
1587 TList fListOfSources; // List of sources to upload and AcLIC
1588 TList fListOfLibraries; // List of libraries to load
1589 TList fListOfExtras; // List of extra files to upload
1590 Int_t fNReplica; // Storage replication
1591 Int_t fESDPass; // ESD pass number
1592 TString fPassPostfix; // Possible pass postfix
1593 TString fEscapedName; // Name escaped for special chars
1594 Bool_t fAllowOverwrite; // Allow overwriting output dir
1595 Bool_t fUseGDB; // Wrap PROOF slaves in GDB
1602 gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2:"
1603 "$ALICE_ROOT/ANALYSIS/macros",
1604 gROOT->GetMacroPath()));
1605 gSystem->AddIncludePath("-I${ALICE_ROOT}/include");
1606 gSystem->Load("libRAliEn");
1607 gSystem->Load("libANALYSIS");
1608 gSystem->Load("libANALYSISalice");
1609 TString path = gSystem->Which(gROOT->GetMacroPath(), "TrainSetup.C");
1610 Info("BuildTrainSetup", "Path=%s", path.Data());
1611 TString tmp("TrainSetup");
1612 FILE* fp = gSystem->TempFileName(tmp, ".");
1614 gSystem->Unlink(tmp);
1616 Info("BuildTrainSetup", "Copy %s -> %s", path.Data(), tmp.Data());
1617 gSystem->CopyFile(path, tmp);
1618 gROOT->LoadMacro(Form("%s+g", tmp.Data()));
1619 gSystem->Unlink(tmp);
1620 tmp.ReplaceAll(".C", "_C.so");
1621 gSystem->Unlink(tmp);
1622 tmp.ReplaceAll("_C.so", "_C.d");
1623 gSystem->Unlink(tmp);
1627 //____________________________________________________________________