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>
39 #include <AliPhysicsSelection.h>
43 class AliAnalysisManager;
46 //====================================================================
48 * Generic set-up of an analysis train using the grid-handler (AliEn plugin).
50 * Users should define a class that derives from this. The class
51 * should implement the member function CreateTasks to add needed
56 * class MyTrain : public TrainSetup
59 * MyTrain(Bool_t dateTime = false,
65 * : TrainSetup("My train", dateTime, year, month, day, hour, min)
67 * void Run(const char* type, const char* mode, const char* oper,
68 * Int_t nEvents=-1, Bool_t mc=false,
69 * Bool_t usePar=false)
71 * Exec(type, mode, oper, nEvents, mc, usePar);
74 * void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)
76 * AliAnalysisManager::SetCommonFileName("my_analysis.root");
77 * LoadLibrary("MyAnalysis", mode, par, true);
78 * Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
79 * gROOT->Macro("MyAnalysis.C");
84 * This can then be run like
88 * Root> .L TrainSetup.C
98 * gROOT->LoadMacro("TrainSetup.C");
99 * gROOT->LoadMacro("MyTrain.C");
105 * To byte compile this, you need to
106 * - load the ROOT AliEn library
107 * - load the analysis libraries
108 * - add $ALICE_ROOT/include to header search
113 * Root> gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2:"
114 * Root> "$ALICE_ROOT/ANALYSIS/macros",
115 * Root> gROOT->GetMacroPath()));
116 * Root> gSystem->AddIncludePath("-I${ALICE_ROOT}/include");
117 * Root> gSystem->Load("libRAliEn");
118 * Root> gSystem->Load("libANALYSIS");
119 * Root> gSystem->Load("libANALYSISalice");
120 * Root> gROOT->LoadMacro("TrainSetup.C+");
123 * @ingroup pwg2_forward_scripts_makers
129 * Data type to process
132 /** Event Summary Data */
134 /** Analysis Object Data */
138 * How to run the analysis
144 /** In PROOF(-Lite) cluster */
150 * What stage of the analysis to run
154 /** Testing. Local processing, a single copied from Grid */
158 /** Submit to queue */
160 /** Merge and terminate */
166 //__________________________________________________________________
170 * @param name Name of analysis (free-form)
171 * @param useDateTime Whether to append date and time to the name
172 * @param year Year - if not specified, taken from current date
173 * @param month Month - if not specified, taken from current date
174 * @param day Day - if not specified, taken from current date
175 * @param hour Hour - if not specified, taken from current time
176 * @param min Minute - if not specified, taken from current time
178 TrainSetup(const char* name, Bool_t useDateTime=true,
179 UShort_t year=0, UShort_t month=0,
180 UShort_t day=0, UShort_t hour=0, UShort_t min=0)
182 fRootVersion("v5-28-00a"),
183 fAliRootVersion("v4-21-18-AN"),
184 fProofServer("alicecaf.cern.ch"),
185 fDataDir("/alice/data/2010/LHC10c"),
186 fDataSet("/COMMON/COMMON/LHC09a4_run8100X#/esdTree"),
196 fAllowOverwrite(kFALSE)
198 char c[] = { ' ', '/', '@', 0 };
201 fEscapedName.ReplaceAll(Form("%c", *p), "_");
206 if (year == 0 || month == 0 || day == 0) {
208 year = now.GetYear();
209 month = now.GetMonth();
211 hour = now.GetHour();
212 min = now.GetMinute();
214 fEscapedName.Append(Form("_%04d%02d%02d_%02d%02d",
215 year, month, day, hour, min));
220 //__________________________________________________________________
222 * Parse a string into a type enum
224 * @param type String to pass
225 * @param mc True on return if the string contained "MC"
227 * @return Enumaration value
229 static EType ParseType(const char* type, Bool_t& mc)
235 if (sType.Contains("MC")) mc = true;
236 if (sType.Contains("ESD")) eType = kESD;
237 else if (sType.Contains("AOD")) eType = kAOD;
239 Fatal("Run", "Unknown type '%s'", type);
243 //__________________________________________________________________
245 * Return a string that reflects the passed mode
249 * @return String representation of mode
251 static const char* ModeString(EMode eMode)
254 case kLocal: return "LOCAL";
255 case kProof: return "PROOF";
256 case kGrid: return "GRID";
260 //__________________________________________________________________
262 * Parse a string for mode specifier
264 * @param mode Mode string
266 * @return EMode value
268 static EMode ParseMode(const char* mode)
272 EMode eMode = kLocal;
273 if (sMode == "LOCAL") eMode = kLocal;
274 else if (sMode == "PROOF") eMode = kProof;
275 else if (sMode == "GRID") eMode = kGrid;
277 Fatal("Run", "Unknown mode '%s'", mode);
281 //__________________________________________________________________
283 * Return a string that reflects the passed operation
285 * @param eOper Operation
287 * @return String representation of operation
289 static const char* OperString(EOper eOper)
292 case kTest: return "TEST";
293 case kOffline: return "OFFLINE";
294 case kSubmit: return "SUBMIT";
295 case kTerminate: return "TERMINATE";
296 case kFull: return "FULL";
300 //__________________________________________________________________
302 * Parse an operation string
304 * @param oper Operation
306 * @return An EOper value
308 static EOper ParseOperation(const char* oper)
313 if (sOper == "TEST") eOper = kTest;
314 else if (sOper == "OFFLINE") eOper = kOffline;
315 else if (sOper == "SUBMIT") eOper = kSubmit;
316 else if (sOper == "TERMINATE") eOper = kTerminate;
317 else if (sOper == "FULL") eOper = kFull;
319 Fatal("Run", "unknown operation '%s'", oper);
323 //__________________________________________________________________
325 * Set ROOT version to use
329 void SetROOTVersion(const char* v) { fRootVersion = v; }
330 //__________________________________________________________________
332 * Set AliROOT version to use
336 void SetAliROOTVersion(const char* v) { fAliRootVersion = v; }
337 //__________________________________________________________________
339 * Set the proof server URL
343 void SetProofServer(const char* s) { fProofServer = s; }
344 //__________________________________________________________________
346 * Set the GRID/Local data dir
350 void SetDataDir(const char* d) { fDataDir = d; }
351 //__________________________________________________________________
353 * Set the PROOF data set
357 void SetDataSet(const char* d) { fDataSet = d; }
358 //__________________________________________________________________
360 * Set the XML file to use
364 void SetXML(const char* x) { fXML = x; }
365 //__________________________________________________________________
367 * Set how many replicas of the output we want
371 void SetNReplica(Int_t n) { fNReplica = n; }
372 //__________________________________________________________________
374 * Add a source file to be copied and byte compiled on slaves
377 * @param addToExtra If false, do not copy
379 void AddSource(const char* src, bool addToExtra=true)
381 fListOfSources.Add(new TObjString(src));
382 if (addToExtra) AddExtraFile(src); // Source code isn't copied!
384 //__________________________________________________________________
386 * Add binary data to be uploaded to slaves
388 * @param lib Name of binary file
390 void AddLibrary(const char* lib) { fListOfLibraries.Add(new TObjString(lib));}
391 //__________________________________________________________________
393 * Add a run to be analysed
395 * @param run Run number
397 void AddRun(Int_t run)
399 Int_t i = fRunNumbers.fN; fRunNumbers.Set(i+1); fRunNumbers[i] = run;
401 //__________________________________________________________________
403 * Read run numbers from a file
405 * @param filename File name
407 void ReadRunNumbers(const char* filename)
409 std::ifstream file(filename);
411 Fatal("ReadRunNumbers", "Cannot read from %s", filename);
413 while (!file.eof()) {
419 if (file.bad()) break;
423 //__________________________________________________________________
425 * Add an extra file to be uploaded to slave
427 * @param file Extra file to be uploaded
429 void AddExtraFile(const char* file)
431 if (!file || file[0] == '\0') return;
432 fListOfExtras.Add(new TObjString(file));
434 //__________________________________________________________________
436 * Set whether to allow overwritting existing files/directories
438 * @param allow If true, allow overwritting files/directories
440 void SetAllowOverwrite(Bool_t allow) { fAllowOverwrite = allow; }
441 //__________________________________________________________________
448 std::cout << fName << " train setup\n"
449 << " ROOT version: " << fRootVersion << "\n"
450 << " AliROOT version: " << fAliRootVersion << "\n"
451 << " Name of proof server: " << fProofServer << "\n"
452 << " Grid Input directory: " << fDataDir << "\n"
453 << " Proof data set name: " << fDataSet << "\n"
454 << " XML collection: " << fXML << "\n"
455 << " Storage replication: " << fNReplica << "\n"
456 << " Run numbers: " << std::flush;
457 for (Int_t i = 0; i < fRunNumbers.GetSize(); i++)
458 std::cout << (i == 0 ? "" : ", ") << fRunNumbers.At(i);
461 << " PAR files: " << std::flush;
464 TIter nextPar(&fListOfPARs);
465 while ((obj = nextPar())) {
466 std::cout << (first ? "" : ", ") << obj->GetName();
471 << " Script sources: " << std::flush;
473 TIter nextSrc(&fListOfSources);
474 while ((obj = nextSrc())) {
475 std::cout << (first ? "" : ", ") << obj->GetName();
480 << " Libraries to load: " << std::flush;
482 TIter nextLib(&fListOfLibraries);
483 while ((obj = nextLib())) {
484 std::cout << (first ? "" : ", ") << obj->GetName();
487 std::cout << std::endl;
489 AliAnalysisGrid* plugin =
490 AliAnalysisManager::GetAnalysisManager()->GetGridHandler();
496 //__________________________________________________________________
497 TrainSetup(const TrainSetup& o)
499 fRootVersion(o.fRootVersion),
500 fAliRootVersion(o.fAliRootVersion),
501 fProofServer(o.fProofServer),
502 fDataDir(o.fDataDir),
503 fDataSet(o.fDataSet),
505 fRunNumbers(o.fRunNumbers),
510 fNReplica(o.fNReplica),
514 TIter nextPar(&o.fListOfPARs);
515 while ((obj = nextPar())) fListOfPARs.Add(obj->Clone());
516 TIter nextSrc(&o.fListOfSources);
517 while ((obj = nextSrc())) fListOfSources.Add(obj->Clone());
518 TIter nextLib(&o.fListOfLibraries);
519 while ((obj = nextLib())) fListOfLibraries.Add(obj->Clone());
520 TIter nextExa(&o.fListOfExtras);
521 while ((obj = nextExa())) fListOfExtras.Add(obj->Clone());
523 //__________________________________________________________________
524 TrainSetup& operator=(const TrainSetup& o)
527 fRootVersion = o.fRootVersion;
528 fAliRootVersion = o.fAliRootVersion;
529 fProofServer = o.fProofServer;
530 fDataDir = o.fDataDir;
531 fDataSet = o.fDataSet;
533 fNReplica = o.fNReplica;
534 fESDPass = o.fESDPass;
535 fRunNumbers = o.fRunNumbers;
537 TIter nextPar(&o.fListOfPARs);
538 while ((obj = nextPar())) fListOfPARs.Add(obj->Clone());
539 TIter nextSrc(&o.fListOfSources);
540 while ((obj = nextSrc())) fListOfSources.Add(obj->Clone());
541 TIter nextLib(&o.fListOfLibraries);
542 while ((obj = nextLib())) fListOfLibraries.Add(obj->Clone());
543 TIter nextExa(&o.fListOfExtras);
544 while ((obj = nextExa())) fListOfExtras.Add(obj->Clone());
549 //__________________________________________________________________
553 * @param type Type of input for analysis (kESD, kAOD)
554 * @param mode Mode of job (kLocal, kProof, kGrid)
555 * @param oper Operation
556 * @param nEvents Number of events to analyse (<0 means all)
557 * @param mc Whether to connect MC data
558 * @param usePar Whether to use PARs
559 * @param dbg Debug level
561 void Exec(const char* type,
562 const char* mode="GRID",
563 const char* oper="FULL",
569 EType eType = ParseType(type, mc);
570 EMode eMode = ParseMode(mode);
571 EOper eOper = ParseOperation(oper);
573 Exec(eType, eMode, eOper, nEvents, mc, usePar, dbg);
576 //__________________________________________________________________
580 * @param type Type of input for analysis (kESD, kAOD)
581 * @param mode Mode of job (kLocal, kProof, kGrid)
582 * @param oper Operation
583 * @param nEvents Number of events to analyse (<0 means all)
584 * @param mc Whether to connect MC data
585 * @param usePar Whether to use PARs
586 * @param dbg Debug level
588 void Exec(EType type,
596 if (mode == kProof) usePar = true;
598 if (!Connect(mode)) return;
600 TString cwd = gSystem->WorkingDirectory();
601 TString nam = EscapedName();
602 if (oper != kTerminate) {
603 if (!fAllowOverwrite && !gSystem->AccessPathName(nam.Data())) {
604 Error("Exec", "File/directory %s already exists", nam.Data());
607 if (gSystem->AccessPathName(nam.Data())) {
608 if (gSystem->MakeDirectory(nam.Data())) {
609 Error("Exec", "Failed to make directory %s", nam.Data());
615 if (gSystem->AccessPathName(nam.Data())) {
616 Error("Exec", "File/directory %s does not exists", nam.Data());
621 if (!gSystem->ChangeDirectory(nam.Data())) {
622 Error("Exec", "Failed to change directory to %s", nam.Data());
625 Info("Exec", "Made subdirectory %s, and cd'ed there", nam.Data());
627 if (!LoadCommonLibraries(mode, usePar)) return;
629 // --- Create analysis manager -----------------------------------
630 AliAnalysisManager *mgr = new AliAnalysisManager(fName,"Analysis Train");
632 // In test mode, collect system information on every event
633 // if (oper == kTest) mgr->SetNSysInfo(1);
634 if (dbg > 0) mgr->SetDebugLevel(dbg);
635 if (mode == kLocal) mgr->SetUseProgressBar(kTRUE, 100);
637 // --- ESD input handler ------------------------------------------
638 AliVEventHandler* inputHandler = CreateInputHandler(type);
639 if (inputHandler) mgr->SetInputEventHandler(inputHandler);
641 // --- Monte-Carlo ------------------------------------------------
642 AliVEventHandler* mcHandler = CreateMCHandler(type,mc);
643 if (mcHandler) mgr->SetMCtruthEventHandler(mcHandler);
645 // --- AOD output handler -----------------------------------------
646 AliVEventHandler* outputHandler = CreateOutputHandler(type);
647 if (outputHandler) mgr->SetOutputEventHandler(outputHandler);
649 // --- Include analysis macro path in search path ----------------
650 gROOT->SetMacroPath(Form("%s:$ALICE_ROOT/ANALYSIS/macros",
651 gROOT->GetMacroPath()));
653 // --- Physics selction ------------------------------------------
654 CreatePhysicsSelection(mc, mgr);
656 // --- Create tasks ----------------------------------------------
657 CreateTasks(mode, usePar, mgr);
659 // --- Create Grid handler ----------------------------------------
660 // _must_ be done after all tasks has been added
661 AliAnalysisAlien* gridHandler = CreateGridHandler(type, mode, oper);
662 if (gridHandler) mgr->SetGridHandler(gridHandler);
664 // --- Create the chain ------------------------------------------
665 TChain* chain = CreateChain(type, mode, oper);
667 // --- Print setup -----------------------------------------------
670 // --- Initialise the train --------------------------------------
671 if (!mgr->InitAnalysis()) {
672 gSystem->ChangeDirectory(cwd.Data());
673 Fatal("Run","Failed to initialise train");
676 // --- Show status -----------------------------------------------
679 Long64_t ret = StartAnalysis(mgr, mode, chain, nEvents);
681 // Make sure we go back
682 gSystem->ChangeDirectory(cwd.Data());
684 if (ret < 0) Fatal("Exec", "Analysis failed");
686 //__________________________________________________________________
690 * @param mgr Analysis manager
691 * @param mode Run mode
692 * @param chain Input data (local and proof only)
693 * @param nEvents Number of events to analyse
695 Long64_t StartAnalysis(AliAnalysisManager* mgr,
700 // --- Run the analysis ------------------------------------------
704 Error("StartAnalysis", "No chain defined");
707 if (nEvents < 0) nEvents = chain->GetEntries();
708 return mgr->StartAnalysis(ModeString(mode), chain, nEvents);
710 if (fDataSet.IsNull()) {
712 Error("StartAnalysis", "No chain defined");
715 if (nEvents < 0) nEvents = chain->GetEntries();
716 return mgr->StartAnalysis(ModeString(mode), chain, nEvents);
718 return mgr->StartAnalysis(ModeString(mode), fDataSet);
721 return mgr->StartAnalysis(ModeString(mode));
722 return mgr->StartAnalysis(ModeString(mode), nEvents);
724 // We should never get here
727 //__________________________________________________________________
729 * Return the escaped name
732 * @return Escaped name
734 const TString& EscapedName() const
738 //__________________________________________________________________
740 * Create a grid handler
742 * @param type Data type
743 * @param mode Run mode
744 * @param oper Operation
746 * @return Grid handler
748 virtual AliAnalysisAlien* CreateGridHandler(EType type, EMode mode, EOper oper)
750 if (mode != kGrid) return 0;
752 TString name = EscapedName();
754 // Create the plug-in object, and set run mode
755 AliAnalysisAlien* plugin = new AliAnalysisAlien();
756 plugin->SetRunMode(OperString(oper));
758 // Production mode - not used here
759 // plugin->SetProductionMode();
761 // Set output to be per run
762 plugin->SetOutputToRunNo();
765 plugin->SetJobTag(fName);
767 // Set number of test files - used in test mode only
768 plugin->SetNtestFiles(1);
770 // Set required version of software
771 plugin->SetAPIVersion("V1.1x");
772 plugin->SetROOTVersion(fRootVersion);
773 plugin->SetAliROOTVersion(fAliRootVersion);
776 plugin->SetKeepLogs();
778 // Declare root of input data directory
779 plugin->SetGridDataDir(fDataDir);
781 // Data search patterns
782 if (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler())
783 plugin->SetRunPrefix("");
785 plugin->SetRunPrefix("000");
786 plugin->SetDataPattern(Form("*ESDs/pass%d/*/*%s.root",
787 fESDPass, type == kESD ? "ESDs" : "AOD"));
789 // Add the run numbers
790 for (Int_t i = 0; i < fRunNumbers.fN; i++) {
791 if (fRunNumbers[i] < 0) continue;
792 plugin->AddRunNumber(fRunNumbers[i]);
795 // Set the working directory to be the trains name (with special
796 // characters replaced by '_' and the date appended), and also set
797 // the output directory (relative to working directory)
798 plugin->SetGridWorkingDir(name.Data());
799 plugin->SetGridOutputDir("output");
801 // Enable configured PARs
802 TIter nextPar(&fListOfPARs);
804 while ((parName = nextPar()))
805 plugin->EnablePackage(parName->GetName());
807 // Add sources that need to be compiled on the workers using
809 TString addSources = SetupSources();
810 if (!addSources.IsNull()) plugin->SetAnalysisSource(addSources.Data());
812 // Add binary libraries that should be uploaded to the workers
813 TString addLibs = SetupLibraries();
814 if (!addLibs.IsNull()) plugin->SetAdditionalLibs(addLibs.Data());
816 // Disable default outputs
817 plugin->SetDefaultOutputs(true);
820 plugin->SetMaxMergeFiles(20);
821 plugin->SetMergeExcludes("AliAOD.root "
822 "EventStat_temp.root "
823 "*event_stat*.root");
825 // Set number of runs per master - set to one to per run
826 plugin->SetNrunsPerMaster(1);
828 // Loop over defined containers in the analysis manager,
829 // and declare these as outputs
830 TString listOfAODs = "";
831 TString listOfHists = "";
832 AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
833 AliAnalysisDataContainer* cont = 0;
834 TIter nextCont(mgr->GetOutputs());
835 while ((cont = static_cast<AliAnalysisDataContainer*>(nextCont()))) {
836 TString outName(cont->GetFileName());
837 TString& list = (outName == "default" ? listOfAODs : listOfHists);
838 if (outName == "default") {
839 if (!mgr->GetOutputEventHandler()) continue;
841 outName = mgr->GetOutputEventHandler()->GetOutputFileName();
843 if (list.Contains(outName)) continue;
844 if (!list.IsNull()) list.Append(",");
845 list.Append(outName);
847 if (!mgr->GetExtraFiles().IsNull()) {
848 if (!listOfAODs.IsNull()) listOfAODs.Append("+");
849 TString extra = mgr->GetExtraFiles();
850 extra.ReplaceAll(" ", ",");
851 listOfAODs.Append(extra);
853 TString outArchive = Form("stderr, stdout@disk=%d", fNReplica);
854 if (!listOfHists.IsNull())
855 outArchive.Append(Form(" hist_archive.zip:%s@disk=%d",
856 listOfHists.Data(), fNReplica));
857 if (!listOfAODs.IsNull())
858 outArchive.Append(Form(" aod_archive.zip:%s@disk=%d",
859 listOfAODs.Data(), fNReplica));
860 if (listOfAODs.IsNull() && listOfHists.IsNull())
861 Fatal("CreateGridHandler", "No outputs defined");
863 // plugin->SetOutputArchive(outArchive);
865 // Set name of generated analysis macro
866 plugin->SetAnalysisMacro(Form("%s.C", name.Data()));
868 // Maximum number of sub-jobs
869 // plugin->SetSplitMaxInputFileNumber(25);
871 // Set the Time-To-Live
872 plugin->SetTTL(70000);
874 // Re-submit failed jobs as long as the ratio of failed jobs is
875 // below this percentage.
876 plugin->SetMasterResubmitThreshold(95);
878 // Set the input format
879 plugin->SetInputFormat("xml-single");
881 // Set the name of the generated jdl
882 plugin->SetJDLName(Form("%s.jdl", name.Data()));
884 // Set the name of the generated executable
885 plugin->SetExecutable(Form("%s.sh", name.Data()));
887 // Set the job price !?
890 // Set whether to merge via JDL
891 plugin->SetMergeViaJDL(true);
894 plugin->SetFastReadOption(false);
896 // Whether to overwrite existing output
897 plugin->SetOverwriteMode(true);
899 // Set the executable binary name and options
900 plugin->SetExecutableCommand("aliroot -b -q -x");
902 // Split by storage element - must be lower case!
903 plugin->SetSplitMode("se");
907 //__________________________________________________________________
909 * Create input handler
915 virtual AliVEventHandler* CreateInputHandler(EType type)
918 case kESD: return new AliESDInputHandler();
919 case kAOD: return new AliAODInputHandler();
923 //__________________________________________________________________
925 * Create input handler
927 * @param type Run type (ESD or AOD)
928 * @param mc Assume monte-carlo input
932 virtual AliVEventHandler* CreateMCHandler(EType type, bool mc)
934 if (!mc || type != kESD) return 0;
935 AliMCEventHandler* mcHandler = new AliMCEventHandler();
936 mcHandler->SetReadTR(true);
939 //__________________________________________________________________
941 * Create output event handler
947 virtual AliVEventHandler* CreateOutputHandler(EType type)
950 case kESD: // Fall through
952 AliAODHandler* ret = new AliAODHandler();
953 ret->SetOutputFileName("AliAOD.root");
959 //__________________________________________________________________
961 * Create physics selection , and add to manager
963 * @param mc Whether this is for MC
966 virtual void CreatePhysicsSelection(Bool_t mc,
967 AliAnalysisManager* mgr)
969 gROOT->Macro(Form("AddTaskPhysicsSelection.C(%d)", mc));
970 mgr->RegisterExtraFile("event_stat.root");
972 //__________________________________________________________________
974 * Create analysis tasks
976 * @param mode Run mode
978 * @param par Whether to use pars
980 virtual void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)=0;
981 //__________________________________________________________________
983 * Connect to external services (Proof and/or grid)
985 * @param mode Running mode
987 * @return true on success
989 virtual Bool_t Connect(EMode mode)
991 if (mode == kLocal) return true;
993 // --- Set-up connections to Proof cluster and alien -------------
994 if (mode == kProof) {
995 // --- Find user name ------------------------------------------
996 TString userName(gSystem->Getenv("alien_API_USER"));
997 if (userName.IsNull()) {
998 userName = gSystem->GetUserInfo()->fUser;
1000 "environment variable 'alien_API_USER' not set, using %s",
1004 // --- Set prefered GSI method ---------------------------------
1005 gEnv->SetValue("XSec.GSI.DelegProxy", "2");
1007 // --- Now open connection to PROOF cluster --------------------
1009 Bool_t lite = false;
1010 if (fProofServer.BeginsWith("workers=") || fProofServer.IsNull()) {
1012 serv = fProofServer;
1015 serv = Form("%s@%s", userName.Data(), fProofServer.Data());
1018 Error("Connect", "Failed to connect to Proof cluster %s as %s",
1019 fProofServer.Data(), userName.Data());
1022 if (lite) return true;
1025 // --- Open a connection to the grid -----------------------------
1026 TGrid::Connect("alien://");
1027 if (!gGrid || !gGrid->IsConnected()) {
1028 // This is only fatal in grid mode
1029 Error("Connect", "Failed to connect to AliEN");
1030 if (mode == kGrid) return false;
1033 if (mode == kGrid) return true;
1036 // --- Set and make output directory -----------------------------
1037 TString name = EscapedName();
1038 TString homeDir(gGrid->GetHomeDirectory());
1039 TString workDir(homeDir);
1040 workDir.Append("/");
1041 workDir.Append(name);
1043 // Make working directory
1044 if (!gGrid->Cd(workDir)) {
1046 if (gGrid->Mkdir(workDir)) {
1048 Info("Connect", "Directory %s created", workDir.Data());
1051 // Make output directory
1052 gGrid->Mkdir("proof_output");
1053 gGrid->Cd("proof_output");
1057 //__________________________________________________________________
1059 * Load common libraries
1061 * @param mode Running mode
1062 * @param par If true, load as PARs
1064 * @return true on success
1066 Bool_t LoadCommonLibraries(EMode mode, Bool_t par)
1068 if (!gSystem->Getenv("ALICE_ROOT")) {
1069 Error("LoadCommonLibraries", "Local AliROOT not available");
1072 gSystem->Load("libTree.so");
1073 gSystem->Load("libGeom.so");
1074 gSystem->Load("libVMC.so");
1075 gSystem->Load("libPhysics.so");
1076 gSystem->Load("libMinuit.so");
1079 Bool_t basic = mode == kGrid ? false : par;
1081 ret &= LoadLibrary("STEERBase", mode, basic, false);
1082 ret &= LoadLibrary("ESD", mode, basic, false);
1083 ret &= LoadLibrary("AOD", mode, basic, false);
1084 ret &= LoadLibrary("ANALYSIS", mode, basic, true);
1085 ret &= LoadLibrary("ANALYSISalice", mode, basic, true);
1089 //__________________________________________________________________
1093 * @param what What library to load
1094 * @param mode Mode (local, proof, grid)
1095 * @param par If true, load as PAR
1096 * @param rec If true, also load on slaves
1098 * @return true on success
1100 Bool_t LoadLibrary(const char* what, EMode mode, Bool_t par, Bool_t rec=false)
1102 if (!what || what[0] == '\0') return true;
1104 TString module(what);
1105 TString libName(what);
1106 if (!libName.BeginsWith("lib")) libName = Form("lib%s", libName.Data());
1107 if (!libName.EndsWith(".so")) libName.Append(".so");
1112 case kLocal: // Just load and exit
1113 gSystem->Load(libName.Data());
1117 ret = SetupPAR(what) ? 0 : -1;
1118 if (rec) fListOfPARs.Add(new TObjString(what));
1120 ret = gSystem->Load(libName.Data());
1121 if (rec) fListOfLibraries.Add(new TObjString(libName));
1125 ret = gProof->UploadPackage(what);
1127 ret = gProof->UploadPackage(gSystem->ExpandPathName(Form("../%s.par",
1131 gProof->UploadPackage(gSystem
1132 ->ExpandPathName(Form("$ALICE_ROOT/%s.par",
1135 Error("LoadLibrary",
1136 "Could not find module %s.par in current directory nor "
1137 "in $ALICE_ROOT", module.Data());
1142 ret = gProof->EnablePackage(what);
1146 Error("LoadLibrary", "Couldn't load %s", what);
1152 //__________________________________________________________________
1153 Bool_t SetupPAR(const char* what)
1155 if (!what || what[0] == '\0') return -1;
1157 TString parFile(Form("%s.par", what));
1158 if (gSystem->AccessPathName(parFile.Data())) {
1159 if (gSystem->AccessPathName(Form("../%s.par", what))) {
1161 TString aliParFile =
1162 gSystem->ExpandPathName(Form("$(ALICE_ROOT)/%s.par", what));
1163 if (gSystem->AccessPathName(aliParFile.Data())) {
1164 Error("SetupPAR", "PAR file %s not found in current directory or "
1165 "$(ALICE_ROOT)", what);
1168 // Copy to current directory
1169 TFile::Cp(aliParFile, parFile);
1172 gSystem->Exec(Form("ln -s ../%s.par .", what));
1176 gSystem->Exec(Form("tar xvzf %s", parFile.Data()));
1178 // Change directory into par archive
1179 TString cwd = gSystem->WorkingDirectory();
1181 if (!gSystem->ChangeDirectory(what)) {
1182 Error("SetupPAR", "Failed to change directory to %s", what);
1187 if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
1188 Info("SetupPar", "Building in PAR archive %s", what);
1189 if (gSystem->Exec("PROOF-INF/BUILD.sh")) {
1190 Error("SetupPar", "Failed to build in PAR directory %s", what);
1191 gSystem->ChangeDirectory(cwd.Data());
1196 // Check for setup script
1197 if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
1198 Info("SetupPAR", "Setting up for PAR %s", what);
1199 gROOT->Macro("PROOF-INF/SETUP.C");
1201 if (!gSystem->ChangeDirectory(cwd.Data())) return false;
1205 //__________________________________________________________________
1206 TString SetupExtras()
1209 TIter next(&fListOfExtras);
1210 TObjString* obj = 0;
1211 while ((obj = static_cast<TObjString*>(next()))) {
1212 TString path = gSystem->ExpandPathName(obj->GetName());
1213 if (!path.BeginsWith("/"))
1214 // If not an absolute path, prepend to up-one
1215 path = Form("../%s", path.Data());
1216 if (gSystem->AccessPathName(path.Data())) {
1217 // File not accessible
1218 Warning("SetupExtras", "File %s not accessible", path.Data());
1221 ret.Append(Form("%s ", gSystem->BaseName(obj->GetName())));
1222 gSystem->Exec(Form("ln -s %s .", path.Data()));
1227 //__________________________________________________________________
1228 TString SetupSources()
1230 TString nam = EscapedName();
1232 TIter next(&fListOfSources);
1234 while ((src = next())) {
1235 TString path = gSystem->ExpandPathName(src->GetName());
1236 if (!path.BeginsWith("/"))
1237 // If not an absolute path, prepend to up-one
1238 path = Form("../%s", path.Data());
1239 if (gSystem->AccessPathName(path.Data())) {
1240 // File not accessible
1241 Warning("SetupSources", "File %s not accessible", path.Data());
1244 ret.Append(Form("%s ", gSystem->BaseName(src->GetName())));
1245 gSystem->Exec(Form("ln -s %s .", path.Data()));
1250 //__________________________________________________________________
1251 TString SetupLibraries()
1254 TIter next(&fListOfLibraries);
1256 while ((lib = next())) {
1257 ret.Append(lib->GetName());
1260 // Also add extra files to this variable
1261 ret.Append(SetupExtras());
1265 //__________________________________________________________________
1267 * Scan directory @a dir (possibly recursive) for tree files to add
1270 * @param dir Directory to scan
1271 * @param chain Chain to add to
1272 * @param type Type of tree (ESD or AOD)
1273 * @param recursive Whether to scan recursively
1275 * @return true if any files where added
1277 Bool_t ScanDirectory(TSystemDirectory* dir, TChain* chain,
1278 EType type, bool recursive)
1282 case kESD: fnPattern = "AliESD"; break;
1283 case kAOD: fnPattern = "AliAOD"; break;
1285 Info("ScanDirectory", "Now investigating %s for %s",
1286 dir->GetName(), fnPattern.Data());
1291 // Get list of files, and go back to old working directory
1292 TString oldDir(gSystem->WorkingDirectory());
1293 TList* files = dir->GetListOfFiles();
1294 gSystem->ChangeDirectory(oldDir);
1295 if (!files) return false;
1297 // Sort list of files and check if we should add it
1300 TSystemFile* file = 0;
1301 while ((file = static_cast<TSystemFile*>(next()))) {
1302 TString name(file->GetName());
1304 // Ignore special links
1305 if (name == "." || name == "..") {
1306 Info("ScanDirectory", "Ignoring %s", name.Data());
1309 Info("ScanDirectory", "Looking at %s", name.Data());
1311 // Check if this is a directory
1312 if (file->IsDirectory()) {
1314 if (ScanDirectory(static_cast<TSystemDirectory*>(file),
1315 chain,type,recursive))
1319 Info("ScanDirectory",
1320 "%s is a directory but we're not scanning recusively",
1325 // If this is not a root file, ignore
1326 if (!name.EndsWith(".root")) continue;
1328 // If this file does not contain AliESDs, ignore
1329 if (!name.Contains(fnPattern)) continue;
1332 TString fn(Form("%s/%s", file->GetTitle(), name.Data()));
1335 Info("ScanDirectory", "Adding %s", fn.Data());
1341 //__________________________________________________________________
1343 * Create a chain from an XML containing an collection
1345 * @param treeName Name of tree's
1346 * @param xmlFile XML collection
1348 * @return Newly allocated chain or null
1350 TChain* CreateChainFromXML(const char* treeName,
1351 const char* xmlFile)
1353 TGridCollection* collection = TAlienCollection::Open(xmlFile);
1355 Error("CreateChainFromXML", "Cannot create AliEn collection from "
1356 "XML file %s", xmlFile);
1360 TChain* chain = new TChain(treeName);
1361 collection->Reset();
1362 while (collection->Next()) chain->Add(collection->GetTURL(""));
1366 //__________________________________________________________________
1368 * Create a chain of data
1370 * @param type Type of data
1371 * @param mode Operation mode
1373 * @return TChain of data
1375 TChain* CreateChain(EType type, EMode mode, EOper /* oper */)
1379 case kESD: treeName = "esdTree"; break;
1380 case kAOD: treeName = "aodTree"; break;
1386 if (!fDataSet.IsNull()) break;
1387 // Otherwise fall through
1389 if (fXML.IsNull()) {
1390 chain = new TChain(treeName.Data());
1391 TString dir(fDataDir);
1392 if (!dir.BeginsWith("/")) dir = Form("../%s", dir.Data());
1393 TSystemDirectory d(dir.Data(), dir.Data());
1394 if (!ScanDirectory(&d, chain, type, true)) {
1400 chain = CreateChainFromXML(treeName.Data(), fXML.Data());
1402 case kGrid: break; // Do nothing - we use plugin
1405 if (chain && chain->GetNtrees() <= 0) {
1411 //__________________________________________________________________
1412 TString fName; // Name of analysis
1413 TString fRootVersion; // ROOT version to use
1414 TString fAliRootVersion; // AliROOT version to use
1415 TString fProofServer; // Name of proof server
1416 TString fDataDir; // Grid Input directory
1417 TString fDataSet; // Proof data set name
1418 TString fXML; // XML collection for local/proof mode
1419 TArrayI fRunNumbers; // List of run number
1420 TList fListOfPARs; // List of PAR files to use
1421 TList fListOfSources; // List of sources to upload and AcLIC
1422 TList fListOfLibraries; // List of libraries to load
1423 TList fListOfExtras; // List of extra files to upload
1424 Int_t fNReplica; // Storage replication
1426 TString fEscapedName;
1427 Bool_t fAllowOverwrite;
1430 //====================================================================
1432 * Analysis train to do energy loss fits
1434 * @ingroup pwg2_forward_scripts_makers
1436 class ForwardELoss : public TrainSetup
1440 * Constructor. Date and time must be specified when running this
1441 * in Termiante mode on Grid
1443 * @param dateTime Append date and time to name
1445 * @param month Month
1448 * @param min Minutes
1450 ForwardELoss(Bool_t dateTime,
1456 : TrainSetup("Forward energy loss", dateTime,
1457 year, month, day, hour, min)
1463 * @param oper Operation
1464 * @param nEvents Number of events (negative means all)
1465 * @param mc If true, assume simulated events
1467 void Run(const char* mode, const char* oper,
1468 Int_t nEvents=-1, Bool_t mc=false)
1470 EMode eMode = ParseMode(mode);
1471 EOper eOper = ParseOperation(oper);
1473 Run(eMode, eOper, nEvents, mc);
1479 * @param oper Operation
1480 * @param nEvents Number of events (negative means all)
1481 * @param mc If true, assume simulated events
1483 void Run(EMode mode, EOper oper, Int_t nEvents=-1, Bool_t mc=false)
1485 Exec(kESD, mode, oper, nEvents, mc, true);
1490 * @param mode Processing mode
1491 * @param par Whether to use par files
1492 * @param mgr Analysis manager
1494 void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)
1496 // --- Output file name ------------------------------------------
1497 AliAnalysisManager::SetCommonFileName("forward_eloss.root");
1499 // --- Load libraries/pars ---------------------------------------
1500 LoadLibrary("PWG2forward2", mode, par, true);
1502 // --- Set load path ---------------------------------------------
1503 gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2",
1504 gROOT->GetMacroPath()));
1506 // --- Check if this is MC ---------------------------------------
1507 Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
1509 // --- Add the task ----------------------------------------------
1510 gROOT->Macro(Form("AddTaskForwardMultEloss.C(%d)", mc));
1514 //====================================================================
1516 * Analysis train to make Forward and Central multiplicity
1518 * @ingroup pwg2_forward_scripts_makers
1519 * @ingroup pwg2_forward_aod
1521 class MakeAODTrain : public TrainSetup
1525 * Constructor. Date and time must be specified when running this
1526 * in Termiante mode on Grid
1528 * @param name Name of train (free form)
1529 * @param sys Collision system (1: pp, 2: PbPb)
1530 * @param sNN Center of mass energy [GeV]
1531 * @param field L3 magnetic field - one of {-5,0,+5} kG
1532 * @param useCent Whether to use centrality
1533 * @param dateTime Append date and time to name
1534 * @param year Year - if not specified, current year
1535 * @param month Month - if not specified, current month
1536 * @param day Day - if not specified, current day
1537 * @param hour Hour - if not specified, current hour
1538 * @param min Minutes - if not specified, current minutes
1540 MakeAODTrain(const char* name,
1544 Bool_t useCent = false,
1545 Bool_t dateTime = false,
1551 : TrainSetup(name, dateTime,
1552 year, month, day, hour, min),
1562 * @param oper Operation
1563 * @param nEvents Number of events (negative means all)
1564 * @param mc If true, assume simulated events
1565 * @param usePar If true, use PARs
1567 void Run(const char* mode, const char* oper,
1568 Int_t nEvents=-1, Bool_t mc=false,
1569 Bool_t usePar=false)
1571 Exec("ESD", mode, oper, nEvents, mc, usePar);
1577 * @param oper Operation
1578 * @param nEvents Number of events (negative means all)
1579 * @param mc If true, assume simulated events
1580 * @param usePar If true, use PARs
1582 void Run(EMode mode, EOper oper, Int_t nEvents=-1, Bool_t mc=false,
1583 Bool_t usePar = false)
1585 Exec(kESD, mode, oper, nEvents, mc, usePar);
1591 * @param mode Processing mode
1592 * @param par Whether to use par files
1593 * @param mgr Analysis manager
1595 void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)
1597 // --- Output file name ------------------------------------------
1598 AliAnalysisManager::SetCommonFileName("forward.root");
1600 // --- Load libraries/pars ---------------------------------------
1601 LoadLibrary("PWG2forward2", mode, par, true);
1603 // --- Set load path ---------------------------------------------
1604 gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2",
1605 gROOT->GetMacroPath()));
1607 // --- Check if this is MC ---------------------------------------
1608 Bool_t mc = mgr->GetMCtruthEventHandler() != 0;
1610 // --- Centrality ------------------------------------------------
1611 if (fUseCent) gROOT->Macro("AddTaskCentrality.C");
1613 // --- Add the task ----------------------------------------------
1614 gROOT->Macro(Form("AddTaskForwardMult.C(%d,%d,%d,%d)",
1615 mc, fSys, fSNN, fField));
1616 AddExtraFile(gSystem->Which(gROOT->GetMacroPath(), "ForwardAODConfig.C"));
1618 // --- Add the task ----------------------------------------------
1619 gROOT->Macro(Form("AddTaskCentralMult.C(%d,%d,%d)",
1620 fSys, fSNN, fField));
1622 //__________________________________________________________________
1624 * Create physics selection , and add to manager
1626 * @param mc Whether this is for MC
1627 * @param mgr Manager
1629 void CreatePhysicsSelection(Bool_t mc,
1630 AliAnalysisManager* mgr)
1632 gROOT->Macro(Form("AddTaskPhysicsSelection.C(%d)", mc));
1633 mgr->RegisterExtraFile("event_stat.root");
1635 // --- Get input event handler -----------------------------------
1636 AliInputEventHandler* ih =
1637 static_cast<AliInputEventHandler*>(mgr->GetInputEventHandler());
1639 // --- Get Physics selection -------------------------------------
1640 AliPhysicsSelection* ps =
1641 static_cast<AliPhysicsSelection*>(ih->GetEventSelection());
1643 // --- Ignore trigger class when selecting events. This means ---
1644 // --- that we get offline+(A,C,E) events too --------------------
1645 ps->SetSkipTriggerClassSelection(true);
1652 //====================================================================
1654 * Analysis train to make @f$ dN/d\eta@f$
1656 * @ingroup pwg2_forward_scripts_makers
1657 * @ingroup pwg2_forward_dndeta
1659 class MakedNdetaTrain : public TrainSetup
1663 * Constructor. Date and time must be specified when running this
1664 * in Termiante mode on Grid
1666 * @param name Name of train (free form)
1667 * @param trig Trigger to use
1668 * @param vzMin Least @f$ v_z@f$
1669 * @param vzMax Largest @f$ v_z@f$
1670 * @param scheme Normalisation scheme
1671 * @param useCent Whether to use centrality
1672 * @param dateTime Append date and time to name
1673 * @param year Year - if not specified, current year
1674 * @param month Month - if not specified, current month
1675 * @param day Day - if not specified, current day
1676 * @param hour Hour - if not specified, current hour
1677 * @param min Minutes - if not specified, current minutes
1679 MakedNdetaTrain(const char* name,
1680 const char* trig="INEL",
1683 const char* scheme="FULL",
1684 Bool_t useCent=false,
1685 Bool_t dateTime=false,
1691 : TrainSetup(name, dateTime, year, month, day, hour, min),
1702 * @param oper Operation
1703 * @param nEvents Number of events (negative means all)
1704 * @param usePar If true, use PARs
1706 void Run(const char* mode, const char* oper,
1707 Int_t nEvents=-1, Bool_t usePar=false)
1709 Exec("AOD", mode, oper, nEvents, false, usePar);
1715 * @param oper Operation
1716 * @param nEvents Number of events (negative means all)
1717 * @param usePar If true, use PARs
1719 void Run(EMode mode, EOper oper, Int_t nEvents=-1,
1720 Bool_t usePar=false)
1722 Exec(kAOD, mode, oper, nEvents, false, usePar);
1725 * Set the trigger to use (INEL, INEL>0, NSD)
1727 * @param trig Trigger to use
1729 void SetTrigger(const char* trig) { fTrig = trig; }
1731 * Set the vertex range to accept
1733 * @param min Minimum
1734 * @param max Maximum
1736 void SetVertexRange(Double_t min, Double_t max) { fVzMin=min; fVzMax=max; }
1738 * Set the normalisation scheme
1740 * @param scheme Normalisation scheme options
1742 void SetScheme(const char* scheme) { fScheme = scheme; }
1744 * Whether to use centrality or not
1746 * @param use To use the centrality
1748 void SetUseCentrality(Bool_t use) { fUseCent = use; }
1753 * @param mode Processing mode
1754 * @param par Whether to use par files
1756 void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager*)
1758 // --- Output file name ------------------------------------------
1759 AliAnalysisManager::SetCommonFileName("forward_dndeta.root");
1761 // --- Load libraries/pars ---------------------------------------
1762 LoadLibrary("PWG2forward2", mode, par, true);
1764 // --- Set load path ---------------------------------------------
1765 gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWG2/FORWARD/analysis2",
1766 gROOT->GetMacroPath()));
1768 // --- Add the task ----------------------------------------------
1769 gROOT->Macro(Form("AddTaskForwarddNdeta.C(\"%s\",%f,%f,%d,\"%s\")",
1770 fTrig.Data(), fVzMin, fVzMax, fUseCent, fScheme.Data()));
1772 gROOT->Macro(Form("AddTaskCentraldNdeta.C(\"%s\",%f,%f,%d,\"%s\")",
1773 fTrig.Data(), fVzMin, fVzMax, fUseCent, fScheme.Data()));
1775 //__________________________________________________________________
1780 void CreatePhysicsSelection(Bool_t,AliAnalysisManager*) {}
1782 * Crete output handler - we don't want one here.
1786 AliVEventHandler* CreateOutputHandler(EType) { return 0; }
1787 TString fTrig; // Trigger to use
1788 Double_t fVzMin; // Least v_z
1789 Double_t fVzMax; // Largest v_z
1790 TString fScheme; // Normalisation scheme
1791 Bool_t fUseCent; // Use centrality
1794 //____________________________________________________________________