Skip to content

Commit

Permalink
Merge pull request #219 from xylar/fix-model-yaml-update
Browse files Browse the repository at this point in the history
Fix how yaml model config options are update
  • Loading branch information
xylar authored Aug 8, 2024
2 parents 1f0c36c + adf207a commit 0cbc130
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 20 deletions.
20 changes: 9 additions & 11 deletions polaris/model_step.py
Original file line number Diff line number Diff line change
Expand Up @@ -658,30 +658,28 @@ def _process_yaml(self, quiet):
if not self.model_config_data:
return

replacements = dict()
if self._yaml is None:
raise ValueError('Trying to update a yaml object but it was '
'never created.')

if not quiet:
print(f'Warning: replacing yaml options in {self.yaml}')

for entry in self.model_config_data:
if 'namelist' in entry:
raise ValueError('Cannot generate a yaml config from an MPAS '
'namelist file.')

if 'options' in entry:
# this is a dictionary of replacement namelist options
# this is a dictionary of replacement model config options
options = entry['options']
self._yaml.update(options=options, quiet=quiet)
else:
yaml = PolarisYaml.read(filename=entry['yaml'],
package=entry['package'],
replacements=entry['replacements'])
options = yaml.configs
replacements.update(options)

if not quiet:
print(f'Warning: replacing yaml options in {self.yaml}')

if self._yaml is None:
raise ValueError('Trying to update a yaml object but it was '
'never created.')
self._yaml = self._yaml.update(replacements, quiet=quiet)
self._yaml.update(configs=yaml.configs, quiet=quiet)


def make_graph_file(mesh_filename, graph_filename='graph.info',
Expand Down
6 changes: 3 additions & 3 deletions polaris/ocean/tasks/manufactured_solution/forward.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ def dynamic_model_config(self, at_setup):

exact_solution = ExactSolution(self.config)
options = {'config_manufactured_solution_amplitude':
exact_solution.eta0,
float(exact_solution.eta0),
'config_manufactured_solution_wavelength_x':
exact_solution.lambda_x,
float(exact_solution.lambda_x),
'config_manufactured_solution_wavelength_y':
exact_solution.lambda_y}
float(exact_solution.lambda_y)}
self.add_model_config_options(options)
54 changes: 48 additions & 6 deletions polaris/yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,30 @@ def read(cls, filename, package=None, replacements=None):
yaml.configs = configs
return yaml

def update(self, configs, quiet=True):
def update(self, configs=None, options=None, quiet=True):
"""
Add config options from a dictionary
Parameters
----------
configs : dict
configs : dict, optional
A nested dictionary of config sections, options and values
options : dict, optional
A flat dictionary of options and values
quiet : bool, optional
Whether or not to print the updated config options as they are
replaced
"""
if self.model in configs:
# we want one layer deeper
configs = configs[self.model]
_update_section(configs, self.configs, quiet)
if configs is not None:
if self.model in configs:
# we want one layer deeper
configs = configs[self.model]
_update_section(configs, self.configs, quiet)

if options is not None:
_update_options(options, self.configs, quiet)

def write(self, filename):
"""
Expand Down Expand Up @@ -275,6 +282,41 @@ def _update_section(src, dst, quiet, print_section=None):
dst[name] = src[name]


def _update_options(src, dst, quiet):
"""
Update config options by searching in the destination nested dictionary
"""
for name in src:
success = _update_option(name, src[name], dst, quiet)
if not success:
raise ValueError(
f'Attempting to modify a nonexistent config '
f'options: {name}')


def _update_option(option, value, dst, quiet, print_section=None):
"""
Recursively attempt to find and replace the value of the
given option
"""
for name in dst:
if isinstance(dst[name], (dict, OrderedDict)):
if print_section is not None:
print_subsection = f'{print_section}: {name}'
else:
print_subsection = name
success = _update_option(option, value, dst[name], quiet,
print_subsection)
if success:
return True
elif name == option:
dst[name] = value
if not quiet:
print(f' {print_section}: {name} = {value}')
return True
return False


def _read_namelist(namelist_template, namelist_filename):
""" Read the defaults file """
record_map = _read_namelist_template(namelist_template)
Expand Down

0 comments on commit 0cbc130

Please sign in to comment.