submit_syst.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 import subprocess
3 import sys
4 import re
5 
6 """
7 TODO :
8 """
9 
10 # valid options to pass to -sg or -xp
11 joint_syst_groups = ['CalibUp', 'CalibDown', 'CalibShape', 'RelCalibUp', 'RelCalibDown',
12  'LightUp', 'LightDown', 'LightNom', 'Cherenkov',
13  'XSec1', 'XSec2', 'XSec3', 'XSec4', 'XSec5', 'XSec6',
14  'MuEnergyJoint', 'Flux', 'GeniePCA', 'Neutron', 'JointSmall']
15 
16 nue_syst_groups = ['NueMichel', 'NueAcceptance']
17 numu_syst_groups = ['NumuSmall', 'MuEnergyNumu']
18 
19 file_syst_groups = ['CalibUp', 'CalibDown', 'CalibShape',
20  'RelCalibUp', 'RelCalibDown', 'LightUp',
21  'LightDown', 'LightNom', 'Cherenkov']
22 
23 nue_gen_groups = ['NuePropExtrap', 'NueComboExtrap', 'NueNoExtrap']
24 numu_gen_groups = ['NumuExtrap', 'NumuNoExtrap']
25 
26 extrap_strings = ['nxp', 'xp_combo', 'xp_prop', 'xp_numu']
27 
28 # get list of groups passed to -sg that need separate loaders
29 def get_file_systs(groups):
30  global file_syst_groups
31  ret = list(set(file_syst_groups) & set(groups))
32  return ret
33 
34 
35 def loader_helper(opts, key):
36  loader_args = ''.join(
37  ((opts.analysis+"_concat" if opts.concat else ""),
38  opts.beam+"_",
39  ("_FakeData_" if opts.fake_data else ""),
40  ("_NoTau_" if opts.notau else ""), key))
41  return loader_args
42 
43 
44 def get_loaders(opts):
45  loaders = {}
46  # Add one loader for generating nominal predictions
47  # Passing syst groups which don't require separate loaders
48  # doesn't create new ones
49  loaders['Normal'] = loader_helper(opts, 'Normal')
50  file_groups = get_file_systs(opts.syst_group)
51  for file_group in file_groups:
52  loaders[file_group] = loader_helper(opts, file_group)
53  return loaders
54 
55 
56 def extrap_helper(key):
57  extrap_args = []
58  # Get arguments to extrapolation functions in syst_header.h,
59  # uses objects defined in syst_header.h
60  if key == 'NumuExtrap':
61  extrap_args = ['HadEFracQuantCuts', 'axisNumu',
62  'cutNumuFD', 'cutNumuND', 'kMCWeight']
63  if key == 'NumuNoExtrap':
64  extrap_args = ['HadEFracQuantCuts', 'axisNumu',
65  'cutNumuFD', 'kMCWeight']
66  if key == 'NueComboExtrap' or key == 'NuePropExtrap':
67  extrap_args = ['axisNue', 'axisNumuForNue', 'cutNueFD',
68  'cutNueND', 'cutNumuForNueND', 'kMCWeight']
69  if key == 'NueNoExtrap':
70  extrap_args = ['axisNue', 'cutNueFD', 'kMCWeight']
71  return extrap_args
72 
73 
74 def get_extraps(opts):
75  extraps = {}
76  # keep a dict with all extrapolations and their arguments
77  for extrap in opts.extraps:
78  extraps[extrap] = extrap_helper(extrap)
79  return extraps
80 
81 
82 def quantile_code(opts):
83  code_str = ''
84  if opts.analysis == 'numu2018':
85  code_str += 'std::vector<Cut> HadEFracQuantCuts = GetQuantileCuts(\n'
86  code_str += ''.join((
87  '"/pnfs/nova/persistent/analysis/numu/Ana2018/official/Quantiles/',
88  'quantiles__' + opts.beam + '_full__numu2018.root"', ',\n'))
89  code_str += 'axisNumu, axisHadEFrac);\n\n'
90  return code_str
91 
92 
93 def loader_code(loaders):
94  code_strs = ['\n']
95  # loaders is a dict holding all necessary loaders
96  for group in loaders.keys():
97  code_str = 'Loaders* loader'+group+' = GetLoaders2018('
98  code_str += '"'+loaders[group]+'");\n'
99 
100  # keep track by pushing it into a vector which we can call Go() on
101  code_str += 'loaders.push_back(loader'+group+');\n'
102 
103  code_strs.append(code_str)
104 
105  return code_strs
106 
107 
108 # syst_group_code and extrap_code takes options passed to -sg and -xp
109 # and calls the corresponding functions defined in syst_header.h
110 def syst_group_code(syst_group):
111  code_strs = ['\n']
112  global file_syst_groups
113  # Add syst groups passed to -sg into systs. (defined in syst_header.h)
114  for group in syst_group:
115  code_str = ''
116  if group in file_syst_groups:
117  code_str += 'AddSystGroup(loader'+group+', "'+group+'",'
118  code_str += 'Get'+group+'GroupShifts(), systs);\n'
119  code_strs.append(code_str)
120  else:
121  code_str += 'AddSystGroup(loaderNormal, "'+group+'",'
122  code_str += 'Get'+group+'GroupShifts(), systs);\n'
123  code_strs.append(code_str)
124 
125  return code_strs
126 
127 
128 def extrap_code(extraps):
129  code_strs = ['\n']
130  for extrap in extraps.keys():
131  code_str = 'Add'+extrap+'Generator('
132  for arg in extraps[extrap]:
133  code_str += arg+', '
134  code_str += 'gens);\n'
135  code_strs.append(code_str)
136 
137  return code_strs
138 
139 
141  pass
142 
143 
144 if __name__ == '__main__':
145  import argparse
146 
147  parser = argparse.ArgumentParser(
148  description='Submit jobs for generating analysis predictions')
149 
150  parser.add_argument('-a', '--analysis', type=str, required=True,
151  help='Specify analysis, numu2018/nue2018/nus2018')
152 
153  parser.add_argument('-b', '--beam', type=str, required=True,
154  help='Specify beam mode, FHC/RHC')
155 
156  parser.add_argument('-c', '--concat', action='store_true',
157  help='Specify whether to use concats')
158 
159  parser.add_argument('-nt', '--notau', action='store_true',
160  help='Do not use tau swap files')
161 
162  parser.add_argument('-fk', '--fake_data', action='store_true',
163  help='Use fake data at ND')
164 
165  parser.add_argument('-sg', '--syst_group', nargs='+',
166  help='Specify syst groups to generate')
167 
168  parser.add_argument('-all', '--all_systs', action='store_true',
169  help='Generate predictions for all syst groups')
170 
171  parser.add_argument('-xp', '--extraps', nargs='+',
172  help='Specify extrapolations to carry out')
173 
174  parser.add_argument('-all_xp', '--all_extraps', action='store_true',
175  help='Generate predictions for all extrapolations')
176 
177  parser.add_argument('-g', '--grid', nargs='?', type=str, const=' ',
178  help='Run on the grid with submit_cafana.py options')
179 
180  parser.add_argument('-i', '--interactive', nargs='?',
181  type=str, const='-bq',
182  help='Run this interactively with cafe options')
183 
184  opts = parser.parse_args()
185 
186  syst_groups = []
187  if opts.analysis == 'nue2018':
188  syst_groups = nue_syst_groups + joint_syst_groups
189  if opts.analysis == 'numu2018':
190  syst_groups = numu_syst_groups + joint_syst_groups
191 
192  # if -all or -all_xp is used, get everything
193  if opts.all_systs:
194  opts.syst_group = syst_groups
195 
196  if opts.all_extraps:
197  if opts.analysis == 'nue2018':
198  opts.extraps = nue_gen_groups
199  if opts.analysis == 'numu2018':
200  opts.extraps = numu_gen_groups
201 
202  # ensure we have the things we need
203  for group in opts.syst_group:
204  if group not in syst_groups:
205  sys.exit(group+' not in syst_header.h, aborting..')
206  for extrap in opts.extraps:
207  if extrap not in nue_gen_groups and opts.analysis == 'nue2018':
208  sys.exit(extrap + ' not in syst_header.h or not valid for ' +
209  opts.analysis + ', aborting..')
210  if extrap not in numu_gen_groups and opts.analysis == 'numu2018':
211  sys.exit(extrap + ' not in syst_header.h or not valid for ' +
212  opts.analysis + ', aborting..')
213 
214  print 'Generating predictions for......'
215  print 'Analysis : ' + opts.analysis
216  print 'Beam Mode : ' + opts.beam
217  if opts.concat:
218  print 'Using '+opts.analysis+' concats'
219  if opts.notau:
220  print 'Discarding tauswap files'
221  if opts.fake_data:
222  print 'Using Fake Data at ND'
223  else:
224  print 'Using Real Data at ND'
225  print 'Syst Groups : ', opts.syst_group
226  print 'Extrapolations : ', opts.extraps
227  if opts.interactive:
228  print 'Running cafe with options : '+opts.interactive+'\n'
229  if opts.grid:
230  print 'Running submit_cafana.py with options : '+opts.grid+'\n'
231 
232  # get the loaders and extraps dicts
233  loaders = get_loaders(opts)
234  extraps = get_extraps(opts)
235 
236  # get the code
237  ldr_code = loader_code(loaders)
238  syst_code = syst_group_code(opts.syst_group)
239  extrap_code = extrap_code(extraps)
240 
241  # make_predictions_systs_template.C has two lines with "start python editing"
242  # and "end python editing". Put all the generated code between those.
243  with open('make_predictions_systs_template.C', 'r') as f_header:
244  fout = open('make_predictions_systs.C', 'w')
245  header = f_header.read()
246  pattern = re.search(
247  '^.*start\spython\s+.*([\r\n]+)(^.*end\spython.*[\r\n]+)',
248  header, re.MULTILINE)
249  x, y = pattern.span(1)
250  x2, y2 = pattern.span(2)
251  f_header.seek(y)
252 
253  fout.write(header[:y])
254  fout.write(quantile_code(opts))
255  for code in ldr_code:
256  fout.write(code)
257  for code in syst_code:
258  fout.write(code)
259  for code in extrap_code:
260  fout.write(code)
261  fout.write(header[x2:])
262  fout.close()
263 
264  if opts.interactive:
265  print 'cafe '+opts.interactive+' make_predictions_systs.C'
266  subprocess.call('cafe '+opts.interactive+' make_predictions_systs.C',
267  shell=True)
268  if opts.grid:
269  print "Grid option not yet implemented"
def get_extraps(opts)
Definition: submit_syst.py:74
def get_loaders(opts)
Definition: submit_syst.py:44
def write_macro()
Definition: submit_syst.py:140
def syst_group_code(syst_group)
Definition: submit_syst.py:110
def extrap_helper(key)
Definition: submit_syst.py:56
def get_file_systs(groups)
Definition: submit_syst.py:29
def loader_code(loaders)
Definition: submit_syst.py:93
procfile open("FD_BRL_v0.txt")
def quantile_code(opts)
Definition: submit_syst.py:82
def loader_helper(opts, key)
Definition: submit_syst.py:35