Skip to content

Commit

Permalink
Merge branch 'development' into fe_updates_from_uci
Browse files Browse the repository at this point in the history
  • Loading branch information
mnlevy1981 committed May 24, 2024
2 parents 6681874 + ece907b commit caf8308
Show file tree
Hide file tree
Showing 84 changed files with 17,613 additions and 6,265 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/run_test_suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ jobs:
strategy:
matrix:
python-version:
- 3.7
- 3.9

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

Expand Down
22 changes: 19 additions & 3 deletions MARBL_tools/MARBL_diagnostics_file_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class MARBL_diagnostics_class(object):
# CONSTRUCTOR #
###############

def __init__(self, default_diagnostics_file, MARBL_settings):
def __init__(self, default_diagnostics_file, MARBL_settings, unit_system):
""" Class constructor: read the JSON file and then construct self.diagnostics_dict
"""

Expand Down Expand Up @@ -44,7 +44,7 @@ def __init__(self, default_diagnostics_file, MARBL_settings):
self.diagnostics_dict[diag_name] = dict(self._diagnostics[diag_name])
else:
# (Also determine correct frequency if 'frequency' is a dict)
self.diagnostics_dict.update(MARBL_tools.expand_template_value(diag_name, MARBL_settings, self._diagnostics[diag_name], check_freq=True))
self.diagnostics_dict.update(MARBL_tools.expand_template_value(diag_name, MARBL_settings, unit_system, self._diagnostics[diag_name], check_freq=True))

# ii. Delete diagnostics where dependencies are not met
# (Some diagnostics have already been removed via expand_template_value())
Expand All @@ -53,10 +53,26 @@ def __init__(self, default_diagnostics_file, MARBL_settings):
diags_to_delete.append(diag_name)
continue

# iii. frequency and operator should always be lists
# iii. frequency, operator, and diag_mode should always be lists
if not isinstance(self.diagnostics_dict[diag_name]['frequency'], list):
self.diagnostics_dict[diag_name]['frequency'] = [self.diagnostics_dict[diag_name]['frequency']]
self.diagnostics_dict[diag_name]['operator'] = [self.diagnostics_dict[diag_name]['operator']]
self.diagnostics_dict[diag_name]['diag_mode'] = [self.diagnostics_dict[diag_name]['diag_mode']]

# iv. update units
fix_units = {}
if unit_system == 'cgs':
fix_units["mmol/m^3 cm"] = "nmol/cm^2"
fix_units["mmol/m^3"] = "nmol/cm^3"
fix_units["meq/m^3"] = "neq/cm^3"
else:
fix_units["mmol/m^3 cm"] = "mmol/m^2"
fix_units["nmol/cm^2"] = "mmol/m^2"
fix_units["g/cm"] = "kg/m"
fix_units["cm"] = "m"

for key, value in fix_units.items():
self.diagnostics_dict[diag_name]["units"] = str(self.diagnostics_dict[diag_name]["units"]).replace(key, value)

