77# with ini files. The --clone flag allows the user to create multiple instances of the generator list,
88# which is a useful feature when running multi-threaded event pool. This can be enabled via setting
99# the --mode flag to 'parallel', which is set "sequential" by default.
10+ # Since the script uses the ROOT dictionary to import the parameters names, O2 must be loaded, otherwise
11+ # the template generation will not work.
1012# Example:
1113# $O2DPG_ROOT/MC/bin/o2_hybrid_gen.py --gen pythia8 boxgen external extkinO2 hepmc pythia8hf --clone 2 \
1214# --output config.json --mode parallel --iniFile /path/to/file0.ini /path/to/file1.ini
1315
1416import argparse
1517import json
18+ import ROOT
19+ import cppyy
20+ import numpy as np
21+
22+ # Get the TClass object for the struct
23+ tclass = ROOT.TClass.GetClass("o2::eventgen::Pythia8GenConfig")
24+ tclass1 = ROOT.TClass.GetClass("o2::eventgen::BoxGenConfig")
25+
26+ gens_params = {"pythia8": "o2::eventgen::Pythia8GenConfig", "external": "o2::eventgen::ExternalGenConfig",
27+ "evtpool": "o2::eventgen::EventPoolGenConfig", "extkinO2": "o2::eventgen::O2KineGenConfig",
28+ "hepmc": "o2::eventgen::HepMCGenConfig", "boxgen": "o2::eventgen::BoxGenConfig"}
29+ cmd_params = "o2::eventgen::FileOrCmdGenConfig"
30+ gens_instances = {"pythia8": ROOT.o2.eventgen.Pythia8GenConfig(), "external": ROOT.o2.eventgen.ExternalGenConfig(),
31+ "evtpool": ROOT.o2.eventgen.EventPoolGenConfig(), "extkinO2": ROOT.o2.eventgen.O2KineGenConfig(),
32+ "hepmc": ROOT.o2.eventgen.HepMCGenConfig(), "boxgen": ROOT.o2.eventgen.BoxGenConfig()}
33+ cmd_instance = ROOT.o2.eventgen.FileOrCmdGenConfig()
34+
35+ def get_params(instance, class_name):
36+ tclass = ROOT.TClass.GetClass(class_name)
37+ members = tclass.GetListOfDataMembers()
38+ params = {}
39+ for member in members:
40+ if isinstance(member, ROOT.TDataMember):
41+ member_value = getattr(instance, member.GetName())
42+ params[member.GetName()] = member_value
43+ # replace C++ strings and arrays
44+ for key, value in params.items():
45+ if isinstance(value, cppyy.gbl.std.string):
46+ # convert to a JSON serialisable python string
47+ params[key] = str(value)
48+ elif hasattr(value, '__len__') and hasattr(value, '__getitem__'):
49+ # convert C++ numerical array to python array, no string arrays are declared as parameters, so far
50+ params[key] = np.array(value).tolist()
51+ return params
1652
1753def main():
1854 parser = argparse.ArgumentParser(description='Create a JSON file from command line flags.')
@@ -42,88 +78,22 @@ def main():
4278 if args.gen:
4379 print(f"Generators to be used: {args.gen}")
4480 for gen in args.gen:
45- if gen == "pythia8":
46- gens.append({
47- 'name': 'pythia8',
48- 'config': {
49- "config": "$O2_ROOT/share/Generators/egconfig/pythia8_inel.cfg",
50- "hooksFileName": "",
51- "hooksFuncName": "",
52- "includePartonEvent": False,
53- "particleFilter": "",
54- "verbose": 0
55- }
56- })
57- elif gen == "external":
58- gens.append({
59- 'name': 'external',
60- 'config': {
61- "fileName": "${O2DPG_ROOT}/MC/config/PWGDQ/external/generator/GeneratorParamPromptJpsiToElectronEvtGen_pp13TeV.C",
62- "funcName": "GeneratorParamPromptJpsiToElectronEvtGen_pp13TeV()",
63- "iniFile": ""
64- }
65- })
66- elif gen == "evtpool":
67- gens.append({
68- 'name': 'evtpool',
69- 'config': {
70- "eventPoolPath": "/path/to/filename.root",
71- "skipNonTrackable": True,
72- "roundRobin": False,
73- "randomize": True,
74- "rngseed": 0,
75- "randomphi": False,
76- }
77- })
78- elif gen == "extkinO2":
79- gens.append({
80- 'name': 'extkinO2',
81- 'config': {
82- "skipNonTrackable": True,
83- "continueMode": False,
84- "roundRobin": False,
85- "randomize": False,
86- "rngseed": 0,
87- "randomphi": False,
88- "fileName": "/path/to/filename.root"
89- }
90- })
91- elif gen == "hepmc":
92- gens.append({
93- "name": "hepmc",
94- "config": {
95- "configcmd": {
96- "fileNames": "",
97- "cmd": ""
98- },
99- "confighepmc": {
100- "version": 2,
101- "eventsToSkip": 0,
102- "fileName": "/path/to/filename.hepmc",
103- "prune": False
81+ if gen in gens_params:
82+ if gen == "hepmc":
83+ configs = [get_params(cmd_instance, cmd_params), get_params(gens_instances[gen], gens_params[gen])]
84+ gens.append({
85+ 'name': gen,
86+ 'config': {
87+ "configcmd": configs[0],
88+ "confighepmc": configs[1]
10489 }
105- }
106- })
107- elif gen == "boxgen":
108- gens.append({
109- "name": "boxgen",
110- "config": {
111- "pdg": 13,
112- "number": 1,
113- "eta": [
114- -4,
115- -2.5
116- ],
117- "prange": [
118- 0.1,
119- 5
120- ],
121- "phirange": [
122- 0,
123- 360
124- ]
125- }
126- })
90+ })
91+ else:
92+ configs = get_params(gens_instances[gen],gens_params[gen])
93+ gens.append({
94+ 'name': gen,
95+ 'config': configs
96+ })
12797 elif gen in noConfGen:
12898 gens.append({
12999 "name": gen,
@@ -139,13 +109,11 @@ def main():
139109 if ".ini" != ini[-4:]:
140110 print(f"File {ini} is not an ini file")
141111 exit(1)
112+ configs = get_params(gens_instances["external"],gens_params["external"])
113+ configs["iniFile"] = ini
142114 gens.append({
143115 'name': 'external',
144- 'config': {
145- "fileName": "",
146- "funcName": "",
147- "iniFile": ini
148- }
116+ 'config': configs
149117 })
150118
151119 if args.clone:
0 commit comments