Skip to content

Commit acacb96

Browse files
committed
Add grid localization to array of interest
1 parent b7bdddc commit acacb96

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

parcels/xgrid.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,23 @@ def get_axis_dim(self, axis: _XGRID_AXES) -> int:
129129

130130
return get_cell_count_along_dim(self.xgcm_grid.axes[axis])
131131

132+
def localize(self, position: dict[_XGRID_AXES, tuple[int, float]], dims: list[str]) -> dict[str, tuple[int, float]]:
133+
"""
134+
Uses the grid context (i.e., the staggering of the grid) to convert a position relative
135+
to the F-points in the grid to a position relative to the dimensions of the array
136+
of interest.
137+
"""
138+
axis_to_var = {get_axis_from_dim_name(self.xgcm_grid.axes, dim): dim for dim in dims}
139+
var_positions = {
140+
axis: get_xgcm_position_from_dim_name(self.xgcm_grid.axes, dim) for axis, dim in axis_to_var.items()
141+
}
142+
return {
143+
axis_to_var[axis]: _convert_center_pos_to_fpoint(
144+
index=index, bcoord=bcoord, position=var_positions[axis], f_points_position=self._fpoint_info[axis]
145+
)
146+
for axis, (index, bcoord) in position.items()
147+
}
148+
132149
@property
133150
def _z4d(self) -> Literal[0, 1]:
134151
"""
@@ -185,6 +202,19 @@ def search(self, z, y, x, ei=None):
185202

186203
raise NotImplementedError("Searching in >2D lon/lat arrays is not implemented yet.")
187204

205+
@cached_property
206+
def _fpoint_info(self):
207+
xgcm_axes = self.xgcm_grid.axes
208+
f_point_positions = ["left", "right", "inner", "outer"]
209+
axis_position_mapping = {}
210+
for axis in self.axes:
211+
coords = xgcm_axes[axis].coords
212+
edge_positions = list(filter(lambda x: x in f_point_positions, coords.keys()))
213+
assert len(edge_positions) == 1, f"Axis {axis} has multiple edge positions: {edge_positions}"
214+
axis_position_mapping[axis] = edge_positions[0]
215+
216+
return axis_position_mapping
217+
188218

189219
def get_axis_from_dim_name(axes: _XGCM_AXES, dim: str) -> _XGCM_AXIS_DIRECTION | None:
190220
"""For a given dimension name in a grid, returns the direction axis it is on."""
@@ -337,3 +367,22 @@ def _search_1d_array(
337367
i = np.argmin(arr <= x) - 1
338368
bcoord = (x - arr[i]) / (arr[i + 1] - arr[i])
339369
return i, bcoord
370+
371+
372+
def _convert_center_pos_to_fpoint(
373+
*, index: int, bcoord: float, position: _XGCM_AXIS_POSITION, f_points_position: _XGCM_AXIS_POSITION
374+
) -> tuple[int, float]:
375+
"""Converts a position relative to the center point along an axis to a reposition relative to the cell edges."""
376+
if position != "center":
377+
return index, bcoord
378+
379+
bcoord = bcoord - 0.5
380+
if bcoord < 0:
381+
bcoord += 1.0
382+
index -= 1
383+
384+
# Correct relative to the f-point position
385+
if f_points_position in ["inner", "right"]:
386+
index += 1
387+
388+
return index, bcoord

0 commit comments

Comments
 (0)