for diag_name in diags_to_delete:
del self.diagnostics_dict[diag_name]
60 changes: 44 additions & 16 deletions MARBL_tools/MARBL_generate_diagnostics_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,30 @@
(default: None)
-o DIAGNOSTICS_FILE_OUT, --diagnostics_file_out DIAGNOSTICS_FILE_OUT
Name of file to be written (default: marbl.diags)
-u {cgs,mks}, --unit_system {cgs,mks}
Unit system for parameter values (default: cgs)
-a, --append Append to existing diagnostics file (default: False)
"""

if __name__ == "__main__":
# We need marbl_root in python path so we can import MARBL_tools from generate_settings_file()
import argparse
import os
import sys
marbl_root = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..'))
sys.path.append(marbl_root)
from MARBL_tools import MARBL_settings_class
from MARBL_tools import MARBL_diagnostics_class

import logging
from MARBL_tools.MARBL_utils import valid_diag_modes

#######################################

def generate_diagnostics_file(MARBL_diagnostics, diagnostics_file_out, append=False):
def generate_diagnostics_file(MARBL_diagnostics, diagnostics_file_out, diag_mode="full", append=False):
""" Produce a list of MARBL diagnostic frequencies and operators from a JSON parameter file
"""

import logging
logger = logging.getLogger(__name__)

if not append:
Expand Down Expand Up @@ -82,12 +96,18 @@ def generate_diagnostics_file(MARBL_diagnostics, diagnostics_file_out, append=Fa
# is also a dictionary containing frequency and operator information. Note that
# string values of frequency and operator are converted to lists of len 1 when the
# JSON file that generates this list is processed
diag_mode_opts = valid_diag_modes()
diag_mode_in = diag_mode_opts.index(diag_mode)
for diag_name in sorted(MARBL_diagnostics.diagnostics_dict.keys()):
frequencies = MARBL_diagnostics.diagnostics_dict[diag_name]['frequency']
operators = MARBL_diagnostics.diagnostics_dict[diag_name]['operator']
diag_modes = MARBL_diagnostics.diagnostics_dict[diag_name]['diag_mode']
freq_op = []
for freq, op in zip(frequencies, operators):
freq_op.append(freq + '_' + op)
for freq, op, dm in zip(frequencies, operators, diag_modes):
if diag_mode_in >= diag_mode_opts.index(dm):
freq_op.append(freq + '_' + op)
elif not freq_op: # Only append "never_{op}" if freq_op is empty list
freq_op.append('never_' + op)
fout.write("%s : %s\n" % (diag_name, ", ".join(freq_op)))
fout.close()

Expand All @@ -97,8 +117,6 @@ def _parse_args(marbl_root):
""" Parse command line arguments
"""

import argparse

parser = argparse.ArgumentParser(description="Generate a MARBL settings file from a JSON file",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)

Expand All @@ -114,7 +132,7 @@ def _parse_args(marbl_root):

# Is the GCM providing initial bury coefficients via saved state?
parser.add_argument('-v', '--saved_state_vars_source', action='store', dest='saved_state_vars_source',
default='settings_file', choices = set(('settings_file', 'GCM')),
default='settings_file', choices=['settings_file', 'GCM'],
help="Source of initial value for saved state vars that can come from GCM or settings file")

# Command line argument to specify resolution (default is None)
Expand All @@ -129,30 +147,40 @@ def _parse_args(marbl_root):
parser.add_argument('-o', '--diagnostics_file_out', action='store', dest='diagnostics_file_out', default='marbl.diags',
help='Name of file to be written')

# Command line argument to where to write the settings file being generated
parser.add_argument('-u', '--unit_system', action='store', dest='unit_system', default='cgs',
choices=['cgs', 'mks'], help='Unit system for parameter values')

# Diagnostic mode (level of output to include)
parser.add_argument('-m', '--diag-mode', action='store', dest='diag_mode', default='full',
choices=valid_diag_modes(),
help='Level of output to include')

# Append to existing diagnostics file?
parser.add_argument('-a', '--append', action='store_true', dest='append',
help='Append to existing diagnostics file')

return parser.parse_args()

#######################################

if __name__ == "__main__":
# We need marbl_root in python path so we can import MARBL_tools from generate_settings_file()
import sys, os
marbl_root = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..'))
sys.path.append(marbl_root)

# Parse command-line arguments (marbl_root is used to set default for JSON file location)
args = _parse_args(marbl_root)

# Set up logging
import logging
logging.basicConfig(format='%(levelname)s (%(funcName)s): %(message)s', level=logging.DEBUG)

from MARBL_tools import MARBL_settings_class
from MARBL_tools import MARBL_diagnostics_class
DefaultSettings = MARBL_settings_class(args.default_settings_file, args.saved_state_vars_source, args.grid, args.settings_file_in)
MARBL_diagnostics = MARBL_diagnostics_class(args.default_diagnostics_file, DefaultSettings)
DefaultSettings = MARBL_settings_class(args.default_settings_file,
args.saved_state_vars_source,
grid=args.grid,
input_file=args.settings_file_in,
unit_system=args.unit_system)
MARBL_diagnostics = MARBL_diagnostics_class(args.default_diagnostics_file, DefaultSettings,
args.unit_system)

# Write the diagnostic file
generate_diagnostics_file(MARBL_diagnostics, args.diagnostics_file_out, args.append)
generate_diagnostics_file(MARBL_diagnostics, args.diagnostics_file_out, args.diag_mode, args.append)
38 changes: 32 additions & 6 deletions MARBL_tools/MARBL_generate_settings_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
A file that overrides values in JSON (default: None)
-o SETTINGS_FILE_OUT, --settings_file_out SETTINGS_FILE_OUT
Name of file to be written (default: marbl.settings)
-u {cgs,mks}, --unit_system {cgs,mks}
Unit system for parameter values (default: cgs)
"""

