min_pedestal_samples is last argument
Build on RHEL9 / build (push) Successful in 2m33s
Build on RHEL8 / build (push) Successful in 3m41s
Run tests using data on local RHEL8 / build (push) Successful in 4m17s

This commit is contained in:
mazzol_a committed 2026-09-03 17:09:15 +02:00
1 parent b117e34089
commit 567111c66e
5 files changed
+19 -18

No files matched your search

+2 -1
View File
@@ -63,7 +63,8 @@ class ClusterFinder {
m_pd_corrected_frame({image_size[0], image_size[1]}, 0) {
LOG(logDEBUG) << "ClusterFinder: "
<< "image_size: " << image_size[0] << "x" << image_size[1]
<< ", nSigma: " << nSigma << ", capacity: " << capacity;
<< ", nSigma: " << nSigma << ", capacity: " << capacity
<< ", min_pedestal_samples: " << min_pedestal_samples;
}
/**
+4 -4
View File
@@ -174,17 +174,17 @@ class ClusterFinderMT {
* @param nSigma number of sigma above the pedestal to consider a photon
* @param capacity initial capacity of the cluster vector. Should match
* expected number of clusters in a frame per frame.
* @param min_pedestal_samples minimum number of pedestal frames to
* accumulate to get reasonable statistics
* @param n_threads number of threads to use
* @param queue_depth number of frame buffers per thread. These are
* allocated once and recycled, so the total resident frame memory is
* n_threads * queue_depth * frame size. Keeping the in flight data below
* the L3 size keeps the per frame copy cheap.
* @param min_pedestal_samples minimum number of pedestal samples to
* accumulate before using the pedestal
*/
ClusterFinderMT(Shape<2> image_size, PEDESTAL_TYPE nSigma = 5.0,
size_t capacity = 2000, size_t min_pedestal_samples = 1000,
size_t n_threads = 3, size_t queue_depth = 16)
size_t capacity = 2000, size_t n_threads = 3,
size_t queue_depth = 16, size_t min_pedestal_samples = 1000)
: m_n_threads(n_threads) {
LOG(logDEBUG1) << "ClusterFinderMT: "
+4 -5
View File
@@ -18,7 +18,7 @@ def _get_class(name, cluster_size, dtype):
def ClusterFinder(image_size, cluster_size=(3,3), n_sigma=5, dtype = np.int32, capacity = 1024, min_pedestal_samples = 1000):
def ClusterFinder(image_size, *, cluster_size=(3,3), n_sigma=5, dtype = np.int32, capacity = 1024, min_pedestal_samples = 1000):
"""
Factory function to create a ClusterFinder object. Provides a cleaner syntax for
the templated ClusterFinder in C++.
@@ -42,8 +42,7 @@ def ClusterFinder(image_size, cluster_size=(3,3), n_sigma=5, dtype = np.int32, c
return cls(image_size, n_sigma=n_sigma, capacity=capacity, min_pedestal_samples=min_pedestal_samples)
def ClusterFinderMT(image_size, cluster_size = (3,3), dtype=np.int32, n_sigma=5, capacity = 1024, min_pedestal_samples = 1000, n_threads = 3):
def ClusterFinderMT(image_size, *, cluster_size = (3,3), dtype=np.int32, n_sigma=5, capacity = 1024, n_threads = 3, min_pedestal_samples = 1000):
"""
Factory function to create a ClusterFinderMT object. Provides a cleaner syntax for
the templated ClusterFinderMT in C++.
@@ -60,10 +59,10 @@ def ClusterFinderMT(image_size, cluster_size = (3,3), dtype=np.int32, n_sigma=5,
The data type of the image. Default is np.int32.
capacity : int, optional
The maximum number of clusters than can be stored before reallocating. Default is 1024.
min_pedestal_samples : int, optional
The minimum number of pedestal samples to accumulate before using the pedestal. Default is 1000.
n_threads : int, optional
The number of threads to use for processing. Default is 3.
min_pedestal_samples : int, optional
The minimum number of pedestal samples to accumulate before using the pedestal. Default is 1000.
"""
cls = _get_class("ClusterFinderMT", cluster_size, dtype)
+3 -2
View File
@@ -34,8 +34,9 @@ void define_ClusterFinderMT(py::module &m, const std::string &typestr) {
m, class_name.c_str())
.def(py::init<Shape<2>, pd_type, size_t, size_t, size_t, size_t>(),
py::arg("image_size"), py::arg("n_sigma") = 5.0,
py::arg("capacity") = 2048, py::arg("min_pedestal_samples") = 1000,
py::arg("n_threads") = 3, py::arg("queue_depth") = 16)
py::arg("capacity") = 2048, py::arg("n_threads") = 3,
py::arg("queue_depth") = 16,
py::arg("min_pedestal_samples") = 1000)
.def("push_pedestal_frame",
[](ClusterFinderMT<ClusterType, uint16_t, pd_type> &self,
py::array_t<uint16_t> frame) {
+6 -6
View File
@@ -22,9 +22,11 @@ class ClusterFinderMTWrapper
public:
ClusterFinderMTWrapper(Shape<2> image_size, PEDESTAL_TYPE nSigma = 5.0,
size_t capacity = 2000, size_t n_threads = 3,
size_t queue_depth = 16)
size_t queue_depth = 16,
size_t minimum_pedestal_samples = 1000)
: ClusterFinderMT<ClusterType, FRAME_TYPE, PEDESTAL_TYPE>(
image_size, nSigma, capacity, n_threads, queue_depth) {}
image_size, nSigma, capacity, n_threads, queue_depth,
minimum_pedestal_samples) {}
size_t get_m_input_queues_size() const {
return this->m_input_queues.size();
@@ -73,15 +75,14 @@ TEST_CASE("multithreaded cluster finder", "[.with-data]") {
File file(fpath);
size_t n_threads = 2;
size_t n_frames_pd = 1;
size_t minimum_pedestal_samples = 1;
size_t n_frames = 10;
using ClusterType = Cluster<int32_t, 3, 3>;
ClusterFinderMTWrapper<ClusterType> cf(
{static_cast<int64_t>(file.rows()), static_cast<int64_t>(file.cols())},
5, 2000, n_frames_pd,
n_threads); // no idea what frame type is!!! default uint16_t
5, 2000, n_threads, 16, minimum_pedestal_samples);
CHECK(cf.get_m_input_queues_size() == n_threads);
CHECK(cf.get_m_output_queues_size() == n_threads);
@@ -110,7 +111,6 @@ TEST_CASE("multithreaded cluster finder", "[.with-data]") {
CHECK(cf.m_sink_size() == 0);
auto clustervec = clustercollector.steal_clusters();
// CHECK(clustervec.size() == ) //dont know how many clusters to expect
}
TEST_CASE("frame buffers are recycled when pushing more frames than the pool "