Project
Loading...
Searching...
No Matches
GeneratorFactory.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
13
16#include "FairGenerator.h"
18#include <fairlogger/Logger.h>
19#include <SimConfig/SimConfig.h>
23#ifdef GENERATORS_WITH_PYTHIA8
26#endif
30#ifdef GENERATORS_WITH_HEPMC3
33#endif
34#if defined(GENERATORS_WITH_PYTHIA8) && defined(GENERATORS_WITH_HEPMC3)
37#endif
44
45#include "TRandom.h"
46
47namespace o2
48{
49namespace eventgen
50{
51
52// reusable helper class
53// main purpose is to init a FairPrimGen given some (Sim)Config
55{
56 if (!primGen) {
57 LOG(warning) << "No primary generator instance; Cannot setup";
58 return;
59 }
60
61 auto primGenO2 = dynamic_cast<PrimaryGenerator*>(primGen);
62
63 auto makeBoxGen = [](int pdgid, int mult, double etamin, double etamax, double pmin, double pmax, double phimin, double phimax) {
64 return new o2::eventgen::BoxGenerator(pdgid, mult, etamin, etamax, pmin, pmax, phimin, phimax);
65 };
66
67#ifdef GENERATORS_WITH_PYTHIA8
68 auto makePythia8Gen = [](std::string& config) {
69 auto& singleton = GeneratorPythia8Param::Instance();
71 .config = config.size() > 0 ? config : singleton.config,
72 .hooksFileName = singleton.hooksFileName,
73 .hooksFuncName = singleton.hooksFuncName,
74 .includePartonEvent = singleton.includePartonEvent,
75 .particleFilter = singleton.particleFilter,
76 .verbose = singleton.verbose,
77 };
78 auto gen = new o2::eventgen::GeneratorPythia8(pars);
79 if (!config.empty()) {
80 LOG(info) << "Setting \'Pythia8\' base configuration: " << config << std::endl;
81 gen->setConfig(config); // assign config; will be executed in Init function
82 }
83 return gen;
84 };
85#endif
86
89 o2::O2DatabasePDG::addALICEParticles(TDatabasePDG::Instance());
90 auto genconfig = conf.getGenerator();
91#if defined(GENERATORS_WITH_PYTHIA8) && defined(GENERATORS_WITH_HEPMC3)
92 if (GeneratorHybridParam::Instance().switchExtToHybrid && (genconfig.compare("external") == 0 || genconfig.compare("extgen") == 0)) {
93 LOG(info) << "Switching external generator to hybrid mode";
94 genconfig = "hybrid";
95 }
96#endif
97 LOG(info) << "** Generator to use: '" << genconfig << "'";
98 if (genconfig.compare("boxgen") == 0) {
99 // a simple "box" generator configurable via BoxGunparam
100 auto& boxparam = BoxGunParam::Instance();
101 LOG(info) << "Init generic box generator with following parameters";
102 LOG(info) << boxparam;
103 auto boxGen = makeBoxGen(boxparam.pdg, boxparam.number, boxparam.eta[0], boxparam.eta[1], boxparam.prange[0], boxparam.prange[1], boxparam.phirange[0], boxparam.phirange[1]);
104 primGen->AddGenerator(boxGen);
105 } else if (genconfig.compare("fwmugen") == 0) {
106 // a simple "box" generator for forward muons
107 LOG(info) << "Init box forward muons generator";
108 auto boxGen = makeBoxGen(13, 1, -4, -2.5, 50., 50., 0., 360);
109 primGen->AddGenerator(boxGen);
110 } else if (genconfig.compare("hmpidgun") == 0) {
111 // a simple "box" generator for forward muons
112 LOG(info) << "Init hmpid gun generator";
113 auto boxGen = makeBoxGen(-211, 100, -0.5, -0.5, 2, 5, -5, 60);
114 primGen->AddGenerator(boxGen);
115 } else if (genconfig.compare("fwpigen") == 0) {
116 // a simple "box" generator for forward pions
117 LOG(info) << "Init box forward pions generator";
118 auto boxGen = makeBoxGen(-211, 10, -4, -2.5, 7, 7, 0, 360);
119 primGen->AddGenerator(boxGen);
120 } else if (genconfig.compare("fwrootino") == 0) {
121 // a simple "box" generator for forward rootinos
122 LOG(info) << "Init box forward rootinos generator";
123 auto boxGen = makeBoxGen(0, 1, -4, -2.5, 1, 5, 0, 360);
124 primGen->AddGenerator(boxGen);
125 } else if (genconfig.compare("zdcgen") == 0) {
126 // a simple "box" generator for forward neutrons
127 LOG(info) << "Init box forward/backward zdc generator";
128 auto boxGenC = makeBoxGen(2112 /*neutrons*/, 1, -8, -9999, 500, 1000, 0., 360.);
129 auto boxGenA = makeBoxGen(2112 /*neutrons*/, 1, 8, 9999, 500, 1000, 0., 360.);
130 primGen->AddGenerator(boxGenC);
131 primGen->AddGenerator(boxGenA);
132 } else if (genconfig.compare("emcgenele") == 0) {
133 // box generator with one electron per event
134 LOG(info) << "Init box generator for electrons in EMCAL";
135 // using phi range of emcal
136 auto elecgen = makeBoxGen(11, 1, -0.67, 0.67, 15, 15, 80, 187);
137 primGen->AddGenerator(elecgen);
138 } else if (genconfig.compare("emcgenphoton") == 0) {
139 LOG(info) << "Init box generator for photons in EMCAL";
140 auto photongen = makeBoxGen(22, 1, -0.67, 0.67, 15, 15, 80, 187);
141 primGen->AddGenerator(photongen);
142 } else if (genconfig.compare("fddgen") == 0) {
143 LOG(info) << "Init box FDD generator";
144 auto boxGenFDC = makeBoxGen(13, 1000, -7, -4.8, 10, 500, 0, 360.);
145 auto boxGenFDA = makeBoxGen(13, 1000, 4.9, 6.3, 10, 500, 0., 360);
146 primGen->AddGenerator(boxGenFDA);
147 primGen->AddGenerator(boxGenFDC);
148 } else if (genconfig.compare("extkin") == 0) {
149 // external kinematics
150 // needs precense of a kinematics file "Kinematics.root"
151 // TODO: make this configurable and check for presence
152 auto extGen = new o2::eventgen::GeneratorFromFile(conf.getExtKinematicsFileName().c_str());
153 extGen->SetStartEvent(conf.getStartEvent());
154 primGen->AddGenerator(extGen);
155 LOG(info) << "using external kinematics";
156 } else if (genconfig.compare("extkinO2") == 0) {
157 // external kinematics from previous O2 output
158 auto& singleton = GeneratorFromO2KineParam::Instance();
159 auto name1 = singleton.fileName;
160 auto name2 = conf.getExtKinematicsFileName();
161 auto pars = O2KineGenConfig{
162 .skipNonTrackable = singleton.skipNonTrackable,
163 .continueMode = singleton.continueMode,
164 .roundRobin = singleton.roundRobin,
165 .randomize = singleton.randomize,
166 .rngseed = singleton.rngseed,
167 .randomphi = singleton.randomphi,
168 .fileName = name1.size() > 0 ? name1.c_str() : name2.c_str()};
169 auto extGen = new o2::eventgen::GeneratorFromO2Kine(pars);
170 extGen->SetStartEvent(conf.getStartEvent());
171 primGen->AddGenerator(extGen);
172 if (pars.continueMode) {
173 auto o2PrimGen = dynamic_cast<o2::eventgen::PrimaryGenerator*>(primGen);
174 if (o2PrimGen) {
175 o2PrimGen->setApplyVertex(false);
176 }
177 }
178 LOG(info) << "using external O2 kinematics";
179 } else if (genconfig.compare("evtpool") == 0) {
180 // case of an "event-pool" which is a specialization of extkinO2
181 // with some additional logic in file management and less configurability
182 // and not features such as "continue transport"
184 primGen->AddGenerator(extGen);
185 LOG(info) << "using the eventpool generator";
186 } else if (genconfig.compare("tparticle") == 0) {
187 // External ROOT file(s) with tree of TParticle in clones array,
188 // or external program generating such a file
189 auto& param0 = GeneratorFileOrCmdParam::Instance();
191 LOG(info) << "Init 'GeneratorTParticle' with the following parameters";
192 LOG(info) << param0;
193 LOG(info) << param;
194 auto tgen = new o2::eventgen::GeneratorTParticle();
195 tgen->setup(param0, param, conf);
196 primGen->AddGenerator(tgen);
197#ifdef GENERATORS_WITH_HEPMC3
198 } else if (genconfig.compare("hepmc") == 0) {
199 // external HepMC file, or external program writing HepMC event
200 // records to standard output.
201 auto& param0 = GeneratorFileOrCmdParam::Instance();
203 LOG(info) << "Init \'GeneratorHepMC\' with following parameters";
204 LOG(info) << param0;
205 LOG(info) << param;
206 auto hepmcGen = new o2::eventgen::GeneratorHepMC();
207 hepmcGen->setup(param0, param, conf);
208 primGen->AddGenerator(hepmcGen);
209#endif
210#ifdef GENERATORS_WITH_PYTHIA8
211 } else if (genconfig.compare("alldets") == 0) {
212 // a simple generator for test purposes - making sure to generate hits
213 // in all detectors
214 // I compose it of:
215 // 1) pythia8
216 auto py8config = std::string(std::getenv("O2_ROOT")) + "/share/Generators/egconfig/pythia8_inel.cfg";
217 auto py8 = makePythia8Gen(py8config);
218 primGen->AddGenerator(py8);
219 // 2) forward muons
220 auto muon = makeBoxGen(13, 100, -2.5, -4.0, 100, 100, 0., 360);
221 primGen->AddGenerator(muon);
222 } else if (genconfig.compare("pythia8") == 0) {
223 auto py8config = std::string();
224 auto py8 = makePythia8Gen(py8config);
225 primGen->AddGenerator(py8);
226 } else if (genconfig.compare("pythia8pp") == 0) {
227 auto py8config = std::string(std::getenv("O2_ROOT")) + "/share/Generators/egconfig/pythia8_inel.cfg";
228 auto py8 = makePythia8Gen(py8config);
229 primGen->AddGenerator(py8);
230 } else if (genconfig.compare("pythia8hf") == 0) {
231 // pythia8 pp (HF production)
232 // configures pythia for HF production in pp collisions at 14 TeV
233 auto py8config = std::string(std::getenv("O2_ROOT")) + "/share/Generators/egconfig/pythia8_hf.cfg";
234 auto py8 = makePythia8Gen(py8config);
235 primGen->AddGenerator(py8);
236 } else if (genconfig.compare("pythia8hi") == 0) {
237 // pythia8 heavy-ion
238 // exploits pythia8 heavy-ion machinery (available from v8.230)
239 // configures pythia for min.bias Pb-Pb collisions at 5.52 TeV
240 auto py8config = std::string(std::getenv("O2_ROOT")) + "/share/Generators/egconfig/pythia8_hi.cfg";
241 auto py8 = makePythia8Gen(py8config);
242 primGen->AddGenerator(py8);
243 } else if (genconfig.compare("pythia8powheg") == 0) {
244 // pythia8 with powheg
245 auto py8config = std::string(std::getenv("O2_ROOT")) + "/share/Generators/egconfig/pythia8_powheg.cfg";
246 auto py8 = makePythia8Gen(py8config);
247 primGen->AddGenerator(py8);
248#endif
249 } else if (genconfig.compare("external") == 0 || genconfig.compare("extgen") == 0) {
250 // external generator via configuration macro
252 LOG(info) << "Setting up external generator with following parameters";
253 LOG(info) << params;
254 auto extgen_filename = params.fileName;
255 auto extgen_func = params.funcName;
256 auto extgen = o2::conf::GetFromMacro<FairGenerator*>(extgen_filename, extgen_func, "FairGenerator*", "extgen");
257 if (!extgen) {
258 LOG(fatal) << "Failed to retrieve \'extgen\': problem with configuration ";
259 }
260 primGen->AddGenerator(extgen);
261 } else if (genconfig.compare("toftest") == 0) { // 1 muon per sector and per module
262 LOG(info) << "Init tof test generator -> 1 muon per sector and per module";
263 for (int i = 0; i < 18; i++) {
264 for (int j = 0; j < 5; j++) {
265 auto boxGen = makeBoxGen(13 /*muons*/, 1, -0.8 + 0.32 * j + 0.15, -0.8 + 0.32 * j + 0.17, 9, 10, 10 + 20. * i - 1, 10 + 20. * i + 1);
266 primGen->AddGenerator(boxGen);
267 }
268 }
269#if defined(GENERATORS_WITH_PYTHIA8) && defined(GENERATORS_WITH_HEPMC3)
270 } else if (genconfig.compare("hybrid") == 0) { // hybrid using multiple generators
271 LOG(info) << "Init hybrid generator";
272 auto& hybridparam = GeneratorHybridParam::Instance();
273 std::string config = hybridparam.configFile;
274 // check if config string points to an existing and not empty file
275 if (config.empty()) {
276 LOG(fatal) << "No configuration file provided for hybrid generator";
277 return;
278 }
279 auto& hybrid = o2::eventgen::GeneratorHybrid::Instance(config);
280 primGen->AddGenerator(&hybrid);
281#endif
282 } else {
283 LOG(fatal) << "Invalid generator";
284 }
285
287 // to be set via GeneratorFactory only if generator is not hybrid
288 // external settings via JSON are supported in the latter
289
290 Trigger trigger = nullptr;
291 DeepTrigger deeptrigger = nullptr;
292 if (!(genconfig.compare("hybrid") == 0)) {
293 auto trgconfig = conf.getTrigger();
294 if (trgconfig.empty()) {
295 return;
296 } else if (trgconfig.compare("particle") == 0) {
298 } else if (trgconfig.compare("external") == 0) {
299 // external trigger via configuration macro
301 LOG(info) << "Setting up external trigger with following parameters";
302 LOG(info) << params;
303 auto external_trigger_filename = params.fileName;
304 auto external_trigger_func = params.funcName;
305 trigger = o2::conf::GetFromMacro<o2::eventgen::Trigger>(external_trigger_filename, external_trigger_func, "o2::eventgen::Trigger", "trigger");
306 if (!trigger) {
307 LOG(info) << "Trying to retrieve a \'o2::eventgen::DeepTrigger\' type" << std::endl;
308 deeptrigger = o2::conf::GetFromMacro<o2::eventgen::DeepTrigger>(external_trigger_filename, external_trigger_func, "o2::eventgen::DeepTrigger", "deeptrigger");
309 }
310 if (!trigger && !deeptrigger) {
311 LOG(fatal) << "Failed to retrieve \'external trigger\': problem with configuration ";
312 }
313 } else {
314 LOG(fatal) << "Invalid trigger";
315 }
316
318 auto generators = primGen->GetListOfGenerators();
319 for (int igen = 0; igen < generators->GetEntries(); ++igen) {
320 auto generator = dynamic_cast<o2::eventgen::Generator*>(generators->At(igen));
321 if (!generator) {
322 LOG(fatal) << "request to add a trigger to an unsupported generator";
323 return;
324 }
326 if (trigger) {
327 generator->addTrigger(trigger);
328 }
329 if (deeptrigger) {
330 generator->addDeepTrigger(deeptrigger);
331 }
332 }
333 }
334}
335
336} // end namespace eventgen
337} // end namespace o2
default_random_engine gen(dev())
int32_t i
uint32_t j
Definition RawData.h:0
static void addALICEParticles(TDatabasePDG *db=TDatabasePDG::Instance())
std::string getExtKinematicsFileName() const
Definition SimConfig.h:159
unsigned int getStartEvent() const
Definition SimConfig.h:161
std::string getTrigger() const
Definition SimConfig.h:156
std::string getGenerator() const
Definition SimConfig.h:155
static GeneratorHybrid & Instance(const std::string &inputgens="")
void setTriggerMode(ETriggerMode_t val)
Definition Generator.h:92
GLenum const GLfloat * params
Definition glcorearb.h:272
GLenum GLfloat param
Definition glcorearb.h:271
std::function< bool(void *, std::string)> DeepTrigger
Definition Trigger.h:26
std::function< bool(const std::vector< TParticle > &)> Trigger
Definition Trigger.h:25
Trigger TriggerParticle(const TriggerParticleParam &param)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
static void setPrimaryGenerator(o2::conf::SimConfig const &, FairPrimaryGenerator *)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"