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