3 * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
4 * @date Wed Mar 23 12:12:00 2011
8 * @ingroup pwg2_forward_scripts_makers
15 #include <TAlienCollection.h>
23 #include <TObjString.h>
27 #include <TSystemDirectory.h>
28 #include <TSystemFile.h>
31 #include <AliAODHandler.h>
32 #include <AliAODInputHandler.h>
33 #include <AliAnalysisDataContainer.h>
34 #include <AliAnalysisManager.h>
35 #include <AliAnalysisAlien.h>
36 #include <AliESDInputHandler.h>
37 #include <AliMCEventHandler.h>
38 #include <AliVEventHandler.h>
42 class AliAnalysisManager;
45 //====================================================================
47 * Generic set-up of an analysis train using the grid-handler (AliEn plugin).
49 * Users should define a class that derives from this. The class
50 * should implement the member function CreateTasks to add needed
55 * class MyTrain : public TrainSetup
58 * MyTrain(Bool_t dateTime = false,
64 * : TrainSetup("My train", dateTime, year, month, day, hour, min)
66 * void Run(const char* type, const char* mode, const char* oper,
67 * Int_t nEvents=-1, Bool_t mc=false,
68 * Bool_t usePar=false)
70 * Exec(type, mode, oper, nEvents, mc, usePar);
73 * void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)
75 * AliAnalysisManager::SetCommonFileName("my_analysis.root");
76 * LoadLibrary("MyAnalysis", mode, par, true);
77 * Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
78 * gROOT->Macro("MyAnalysis.C");
83 * This can then be run like
87 * Root> .L TrainSetup.C
97 * gROOT->LoadMacro("TrainSetup.C");
98 * gROOT->LoadMacro("MyTrain.C");
104 * To byte compile this, you need to load the analsys libraries first
108 * Root> gSystem->Load("libANALYSIS.so");
109 * Root> gSystem->Load("libANALYSISalice.so");
110 * Root> gROOT->LoadMacro("TrainSetup.C++");
113 * @ingroup pwg2_forward_scripts_makers
119 * Data type to process
122 /** Event Summary Data */
124 /** Analysis Object Data */
128 * How to run the analysis
134 /** In PROOF(-Lite) cluster */
140 * What stage of the analysis to run
144 /** Testing. Local processing, a single copied from Grid */
148 /** Submit to queue */
150 /** Merge and terminate */
156 //__________________________________________________________________
160 * @param name Name of analysis (free-form)
161 * @param useDateTime Whether to append date and time to the name
162 * @param year Year - if not specified, taken from current date
163 * @param month Month - if not specified, taken from current date
164 * @param day Day - if not specified, taken from current date
165 * @param hour Hour - if not specified, taken from current time
166 * @param min Minute - if not specified, taken from current time
168 TrainSetup(const char* name, Bool_t useDateTime=true,
169 UShort_t year=0, UShort_t month=0,
170 UShort_t day=0, UShort_t hour=0, UShort_t min=0)
172 fRootVersion("v5-28-00a"),
173 fAliRootVersion("v4-21-18-AN"),
174 fProofServer("alicecaf.cern.ch"),
175 fDataDir("/alice/data/2010/LHC10c"),
176 fDataSet("/COMMON/COMMON/LHC09a4_run8100X#/esdTree"),
187 char c[] = { ' ', '/', '@', 0 };
190 fEscapedName.ReplaceAll(Form("%c", *p), "_");
195 if (year == 0 || month == 0 || day == 0) {
197 year = now.GetYear();
198 month = now.GetMonth();
200 hour = now.GetHour();
201 min = now.GetMinute();
203 fEscapedName.Append(Form("_%04d%02d%02d_%02d%02d",
204 year, month, day, hour, min));
209 //__________________________________________________________________
211 * Parse a string into a type enum
213 * @param type String to pass
214 * @param mc True on return if the string contained "MC"
216 * @return Enumaration value
218 static EType ParseType(const char* type, Bool_t& mc)
224 if (sType.Contains("MC")) mc = true;
225 if (sType.Contains("ESD")) eType = kESD;
226 else if (sType.Contains("AOD")) eType = kAOD;
228 Fatal("Run", "Unknown type '%s'", type);
232 //__________________________________________________________________
234 * Return a string that reflects the passed mode
238 * @return String representation of mode
240 static const char* ModeString(EMode eMode)
243 case kLocal: return "LOCAL";
244 case kProof: return "PROOF";
245 case kGrid: return "GRID";
249 //__________________________________________________________________
251 * Parse a string for mode specifier
253 * @param mode Mode string
255 * @return EMode value
257 static EMode ParseMode(const char* mode)
261 EMode eMode = kLocal;
262 if (sMode == "LOCAL") eMode = kLocal;
263 else if (sMode == "PROOF") eMode = kProof;
264 else if (sMode == "GRID") eMode = kGrid;
266 Fatal("Run", "Unknown mode '%s'", mode);
270 //__________________________________________________________________
272 * Return a string that reflects the passed operation
274 * @param eOper Operation
276 * @return String representation of operation
278 static const char* OperString(EOper eOper)
281 case kTest: return "TEST";
282 case kOffline: return "OFFLINE";
283 case kSubmit: return "SUBMIT";
284 case kTerminate: return "TERMINATE";
285 case kFull: return "FULL";
289 //__________________________________________________________________
291 * Parse an operation string
293 * @param oper Operation
295 * @return An EOper value
297 static EOper ParseOperation(const char* oper)
302 if (sOper == "TEST") eOper = kTest;
303 else if (sOper == "OFFLINE") eOper = kOffline;
304 else if (sOper == "SUBMIT") eOper = kSubmit;
305 else if (sOper == "TERMINATE") eOper = kTerminate;
306 else if (sOper == "FULL") eOper = kFull;
308 Fatal("Run", "unknown operation '%s'", oper);
312 //__________________________________________________________________
314 * Set ROOT version to use
318 void SetROOTVersion(const char* v) { fRootVersion = v; }
319 //__________________________________________________________________
321 * Set AliROOT version to use
325 void SetAliROOTVersion(const char* v) { fAliRootVersion = v; }
326 //__________________________________________________________________
328 * Set the proof server URL
332 void SetProofServer(const char* s) { fProofServer = s; }
333 //__________________________________________________________________
335 * Set the GRID/Local data dir
339 void SetDataDir(const char* d) { fDataDir = d; }
340 //__________________________________________________________________
342 * Set the PROOF data set
346 void SetDataSet(const char* d) { fDataSet = d; }
347 //__________________________________________________________________
349 * Set the XML file to use
353 void SetXML(const char* x) { fXML = x; }
354 //__________________________________________________________________
356 * Set how many replicas of the output we want
360 void SetNReplica(Int_t n) { fNReplica = n; }
361 //__________________________________________________________________
363 * Add a source file to be copied and byte compiled on slaves
366 * @param addToExtra If false, do not copy
368 void AddSource(const char* src, bool addToExtra=true)
370 fListOfSources.Add(new TObjString(src));
371 if (addToExtra) AddExtraFile(src); // Source code isn't copied!
373 //__________________________________________________________________
375 * Add binary data to be uploaded to slaves
377 * @param lib Name of binary file
379 void AddLibrary(const char* lib) { fListOfLibraries.Add(new TObjString(lib));}
380 //__________________________________________________________________
382 * Add a run to be analysed
384 * @param run Run number
386 void AddRun(Int_t run)
388 Int_t i = fRunNumbers.fN; fRunNumbers.Set(i+1); fRunNumbers[i] = run;
390 //__________________________________________________________________
392 * Read run numbers from a file
394 * @param filename File name
396 void ReadRunNumbers(const char* filename)
398 std::ifstream file(filename);
400 Fatal("ReadRunNumbers", "Cannot read from %s", filename);
402 while (!file.eof()) {
408 if (file.bad()) break;
412 //__________________________________________________________________
414 * Add an extra file to be uploaded to slave
416 * @param file Extra file to be uploaded
418 void AddExtraFile(const char* file)
420 fListOfExtras.Add(new TObjString(file));
422 //__________________________________________________________________
429 std::cout << fName << " train setup\n"
430 << " ROOT version: " << fRootVersion << "\n"
431 << " AliROOT version: " << fAliRootVersion << "\n"
432 << " Name of proof server: " << fProofServer << "\n"
433 << " Grid Input directory: " << fDataDir << "\n"
434 << " Proof data set name: " << fDataSet << "\n"
435 << " XML collection: " << fXML << "\n"
436 << " Storage replication: " << fNReplica << "\n"
437 << " Run numbers: " << std::flush;
438 for (Int_t i = 0; i < fRunNumbers.GetSize(); i++)
439 std::cout << (i == 0 ? "" : ", ") << fRunNumbers.At(i);
442 << " PAR files: " << std::flush;
445 TIter nextPar(&fListOfPARs);
446 while ((obj = nextPar())) {
447 std::cout << (first ? "" : ", ") << obj->GetName();
452 << " Script sources: " << std::flush;
454 TIter nextSrc(&fListOfSources);
455 while ((obj = nextSrc())) {
456 std::cout << (first ? "" : ", ") << obj->GetName();
461 << " Libraries to load: " << std::flush;
463 TIter nextLib(&fListOfLibraries);
464 while ((obj = nextLib())) {
465 std::cout << (first ? "" : ", ") << obj->GetName();
468 std::cout << std::endl;
470 AliAnalysisGrid* plugin =
471 AliAnalysisManager::GetAnalysisManager()->GetGridHandler();
477 //__________________________________________________________________
478 TrainSetup(const TrainSetup& o)
480 fRootVersion(o.fRootVersion),
481 fAliRootVersion(o.fAliRootVersion),
482 fProofServer(o.fProofServer),
483 fDataDir(o.fDataDir),
484 fDataSet(o.fDataSet),
486 fRunNumbers(o.fRunNumbers),
491 fNReplica(o.fNReplica),
495 TIter nextPar(&o.fListOfPARs);
496 while ((obj = nextPar())) fListOfPARs.Add(obj->Clone());
497 TIter nextSrc(&o.fListOfSources);
498 while ((obj = nextSrc())) fListOfSources.Add(obj->Clone());
499 TIter nextLib(&o.fListOfLibraries);
500 while ((obj = nextLib())) fListOfLibraries.Add(obj->Clone());
501 TIter nextExa(&o.fListOfExtras);
502 while ((obj = nextExa())) fListOfExtras.Add(obj->Clone());
504 //__________________________________________________________________
505 TrainSetup& operator=(const TrainSetup& o)
508 fRootVersion = o.fRootVersion;
509 fAliRootVersion = o.fAliRootVersion;
510 fProofServer = o.fProofServer;
511 fDataDir = o.fDataDir;
512 fDataSet = o.fDataSet;
514 fNReplica = o.fNReplica;
515 fESDPass = o.fESDPass;
516 fRunNumbers = o.fRunNumbers;
518 TIter nextPar(&o.fListOfPARs);
519 while ((obj = nextPar())) fListOfPARs.Add(obj->Clone());
520 TIter nextSrc(&o.fListOfSources);
521 while ((obj = nextSrc())) fListOfSources.Add(obj->Clone());
522 TIter nextLib(&o.fListOfLibraries);
523 while ((obj = nextLib())) fListOfLibraries.Add(obj->Clone());
524 TIter nextExa(&o.fListOfExtras);
525 while ((obj = nextExa())) fListOfExtras.Add(obj->Clone());
530 //__________________________________________________________________
534 * @param type Type of input for analysis (kESD, kAOD)
535 * @param mode Mode of job (kLocal, kProof, kGrid)
536 * @param oper Operation
537 * @param nEvents Number of events to analyse (<0 means all)
538 * @param mc Whether to connect MC data
539 * @param usePar Whether to use PARs
540 * @param dbg Debug level
542 void Exec(const char* type,
543 const char* mode="GRID",
544 const char* oper="FULL",
550 EType eType = ParseType(type);
551 EMode eMode = ParseMode(mode);
552 EOper eOper = ParseOperation(oper);
554 Exec(eType, eMode, eOper, nEvents, mc, usePar, dbg);
557 //__________________________________________________________________
561 * @param type Type of input for analysis (kESD, kAOD)
562 * @param mode Mode of job (kLocal, kProof, kGrid)
563 * @param oper Operation
564 * @param nEvents Number of events to analyse (<0 means all)
565 * @param mc Whether to connect MC data
566 * @param usePar Whether to use PARs
567 * @param dbg Debug level
569 void Exec(EType type,
577 if (mode == kProof) usePar = true;
579 if (!Connect(mode)) return;
581 TString cwd = gSystem->WorkingDirectory();
582 TString nam = EscapedName();
583 if (oper != kTerminate) {
584 if (!gSystem->AccessPathName(nam.Data())) {
585 Error("Exec", "File/directory %s already exists", nam.Data());
588 if (gSystem->MakeDirectory(nam.Data())) {
589 Error("Exec", "Failed to make directory %s", nam.Data());
594 if (gSystem->AccessPathName(nam.Data())) {
595 Error("Exec", "File/directory %s does not exists", nam.Data());
600 if (!gSystem->ChangeDirectory(nam.Data())) {
601 Error("Exec", "Failed to change directory to %s", nam.Data());
604 Info("Exec", "Made subdirectory %s, and cd'ed there", nam.Data());
606 if (!LoadCommonLibraries(mode, usePar)) return;
608 // --- Create analysis manager -----------------------------------
609 AliAnalysisManager *mgr = new AliAnalysisManager(fName,"Analysis Train");
611 // In test mode, collect system information on every event
612 // if (oper == kTest) mgr->SetNSysInfo(1);
613 if (dbg > 0) mgr->SetDebugLevel(dbg);
614 if (mode == kLocal) mgr->SetUseProgressBar(kTRUE, 100);
616 // --- ESD input handler ------------------------------------------
617 mgr->SetInputEventHandler(CreateInputHandler(type));
619 // --- Monte-Carlo ------------------------------------------------
620 mgr->SetMCtruthEventHandler(CreateMCHandler(type,mc));
622 // --- AOD output handler -----------------------------------------
623 mgr->SetOutputEventHandler(CreateOutputHandler(type));
625 // --- Include analysis macro path in search path ----------------
626 gROOT->SetMacroPath(Form("%s:$ALICE_ROOT/ANALYSIS/macros",
627 gROOT->GetMacroPath()));
629 // --- Physics selction ------------------------------------------
630 gROOT->Macro(Form("AddTaskPhysicsSelection.C(%d)", mc));
631 mgr->RegisterExtraFile("event_stat.root");
633 // --- Create tasks ----------------------------------------------
634 CreateTasks(mode, usePar, mgr);
636 // --- Create Grid handler ----------------------------------------
637 // _must_ be done after all tasks has been added
638 mgr->SetGridHandler(CreateGridHandler(type, mode, oper));
640 // --- Create the chain ------------------------------------------
641 TChain* chain = CreateChain(type, mode, oper);
643 // --- Print setup -----------------------------------------------
646 // --- Initialise the train --------------------------------------
647 if (!mgr->InitAnalysis()) {
648 gSystem->ChangeDirectory(cwd.Data());
649 Fatal("Run","Failed initialise train");
652 // --- Show status -----------------------------------------------
655 StartAnalysis(mgr, mode, chain, nEvents);
657 gSystem->ChangeDirectory(cwd.Data());
660 void StartAnalysis(AliAnalysisManager* mgr,
665 // --- Run the analysis ------------------------------------------
668 if (!chain) Fatal("Run", "No chain defined");
669 if (nEvents < 0) nEvents = chain->GetEntries();
670 mgr->StartAnalysis(ModeString(mode), chain, nEvents);
673 if (fDataSet.IsNull()) {
674 if (!chain) Fatal("Run", "No chain defined");
675 if (nEvents < 0) nEvents = chain->GetEntries();
676 mgr->StartAnalysis(ModeString(mode), chain, nEvents);
679 mgr->StartAnalysis(ModeString(mode), fDataSet);
682 mgr->StartAnalysis(ModeString(mode));
685 //__________________________________________________________________
686 const TString& EscapedName() const
690 //__________________________________________________________________
692 * Create a grid handler
694 * @param type Data type
695 * @param mode Run mode
696 * @param oper Operation
698 * @return Grid handler
700 AliAnalysisAlien* CreateGridHandler(EType type, EMode mode, EOper oper)
702 if (mode != kGrid) return 0;
704 TString name = EscapedName();
706 // Create the plug-in object, and set run mode
707 AliAnalysisAlien* plugin = new AliAnalysisAlien();
708 plugin->SetRunMode(OperString(oper));
710 // Production mode - not used here
711 // plugin->SetProductionMode();
713 // Set output to be per run
714 plugin->SetOutputToRunNo();
717 plugin->SetJobTag(fName);
719 // Set number of test files - used in test mode only
720 plugin->SetNtestFiles(1);
722 // Set required version of software
723 plugin->SetAPIVersion("V1.1x");
724 plugin->SetROOTVersion(fRootVersion);
725 plugin->SetAliROOTVersion(fAliRootVersion);
728 plugin->SetKeepLogs();
730 // Declare root of input data directory
731 plugin->SetGridDataDir(fDataDir);
733 // Data search patterns
734 if (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler())
735 plugin->SetRunPrefix("");
737 plugin->SetRunPrefix("000");
738 plugin->SetDataPattern(Form("*ESDs/pass%d/*/*%s.root",
739 fESDPass, type == kESD ? "ESDs" : "AOD"));
741 // Add the run numbers
742 for (Int_t i = 0; i < fRunNumbers.fN; i++) {
743 if (fRunNumbers[i] < 0) continue;
744 plugin->AddRunNumber(fRunNumbers[i]);
747 // Set the working directory to be the trains name (with special
748 // characters replaced by '_' and the date appended), and also set
749 // the output directory (relative to working directory)
750 plugin->SetGridWorkingDir(name.Data());
751 plugin->SetGridOutputDir("output");
753 // Enable configured PARs
754 TIter nextPar(&fListOfPARs);
756 while ((parName = nextPar()))
757 plugin->EnablePackage(parName->GetName());
759 // Add sources that need to be compiled on the workers using
761 TString addSources = SetupSources();
762 if (!addSources.IsNull()) plugin->SetAnalysisSource(addSources.Data());
764 // Add binary libraries that should be uploaded to the workers
765 TString addLibs = SetupLibraries();
766 if (!addLibs.IsNull()) plugin->SetAdditionalLibs(addLibs.Data());
768 // Disable default outputs
769 plugin->SetDefaultOutputs(true);
772 plugin->SetMaxMergeFiles(20);
773 plugin->SetMergeExcludes("AliAOD.root "
774 "EventStat_temp.root "
775 "*event_stat*.root");
777 // Set number of runs per master - set to one to per run
778 plugin->SetNrunsPerMaster(1);
780 // Loop over defined containers in the analysis manager,
781 // and declare these as outputs
782 TString listOfAODs = "";
783 TString listOfHists = "";
784 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
785 AliAnalysisDataContainer* cont = 0;
786 TIter nextCont(mgr->GetOutputs());
787 while ((cont = static_cast<AliAnalysisDataContainer*>(nextCont()))) {
788 TString outName(cont->GetFileName());
789 TString& list = (outName == "default" ? listOfAODs : listOfHists);
790 if (outName == "default") {
791 if (!mgr->GetOutputEventHandler()) continue;
793 outName = mgr->GetOutputEventHandler()->GetOutputFileName();
795 if (list.Contains(outName)) continue;
796 if (!list.IsNull()) list.Append(",");
797 list.Append(outName);
799 if (!mgr->GetExtraFiles().IsNull()) {
800 if (!listOfAODs.IsNull()) listOfAODs.Append("+");
801 TString extra = mgr->GetExtraFiles();
802 extra.ReplaceAll(" ", ",");
803 listOfAODs.Append(extra);
805 TString outArchive = Form("stderr, stdout@disk=%d", fNReplica);
806 if (!listOfHists.IsNull())
807 outArchive.Append(Form(" hist_archive.zip:%s@disk=%d",
808 listOfHists.Data(), fNReplica));
809 if (!listOfAODs.IsNull())
810 outArchive.Append(Form(" aod_archive.zip:%s@disk=%d",
811 listOfAODs.Data(), fNReplica));
812 if (listOfAODs.IsNull() && listOfHists.IsNull())
813 Fatal("CreateGridHandler", "No outputs defined");
815 // plugin->SetOutputArchive(outArchive);
817 // Set name of generated analysis macro
818 plugin->SetAnalysisMacro(Form("%s.C", name.Data()));
820 // Maximum number of sub-jobs
821 plugin->SetSplitMaxInputFileNumber(25);
823 // Set the Time-To-Live
824 plugin->SetTTL(70000);
826 // Re-submit failed jobs as long as the ratio of failed jobs is
827 // below this percentage.
828 plugin->SetMasterResubmitThreshold(95);
830 // Set the input format
831 plugin->SetInputFormat("xml-single");
833 // Set the name of the generated jdl
834 plugin->SetJDLName(Form("%s.jdl", name.Data()));
836 // Set the name of the generated executable
837 plugin->SetExecutable(Form("%s.sh", name.Data()));
839 // Set the job price !?
842 // Set whether to merge via JDL
843 plugin->SetMergeViaJDL(true);
846 plugin->SetFastReadOption(false);
848 // Whether to overwrite existing output
849 plugin->SetOverwriteMode(true);
851 // Set the executable binary name and options
852 plugin->SetExecutableCommand("aliroot -b -q -x");
854 // Split by storage element - must be lower case!
855 plugin->SetSplitMode("se");
859 //__________________________________________________________________
861 * Create input handler
867 AliVEventHandler* CreateInputHandler(EType type)
870 case kESD: return new AliESDInputHandler();
871 case kAOD: return new AliAODInputHandler();
875 //__________________________________________________________________
877 * Create input handler
879 * @param type Run type (ESD or AOD)
880 * @param mc Assume monte-carlo input
884 AliVEventHandler* CreateMCHandler(EType type, bool mc)
886 if (!mc || type != kESD) return 0;
887 AliMCEventHandler* mcHandler = new AliMCEventHandler();
888 mcHandler->SetReadTR(true);
891 //__________________________________________________________________
893 * Create output event handler
899 AliVEventHandler* CreateOutputHandler(EType type)
902 case kESD: // Fall through
904 AliAODHandler* ret = new AliAODHandler();
905 ret->SetOutputFileName("AliAOD.root");
911 //__________________________________________________________________
913 * Create analysis tasks
915 * @param mode Run mode
917 * @param par Whether to use pars
919 virtual void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)=0;
920 //__________________________________________________________________
922 * Connect to external services (Proof and/or grid)
924 * @param mode Running mode
926 * @return true on success
928 virtual Bool_t Connect(EMode mode)
930 if (mode == kLocal) return true;
932 // --- Set-up connections to Proof cluster and alien -------------
933 if (mode == kProof) {
934 // --- Find user name ------------------------------------------
935 TString userName(gSystem->Getenv("alien_API_USER"));
936 if (userName.IsNull()) {
937 userName = gSystem->GetUserInfo()->fUser;
939 "environment variable 'alien_API_USER' not set, using %s",
943 // --- Set prefered GSI method ---------------------------------
944 gEnv->SetValue("XSec.GSI.DelegProxy", "2");
946 // --- Now open connection to PROOF cluster --------------------
947 TProof::Open(Form("%s@%s", userName.Data(), fProofServer.Data()));
949 Error("Connect", "Failed to connect to Proof cluster %s as %s",
950 fProofServer.Data(), userName.Data());
955 // --- Open a connection to the grid -----------------------------
956 TGrid::Connect("alien://");
957 if (!gGrid || !gGrid->IsConnected()) {
958 // This is only fatal in grid mode
959 Error("Connect", "Failed to connect to AliEN");
960 if (mode == kGrid) return false;
962 if (mode == kGrid) return true;
965 // --- Set and make output directory -----------------------------
966 TString name = EscapedName();
967 TString homeDir(gGrid->GetHomeDirectory());
968 TString workDir(homeDir);
970 workDir.Append(name);
972 // Make working directory
973 if (!gGrid->Cd(workDir)) {
975 if (gGrid->Mkdir(workDir)) {
977 Info("Connect", "Directory %s created", workDir.Data());
980 // Make output directory
981 gGrid->Mkdir("proof_output");
982 gGrid->Cd("proof_output");
986 //__________________________________________________________________
988 * Load common libraries
990 * @param mode Running mode
991 * @param par If true, load as PARs
993 * @return true on success
995 Bool_t LoadCommonLibraries(EMode mode, Bool_t par)
997 if (!gSystem->Getenv("ALICE_ROOT")) {
998 Error("LoadCommonLibraries", "Local AliROOT not available");
1001 gSystem->Load("libTree.so");
1002 gSystem->Load("libGeom.so");
1003 gSystem->Load("libVMC.so");
1004 gSystem->Load("libPhysics.so");
1005 gSystem->Load("libMinuit.so");
1008 Bool_t basic = mode == kGrid ? false : par;
1010 ret &= LoadLibrary("STEERBase", mode, basic, false);
1011 ret &= LoadLibrary("ESD", mode, basic, false);
1012 ret &= LoadLibrary("AOD", mode, basic, false);
1013 ret &= LoadLibrary("ANALYSIS", mode, basic, true);
1014 ret &= LoadLibrary("ANALYSISalice", mode, basic, true);
1018 //__________________________________________________________________
1022 * @param what What library to load
1023 * @param mode Mode (local, proof, grid)
1024 * @param par If true, load as PAR
1025 * @param rec If true, also load on slaves
1027 * @return true on success
1029 Bool_t LoadLibrary(const char* what, EMode mode, Bool_t par, Bool_t rec=false)
1031 if (!what || what[0] == '\0') return true;
1033 TString module(what);
1034 TString libName(what);
1035 if (!libName.BeginsWith("lib")) libName = Form("lib%s", libName.Data());
1036 if (!libName.EndsWith(".so")) libName.Append(".so");
1041 case kLocal: // Just load and exit
1042 gSystem->Load(libName.Data());
1046 ret = SetupPAR(what) ? 0 : -1;
1047 if (rec) fListOfPARs.Add(new TObjString(what));
1049 ret = gSystem->Load(libName.Data());
1050 if (rec) fListOfLibraries.Add(new TObjString(libName));
1054 ret = gProof->UploadPackage(what);
1056 ret = gProof->UploadPackage(gSystem->ExpandPathName(Form("../%s.par",
1060 gProof->UploadPackage(gSystem
1061 ->ExpandPathName(Form("$ALICE_ROOT/%s.par",
1064 Error("LoadLibrary",
1065 "Could not find module %s.par in current directory nor "
1066 "in $ALICE_ROOT", module.Data());
1071 ret = gProof->EnablePackage(what);
1075 Error("LoadLibrary", "Couldn't load %s", what);
1081 //__________________________________________________________________
1082 Bool_t SetupPAR(const char* what)
1084 if (!what || what[0] == '\0') return -1;
1086 TString parFile(Form("%s.par", what));
1087 if (gSystem->AccessPathName(parFile.Data())) {
1088 if (gSystem->AccessPathName(Form("../%s.par", what))) {
1090 TString aliParFile =
1091 gSystem->ExpandPathName(Form("$(ALICE_ROOT)/%s.par", what));
1092 if (gSystem->AccessPathName(aliParFile.Data())) {
1093 Error("SetupPAR", "PAR file %s not found in current directory or "
1094 "$(ALICE_ROOT)", what);
1097 // Copy to current directory
1098 TFile::Cp(aliParFile, parFile);
1101 gSystem->Exec(Form("ln -s ../%s.par .", what));
1105 gSystem->Exec(Form("tar xvzf %s", parFile.Data()));
1107 // Change directory into par archive
1108 TString cwd = gSystem->WorkingDirectory();
1110 if (!gSystem->ChangeDirectory(what)) {
1111 Error("SetupPAR", "Failed to change directory to %s", what);
1116 if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
1117 Info("SetupPar", "Building in PAR archive %s", what);
1118 if (gSystem->Exec("PROOF-INF/BUILD.sh")) {
1119 Error("SetupPar", "Failed to build in PAR directory %s", what);
1120 gSystem->ChangeDirectory(cwd.Data());
1125 // Check for setup script
1126 if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
1127 Info("SetupPAR", "Setting up for PAR %s", what);
1128 gROOT->Macro("PROOF-INF/SETUP.C");
1130 if (!gSystem->ChangeDirectory(cwd.Data())) return false;
1134 //__________________________________________________________________
1135 TString SetupExtras()
1138 TIter next(&fListOfExtras);
1139 TObjString* obj = 0;
1140 while ((obj = static_cast<TObjString*>(next()))) {
1141 TString path = gSystem->ExpandPathName(obj->GetName());
1142 if (!path.BeginsWith("/"))
1143 // If not an absolute path, prepend to up-one
1144 path = Form("../%s", path.Data());
1145 if (gSystem->AccessPathName(path.Data())) {
1146 // File not accessible
1147 Warning("SetupExtras", "File %s not accessible", path.Data());
1150 ret.Append(Form("%s ", gSystem->BaseName(obj->GetName())));
1151 gSystem->Exec(Form("ln -s %s .", path.Data()));
1156 //__________________________________________________________________
1157 TString SetupSources()
1159 TString nam = EscapedName();
1161 TIter next(&fListOfSources);
1163 while ((src = next())) {
1164 TString path = gSystem->ExpandPathName(src->GetName());
1165 if (!path.BeginsWith("/"))
1166 // If not an absolute path, prepend to up-one
1167 path = Form("../%s", path.Data());
1168 if (gSystem->AccessPathName(path.Data())) {
1169 // File not accessible
1170 Warning("SetupSources", "File %s not accessible", path.Data());
1173 ret.Append(Form("%s ", gSystem->BaseName(src->GetName())));
1174 gSystem->Exec(Form("ln -s %s .", path.Data()));
1179 //__________________________________________________________________
1180 TString SetupLibraries()
1183 TIter next(&fListOfLibraries);
1185 while ((lib = next())) {
1186 ret.Append(lib->GetName());
1189 // Also add extra files to this variable
1190 ret.Append(SetupExtras());
1194 //__________________________________________________________________
1196 * Scan directory @a dir (possibly recursive) for tree files to add
1199 * @param dir Directory to scan
1200 * @param chain Chain to add to
1201 * @param type Type of tree (ESD or AOD)
1202 * @param recursive Whether to scan recursively
1204 * @return true if any files where added
1206 Bool_t ScanDirectory(TSystemDirectory* dir, TChain* chain,
1207 EType type, bool recursive)
1211 case kESD: fnPattern = "AliESD"; break;
1212 case kAOD: fnPattern = "AliAOD"; break;
1214 Info("ScanDirectory", "Now investigating %s for %s",
1215 dir->GetName(), fnPattern.Data());
1220 // Get list of files, and go back to old working directory
1221 TString oldDir(gSystem->WorkingDirectory());
1222 TList* files = dir->GetListOfFiles();
1223 gSystem->ChangeDirectory(oldDir);
1224 if (!files) return false;
1226 // Sort list of files and check if we should add it
1229 TSystemFile* file = 0;
1230 while ((file = static_cast<TSystemFile*>(next()))) {
1231 TString name(file->GetName());
1233 // Ignore special links
1234 if (name == "." || name == "..") continue;
1236 // Check if this is a directory
1237 if (file->IsDirectory()) {
1239 if (ScanDirectory(static_cast<TSystemDirectory*>(file),
1240 chain,type,recursive))
1245 // If this is not a root file, ignore
1246 if (!name.EndsWith(".root")) continue;
1248 // If this file does not contain AliESDs, ignore
1249 if (!name.Contains(fnPattern)) continue;
1252 TString fn(Form("%s/%s", file->GetTitle(), name.Data()));
1255 Info("ScanDirectory", "Adding %s", fn.Data());
1261 //__________________________________________________________________
1263 * Create a chain from an XML containing an collection
1265 * @param treeName Name of tree's
1266 * @param xmlFile XML collection
1268 * @return Newly allocated chain or null
1270 TChain* CreateChainFromXML(const char* treeName,
1271 const char* xmlFile)
1273 TGridCollection* collection = TAlienCollection::Open(xmlFile);
1275 Error("CreateChainFromXML", "Cannot create AliEn collection from "
1276 "XML file %s", xmlFile);
1280 TChain* chain = new TChain(treeName);
1281 collection->Reset();
1282 while (collection->Next()) chain->Add(collection->GetTURL(""));
1286 //__________________________________________________________________
1288 * Create a chain of data
1290 * @param type Type of data
1291 * @param mode Operation mode
1293 * @return TChain of data
1295 TChain* CreateChain(EType type, EMode mode, EOper /* oper */)
1299 case kESD: treeName = "esdTree"; break;
1300 case kAOD: treeName = "aodTree"; break;
1306 if (!fDataSet.IsNull()) break;
1307 // Otherwise fall through
1309 if (fXML.IsNull()) {
1310 chain = new TChain(treeName.Data());
1311 TString dir(fDataDir);
1312 if (!dir.BeginsWith("/")) dir = Form("../%s", dir.Data());
1313 TSystemDirectory d(dir.Data(), dir.Data());
1314 if (!ScanDirectory(&d, chain, type, true)) {
1320 chain = CreateChainFromXML(treeName.Data(), fXML.Data());
1322 case kGrid: break; // Do nothing - we use plugin
1325 if (chain && chain->GetNtrees() <= 0) {
1331 //__________________________________________________________________
1332 TString fName; // Name of analysis
1333 TString fRootVersion; // ROOT version to use
1334 TString fAliRootVersion; // AliROOT version to use
1335 TString fProofServer; // Name of proof server
1336 TString fDataDir; // Grid Input directory
1337 TString fDataSet; // Proof data set name
1338 TString fXML; // XML collection for local/proof mode
1339 TArrayI fRunNumbers; // List of run number
1340 TList fListOfPARs; // List of PAR files to use
1341 TList fListOfSources; // List of sources to upload and AcLIC
1342 TList fListOfLibraries; // List of libraries to load
1343 TList fListOfExtras; // List of extra files to upload
1344 Int_t fNReplica; // Storage replication
1346 TString fEscapedName;
1349 //====================================================================
1351 * Analysis train to make Forward and Central multiplicity
1353 * @ingroup pwg2_forward_scripts_makers
1354 * @ingroup pwg2_forward_aod
1356 class ForwardPass1 : public TrainSetup
1360 * Constructor. Date and time must be specified when running this
1361 * in Termiante mode on Grid
1363 * @param dateTime Append date and time to name
1364 * @param sys Collision system (1: pp, 2: PbPb)
1365 * @param sNN Center of mass energy [GeV]
1366 * @param field L3 magnetic field - one of {-5,0,+5} kG
1367 * @param year Year - if not specified, current year
1368 * @param month Month - if not specified, current month
1369 * @param day Day - if not specified, current day
1370 * @param hour Hour - if not specified, current hour
1371 * @param min Minutes - if not specified, current minutes
1373 ForwardPass1(UShort_t sys = 0,
1375 Bool_t dateTime = false,
1382 : TrainSetup("Forward d2Ndetadphi pass1", dateTime,
1383 year, month, day, hour, min),
1392 * @param oper Operation
1393 * @param nEvents Number of events (negative means all)
1394 * @param mc If true, assume simulated events
1395 * @param usePar If true, use PARs
1397 void Run(const char* mode, const char* oper,
1398 Int_t nEvents=-1, Bool_t mc=false,
1399 Bool_t usePar=false)
1401 EMode eMode = ParseMode(mode);
1402 EOper eOper = ParseOperation(oper);
1404 Run(eMode, eOper, nEvents, mc, usePar);
1410 * @param oper Operation
1411 * @param nEvents Number of events (negative means all)
1412 * @param mc If true, assume simulated events
1413 * @param usePar If true, use PARs
1415 void Run(EMode mode, EOper oper, Int_t nEvents=-1, Bool_t mc=false,
1416 Bool_t usePar = false)
1418 Exec(kESD, mode, oper, nEvents, mc, usePar);
1423 * @param mode Processing mode
1424 * @param par Whether to use par files
1425 * @param mgr Analysis manager
1427 void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)
1429 // --- Output file name ------------------------------------------
1430 AliAnalysisManager::SetCommonFileName("forward.root");
1432 // --- Load libraries/pars ---------------------------------------
1433 LoadLibrary("PWG2forward2", mode, par, true);
1435 // --- Set load path ---------------------------------------------
1436 gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2"
1437 gROOT->GetMacroPath()));
1439 // --- Check if this is MC ---------------------------------------
1440 Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
1442 // --- Add the task ----------------------------------------------
1443 gROOT->Macro(Form("AddTaskForwardMult(%d,%d,%d,%d).C", mc, fSys, fSNN, fField));
1450 //====================================================================
1452 * Analysis train to make @f$ dN/d\eta@f$
1454 * @ingroup pwg2_forward_scripts_makers
1455 * @ingroup pwg2_forward_dndeta
1457 class ForwardPass2 : public TrainSetup
1461 * Constructor. Date and time must be specified when running this
1462 * in Termiante mode on Grid
1464 * @param trig Trigger to use
1465 * @param vzMin Least @f$ v_z@f$
1466 * @param vzMax Largest @f$ v_z@f$
1467 * @param dateTime Append date and time to name
1468 * @param year Year - if not specified, current year
1469 * @param month Month - if not specified, current month
1470 * @param day Day - if not specified, current day
1471 * @param hour Hour - if not specified, current hour
1472 * @param min Minutes - if not specified, current minutes
1474 ForwardPass2(const char* trig="INEL",
1477 Bool_t dateTime=false,
1483 : TrainSetup("Forward d2Ndetadphi pass2", dateTime,
1484 year, month, day, hour, min),
1493 * @param oper Operation
1494 * @param nEvents Number of events (negative means all)
1495 * @param mc If true, assume simulated events
1496 * @param usePar If true, use PARs
1498 void Run(const char* mode, const char* oper,
1499 Int_t nEvents=-1, Bool_t mc=false, Bool_t usePar=false)
1501 EMode eMode = ParseMode(mode);
1502 EOper eOper = ParseOperation(oper);
1504 Run(eMode, eOper, nEvents, mc, usePar);
1510 * @param oper Operation
1511 * @param nEvents Number of events (negative means all)
1512 * @param mc If true, assume simulated events
1513 * @param usePar If true, use PARs
1515 void Run(EMode mode, EOper oper, Int_t nEvents=-1, Bool_t mc=false,
1516 Bool_t usePar=false)
1518 Exec(kESD, mode, oper, nEvents, mc, usePar);
1523 * @param mode Processing mode
1524 * @param par Whether to use par files
1525 * @param mgr Analysis manager
1527 void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)
1529 // --- Output file name ------------------------------------------
1530 AliAnalysisManager::SetCommonFileName("forward_dndeta.root");
1532 // --- Load libraries/pars ---------------------------------------
1533 LoadLibrary("PWG2forward2", mode, par, true);
1535 // --- Set load path ---------------------------------------------
1536 gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2"
1537 gROOT->GetMacroPath()));
1539 // --- Check if this is MC ---------------------------------------
1540 Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
1542 // --- Add the task ----------------------------------------------
1543 gROOT->Macro(Form("AddTaskForwarddNdeta.C(\"%s\",%f,%f)",
1544 fTrig.Data(), fVzMin, fVzMax));
1551 //====================================================================
1553 * Analysis train to do energy loss fits
1555 * @ingroup pwg2_forward_scripts_makers
1557 class ForwardELoss : public TrainSetup
1561 * Constructor. Date and time must be specified when running this
1562 * in Termiante mode on Grid
1564 * @param dateTime Append date and time to name
1566 * @param month Month
1569 * @param min Minutes
1571 ForwardELoss(Bool_t dateTime,
1577 : TrainSetup("Forward energy loss", dateTime,
1578 year, month, day, hour, min)
1584 * @param oper Operation
1585 * @param nEvents Number of events (negative means all)
1586 * @param mc If true, assume simulated events
1588 void Run(const char* mode, const char* oper,
1589 Int_t nEvents=-1, Bool_t mc=false)
1591 EMode eMode = ParseMode(mode);
1592 EOper eOper = ParseOperation(oper);
1594 Run(eMode, eOper, nEvents, mc);
1600 * @param oper Operation
1601 * @param nEvents Number of events (negative means all)
1602 * @param mc If true, assume simulated events
1604 void Run(EMode mode, EOper oper, Int_t nEvents=-1, Bool_t mc=false)
1606 Exec(kESD, mode, oper, nEvents, mc, true);
1611 * @param mode Processing mode
1612 * @param par Whether to use par files
1613 * @param mgr Analysis manager
1615 void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)
1617 // --- Output file name ------------------------------------------
1618 AliAnalysisManager::SetCommonFileName("forward_eloss.root");
1620 // --- Load libraries/pars ---------------------------------------
1621 LoadLibrary("PWG2forward2", mode, par, true);
1623 // --- Set load path ---------------------------------------------
1624 gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2"
1625 gROOT->GetMacroPath()));
1627 // --- Check if this is MC ---------------------------------------
1628 Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
1630 // --- Add the task ----------------------------------------------
1631 gROOT->Macro(Form("AddTaskForwardMultEloss.C(%d)", mc));
1635 //____________________________________________________________________