Skip to content

Commit cbdf90b

Browse files
author
Diana Gergel
authored
Merge pull request #39 from dgergel/fix_dimnaming_regridding_service
update regridding output dimensions
2 parents 6a90cc9 + fbb295a commit cbdf90b

File tree

4 files changed

+48
-21
lines changed

4 files changed

+48
-21
lines changed

dodola/cli.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,14 @@ def rechunk(x, variable, chunk, maxmemory, out):
140140
required=True,
141141
help="Regridding method - 'bilinear' or 'conservative'",
142142
)
143-
@click.option(
144-
"--targetresolution", "-r", default=1.0, help="Global-grid resolution to regrid to"
145-
)
143+
@click.option("--domain-file", "-d", help="Domain file to regrid to")
146144
@click.option(
147145
"--weightspath",
148146
"-w",
149147
default=None,
150148
help="Local path to existing regrid weights file",
151149
)
152-
def regrid(x, out, method, targetresolution, weightspath):
150+
def regrid(x, out, method, domain_file, weightspath):
153151
"""Regrid a target climate dataset
154152
155153
Note, the weightspath only accepts paths to NetCDF files on the local disk. See
@@ -162,6 +160,6 @@ def regrid(x, out, method, targetresolution, weightspath):
162160
out=str(out),
163161
method=str(method),
164162
storage=_authenticate_storage(),
163+
domain_file=domain_file,
165164
weights_path=weightspath,
166-
target_resolution=float(targetresolution),
167165
)

dodola/core.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,26 +92,27 @@ def build_xesmf_weights_file(x, method, target_resolution, filename=None):
9292
return str(out.filename)
9393

9494

95-
def xesmf_regrid(x, method, target_resolution, weights_path=None):
95+
def xesmf_regrid(x, domain, method, weights_path=None):
9696
"""
9797
9898
Parameters
9999
----------
100100
x : xr.Dataset
101+
domain : xr.Dataset
102+
Domain to regrid to.
101103
method : str
102104
Method of regridding. Passed to ``xesmf.Regridder``.
103-
target_resolution : float
104-
Decimal-degree resolution of global latxlon grid to regrid to.
105105
weights_path : str, optional
106106
Local path to netCDF file of pre-calculated XESMF regridding weights.
107107
108108
Returns
109109
-------
110110
xr.Dataset
111111
"""
112+
112113
regridder = xe.Regridder(
113114
x,
114-
xe.util.grid_global(target_resolution, target_resolution),
115+
domain,
115116
method=method,
116117
filename=weights_path,
117118
)

dodola/services.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def rechunk(x, target_chunks, out, max_mem, storage):
126126

127127

128128
@log_service
129-
def regrid(x, out, method, storage, weights_path=None, target_resolution=1.0):
129+
def regrid(x, out, method, storage, domain_file, weights_path=None):
130130
"""Regrid climate data
131131
132132
Parameters
@@ -139,18 +139,22 @@ def regrid(x, out, method, storage, weights_path=None, target_resolution=1.0):
139139
Method of regridding. Passed to ``xesmf.Regridder``.
140140
storage : dodola.repository._ZarrRepo
141141
Storage abstraction for data IO.
142+
domain_file : str
143+
Storage URL to input xr.Dataset domain file to regrid to.
142144
weights_path : optional
143145
Local file path name to write regridding weights file to.
144-
target_resolution : float, optional
145-
Decimal-degree resolution of global grid to regrid to.
146146
"""
147147
ds = storage.read(x)
148+
149+
ds_domain = storage.read(domain_file)
150+
148151
regridded_ds = xesmf_regrid(
149152
ds,
153+
ds_domain,
150154
method=method,
151-
target_resolution=target_resolution,
152155
weights_path=weights_path,
153156
)
157+
154158
storage.write(out, regridded_ds)
155159

156160

dodola/tests/test_services.py

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ def _datafactory(x, start_time="1950-01-01"):
3232
return out
3333

3434

35+
@pytest.fixture
36+
def domain_file(request):
37+
""" Creates a fake domain Dataset for testing"""
38+
lon_name = "lon"
39+
lat_name = "lat"
40+
domain = grid_global(request.param, request.param)
41+
domain[lat_name] = np.unique(domain[lat_name].values)
42+
domain[lon_name] = np.unique(domain[lon_name].values)
43+
44+
return domain
45+
46+
3547
@pytest.mark.parametrize(
3648
"method, expected_head, expected_tail",
3749
[
@@ -163,21 +175,24 @@ def test_rechunk():
163175

164176

165177
@pytest.mark.parametrize(
166-
"regrid_method, expected_shape",
178+
"domain_file, regrid_method, expected_shape",
167179
[
168180
pytest.param(
181+
1.0,
169182
"bilinear",
170183
(180, 360),
171184
id="Bilinear regrid",
172185
),
173186
pytest.param(
187+
1.0,
174188
"conservative",
175189
(180, 360),
176190
id="Conservative regrid",
177191
),
178192
],
193+
indirect=["domain_file"],
179194
)
180-
def test_regrid_methods(regrid_method, expected_shape):
195+
def test_regrid_methods(domain_file, regrid_method, expected_shape):
181196
"""Smoke test that services.regrid outputs with different regrid methods
182197
183198
The expected shape is the same, but change in methods should not error.
@@ -189,6 +204,7 @@ def test_regrid_methods(regrid_method, expected_shape):
189204
fakestorage = memory_repository(
190205
{
191206
"an/input/path.zarr": ds_in,
207+
"a/domainfile/path.zarr": domain_file,
192208
}
193209
)
194210

