3 * @author Christian Holm Christensen <cholm@nbi.dk>
4 * @date Wed Oct 15 12:52:58 2014
6 * @brief Base classes for configurations shared amoung steps.
10 //====================================================================
12 * Base class for detector configuration. By default, everything is on
17 virtual Bool_t UseABSO() const { return true; }
18 virtual Bool_t UseACORDE() const { return false; }
19 virtual Bool_t UseDIPO() const { return true; }
20 virtual Bool_t UseEMCAL() const { return true; }
21 virtual Bool_t UseFMD() const { return true; }
22 virtual Bool_t UseFRAME() const { return true; }
23 virtual Bool_t UseHALL() const { return true; }
24 virtual Bool_t UseITS() const { return true; }
25 virtual Bool_t UseMAG() const { return true; }
26 virtual Bool_t UseMUON() const { return true; }
27 virtual Bool_t UsePHOS() const { return true; }
28 virtual Bool_t UsePIPE() const { return true; }
29 virtual Bool_t UsePMD() const { return true; }
30 virtual Bool_t UseHMPID() const { return true; }
31 virtual Bool_t UseSHIL() const { return true; }
32 virtual Bool_t UseT0() const { return true; }
33 virtual Bool_t UseTOF() const { return true; }
34 virtual Bool_t UseTPC() const { return true; }
35 virtual Bool_t UseTRD() const { return true; }
36 virtual Bool_t UseVZERO() const { return true; }
37 virtual Bool_t UseZDC() const { return true; }
40 Printf("ABSO: %3s", UseABSO() ? "yes" : "no");
41 Printf("ACORDE: %3s", UseACORDE() ? "yes" : "no");
42 Printf("DIPO: %3s", UseDIPO() ? "yes" : "no");
43 Printf("EMCAL: %3s", UseEMCAL() ? "yes" : "no");
44 Printf("FMD: %3s", UseFMD() ? "yes" : "no");
45 Printf("FRAME: %3s", UseFRAME() ? "yes" : "no");
46 Printf("HALL: %3s", UseHALL() ? "yes" : "no");
47 Printf("ITS: %3s", UseITS() ? "yes" : "no");
48 Printf("MAG: %3s", UseMAG() ? "yes" : "no");
49 Printf("MUON: %3s", UseMUON() ? "yes" : "no");
50 Printf("PHOS: %3s", UsePHOS() ? "yes" : "no");
51 Printf("PIPE: %3s", UsePIPE() ? "yes" : "no");
52 Printf("PMD: %3s", UsePMD() ? "yes" : "no");
53 Printf("HMPID: %3s", UseHMPID() ? "yes" : "no");
54 Printf("SHIL: %3s", UseSHIL() ? "yes" : "no");
55 Printf("T0: %3s", UseT0() ? "yes" : "no");
56 Printf("TOF: %3s", UseTOF() ? "yes" : "no");
57 Printf("TPC: %3s", UseTPC() ? "yes" : "no");
58 Printf("TRD: %3s", UseTRD() ? "yes" : "no");
59 Printf("VZERO: %3s", UseVZERO() ? "yes" : "no");
60 Printf("ZDC: %3s", UseZDC() ? "yes" : "no");
63 * Get the string of enabled detectors for local reconstruction.
65 * @param enable On return, contains string of enable detectors
67 void GetRecoString(TString& enable) const
69 if (UseITS()) Append2Str(enable, "ITS");
70 if (UseTPC()) Append2Str(enable, "TPC");
71 if (UseTRD()) Append2Str(enable, "TRD");
72 if (UseTOF()) Append2Str(enable, "TOF");
73 if (UsePHOS()) Append2Str(enable, "PHOS");
74 if (UseHMPID()) Append2Str(enable, "HMPID");
75 if (UseEMCAL()) Append2Str(enable, "EMCAL");
76 if (UseMUON()) Append2Str(enable, "MUON");
77 if (UseFMD()) Append2Str(enable, "FMD");
78 if (UseZDC()) Append2Str(enable, "ZDC");
79 if (UsePMD()) Append2Str(enable, "PMD");
80 if (UseT0()) Append2Str(enable, "T0");
81 if (UseVZERO()) Append2Str(enable, "VZERO");
84 * Get the string of detectors for which we should make Summable
87 * @param sDigits On returm contains the string of enable detectors
89 void GetSDigitString(TString& sDigits) const
91 if (UseTRD()) Append2Str(sDigits, "TRD");
92 if (UseTOF()) Append2Str(sDigits, "TOF");
93 if (UsePHOS()) Append2Str(sDigits, "PHOS");
94 if (UseHMPID()) Append2Str(sDigits, "HMPID");
95 if (UseEMCAL()) Append2Str(sDigits, "EMCAL");
96 if (UseMUON()) Append2Str(sDigits, "MUON");
97 if (UseFMD()) Append2Str(sDigits, "FMD");
98 if (UseZDC()) Append2Str(sDigits, "ZDC");
99 if (UsePMD()) Append2Str(sDigits, "PMD");
100 if (UseT0()) Append2Str(sDigits, "T0");
101 if (UseVZERO()) Append2Str(sDigits, "VZERO");
104 * Get the sting of detectors for which we should do the hit to
105 * digit conversion directly.
107 * @param fromHits On returm contains the string of enable detectors
109 void GetHits2DigitsString(TString& fromHits) const
111 if (UseITS()) Append2Str(fromHits, "ITS");
112 if (UseTPC()) Append2Str(fromHits, "TPC");
115 * Append a C style string to a string, possibly adding a space before
117 * @param str Where to append
118 * @param append What to append
120 static void Append2Str(TString& str, const char* append)
122 if (!str.IsNull()) str.Append(" ");
127 /** Global variable */
128 VirtualDetCfg* detCfg = 0;
130 //====================================================================
132 * Base class for the OCDG configration
134 struct VirtualOCDBCfg
137 * This member function must return the default prefix.
139 * @return Prefix of OCDB specific storages
141 virtual const char* Prefix() const { return ""; }
143 * This member function should define the real setup.
145 * @param forSim Whether we're setting up for simulations or not
147 virtual void Init(Bool_t forSim)
149 ::Fatal("VirtualOCDBConfig", "Dummy init called - redefine!");
152 * Set the specific storage for a given key (possibly wild-carded).
155 * @param ideal Whether it is residual or ideal
157 void AddStore(const char* key,
160 AliCDBManager* cdb = AliCDBManager::Instance();
161 const char* prefix = Prefix();
162 TString path = Form("alien://Folder=/alice/simulation/%s/%s",
163 prefix, !ideal ? "Residual" : "Ideal");
164 ::Info("AddStore", "%s -> %s", key, path.Data());
165 cdb->SetSpecificStorage(key, path);
169 /** Global variable */
170 VirtualOCDBCfg* ocdbCfg = 0;
172 //====================================================================
174 * Event generator configuration
180 VirtualEGCfg() : runType("") {}
181 virtual ~VirtualEGCfg() {}
183 * Load the general libraries needed
186 static void LoadGen(const TString& runType) {
187 if (!gROOT->GetClass("AliStructFuncType"))
188 gSystem->Load("liblhapdf"); // Parton density functions
189 if (!gROOT->GetClass("TPythia6"))
190 gSystem->Load("libEGPythia6"); // TGenerator interface
191 if (!runType.EqualTo("hydjet", TString::kIgnoreCase))
196 * Load the pythia libraries
198 * @param vers Optional version post-fix
200 static void LoadPythia(Bool_t gen=true, const char* vers="6.4.21")
202 if (gen) LoadGen("");
204 if (gROOT->GetClass(Form("AliPythia6%c", m))) return;
205 gSystem->Load(Form("libpythia%s", vers));
206 gSystem->Load(Form("libAliPythia%c", m));
209 * Load HIJING libraries
211 static void LoadHijing()
214 if (gROOT->GetClass("THijing")) return;
215 gSystem->Load("libhijing");
216 gSystem->Load("libTHijing");
217 AliPDG::AddParticlesToPdgDataBase();
220 * Load HydJet libraries
222 static void LoadHydjet()
224 if (gROOT->GetClass("TUHKMgen")) return;
225 gSystem->Load("libTUHKMgen");
228 * Load DPMJet libraries
230 static void LoadDpmjet()
233 if (gROOT->GetClass("TDPMjet")) return;
234 gSystem->Load("libdpmjet");
235 gSystem->Load("libTDPMjet");
238 * Load AMPT libraries
240 static void LoadAmpt()
243 if (gROOT->GetClass("TAmpt")) return;
244 gSystem->Load("libampt");
245 gSystem->Load("libTAmpt");
250 * @param rt Event generator identifier
251 * @param b1 Least impact parameter
252 * @param b2 Largest impact parameter
253 * @param smear If true, smear interaction per event
255 * @return Point to newly allocated generator or null
258 AliGenerator* MakeGenerator(const TString& rt,
264 ::Fatal("MakeGenerator", "No EG spec given");
268 TString runType = rt;
271 AliGenerator* g = CreateGenerator(runType,b1,b2);
272 if (g && smear) g->SetVertexSmear(AliGenerator::kPerEvent);
279 * @param rt The EG to use
281 * @return Newly allocated decayer or null
283 TVirtualMCDecayer* MakeDecayer(const TString& rt)
286 ::Fatal("MakeGenerator", "No EG spec given");
290 TString runType = rt;
293 TVirtualMCDecayer* decayer = CreateDecayer(runType);
295 if (decayer) decayer->Init();
300 * Create the generator. This function must be defined in a derived class.
302 * @param runType The generator ID (all lower case)
303 * @param b1 Least impact parameter
304 * @param b2 Largest impact parameter
306 * @return Must return a pointer to a new AliGenerator or null
308 virtual AliGenerator* CreateGenerator(const TString& runType,
312 * Create the decayer. This function must be defined in a derived class.
314 * @param runType The generator ID (all lower case)
316 * @return Must return a pointer to a new TVirtualMCDecayer or null
318 virtual TVirtualMCDecayer* CreateDecayer(const TString& runType) = 0;
321 /** Global variable */
322 VirtualEGCfg* egCfg = 0;
324 //====================================================================
326 * Base class for trains
343 Bool_t Run(UInt_t run,
344 const char* xmlFile = "wn.xml",
346 const char* cdb = "raw://")
348 // --- Load configuration script ---------------------------------
351 // --- Set-up for CDB access through Grid ------------------------
352 TString cdbString(cdb);
353 if (cdbString.Contains("raw://")) {
354 TGrid::Connect("alien://");
355 if (!gGrid || !gGrid->IsConnected()) {
356 ::Error("Run", "No grid connection");
361 // --- Some environment variables --------------------------------
362 // Temp dir is here, and compilation is here too
363 gSystem->Setenv("TMPDIR", gSystem->pwd());
364 gSystem->SetBuildDir(gSystem->pwd(), kTRUE);
366 // --- Now load common libraries ---------------------------------
369 // --- Now create and configure manager --------------------------
370 AliAnalysisManager *mgr = new AliAnalysisManager(GetName(),
372 mgr->SetRunFromPath(grp->run);
374 // --- Create ESD input handler ------------------------------------
375 AliESDInputHandlerRP *esdHandler = new AliESDInputHandlerRP();
376 mgr->SetInputEventHandler(esdHandler);
378 esdHandler->SetReadFriends(kTRUE);
379 esdHandler->SetActiveBranches("ESDfriend");
382 // --- Monte Carlo handler -----------------------------------------
384 AliMCEventHandler* mcHandler = new AliMCEventHandler();
385 mgr->SetMCtruthEventHandler(mcHandler);
386 mcHandler->SetPreReadMode(1);
387 mcHandler->SetReadTR(true);
389 // --- AOD output handler ----------------------------------------
391 AliAODHandler* aodHandler = new AliAODHandler();
392 aodHandler->SetOutputFileName("AliAOD.root");
393 mgr->SetOutputEventHandler(aodHandler);
396 // --- Call user routine for adding tasks ------------------------
397 if (!AddTasks()) return false;
399 // --- Check if we are to merge ----------------------------------
401 return Merge(xmlfile, stage);
403 // --- Otherwise run the train -----------------------------------
404 TChain* chain = CreateChain();
405 if (!chain) return false;
409 if (!mgr->InitAnalysis()) {
410 ::Error("Run", "Failed to initialize the train");
415 mgr->SetSkipTerminate(kTRUE);
416 mgr->StartAnalysis("local", chain);
421 * Merge requested files
423 * @param dir Output directory
426 * @return true on success
428 Bool_t Merge(const char* dir, Int_t stage)
433 TString outputDir = dir;
434 Bool_t final = outputDir.Contains("Stage");
435 TCollection* outputFiles = GetFilesToMerge(stage, final);
437 ::Warning("Merge", "Nothing to merge");
440 TIter iter(outputFiles);
442 Bool_t merged = kTRUE;
443 while((str = static_cast<TObjString*>(iter()))) {
444 TString& outputFile = str->GetString();
445 // Skip already merged outputs
446 if (!gSystem->AccessPathName(outputFile)) {
447 ::Warning("Merge","Output file <%s> found. Not merging again.",
451 merged = AliAnalysisAlien::MergeOutput(outputFile,
455 if (merged) continue;
457 ::Error("Merge", "Cannot merge %s\n", outputFile.Data());
459 // --- possible merge file information files ---------------------
460 if (MergeFileInfo()) {
461 TString infolog = "fileinfo.log";
462 AliAnalysisAlien::MergeInfo(infolog, dir);
465 // --- If not final stage, get out here --------------------------
472 // --- set up and run termiante ----------------------------------
473 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
474 mgr->SetSkipTerminate(kFALSE);
475 if (!mgr->InitAnalysis()) {
476 ::Error("Merge", "Failed to initialize the train");
481 mgr->StartAnalysis("gridterminate", (TTree*)0);
489 * Load a library/module
491 * @param module Library/module name
493 * @return true on success
495 Bool_t LoadLibrary(const char *module)
497 // Load a module library in a given mode. Reports success.
500 ::Info("LoadLibrary", "Loading %s", module);
501 gROOT->IncreaseDirLevel();
504 ::Error("AnalysisTrainNew.C::LoadLibrary", "Empty module name");
505 gROOT->DecreaseDirLevel();
509 // If a library is specified, just load it
510 if (mod.EndsWith(".so")) {
511 mod.Remove(mod.Index(".so"));
512 ::Info("LoadLibrary", "Loading .so: %s", mod.Data());
513 result = gSystem->Load(mod);
515 ::Error("AnalysisTrainNew.C::LoadLibrary",
516 "Could not load library %s", module);
518 gROOT->DecreaseDirLevel();
519 return (result >= 0);
521 // Check if the library is already loaded
522 if (strlen(gSystem->GetLibraries(Form("%s.so", module), "", kFALSE)) > 0) {
523 ::Info("LoadLibrary", "Module %s.so already loaded", module);
524 gROOT->DecreaseDirLevel();
528 ::Info("LoadLibrary", "Trying to load lib%s.so", module);
529 result = gSystem->Load(Form("lib%s.so", module));
531 ::Error("AnalysisTrainNew.C::LoadLibrary",
532 "Could not load module %s", module);
533 ::Info("LoadLibrary", "Module %s, successfully loaded", module);
534 gROOT->DecreaseDirLevel();
535 return (result >= 0);
538 * Load common libraries
540 * @return true on sucess
542 virtual Bool_t LoadBaseLibraries()
544 // Load common analysis libraries.
545 if (!gSystem->Getenv("ALICE_ROOT")) {
546 ::Error("LoadBaseLibraries",
547 "Analysis trains requires that analysis libraries are "
548 "compiled with a local AliRoot");
552 Bool_t success = true;
553 // Load framework classes. Par option ignored here.
554 success &= LoadLibrary("libSTEERBase.so");
555 success &= LoadLibrary("libESD.so");
556 success &= LoadLibrary("libAOD.so");
557 success &= LoadLibrary("libANALYSIS.so");
558 success &= LoadLibrary("libOADB.so");
559 success &= LoadLibrary("libANALYSISalice.so");
560 success &= LoadLibrary("libESDfilter.so");
561 success &= LoadLibrary("libCORRFW.so");
562 success &= LoadLibrary("libPWGPP.so");
563 gROOT->ProcessLine(".include $ALICE_ROOT/include");
565 ::Info("LoadBaseLibraries",
566 "Load common libraries: SUCCESS");
567 ::Info("LoadBaseLibraries",
568 "Include path for Aclic compilation:\n%s",
569 gSystem->GetIncludePath());
571 ::Info("LoadBaseLibraries",
572 "Load common libraries: FAILED");
577 * Create the input chain
579 * @return Pointer to newly allocated train
581 TChain* CreateChain()
583 if (gSystem->AccessPathName("AliESDs.root")) {
584 ::Error("CreateChain",
585 "File: AliESDs.root not in ./data dir");
589 // Create the input chain
590 TChain* chain = new TChain("esdTree");
591 chain->Add("AliESDs.root");
592 if (!chain->GetNtrees()) {
600 * Helper function to make @c outputs_valid file
603 void ValidateOutput()
606 out.open("outputs_valid", ios::out);
612 * @name Functions to overload
615 * Load the configuration script. Override to load specific script.
617 virtual void LoadConfig() {};
619 * Override to set a name of the analysis manager
621 * @return Name of analysis manager
623 virtual const char* GetName() const { return "dummy"; }
625 * Override to return true if friends are needed.
629 virtual Bool_t UseFriends() const { return false; }
631 * Override to return true if MC info is needed
635 virtual Bool_t UseMC() const { return false; }
637 * Override to return true if AODs should be made
641 virtual Bool_t MakeAOD() const { return false; }
643 * User rountine for adding tasks. Override to add tasks to the
648 virtual Bool_t AddTasks() const { return true; }
650 * Override to return true to merge file information files.
654 virtual Bool_t MergFileInfo() const { return false; }
656 * Return the list of ouput files (TObjString objects)
658 * @param stage Merge stage
659 * @param final Final merging (also terminate)
661 * @return Pointer to TCollection.
663 virtual TCollection* GetFilesToMerge(Int_t stage, Bool_t final) const
672 //====================================================================
674 * A function so that we can do TROOT::Macro. Does nothing but print a message.
679 Info("", "Defined base classes for configuration");