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

Rename to AGILE #34

Merged
merged 4 commits into from
Jul 12, 2023
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
2 changes: 1 addition & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[run]
source = combine1d
source = agile1d
omit =
*/tests/*
*/_version.py
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
id: push-image
uses: OGGM/docker-build-and-push-action@v2
with:
only_on_repo: OGGM/COMBINE
only_on_repo: OGGM/AGILE
user: ${{ github.actor }}
pass: ${{ github.token }}
registry: ghcr.io
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# COMBINE
COMBINE - COst Minimization Bed INvErsion model for ice caps and valley glaciers
# AGILE
AGILE - Open Global Glacier Data Assimilation Framework

Work in progress!

This project is an adaption/extension to [OGGM](https://github.com/OGGM/oggm) and utilizes its dynamical model together with backwards functionalities (Automatic/Algorithmic Differentiation) of [PyTorch](https://pytorch.org/) to enable a cost function based inversion of bedrock topography.
This project is an adaption/extension to [OGGM](https://github.com/OGGM/oggm) and utilizes its dynamical model together with backwards functionalities (Automatic/Algorithmic Differentiation) of [PyTorch](https://pytorch.org/) to enable a cost function based assimilation.

COMBINE2D is based on a dynamical 2D Shallow-Ice-Approximation model, using surface outlines, surface topography, surface mass-balance time series and optionally also existing ice thickness measurements for ice caps. For further information look at the [master thesis](https://diglib.uibk.ac.at/ulbtirolhs/content/titleinfo/3086935/full.pdf) of @phigre ([Repository stage of master thesis](https://github.com/OGGM/COMBINE/tree/04aa57353f72f272a264be5a4c683ffa7dc5bf0f)).
agile2D (previously called combine2d) is based on a dynamical 2D Shallow-Ice-Approximation model, using surface outlines, surface topography, surface mass-balance time series and optionally also existing ice thickness measurements for ice caps. For further information look at the [master thesis](https://diglib.uibk.ac.at/ulbtirolhs/content/titleinfo/3086935/full.pdf) of @phigre ([Repository stage of master thesis](https://github.com/OGGM/agile/tree/04aa57353f72f272a264be5a4c683ffa7dc5bf0f)).

COMBINE1D is based on a dynamical 1D or flowline model, using flowline surface heights and widths as well as surface mass-balance time series for valley glaciers. For further information look at the [master thesis](https://diglib.uibk.ac.at/ulbtirolhs/content/titleinfo/6139027/full.pdf) of @pat-schmitt ([Repository stage of master thesis](https://github.com/OGGM/COMBINE/tree/bf2f7372787adf3e4f31ba5fd56e8968b9fb3347)).
agile1D (previously called combine1d) is based on a dynamical 1D or flowline model, using flowline surface heights and widths as well as surface mass-balance time series for valley glaciers. For further information look at the [master thesis](https://diglib.uibk.ac.at/ulbtirolhs/content/titleinfo/6139027/full.pdf) of @pat-schmitt ([Repository stage of master thesis](https://github.com/OGGM/agile/tree/bf2f7372787adf3e4f31ba5fd56e8968b9fb3347)).
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import time
from functools import partial

from combine1d.core.dynamics import run_model_and_get_temporal_model_data
from combine1d.core.massbalance import ConstantMassBalanceTorch, MBModelTorchWrapper
from combine1d.core.flowline import MixedBedFlowline, FluxBasedModel
from agile1d.core.dynamics import run_model_and_get_temporal_model_data
from agile1d.core.massbalance import ConstantMassBalanceTorch, MBModelTorchWrapper
from agile1d.core.flowline import MixedBedFlowline, FluxBasedModel
from oggm.core.flowline import MixedBedFlowline as OggmFlowline
from oggm.core.massbalance import MonthlyTIModel, ConstantMassBalance
from oggm import cfg
Expand Down Expand Up @@ -221,7 +221,7 @@ def cost_fct(unknown_parameters, data_logger):
Unknown parameter values for the optimisation variable (ice part of
the glacier). For simultaneously optimisation of two variables contains
both unknown variables consecutively.
data_logger : :py:class:`combine.core.data_logging.DataLogger`
data_logger : :py:class:`agile.core.data_logging.DataLogger`
Keep track of all variables during the calculation.

Returns
Expand Down Expand Up @@ -881,7 +881,7 @@ def detach_flowline(final_fl_in):
bed_h=final_fl_in.bed_h.detach().to('cpu').numpy().astype(np.float64),
section=final_fl_in.section.detach().to('cpu').numpy().astype(np.float64),
bed_shape=final_fl_in.bed_shape.detach().to('cpu').numpy().astype(np.float64),
# here we need 'logical_or' as COMBINE separates rectangular and
# here we need 'logical_or' as agile separates rectangular and
# trapezoidal whereas OGGM do not separate
is_trapezoid=np.logical_or(
final_fl_in.is_trapezoid.detach().to('cpu').numpy().astype(bool),
Expand Down
14 changes: 7 additions & 7 deletions combine1d/core/data_logging.py → agile1d/core/data_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import numpy as np
import xarray as xr
import time
from combine1d.core.arithmetics import RMSE, mean_BIAS, max_dif
from combine1d.core.exception import MaxCalculationTimeReached
from combine1d.core.flowline import FluxBasedModel, SemiImplicitModel
from agile1d.core.arithmetics import RMSE, mean_BIAS, max_dif
from agile1d.core.exception import MaxCalculationTimeReached
from agile1d.core.flowline import FluxBasedModel, SemiImplicitModel
import os
import warnings
import copy
Expand Down Expand Up @@ -117,7 +117,7 @@ def __init__(self, gdir, fls_init, inversion_input, climate_filename,
self.is_rectangular = self.flowline_init.is_rectangular
self.is_parabolic = ~self.flowline_init.is_trapezoid
else:
raise TypeError('COMBINE 1D only works with MixedBedFlowline!')
raise TypeError('agile 1D only works with MixedBedFlowline!')

self.climate_filename = climate_filename
self.climate_filesuffix = climate_filesuffix
Expand Down Expand Up @@ -338,11 +338,11 @@ def create_and_save_dataset(self):
# b = pickle.load(handle)


def initialise_DataLogger(gdir, inversion_input_filesuffix='_combine',
def initialise_DataLogger(gdir, inversion_input_filesuffix='_agile',
init_model_filesuffix=None,
init_model_fls='_trapezoidal',
climate_filename='climate_historical',
climate_filesuffix='', output_filesuffix='_combine',
climate_filesuffix='', output_filesuffix='_agile',
output_filepath=None):
'''
extract information out of gdir and save in datalogger. TODO
Expand All @@ -362,7 +362,7 @@ def initialise_DataLogger(gdir, inversion_input_filesuffix='_combine',
fls_init = copy.deepcopy(init_model_fls)

if len(fls_init) > 1:
raise NotImplementedError('COMBINE only works with single flowlines!')
raise NotImplementedError('agile only works with single flowlines!')

# include check if inversion_input file exist
if not os.path.isfile(gdir.get_filepath('inversion_input',
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
8 changes: 4 additions & 4 deletions combine1d/core/flowline.py → agile1d/core/flowline.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from oggm.core.flowline import FlowlineModel as FlowlineModelOGGM

# help function for gradient calculation
from combine1d.core.special_gradient_functions import para_width_from_thick,\
from agile1d.core.special_gradient_functions import para_width_from_thick,\
para_thick_from_section, SolveBandedPyTorch

# Constants
Expand Down Expand Up @@ -833,7 +833,7 @@ def run_until_and_store(self, y1,


class RectangularBedDiffusiveFlowlineModel(FlowlineModelTorch):
"""A rectangular bed diffusive model, not used in the Thesis of COMBINE1D.
"""A rectangular bed diffusive model, not used in the Thesis of agile1D.
The actual model, only valid for RectangularBedFlowline"""

def __init__(self, flowlines, mb_model=None, y0=0., glen_a=None, fs=0.,
Expand Down Expand Up @@ -861,7 +861,7 @@ def __init__(self, flowlines, mb_model=None, y0=0., glen_a=None, fs=0.,
raise ValueError('Model does not work with tributaries.')

# TODO: check if RectangularBedFlowline
# if type(self.fls[0]) == combine.core.flowline_adapted.RectangularBedFlowline:
# if type(self.fls[0]) == agile.core.flowline_adapted.RectangularBedFlowline:
# raise TypeError('Only can use RectangularBedFlowline')

self.dt_warning = False,
Expand Down Expand Up @@ -1105,7 +1105,7 @@ def step(self, dt):
if (dt_use != dt) and (dt_use / self.max_dt < 0.0001):
raise MemoryError('Stopping dynamics run to avoid memory overflow')

# get massbalance with COMBINE MassBalanceModel
# get massbalance with agile MassBalanceModel
m_dot = self.get_mb(S,
year=self.yr,
fl_id=0) # 0 because only one flowline
Expand Down
28 changes: 14 additions & 14 deletions combine1d/core/inversion.py → agile1d/core/inversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@
import time

# External libs
from combine1d.core.dynamics import run_model_and_get_model_values
from combine1d.core.flowline import MixedBedFlowline
from agile1d.core.dynamics import run_model_and_get_model_values
from agile1d.core.flowline import MixedBedFlowline
from scipy.optimize import minimize, Bounds
import numpy as np

# Locals
from oggm import utils, cfg, workflow, tasks, entity_task
from oggm.cfg import G
from combine1d.core.cost_function import create_cost_fct, initialise_mb_models, \
from agile1d.core.cost_function import create_cost_fct, initialise_mb_models, \
initialise_flowline, do_height_shift_spinup
from combine1d.core.data_logging import initialise_DataLogger
from combine1d.core.exception import MaxCalculationTimeReached
from combine1d.core.first_guess import get_first_guess
from agile1d.core.data_logging import initialise_DataLogger
from agile1d.core.exception import MaxCalculationTimeReached
from agile1d.core.first_guess import get_first_guess

# Module logger
log = logging.getLogger(__name__)
Expand Down Expand Up @@ -200,8 +200,8 @@ def add_setting():
_key = "experiment_description"
_doc = "Explanation of the current experiment. If a dataset is saved this" \
"is the filename of the resulting nc datafile. " \
"Default: 'COMBINE_inversion_results'"
_default = 'COMBINE_inversion_results'
"Default: 'agile_inversion_results'"
_default = 'agile_inversion_results'
add_setting()

_key = "spinup_options"
Expand All @@ -228,7 +228,7 @@ def add_setting():
"control variable (with constant dx also can be considered as " \
" initial volume distribution), it is similar to 'surface_h' option " \
"but also takes grid cells of different sizes into account. It " \
"should be combined with a regularisation term which smoothes the " \
"should be agiled with a regularisation term which smoothes the " \
"initial ice flux. With 'extra_grid_points' you can define how " \
"many grid points you want to allow an advance/retreat of the " \
"glacier at the inital state." \
Expand Down Expand Up @@ -291,8 +291,8 @@ def add_setting():


@entity_task(log, writes=['inversion_input'])
def prepare_for_combine_inversion(gdir, inversion_settings=None,
filesuffix='_combine'):
def prepare_for_agile_inversion(gdir, inversion_settings=None,
filesuffix='_agile'):
"""TODO
"""
if inversion_settings is None:
Expand Down Expand Up @@ -458,10 +458,10 @@ def save_past_evolution_to_disk(gdir, data_logger):


@entity_task(log, writes=['model_flowlines'])
def combine_inversion(gdir, inversion_input_filesuffix='_combine',
def agile_inversion(gdir, inversion_input_filesuffix='_agile',
init_model_filesuffix=None, init_model_fls='_trapezoidal',
climate_filename='climate_historical',
climate_filesuffix='', output_filesuffix='_combine_output',
climate_filesuffix='', output_filesuffix='_agile_output',
output_filepath=None, save_dataset=True,
give_data_logger_back=False, save_past_evolution=True):
"""TODO
Expand Down Expand Up @@ -527,7 +527,7 @@ def combine_inversion(gdir, inversion_input_filesuffix='_combine',

gdir.write_pickle(data_logger.flowlines[-1], 'model_flowlines',
filesuffix=output_filesuffix)
log.debug('Combine Inversion finished')
log.debug('agile Inversion finished')

if give_data_logger_back:
return data_logger
Expand Down
4 changes: 2 additions & 2 deletions combine1d/core/massbalance.py → agile1d/core/massbalance.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
from oggm.utils import SuperclassMeta, ncDataset
from oggm.utils._funcs import date_to_floatyear, floatyear_to_date

# packages for COMBINE
# packages for agile
import torch

# help functions
from combine1d.core.torch_interp1d import Interp1d
from agile1d.core.torch_interp1d import Interp1d

# other stuff
from functools import partial
Expand Down
File renamed without changes.
6 changes: 3 additions & 3 deletions combine1d/core/utils.py → agile1d/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from oggm.utils import GlacierDirectory, mkdir
from oggm.utils._funcs import multipolygon_to_polygon
from oggm.exceptions import InvalidParamsError
from combine2d.core.data_logging import write_pickle, load_pickle
from agile2d.core.data_logging import write_pickle, load_pickle
# TODO: move pickle methods


Expand All @@ -24,7 +24,7 @@ class InversionGlacierDirectory(GlacierDirectory):

def __init__(self, rgi_entity, base_dir=None, reset=False, from_tar=False, delete_tar=False):
"""
Initializes the glacier directory for COMBINE
Initializes the glacier directory for agile

TODO
"""
Expand All @@ -33,7 +33,7 @@ def __init__(self, rgi_entity, base_dir=None, reset=False, from_tar=False, delet

# add aditional BASENAMES used by the Inversion
cfg.add_to_basenames('inversion_settings', 'inversion_settings.pkl', 'Contains the needed information for the '
'COMBINE inversion. TODO: doc needed '
'agile inversion. TODO: doc needed '
'information')


Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def calculate_result_statistics(gdir, data_logger, print_statistic=False):
ds.unknown_parameters[-1][control_indices[control_var]].values
controls_true = {}
fls_true = gdir.read_pickle('model_flowlines',
filesuffix='_combine_true_init')[0]
filesuffix='_agile_true_init')[0]
for control_var in controls_mdl:
if control_var in ['bed_h', 'area_bed_h']:
controls_true[control_var] = \
Expand Down Expand Up @@ -149,7 +149,7 @@ def get_volume(fl):
with xr.open_dataset(fp) as ds_diag:
past_evol_mdl = ds_diag.load()
fp = gdir.get_filepath('model_diagnostics',
filesuffix='_combine_true_total_run')
filesuffix='_agile_true_total_run')
with xr.open_dataset(fp) as ds_diag:
past_evol_true = ds_diag.load()

Expand All @@ -164,7 +164,7 @@ def get_volume(fl):
# how well do we match today's glacier state ------------------------------
fls_end_mdl = data_logger.flowlines[-1]
fls_end_true = gdir.read_pickle('model_flowlines',
filesuffix='_combine_true_end')[0]
filesuffix='_agile_true_end')[0]

today_state_stats = {}
for var in ['thick', 'area_m2', 'volume_m3']:
Expand Down Expand Up @@ -195,7 +195,7 @@ def get_volume(fl):
with xr.open_dataset(fp) as ds_diag:
future_evol_mdl = ds_diag.load()
fp = gdir.get_filepath('model_diagnostics',
filesuffix='_combine_true_future')
filesuffix='_agile_true_future')
with xr.open_dataset(fp) as ds_diag:
future_evol_true = ds_diag.load()

Expand Down Expand Up @@ -291,7 +291,7 @@ def calculate_default_oggm_statistics(gdir):

# how well do we match the observations -------------------------------
obs_given = gdir.read_pickle('inversion_input',
filesuffix='_combine_measurements')
filesuffix='_agile_measurements')
obs_stats = {}
for obs_key in obs_given.keys():
obs_stats[obs_key] = {}
Expand Down Expand Up @@ -373,9 +373,9 @@ def calculate_default_oggm_statistics(gdir):
controls_mdl = {}
controls_true = {}
fls_mdl = gdir.read_pickle('model_flowlines',
filesuffix='_combine_first_guess')[0]
filesuffix='_agile_first_guess')[0]
fls_true = gdir.read_pickle('model_flowlines',
filesuffix='_combine_true_init')[0]
filesuffix='_agile_true_init')[0]

for control_var in all_control_vars:
if control_var in ['bed_h', 'area_bed_h']:
Expand Down Expand Up @@ -434,7 +434,7 @@ def get_volume(fl):
# how well do we match the past glacier evolution ---------------------
past_evol_mdl = diag_past
fp = gdir.get_filepath('model_diagnostics',
filesuffix='_combine_true_total_run')
filesuffix='_agile_true_total_run')
with xr.open_dataset(fp) as ds_diag:
past_evol_true = ds_diag.load()

Expand All @@ -449,7 +449,7 @@ def get_volume(fl):
# how well do we match today's glacier state --------------------------
fls_end_mdl = fl_diag_past.sel(time=fl_diag_past.time[-1])
fls_end_true = gdir.read_pickle('model_flowlines',
filesuffix='_combine_true_end')[0]
filesuffix='_agile_true_end')[0]

today_state_stats = {}
for var in ['thick', 'area_m2', 'volume_m3']:
Expand Down Expand Up @@ -479,7 +479,7 @@ def get_volume(fl):
# how well do we match the future glacier evolution -------------------
future_evol_mdl = diag_future
fp = gdir.get_filepath('model_diagnostics',
filesuffix='_combine_true_future')
filesuffix='_agile_true_future')
with xr.open_dataset(fp) as ds_diag:
future_evol_true = ds_diag.load()

Expand Down
Loading
Loading