Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions polaris/model_step.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,11 +338,15 @@ def map_yaml_options(self, options, config_model):

Returns
-------
options : dict
options : dict or None
A revised dictionary of yaml options and value to use as
replacements for existing values

configs : dict or None
A revised nested dictionary of yaml sections, options and value to
use as replacements for existing values
"""
return options
return options, None

def map_yaml_configs(self, configs, config_model):
"""
Expand Down Expand Up @@ -732,11 +736,18 @@ def _process_namelists(self, quiet):
):
# this is a dictionary of replacement model config options
options = entry['options']
options = self.map_yaml_options(
options, configs = self.map_yaml_options(
options=entry['options'], config_model=config_model
)
options = self.map_yaml_to_namelist(options)
replacements.update(options)
if options is not None:
options = self.map_yaml_to_namelist(options)
replacements.update(options)
if configs is not None:
configs = self.map_yaml_configs(
configs=configs, config_model=config_model
)
configs = self.map_yaml_to_namelist(configs)
replacements.update(configs)
if 'yaml' in entry:
yaml = PolarisYaml.read(
filename=entry['yaml'],
Expand Down Expand Up @@ -896,10 +907,13 @@ def _process_yaml(self, quiet, remove_unrequested_streams):
):
# this is a dictionary of replacement model config options
options = entry['options']
options = self.map_yaml_options(
options, configs = self.map_yaml_options(
options=entry['options'], config_model=config_model
)
self._yaml.update(options=options, quiet=quiet)
if options is not None:
self._yaml.update(options=options, quiet=quiet)
if configs is not None:
self._yaml.update(configs=configs, quiet=quiet)
if 'yaml' in entry:
yaml = PolarisYaml.read(
filename=entry['yaml'],
Expand Down
117 changes: 38 additions & 79 deletions polaris/ocean/model/ocean_model_step.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
MapSectionKey = Union[str, List[str]]
# in principle, any number of levels but 4 seems sufficient for now
ConfigsType = Dict[
str,
Union[str, None],
Union[
Dict[str, OptionValue],
Dict[str, Dict[str, OptionValue]],
Expand Down Expand Up @@ -238,7 +238,7 @@ def map_yaml_options(
self,
options: Dict[str, OptionValue],
config_model: Optional[str],
) -> Dict[str, OptionValue]:
) -> Tuple[Optional[Dict[str, OptionValue]], Optional[ConfigsType]]:
"""
A mapping between model config options from MPAS-Ocean to Omega

Expand All @@ -254,15 +254,23 @@ def map_yaml_options(

Returns
-------
options : dict
options : dict or None
A revised dictionary of yaml options and value to use as
replacements for existing values

configs : dict or None
A revised nested dictionary of yaml sections, options and value to
use as replacements for existing values
"""
config = self.config
model = config.get('ocean', 'model')
if model == 'omega' and config_model == 'ocean':
options = self._map_mpaso_to_omega_options(options)
return options
# make a dummy configs dict with None as the section
mpaso_configs: ConfigsType = {None: options}
configs = self._map_mpaso_to_omega_configs(mpaso_configs)
return None, configs
else:
return options, None

def map_yaml_configs(
self,
Expand Down Expand Up @@ -529,60 +537,6 @@ def _read_config_map(self) -> None:
nested_dict = yaml_data.load(text)
self.config_map = nested_dict['config']

def _map_mpaso_to_omega_options(
self,
options: Dict[str, OptionValue],
) -> Dict[str, OptionValue]:
"""
Map MPAS-Ocean namelist options to Omega config options
"""

out_options: Dict[str, OptionValue] = {}
not_found = []
for mpaso_option, mpaso_value in options.items():
try:
omega_option, omega_value = self._map_mpaso_to_omega_option(
option=mpaso_option, value=mpaso_value
)
out_options[omega_option] = omega_value
except ValueError:
not_found.append(mpaso_option)

self._warn_not_found(not_found)

return out_options

def _map_mpaso_to_omega_option(
self,
option: str,
value: OptionValue,
) -> Tuple[str, OptionValue]:
"""
Map MPAS-Ocean namelist option to Omega equivalent
"""
out_option = option
found = False

assert self.config_map is not None
# traverse the map
for entry in self.config_map:
options_dict = entry['options']
for mpaso_option, omega_option in options_dict.items():
if option == mpaso_option:
found = True
out_option = omega_option
break

if found:
break

if not found:
raise ValueError(f'No mapping found for {option}')

out_option, out_value = self._map_handle_not(out_option, value)

return out_option, out_value

def _map_mpaso_to_omega_configs(
self,
configs: ConfigsType,
Expand All @@ -605,7 +559,7 @@ def _map_mpaso_to_omega_configs(
section=section, option=option, value=mpaso_value
)
)
local_config: Dict[str, Any] = out_configs
local_config: Dict[str | None, Any] = out_configs
sec_str = '/'.join(omega_sections)
for omega_section in omega_sections:
if omega_section not in local_config:
Expand All @@ -626,14 +580,14 @@ def _map_mpaso_to_omega_configs(

def _map_mpaso_to_omega_section_option(
self,
section: str,
option: str,
value: OptionValue,
section: str | None = None,
) -> Tuple[List[str], str, OptionValue]:
"""
Map MPAS-Ocean namelist section and option to Omega equivalent
"""
out_sections: List[str] = [section]
out_sections: List[str] = []
out_option = option

assert self.config_map is not None
Expand All @@ -642,27 +596,32 @@ def _map_mpaso_to_omega_section_option(
# traverse the map
for entry in self.config_map:
section_dict = entry['section']
if len(section_dict) != 1:
raise ValueError(
'Mapping entries must have exactly one section'
)

mpaso_section = next(iter(section_dict))
omega_sections: MapSectionKey = section_dict[mpaso_section]
if section is not None and mpaso_section != section:
continue

options_dict = entry['options']
option_found = False
try:
omega_section: MapSectionKey = section_dict[section]
omega_option = options_dict[option]
except KeyError:
continue
else:
options_dict = entry['options']
option_found = False
try:
omega_option = options_dict[option]
except KeyError:
continue
else:
option_found = True
# make sure out_sections is a list
out_sections = (
omega_section
if isinstance(omega_section, list)
else [omega_section]
)
out_option = omega_option
break
option_found = True
# make sure out_sections is a list
out_sections = (
omega_sections
if isinstance(omega_sections, list)
else [omega_sections]
)
out_option = omega_option
break

if not option_found:
sec_str = (
Expand Down
Loading