Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow special MB models to work even without t* #1464

Merged
merged 1 commit into from
Sep 6, 2022
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
20 changes: 4 additions & 16 deletions oggm/core/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -541,10 +541,7 @@ def mb_climate_on_height(gdir, heights, *, time_range=None, year_range=None):
"None if using a winter_prcp_factor")

# Have we decided on a factor yet?
try:
df = gdir.read_json('local_mustar')
except FileNotFoundError:
df = {}
df = gdir.read_json('local_mustar', allow_empty=True)
prcp_fac = df.get('glacier_prcp_scaling_factor')
if prcp_fac is None:
# Then decide and store
Expand Down Expand Up @@ -924,10 +921,7 @@ def _fallback_local_t_star(gdir):

"""
# Scalars in a small dict for later
try:
df = gdir.read_json('local_mustar')
except FileNotFoundError:
df = {}
df = gdir.read_json('local_mustar', allow_empty=True)
df['rgi_id'] = gdir.rgi_id
df['t_star'] = np.nan
df['bias'] = np.nan
Expand Down Expand Up @@ -1062,10 +1056,7 @@ def local_t_star(gdir, *, ref_df=None, tstar=None, bias=None,
'{:.2f}'.format(gdir.rgi_id, mustar))

# Scalars in a small dict for later
try:
df = gdir.read_json('local_mustar')
except FileNotFoundError:
df = {}
df = gdir.read_json('local_mustar', allow_empty=True)
df['rgi_id'] = gdir.rgi_id
df['t_star'] = int(tstar)
df['bias'] = bias
Expand Down Expand Up @@ -1574,10 +1565,7 @@ def mu_star_calibration_from_geodetic_mb(gdir,
gdir.write_json(out, 'climate_info')

# Store diagnostics
try:
df = gdir.read_json('local_mustar')
except FileNotFoundError:
df = {}
df = gdir.read_json('local_mustar', allow_empty=True)
df['rgi_id'] = gdir.rgi_id
df['t_star'] = np.nan
df['bias'] = 0
Expand Down
24 changes: 19 additions & 5 deletions oggm/core/massbalance.py
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,8 @@ def __init__(self, gdir, mu_star=None, bias=None,
you want to use (the default is to use the calibrated value)
y0 : int, optional, default: tstar
the year at the center of the period of interest. The default
is to use tstar as center.
is to use tstar as center. If t_star is not available, raises
an error.
halfsize : int, optional
the half-size of the time window (window size = 2 * halfsize + 1)
filename : str, optional
Expand All @@ -651,7 +652,10 @@ def __init__(self, gdir, mu_star=None, bias=None,

if y0 is None:
df = gdir.read_json('local_mustar')
y0 = df['t_star']
y0 = df.get('t_star', np.NaN)
if not np.isfinite(y0):
raise InvalidParamsError('t_star has not been set for this '
'glacier. Please set `y0` explicitly')

# This is a quick'n dirty optimisation
try:
Expand Down Expand Up @@ -851,7 +855,10 @@ def __init__(self, gdir, mu_star=None, bias=None,

if y0 is None:
df = gdir.read_json('local_mustar')
y0 = df['t_star']
y0 = df.get('t_star', np.NaN)
if not np.isfinite(y0):
raise InvalidParamsError('t_star has not been set for this '
'glacier. Please set `y0` explicitly')

self.mbmod = PastMassBalance(gdir, mu_star=mu_star, bias=bias,
filename=filename,
Expand Down Expand Up @@ -950,7 +957,10 @@ def __init__(self, gdir, mu_star=None, bias=None,
else:
if y0 is None:
df = gdir.read_json('local_mustar')
y0 = df['t_star']
y0 = df.get('t_star', np.NaN)
if not np.isfinite(y0):
raise InvalidParamsError('t_star has not been set for this '
'glacier. Please set `y0` explicitly')
self.years = np.arange(y0 - halfsize, y0 + halfsize + 1)
else:
self.rng = None
Expand Down Expand Up @@ -1247,7 +1257,11 @@ def __init__(self, gdir, fls=None, mu_star=None,
fl.rgi_id != gdir.rgi_id) and (_y0 is None):

df = gdir.read_json('local_mustar', filesuffix='_' + fl.rgi_id)
kwargs['y0'] = df['t_star']
y0 = df.get('t_star', np.NaN)
if not np.isfinite(y0):
raise InvalidParamsError('t_star has not been set for this '
'glacier. Please set `y0` explicitly')
kwargs['y0'] = y0

self.flowline_mb_models.append(
mb_model_class(gdir, mu_star=fl.mu_star, bias=fl_bias,
Expand Down
6 changes: 6 additions & 0 deletions oggm/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1065,10 +1065,16 @@ def test_hef_mu_star_calibration_from_geodetic_mb(self, hef_gdir):

np.testing.assert_allclose(ref_mb_geodetic, mb_modelled.mean())
np.testing.assert_allclose(pf, 3.35713, rtol=1e-4)

with pytest.raises(InvalidParamsError):
# This does not work
mb = massbalance.ConstantMassBalance(gdir)

cfg.PARAMS['use_winter_prcp_factor'] = False
cfg.PARAMS['prcp_scaling_factor'] = prev_fac



class TestModelFlowlines():

def test_rectangular(self):
Expand Down
15 changes: 12 additions & 3 deletions oggm/utils/_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -3067,7 +3067,7 @@ def write_pickle(self, var, filename, use_compression=None, filesuffix=''):
with _open(fp, 'wb') as f:
pickle.dump(var, f, protocol=4)

def read_json(self, filename, filesuffix=''):
def read_json(self, filename, filesuffix='', allow_empty=False):
"""Reads a JSON file located in the directory.

Parameters
Expand All @@ -3076,6 +3076,8 @@ def read_json(self, filename, filesuffix=''):
file name (must be listed in cfg.BASENAME)
filesuffix : str
append a suffix to the filename (useful for experiments).
allow_empty : bool
if True, does not raise an error if the file is not there.

Returns
-------
Expand All @@ -3087,8 +3089,15 @@ def read_json(self, filename, filesuffix=''):
return self._read_deprecated_climate_info()

fp = self.get_filepath(filename, filesuffix=filesuffix)
with open(fp, 'r') as f:
out = json.load(f)
if allow_empty:
try:
with open(fp, 'r') as f:
out = json.load(f)
except FileNotFoundError:
out = {}
else:
with open(fp, 'r') as f:
out = json.load(f)
return out

def write_json(self, var, filename, filesuffix=''):
Expand Down