From c1ad43e53d8d3f57509c6101c49de2038cec7eac Mon Sep 17 00:00:00 2001 From: Jonathan Mulvey Date: Thu, 22 Jan 2026 15:49:03 +0100 Subject: [PATCH] Fresh branch with up-to-date changes from Main. Changes from fix/rounding have also been implemented here. This commit also includes the changes necessary so that the cluster finder can search for NxN clusters while saving MxM which greatly improves performance and the efficiency of pile-up rejection later down the line --- include/aare/ClusterFinder.hpp | 21 ++++++++++++++------- include/aare/ClusterFinderMT.hpp | 5 +++-- python/aare/ClusterFinder.py | 12 ++++++------ python/src/bind_ClusterFinder.hpp | 5 +++-- python/src/bind_ClusterFinderMT.hpp | 5 +++-- 5 files changed, 29 insertions(+), 19 deletions(-) diff --git a/include/aare/ClusterFinder.hpp b/include/aare/ClusterFinder.hpp index 7d059ff..46275c0 100644 --- a/include/aare/ClusterFinder.hpp +++ b/include/aare/ClusterFinder.hpp @@ -26,11 +26,13 @@ class ClusterFinder { const PEDESTAL_TYPE m_nSigma; const PEDESTAL_TYPE c2; const PEDESTAL_TYPE c3; + const uint32_t ClusterSizeX; + const uint32_t ClusterSizeY; Pedestal m_pedestal; ClusterVector m_clusters; - static const uint8_t ClusterSizeX = ClusterType::cluster_size_x; - static const uint8_t ClusterSizeY = ClusterType::cluster_size_y; + static const uint8_t SavedClusterSizeX = ClusterType::cluster_size_x; + static const uint8_t SavedClusterSizeY = ClusterType::cluster_size_y; using CT = typename ClusterType::value_type; public: @@ -43,10 +45,12 @@ class ClusterFinder { * */ ClusterFinder(Shape<2> image_size, PEDESTAL_TYPE nSigma = 5.0, - size_t capacity = 1000000) + size_t capacity = 1000000, + uint32_t cluster_size_x = 3, uint32_t cluster_size_y = 3) : m_image_size(image_size), m_nSigma(nSigma), - c2(sqrt((ClusterSizeY + 1) / 2 * (ClusterSizeX + 1) / 2)), - c3(sqrt(ClusterSizeX * ClusterSizeY)), + c2(sqrt((cluster_size_y + 1) / 2 * (cluster_size_x + 1) / 2)), + c3(sqrt(cluster_size_x * cluster_size_y)), + ClusterSizeX(cluster_size_x), ClusterSizeY(cluster_size_y), m_pedestal(image_size[0], image_size[1]), m_clusters(capacity) { LOG(logDEBUG) << "ClusterFinder: " << "image_size: " << image_size[0] << "x" << image_size[1] @@ -83,6 +87,9 @@ class ClusterFinder { // // 4,4 -> +/- 2 int dy = ClusterSizeY / 2; int dx = ClusterSizeX / 2; + int dy2 = SavedClusterSizeY / 2; + int dx2 = SavedClusterSizeX / 2; + int has_center_pixel_x = ClusterSizeX % 2; // for even sized clusters there is no proper cluster center and @@ -144,8 +151,8 @@ class ClusterFinder { // It's worth redoing the look since most of the time we // don't have a photon int i = 0; - for (int ir = -dy; ir < dy + has_center_pixel_y; ir++) { - for (int ic = -dx; ic < dx + has_center_pixel_x; ic++) { + for (int ir = -dy2; ir < dy2 + has_center_pixel_y; ir++) { + for (int ic = -dx2; ic < dx2 + has_center_pixel_x; ic++) { if (ix + ic >= 0 && ix + ic < frame.shape(1) && iy + ir >= 0 && iy + ir < frame.shape(0)) { diff --git a/include/aare/ClusterFinderMT.hpp b/include/aare/ClusterFinderMT.hpp index b5df766..f941f35 100644 --- a/include/aare/ClusterFinderMT.hpp +++ b/include/aare/ClusterFinderMT.hpp @@ -126,7 +126,8 @@ class ClusterFinderMT { * @param n_threads number of threads to use */ ClusterFinderMT(Shape<2> image_size, PEDESTAL_TYPE nSigma = 5.0, - size_t capacity = 2000, size_t n_threads = 3) + size_t capacity = 2000, size_t n_threads = 3, + uint32_t cluster_size_x = 3, uint32_t cluster_size_y = 3) : m_n_threads(n_threads) { LOG(logDEBUG1) << "ClusterFinderMT: " @@ -139,7 +140,7 @@ class ClusterFinderMT { m_cluster_finders.push_back( std::make_unique< ClusterFinder>( - image_size, nSigma, capacity)); + image_size, nSigma, capacity, cluster_size_x, cluster_size_y)); } for (size_t i = 0; i < n_threads; i++) { m_input_queues.emplace_back(std::make_unique(200)); diff --git a/python/aare/ClusterFinder.py b/python/aare/ClusterFinder.py index eae7ad7..efb44f6 100644 --- a/python/aare/ClusterFinder.py +++ b/python/aare/ClusterFinder.py @@ -29,24 +29,24 @@ def _get_class(name, cluster_size, dtype): -def ClusterFinder(image_size, cluster_size=(3,3), n_sigma=5, dtype = np.int32, capacity = 1024): +def ClusterFinder(image_size, saved_cluster_size=(3,3), checked_cluster_size=(3,3), n_sigma=5, dtype = np.int32, capacity = 1024): """ Factory function to create a ClusterFinder object. Provides a cleaner syntax for the templated ClusterFinder in C++. """ - cls = _get_class("ClusterFinder", cluster_size, dtype) - return cls(image_size, n_sigma=n_sigma, capacity=capacity) + cls = _get_class("ClusterFinder", saved_cluster_size, dtype) + return cls(image_size, n_sigma=n_sigma, capacity=capacity, cluster_size_x=checked_cluster_size[0], cluster_size_y=checked_cluster_size[1]) -def ClusterFinderMT(image_size, cluster_size = (3,3), dtype=np.int32, n_sigma=5, capacity = 1024, n_threads = 3): +def ClusterFinderMT(image_size, saved_cluster_size=(3,3), checked_cluster_size=(3,3), dtype=np.int32, n_sigma=5, capacity = 1024, n_threads = 3): """ Factory function to create a ClusterFinderMT object. Provides a cleaner syntax for the templated ClusterFinderMT in C++. """ - cls = _get_class("ClusterFinderMT", cluster_size, dtype) - return cls(image_size, n_sigma=n_sigma, capacity=capacity, n_threads=n_threads) + cls = _get_class("ClusterFinderMT", saved_cluster_size, dtype) + return cls(image_size, n_sigma=n_sigma, capacity=capacity, n_threads=n_threads, cluster_size_x=checked_cluster_size[0], cluster_size_y=checked_cluster_size[1]) def ClusterCollector(clusterfindermt, dtype=np.int32): diff --git a/python/src/bind_ClusterFinder.hpp b/python/src/bind_ClusterFinder.hpp index 49e203b..db64980 100644 --- a/python/src/bind_ClusterFinder.hpp +++ b/python/src/bind_ClusterFinder.hpp @@ -31,8 +31,9 @@ void define_ClusterFinder(py::module &m, const std::string &typestr) { py::class_>( m, class_name.c_str()) - .def(py::init, pd_type, size_t>(), py::arg("image_size"), - py::arg("n_sigma") = 5.0, py::arg("capacity") = 1'000'000) + .def(py::init, pd_type, size_t, uint32_t, uint32_t>(), py::arg("image_size"), + py::arg("n_sigma") = 5.0, py::arg("capacity") = 1'000'000, + py::arg("cluster_size_x") = 3, py::arg("cluster_size_y") = 3) .def("push_pedestal_frame", [](ClusterFinder &self, py::array_t frame) { diff --git a/python/src/bind_ClusterFinderMT.hpp b/python/src/bind_ClusterFinderMT.hpp index c03eeeb..46375eb 100644 --- a/python/src/bind_ClusterFinderMT.hpp +++ b/python/src/bind_ClusterFinderMT.hpp @@ -31,9 +31,10 @@ void define_ClusterFinderMT(py::module &m, const std::string &typestr) { py::class_>( m, class_name.c_str()) - .def(py::init, pd_type, size_t, size_t>(), + .def(py::init, pd_type, size_t, size_t, uint32_t, uint32_t>(), py::arg("image_size"), py::arg("n_sigma") = 5.0, - py::arg("capacity") = 2048, py::arg("n_threads") = 3) + py::arg("capacity") = 2048, py::arg("n_threads") = 3, + py::arg("cluster_size_x") = 3, py::arg("cluster_size_y") = 3) .def("push_pedestal_frame", [](ClusterFinderMT &self, py::array_t frame) {