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() {}
182 virtual Bool_t IsLego() const { return false; }
184 * Set the default generator based on the beam type
187 * - p-A or A-p DPMJet
190 static const char* DeduceRunType()
192 if (grp->IsPP()) return "pythia";
193 else if (grp->IsPA() || grp->IsAP()) return "dpmjet";
194 else if (grp->IsAA()) return "hijing";
198 static void LoadLibrary(const TString& name,
199 const TString& cls="")
201 // If we're looking for a specific class, check that first, and
202 // if available, do nothing;
203 if (!cls.IsNull() && gROOT->GetClass(cls)) return;
205 // Now check the list of loaded and linekd libraries
206 TString libs(gSystem->GetLibraries("", "SD"));
208 // IF already in the list, do nothing
209 if (libs.Contains(name)) return;
211 // Otherwise load the library
215 * Load the general libraries needed
218 static void LoadGen(const TString& runType) {
219 LoadLibrary("liblhapdf","AliStructFuncType"); // Parton density functions
220 LoadLibrary("libEGPythia6","TPythia6"); // TGenerator interface
221 if (!runType.EqualTo("hydjet", TString::kIgnoreCase))
226 * Load the pythia libraries
228 * @param vers Optional version post-fix
230 static void LoadPythia(Bool_t gen=true, const char* vers="6.4.21")
232 if (gen) LoadGen("");
234 if (gROOT->GetClass(Form("AliPythia6%c", m))) return;
236 LoadLibrary("libmicrocern");
237 LoadLibrary(Form("libpythia%s",vers));
238 LoadLibrary(Form("libAliPythia%c", m));
241 * Load HIJING libraries
243 static void LoadHijing()
246 if (gROOT->GetClass("THijing")) return;
247 LoadLibrary("libhijing");
248 LoadLibrary("libTHijing");
249 AliPDG::AddParticlesToPdgDataBase();
252 * Load HydJet libraries
254 static void LoadHydjet()
256 LoadLibrary("libTUHKMgen","TUHKMgen");
259 * Load DPMJet libraries
261 static void LoadDpmjet()
264 if (gROOT->GetClass("TDPMjet")) return;
265 LoadLibrary("libdpmjet");
266 LoadLibrary("libTDPMjet");
269 * Load AMPT libraries
271 static void LoadAmpt()
274 if (gROOT->GetClass("TAmpt")) return;
275 LoadLibrary("libampt");
276 LoadLibrary("libTAmpt");
281 * @param rt Event generator identifier
282 * @param b1 Least impact parameter
283 * @param b2 Largest impact parameter
284 * @param smear If true, smear interaction per event
286 * @return Point to newly allocated generator or null
289 AliGenerator* MakeGenerator(const TString& rt,
295 ::Fatal("MakeGenerator", "No EG spec given");
299 TString runType = rt;
302 AliGenerator* g = CreateGenerator(runType,b1,b2);
303 if (g && smear) g->SetVertexSmear(AliGenerator::kPerEvent);
310 * @param rt The EG to use
312 * @return Newly allocated decayer or null
314 TVirtualMCDecayer* MakeDecayer(const TString& rt)
317 ::Fatal("MakeGenerator", "No EG spec given");
321 TString runType = rt;
324 TVirtualMCDecayer* decayer = CreateDecayer(runType);
326 if (decayer) decayer->Init();
331 * Create the generator. This function must be defined in a derived class.
333 * @param runType The generator ID (all lower case)
334 * @param b1 Least impact parameter
335 * @param b2 Largest impact parameter
337 * @return Must return a pointer to a new AliGenerator or null
339 virtual AliGenerator* CreateGenerator(const TString& runType,
343 * Create the decayer. This function must be defined in a derived class.
345 * @param runType The generator ID (all lower case)
347 * @return Must return a pointer to a new TVirtualMCDecayer or null
349 virtual TVirtualMCDecayer* CreateDecayer(const TString& runType) = 0;
352 /** Global variable */
353 VirtualEGCfg* egCfg = 0;
355 //====================================================================
357 * Base class for trains
374 Bool_t Run(UInt_t run,
375 const char* xmlFile = "wn.xml",
377 const char* cdb = "raw://")
379 // --- Load configuration script ---------------------------------
382 // --- Set-up for CDB access through Grid ------------------------
383 TString cdbString(cdb);
384 if (cdbString.Contains("raw://")) {
385 TGrid::Connect("alien://");
386 if (!gGrid || !gGrid->IsConnected()) {
387 ::Error("Run", "No grid connection");
392 // --- Some environment variables --------------------------------
393 // Temp dir is here, and compilation is here too
394 gSystem->Setenv("TMPDIR", gSystem->pwd());
395 gSystem->SetBuildDir(gSystem->pwd(), kTRUE);
397 // --- Now load common libraries ---------------------------------
400 // --- Now create and configure manager --------------------------
401 AliAnalysisManager *mgr = new AliAnalysisManager(GetName(),
403 mgr->SetRunFromPath(grp->run);
405 // --- Create ESD input handler ------------------------------------
406 AliESDInputHandlerRP *esdHandler = new AliESDInputHandlerRP();
407 mgr->SetInputEventHandler(esdHandler);
409 esdHandler->SetReadFriends(kTRUE);
410 esdHandler->SetActiveBranches("ESDfriend");
413 // --- Monte Carlo handler -----------------------------------------
415 AliMCEventHandler* mcHandler = new AliMCEventHandler();
416 mgr->SetMCtruthEventHandler(mcHandler);
417 mcHandler->SetPreReadMode(1);
418 mcHandler->SetReadTR(true);
420 // --- AOD output handler ----------------------------------------
422 AliAODHandler* aodHandler = new AliAODHandler();
423 aodHandler->SetOutputFileName("AliAOD.root");
424 mgr->SetOutputEventHandler(aodHandler);
427 // --- Call user routine for adding tasks ------------------------
428 if (!AddTasks()) return false;
430 // --- Check if we are to merge ----------------------------------
432 return Merge(xmlfile, stage);
434 // --- Otherwise run the train -----------------------------------
435 TChain* chain = CreateChain();
436 if (!chain) return false;
440 if (!mgr->InitAnalysis()) {
441 ::Error("Run", "Failed to initialize the train");
446 mgr->SetSkipTerminate(kTRUE);
447 mgr->StartAnalysis("local", chain);
452 * Merge requested files
454 * @param dir Output directory
457 * @return true on success
459 Bool_t Merge(const char* dir, Int_t stage)
464 TString outputDir = dir;
465 Bool_t final = outputDir.Contains("Stage");
466 TCollection* outputFiles = GetFilesToMerge(stage, final);
468 ::Warning("Merge", "Nothing to merge");
471 TIter iter(outputFiles);
473 Bool_t merged = kTRUE;
474 while((str = static_cast<TObjString*>(iter()))) {
475 TString& outputFile = str->GetString();
476 // Skip already merged outputs
477 if (!gSystem->AccessPathName(outputFile)) {
478 ::Warning("Merge","Output file <%s> found. Not merging again.",
482 merged = AliAnalysisAlien::MergeOutput(outputFile,
486 if (merged) continue;
488 ::Error("Merge", "Cannot merge %s\n", outputFile.Data());
490 // --- possible merge file information files ---------------------
491 if (MergeFileInfo()) {
492 TString infolog = "fileinfo.log";
493 AliAnalysisAlien::MergeInfo(infolog, dir);
496 // --- If not final stage, get out here --------------------------
503 // --- set up and run termiante ----------------------------------
504 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
505 mgr->SetSkipTerminate(kFALSE);
506 if (!mgr->InitAnalysis()) {
507 ::Error("Merge", "Failed to initialize the train");
512 mgr->StartAnalysis("gridterminate", (TTree*)0);
520 * Load a library/module
522 * @param module Library/module name
524 * @return true on success
526 Bool_t LoadLibrary(const char *module)
528 // Load a module library in a given mode. Reports success.
531 ::Info("LoadLibrary", "Loading %s", module);
532 gROOT->IncreaseDirLevel();
535 ::Error("LoadLibrary", "Empty module name");
536 gROOT->DecreaseDirLevel();
540 // If a library is specified, just load it
541 if (mod.EndsWith(".so")) {
542 mod.Remove(mod.Index(".so"));
543 ::Info("LoadLibrary", "Loading .so: %s", mod.Data());
544 result = gSystem->Load(mod);
546 ::Error("oadLibrary", "Could not load library %s", module);
548 gROOT->DecreaseDirLevel();
549 return (result >= 0);
551 // Check if the library is already loaded
552 if (strlen(gSystem->GetLibraries(Form("%s.so", module), "", kFALSE)) > 0) {
553 ::Info("LoadLibrary", "Module %s.so already loaded", module);
554 gROOT->DecreaseDirLevel();
558 ::Info("LoadLibrary", "Trying to load lib%s.so", module);
559 result = gSystem->Load(Form("lib%s", module));
561 ::Error("LoadLibrary", "Could not load module %s", module);
562 ::Info("LoadLibrary", "Module %s, successfully loaded", module);
563 gROOT->DecreaseDirLevel();
564 return (result >= 0);
567 * Load common libraries
569 * @return true on sucess
571 virtual Bool_t LoadBaseLibraries()
573 // Load common analysis libraries.
574 if (!gSystem->Getenv("ALICE_ROOT")) {
575 ::Error("LoadBaseLibraries",
576 "Analysis trains requires that analysis libraries are "
577 "compiled with a local AliRoot");
581 Bool_t success = true;
582 // Load framework classes. Par option ignored here.
583 success &= LoadLibrary("libSTEERBase.so");
584 success &= LoadLibrary("libESD.so");
585 success &= LoadLibrary("libAOD.so");
586 success &= LoadLibrary("libANALYSIS.so");
587 success &= LoadLibrary("libOADB.so");
588 success &= LoadLibrary("libANALYSISalice.so");
589 success &= LoadLibrary("libESDfilter.so");
590 success &= LoadLibrary("libCORRFW.so");
591 success &= LoadLibrary("libPWGPP.so");
592 gROOT->ProcessLine(".include $ALICE_ROOT/include");
594 ::Info("LoadBaseLibraries",
595 "Load common libraries: SUCCESS");
596 ::Info("LoadBaseLibraries",
597 "Include path for Aclic compilation:\n%s",
598 gSystem->GetIncludePath());
600 ::Info("LoadBaseLibraries",
601 "Load common libraries: FAILED");
606 * Create the input chain
608 * @return Pointer to newly allocated train
610 TChain* CreateChain()
612 if (gSystem->AccessPathName("AliESDs.root")) {
613 ::Error("CreateChain",
614 "File: AliESDs.root not in ./data dir");
618 // Create the input chain
619 TChain* chain = new TChain("esdTree");
620 chain->Add("AliESDs.root");
621 if (!chain->GetNtrees()) {
629 * Helper function to make @c outputs_valid file
632 void ValidateOutput()
635 out.open("outputs_valid", ios::out);
641 * @name Functions to overload
644 * Load the configuration script. Override to load specific script.
646 virtual void LoadConfig() {};
648 * Override to set a name of the analysis manager
650 * @return Name of analysis manager
652 virtual const char* GetName() const { return "dummy"; }
654 * Override to return true if friends are needed.
658 virtual Bool_t UseFriends() const { return false; }
660 * Override to return true if MC info is needed
664 virtual Bool_t UseMC() const { return false; }
666 * Override to return true if AODs should be made
670 virtual Bool_t MakeAOD() const { return false; }
672 * User rountine for adding tasks. Override to add tasks to the
677 virtual Bool_t AddTasks() const { return true; }
679 * Override to return true to merge file information files.
683 virtual Bool_t MergeFileInfo() const { return false; }
685 * Return the list of ouput files (TObjString objects)
687 * @param stage Merge stage
688 * @param final Final merging (also terminate)
690 * @return Pointer to TCollection.
692 virtual TCollection* GetFilesToMerge(Int_t stage, Bool_t final) const
701 //====================================================================
703 * A function so that we can do TROOT::Macro. Does nothing but print a message.
708 Info("", "Defined base classes for configuration");