EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
run_study.py
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file run_study.py
1 #!/usr/bin/env python
2 #SBATCH -J EICSTUDY # job name
3 #SBATCH -o logs/eicstudy-%A_%a.out
4 #SBATCH -e logs/eicstudy-%A_%a.out
5 #SBATCH -n 1
6 #SBATCH -c 1
7 #SBATCH --mem=6G
8 #SBATCH -p htc # queue (partition) -- batch, parallel, etc. parallel-medium
9 #SBATCH -t 12:00:00 # run time (hh:mm:ss)
10 #SBATCH -D . # Directory where executable will be run
11 #SBATCH --mail-user=ssekula@smu.edu
12 #SBATCH --mail-type=fail # email me when the job finishes
13 
14 
15 # This script was written originally for use on a SLURM-based batch system,
16 # like the one available at SMU ("ManeFrame II"). It can be run on the command-line
17 # alone; if the script doesn't detect the requested SLURM environment variables,
18 # it will ask you to specify them. For instance, to run the first variation in a
19 # study,
20 #
21 # SLURM_ARRAY_TASK_ID=0 ./run_study.py -t ./bfield_study_template.tcl -p "['PARAM_BFIELD']" -v "[[1.0,1.5,2.0,2.5,3.0,3.5]]" -n bfield
22 #
23 # The above will manually select the first variation in the array passed to "-v" and run it.
24 #
25 # General idea:
26 #
27 # A template script is executed by the Delphes simulation executable. Before execution,
28 # placeholder parameters are filled in by the script and a copy of the template is
29 # generated (with the parameter values set) for actual execution. For example:
30 #
31 # SLURM_ARRAY_TASK_ID=0 ./run_study.py -t ./bfield_study_template.tcl -p "['PARAM_BFIELD']" -v "[[2.0]]" -n bfield
32 #
33 # will open ./bfield_study_template.tcl, find all instanced of PARAM_BFIELD, and replace them with the number "2.0".
34 # This allows command-line variation of one or more parameters to perform a study of changes to simulation.
35 #
36 
37 import subprocess
38 import math
39 import os
40 import sys
41 import shutil
42 import glob
43 import re
44 import ast
45 
46 import argparse
47 
48 global tclparams, pythiaparams
49 tclparams = {}
50 pythiaparams = {}
51 
52 
53 def LoadParamsTcl(tclfile):
54  tcl = open(tclfile)
55 
56  param_pattern = re.compile("^set\s+(.*?)\s+(.*)")
57  for line in tcl:
58  line = line.rstrip('\n')
59  match = param_pattern.match(line)
60  if match != None:
61  tclparams[match.group(1)] = str(match.group(2))
62 
63  print("Customization TCL Parameters are:")
64  print(tclparams)
65 
66 def LoadParamsPythia(cmndfile):
67  cmnd = open(cmndfile)
68 
69  param_pattern = re.compile("^\!\s*(.*?)\s*=\s*(.*)")
70  for line in cmnd:
71  line = line.rstrip('\n')
72 
73  if line.find('END HEADER') != -1:
74  break
75 
76  match = param_pattern.match(line)
77  if match != None:
78  pythiaparams[match.group(1)] = str(match.group(2))
79 
80  print("Customization Pythia8 Parameters are:")
81  print(pythiaparams)
82 
83 
84 def WriteTclFile(filename):
85  global args
86  tclfile = open(filename, 'w')
87 
88  for param in args.params:
89  value = args.params[param]
90  if (param not in tclparams.keys()) and (param not in pythiaparams.keys()):
91  print("WARNING: you tried to set %s, which is not an available parameter!" % (param))
92  continue
93  tclparams[param] = str(value)
94 
95  for param in tclparams:
96  line = "set %s %s\n" % (param, tclparams[param])
97  tclfile.write(line)
98  tclfile.close()
99 
100 def WritePythiaFile(output_filename):
101  global args
102 
103  for param in args.params:
104  value = args.params[param]
105  if (param not in pythiaparams.keys()) and (param not in tclparams.keys()):
106  print("WARNING: you tried to set %s, which is not an available parameter!" % (param))
107  continue
108  pythiaparams[param] = str(value)
109 
110 
111  with open(args.commands, "rt") as input_template:
112  with open(output_filename, "wt") as output_template:
113  for line in input_template:
114  for param in pythiaparams:
115  value = str(pythiaparams[param])
116  line = line.replace(param, value)
117 
118  output_template.write(line)
119 
120 
121 def TransferTclFile(tclfile, taskdir):
122  with open(tclfile, "rt") as input_template:
123  with open("%s/%s" % (taskdir, tclfile), "wt") as output_template:
124  for line in input_template:
125  line = line.replace("customizations.tcl", "%s/customizations.tcl" % (taskdir))
126 
127  output_template.write(line)
128 
129 
130 
131 parser = argparse.ArgumentParser()
132 
133 parser.add_argument("-n", "--name", type=str,
134  help="name for this study set (e.g. bfield)")
135 parser.add_argument("-t", "--template", type=str,
136  help="template TCL file for study")
137 parser.add_argument("-c", "--commands", type=str,
138  help="template command file for study")
139 parser.add_argument("-p", "--params", type=ast.literal_eval, default={},
140  help="environment variables to set for study")
141 #parser.add_argument("-v", "--values", type=ast.literal_eval, default=[],
142 # help="parameter values for study")
143 parser.add_argument("-f", "--force", default=False, action='store_true',
144  help="force-overwrite existing output")
145 
146 global args
147 args = parser.parse_args()
148 
149 # Create the task superdirectory
150 
151 if not os.path.exists(args.name):
152  try:
153  os.makedirs(args.name)
154  except OSError:
155  print("%s already exists... continuing..." % (args.name))
156 
157 
158 SLURM_ARRAY_TASK_ID="0"
159 
160 try:
161  SLURM_ARRAY_TASK_ID=os.environ["SLURM_ARRAY_TASK_ID"]
162 except:
163  print("Please set the SLURM_ARRAY_TASK_ID environment variable to a number (e.g. 0) before running this script.")
164  sys.exit()
165  pass
166 
167 print("Task ID requested: %d" % (int(SLURM_ARRAY_TASK_ID)))
168 
169 
170 
171 value_index = int(SLURM_ARRAY_TASK_ID)
172 
173 
174 # Load the available parameters and their default values from
175 # customizations.tcl and from the header of the PYTHIA8 command
176 # file
177 
178 LoadParamsTcl("customizations.tcl")
179 LoadParamsPythia(args.commands)
180 
181 
182 # Handle random number seed issues and other defaults
183 
184 random_seed = 0
185 if "PARAM_RANDOM_SEED" not in args.params:
186  random_seed = abs(hash(args.name)) % (10 ** 8) + value_index
187  pythiaparams["PARAM_RANDOM_SEED"] = random_seed
188 
189 # Execute the study
190 
191 taskdir="%s/%d" % (args.name, value_index)
192 tclfile = "%s/customizations.tcl" % (taskdir)
193 cmndfile = "%s/%s" % (taskdir, args.commands)
194 
195 if os.path.exists(taskdir) and not args.force:
196  print("Skipping this task directory --- it already exists. Cleanup before overwriting!")
197  print(taskdir)
198 else:
199  if not os.path.exists(taskdir):
200  os.makedirs(taskdir)
201 
202  # Replace parameter placeholders with values for this study
203  WriteTclFile(tclfile)
204  WritePythiaFile(cmndfile)
205 
206  # Copy files to the task directory before execution
207  copy_files = [args.template]
208  for a_file in copy_files:
209  subprocess.call("cp %s %s" % (a_file, taskdir), shell=True)
210  #TransferTclFile(a_file, taskdir)
211  # Write the random number seed to disk
212  rndm_file = open(taskdir+"/random_seed.dat", "w")
213  rndm_file.write(str(random_seed))
214  rndm_file.close()
215 
216  # Execute the study
217  subprocess.call("DelphesPythia8 {0[taskdir]}/{0[template]} {0[taskdir]}/{0[commands]} {0[taskdir]}/out.root".format({'taskdir': taskdir, 'template': args.template, 'commands': args.commands}), shell=True)