Skip to content

Commit f0d7ec9

Browse files
some gapfilling of ice surface height, recalculation of hs_winter after a shift
1 parent 6589796 commit f0d7ec9

File tree

1 file changed

+44
-10
lines changed

1 file changed

+44
-10
lines changed

src/pypromice/process/L2toL3.py

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ def process_surface_height(ds, station_config={}):
173173

174174
if ds.attrs['site_type'] == 'ablation':
175175
# Calculate rolling minimum for ice surface height and snow height
176-
ts_interpolated = ds.z_surf_combined.to_series().resample('H').interpolate(limit=72)
176+
ts_interpolated = np.minimum(xr.where(ds.z_ice_surf.notnull(),ds.z_ice_surf,ds.z_surf_combined),
177+
ds.z_surf_combined).to_series().resample('H').interpolate(limit=72)
177178

178179
# Apply the rolling window with median calculation
179180
z_ice_surf = (ts_interpolated
@@ -189,12 +190,39 @@ def process_surface_height(ds, station_config={}):
189190
.rolling('1D', center=True, min_periods=1)
190191
.median().values)
191192

193+
z_ice_surf = z_ice_surf.loc[ds.time]
192194
# here we make sure that the periods where both z_stake and z_pt are
193195
# missing are also missing in z_ice_surf
194196
msk = ds['z_ice_surf'].notnull() | ds['z_surf_2_adj'].notnull()
195197
z_ice_surf = z_ice_surf.where(msk)
198+
199+
# taking running minimum to get ice
200+
z_ice_surf = z_ice_surf.cummin()
201+
202+
# filling gaps only if they are less than a year long and if values on both
203+
# sides are less than 0.01 m appart
204+
205+
# Forward and backward fill to identify bounds of gaps
206+
df_filled = z_ice_surf.fillna(method='ffill').fillna(method='bfill')
207+
208+
# Identify gaps and their start and end dates
209+
gaps = pd.DataFrame(index=z_ice_surf[z_ice_surf.isna()].index)
210+
gaps['prev_value'] = df_filled.shift(1)
211+
gaps['next_value'] = df_filled.shift(-1)
212+
gaps['gap_start'] = gaps.index.to_series().shift(1)
213+
gaps['gap_end'] = gaps.index.to_series().shift(-1)
214+
gaps['gap_duration'] = (gaps['gap_end'] - gaps['gap_start']).dt.days
215+
gaps['value_diff'] = (gaps['next_value'] - gaps['prev_value']).abs()
196216

197-
ds['z_ice_surf'] = z_ice_surf.cummin()
217+
# Determine which gaps to fill
218+
mask = (gaps['gap_duration'] < 365) & (gaps['value_diff'] < 0.01)
219+
gaps_to_fill = gaps[mask].index
220+
221+
# Fill gaps in the original Series
222+
z_ice_surf.loc[gaps_to_fill] = df_filled.loc[gaps_to_fill]
223+
224+
# bringing the variable into the dataset
225+
ds['z_ice_surf'] = z_ice_surf
198226

199227
ds['z_surf_combined'] = np.maximum(ds['z_surf_combined'], ds['z_ice_surf'])
200228
ds['snow_height'] = np.maximum(0, ds['z_surf_combined'] - ds['z_ice_surf'])
@@ -334,10 +362,13 @@ def combine_surface_height(df, site_type, threshold_ablation = -0.0002):
334362

335363
# the surface heights are adjusted so that they start at 0
336364

337-
if any(~np.isnan(hs1.iloc[:24*7])):
338-
hs1 = hs1 - hs1.iloc[:24*7].mean()
365+
339366
if any(~np.isnan(hs2.iloc[:24*7])):
340367
hs2 = hs2 - hs2.iloc[:24*7].mean()
368+
369+
if any(~np.isnan(hs2.iloc[:24*7])) & any(~np.isnan(hs1.iloc[:24*7])):
370+
hs2 = hs2 + hs1.iloc[:24*7].mean() - hs2.iloc[:24*7].mean()
371+
341372
if any(~np.isnan(z.iloc[:24*7])):
342373
# expressing ice surface height relative to its mean value in the
343374
# first week of the record
@@ -424,9 +455,6 @@ def combine_surface_height(df, site_type, threshold_ablation = -0.0002):
424455
hs2_winter = hs2[str(y)+'-01-01':str(y)+'-03-01'].copy()
425456
z_winter = z[str(y)+'-01-01':str(y)+'-03-01'].copy()
426457

427-
hs1_following_winter = hs1[str(y)+'-09-01':str(y+1)+'-03-01'].copy()
428-
hs2_following_winter = hs2[str(y)+'-09-01':str(y+1)+'-03-01'].copy()
429-
430458
z_year = z[str(y)]
431459
if hs1_jja.isnull().all() and hs2_jja.isnull().all() and z_jja.isnull().all():
432460
# if there is no height for a year between June and September
@@ -546,7 +574,8 @@ def combine_surface_height(df, site_type, threshold_ablation = -0.0002):
546574
np.nanmean(z.iloc[(ind_start[i+1]-24*7):(ind_start[i+1]+24*7)])
547575
else:
548576
logger.debug('no ablation')
549-
577+
hs1_following_winter = hs1[str(y)+'-09-01':str(y+1)+'-03-01'].copy()
578+
hs2_following_winter = hs2[str(y)+'-09-01':str(y+1)+'-03-01'].copy()
550579
if all(np.isnan(hs2_following_winter)):
551580
logger.debug('no hs2')
552581
missing_hs2 = 1
@@ -565,9 +594,12 @@ def combine_surface_height(df, site_type, threshold_ablation = -0.0002):
565594
- np.nanmean(hs2_following_winter) + np.nanmean(hs1_following_winter)
566595
missing_hs2 = 0
567596

597+
598+
hs1_following_winter = hs1[str(y)+'-09-01':str(y+1)+'-03-01'].copy()
599+
hs2_following_winter = hs2[str(y)+'-09-01':str(y+1)+'-03-01'].copy()
568600
# adjusting hs1 to hs2 (no ablation case)
569601
if any(~np.isnan(hs1_following_winter)):
570-
logger.debug('adjusting hs1')
602+
logger.debug('adjusting hs1')
571603
# and if there are some hs2 during the accumulation period
572604
if any(~np.isnan(hs2_following_winter)):
573605
logger.debug('to hs2')
@@ -579,10 +611,12 @@ def combine_surface_height(df, site_type, threshold_ablation = -0.0002):
579611

580612
hs1[str(y)+'-09-01':] = hs1[str(y)+'-09-01':] \
581613
- np.nanmean(hs1_following_winter) + np.nanmean(hs2_following_winter)
614+
hs1_following_winter = hs1[str(y)+'-09-01':str(y+1)+'-03-01'].copy()
582615

583616
if ind_end[i] != -999:
584617
# if there is some hs1
585-
618+
hs1_following_winter = hs1[str(y)+'-09-01':str(y+1)+'-03-01'].copy()
619+
hs2_following_winter = hs2[str(y)+'-09-01':str(y+1)+'-03-01'].copy()
586620
if any(~np.isnan(hs1_following_winter)):
587621
logger.debug('adjusting hs1')
588622
# and if there are some hs2 during the accumulation period

0 commit comments

Comments
 (0)