@@ -173,7 +173,8 @@ def process_surface_height(ds, station_config={}):
173
173
174
174
if ds .attrs ['site_type' ] == 'ablation' :
175
175
# 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 )
177
178
178
179
# Apply the rolling window with median calculation
179
180
z_ice_surf = (ts_interpolated
@@ -189,12 +190,39 @@ def process_surface_height(ds, station_config={}):
189
190
.rolling ('1D' , center = True , min_periods = 1 )
190
191
.median ().values )
191
192
193
+ z_ice_surf = z_ice_surf .loc [ds .time ]
192
194
# here we make sure that the periods where both z_stake and z_pt are
193
195
# missing are also missing in z_ice_surf
194
196
msk = ds ['z_ice_surf' ].notnull () | ds ['z_surf_2_adj' ].notnull ()
195
197
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 ()
196
216
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
198
226
199
227
ds ['z_surf_combined' ] = np .maximum (ds ['z_surf_combined' ], ds ['z_ice_surf' ])
200
228
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):
334
362
335
363
# the surface heights are adjusted so that they start at 0
336
364
337
- if any (~ np .isnan (hs1 .iloc [:24 * 7 ])):
338
- hs1 = hs1 - hs1 .iloc [:24 * 7 ].mean ()
365
+
339
366
if any (~ np .isnan (hs2 .iloc [:24 * 7 ])):
340
367
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
+
341
372
if any (~ np .isnan (z .iloc [:24 * 7 ])):
342
373
# expressing ice surface height relative to its mean value in the
343
374
# first week of the record
@@ -424,9 +455,6 @@ def combine_surface_height(df, site_type, threshold_ablation = -0.0002):
424
455
hs2_winter = hs2 [str (y )+ '-01-01' :str (y )+ '-03-01' ].copy ()
425
456
z_winter = z [str (y )+ '-01-01' :str (y )+ '-03-01' ].copy ()
426
457
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
-
430
458
z_year = z [str (y )]
431
459
if hs1_jja .isnull ().all () and hs2_jja .isnull ().all () and z_jja .isnull ().all ():
432
460
# 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):
546
574
np .nanmean (z .iloc [(ind_start [i + 1 ]- 24 * 7 ):(ind_start [i + 1 ]+ 24 * 7 )])
547
575
else :
548
576
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 ()
550
579
if all (np .isnan (hs2_following_winter )):
551
580
logger .debug ('no hs2' )
552
581
missing_hs2 = 1
@@ -565,9 +594,12 @@ def combine_surface_height(df, site_type, threshold_ablation = -0.0002):
565
594
- np .nanmean (hs2_following_winter ) + np .nanmean (hs1_following_winter )
566
595
missing_hs2 = 0
567
596
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 ()
568
600
# adjusting hs1 to hs2 (no ablation case)
569
601
if any (~ np .isnan (hs1_following_winter )):
570
- logger .debug ('adjusting hs1' )
602
+ logger .debug ('adjusting hs1' )
571
603
# and if there are some hs2 during the accumulation period
572
604
if any (~ np .isnan (hs2_following_winter )):
573
605
logger .debug ('to hs2' )
@@ -579,10 +611,12 @@ def combine_surface_height(df, site_type, threshold_ablation = -0.0002):
579
611
580
612
hs1 [str (y )+ '-09-01' :] = hs1 [str (y )+ '-09-01' :] \
581
613
- 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 ()
582
615
583
616
if ind_end [i ] != - 999 :
584
617
# 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 ()
586
620
if any (~ np .isnan (hs1_following_winter )):
587
621
logger .debug ('adjusting hs1' )
588
622
# and if there are some hs2 during the accumulation period
0 commit comments