|
14 | 14 | 60(221), 537-552. http://doi.org/10.3189/2014JoG13J176
|
15 | 15 | """
|
16 | 16 | # Built ins
|
17 |
| -import os |
18 | 17 | import logging
|
19 | 18 | import json
|
| 19 | +import warnings |
20 | 20 | from functools import partial
|
21 | 21 | from distutils.version import LooseVersion
|
22 | 22 | # External libs
|
| 23 | +import netCDF4 |
23 | 24 | import salem
|
24 | 25 | import pyproj
|
25 | 26 | import numpy as np
|
26 | 27 | import shapely.ops
|
| 28 | +import pandas as pd |
27 | 29 | import geopandas as gpd
|
28 | 30 | import skimage.draw as skdraw
|
29 | 31 | import shapely.geometry as shpg
|
30 | 32 | import scipy.signal
|
31 | 33 | from scipy.ndimage.measurements import label
|
| 34 | +from scipy.ndimage import binary_erosion |
| 35 | +from scipy.ndimage.morphology import distance_transform_edt |
32 | 36 | from scipy.interpolate import griddata
|
33 | 37 | import rasterio
|
34 | 38 | from rasterio.warp import reproject, Resampling
|
@@ -742,3 +746,98 @@ def proj(x, y):
|
742 | 746 | nc.max_h_glacier = np.max(dem_on_g)
|
743 | 747 | nc.min_h_glacier = np.min(dem_on_g)
|
744 | 748 | nc.close()
|
| 749 | + |
| 750 | + |
| 751 | +@entity_task(log, writes=['gridded_data']) |
| 752 | +def interpolation_masks(gdir): |
| 753 | + """Computes the glacier exterior masks taking ice divides into account. |
| 754 | +
|
| 755 | + This is useful for distributed ice thickness. The masks are added to the |
| 756 | + gridded data file. For convenience we also add a slope mask. |
| 757 | +
|
| 758 | + Parameters |
| 759 | + ---------- |
| 760 | + gdir : :py:class:`oggm.GlacierDirectory` |
| 761 | + where to write the data |
| 762 | + """ |
| 763 | + |
| 764 | + # Variables |
| 765 | + grids_file = gdir.get_filepath('gridded_data') |
| 766 | + with netCDF4.Dataset(grids_file) as nc: |
| 767 | + topo_smoothed = nc.variables['topo_smoothed'][:] |
| 768 | + glacier_mask = nc.variables['glacier_mask'][:] |
| 769 | + |
| 770 | + # Glacier exterior including nunataks |
| 771 | + erode = binary_erosion(glacier_mask) |
| 772 | + glacier_ext = glacier_mask ^ erode |
| 773 | + glacier_ext = np.where(glacier_mask == 1, glacier_ext, 0) |
| 774 | + |
| 775 | + # Intersects between glaciers |
| 776 | + gdfi = gpd.GeoDataFrame(columns=['geometry']) |
| 777 | + if gdir.has_file('intersects'): |
| 778 | + # read and transform to grid |
| 779 | + gdf = gpd.read_file(gdir.get_filepath('intersects')) |
| 780 | + salem.transform_geopandas(gdf, gdir.grid, inplace=True) |
| 781 | + gdfi = pd.concat([gdfi, gdf[['geometry']]]) |
| 782 | + |
| 783 | + # Ice divide mask |
| 784 | + # Probably not the fastest way to do this, but it works |
| 785 | + dist = np.array([]) |
| 786 | + jj, ii = np.where(glacier_ext) |
| 787 | + for j, i in zip(jj, ii): |
| 788 | + dist = np.append(dist, np.min(gdfi.distance(shpg.Point(i, j)))) |
| 789 | + |
| 790 | + with warnings.catch_warnings(): |
| 791 | + warnings.filterwarnings("ignore", category=RuntimeWarning) |
| 792 | + pok = np.where(dist <= 1) |
| 793 | + glacier_ext_intersect = glacier_ext * 0 |
| 794 | + glacier_ext_intersect[jj[pok], ii[pok]] = 1 |
| 795 | + |
| 796 | + # Distance from border mask - Scipy does the job |
| 797 | + dx = gdir.grid.dx |
| 798 | + dis_from_border = 1 + glacier_ext_intersect - glacier_ext |
| 799 | + dis_from_border = distance_transform_edt(dis_from_border) * dx |
| 800 | + |
| 801 | + # Slope |
| 802 | + sy, sx = np.gradient(topo_smoothed, dx, dx) |
| 803 | + slope = np.arctan(np.sqrt(sy**2 + sx**2)) |
| 804 | + slope = np.clip(slope, np.deg2rad(cfg.PARAMS['min_slope']*4), np.pi/2.) |
| 805 | + slope = 1 / slope**(cfg.N / (cfg.N+2)) |
| 806 | + |
| 807 | + with netCDF4.Dataset(grids_file, 'a') as nc: |
| 808 | + |
| 809 | + vn = 'glacier_ext_erosion' |
| 810 | + if vn in nc.variables: |
| 811 | + v = nc.variables[vn] |
| 812 | + else: |
| 813 | + v = nc.createVariable(vn, 'i1', ('y', 'x', )) |
| 814 | + v.units = '-' |
| 815 | + v.long_name = 'Glacier exterior with binary erosion method' |
| 816 | + v[:] = glacier_ext |
| 817 | + |
| 818 | + vn = 'ice_divides' |
| 819 | + if vn in nc.variables: |
| 820 | + v = nc.variables[vn] |
| 821 | + else: |
| 822 | + v = nc.createVariable(vn, 'i1', ('y', 'x', )) |
| 823 | + v.units = '-' |
| 824 | + v.long_name = 'Glacier ice divides' |
| 825 | + v[:] = glacier_ext_intersect |
| 826 | + |
| 827 | + vn = 'slope_factor' |
| 828 | + if vn in nc.variables: |
| 829 | + v = nc.variables[vn] |
| 830 | + else: |
| 831 | + v = nc.createVariable(vn, 'f4', ('y', 'x', )) |
| 832 | + v.units = '-' |
| 833 | + v.long_name = 'Slope factor as defined in Farinotti et al 2009' |
| 834 | + v[:] = slope |
| 835 | + |
| 836 | + vn = 'dis_from_border' |
| 837 | + if vn in nc.variables: |
| 838 | + v = nc.variables[vn] |
| 839 | + else: |
| 840 | + v = nc.createVariable(vn, 'f4', ('y', 'x', )) |
| 841 | + v.units = 'm' |
| 842 | + v.long_name = 'Distance from border' |
| 843 | + v[:] = dis_from_border |
0 commit comments