Skip to content

Commit 261afd3

Browse files
committed
fixes
1 parent dd919ab commit 261afd3

3 files changed

Lines changed: 650 additions & 1 deletion

File tree

src/nanomodule/geoprocessing/datastructures/c_beamsamplegeometry.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
// -- include nanobind headers
1111
#include <nanobind/nanobind.h>
1212
#include <nanobind/stl/string.h>
13+
#include <nanobind/stl/optional.h>
1314

1415
namespace themachinethatgoesping {
1516
namespace algorithms {
@@ -30,6 +31,24 @@ using namespace themachinethatgoesping::algorithms::geoprocessing::datastructure
3031

3132
void init_c_beamsamplegeometry(nb::module_& m)
3233
{
34+
// Register Bounds struct
35+
nb::class_<BeamSampleGeometry::Bounds>(m, "BeamSampleGeometryBounds",
36+
"Bounding box of beam/sample coordinates.")
37+
.def(nb::init<>())
38+
.def_rw("x_min", &BeamSampleGeometry::Bounds::x_min)
39+
.def_rw("x_max", &BeamSampleGeometry::Bounds::x_max)
40+
.def_rw("y_min", &BeamSampleGeometry::Bounds::y_min)
41+
.def_rw("y_max", &BeamSampleGeometry::Bounds::y_max)
42+
.def_rw("z_min", &BeamSampleGeometry::Bounds::z_min)
43+
.def_rw("z_max", &BeamSampleGeometry::Bounds::z_max)
44+
.def("__eq__", &BeamSampleGeometry::Bounds::operator==, nb::arg("other"))
45+
.def("__repr__", [](const BeamSampleGeometry::Bounds& b) {
46+
return fmt::format(
47+
"BeamSampleGeometryBounds(x=[{}, {}], y=[{}, {}], z=[{}, {}])",
48+
b.x_min, b.x_max, b.y_min, b.y_max, b.z_min, b.z_max);
49+
})
50+
;
51+
3352
nb::class_<BeamSampleGeometry>(m,
3453
"BeamSampleGeometry",
3554
DOC(themachinethatgoesping,
@@ -275,6 +294,53 @@ void init_c_beamsamplegeometry(nb::module_& m)
275294
&BeamSampleGeometry::forward_z_flat,
276295
DOC_BeamSampleGeometry(forward_z_flat))
277296

297+
// --- bounds ---
298+
.def("get_bounds",
299+
&BeamSampleGeometry::get_bounds,
300+
DOC_BeamSampleGeometry(get_bounds))
301+
302+
// --- backward mapping ---
303+
.def("backward_nearest",
304+
[](const BeamSampleGeometry& self,
305+
const xt::nanobind::pytensor<float, 2>& data,
306+
const xt::nanobind::pytensor<float, 1>& y_coordinates,
307+
const xt::nanobind::pytensor<float, 1>& z_coordinates,
308+
unsigned int supersampling,
309+
int mp_cores) {
310+
return self.backward_nearest<xt::nanobind::pytensor<float, 2>>(
311+
data, y_coordinates, z_coordinates,
312+
supersampling, mp_cores);
313+
},
314+
"Backward-map WCI data to (y, z) image via nearest-neighbor.\n"
315+
"Sample numbers use Euclidean range from the sensor to each pixel.\n"
316+
"When supersampling > 1, probes S*S sub-pixel locations per pixel\n"
317+
"and averages (equivalent to render-at-high-res-then-downsample).",
318+
nb::arg("data"),
319+
nb::arg("y_coordinates"),
320+
nb::arg("z_coordinates"),
321+
nb::arg("supersampling") = 1,
322+
nb::arg("mp_cores") = 1)
323+
.def("backward_bilinear",
324+
[](const BeamSampleGeometry& self,
325+
const xt::nanobind::pytensor<float, 2>& data,
326+
const xt::nanobind::pytensor<float, 1>& y_coordinates,
327+
const xt::nanobind::pytensor<float, 1>& z_coordinates,
328+
unsigned int supersampling,
329+
int mp_cores) {
330+
return self.backward_bilinear<xt::nanobind::pytensor<float, 2>>(
331+
data, y_coordinates, z_coordinates,
332+
supersampling, mp_cores);
333+
},
334+
"Backward-map WCI data to (y, z) image via bilinear interpolation.\n"
335+
"Sample numbers use Euclidean range from the sensor to each pixel.\n"
336+
"When supersampling > 1, probes S*S sub-pixel locations per pixel\n"
337+
"and averages (equivalent to render-at-high-res-then-downsample).",
338+
nb::arg("data"),
339+
nb::arg("y_coordinates"),
340+
nb::arg("z_coordinates"),
341+
nb::arg("supersampling") = 1,
342+
nb::arg("mp_cores") = 1)
343+
278344
// default copy functions
279345
__PYCLASS_DEFAULT_COPY__(BeamSampleGeometry)
280346
// default binary functions

src/themachinethatgoesping/algorithms/geoprocessing/datastructures/.docstrings/beamsamplegeometry.doc.hpp

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//sourcehash: 97d19657d33075163f50667baa67c3394102512c554c17c24a5f3e02651efe06
1+
//sourcehash: 2a84e8c19f986b614b955d391432e1228168461d4db1898ee54361b1b5cb5359
22

33
/*
44
This file contains docstrings for use in the Python bindings.
@@ -62,12 +62,91 @@ set)
6262
first_sample_numbers: first valid sample number per beam [n_beams]
6363
number_of_samples: number of samples per beam [n_beams])doc";
6464

65+
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_Bounds =
66+
R"doc(Bounding box of all beam endpoints in (x, y, z) space.
67+
68+
Coordinates are NaN for dimensions without a set affine.)doc";
69+
70+
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_Bounds_operator_eq = R"doc()doc";
71+
72+
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_Bounds_x_max = R"doc()doc";
73+
74+
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_Bounds_x_min = R"doc()doc";
75+
76+
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_Bounds_y_max = R"doc()doc";
77+
78+
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_Bounds_y_min = R"doc()doc";
79+
80+
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_Bounds_z_max = R"doc()doc";
81+
82+
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_Bounds_z_min = R"doc()doc";
83+
6584
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_affine_x = R"doc(sample_nr → x per beam)doc";
6685

6786
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_affine_y = R"doc(sample_nr → y per beam)doc";
6887

6988
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_affine_z = R"doc(sample_nr → z per beam)doc";
7089

90+
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_backward_bilinear =
91+
R"doc(Backward-map WCI data into a (y, z) image via bilinear interpolation.
92+
93+
For each output pixel, brackets the nearest two beams and the
94+
fractional sample number, then bilinearly interpolates. Sample numbers
95+
are computed from the Euclidean range to the sensor.
96+
97+
When supersampling > 1, each pixel probes S×S sub-pixel locations and
98+
averages the results for anti-aliasing.
99+
100+
Pixels outside the beam/sample coverage are NaN.
101+
102+
Args:
103+
data: WCI data [n_beams x max_samples]
104+
y_coordinates: target crosstrack coordinates [n_y], must be sorted
105+
z_coordinates: target depth coordinates [n_z], must be sorted
106+
supersampling: sub-pixel factor per axis (default 1)
107+
mp_cores: OpenMP threads (default 1)
108+
109+
Template Args:
110+
t_xtensor_out: 2D output type (e.g. xt::xtensor<float,2> or
111+
pytensor)
112+
t_xtensor_2d: 2D xtensor-like input type
113+
t_xtensor_1d_y: 1D xtensor-like type for y coordinates
114+
t_xtensor_1d_z: 1D xtensor-like type for z coordinates
115+
116+
Returns:
117+
image [n_y x n_z], NaN where no valid data)doc";
118+
119+
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_backward_nearest =
120+
R"doc(Backward-map WCI data into a (y, z) image via nearest-neighbor.
121+
122+
For each output pixel, finds the nearest beam via depth-invariant
123+
tangent matching and computes the sample number from the pixel's
124+
Euclidean range to the sensor (matching BTConstantSVP behaviour).
125+
126+
When supersampling > 1, each pixel probes S×S sub-pixel locations and
127+
averages the results for anti-aliasing. This is equivalent to
128+
rendering at S× resolution then downsampling, but uses no extra
129+
memory.
130+
131+
Pixels outside the beam/sample coverage are NaN.
132+
133+
Args:
134+
data: WCI data [n_beams x max_samples]
135+
y_coordinates: target crosstrack coordinates [n_y], must be sorted
136+
z_coordinates: target depth coordinates [n_z], must be sorted
137+
supersampling: sub-pixel factor per axis (default 1)
138+
mp_cores: OpenMP threads (default 1)
139+
140+
Template Args:
141+
t_xtensor_out: 2D output type (e.g. xt::xtensor<float,2> or
142+
pytensor)
143+
t_xtensor_2d: 2D xtensor-like input type
144+
t_xtensor_1d_y: 1D xtensor-like type for y coordinates
145+
t_xtensor_1d_z: 1D xtensor-like type for z coordinates
146+
147+
Returns:
148+
image [n_y x n_z], NaN where no valid data)doc";
149+
71150
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_check_affine_size = R"doc()doc";
72151

73152
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_first_sample_numbers = R"doc([n_beams] first valid sample nr)doc";
@@ -227,6 +306,13 @@ per-beam bottom depths at known sample numbers.
227306

228307
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_from_stream = R"doc()doc";
229308

309+
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_get_bounds =
310+
R"doc(Compute the bounding box of all beam/sample coordinates.
311+
312+
Evaluates the forward transform at the first and last sample of every
313+
beam and takes min/max. Only populates bounds for dimensions that
314+
have a set affine; others stay NaN.)doc";
315+
230316
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_get_first_sample_numbers = R"doc()doc";
231317

232318
static const char *mkd_doc_themachinethatgoesping_algorithms_geoprocessing_datastructures_BeamSampleGeometry_get_flat_offsets =

0 commit comments

Comments
 (0)