Skip to content

Commit 92d21cc

Browse files
add genYAML.py; clean up run_jedi_exe.py (#223)
1 parent 4528030 commit 92d21cc

File tree

2 files changed

+109
-85
lines changed

2 files changed

+109
-85
lines changed

ush/run_jedi_exe.py

Lines changed: 2 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
import sys
99
import yaml
1010

11-
from pygw.template import Template, TemplateConstants
12-
from pygw.yaml_file import YAMLFile
11+
from ufsda.genYAML import genYAML
1312

1413

1514
def export_envar(yamlfile, bashout):
@@ -130,7 +129,7 @@ def run_jedi_exe(yamlconfig):
130129
os.environ[key] = str(value)
131130
# generate YAML for executable based on input config
132131
logging.info(f'Using yamlconfig {yamlconfig}')
133-
genYAML(yamlconfig, output_file)
132+
genYAML(yamlconfig, output=output_file)
134133
logging.info(f'Wrote YAML file to {output_file}')
135134
# use R2D2 to stage backgrounds, obs, bias correction files, etc.
136135
ufsda.stage.gdas_single_cycle(var_config)
@@ -219,88 +218,6 @@ def run_jedi_exe(yamlconfig):
219218
ufsda.misc_utils.submit_batch_job(all_config_dict['job options'], workdir, job_script)
220219

221220

222-
def genYAML(yamlconfig, output_file):
223-
logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s', level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S')
224-
# open YAML file to get config
225-
try:
226-
with open(yamlconfig, 'r') as yamlconfig_opened:
227-
all_config_dict = yaml.safe_load(yamlconfig_opened)
228-
logging.info(f'Loading configuration from {yamlconfig}')
229-
except Exception as e:
230-
logging.error(f'Error occurred when attempting to load: {yamlconfig}, error: {e}')
231-
template = all_config_dict['template']
232-
config_dict = all_config_dict['config']
233-
# what if the config_dict has environment variables that need substituted?
234-
pattern = re.compile(r'.*?\${(\w+)}.*?')
235-
for key, value in config_dict.items():
236-
if type(value) == str:
237-
match = pattern.findall(value)
238-
if match:
239-
fullvalue = value
240-
for g in match:
241-
config_dict[key] = fullvalue.replace(
242-
f'${{{g}}}', os.environ.get(g, f'${{{g}}}')
243-
)
244-
# NOTE the following is a hack until YAMLFile can take in an input config dict
245-
# if something in the template is expected to be an env var
246-
# but it is not defined in the env, problems will arise
247-
# so we set the env var in this subprocess for the substitution to occur
248-
for key, value in config_dict.items():
249-
os.environ[key] = str(value)
250-
# next we need to compute a few things
251-
runtime_config = get_runtime_config(dict(os.environ, **config_dict))
252-
# now run the global-workflow parser
253-
outconfig = YAMLFile(path=template)
254-
outconfig = Template.substitute_structure(outconfig, TemplateConstants.DOUBLE_CURLY_BRACES, config_dict.get)
255-
outconfig = Template.substitute_structure(outconfig, TemplateConstants.DOLLAR_PARENTHESES, config_dict.get)
256-
outconfig = Template.substitute_structure(outconfig, TemplateConstants.DOUBLE_CURLY_BRACES, runtime_config.get)
257-
outconfig = Template.substitute_structure(outconfig, TemplateConstants.DOLLAR_PARENTHESES, runtime_config.get)
258-
outconfig.save(output_file)
259-
260-
261-
def get_runtime_config(config_dict):
262-
# compute some runtime variables
263-
# this will probably need pulled out somewhere else eventually
264-
# a temporary hack to get UFO evaluation stuff and ATM VAR going again
265-
valid_time = dt.datetime.strptime(config_dict['CDATE'], '%Y%m%d%H')
266-
assim_freq = int(config_dict.get('assim_freq', 6))
267-
window_begin = valid_time - dt.timedelta(hours=assim_freq/2)
268-
window_end = valid_time + dt.timedelta(hours=assim_freq/2)
269-
component_dict = {
270-
'atmos': 'ATM',
271-
'chem': 'AERO',
272-
'ocean': 'SOCA',
273-
'land': 'land',
274-
}
275-
win_begin_var = component_dict[config_dict.get('COMPONENT', 'atmos')] + '_WINDOW_BEGIN'
276-
win_end_var = component_dict[config_dict.get('COMPONENT', 'atmos')] + '_WINDOW_END'
277-
win_len_var = component_dict[config_dict.get('COMPONENT', 'atmos')] + '_WINDOW_LENGTH'
278-
bkg_string_var = 'BKG_YYYYmmddHHMMSS'
279-
bkg_isotime_var = 'BKG_ISOTIME'
280-
npx_ges_var = 'npx_ges'
281-
npy_ges_var = 'npy_ges'
282-
npz_ges_var = 'npz_ges'
283-
npx_anl_var = 'npx_anl'
284-
npy_anl_var = 'npy_anl'
285-
npz_anl_var = 'npz_anl'
286-
287-
runtime_config = {
288-
win_begin_var: f"{window_begin.strftime('%Y-%m-%dT%H:%M:%SZ')}",
289-
win_end_var: f"{window_end.strftime('%Y-%m-%dT%H:%M:%SZ')}",
290-
win_len_var: f"PT{assim_freq}H",
291-
bkg_string_var: f"{valid_time.strftime('%Y%m%d.%H%M%S')}",
292-
bkg_isotime_var: f"{valid_time.strftime('%Y-%m-%dT%H:%M:%SZ')}",
293-
npx_ges_var: f"{int(os.environ['CASE'][1:]) + 1}",
294-
npy_ges_var: f"{int(os.environ['CASE'][1:]) + 1}",
295-
npz_ges_var: f"{int(os.environ['LEVS']) - 1}",
296-
npx_anl_var: f"{int(os.environ['CASE_ENKF'][1:]) + 1}",
297-
npy_anl_var: f"{int(os.environ['CASE_ENKF'][1:]) + 1}",
298-
npz_anl_var: f"{int(os.environ['LEVS']) - 1}",
299-
}
300-
301-
return runtime_config
302-
303-
304221
if __name__ == "__main__":
305222
parser = argparse.ArgumentParser()
306223
parser.add_argument('-c', '--config', type=str, help='Input YAML Configuration', required=True)