#######################################
Expand All @@ -44,12 +45,19 @@ def generate_settings_file(MARBL_settings, settings_file_out):

fout = open(settings_file_out,"w")
# Sort variables by subcategory
written_any = False
for subcat_name in MARBL_settings.get_subcategory_names():
fout.write("! %s\n" % subcat_name.split('. ')[1])
header = "! %s\n" % subcat_name.split('. ')[1]
var_values = []
for varname in MARBL_settings.get_settings_dict_variable_names(subcat_name):
fout.write("%s = %s\n" % (varname, MARBL_settings.settings_dict[varname]['value']))
if subcat_name != MARBL_settings.get_subcategory_names()[-1]:
fout.write("\n")
var_values.append("%s = %s\n" % (varname, MARBL_settings.settings_dict[varname]['value']))
if len(var_values) > 0:
if written_any:
fout.write("\n")
written_any = True
fout.write(header)
for line in var_values:
fout.write(line)
fout.close()

#######################################
Expand All @@ -73,6 +81,14 @@ def _parse_args(marbl_root):
default='settings_file', choices = set(('settings_file', 'GCM')),
help="Source of initial value for saved state vars that can come from GCM or settings file")

# Command line flag to turn off the base biotic tracers
parser.add_argument('--disable-base-bio', action='store_false', dest='base_bio_on',
help='Turn off base biotic tracer module (default is on)')

# Command line flag to turn on the abiotic DIC tracers
parser.add_argument('--enable-abio-dic', action='store_true', dest='abio_dic_on',
help='Turn on abiotic DIC tracer module (default is off)')

# Command line argument to specify resolution (default is None)
parser.add_argument('-g', '--grid', action='store', dest='grid',
help='Some default values are grid-dependent')
Expand All @@ -85,6 +101,10 @@ def _parse_args(marbl_root):
parser.add_argument('-o', '--settings_file_out', action='store', dest='settings_file_out', default='marbl.settings',
help='Name of file to be written')

# Command line argument to where to write the settings file being generated
parser.add_argument('-u', '--unit_system', action='store', dest='unit_system', default='cgs',
choices=['cgs', 'mks'], help='Unit system for parameter values')

return parser.parse_args()

#######################################
Expand All @@ -103,7 +123,13 @@ def _parse_args(marbl_root):
logging.basicConfig(format='%(levelname)s (%(funcName)s): %(message)s', level=logging.DEBUG)

from MARBL_tools import MARBL_settings_class
DefaultSettings = MARBL_settings_class(args.default_settings_file, args.saved_state_vars_source, args.grid, args.settings_file_in)
DefaultSettings = MARBL_settings_class(args.default_settings_file,
args.saved_state_vars_source,
args.base_bio_on,
args.abio_dic_on,
args.grid,
args.settings_file_in,
args.unit_system)

# Write the settings file
generate_settings_file(DefaultSettings, args.settings_file_out)
Loading

0 comments on commit caf8308

Please sign in to comment.