fill_async
Build on RHEL8 / build (push) Failing after 1m17s
Build on RHEL9 / build (push) Failing after 1m22s
Run tests using data on local RHEL8 / build (push) Failing after 1m54s

This commit is contained in:
Erik Frojdh
2026-05-24 10:02:49 +02:00
parent ee6b6dc990
commit e71bbb8288
5 changed files with 317 additions and 15 deletions
+1
View File
@@ -43,3 +43,4 @@ 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
+67 -9
View File
@@ -13,10 +13,10 @@ using namespace ::aare;
void define_pixel_histogram_bindings(py::module &m) {
py::class_<PixelHistogram>(m, "PixelHistogram",
"A histogram for pixel-wise statistics")
.def(py::init<int, int, int, double, double, int>(),
.def(py::init<int, int, int, double, double, int, std::size_t>(),
R"(
Initialize a PixelHistogram.
Args:
rows: Number of rows in the detector
cols: Number of columns in the detector
@@ -24,9 +24,13 @@ void define_pixel_histogram_bindings(py::module &m) {
xmin: Minimum value for histogram range
xmax: Maximum value for histogram range
n_threads: Number of threads for parallel filling (default: 1)
max_pending: Maximum number of images that can be queued for
asynchronous filling before fill_async() applies
backpressure on the caller (default: 16)
)",
py::arg("rows"), py::arg("cols"), py::arg("n_bins"),
py::arg("xmin"), py::arg("xmax"), py::arg("n_threads") = 1)
py::arg("xmin"), py::arg("xmax"), py::arg("n_threads") = 1,
py::arg("max_pending") = std::size_t{16})
.def("fill",
[](PixelHistogram &self,
@@ -35,21 +39,75 @@ void define_pixel_histogram_bindings(py::module &m) {
self.fill(view);
},
R"(
Fill the histogram with image data.
Fill the histogram with image data (blocking).
Args:
image: A 2D numpy array of pixel values (dtype: float32)
)",
py::arg("image").noconvert())
.def("fill_async",
[](PixelHistogram &self,
py::array_t<PixelHistogram::AxisType, 0> 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<PixelHistogram::AxisType, 2> owned(view);
// Release the GIL while enqueueing - fill_async can block
// on backpressure when the queue is full.
py::gil_scoped_release release;
self.fill_async(std::move(owned));
},
R"(
Submit an image for asynchronous filling.
The image is copied into an internal buffer before this call
returns, so the caller may mutate or free the numpy array
immediately. The actual histogram update happens on a
background thread. If the internal queue is full this call
blocks (with the GIL released) until a slot becomes available.
Args:
image: A 2D numpy array of pixel values (dtype: float32)
)",
py::arg("image").noconvert())
.def("flush",
&PixelHistogram::flush,
R"(
Block until all images submitted via fill_async() have been
merged into the accumulators. Cheap when nothing is pending.
)",
py::call_guard<py::gil_scoped_release>())
.def("pending",
&PixelHistogram::pending,
R"(
Return the number of images either waiting in the queue or
currently being processed by the background thread. Useful
for monitoring/diagnostics.
)")
.def("hdata",
[](const PixelHistogram &self) {
auto ptr = new NDArray<PixelHistogram::StorageType, 3>(self.hdata());
// hdata() 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<PixelHistogram::StorageType, 3>* ptr = nullptr;
{
py::gil_scoped_release release;
ptr = new NDArray<PixelHistogram::StorageType, 3>(self.hdata());
}
return return_image_data(ptr);
},
R"(
Get the histogram data as a numpy array.
Implicitly flushes any pending asynchronous fills before
returning, so the snapshot is consistent with everything
submitted up to this call.
Returns:
A 3D numpy array containing the histogram bins for each pixel
)")
@@ -61,7 +119,7 @@ void define_pixel_histogram_bindings(py::module &m) {
},
R"(
Get the bin centers along the value axis.
Returns:
A 1D numpy array containing the center values for each histogram bin
)")
@@ -72,7 +130,7 @@ void define_pixel_histogram_bindings(py::module &m) {
},
R"(
Get the bin edges along the value axis.
Returns:
A 1D numpy array containing the edge values for the histogram bins
)");