@@ -197,28 +213,30 @@ def test_regrid_methods(regrid_method, expected_shape):
197213
out="an/output/path.zarr",
198214
method=regrid_method,
199215
storage=fakestorage,
216+
domain_file="a/domainfile/path.zarr",
200217
)
201218
actual_shape = fakestorage.read("an/output/path.zarr")["fakevariable"].shape
202219
assert actual_shape == expected_shape
203220

204221

205222
@pytest.mark.parametrize(
206-
"target_resolution, expected_shape",
223+
"domain_file, expected_shape",
207224
[
208225
pytest.param(
209226
1.0,
210227
(180, 360),
211-
id="Regrid to global 1.0° x 1.0° grid",
228+
id="Regrid to domain file grid",
212229
),
213230
pytest.param(
214231
2.0,
215232
(90, 180),
216233
id="Regrid to global 2.0° x 2.0° grid",
217234
),
218235
],
236+
indirect=["domain_file"],
219237
)
220-
def test_regrid_resolution(target_resolution, expected_shape):
221-
"""Smoke test that services.regrid outputs with different regrid methods
238+
def test_regrid_resolution(domain_file, expected_shape):
239+
"""Smoke test that services.regrid outputs with different grid resolutions
222240
223241
The expected shape is the same, but change in methods should not error.
224242
"""
@@ -229,21 +247,25 @@ def test_regrid_resolution(target_resolution, expected_shape):
229247
fakestorage = memory_repository(
230248
{
231249
"an/input/path.zarr": ds_in,
250+
"a/domainfile/path.zarr": domain_file,
232251
}
233252
)
234253

235254
regrid(
236255
"an/input/path.zarr",
237256
out="an/output/path.zarr",
238-
target_resolution=target_resolution,
239257
method="bilinear",
240258
storage=fakestorage,
259+
domain_file="a/domainfile/path.zarr",
241260
)
242261
actual_shape = fakestorage.read("an/output/path.zarr")["fakevariable"].shape
243262
assert actual_shape == expected_shape
244263

245264

246-
def test_regrid_weights_integration(tmpdir):
265+
@pytest.mark.parametrize(
266+
"domain_file", [pytest.param(1.0, id="Regrid to domain file grid")], indirect=True
267+
)
268+
def test_regrid_weights_integration(domain_file, tmpdir):
247269
"""Test basic integration between service.regrid and service.build_weights"""
248270
expected_shape = (180, 360)
249271
# Output to tmp dir so we cleanup & don't clobber existing files...
@@ -256,6 +278,7 @@ def test_regrid_weights_integration(tmpdir):
256278
fakestorage = memory_repository(
257279
{
258280
"an/input/path.zarr": ds_in,
281+
"a/domainfile/path.zarr": domain_file,
259282
}
260283
)
261284

@@ -272,6 +295,7 @@ def test_regrid_weights_integration(tmpdir):
272295
method="bilinear",
273296
weights_path=weightsfile,
274297
storage=fakestorage,
298+
domain_file="a/domainfile/path.zarr",
275299
)
276300
actual_shape = fakestorage.read("an/output/path.zarr")["fakevariable"].shape
277301
assert actual_shape == expected_shape

0 commit comments

Comments
 (0)