Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/Voronoi issue #79

Merged
merged 4 commits into from
Nov 21, 2024
Merged
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 @@ -28,6 +28,7 @@ Keep it human-readable, your future self will thank you!
- Added `CutOutMask` class to create a mask for a cutout. (#68)
- Added `MissingZarrVariable` and `NotMissingZarrVariable` classes to create a mask for missing zarr variables. (#68)
- feat: Add CONTRIBUTORS.md file. (#72)
- Fixed issue when computing area weights with scipy.Voronoi. (#79)

### Changed

Expand Down
16 changes: 13 additions & 3 deletions src/anemoi/graphs/nodes/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ class AreaWeights(BaseNodeAttribute):
Radius of the sphere.
centre : np.ndarray
Centre of the sphere.
fill_value : float
Value to fill the empty regions.

Methods
-------
Expand All @@ -118,11 +120,13 @@ def __init__(
norm: str | None = None,
radius: float = 1.0,
centre: np.ndarray = np.array([0, 0, 0]),
fill_value: float = 0.0,
dtype: str = "float32",
) -> None:
super().__init__(norm, dtype)
self.radius = radius
self.centre = centre
self.fill_value = fill_value

def get_raw_values(self, nodes: NodeStorage, **kwargs) -> np.ndarray:
"""Compute the area associated to each node.
Expand All @@ -144,13 +148,19 @@ def get_raw_values(self, nodes: NodeStorage, **kwargs) -> np.ndarray:
latitudes, longitudes = nodes.x[:, 0], nodes.x[:, 1]
points = latlon_rad_to_cartesian((np.asarray(latitudes), np.asarray(longitudes)))
sv = SphericalVoronoi(points, self.radius, self.centre)
mask = np.array([bool(i) for i in sv.regions])
sv.regions = [region for region in sv.regions if region]
# compute the area weight without empty regions
area_weights = sv.calculate_areas()
# add them back with zero weight
result = np.ones(points.shape[0]) * self.fill_value
result[mask] = area_weights
LOGGER.debug(
"There are %d of weights, which (unscaled) add up a total weight of %.2f.",
len(area_weights),
np.array(area_weights).sum(),
len(result),
np.array(result).sum(),
)
return area_weights
return result


class BooleanBaseNodeAttribute(BaseNodeAttribute, ABC):
Expand Down
Loading