Skip to content

Commit 87e2ca6

Browse files
authored
Merge pull request #95 from dgergel/add_analogdownscaling_qdm_options
Add analogdownscaling qdm options
2 parents 18b42c1 + 11d8782 commit 87e2ca6

File tree

6 files changed

+67
-8
lines changed

6 files changed

+67
-8
lines changed

HISTORY.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ History
55

66
0.X.X (XXXX-XX-XX)
77
------------------
8+
* Add ``include-quantiles`` flag to ``apply_qdm`` to allow for including quantile information in bias corrected output. (PR #95, @dgergel)
89
* Add ``astype`` argument to ``regrid``. (PR #92, @brews)
910
* Make ``dodola`` container's default CMD. (PR #90, @brews)
1011
* Add ``dask-kubernetes``, ``distributed`` to container environment. (PR #90, @brews)

dodola/cli.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,20 @@ def dodola_cli(debug):
4949
required=True,
5050
help="URL to write NetCDF4 with adjusted simulation year to",
5151
)
52-
def apply_qdm(simulation, qdm, year, variable, out):
52+
@click.option(
53+
"--include-quantiles",
54+
is_flag=True,
55+
help="Include simulation quantiles in output",
56+
)
57+
def apply_qdm(simulation, qdm, year, variable, out, include_quantiles):
5358
"""Adjust simulation year with QDM bias correction method, outputting to local NetCDF4 file"""
5459
services.apply_qdm(
55-
simulation=simulation, qdm=qdm, year=year, variable=variable, out=out
60+
simulation=simulation,
61+
qdm=qdm,
62+
year=year,
63+
variable=variable,
64+
out=out,
65+
include_quantiles=include_quantiles,
5666
)
5767

5868

dodola/core.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import logging
99
from skdownscale.spatial_models import SpatialDisaggregator
1010
import xarray as xr
11-
from xclim import sdba
11+
from xclim import sdba, set_options
1212
from xclim.sdba.utils import equally_spaced_nodes
1313
from xclim.core.calendar import convert_calendar
1414
import xesmf as xe
@@ -53,7 +53,7 @@ def train_quantiledeltamapping(
5353

5454

5555
def adjust_quantiledeltamapping_year(
56-
simulation, qdm, year, variable, halfyearwindow_n=10
56+
simulation, qdm, year, variable, halfyearwindow_n=10, include_quantiles=False
5757
):
5858
"""Apply QDM to adjust a year within a simulation.
5959
@@ -74,6 +74,9 @@ def adjust_quantiledeltamapping_year(
7474
halfyearwindow_n : int, optional
7575
Half-length of the annual rolling window to extract along either
7676
side of `year`.
77+
include_quantiles : bool, optional
78+
Whether or not to output quantiles (sim_q) as a coordinate on
79+
the bias corrected data variable in output.
7780
7881
Returns
7982
-------
@@ -96,7 +99,14 @@ def adjust_quantiledeltamapping_year(
9699
simulation = simulation[variable].sel(
97100
time=timeslice
98101
) # TODO: Need a check to ensure we have all the data in this slice!
99-
out = qdm.adjust(simulation, interp="nearest").sel(time=str(year))
102+
if include_quantiles:
103+
# include quantile information in output
104+
with set_options(sdba_extra_output=True):
105+
out = qdm.adjust(simulation, interp="nearest").sel(time=str(year))
106+
# make quantiles a coordinate of bias corrected output variable
107+
out = out["scen"].assign_coords(sim_q=out.sim_q)
108+
else:
109+
out = qdm.adjust(simulation, interp="nearest").sel(time=str(year))
100110

101111
return out.to_dataset(name=variable)
102112

dodola/services.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def train_qdm(historical, reference, out, variable, kind):
6464

6565

6666
@log_service
67-
def apply_qdm(simulation, qdm, year, variable, out):
67+
def apply_qdm(simulation, qdm, year, variable, out, include_quantiles=False):
6868
"""Apply trained QDM to adjust a year within a simulation, dump to NetCDF.
6969
7070
Dumping to NetCDF is a feature likely to change in the near future.
@@ -84,6 +84,9 @@ def apply_qdm(simulation, qdm, year, variable, out):
8484
out : str
8585
fsspec-compatible path or URL pointing to NetCDF4 file where the
8686
QDM-adjusted simulation data will be written.
87+
include_quantiles : bool
88+
Flag to indicate whether bias-corrected quantiles should be
89+
included in the QDM-adjusted output.
8790
"""
8891
sim_ds = storage.read(simulation)
8992
qdm_ds = storage.read(qdm)
@@ -92,7 +95,11 @@ def apply_qdm(simulation, qdm, year, variable, out):
9295
variable = str(variable)
9396

9497
adjusted_ds = adjust_quantiledeltamapping_year(
95-
simulation=sim_ds, qdm=qdm_ds, year=year, variable=variable
98+
simulation=sim_ds,
99+
qdm=qdm_ds,
100+
year=year,
101+
variable=variable,
102+
include_quantiles=include_quantiles,
96103
)
97104

98105
# Write to NetCDF, usually on local disk, pooling and "fanning-in" NetCDFs is

dodola/tests/test_core.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,36 @@ def test_adjust_quantiledeltamapping_year_kind(variable_kind, expected):
115115
assert all(adjusted_ds[target_variable] == expected)
116116

117117

118+
def test_adjust_quantiledeltamapping_include_quantiles():
119+
"""Test that include-quantiles flag results in bias corrected quantiles
120+
included in output"""
121+
target_variable = "fakevariable"
122+
n_simdays = 5 * 365 # 100 years of daily simulation.
123+
124+
model_bias = 2.0
125+
ts_sim = np.ones(n_simdays, dtype=np.float64)
126+
sim = _timeseriesfactory(
127+
ts_sim * model_bias, start_dt="2015-01-01", variable_name=target_variable
128+
)
129+
130+
target_year = 2017
131+
132+
# Yes, I'm intentionally training the QDM to a different bias. This is to
133+
# spurn a difference between "kind" adjustments...
134+
qdm = _train_simple_qdm(
135+
target_variable="fakevariable", kind="+", additive_bias=model_bias + 1
136+
)
137+
adjusted_ds = adjust_quantiledeltamapping_year(
138+
simulation=sim,
139+
qdm=qdm,
140+
year=target_year,
141+
variable=target_variable,
142+
include_quantiles=True,
143+
)
144+
# check that quantiles are contained in output
145+
assert "sim_q" in adjusted_ds[target_variable].coords
146+
147+
118148
def test_adjust_quantiledeltamapping_year_output_time():
119149
"""Check 'time' year and edges of QDM adjusted output
120150

environment.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ dependencies:
1111
- fsspec=2021.5.0 # Prevent azure blob errors, not hard req.
1212
- gcsfs=2021.5.0
1313
- numpy=1.20.3
14+
- pandas=1.2.5
1415
- pip=21.1.2
1516
- pytest=6.2.4
1617
- python=3.9
@@ -21,4 +22,4 @@ dependencies:
2122
- zarr=2.8.3
2223
- pip:
2324
- git+https://github.com/dgergel/xsd@458f292dab6e8a6584659e97a66c37e028da2b7a
24-
- git+https://github.com/Ouranosinc/xclim@d1e654cf59a5d5761f5586bca1102a1590ae6e32
25+
- xclim

0 commit comments

Comments
 (0)