Skip to content

Commit

Permalink
Add fixed_geometry_mass_balance task (#1098)
Browse files Browse the repository at this point in the history
* Add fixed_geometry_mass_balance task

* fix doc
  • Loading branch information
fmaussion committed Nov 18, 2020
1 parent f71fe7d commit e20e673
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ __pycache__
# asv stuff
.asv/

# PyCharm stuffs
# IDE stuffs
.idea/
.vscode/

# coverage stuffs
.coverage
Expand Down Expand Up @@ -42,3 +43,4 @@ docs/_sources
docs/_images
docs/.doctrees
oggm/version.py
oggm/ignore
62 changes: 62 additions & 0 deletions oggm/core/massbalance.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
"""Mass-balance models"""
# Built ins
import logging
# External libs
import numpy as np
import pandas as pd
import netCDF4
from scipy.interpolate import interp1d
from scipy import optimize as optimization
Expand All @@ -12,7 +14,10 @@
date_to_floatyear, monthly_timeseries, ncDataset,
tolist, clip_min, clip_max, clip_array)
from oggm.exceptions import InvalidWorkflowError
from oggm import entity_task

# Module logger
log = logging.getLogger(__name__)

class MassBalanceModel(object, metaclass=SuperclassMeta):
"""Common logic for the mass balance models.
Expand Down Expand Up @@ -1122,3 +1127,60 @@ def get_ela(self, year=None, **kwargs):
areas = np.append(areas, np.sum(fl.widths))

return np.average(elas, weights=areas)


@entity_task(log)
def fixed_geometry_mass_balance(gdir, ys=None, ye=None, years=None,
monthly_step=False,
climate_filename='climate_historical',
climate_input_filesuffix=''):
"""Runs a glacier with climate input from e.g. CRU or a GCM.
This will initialize a
:py:class:`oggm.core.massbalance.MultipleFlowlineMassBalance`,
and run a :py:func:`oggm.core.flowline.robust_model_run`.
Parameters
----------
gdir : :py:class:`oggm.GlacierDirectory`
the glacier directory to process
ys : int
start year of the model run (default: from the climate file)
date)
ye : int
end year of the model run (default: from the climate file)
years : array of ints
override ys and ye with the years of your choice
monthly_step : bool
whether to store the diagnostic data at a monthly time step or not
(default is yearly)
climate_filename : str
name of the climate file, e.g. 'climate_historical' (default) or
'gcm_data'
climate_input_filesuffix: str
filesuffix for the input climate file
"""

if monthly_step:
raise NotImplementedError('monthly_step not implemented yet')

try:
mb = MultipleFlowlineMassBalance(gdir, mb_model_class=PastMassBalance,
filename=climate_filename,
input_filesuffix=climate_input_filesuffix)
except InvalidWorkflowError:
mb = MultipleFlowlineMassBalance(gdir, mb_model_class=PastMassBalance,
filename=climate_filename,
use_inversion_flowlines=True,
input_filesuffix=climate_input_filesuffix)

if years is None:
if ys is None:
ys = mb.flowline_mb_models[0].ys
if ye is None:
ye = mb.flowline_mb_models[0].ye
years = np.arange(ys, ye + 1)

odf = pd.Series(data=mb.get_specific_mb(year=years),
index=years)
return odf
1 change: 1 addition & 0 deletions oggm/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from oggm.core.climate import local_t_star
from oggm.core.climate import mu_star_calibration
from oggm.core.climate import apparent_mb_from_linear_mb
from oggm.core.massbalance import fixed_geometry_mass_balance
from oggm.core.inversion import prepare_for_inversion
from oggm.core.inversion import mass_conservation_inversion
from oggm.core.inversion import filter_inversion_output
Expand Down
3 changes: 3 additions & 0 deletions oggm/tests/test_benchmarks.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,9 @@ def test_workflow(self):
df = utils.compile_glacier_statistics(gdirs)
assert df.inv_thickness_m[0] < 100

df = utils.compile_fixed_geometry_mass_balance(gdirs)
assert len(df) > 100

if do_plot:
import matplotlib.pyplot as plt
from oggm.graphics import plot_inversion
Expand Down
13 changes: 13 additions & 0 deletions oggm/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,19 @@ def test_past_mb_model(self, hef_gdir):
mb_gw = mb_gw_mod.get_specific_mb(year=yrs)
assert_allclose(mb, mb_gw)

# Test massbalance task
s = massbalance.fixed_geometry_mass_balance(gdir)
assert s.index[0] == 1802
assert s.index[-1] == 2003

s = massbalance.fixed_geometry_mass_balance(gdir, ys=1990, ye=2000)
assert s.index[0] == 1990
assert s.index[-1] == 2000

s = massbalance.fixed_geometry_mass_balance(gdir,
years=mbdf.index.values)
assert_allclose(s, mbdf['MY_MB'])

@pytest.mark.parametrize("cl", [massbalance.PastMassBalance,
massbalance.ConstantMassBalance,
massbalance.RandomMassBalance])
Expand Down
43 changes: 43 additions & 0 deletions oggm/utils/_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,49 @@ def compile_glacier_statistics(gdirs, filesuffix='', path=True,
return out


def compile_fixed_geometry_mass_balance(gdirs, filesuffix='', path=True,
ys=None, ye=None, years=None):
"""Compiles a table of specific mass-balance timeseries for all glaciers.
Parameters
----------
gdirs : list of :py:class:`oggm.GlacierDirectory` objects
the glacier directories to process
filesuffix : str
add suffix to output file
path : str, bool
Set to "True" in order to store the info in the working directory
Set to a path to store the file to your chosen location
ys : int
start year of the model run (default: from the climate file)
date)
ye : int
end year of the model run (default: from the climate file)
years : array of ints
override ys and ye with the years of your choice
"""
from oggm.workflow import execute_entity_task
from oggm.core.massbalance import fixed_geometry_mass_balance

out_df = execute_entity_task(fixed_geometry_mass_balance, gdirs,
ys=ys, ye=ye, years=years)

for idx, s in enumerate(out_df):
if s is None:
out_df[idx] = pd.Series(np.NaN)

out = pd.concat(out_df, axis=1, keys=[gd.rgi_id for gd in gdirs])

if path:
if path is True:
out.to_csv(os.path.join(cfg.PATHS['working_dir'],
('fixed_geometry_mass_balance' +
filesuffix + '.csv')))
else:
out.to_csv(path)
return out


@entity_task(log)
def climate_statistics(gdir, add_climate_period=1995):
"""Gather as much statistics as possible about this glacier.
Expand Down

0 comments on commit e20e673

Please sign in to comment.