-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDelta-H Implementation.py
290 lines (174 loc) · 9.33 KB
/
Delta-H Implementation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# Imports
from osgeo import osr, gdal, ogr
import numpy as np
import pandas as pd
# Functions
def getRasterBand (ds, band=1, access=0):
band=ds.GetRasterBand(1).ReadAsArray()
return band
def createRasterFromCopy(dst,ds,data,driverFmt='GTiff'):
driver=gdal.GetDriverByName(driverFmt)
outds=driver.CreateCopy(dst,ds,strict=0)
outds.GetRasterBand(1).WriteArray(data)
ds=None
outds=None
def normalize_DHM(dhm):
dhm_n = dhm.copy()
dhm_n = (dhm.max() - dhm)/(dhm.max() - dhm.min())
return dhm_n
def normalize_dh (dh):
dh_n = dh.copy()
dh_n = dh/dh.max()
return dh_n
# Workspace: Enter the path of a separate workspace for the implementation
ws = input('Enter the path of your workspace for the implementation script:')
#Check Input Data
print('Make sure that all seven input files according to the README are saved in your ws')
#Drivers and Proj(EPSG 21781 for LV03)
drv = gdal.GetDriverByName('GTiff')
srs = osr.SpatialReference()
srs.ImportFromEPSG(21781)
#Glacier to model
glacier = 'Glacier de Tsanfleuron'
#Open and edit files
#Open dhm25
dhm98=gdal.Open(ws + '/dhm25_grid_raster.tif')
#Edit dhm25(Reproject and Clip) with the 1998 glacier extend
ba_edit_dhm98 = gdal.Warp(ws + '/' + 'ba_edit_dhm25.tif', dhm98, dstSRS='EPSG:2056', cutlineDSName=ws + "/98_outline/outline_98_2.shp", cutlineWhere=f"name='{glacier}'", cropToCutline=True, dstNodata=np.nan)
#Open and Edit dhm16 (Resample and Clip) with the 1998 glacier extend
dhm16 = gdal.Open(ws + '/glacier_tsanfleuron.tif')
transform = dhm98.GetGeoTransform()
ba_edit_dhm16 =gdal.Warp(ws + '/ba_edit_glacier_tsanfleuron.tif', dhm16, xRes=transform[1], yRes=transform[1], resampleAlg="bilinear", cutlineDSName=ws + "/98_outline/outline_98_2.shp", cutlineWhere=f"name='{glacier}'", cropToCutline=True, dstNodata=np.nan)
#Open the parametrication .txt file
parametrization = pd.read_csv(ws + '/deltaH_Glacier de Tsanfleuron.txt', sep=';')
#Open the Edit dhm16 file with the 2016 glacier extend
edit_dhm16 = gdal.Open(ws + '/edit_glacier_tsanfleuron.tif')
#Open and edit the glacier bed file
glacier_bed = gdal.Open(ws + '\GlacierBed.tif')
edit_glacier_bed =gdal.Warp(ws +'/glacier_bed_gltsf.tif', glacier_bed, xRes=25, yRes=25, resampleAlg="bilinear", cutlineDSName=ws + "/16_outlines/SGI_2016_glaciers.shp", cutlineWhere=f"name='{glacier}'", cropToCutline=True, dstNodata=np.nan)
#########################################################Calculating Geodetic Mass Balance Change (Ba) according to Fischer M. et al. 2015##############################################
#Calculate volume change from 1998 to 2016
NewFile = ws+'/'+ 'ba_substract_glacier_tsanfleuron.tif'
#Calculate Diffrence and write to a new Tiff
Old=getRasterBand(ba_edit_dhm98)
New=getRasterBand(ba_edit_dhm16)
Diff=Old-New
createRasterFromCopy(NewFile, ba_edit_dhm16, Diff)
ba_substract = gdal.Open(ws+'/'+'ba_substract_glacier_tsanfleuron.tif')
#Read as Array
ba_substractArray = ba_substract.GetRasterBand(1).ReadAsArray()
ba_dhm16Array = ba_edit_dhm16.ReadAsArray()
#Masking the two dhm's
ba_masked_substract= np.ma.masked_invalid(ba_substractArray)
ba_masked_dhm16= np.ma.masked_invalid(ba_dhm16Array)
#Merge the two Masks
ba_multimask = np.ma.mask_or(np.ma.getmask(ba_masked_substract), np.ma.getmask(ba_masked_dhm16))
ba_substract_Final_Mask=np.ma.array(ba_substractArray, mask=ba_multimask, fill_value=np.nan ).compressed()
ba_dhm16_Final_Mask=np.ma.array(ba_dhm16Array, mask=ba_multimask, fill_value=np.nan).compressed()
#Make Dataframe dh/DHM
ba_df = pd.DataFrame(np.column_stack([ba_substract_Final_Mask, ba_dhm16_Final_Mask]), columns=['dh', 'DHM'])
ba_df_sort = ba_df.sort_values('dh')
######################################################Equation (1) in Fischer et al. 2015######################################################
#Avarage elevation Change between 1998 and 2016.
dh_mean =ba_df_sort['dh'].mean()
#dv = dh_mean x A98
#Glacier Area 1998
A98 =(ba_df['dh'].count()) * 625
#dv in m^3
dv = -dh_mean * A98
#Constant according to Densitiy of Vol. Change (fdv) = 0.85
fdv= 0.85
# A = Average Area between 1998 and 2016 ((A98 + A16)/2))
#A 16 from SGI
A16 = 2442977
A= (A98 + A16)/2
#dt = time between dhm25 and alti3D
dt= 18
#BA = (dv * fdv) / (A * dt) in m w.a yr^-1
BA = (dv * fdv) / (A * dt)
############################################Calculate fs according to Huss et al. 2010 Eq. 2########################################################################################
#Ba = fs * pice * Sum (Ai * dhi)
#fs= Ba/fs*pice * Sum (Ai* dhi)
#Band Area * normalized elevation range (Ba in m.w.a/yr is convertet in to m with density of water (997) and the area.
fs= (BA* 997 * 2442977) / (((parametrization.iloc[:, 2] * parametrization.iloc[:, 6]).sum()) * 920)
##############################################################Calculate h1################################################################################################
#Read the alti3d file with 2016 glacier extend and the glacier bed file as an array
dhm16Array = edit_dhm16.ReadAsArray()
edit_glacier_bed_array = edit_glacier_bed.ReadAsArray()
#####Update alti 3d array band by band with dh and compare with glacier bed!!!!!
Alti_H1 = None
for index in range(len(parametrization)):
if index == 0:
Alti_H1 = np.where(((dhm16Array >= (parametrization.iloc[index, 4])) & (dhm16Array <= (parametrization.iloc[index, 5]))), dhm16Array + fs * parametrization.iloc[index, 2], dhm16Array)
else:
Alti_H1 = np.where(((dhm16Array >= (parametrization.iloc[index, 4])) & (dhm16Array <= (parametrization.iloc[index, 5]))), dhm16Array + fs * parametrization.iloc[index, 2], Alti_H1)
Alti_H1_Final = np.where(Alti_H1 >= edit_glacier_bed_array, Alti_H1, np.nan)
########################################################Calculae new fs_H1 according to alti_H1_final#########################################################################
#Mask alti_H1_Final
masked_alti_H1= np.ma.masked_invalid(Alti_H1_Final)
#Elevation Bands
bins = list (parametrization.iloc[:, 4])
bins.append(parametrization.iloc[-1, 5])
#Hypsometry
hypsometry, bins = np.histogram(masked_alti_H1.compressed(), bins=bins)
#Area
band_area_h1 = []
for i in hypsometry:
band_area_h1.append(i * 625)
#Fs_H1
fs_H1 = (BA* 997 * 2442977) / (((parametrization.iloc[:, 2] * band_area_h1).sum()) * 920)
#Calculate Alti_H2 with fs_H1
Alti_H2 = None
for index in range(len(parametrization)):
Alti_H2 = np.where(((Alti_H1_Final >= (parametrization.iloc[index, 4])) & (Alti_H1_Final <= (parametrization.iloc[index, 5]))), Alti_H1_Final + fs_H1 * parametrization.iloc[index, 2], Alti_H2)
Alti_H2_float = np.array(Alti_H2, dtype= float)
Alti_H2_Final = np.where(Alti_H2_float >= edit_glacier_bed_array, Alti_H2_float, np.nan)
#########################################Calculate fs_H2 according to alti_H2################################################################
#Mask alti_H2_Final
masked_alti_H2= np.ma.masked_invalid(Alti_H2_Final)
#Hypsometrie
hypsometry, bins = np.histogram(masked_alti_H2.compressed(), bins=bins)
#Area
band_area_h2 = []
for i in hypsometry:
band_area_h2.append(i * 625)
#Fs_H2
fs_H2 = (BA* 997 * 2442977) / (((parametrization.iloc[:, 2] * band_area_h2).sum()) * 920)
###############################################################Repeat the code for as many years you like with a loop#########################
#Create a list of each years updated glacier surface and add the first two runs
Alti_List=[]
Alti_List.append(Alti_H1_Final)
Alti_List.append(Alti_H2_Final)
#Indicate the number of years to project into the future
years= int(input ('number of years you want to model in to the future:'))
#Run the loop for as many years as insertet
for x in range(years-2):
Alti_List[x+1] = None
for index in range(len(parametrization)):
Alti_List[x+1] = np.where(((Alti_List[x] >= (parametrization.iloc[index, 4])) & (Alti_List[x] <= (parametrization.iloc[index, 5]))), Alti_List[x] + fs_H1 * parametrization.iloc[index, 2], Alti_List[x + 1])
Alti_List[x+1] = np.array(Alti_List[x+1], dtype=float)
Alti_List[x+1] = np.where(Alti_List[x+1] >= edit_glacier_bed_array, Alti_List[x+1], np.nan)
Alti_List.append(Alti_List[x+1])
# Mask alti
masked_alti = np.ma.masked_invalid(Alti_List[x+1])
# Hypsometrie
hypsometry, bins = np.histogram(masked_alti.compressed(), bins=bins)
# Area
band_area = []
for i in hypsometry:
band_area.append(i * 625)
# Fs_H2
fs_years = (BA * 997 * 2442977) / (((parametrization.iloc[:, 2] * band_area).sum()) * 920)
#Safe the updated glacier surface to ws
NewFile = ws+'/'+f'gltsf_{2016+years}.tif'
createRasterFromCopy(NewFile, edit_dhm16, Alti_List[years - 1])
NewFile=None
print('you will find a .tif file: gltsf_... with the year number according to your insertet number of years in your ws ')
#Calculating the difference in glacier surface elevation between 2016 and the year you have chosen
substract_years = dhm16Array - Alti_List[years - 1]
NewFile = ws+'/'+f'substract_gltsf_2016-{2016+years}.tif'
createRasterFromCopy(NewFile, edit_dhm16, substract_years)
Alti_List=NewFile=None
print('you will find a .tif file: substract_gltsf_2016-(the year you have chosen) in your ws')
print( 'if you like to model another time span just run the code again')
################################################################END#########################################################################