]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/analysis2/sim/BaseConfig.C
Merge branch 'feature-movesplit'
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / sim / BaseConfig.C
CommitLineData
421f877c 1/**
2 * @file BaseConfig.C
3 * @author Christian Holm Christensen <cholm@nbi.dk>
4 * @date Wed Oct 15 12:52:58 2014
5 *
6 * @brief Base classes for configurations shared amoung steps.
7 *
8 *
9 */
b2a78539 10//====================================================================
421f877c 11/**
12 * Base class for detector configuration. By default, everything is on
13 * except ACORDE.
14 */
15struct VirtualDetCfg
16{
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; }
38 virtual void Print()
39 {
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");
61 }
62 /**
63 * Get the string of enabled detectors for local reconstruction.
64 *
65 * @param enable On return, contains string of enable detectors
66 */
67 void GetRecoString(TString& enable) const
68 {
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");
82 }
83 /**
84 * Get the string of detectors for which we should make Summable
85 * Digits
86 *
87 * @param sDigits On returm contains the string of enable detectors
88 */
89 void GetSDigitString(TString& sDigits) const
90 {
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");
102 }
103 /**
104 * Get the sting of detectors for which we should do the hit to
105 * digit conversion directly.
106 *
107 * @param fromHits On returm contains the string of enable detectors
108 */
109 void GetHits2DigitsString(TString& fromHits) const
110 {
111 if (UseITS()) Append2Str(fromHits, "ITS");
112 if (UseTPC()) Append2Str(fromHits, "TPC");
113 }
114 /**
115 * Append a C style string to a string, possibly adding a space before
116 *
117 * @param str Where to append
118 * @param append What to append
119 */
120 static void Append2Str(TString& str, const char* append)
121 {
122 if (!str.IsNull()) str.Append(" ");
123 str.Append(append);
124 }
125
126};
127/** Global variable */
128VirtualDetCfg* detCfg = 0;
129
b2a78539 130//====================================================================
421f877c 131/**
132 * Base class for the OCDG configration
133 */
134struct VirtualOCDBCfg
135{
136 /**
137 * This member function must return the default prefix.
138 *
139 * @return Prefix of OCDB specific storages
140 */
141 virtual const char* Prefix() const { return ""; }
142 /**
143 * This member function should define the real setup.
144 *
145 * @param forSim Whether we're setting up for simulations or not
146 */
147 virtual void Init(Bool_t forSim)
148 {
149 ::Fatal("VirtualOCDBConfig", "Dummy init called - redefine!");
150 }
151 /**
152 * Set the specific storage for a given key (possibly wild-carded).
153 *
154 * @param key Key
155 * @param ideal Whether it is residual or ideal
156 */
157 void AddStore(const char* key,
158 Bool_t ideal)
159 {
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);
166 }
167};
168
169/** Global variable */
170VirtualOCDBCfg* ocdbCfg = 0;
171
b2a78539 172//====================================================================
173/**
174 * Event generator configuration
175 *
176 */
66ff3038 177struct VirtualEGCfg
178{
179 TString runType;
180 VirtualEGCfg() : runType("") {}
181 virtual ~VirtualEGCfg() {}
15cb4a2b 182 virtual Bool_t IsLego() const { return false; }
183 /**
184 * Set the default generator based on the beam type
185 *
186 * - p-p PYTHIA
187 * - p-A or A-p DPMJet
188 * - A-A Hijing
189 */
190 static const char* DeduceRunType()
191 {
192 if (grp->IsPP()) return "pythia";
193 else if (grp->IsPA() || grp->IsAP()) return "dpmjet";
194 else if (grp->IsAA()) return "hijing";
195 return "hijing";
196 }
197
198 static void LoadLibrary(const TString& name,
199 const TString& cls="")
200 {
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;
204
205 // Now check the list of loaded and linekd libraries
206 TString libs(gSystem->GetLibraries("", "SD"));
207
208 // IF already in the list, do nothing
209 if (libs.Contains(name)) return;
210
211 // Otherwise load the library
212 gSystem->Load(name);
213 }
66ff3038 214 /**
215 * Load the general libraries needed
216 *
217 */
218 static void LoadGen(const TString& runType) {
15cb4a2b 219 LoadLibrary("liblhapdf","AliStructFuncType"); // Parton density functions
220 LoadLibrary("libEGPythia6","TPythia6"); // TGenerator interface
66ff3038 221 if (!runType.EqualTo("hydjet", TString::kIgnoreCase))
222 LoadPythia(false);
223 }
224
225 /**
226 * Load the pythia libraries
227 *
228 * @param vers Optional version post-fix
229 */
230 static void LoadPythia(Bool_t gen=true, const char* vers="6.4.21")
231 {
232 if (gen) LoadGen("");
233 char m = vers[0];
234 if (gROOT->GetClass(Form("AliPythia6%c", m))) return;
15cb4a2b 235
236 LoadLibrary("libmicrocern");
237 LoadLibrary(Form("libpythia%s",vers));
238 LoadLibrary(Form("libAliPythia%c", m));
66ff3038 239 }
240 /**
241 * Load HIJING libraries
242 */
243 static void LoadHijing()
244 {
245 LoadPythia();
246 if (gROOT->GetClass("THijing")) return;
15cb4a2b 247 LoadLibrary("libhijing");
248 LoadLibrary("libTHijing");
66ff3038 249 AliPDG::AddParticlesToPdgDataBase();
250 }
251 /**
252 * Load HydJet libraries
253 */
254 static void LoadHydjet()
255 {
15cb4a2b 256 LoadLibrary("libTUHKMgen","TUHKMgen");
66ff3038 257 }
258 /**
259 * Load DPMJet libraries
260 */
261 static void LoadDpmjet()
262 {
263 LoadPythia();
264 if (gROOT->GetClass("TDPMjet")) return;
15cb4a2b 265 LoadLibrary("libdpmjet");
266 LoadLibrary("libTDPMjet");
66ff3038 267 }
268 /**
269 * Load AMPT libraries
270 */
271 static void LoadAmpt()
272 {
273 LoadPythia();
274 if (gROOT->GetClass("TAmpt")) return;
15cb4a2b 275 LoadLibrary("libampt");
276 LoadLibrary("libTAmpt");
66ff3038 277 }
278 /**
279 * Make the generator
280 *
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
285 *
286 * @return Point to newly allocated generator or null
287 *
288 */
289 AliGenerator* MakeGenerator(const TString& rt,
290 Float_t b1,
291 Float_t b2,
292 Bool_t smear=true)
293 {
294 if (rt.IsNull()) {
295 ::Fatal("MakeGenerator", "No EG spec given");
296 return 0;
297 }
298
299 TString runType = rt;
300 runType.ToLower();
301
302 AliGenerator* g = CreateGenerator(runType,b1,b2);
303 if (g && smear) g->SetVertexSmear(AliGenerator::kPerEvent);
304
305 return g;
306 }
307 /**
308 * Make our decayer
309 *
310 * @param rt The EG to use
311 *
312 * @return Newly allocated decayer or null
313 */
314 TVirtualMCDecayer* MakeDecayer(const TString& rt)
315 {
316 if (rt.IsNull()) {
317 ::Fatal("MakeGenerator", "No EG spec given");
318 return 0;
319 }
320
321 TString runType = rt;
322 rt.ToLower();
323
324 TVirtualMCDecayer* decayer = CreateDecayer(runType);
325
326 if (decayer) decayer->Init();
327 return decayer;
328 }
329protected:
330 /**
331 * Create the generator. This function must be defined in a derived class.
332 *
333 * @param runType The generator ID (all lower case)
334 * @param b1 Least impact parameter
335 * @param b2 Largest impact parameter
336 *
337 * @return Must return a pointer to a new AliGenerator or null
338 */
339 virtual AliGenerator* CreateGenerator(const TString& runType,
340 Float_t b1,
341 Float_t b2) = 0;
342 /**
343 * Create the decayer. This function must be defined in a derived class.
344 *
345 * @param runType The generator ID (all lower case)
346 *
347 * @return Must return a pointer to a new TVirtualMCDecayer or null
348 */
349 virtual TVirtualMCDecayer* CreateDecayer(const TString& runType) = 0;
350
351};
352/** Global variable */
353VirtualEGCfg* egCfg = 0;
354
b2a78539 355//====================================================================
356/**
357 * Base class for trains
358 *
359 */
360struct VirtualTrain
361{
362
363
364 /**
365 * Run this train
366 *
367 * @param run
368 * @param xmlFile
369 * @param stage
370 * @param cdb
371 *
372 * @return
373 */
374 Bool_t Run(UInt_t run,
375 const char* xmlFile = "wn.xml",
376 Int_t stage = 0,
377 const char* cdb = "raw://")
378 {
379 // --- Load configuration script ---------------------------------
380 LoadConfig();
381
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");
388 return false;
389 }
390 }
391
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);
396
397 // --- Now load common libraries ---------------------------------
398 LoadBaseLibraries();
399
400 // --- Now create and configure manager --------------------------
401 AliAnalysisManager *mgr = new AliAnalysisManager(GetName(),
402 "Production train");
403 mgr->SetRunFromPath(grp->run);
404
405 // --- Create ESD input handler ------------------------------------
406 AliESDInputHandlerRP *esdHandler = new AliESDInputHandlerRP();
407 mgr->SetInputEventHandler(esdHandler);
408 if (UseFriends()) {
409 esdHandler->SetReadFriends(kTRUE);
410 esdHandler->SetActiveBranches("ESDfriend");
411 }
412
413 // --- Monte Carlo handler -----------------------------------------
414 if (UseMC()) {
415 AliMCEventHandler* mcHandler = new AliMCEventHandler();
416 mgr->SetMCtruthEventHandler(mcHandler);
417 mcHandler->SetPreReadMode(1);
418 mcHandler->SetReadTR(true);
419 }
420 // --- AOD output handler ----------------------------------------
421 if (MakeAOD()) {
422 AliAODHandler* aodHandler = new AliAODHandler();
423 aodHandler->SetOutputFileName("AliAOD.root");
424 mgr->SetOutputEventHandler(aodHandler);
425 }
426
427 // --- Call user routine for adding tasks ------------------------
428 if (!AddTasks()) return false;
429
430 // --- Check if we are to merge ----------------------------------
431 if (stage > 0)
432 return Merge(xmlfile, stage);
433
434 // --- Otherwise run the train -----------------------------------
435 TChain* chain = CreateChain();
436 if (!chain) return false;
437
438 TStopwatch timer;
439 timer.Start();
440 if (!mgr->InitAnalysis()) {
441 ::Error("Run", "Failed to initialize the train");
442 return false;
443 }
444
445 mgr->PrintStatus();
446 mgr->SetSkipTerminate(kTRUE);
447 mgr->StartAnalysis("local", chain);
448 timer.Print();
449
450 }
451 /**
452 * Merge requested files
453 *
454 * @param dir Output directory
455 * @param stage Stage
456 *
457 * @return true on success
458 */
459 Bool_t Merge(const char* dir, Int_t stage)
460 {
461
462 TStopwatch timer;
463 timer.Start();
464 TString outputDir = dir;
465 Bool_t final = outputDir.Contains("Stage");
466 TCollection* outputFiles = GetFilesToMerge(stage, final);
467 if (!outputFiles) {
468 ::Warning("Merge", "Nothing to merge");
469 return true;
470 }
471 TIter iter(outputFiles);
472 TObjString* str = 0;
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.",
479 outputFile.Data());
480 continue;
481 }
482 merged = AliAnalysisAlien::MergeOutput(outputFile,
483 outputDir,
484 10,
485 stage);
486 if (merged) continue;
487
488 ::Error("Merge", "Cannot merge %s\n", outputFile.Data());
489 }
490 // --- possible merge file information files ---------------------
491 if (MergeFileInfo()) {
492 TString infolog = "fileinfo.log";
493 AliAnalysisAlien::MergeInfo(infolog, dir);
494 }
495
496 // --- If not final stage, get out here --------------------------
497 if (!final) {
498 ValidateOutput();
499 timer.Print();
500 return true;
501 }
502
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");
508 return false;
509 }
510
511 mgr->PrintStatus();
512 mgr->StartAnalysis("gridterminate", (TTree*)0);
513 ValidateOutput();
514 timer.Print();
515
516 return true;
517 }
518
519 /**
520 * Load a library/module
521 *
522 * @param module Library/module name
523 *
524 * @return true on success
525 */
526 Bool_t LoadLibrary(const char *module)
527 {
528 // Load a module library in a given mode. Reports success.
529 Int_t result = 0;
530 TString mod(module);
531 ::Info("LoadLibrary", "Loading %s", module);
532 gROOT->IncreaseDirLevel();
533
534 if (mod.IsNull()) {
15cb4a2b 535 ::Error("LoadLibrary", "Empty module name");
b2a78539 536 gROOT->DecreaseDirLevel();
537 return kFALSE;
538 }
539
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);
545 if (result < 0) {
15cb4a2b 546 ::Error("oadLibrary", "Could not load library %s", module);
b2a78539 547 }
548 gROOT->DecreaseDirLevel();
549 return (result >= 0);
550 }
551 // Check if the library is already loaded
9a3036c4 552 if (strlen(gSystem->GetLibraries(module, "", kFALSE)) > 0) {
b2a78539 553 ::Info("LoadLibrary", "Module %s.so already loaded", module);
554 gROOT->DecreaseDirLevel();
555 return kTRUE;
556 }
557
558 ::Info("LoadLibrary", "Trying to load lib%s.so", module);
b0635849 559 result = gSystem->Load(Form("lib%s", module));
b2a78539 560 if (result < 0)
15cb4a2b 561 ::Error("LoadLibrary", "Could not load module %s", module);
b2a78539 562 ::Info("LoadLibrary", "Module %s, successfully loaded", module);
563 gROOT->DecreaseDirLevel();
564 return (result >= 0);
565 }
566 /**
567 * Load common libraries
568 *
569 * @return true on sucess
570 */
571 virtual Bool_t LoadBaseLibraries()
572 {
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");
578 return false;
579 }
580
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");
593 if (success) {
594 ::Info("LoadBaseLibraries",
595 "Load common libraries: SUCCESS");
596 ::Info("LoadBaseLibraries",
597 "Include path for Aclic compilation:\n%s",
598 gSystem->GetIncludePath());
599 } else {
600 ::Info("LoadBaseLibraries",
601 "Load common libraries: FAILED");
602 }
603 return success;
604 }
605 /**
606 * Create the input chain
607 *
608 * @return Pointer to newly allocated train
609 */
610 TChain* CreateChain()
611 {
612 if (gSystem->AccessPathName("AliESDs.root")) {
613 ::Error("CreateChain",
614 "File: AliESDs.root not in ./data dir");
615 return 0;
616 }
617
618 // Create the input chain
619 TChain* chain = new TChain("esdTree");
620 chain->Add("AliESDs.root");
621 if (!chain->GetNtrees()) {
622 delete chain;
623 chain = 0;
624 }
625
626 return chain;
627 }
628 /**
629 * Helper function to make @c outputs_valid file
630 *
631 */
632 void ValidateOutput()
633 {
634 std::ofstream out;
635 out.open("outputs_valid", ios::out);
636 out.close();
637 }
638
639 /**
640 * @{
641 * @name Functions to overload
642 */
643 /**
644 * Load the configuration script. Override to load specific script.
645 */
646 virtual void LoadConfig() {};
647 /**
648 * Override to set a name of the analysis manager
649 *
650 * @return Name of analysis manager
651 */
652 virtual const char* GetName() const { return "dummy"; }
653 /**
654 * Override to return true if friends are needed.
655 *
656 * @return false
657 */
658 virtual Bool_t UseFriends() const { return false; }
659 /**
660 * Override to return true if MC info is needed
661 *
662 * @return false
663 */
664 virtual Bool_t UseMC() const { return false; }
665 /**
666 * Override to return true if AODs should be made
667 *
668 * @return false
669 */
670 virtual Bool_t MakeAOD() const { return false; }
671 /**
672 * User rountine for adding tasks. Override to add tasks to the
673 * train.
674 *
675 * @return true
676 */
677 virtual Bool_t AddTasks() const { return true; }
678 /**
679 * Override to return true to merge file information files.
680 *
681 * @return false
682 */
15cb4a2b 683 virtual Bool_t MergeFileInfo() const { return false; }
b2a78539 684 /**
685 * Return the list of ouput files (TObjString objects)
686 *
687 * @param stage Merge stage
688 * @param final Final merging (also terminate)
689 *
690 * @return Pointer to TCollection.
691 */
692 virtual TCollection* GetFilesToMerge(Int_t stage, Bool_t final) const
693 {
694 return 0;
695 }
696};
697
698
66ff3038 699
700
b2a78539 701//====================================================================
66ff3038 702/**
703 * A function so that we can do TROOT::Macro. Does nothing but print a message.
704 *
705 */
706void BaseConfig()
707{
708 Info("", "Defined base classes for configuration");
709}
710//
421f877c 711// EOF
712//
713