From bcb0a582727533324d7a226be8670a65b995258e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Fr=C3=B6jdh?= Date: Fri, 5 Jun 2026 15:14:32 +0200 Subject: [PATCH] bind all variants --- python/aare/__init__.py | 11 +++++- python/src/bind_PixelHistogram.hpp | 58 ++++++++++++++++++++++-------- 2 files changed, 53 insertions(+), 16 deletions(-) diff --git a/python/aare/__init__.py b/python/aare/__init__.py index b677c13..10872f8 100644 --- a/python/aare/__init__.py +++ b/python/aare/__init__.py @@ -44,4 +44,13 @@ from ._aare import apply_calibration, count_switching_pixels from ._aare import calculate_pedestal, calculate_pedestal_float, calculate_pedestal_g0, calculate_pedestal_g0_float from ._aare import VarClusterFinder -from ._aare import PixelHistogram, PedestalTrackingPixelHistogram +from ._aare import ( + PedestalTrackingPixelHistogram, + PixelHistogram, + PixelHistogram_d, + PixelHistogram_f, + PixelHistogram_u8, + PixelHistogram_u16, + PixelHistogram_u32, + PixelHistogram_u64, +) diff --git a/python/src/bind_PixelHistogram.hpp b/python/src/bind_PixelHistogram.hpp index a9f6093..0e61f52 100644 --- a/python/src/bind_PixelHistogram.hpp +++ b/python/src/bind_PixelHistogram.hpp @@ -2,19 +2,29 @@ #include "aare/hist/PixelHistogram.hpp" #include "np_helper.hpp" +#include #include #include #include #include +#include namespace py = pybind11; using namespace ::aare; -void define_pixel_histogram_bindings(py::module &m) { - using PixelHistogramF32U16 = PixelHistogram; +namespace { - py::class_(m, "PixelHistogram", - "A histogram for pixel-wise statistics") +template +void define_pixel_histogram_binding(py::module &m, const char *class_name, + const char *storage_dtype) { + using Hist = PixelHistogram; + + const std::string doc = + std::string("A histogram for pixel-wise statistics with float64 input " + "axis and ") + + storage_dtype + " bin storage"; + + py::class_(m, class_name, doc.c_str()) .def(py::init(), R"( Initialize a PixelHistogram. @@ -36,12 +46,12 @@ void define_pixel_histogram_bindings(py::module &m) { .def( "fill_async", - [](PixelHistogramF32U16 &self, py::array_t image) { + [](Hist &self, py::array_t image) { // Copy the numpy buffer into an owned NDArray while we // still hold the GIL so we don't depend on the array's // backing storage outliving this call. auto view = make_view_2d(image); - NDArray owned(view); + NDArray owned(view); // Release the GIL while enqueueing - fill_async can block // on backpressure when the queue is full. py::gil_scoped_release release; @@ -57,11 +67,11 @@ void define_pixel_histogram_bindings(py::module &m) { blocks (with the GIL released) until a slot becomes available. Args: - image: A 2D numpy array of pixel values (dtype: float32) + image: A 2D numpy array of pixel values (dtype: float64) )", py::arg("image").noconvert()) - .def("flush", &PixelHistogramF32U16::flush, + .def("flush", &Hist::flush, R"( Block until all images submitted via fill_async() have been merged into the accumulators. Cheap when nothing is pending. @@ -70,14 +80,14 @@ void define_pixel_histogram_bindings(py::module &m) { .def( "values", - [](const PixelHistogramF32U16 &self) { + [](const Hist &self) { // values() implicitly flushes - release the GIL while it // does so. Allocation/copy into the NDArray runs without // the GIL too; only the numpy wrapping needs it. - NDArray *ptr = nullptr; + NDArray *ptr = nullptr; { py::gil_scoped_release release; - ptr = new NDArray(self.values()); + ptr = new NDArray(self.values()); } return return_image_data(ptr); }, @@ -94,8 +104,8 @@ void define_pixel_histogram_bindings(py::module &m) { .def( "bin_centers", - [](const PixelHistogramF32U16 &self) { - auto ptr = new NDArray(self.bin_centers()); + [](const Hist &self) { + auto ptr = new NDArray(self.bin_centers()); return return_image_data(ptr); }, R"( @@ -106,8 +116,8 @@ void define_pixel_histogram_bindings(py::module &m) { )") .def( "bin_edges", - [](const PixelHistogramF32U16 &self) { - auto ptr = new NDArray(self.bin_edges()); + [](const Hist &self) { + auto ptr = new NDArray(self.bin_edges()); return return_image_data(ptr); }, R"( @@ -117,3 +127,21 @@ void define_pixel_histogram_bindings(py::module &m) { A 1D numpy array containing the edge values for the histogram bins )"); } + +} // namespace + +void define_pixel_histogram_bindings(py::module &m) { + define_pixel_histogram_binding(m, "PixelHistogram_d", "float64"); + define_pixel_histogram_binding(m, "PixelHistogram_f", "float32"); + define_pixel_histogram_binding(m, "PixelHistogram_u64", + "uint64"); + define_pixel_histogram_binding(m, "PixelHistogram_u32", + "uint32"); + define_pixel_histogram_binding(m, "PixelHistogram_u16", + "uint16"); + define_pixel_histogram_binding(m, "PixelHistogram_u8", + "uint8"); + + // Backwards-compatible alias for the generic Python class name. + m.attr("PixelHistogram") = m.attr("PixelHistogram_d"); +}