ush/ufsda/genYAML.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#!/usr/bin/env python3
2+
# genYAML
3+
# generate YAML using ufsda python module,
4+
# current runtime env, and optional input YAML
5+
import argparse
6+
import datetime as dt
7+
import logging
8+
import os
9+
import re
10+
import yaml
11+
from pygw.template import Template, TemplateConstants
12+
from pygw.yaml_file import YAMLFile
13+
14+
15+
def genYAML(yamlconfig, output=None):
16+
logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s', level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S')
17+
# open YAML file to get config
18+
try:
19+
with open(yamlconfig, 'r') as yamlconfig_opened:
20+
all_config_dict = yaml.safe_load(yamlconfig_opened)
21+
logging.info(f'Loading configuration from {yamlconfig}')
22+
except Exception as e:
23+
logging.error(f'Error occurred when attempting to load: {yamlconfig}, error: {e}')
24+
25+
if not output:
26+
output_file = all_config_dict['output']
27+
else:
28+
output_file = output
29+
30+
template = all_config_dict['template']
31+
config_dict = all_config_dict['config']
32+
# what if the config_dict has environment variables that need substituted?
33+
pattern = re.compile(r'.*?\${(\w+)}.*?')
34+
for key, value in config_dict.items():
35+
if type(value) == str:
36+
match = pattern.findall(value)
37+
if match:
38+
fullvalue = value
39+
for g in match:
40+
config_dict[key] = fullvalue.replace(
41+
f'${{{g}}}', os.environ.get(g, f'${{{g}}}')
42+
)
43+
# NOTE the following is a hack until YAMLFile can take in an input config dict
44+
# if something in the template is expected to be an env var
45+
# but it is not defined in the env, problems will arise
46+
# so we set the env var in this subprocess for the substitution to occur
47+
for key, value in config_dict.items():
48+
os.environ[key] = str(value)
49+
# next we need to compute a few things
50+
runtime_config = get_runtime_config(dict(os.environ, **config_dict))
51+
# now run the global-workflow parser
52+
outconfig = YAMLFile(path=template)
53+
outconfig = Template.substitute_structure(outconfig, TemplateConstants.DOUBLE_CURLY_BRACES, config_dict.get)
54+
outconfig = Template.substitute_structure(outconfig, TemplateConstants.DOLLAR_PARENTHESES, config_dict.get)
55+
outconfig = Template.substitute_structure(outconfig, TemplateConstants.DOUBLE_CURLY_BRACES, runtime_config.get)
56+
outconfig = Template.substitute_structure(outconfig, TemplateConstants.DOLLAR_PARENTHESES, runtime_config.get)
57+
outconfig.save(output_file)
58+
59+
60+
def get_runtime_config(config_dict):
61+
# compute some runtime variables
62+
# this will probably need pulled out somewhere else eventually
63+
# a temporary hack to get UFO evaluation stuff and ATM VAR going again
64+
valid_time = dt.datetime.strptime(config_dict['CDATE'], '%Y%m%d%H')
65+
assim_freq = int(config_dict.get('assim_freq', 6))
66+
window_begin = valid_time - dt.timedelta(hours=assim_freq/2)
67+
window_end = valid_time + dt.timedelta(hours=assim_freq/2)
68+
component_dict = {
69+
'atmos': 'ATM',
70+
'chem': 'AERO',
71+
'ocean': 'SOCA',
72+
'land': 'land',
73+
}
74+
win_begin_var = component_dict[config_dict.get('COMPONENT', 'atmos')] + '_WINDOW_BEGIN'
75+
win_end_var = component_dict[config_dict.get('COMPONENT', 'atmos')] + '_WINDOW_END'
76+
win_len_var = component_dict[config_dict.get('COMPONENT', 'atmos')] + '_WINDOW_LENGTH'
77+
bkg_string_var = 'BKG_YYYYmmddHHMMSS'
78+
bkg_isotime_var = 'BKG_ISOTIME'
79+
npx_ges_var = 'npx_ges'
80+
npy_ges_var = 'npy_ges'
81+
npz_ges_var = 'npz_ges'
82+
npx_anl_var = 'npx_anl'
83+
npy_anl_var = 'npy_anl'
84+
npz_anl_var = 'npz_anl'
85+
86+
runtime_config = {
87+
win_begin_var: f"{window_begin.strftime('%Y-%m-%dT%H:%M:%SZ')}",
88+
win_end_var: f"{window_end.strftime('%Y-%m-%dT%H:%M:%SZ')}",
89+
win_len_var: f"PT{assim_freq}H",
90+
bkg_string_var: f"{valid_time.strftime('%Y%m%d.%H%M%S')}",
91+
bkg_isotime_var: f"{valid_time.strftime('%Y-%m-%dT%H:%M:%SZ')}",
92+
npx_ges_var: f"{int(os.environ['CASE'][1:]) + 1}",
93+
npy_ges_var: f"{int(os.environ['CASE'][1:]) + 1}",
94+
npz_ges_var: f"{int(os.environ['LEVS']) - 1}",
95+
npx_anl_var: f"{int(os.environ['CASE_ENKF'][1:]) + 1}",
96+
npy_anl_var: f"{int(os.environ['CASE_ENKF'][1:]) + 1}",
97+
npz_anl_var: f"{int(os.environ['LEVS']) - 1}",
98+
}
99+
100+
return runtime_config
101+
102+
103+
if __name__ == "__main__":
104+
parser = argparse.ArgumentParser()
105+
parser.add_argument('-c', '--config', type=str, help='Input YAML Configuration', required=True)
106+
args = parser.parse_args()
107+
genYAML(args.config)

0 commit comments

Comments
 (0)