Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c056b80
Added support for 3D conservative resampling to `regridding.weights()`.
roytsmart Apr 29, 2025
90ea88c
added `_index_of_point_brute()`
roytsmart Apr 30, 2025
66887cb
Added `_indices_boundary()` function.
roytsmart Apr 30, 2025
01348d7
Added `_arrays` module.
roytsmart May 2, 2025
42cd564
Added `_volumes` module.
roytsmart May 2, 2025
0991d1f
Added `_grids` module.
roytsmart May 2, 2025
b708151
Added `_intercepts` module
roytsmart May 2, 2025
43c3bc3
Moving stuff
roytsmart May 2, 2025
107d83d
Moving stuff around
roytsmart May 4, 2025
5510063
renaming bug
roytsmart May 4, 2025
1de6fd2
added `_line_point_closest_approach()`
roytsmart May 4, 2025
664e6ff
added `_line_point_closest_approach()`
roytsmart May 4, 2025
20a0b2d
Added `_arrays.axes`
roytsmart May 5, 2025
e418099
slight improvements
roytsmart May 5, 2025
ba12302
Moving stuff and first draft of `_step_inside_static()`.
roytsmart May 5, 2025
f60a534
Lots of updates and refactoring
roytsmart May 7, 2025
6c22d03
Added `_intercepts.insert_intercept()`.
roytsmart May 8, 2025
0c2c08b
Fixed a ton of bugs so that the program runs now. Still doesn't produ…
roytsmart May 14, 2025
2ee6087
fixe bugs introduced by previous commit
roytsmart May 14, 2025
e0a8284
First working version
roytsmart Feb 3, 2026
7cb5876
actual first working version
roytsmart Feb 3, 2026
b0209a7
fix test
roytsmart Feb 3, 2026
5e7fc16
black
roytsmart Feb 3, 2026
7298d2c
Fixed a bug where the first point of the "parallel" vector was incorr…
roytsmart Mar 5, 2026
2028cc9
indent error
roytsmart May 7, 2026
4c600e9
more indent issues
roytsmart May 7, 2026
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
19 changes: 18 additions & 1 deletion regridding/_weights/_weights_conservative.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from regridding import _util
from ._weights_conservative_1d import weights_conservative_1d
from regridding._conservative_ramshaw import _conservative_ramshaw
from ._weights_conservative_3d import weights_conservative_3d


def _weights_conservative(
Expand Down Expand Up @@ -127,9 +128,25 @@ def _weights_conservative(
weights_input=weights_input_index,
)

elif len(axis_input) == 3:
x_input, y_input, z_input = coordinates_input
x_output, y_output, z_output = coordinates_output
weights[index] = weights_conservative_3d(
grid_input=(
x_input[index_vertices_input],
y_input[index_vertices_input],
z_input[index_vertices_input],
),
grid_output=(
x_output[index_vertices_output],
y_output[index_vertices_output],
z_output[index_vertices_output],
),
)

else: # pragma: nocover
raise NotImplementedError(
"Regridding operations greater than 2D are not supported"
"Regridding operations greater than 3D are not supported"
)

return weights, shape_values_input, shape_values_output
9 changes: 9 additions & 0 deletions regridding/_weights/_weights_conservative_3d/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""
A subpackage for performing 3D conservative resampling
"""

from ._weights_conservative_3d import weights_conservative_3d

__all__ = [
"weights_conservative_3d",
]
147 changes: 147 additions & 0 deletions regridding/_weights/_weights_conservative_3d/_arrays.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
"""
3-dimensional array manipulation routines.
"""

import numpy as np
import numba

__all__ = [
"axis_x",
"axis_y",
"axis_z",
"axes",
"index_in_bounds",
"index_flat",
"index_3d",
"align_axis_right",
]

axis_x = 0
axis_y = 1
axis_z = 2

axes = (axis_x, axis_y, axis_z)

vector_unit = (
(1, 0, 0),
(0, 1, 0),
(0, 0, 1),
)


@numba.njit(cache=True)
def index_in_bounds(
index: tuple[int, int, int],
shape: tuple[int, int, int],
):
"""
Check if a 3D index is within array bounds specified by `shape`.

Parameters
----------
index
The 3D index to check.
shape
The shape of the array to use as the bounds.
"""
i, j, k = index

if i < 0:
return False
if j < 0:
return False
if k < 0:
return False

nx, ny, nz = shape

if i >= nx:
return False
if j >= ny:
return False
if k >= nz:
return False

return True


@numba.njit(cache=True)
def index_flat(
index: tuple[int, int, int],
shape: tuple[int, int, int],
) -> int:
"""
Convert a 3D index to a flat index.

Parameters
----------
index
A 3D index to convert.
shape
The sizes of each axis of the array.
"""

i, j, k = index

num_x, num_y, num_z = shape

result = i * num_y * num_z + j * num_z + k

return result


@numba.njit(cache=True)
def index_3d(
index: int,
shape: tuple[int, int, int],
) -> tuple[int, int, int]:
"""
Convert a flat index to a 3D index.

Parameters
----------
index
A flat index to convert.
shape
The sizes of each axis of the array.
"""

num_x, num_y, num_z = shape

k = index % num_z

j = (index // num_z) % num_y

i = index // (num_z * num_y)

return i, j, k


@numba.njit(cache=True)
def align_axis_right(
a: np.ndarray,
axis: int,
) -> np.ndarray:
"""
Roll all the axes of a 3D array to the right until `axis` is the last axis.

This function is needed to permute the axes in such a way to retain
their right-handedness.

Parameters
----------
a
The array to modify the axes of.
axis
The axis to set as the last axis.
"""
axis = axis % a.ndim

if axis == axis_x:
result = a.transpose((axis_y, axis_z, axis_x))
elif axis == axis_y:
result = a.transpose((axis_z, axis_x, axis_y))
else:
result = a

return result
85 changes: 85 additions & 0 deletions regridding/_weights/_weights_conservative_3d/_arrays_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import pytest
import numpy as np
from . import _arrays


@pytest.mark.parametrize(
argnames="index,shape,result_expected",
argvalues=[
(
(0, 0, 0),
(11, 12, 13),
True,
),
(
(5, 5, 5),
(11, 12, 13),
True,
),
(
(-1, 0, 0),
(11, 12, 13),
False,
),
(
(0, 12, 0),
(11, 12, 13),
False,
),
],
)
def test_index_in_bounds(
index: tuple[int, int, int],
shape: tuple[int, int, int],
result_expected: bool,
):
result = _arrays.index_in_bounds(index=index, shape=shape)

assert result == result_expected


@pytest.mark.parametrize(
argnames="index",
argvalues=[
(1, 1, 1),
(5, 6, 7),
],
)
@pytest.mark.parametrize(
argnames="shape",
argvalues=[
(11, 12, 13),
],
)
def test_index_flat(
index: tuple[int, int, int],
shape: tuple[int, int, int],
):
result = _arrays.index_flat(index=index, shape=shape)
result_expected = np.ravel_multi_index(index, shape)

assert result == result_expected


@pytest.mark.parametrize(
argnames="index",
argvalues=[0, 11, 25],
)
@pytest.mark.parametrize(
argnames="shape",
argvalues=[
(11, 12, 13),
],
)
def test_index_3d(
index: int,
shape: tuple[int, int, int],
):
result = _arrays.index_3d(index=index, shape=shape)
result_expected = np.unravel_index(index, shape)

print(f"{result=}")
print(f"{result_expected=}")

assert result == result_expected
assert index == np.ravel_multi_index(result, shape)
Loading
Loading