Skip to content

Commit

Permalink
Extend testing to handle dumping rho and sigma remapped diagnostics a…
Browse files Browse the repository at this point in the history
…s well as z. mom-ocean#328
  • Loading branch information
Nicholas Hannah committed Nov 17, 2016
1 parent 6110b55 commit 800027b
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 48 deletions.
2 changes: 2 additions & 0 deletions ice_ocean_SIS2/Baltic/MOM_input
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ NK = 63 ! [nondim]
! The number of model layers.

DIAG_REMAP_Z_GRID_DEF = "FILE:OM3_zgrid.nc,zw,zt"
DIAG_REMAP_RHO_GRID_DEF = "UNIFORM"
DIAG_REMAP_SIGMA_GRID_DEF = "UNIFORM"

! === module MOM_verticalGrid ===
! Parameters providing information about the vertical grid.
Expand Down
2 changes: 1 addition & 1 deletion src/MOM6
23 changes: 18 additions & 5 deletions tools/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ def pytest_generate_tests(metafunc):
Parameterize tests. Presently handles those that have 'exp' as an argument.
"""

print("Calling pytest_generate_tests")

if 'exp' in metafunc.fixturenames:
if metafunc.config.option.full:
# Run tests on all experiments.
Expand All @@ -49,13 +47,14 @@ def exp(request):
"""
exp = request.param

# Run the experiment to get latest code changes. This will do nothing if
# the experiment has already been run.
# Run the experiment to get latest code changes, and updates to the
# available_diags. This will do nothing if the experiment has already been
# run.
exp.run()
# Dump all available diagnostics, if they haven't been already.
if not exp.has_dumped_diags:
# Before dumping we delete old ones if they exist.
diags = exp.get_available_diags()
diags = exp.parse_available_diags()
for d in diags:
try:
os.remove(d.output)
Expand All @@ -66,6 +65,20 @@ def exp(request):
exp.has_dumped_diags = True
return exp


@pytest.fixture(scope='session')
def exp_diags_not_dumped():

exp = experiment_dict['ice_ocean_SIS2/Baltic']

# Run the experiment to get latest code changes, and updates to the
# available_diags. This will do nothing if the experiment has already been
# run.
exp.run()

return exp


def restore_after_test():
"""
Restore experiment state after running a test.
Expand Down
11 changes: 6 additions & 5 deletions tools/tests/dump_all_diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ def dump_diags(exp, diags):
with open(os.path.join(exp.path, 'diag_table'), 'w') as f:
print('All {} diags'.format(exp.name), file=f)
print('1 1 1 0 0 0', file=f)
for d in diags:
print('"{}_{}", 0, "seconds", 1, "seconds",' \
'"time"'.format(d.model, d.name), file=f)
for fname in list(set([d.filename for d in diags])):
print('"{}", 0, "seconds", 1, "seconds",' \
'"time"'.format(fname), file=f)
for d in diags:
m = d.model
n = d.name
print('"{}", "{}", "{}", "{}_{}", "all",' \
'.false., "none", 2'.format(m, n, n, m, n), file=f)
fname = d.filename
print('"{}", "{}", "{}", "{}", "all",' \
'.false., "none", 2'.format(m, n, n, fname, n), file=f)
return exp.force_run()

def main():
Expand Down
78 changes: 58 additions & 20 deletions tools/tests/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import os
import re
import shlex
import random
import subprocess as sp
import run_config as rc
from model import Model
Expand All @@ -17,18 +18,33 @@

class Diagnostic:

def __init__(self, model, name, path):
def __init__(self, model, name, path, packed=True):
self.model = model
self.name = name
self.full_name = '{}_{}'.format(model, name)
self.output = os.path.join(path, '00010101.{}.nc'.format(self.full_name))
self.run_path = path

# Hack to deal with FMS limitations, see https://github.com/NOAA-GFDL/FMS/issues/27
# Use fewer different files for diagnostics.
if packed:
letter = self.name[0]
self.packed_filename = '{}_{}'.format(self.model, letter)

self.unpacked_filename = '{}_{}'.format(self.model, self.name)

if packed:
self.filename = self.packed_filename
else:
self.filename = self.unpacked_filename

self.output = os.path.join(path, '00010101.{}.nc'.format(self.filename))

def __eq__(self, other):
return ((self.model, self.name, self.output) ==
(other.model, other.name, other.output))
return ((self.model, self.name) ==
(other.model, other.name))

def __hash__(self):
return hash(self.model + self.name + self.output)
return hash(self.full_name)


# Unfinished diagnostics are those which have been registered but have not been
Expand Down Expand Up @@ -101,6 +117,7 @@ def __init__(self, id, platform='raijin', compiler='gnu', build='DEBUG', memory_
self.has_run = False
# Another thing to avoid repeating.
self.has_dumped_diags = False
self.diags_parsed = False

def build_model(self):
"""
Expand Down Expand Up @@ -146,11 +163,19 @@ def force_run(self):

return ret

def _parse_available_diags(self):
def parse_available_diags(self, packed=True):
"""
Create a list of available diags for the experiment by parsing
available_diags.000001 and SIS.available_diags.
Return a list of the available diagnostics for this experiment by
parsing available_diags.000001 and SIS.available_diags.
The 'packed' argument is used to pack many diagnostics into a few
output files. Without this each diagnostic is in it's own file.
The experiment needs to have been run before calling this.
"""

assert self.has_run

mom_av_file = os.path.join(self.path, 'available_diags.000000')
sis_av_file = os.path.join(self.path, 'SIS.available_diags')

Expand All @@ -164,20 +189,14 @@ def _parse_available_diags(self):
# Pull out the model name and variable name.
matches = re.findall('^\"(\w+)\", \"(\w+)\".*$',
f.read(), re.MULTILINE)
diags.extend([Diagnostic(m, d, self.path) for m, d in matches])
return diags

def get_available_diags(self):
"""
Return a list of the available diagnostics for this experiment.
The experiment needs to have been run before calling this.
"""

assert self.has_run
for m, d in matches:
if m[-5:] == '_zold':
diags.append(Diagnostic(m, d, self.path, packed=False))
else:
diags.append(Diagnostic(m, d, self.path, packed))

# Lists of available and unfinished diagnostics.
self.available_diags = self._parse_available_diags()
self.available_diags = diags
self.unfinished_diags = [Diagnostic(m, d, self.path) \
for m, d in _unfinished_diags]
# Available diags is not what you think! Need to remove the unfinished
Expand All @@ -187,8 +206,27 @@ def get_available_diags(self):
# It helps with testing and human readability if this is sorted.
self.available_diags.sort(key=lambda d: d.full_name)

self.diags_parsed = True

return self.available_diags

def get_diags(self):

assert self.has_run
assert self.diags_parsed

return self.available_diags

def get_diags_dict(self):

diags = self.get_diags()

d = {}
for diag in diags:
d[diag.full_name] = diag

return d

def get_unfinished_diags(self):
"""
Return a list of the unfinished diagnostics for this experiment.
Expand Down
Loading

0 comments on commit 800027b

Please sign in to comment.