Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- consider full time information for derived calculation of TOA radiation [\#84](https://github.com/mllam/mllam-data-prep/pull/84) @observingClouds

### Fixes
- fix `crop_with_convex_hull` crash when `margin_thickness == 0.0` caused by not unpacking the tuple returned by `create_convex_hull_mask` [\#99](https://github.com/mllam/mllam-data-prep/issues/99) @RajdeepKushwaha5
- fix bug where coordinate selection of an unshared dimension isn't applied to subsequent ouput variables when an output variable without this dimension is processed before the others [\#90](https://github.com/mllam/mllam-data-prep/pull/90) @zweihuehner & @leifdenby

## [v0.7.0](https://github.com/mllam/mllam-data-prep/release/tag/v0.7.0)
Expand Down
6 changes: 3 additions & 3 deletions mllam_data_prep/ops/cropping.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def _get_latlon_coords(da: xr.DataArray) -> tuple:
raise Exception("Could not find lat/lon coordinates in DataArray.")


def create_convex_hull_mask(ds: xr.Dataset, ds_reference: xr.Dataset) -> xr.DataArray:
def create_convex_hull_mask(ds: xr.Dataset, ds_reference: xr.Dataset) -> Tuple[xr.DataArray, xr.Dataset]:
"""
Create a grid-point mask for lat/lon coordinates in `da` indicating which
points are interior to the convex hull of the lat/lon coordinates of
Expand Down Expand Up @@ -334,9 +334,9 @@ def crop_with_convex_hull(
if margin_thickness == 0.0:
if not include_interior_points:
raise Exception(
"With no margin and exclude_interior=False, all points would be excluded."
"With no margin and include_interior_points=False, all points would be excluded."
)
da_mask = create_convex_hull_mask(ds=ds, ds_reference=ds_reference)
da_mask, _ = create_convex_hull_mask(ds=ds, ds_reference=ds_reference)
else:
da_min_dist_to_ref, da_ch_mask = distance_to_convex_hull_boundary(
ds,
Expand Down
61 changes: 61 additions & 0 deletions tests/test_convex_hull_cropping.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import numpy as np
import pytest
import xarray as xr

import mllam_data_prep as mdp
import mllam_data_prep.config as mdp_config
Expand Down Expand Up @@ -208,3 +209,63 @@ def test_crop_era5_with_generated_lam_domain():
assert var in ds_cropped.data_vars
for coord in ds_uncropped[var].coords:
assert coord in ds_cropped[var].coords


def test_crop_with_zero_margin_thickness():
"""
Regression test for https://github.com/mllam/mllam-data-prep/issues/99
crop_with_convex_hull should work when margin_thickness=0.0 with
include_interior_points=True, returning only the interior points.
"""
tmpdir = tempfile.TemporaryDirectory()
domain_size = 500 * 1.0e3
N = 50
config_lam = testdata.create_input_datasets_and_config(
identifier="lam",
data_categories=["state"],
tmpdir=tmpdir,
xlim=[-domain_size / 2.0, domain_size / 2.0],
ylim=[-domain_size / 2.0, domain_size / 2.0],
nx=N,
ny=N,
add_latlon=True,
)
config_global = testdata.create_input_datasets_and_config(
identifier="global",
data_categories=["state"],
tmpdir=tmpdir,
xlim=[-domain_size, domain_size],
ylim=[-domain_size, domain_size],
nx=N // 2,
ny=N // 2,
add_latlon=True,
)

ds_lam = mdp.create_dataset(config=config_lam)
ds_global = mdp.create_dataset(config=config_global)

# this previously crashed with AttributeError: 'tuple' object has no
# attribute 'dims' because create_convex_hull_mask returns a tuple
ds_cropped = cropping.crop_with_convex_hull(
ds=ds_global,
ds_reference=ds_lam,
margin_thickness=0.0,
include_interior_points=True,
)

assert isinstance(ds_cropped, xr.Dataset)
# with zero margin and interior points included, the result should have
# fewer points than the full global domain
assert ds_cropped.grid_index.size < ds_global.grid_index.size
assert ds_cropped.grid_index.size > 0

# also test the return_mask path
_, da_mask = cropping.crop_with_convex_hull(
ds=ds_global,
ds_reference=ds_lam,
margin_thickness=0.0,
include_interior_points=True,
return_mask=True,
)
assert isinstance(da_mask, xr.DataArray)
assert da_mask.dtype == bool