5
5
from functools import partial
6
6
from tqdm .autonotebook import tqdm
7
7
from bmorph .util import mizuroute_utils as mizutil
8
+ import os
8
9
9
10
def apply_bmorph (raw_ts , train_ts , ref_ts ,
10
11
apply_window , raw_train_window , ref_train_window ,
@@ -13,7 +14,7 @@ def apply_bmorph(raw_ts, train_ts, ref_ts,
13
14
interval = pd .DateOffset (years = 1 ),
14
15
overlap = 60 , n_smooth_long = None , n_smooth_short = 5 ,
15
16
bw = 3 , xbins = 200 , ybins = 10 ,
16
- rtol = 1e-6 , atol = 1e-8 , method = 'hist' , ** kwargs ):
17
+ rtol = 1e-6 , atol = 1e-8 , method = 'hist' , train_cdf_min = 1e-4 , ** kwargs ):
17
18
"""Bias correction is performed by bmorph on user-defined intervals.
18
19
19
20
Parameters
@@ -122,7 +123,7 @@ def apply_bmorph(raw_ts, train_ts, ref_ts,
122
123
raw_apply_window , raw_train_window , ref_train_window , raw_cdf_window ,
123
124
raw_y , ref_y , train_y ,
124
125
n_smooth_short , bw = bw , xbins = xbins , ybins = ybins , rtol = rtol , atol = atol ,
125
- method = method )
126
+ method = method , train_cdf_min = train_cdf_min )
126
127
bmorph_ts = bmorph_ts .append (bc_total )
127
128
bmorph_multipliers = bmorph_multipliers .append (bc_mult )
128
129
@@ -150,7 +151,8 @@ def apply_blendmorph(raw_upstream_ts, raw_downstream_ts,
150
151
train_upstream_y = None , train_downstream_y = None ,
151
152
ref_upstream_y = None , ref_downstream_y = None ,
152
153
n_smooth_long = None , n_smooth_short = 5 ,
153
- bw = 3 , xbins = 200 , ybins = 10 , rtol = 1e-6 , atol = 1e-8 , method = 'hist' , ** kwargs ):
154
+ bw = 3 , xbins = 200 , ybins = 10 , rtol = 1e-6 , atol = 1e-8 ,
155
+ method = 'hist' , train_cdf_min = 1e-4 , ** kwargs ):
154
156
"""Bias correction performed by blending bmorphed flows on user defined intervals.
155
157
156
158
Blendmorph is used to perform spatially consistent bias correction, this function
@@ -298,22 +300,22 @@ def apply_blendmorph(raw_upstream_ts, raw_downstream_ts,
298
300
raw_apply_window , raw_train_window , ref_train_window , raw_cdf_window ,
299
301
raw_upstream_y , ref_upstream_y , train_upstream_y ,
300
302
n_smooth_short , bw = bw , xbins = xbins , ybins = ybins , rtol = rtol , atol = atol ,
301
- method = method )
303
+ method = method , train_cdf_min = train_cdf_min )
302
304
bc_down_total , bc_down_mult = bmorph .bmorph (
303
305
raw_downstream_ts , train_downstream_ts , ref_downstream_ts ,
304
306
raw_apply_window , raw_train_window , ref_train_window , raw_cdf_window ,
305
307
raw_downstream_y , ref_downstream_y , train_downstream_y ,
306
308
n_smooth_short , bw = bw , xbins = xbins , ybins = ybins , rtol = rtol , atol = atol ,
307
- method = method )
309
+ method = method , train_cdf_min = train_cdf_min )
308
310
else :
309
311
bc_up_total , bc_up_mult = bmorph .bmorph (
310
312
raw_upstream_ts , train_upstream_ts , ref_upstream_ts ,
311
313
raw_apply_window , raw_train_window , ref_train_window , raw_cdf_window ,
312
- n_smooth_short )
314
+ n_smooth_short , train_cdf_min = train_cdf_min )
313
315
bc_down_total , bc_down_mult = bmorph .bmorph (
314
316
raw_downstream_ts , train_downstream_ts , ref_downstream_ts ,
315
317
raw_apply_window , raw_train_window , ref_train_window , raw_cdf_window ,
316
- n_smooth_short )
318
+ n_smooth_short , train_cdf_min = train_cdf_min )
317
319
318
320
bc_multiplier = (blend_factor * bc_up_mult ) + ((1 - blend_factor ) * bc_down_mult )
319
321
bc_total = (blend_factor * bc_up_total ) + ((1 - blend_factor ) * bc_down_total )
@@ -392,7 +394,7 @@ def _scbc_u_seg(ds, apply_window, raw_train_window, ref_train_window,
392
394
return scbc_u_flows , scbc_u_mults , scbc_u_locals
393
395
394
396
395
- def apply_scbc (ds , mizuroute_exe , bmorph_config , client = None ):
397
+ def apply_scbc (ds , mizuroute_exe , bmorph_config , client = None , save_mults = False ):
396
398
"""
397
399
Applies Spatially Consistent Bias Correction (SCBC) by
398
400
bias correcting local flows and re-routing them through
@@ -413,13 +415,17 @@ def apply_scbc(ds, mizuroute_exe, bmorph_config, client=None):
413
415
for descriptions of the options and their choices.
414
416
client: dask.Client (optional)
415
417
A `client` object to manage parallel computation.
418
+ save_mults: boolean (optional)
419
+ Whether to save multipliers from bmorph for diagnosis. If True,
420
+ multipliers are saved in the same directory as local flows. Defaults
421
+ as False to not save multipliers.
416
422
417
423
Returns
418
424
-------
419
425
region_totals: xr.Dataset
420
426
The rerouted, total, bias corrected flows for the region
421
427
"""
422
- def unpack_and_write_netcdf (results , segs , file_path , out_varname = 'scbc_flow' ):
428
+ def unpack_and_write_netcdf (results , segs , file_path , out_varname = 'scbc_flow' , mult_path = None ):
423
429
flows = [r [0 ] for r in results ]
424
430
mults = [r [1 ] for r in results ]
425
431
local = [r [2 ] for r in results ]
@@ -428,8 +434,23 @@ def unpack_and_write_netcdf(results, segs, file_path, out_varname='scbc_flow'):
428
434
local_ds ['time' ] = flows [0 ].index
429
435
local_ds .name = out_varname
430
436
local_ds = local_ds .where (local_ds >= 1e-4 , other = 1e-4 )
437
+ try :
438
+ os .remove (file_path )
439
+ except OSError :
440
+ pass
431
441
local_ds .transpose ().to_netcdf (file_path )
432
442
443
+ if mult_path :
444
+ try :
445
+ os .remove (mult_path )
446
+ except OSError :
447
+ pass
448
+ mult_ds = xr .DataArray (np .vstack (mults ), dims = ('seg' ,'time' ))
449
+ mult_ds ['seg' ] = segs
450
+ mult_ds ['time' ] = flows [0 ].index
451
+ mult_ds .name = 'mults'
452
+ mult_ds .transpose ().to_netcdf (mult_path )
453
+
433
454
if 'condition_var' in bmorph_config .keys () and bmorph_config ['condition_var' ]:
434
455
scbc_type = 'conditional'
435
456
scbc_fun = partial (_scbc_c_seg , ** bmorph_config )
@@ -447,7 +468,12 @@ def unpack_and_write_netcdf(results, segs, file_path, out_varname='scbc_flow'):
447
468
448
469
out_file = (f'{ bmorph_config ["data_path" ]} /input/'
449
470
f'{ bmorph_config ["output_prefix" ]} _local_{ scbc_type } _scbc.nc' )
450
- unpack_and_write_netcdf (results , ds ['seg' ], out_file )
471
+ if save_mults :
472
+ mult_file = (f'{ bmorph_config ["data_path" ]} /input/'
473
+ f'{ bmorph_config ["output_prefix" ]} _local_mult_{ scbc_type } _scbc.nc' )
474
+ else :
475
+ mult_file = None
476
+ unpack_and_write_netcdf (results , ds ['seg' ], out_file , mult_path = mult_file )
451
477
config_path , mizuroute_config = mizutil .write_mizuroute_config (
452
478
bmorph_config ["output_prefix" ],
453
479
scbc_type , bmorph_config ['apply_window' ],
0 commit comments