Skip to content

Commit bf67c82

Browse files
committed
Implement configuration fed simulation running
1 parent 1bd72df commit bf67c82

3 files changed

Lines changed: 240 additions & 12 deletions

File tree

examples/aod/createO2tables.C

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,12 @@ void createO2tables(const char* inputFile = "delphes.root",
2828

2929
// smearer
3030
o2::delphes::TrackSmearer smearer;
31-
if (Bz == 0.2) {
32-
smearer.loadTable(11, "lutCovm.el.2kG.dat");
33-
smearer.loadTable(13, "lutCovm.mu.2kG.dat");
34-
smearer.loadTable(211, "lutCovm.pi.2kG.dat");
35-
smearer.loadTable(321, "lutCovm.ka.2kG.dat");
36-
smearer.loadTable(2212, "lutCovm.pr.2kG.dat");
37-
} else if (Bz == 0.5) {
38-
smearer.loadTable(11, "lutCovm.el.5kG.dat");
39-
smearer.loadTable(13, "lutCovm.mu.5kG.dat");
40-
smearer.loadTable(211, "lutCovm.pi.5kG.dat");
41-
smearer.loadTable(321, "lutCovm.ka.5kG.dat");
42-
smearer.loadTable(2212, "lutCovm.pr.5kG.dat");
31+
if (Bz == 0.2 || Bz == 0.5) {
32+
smearer.loadTable(11, "lutCovm.el.dat");
33+
smearer.loadTable(13, "lutCovm.mu.dat");
34+
smearer.loadTable(211, "lutCovm.pi.dat");
35+
smearer.loadTable(321, "lutCovm.ka.dat");
36+
smearer.loadTable(2212, "lutCovm.pr.dat");
4337
} else {
4438
std::cout << " --- invalid Bz field: " << Bz << std::endl;
4539
return;

examples/scripts/createO2tables.py

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
#! /usr/bin/env python3
2+
3+
import argparse
4+
import configparser
5+
import subprocess
6+
import os
7+
import shutil
8+
import multiprocessing
9+
import numpy
10+
11+
verbose_mode = False
12+
13+
14+
class bcolors:
15+
# Colors for bash
16+
BOLD = "\033[1m"
17+
UNDERLINE = "\033[4m"
18+
HEADER = "\033[95m"
19+
OKBLUE = "\033[94m"
20+
BOKBLUE = BOLD + OKBLUE
21+
OKGREEN = "\033[92m"
22+
BOKGREEN = BOLD + OKGREEN
23+
WARNING = "\033[93m"
24+
BWARNING = BOLD + WARNING
25+
FAIL = "\033[91m"
26+
BFAIL = BOLD + FAIL
27+
ENDC = "\033[0m"
28+
29+
30+
def verbose_msg(*args):
31+
if verbose_mode:
32+
print("** ", bcolors.OKBLUE, *args, bcolors.ENDC)
33+
34+
35+
def msg(*args):
36+
print(bcolors.BOKGREEN, *args, bcolors.ENDC)
37+
38+
39+
def run_cmd(cmd):
40+
verbose_msg("Running", cmd)
41+
content = os.popen(cmd).read()
42+
if content:
43+
verbose_msg(content)
44+
45+
46+
def process_run(run_number, remove_after_run=False):
47+
msg("> starting run", run_number)
48+
# run Delphes and analysis
49+
generator_cfg = f"generator.{run_number}.cfg"
50+
delphes_file = f"delphes.{run_number}.root"
51+
delphes_log_file = delphes_file.replace(".root", ".log")
52+
aod_file = f"AODRun5.{run_number}.root"
53+
aod_log_file = aod_file.replace(".root", ".log")
54+
run_cmd(
55+
f"DelphesPythia8 propagate.tcl {generator_cfg} {delphes_file} &> {delphes_log_file}")
56+
run_cmd(
57+
f"root -b -q -l 'createO2tables.C(\"{delphes_file}\", \"{aod_file}\", 0)' &> {aod_log_file}")
58+
59+
if remove_after_run:
60+
os.remove("delphes_file")
61+
msg("< complete run", run_number)
62+
63+
64+
def main(configuration_file, config_entry, verbose=True):
65+
global verbose_mode
66+
verbose_mode = verbose
67+
parser = configparser.RawConfigParser()
68+
parser.read(configuration_file)
69+
70+
run_cmd("./clean.sh")
71+
72+
def opt(entry):
73+
o = parser.get(config_entry, entry)
74+
b = ['yes', 'no', 'on', 'off', 'true', 'false']
75+
for i in b:
76+
if o.lower() == i:
77+
o = parser.getboolean(config_entry, entry)
78+
break
79+
verbose_msg("Got option", entry, "=", f"'{o}'")
80+
return o
81+
82+
# Config from the config file
83+
nJobs = int(opt('nJobs'))
84+
nRuns = int(opt('nRuns'))
85+
nEvents = opt('nEvents')
86+
87+
# detector configuration
88+
bField = opt("bField")
89+
sigmaT = opt("sigmaT")
90+
radius = opt("radius")
91+
length = opt("length")
92+
etaMax = opt("etaMax")
93+
94+
# calculate max eta from geometry
95+
th = numpy.arctan2(float(radius), float(length))*0.5
96+
sth = numpy.sin(th)
97+
cth = numpy.cos(th)
98+
etaMax = -numpy.log(sth/cth)
99+
100+
# Printing configuration
101+
msg(" --- running createO2tables.sh ")
102+
msg(" nJobs = ", nJobs)
103+
msg(" nRuns = ", nRuns)
104+
msg(" nEvents = ", nEvents)
105+
msg(" --- with detector configuration ")
106+
msg(" bField = ", bField, " [kG] ")
107+
msg(" sigmaT = ", sigmaT, " [ns] ")
108+
msg(" radius = ", radius, " [cm] ")
109+
msg(" length = ", length, " [cm] ")
110+
msg(" etaMax = ", etaMax)
111+
msg(" --- start processing the runs ")
112+
113+
# copy relevant files in the working directory
114+
def do_copy(in_file, out_file):
115+
in_file = os.path.expanduser(os.path.expandvars(in_file))
116+
verbose_msg("Copying", in_file, "to", out_file)
117+
shutil.copy2(in_file, out_file)
118+
119+
do_copy(os.path.join(opt("card_path"),
120+
opt("propagate_card")),
121+
"propagate.tcl")
122+
123+
lut_path = opt("lut_path")
124+
lut_tag = opt("lut_tag")
125+
lut_particles = ["el", "mu", "pi", "ka", "pr"]
126+
for i in lut_particles:
127+
do_copy(os.path.join(lut_path,
128+
"lutCovm.{}{}.dat".format(i, lut_tag)),
129+
f"lutCovm.{i}.dat")
130+
131+
generators = opt("generators").split(" ")
132+
for i in generators:
133+
do_copy(i, ".")
134+
135+
aod_path = opt("aod_path")
136+
do_copy(os.path.join(aod_path, "createO2tables.h"), ".")
137+
do_copy(os.path.join(aod_path, "createO2tables.C"), ".")
138+
139+
def set_config(config_file, config, value):
140+
run_cmd(
141+
"sed -i -e \"" f"s/{config} .*$/{config} {value}" "\" " + config_file)
142+
143+
# set magnetic field
144+
set_config("propagate.tcl", "set barrel_Bz", f"{bField}""e\-1/")
145+
set_config("createO2tables.C", "double Bz = ", f"{bField}""e\-1\;/")
146+
set_config("dpl-config_std.json", "\"d_bz\":", "\""f"{bField}""\"\,/")
147+
# set radius
148+
set_config("propagate.tcl", "set barrel_Radius", f"{radius}""e\-2/")
149+
set_config("createO2tables.C", "double tof_radius =", f"{radius}""\;/")
150+
# set length
151+
set_config("propagate.tcl", "set barrel_HalfLength", f"{length}""e\-2/")
152+
set_config("createO2tables.C", "double tof_length =", f"{length}""\;/")
153+
# # set acceptance
154+
set_config("propagate.tcl", "set barrel_Acceptance",
155+
"\{ 0.0 + 1.0 * fabs(eta) < "f"{etaMax}"" \}/")
156+
# set time resolution
157+
set_config("propagate.tcl", "set barrel_TimeResolution",
158+
f"{sigmaT}""e\-9/")
159+
set_config("createO2tables.C", "double tof_sigmat =", f"{sigmaT}""\;/")
160+
161+
run_list = range(nRuns)
162+
163+
def configure_run(run_number):
164+
# copy generator configuration
165+
generator_cfg = f"generator.{run_number}.cfg"
166+
generator_orig = generators[0].split("/")[-1]
167+
do_copy(generator_orig, generator_cfg)
168+
# Adjust configuration file
169+
with open(generator_cfg, "a") as f_cfg:
170+
# number of events and random seed
171+
f_cfg.write(f"Main:numberOfEvents {nEvents}\n")
172+
f_cfg.write(f"Random:seed = {run_number}\n")
173+
# collision time spread [mm/c]
174+
f_cfg.write("Beams:allowVertexSpread on \n")
175+
f_cfg.write("Beams:sigmaTime 60.\n")
176+
for i in generators[1:]:
177+
with open(i.split("/")[-1], "r") as f_append:
178+
f_cfg.write(f_append.read())
179+
180+
for i in run_list:
181+
configure_run(i)
182+
with multiprocessing.Pool(processes=nJobs) as pool:
183+
pool.map(process_run, run_list)
184+
185+
# merge runs when all done
186+
msg(" --- waiting for runs to be completed ")
187+
msg(" --- all runs are processed, so long ")
188+
189+
with open("listfiles.txt", "w") as listfiles:
190+
for i in os.listdir("."):
191+
if "AODRun5." in i and i.endswith(".root"):
192+
listfiles.write(i)
193+
194+
195+
if __name__ == "__main__":
196+
parser = argparse.ArgumentParser(description=__doc__)
197+
parser.add_argument("configuration_file", type=str,
198+
help="Input configuration file")
199+
parser.add_argument("--entry", type=str,
200+
default="DEFAULT",
201+
help="Input configuration file")
202+
parser.add_argument("-b", action="store_true", help="Background mode")
203+
parser.add_argument("-v", action="store_true", help="Verbose mode")
204+
args = parser.parse_args()
205+
main(configuration_file=args.configuration_file,
206+
config_entry=args.entry,
207+
verbose=args.v)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
[DEFAULT]
2+
### running configuration
3+
njobs = 1
4+
nruns = 1
5+
nevents = 1000
6+
7+
### detector configuration
8+
# magnetic field [kG]
9+
bfield = 5.
10+
# time resolution [ns]
11+
sigmat = 0.020
12+
# radius [cm]
13+
radius = 100.
14+
# half length [cm]
15+
length = 200.
16+
# max pseudorapidity
17+
etamax = 1.443
18+
19+
card_path = $DELPHESO2_ROOT/examples/cards/
20+
propagate_card = propagate.2kG.tcl
21+
22+
lut_path = $DELPHESO2_ROOT/examples/smearing/luts
23+
lut_tag = .5kG.100cm.default
24+
25+
generators = $DELPHESO2_ROOT/examples/pythia8/pythia8_ccbar.cfg $DELPHESO2_ROOT/examples/pythia8/decays/force_hadronic_D.cfg
26+
27+
aod_path = $DELPHESO2_ROOT/examples/aod/

0 commit comments

Comments
 (0)