diff --git a/include/aare/ClusterFile.hpp b/include/aare/ClusterFile.hpp index ef78874..e26e765 100644 --- a/include/aare/ClusterFile.hpp +++ b/include/aare/ClusterFile.hpp @@ -5,6 +5,8 @@ #include "aare/GainMap.hpp" #include "aare/NDArray.hpp" #include "aare/defs.hpp" +#include "aare/logger.hpp" + #include #include #include @@ -369,11 +371,15 @@ ClusterFile::read_frame_without_cut() { "Could not read number of clusters"); } + LOG(logDEBUG1) << "Reading " << n_clusters + << " clusters from frame " << frame_number; + ClusterVector clusters(n_clusters); clusters.set_frame_number(frame_number); - clusters.resize(n_clusters); + LOG(logDEBUG1) << "clusters.item_size(): " << clusters.item_size(); + if (fread(clusters.data(), clusters.item_size(), n_clusters, fp) != static_cast(n_clusters)) { throw std::runtime_error(LOCATION + "Could not read clusters"); diff --git a/include/aare/ClusterFileSink.hpp b/include/aare/ClusterFileSink.hpp index 810e63c..09190fe 100644 --- a/include/aare/ClusterFileSink.hpp +++ b/include/aare/ClusterFileSink.hpp @@ -21,7 +21,7 @@ class ClusterFileSink { void process() { m_stopped = false; - fmt::print("ClusterFileSink started\n"); + LOG(logDEBUG) << "ClusterFileSink started"; while (!m_stop_requested || !m_source->isEmpty()) { if (ClusterVector *clusters = m_source->frontPtr(); clusters != nullptr) { @@ -41,13 +41,16 @@ class ClusterFileSink { std::this_thread::sleep_for(m_default_wait); } } - fmt::print("ClusterFileSink stopped\n"); + LOG(logDEBUG) << "ClusterFileSink stopped"; m_stopped = true; } public: ClusterFileSink(ClusterFinderMT *source, const std::filesystem::path &fname) { + LOG(logDEBUG) << "ClusterFileSink: " + << "source: " << source->sink() + << ", file: " << fname.string(); m_source = source->sink(); m_thread = std::thread(&ClusterFileSink::process, this); m_file.open(fname, std::ios::binary); diff --git a/include/aare/ClusterFinder.hpp b/include/aare/ClusterFinder.hpp index ea11162..7a34722 100644 --- a/include/aare/ClusterFinder.hpp +++ b/include/aare/ClusterFinder.hpp @@ -38,7 +38,12 @@ class ClusterFinder { : m_image_size(image_size), m_nSigma(nSigma), c2(sqrt((ClusterSizeY + 1) / 2 * (ClusterSizeX + 1) / 2)), c3(sqrt(ClusterSizeX * ClusterSizeY)), - m_pedestal(image_size[0], image_size[1]), m_clusters(capacity) {}; + m_pedestal(image_size[0], image_size[1]), m_clusters(capacity) { + LOG(logDEBUG ) << "ClusterFinder: " + << "image_size: " << image_size[0] << "x" << image_size[1] + << ", nSigma: " << nSigma + << ", capacity: " << capacity; + } void push_pedestal_frame(NDView frame) { m_pedestal.push(frame); diff --git a/include/aare/ClusterFinderMT.hpp b/include/aare/ClusterFinderMT.hpp index 2dfb279..efc22d4 100644 --- a/include/aare/ClusterFinderMT.hpp +++ b/include/aare/ClusterFinderMT.hpp @@ -7,6 +7,7 @@ #include "aare/ClusterFinder.hpp" #include "aare/NDArray.hpp" +#include "aare/logger.hpp" #include "aare/ProducerConsumerQueue.hpp" namespace aare { @@ -123,6 +124,12 @@ class ClusterFinderMT { size_t capacity = 2000, size_t n_threads = 3) : m_n_threads(n_threads) { + LOG(logDEBUG1) << "ClusterFinderMT: " + << "image_size: " << image_size[0] << "x" << image_size[1] + << ", nSigma: " << nSigma + << ", capacity: " << capacity + << ", n_threads: " << n_threads; + for (size_t i = 0; i < n_threads; i++) { m_cluster_finders.push_back( std::make_unique< diff --git a/include/aare/logger.hpp b/include/aare/logger.hpp index 06e6feb..b93c091 100644 --- a/include/aare/logger.hpp +++ b/include/aare/logger.hpp @@ -37,7 +37,7 @@ enum TLogLevel { logINFOCYAN, logINFOMAGENTA, logINFO, - logDEBUG, + logDEBUG, // constructors, destructors etc. should still give too much output logDEBUG1, logDEBUG2, logDEBUG3, diff --git a/python/aare/ClusterFinder.py b/python/aare/ClusterFinder.py index 6e7c352..99bcc5f 100644 --- a/python/aare/ClusterFinder.py +++ b/python/aare/ClusterFinder.py @@ -1,22 +1,47 @@ -from ._aare import ClusterFinder_Cluster3x3i, ClusterFinder_Cluster2x2i, ClusterFinderMT_Cluster3x3i, ClusterFinderMT_Cluster2x2i, ClusterCollector_Cluster3x3i, ClusterCollector_Cluster2x2i +# from ._aare import ClusterFinder_Cluster3x3i, ClusterFinder_Cluster2x2i, ClusterFinderMT_Cluster3x3i, ClusterFinderMT_Cluster2x2i, ClusterCollector_Cluster3x3i, ClusterCollector_Cluster2x2i -from ._aare import ClusterFileSink_Cluster3x3i, ClusterFileSink_Cluster2x2i +# from ._aare import ClusterFileSink_Cluster3x3i, ClusterFileSink_Cluster2x2i + +from . import _aare import numpy as np +_supported_cluster_sizes = [(2,2), (3,3), (5,5), (7,7), (9,9),] + +# def _get_class() + +def _type_to_char(dtype): + if dtype == np.int32: + return 'i' + elif dtype == np.float32: + return 'f' + elif dtype == np.float64: + return 'd' + else: + raise ValueError(f"Unsupported dtype: {dtype}. Only np.int32, np.float32, and np.float64 are supported.") + +def _get_class(name, cluster_size, dtype): + """ + Helper function to get the class based on the name, cluster size, and dtype. + """ + try: + class_name = f"{name}_Cluster{cluster_size[0]}x{cluster_size[1]}{_type_to_char(dtype)}" + cls = getattr(_aare, class_name) + except AttributeError: + raise ValueError(f"Unsupported combination of type and cluster size: {dtype}/{cluster_size} when requesting {class_name}") + return cls + + + def ClusterFinder(image_size, cluster_size, 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++. """ - if dtype == np.int32 and cluster_size == (3,3): - return ClusterFinder_Cluster3x3i(image_size, n_sigma = n_sigma, capacity=capacity) - elif dtype == np.int32 and cluster_size == (2,2): - return ClusterFinder_Cluster2x2i(image_size, n_sigma = n_sigma, capacity=capacity) - else: - #TODO! add the other formats - raise ValueError(f"Unsupported dtype: {dtype}. Only np.int32 is supported.") + cls = _get_class("ClusterFinder", cluster_size, dtype) + return cls(image_size, n_sigma=n_sigma, capacity=capacity) + def ClusterFinderMT(image_size, cluster_size = (3,3), dtype=np.int32, n_sigma=5, capacity = 1024, n_threads = 3): @@ -25,15 +50,9 @@ def ClusterFinderMT(image_size, cluster_size = (3,3), dtype=np.int32, n_sigma=5, the templated ClusterFinderMT in C++. """ - if dtype == np.int32 and cluster_size == (3,3): - return ClusterFinderMT_Cluster3x3i(image_size, n_sigma = n_sigma, - capacity = capacity, n_threads = n_threads) - elif dtype == np.int32 and cluster_size == (2,2): - return ClusterFinderMT_Cluster2x2i(image_size, n_sigma = n_sigma, - capacity = capacity, n_threads = n_threads) - else: - #TODO! add the other formats - raise ValueError(f"Unsupported dtype: {dtype}. Only np.int32 is supported.") + cls = _get_class("ClusterFinderMT", cluster_size, dtype) + return cls(image_size, n_sigma=n_sigma, capacity=capacity, n_threads=n_threads) + def ClusterCollector(clusterfindermt, cluster_size = (3,3), dtype=np.int32): @@ -42,14 +61,8 @@ def ClusterCollector(clusterfindermt, cluster_size = (3,3), dtype=np.int32): the templated ClusterCollector in C++. """ - if dtype == np.int32 and cluster_size == (3,3): - return ClusterCollector_Cluster3x3i(clusterfindermt) - elif dtype == np.int32 and cluster_size == (2,2): - return ClusterCollector_Cluster2x2i(clusterfindermt) - - else: - #TODO! add the other formats - raise ValueError(f"Unsupported dtype: {dtype}. Only np.int32 is supported.") + cls = _get_class("ClusterCollector", cluster_size, dtype) + return cls(clusterfindermt) def ClusterFileSink(clusterfindermt, cluster_file, dtype=np.int32): """ @@ -57,11 +70,15 @@ def ClusterFileSink(clusterfindermt, cluster_file, dtype=np.int32): the templated ClusterCollector in C++. """ - if dtype == np.int32 and clusterfindermt.cluster_size == (3,3): - return ClusterFileSink_Cluster3x3i(clusterfindermt, cluster_file) - elif dtype == np.int32 and clusterfindermt.cluster_size == (2,2): - return ClusterFileSink_Cluster2x2i(clusterfindermt, cluster_file) - - else: - #TODO! add the other formats - raise ValueError(f"Unsupported dtype: {dtype}. Only np.int32 is supported.") \ No newline at end of file + cls = _get_class("ClusterFileSink", clusterfindermt.cluster_size, dtype) + return cls(clusterfindermt, cluster_file) + + +def ClusterFile(fname, cluster_size=(3,3), dtype=np.int32): + """ + Factory function to create a ClusterFile object. Provides a cleaner syntax for + the templated ClusterFile in C++. + """ + + cls = _get_class("ClusterFile", cluster_size, dtype) + return cls(fname) diff --git a/python/aare/__init__.py b/python/aare/__init__.py index d2bbe0a..0b95702 100644 --- a/python/aare/__init__.py +++ b/python/aare/__init__.py @@ -5,13 +5,12 @@ from . import _aare from ._aare import File, RawMasterFile, RawSubFile, JungfrauDataFile from ._aare import Pedestal_d, Pedestal_f, ClusterFinder_Cluster3x3i, VarClusterFinder from ._aare import DetectorType -from ._aare import ClusterFile_Cluster3x3i as ClusterFile from ._aare import hitmap from ._aare import ROI # from ._aare import ClusterFinderMT, ClusterCollector, ClusterFileSink, ClusterVector_i -from .ClusterFinder import ClusterFinder, ClusterCollector, ClusterFinderMT, ClusterFileSink +from .ClusterFinder import ClusterFinder, ClusterCollector, ClusterFinderMT, ClusterFileSink, ClusterFile from .ClusterVector import ClusterVector diff --git a/python/src/bind_Cluster.hpp b/python/src/bind_Cluster.hpp new file mode 100644 index 0000000..daf0946 --- /dev/null +++ b/python/src/bind_Cluster.hpp @@ -0,0 +1,64 @@ +#include "aare/Cluster.hpp" + +#include +#include +#include +#include +#include +#include +#include + +namespace py = pybind11; +using pd_type = double; + +using namespace aare; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" + +template +void define_Cluster(py::module &m, const std::string &typestr) { + auto class_name = fmt::format("Cluster{}", typestr); + + py::class_>( + m, class_name.c_str(), py::buffer_protocol()) + + .def(py::init([](uint8_t x, uint8_t y, py::array_t data) { + py::buffer_info buf_info = data.request(); + Cluster cluster; + cluster.x = x; + cluster.y = y; + auto r = data.template unchecked<1>(); // no bounds checks + for (py::ssize_t i = 0; i < data.size(); ++i) { + cluster.data[i] = r(i); + } + return cluster; + })); + + /* + //TODO! Review if to keep or not + .def_property( + "data", + [](ClusterType &c) -> py::array { + return py::array(py::buffer_info( + c.data, sizeof(Type), + py::format_descriptor::format(), // Type + // format + 1, // Number of dimensions + {static_cast(ClusterSizeX * + ClusterSizeY)}, // Shape (flattened) + {sizeof(Type)} // Stride (step size between elements) + )); + }, + [](ClusterType &c, py::array_t arr) { + py::buffer_info buf_info = arr.request(); + Type *ptr = static_cast(buf_info.ptr); + std::copy(ptr, ptr + ClusterSizeX * ClusterSizeY, + c.data); // TODO dont iterate over centers!!! + + }); + */ +} + +#pragma GCC diagnostic pop \ No newline at end of file diff --git a/python/src/bind_ClusterCollector.hpp b/python/src/bind_ClusterCollector.hpp new file mode 100644 index 0000000..4836e6e --- /dev/null +++ b/python/src/bind_ClusterCollector.hpp @@ -0,0 +1,46 @@ +#include "aare/ClusterCollector.hpp" +#include "aare/ClusterFileSink.hpp" +#include "aare/ClusterFinder.hpp" +#include "aare/ClusterFinderMT.hpp" +#include "aare/ClusterVector.hpp" +#include "aare/NDView.hpp" +#include "aare/Pedestal.hpp" +#include "np_helper.hpp" + +#include +#include +#include +#include +#include + +namespace py = pybind11; +using pd_type = double; + +using namespace aare; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" + + +template +void define_ClusterCollector(py::module &m, + const std::string &typestr) { + auto class_name = fmt::format("ClusterCollector_{}", typestr); + + using ClusterType = Cluster; + + py::class_>(m, class_name.c_str()) + .def(py::init *>()) + .def("stop", &ClusterCollector::stop) + .def( + "steal_clusters", + [](ClusterCollector &self) { + auto v = new std::vector>( + self.steal_clusters()); + return v; // TODO change!!! + }, + py::return_value_policy::take_ownership); +} + +#pragma GCC diagnostic pop \ No newline at end of file diff --git a/python/src/cluster_file.hpp b/python/src/bind_ClusterFile.hpp similarity index 98% rename from python/src/cluster_file.hpp rename to python/src/bind_ClusterFile.hpp index ac384b2..8ce5360 100644 --- a/python/src/cluster_file.hpp +++ b/python/src/bind_ClusterFile.hpp @@ -21,7 +21,7 @@ using namespace ::aare; template -void define_cluster_file_io_bindings(py::module &m, +void define_ClusterFile(py::module &m, const std::string &typestr) { using ClusterType = Cluster; diff --git a/python/src/bind_ClusterFileSink.hpp b/python/src/bind_ClusterFileSink.hpp new file mode 100644 index 0000000..9b3a74d --- /dev/null +++ b/python/src/bind_ClusterFileSink.hpp @@ -0,0 +1,44 @@ +#include "aare/ClusterCollector.hpp" +#include "aare/ClusterFileSink.hpp" +#include "aare/ClusterFinder.hpp" +#include "aare/ClusterFinderMT.hpp" +#include "aare/ClusterVector.hpp" +#include "aare/NDView.hpp" +#include "aare/Pedestal.hpp" +#include "np_helper.hpp" + +#include +#include +#include +#include +#include + +namespace py = pybind11; +using pd_type = double; + +using namespace aare; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" + + + + + + +template +void define_ClusterFileSink(py::module &m, + const std::string &typestr) { + auto class_name = fmt::format("ClusterFileSink_{}", typestr); + + using ClusterType = Cluster; + + py::class_>(m, class_name.c_str()) + .def(py::init *, + const std::filesystem::path &>()) + .def("stop", &ClusterFileSink::stop); +} + + +#pragma GCC diagnostic pop diff --git a/python/src/bind_ClusterFinder.hpp b/python/src/bind_ClusterFinder.hpp new file mode 100644 index 0000000..5f0fe8d --- /dev/null +++ b/python/src/bind_ClusterFinder.hpp @@ -0,0 +1,77 @@ +#include "aare/ClusterCollector.hpp" +#include "aare/ClusterFileSink.hpp" +#include "aare/ClusterFinder.hpp" +#include "aare/ClusterFinderMT.hpp" +#include "aare/ClusterVector.hpp" +#include "aare/NDView.hpp" +#include "aare/Pedestal.hpp" +#include "np_helper.hpp" + +#include +#include +#include +#include +#include + +namespace py = pybind11; +using pd_type = double; + +using namespace aare; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" + +template +void define_ClusterFinder(py::module &m, const std::string &typestr) { + auto class_name = fmt::format("ClusterFinder_{}", typestr); + + using ClusterType = Cluster; + + 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("push_pedestal_frame", + [](ClusterFinder &self, + py::array_t frame) { + auto view = make_view_2d(frame); + self.push_pedestal_frame(view); + }) + .def("clear_pedestal", + &ClusterFinder::clear_pedestal) + .def_property_readonly( + "pedestal", + [](ClusterFinder &self) { + auto pd = new NDArray{}; + *pd = self.pedestal(); + return return_image_data(pd); + }) + .def_property_readonly( + "noise", + [](ClusterFinder &self) { + auto arr = new NDArray{}; + *arr = self.noise(); + return return_image_data(arr); + }) + .def( + "steal_clusters", + [](ClusterFinder &self, + bool realloc_same_capacity) { + ClusterVector clusters = + self.steal_clusters(realloc_same_capacity); + return clusters; + }, + py::arg("realloc_same_capacity") = false) + .def( + "find_clusters", + [](ClusterFinder &self, + py::array_t frame, uint64_t frame_number) { + auto view = make_view_2d(frame); + self.find_clusters(view, frame_number); + return; + }, + py::arg(), py::arg("frame_number") = 0); +} + +#pragma GCC diagnostic pop \ No newline at end of file diff --git a/python/src/bind_ClusterFinderMT.hpp b/python/src/bind_ClusterFinderMT.hpp new file mode 100644 index 0000000..d1769db --- /dev/null +++ b/python/src/bind_ClusterFinderMT.hpp @@ -0,0 +1,81 @@ +#include "aare/ClusterCollector.hpp" +#include "aare/ClusterFileSink.hpp" +#include "aare/ClusterFinder.hpp" +#include "aare/ClusterFinderMT.hpp" +#include "aare/ClusterVector.hpp" +#include "aare/NDView.hpp" +#include "aare/Pedestal.hpp" +#include "np_helper.hpp" + +#include +#include +#include +#include +#include + +namespace py = pybind11; +using pd_type = double; + +using namespace aare; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" + +template +void define_ClusterFinderMT(py::module &m, + const std::string &typestr) { + auto class_name = fmt::format("ClusterFinderMT_{}", typestr); + + using ClusterType = Cluster; + + py::class_>( + m, class_name.c_str()) + .def(py::init, pd_type, size_t, size_t>(), + py::arg("image_size"), py::arg("n_sigma") = 5.0, + py::arg("capacity") = 2048, py::arg("n_threads") = 3) + .def("push_pedestal_frame", + [](ClusterFinderMT &self, + py::array_t frame) { + auto view = make_view_2d(frame); + self.push_pedestal_frame(view); + }) + .def( + "find_clusters", + [](ClusterFinderMT &self, + py::array_t frame, uint64_t frame_number) { + auto view = make_view_2d(frame); + self.find_clusters(view, frame_number); + return; + }, + py::arg(), py::arg("frame_number") = 0) + .def_property_readonly("cluster_size", [](ClusterFinderMT &self){ + return py::make_tuple(ClusterSizeX, ClusterSizeY); + }) + .def("clear_pedestal", + &ClusterFinderMT::clear_pedestal) + .def("sync", &ClusterFinderMT::sync) + .def("stop", &ClusterFinderMT::stop) + .def("start", &ClusterFinderMT::start) + .def( + "pedestal", + [](ClusterFinderMT &self, + size_t thread_index) { + auto pd = new NDArray{}; + *pd = self.pedestal(thread_index); + return return_image_data(pd); + }, + py::arg("thread_index") = 0) + .def( + "noise", + [](ClusterFinderMT &self, + size_t thread_index) { + auto arr = new NDArray{}; + *arr = self.noise(thread_index); + return return_image_data(arr); + }, + py::arg("thread_index") = 0); +} + + +#pragma GCC diagnostic pop \ No newline at end of file diff --git a/python/src/bind_ClusterVector.hpp b/python/src/bind_ClusterVector.hpp index db8c8a3..550db9a 100644 --- a/python/src/bind_ClusterVector.hpp +++ b/python/src/bind_ClusterVector.hpp @@ -101,4 +101,6 @@ void define_ClusterVector(py::module &m, const std::string &typestr) { return hitmap; }); -} \ No newline at end of file +} + +#pragma GCC diagnostic pop \ No newline at end of file diff --git a/python/src/cluster.hpp b/python/src/cluster.hpp deleted file mode 100644 index 58f137c..0000000 --- a/python/src/cluster.hpp +++ /dev/null @@ -1,211 +0,0 @@ -#include "aare/ClusterCollector.hpp" -#include "aare/ClusterFileSink.hpp" -#include "aare/ClusterFinder.hpp" -#include "aare/ClusterFinderMT.hpp" -#include "aare/ClusterVector.hpp" -#include "aare/NDView.hpp" -#include "aare/Pedestal.hpp" -#include "np_helper.hpp" - -#include -#include -#include -#include -#include - -namespace py = pybind11; -using pd_type = double; - -using namespace aare; - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" - -template -void define_cluster(py::module &m, const std::string &typestr) { - auto class_name = fmt::format("Cluster{}", typestr); - - py::class_>( - m, class_name.c_str(), py::buffer_protocol()) - - .def(py::init([](uint8_t x, uint8_t y, py::array_t data) { - py::buffer_info buf_info = data.request(); - Cluster cluster; - cluster.x = x; - cluster.y = y; - auto r = data.template unchecked<1>(); // no bounds checks - for (py::ssize_t i = 0; i < data.size(); ++i) { - cluster.data[i] = r(i); - } - return cluster; - })); - - /* - .def_property( - "data", - [](ClusterType &c) -> py::array { - return py::array(py::buffer_info( - c.data, sizeof(Type), - py::format_descriptor::format(), // Type - // format - 1, // Number of dimensions - {static_cast(ClusterSizeX * - ClusterSizeY)}, // Shape (flattened) - {sizeof(Type)} // Stride (step size between elements) - )); - }, - [](ClusterType &c, py::array_t arr) { - py::buffer_info buf_info = arr.request(); - Type *ptr = static_cast(buf_info.ptr); - std::copy(ptr, ptr + ClusterSizeX * ClusterSizeY, - c.data); // TODO dont iterate over centers!!! - - }); - */ -} - -template -void define_cluster_finder_mt_bindings(py::module &m, - const std::string &typestr) { - auto class_name = fmt::format("ClusterFinderMT_{}", typestr); - - using ClusterType = Cluster; - - py::class_>( - m, class_name.c_str()) - .def(py::init, pd_type, size_t, size_t>(), - py::arg("image_size"), py::arg("n_sigma") = 5.0, - py::arg("capacity") = 2048, py::arg("n_threads") = 3) - .def("push_pedestal_frame", - [](ClusterFinderMT &self, - py::array_t frame) { - auto view = make_view_2d(frame); - self.push_pedestal_frame(view); - }) - .def( - "find_clusters", - [](ClusterFinderMT &self, - py::array_t frame, uint64_t frame_number) { - auto view = make_view_2d(frame); - self.find_clusters(view, frame_number); - return; - }, - py::arg(), py::arg("frame_number") = 0) - .def_property_readonly("cluster_size", [](ClusterFinderMT &self){ - return py::make_tuple(ClusterSizeX, ClusterSizeY); - }) - .def("clear_pedestal", - &ClusterFinderMT::clear_pedestal) - .def("sync", &ClusterFinderMT::sync) - .def("stop", &ClusterFinderMT::stop) - .def("start", &ClusterFinderMT::start) - .def( - "pedestal", - [](ClusterFinderMT &self, - size_t thread_index) { - auto pd = new NDArray{}; - *pd = self.pedestal(thread_index); - return return_image_data(pd); - }, - py::arg("thread_index") = 0) - .def( - "noise", - [](ClusterFinderMT &self, - size_t thread_index) { - auto arr = new NDArray{}; - *arr = self.noise(thread_index); - return return_image_data(arr); - }, - py::arg("thread_index") = 0); -} - -template -void define_cluster_collector_bindings(py::module &m, - const std::string &typestr) { - auto class_name = fmt::format("ClusterCollector_{}", typestr); - - using ClusterType = Cluster; - - py::class_>(m, class_name.c_str()) - .def(py::init *>()) - .def("stop", &ClusterCollector::stop) - .def( - "steal_clusters", - [](ClusterCollector &self) { - auto v = new std::vector>( - self.steal_clusters()); - return v; // TODO change!!! - }, - py::return_value_policy::take_ownership); -} - -template -void define_cluster_file_sink_bindings(py::module &m, - const std::string &typestr) { - auto class_name = fmt::format("ClusterFileSink_{}", typestr); - - using ClusterType = Cluster; - - py::class_>(m, class_name.c_str()) - .def(py::init *, - const std::filesystem::path &>()) - .def("stop", &ClusterFileSink::stop); -} - -template -void define_cluster_finder_bindings(py::module &m, const std::string &typestr) { - auto class_name = fmt::format("ClusterFinder_{}", typestr); - - using ClusterType = Cluster; - - 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("push_pedestal_frame", - [](ClusterFinder &self, - py::array_t frame) { - auto view = make_view_2d(frame); - self.push_pedestal_frame(view); - }) - .def("clear_pedestal", - &ClusterFinder::clear_pedestal) - .def_property_readonly( - "pedestal", - [](ClusterFinder &self) { - auto pd = new NDArray{}; - *pd = self.pedestal(); - return return_image_data(pd); - }) - .def_property_readonly( - "noise", - [](ClusterFinder &self) { - auto arr = new NDArray{}; - *arr = self.noise(); - return return_image_data(arr); - }) - .def( - "steal_clusters", - [](ClusterFinder &self, - bool realloc_same_capacity) { - ClusterVector clusters = - self.steal_clusters(realloc_same_capacity); - return clusters; - }, - py::arg("realloc_same_capacity") = false) - .def( - "find_clusters", - [](ClusterFinder &self, - py::array_t frame, uint64_t frame_number) { - auto view = make_view_2d(frame); - self.find_clusters(view, frame_number); - return; - }, - py::arg(), py::arg("frame_number") = 0); -} -#pragma GCC diagnostic pop diff --git a/python/src/module.cpp b/python/src/module.cpp index 946a41b..681dd4b 100644 --- a/python/src/module.cpp +++ b/python/src/module.cpp @@ -1,11 +1,15 @@ // Files with bindings to the different classes //New style file naming +#include "bind_Cluster.hpp" +#include "bind_ClusterCollector.hpp" +#include "bind_ClusterFinder.hpp" +#include "bind_ClusterFinderMT.hpp" +#include "bind_ClusterFile.hpp" +#include "bind_ClusterFileSink.hpp" #include "bind_ClusterVector.hpp" //TODO! migrate the other names -#include "cluster.hpp" -#include "cluster_file.hpp" #include "ctb_raw_file.hpp" #include "file.hpp" #include "fit.hpp" @@ -24,6 +28,25 @@ namespace py = pybind11; +/* MACRO that defines Cluster bindings for a specific size and type + +T - Storage type of the cluster data (int, float, double) +N - Number of rows in the cluster +M - Number of columns in the cluster +U - Type of the pixel data (e.g., uint16_t) +TYPE_CODE - A character representing the type code (e.g., 'i' for int, 'd' for double, 'f' for float) + +*/ +#define DEFINE_CLUSTER_BINDINGS(T, N, M, U, TYPE_CODE) \ + define_ClusterFile(m, "Cluster" #N "x" #M #TYPE_CODE); \ + define_ClusterVector(m, "Cluster" #N "x" #M #TYPE_CODE); \ + define_ClusterFinder(m, "Cluster" #N "x" #M #TYPE_CODE); \ + define_ClusterFinderMT(m, "Cluster" #N "x" #M #TYPE_CODE); \ + define_ClusterFileSink(m, "Cluster" #N "x" #M #TYPE_CODE); \ + define_ClusterCollector(m, "Cluster" #N "x" #M #TYPE_CODE); \ + define_Cluster(m, #N "x" #M #TYPE_CODE); \ + register_calculate_eta(m); + PYBIND11_MODULE(_aare, m) { define_file_io_bindings(m); define_raw_file_io_bindings(m); @@ -38,59 +61,23 @@ PYBIND11_MODULE(_aare, m) { define_interpolation_bindings(m); define_jungfrau_data_file_io_bindings(m); - define_cluster_file_io_bindings(m, "Cluster3x3i"); - define_cluster_file_io_bindings(m, "Cluster3x3d"); - define_cluster_file_io_bindings(m, "Cluster3x3f"); - define_cluster_file_io_bindings(m, "Cluster2x2i"); - define_cluster_file_io_bindings(m, "Cluster2x2f"); - define_cluster_file_io_bindings(m, "Cluster2x2d"); + DEFINE_CLUSTER_BINDINGS(int, 3, 3, uint16_t, i); + DEFINE_CLUSTER_BINDINGS(double, 3, 3, uint16_t, d); + DEFINE_CLUSTER_BINDINGS(float, 3, 3, uint16_t, f); - define_ClusterVector(m, "Cluster3x3i"); - define_ClusterVector(m, "Cluster3x3d"); - define_ClusterVector(m, "Cluster3x3f"); - define_ClusterVector(m, "Cluster2x2i"); - define_ClusterVector(m, "Cluster2x2d"); - define_ClusterVector(m, "Cluster2x2f"); + DEFINE_CLUSTER_BINDINGS(int, 2, 2, uint16_t, i); + DEFINE_CLUSTER_BINDINGS(double, 2, 2, uint16_t, d); + DEFINE_CLUSTER_BINDINGS(float, 2, 2, uint16_t, f); - define_cluster_finder_bindings(m, "Cluster3x3i"); - define_cluster_finder_bindings(m, "Cluster3x3d"); - define_cluster_finder_bindings(m, "Cluster3x3f"); - define_cluster_finder_bindings(m, "Cluster2x2i"); - define_cluster_finder_bindings(m, "Cluster2x2d"); - define_cluster_finder_bindings(m, "Cluster2x2f"); + DEFINE_CLUSTER_BINDINGS(int, 5, 5, uint16_t, i); + DEFINE_CLUSTER_BINDINGS(double, 5, 5, uint16_t, d); + DEFINE_CLUSTER_BINDINGS(float, 5, 5, uint16_t, f); - define_cluster_finder_mt_bindings(m, "Cluster3x3i"); - define_cluster_finder_mt_bindings(m, "Cluster3x3d"); - define_cluster_finder_mt_bindings(m, "Cluster3x3f"); - define_cluster_finder_mt_bindings(m, "Cluster2x2i"); - define_cluster_finder_mt_bindings(m, "Cluster2x2d"); - define_cluster_finder_mt_bindings(m, "Cluster2x2f"); + DEFINE_CLUSTER_BINDINGS(int, 7, 7, uint16_t, i); + DEFINE_CLUSTER_BINDINGS(double, 7, 7, uint16_t, d); + DEFINE_CLUSTER_BINDINGS(float, 7, 7, uint16_t, f); - define_cluster_file_sink_bindings(m, "Cluster3x3i"); - define_cluster_file_sink_bindings(m, "Cluster3x3d"); - define_cluster_file_sink_bindings(m, "Cluster3x3f"); - define_cluster_file_sink_bindings(m, "Cluster2x2i"); - define_cluster_file_sink_bindings(m, "Cluster2x2d"); - define_cluster_file_sink_bindings(m, "Cluster2x2f"); - - define_cluster_collector_bindings(m, "Cluster3x3i"); - define_cluster_collector_bindings(m, "Cluster3x3f"); - define_cluster_collector_bindings(m, "Cluster3x3d"); - define_cluster_collector_bindings(m, "Cluster2x2i"); - define_cluster_collector_bindings(m, "Cluster2x2f"); - define_cluster_collector_bindings(m, "Cluster2x2d"); - - define_cluster(m, "3x3i"); - define_cluster(m, "3x3f"); - define_cluster(m, "3x3d"); - define_cluster(m, "2x2i"); - define_cluster(m, "2x2f"); - define_cluster(m, "2x2d"); - - register_calculate_eta(m); - register_calculate_eta(m); - register_calculate_eta(m); - register_calculate_eta(m); - register_calculate_eta(m); - register_calculate_eta(m); + DEFINE_CLUSTER_BINDINGS(int, 9, 9, uint16_t, i); + DEFINE_CLUSTER_BINDINGS(double, 9, 9, uint16_t, d); + DEFINE_CLUSTER_BINDINGS(float, 9, 9, uint16_t, f); }