From a13affa4d3a3ccb52c16b0259311d4433d7001f9 Mon Sep 17 00:00:00 2001 From: Mazzoleni Alice Francesca Date: Thu, 10 Apr 2025 09:13:58 +0200 Subject: [PATCH] changed template arguments added tests --- python/src/cluster.hpp | 116 +++++++++++++++-------------------- python/src/cluster_file.hpp | 5 ++ python/src/interpolation.hpp | 23 +++---- python/src/module.cpp | 55 +++++++++-------- python/tests/test_Cluster.py | 96 +++++++++++++++++++++++------ 5 files changed, 175 insertions(+), 120 deletions(-) diff --git a/python/src/cluster.hpp b/python/src/cluster.hpp index 30b80f0..f6d3636 100644 --- a/python/src/cluster.hpp +++ b/python/src/cluster.hpp @@ -23,10 +23,8 @@ template ; py::class_>( - m, class_name.c_str()) + 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(); @@ -37,83 +35,57 @@ void define_cluster(py::module &m, const std::string &typestr) { std::copy(ptr, ptr + ClusterSizeX * ClusterSizeY, cluster.data); // Copy array contents return cluster; - })) + })); - //.def(py::init<>()) - .def_readwrite("x", &ClusterType::x) - .def_readwrite("y", &ClusterType::y) - .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!!! - }); + /* + .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_vector(py::module &m, const std::string &typestr) { using ClusterType = - Cluster; + Cluster; auto class_name = fmt::format("ClusterVector_{}", typestr); - py::class_>(m, class_name.c_str(), - py::buffer_protocol()) + py::class_, void>>( + m, class_name.c_str(), + py::buffer_protocol()) .def(py::init()) // TODO change!!! - /* - .def("push_back", - [](ClusterVector &self, ClusterType &cl) { - // auto view = make_view_2d(data); - self.push_back(cl); - }) - */ - /* - .def( - "push_back", - [](ClusterVector &self, py::object obj) { - ClusterType &cl = py::cast(obj); - self.push_back(cl); - }, - py::arg("cluster")) - */ .def("push_back", [](ClusterVector &self, const ClusterType &cluster) { self.push_back(cluster); }) - //.def("push_back", &ClusterVector::push_back) //TODO // implement push_back .def_property_readonly("size", &ClusterVector::size) .def("item_size", &ClusterVector::item_size) .def_property_readonly("fmt", [typestr]() { return fmt_format; }) - /* - .def("sum", - [](ClusterVector &self) { - auto *vec = new std::vector(self.sum()); - return return_vector(vec); - }) - .def("sum_2x2", - [](ClusterVector &self) { - auto *vec = new std::vector(self.sum_2x2()); - return return_vector(vec); - }) - */ + .def_property_readonly("cluster_size_x", &ClusterVector::cluster_size_x) .def_property_readonly("cluster_size_y", @@ -135,11 +107,14 @@ void define_cluster_vector(py::module &m, const std::string &typestr) { }); } -template +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>(), @@ -185,11 +160,14 @@ void define_cluster_finder_mt_bindings(py::module &m, py::arg("thread_index") = 0); } -template +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) @@ -198,26 +176,32 @@ void define_cluster_collector_bindings(py::module &m, [](ClusterCollector &self) { auto v = new std::vector>( self.steal_clusters()); - return v; + return v; // TODO change!!! }, py::return_value_policy::take_ownership); } -template +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 +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"), @@ -248,9 +232,9 @@ void define_cluster_finder_bindings(py::module &m, const std::string &typestr) { "steal_clusters", [](ClusterFinder &self, bool realloc_same_capacity) { - auto v = new ClusterVector( - self.steal_clusters(realloc_same_capacity)); - return v; + ClusterVector clusters = + self.steal_clusters(realloc_same_capacity); + return clusters; }, py::arg("realloc_same_capacity") = false) .def( diff --git a/python/src/cluster_file.hpp b/python/src/cluster_file.hpp index b41cab8..7ece8e6 100644 --- a/python/src/cluster_file.hpp +++ b/python/src/cluster_file.hpp @@ -80,7 +80,12 @@ void define_cluster_file_io_bindings(py::module &m, } return v; }); +} +template +void register_calculate_eta(py::module &m) { + using ClusterType = Cluster; m.def("calculate_eta2", [](const aare::ClusterVector &clusters) { auto eta2 = new NDArray(calculate_eta2(clusters)); diff --git a/python/src/interpolation.hpp b/python/src/interpolation.hpp index 08ec98d..e667015 100644 --- a/python/src/interpolation.hpp +++ b/python/src/interpolation.hpp @@ -9,12 +9,13 @@ namespace py = pybind11; -template -void register_interpolate(py::class_ &interpolator, - const std::string &typestr) { - auto name = fmt::format("interpolate_{}", typestr); +template +void register_interpolate(py::class_ &interpolator) { - interpolator.def(name.c_str(), + using ClusterType = Cluster; + + interpolator.def("interpolate", [](aare::Interpolator &self, const ClusterVector &clusters) { auto photons = self.interpolate(clusters); @@ -50,12 +51,12 @@ void define_interpolation_bindings(py::module &m) { return return_image_data(ptr); }); - register_interpolate>(interpolator, "Cluster3x3i"); - register_interpolate>(interpolator, "Cluster3x3f"); - register_interpolate>(interpolator, "Cluster3x3d"); - register_interpolate>(interpolator, "Cluster2x2i"); - register_interpolate>(interpolator, "Cluster2x2f"); - register_interpolate>(interpolator, "Cluster2x2d"); + register_interpolate(interpolator); + register_interpolate(interpolator); + register_interpolate(interpolator); + register_interpolate(interpolator); + register_interpolate(interpolator); + register_interpolate(interpolator); // TODO! Evaluate without converting to double m.def( diff --git a/python/src/module.cpp b/python/src/module.cpp index 38d3681..bfc1bc1 100644 --- a/python/src/module.cpp +++ b/python/src/module.cpp @@ -43,33 +43,33 @@ PYBIND11_MODULE(_aare, m) { define_cluster_vector(m, "Cluster2x2d"); define_cluster_vector(m, "Cluster2x2f"); - 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_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_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_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_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_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_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"); @@ -77,4 +77,11 @@ PYBIND11_MODULE(_aare, m) { 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); } diff --git a/python/tests/test_Cluster.py b/python/tests/test_Cluster.py index bd2c482..3bb4828 100644 --- a/python/tests/test_Cluster.py +++ b/python/tests/test_Cluster.py @@ -1,12 +1,12 @@ import pytest import numpy as np -from _aare import ClusterVector_Cluster3x3i, Interpolator, Cluster3x3i, ClusterFinder_Cluster3x3i +import aare._aare as aare #import ClusterVector_Cluster3x3i, ClusterVector_Cluster2x2i, Interpolator, Cluster3x3i, ClusterFinder_Cluster3x3i, Cluster2x2i, ClusterFile_Cluster3x3i, Cluster3x3f, calculate_eta2 def test_ClusterVector(): """Test ClusterVector""" - clustervector = ClusterVector_Cluster3x3i() + clustervector = aare.ClusterVector_Cluster3x3i() assert clustervector.cluster_size_x == 3 assert clustervector.cluster_size_y == 3 assert clustervector.item_size() == 4+9*4 @@ -14,14 +14,16 @@ def test_ClusterVector(): assert clustervector.capacity == 1024 assert clustervector.size == 0 - cluster = Cluster3x3i(0,0,np.ones(9, dtype=np.int32)) + cluster = aare.Cluster3x3i(0,0,np.ones(9, dtype=np.int32)) clustervector.push_back(cluster) assert clustervector.size == 1 - #push_back - check size - + with pytest.raises(TypeError): # Or use the appropriate exception type + clustervector.push_back(aare.Cluster2x2i(0,0,np.ones(4, dtype=np.int32))) + with pytest.raises(TypeError): + clustervector.push_back(aare.Cluster3x3f(0,0,np.ones(9, dtype=np.float32))) def test_Interpolator(): """Test Interpolator""" @@ -31,31 +33,87 @@ def test_Interpolator(): ybins = np.linspace(0, 5, 30, dtype=np.float64) etacube = np.zeros(shape=[30, 30, 20], dtype=np.float64) - interpolator = Interpolator(etacube, xbins, ybins, ebins) + interpolator = aare.Interpolator(etacube, xbins, ybins, ebins) assert interpolator.get_ietax().shape == (30,30,20) assert interpolator.get_ietay().shape == (30,30,20) - clustervector = ClusterVector_Cluster3x3i() + clustervector = aare.ClusterVector_Cluster3x3i() - cluster = Cluster3x3i(0,0, np.ones(9, dtype=np.int32)) - #clustervector.push_back(cluster) - #num_clusters = 1; + cluster = aare.Cluster3x3i(0,0, np.ones(9, dtype=np.int32)) + clustervector.push_back(cluster) - #assert interpolator.interpolate_Cluster3x3i(clustervector).shape == (num_clusters, 3) + interpolated_photons = interpolator.interpolate(clustervector) + + assert interpolated_photons.size == 1 + + assert interpolated_photons[0]["x"] == -1 + assert interpolated_photons[0]["y"] == -1 + assert interpolated_photons[0]["energy"] == 4 #eta_sum = 4, dx, dy = -1,-1 m_ietax = 0, m_ietay = 0 + + clustervector = aare.ClusterVector_Cluster2x2i() + + cluster = aare.Cluster2x2i(0,0, np.ones(4, dtype=np.int32)) + clustervector.push_back(cluster) + + interpolated_photons = interpolator.interpolate(clustervector) + + assert interpolated_photons.size == 1 + + assert interpolated_photons[0]["x"] == 0 + assert interpolated_photons[0]["y"] == 0 + assert interpolated_photons[0]["energy"] == 4 + +@pytest.mark.files +def test_cluster_file(): + """Test ClusterFile""" + cluster_file = aare.ClusterFile_Cluster3x3i(test_data_path() / "clust/single_frame_97_clustrers.clust") + clustervector = cluster_file.read_clusters() #conversion does not work + + cluster_file.close() + + ###reading with wrong file + cluster_file = ClusterFile_Cluster2x2i(test_data_path() / "clust/single_frame_97_clustrers.clust") #TODO check behavior! + +def test_calculate_eta(): + """Calculate Eta""" + clusters = aare.ClusterVector_Cluster3x3i() + clusters.push_back(aare.Cluster3x3i(0,0, np.ones(9, dtype=np.int32))) + clusters.push_back(aare.Cluster3x3i(0,0, np.array([1,1,1,2,2,2,3,3,3]))) + + eta2 = aare.calculate_eta2(clusters) + + assert eta2.shape == (2,2) + assert eta2[0,0] == 0.5 + assert eta2[0,1] == 0.5 + assert eta2[1,0] == 0.5 + assert eta2[1,1] == 0.6 #1/5 + +def test_cluster_finder(): + """Test ClusterFinder""" + + clusterfinder = aare.ClusterFinder_Cluster3x3i([100,100]) + + #frame = np.random.rand(100,100) + frame = np.zeros(shape=[100,100]) + + clusterfinder.find_clusters(frame) + + clusters = clusterfinder.steal_clusters(False) #conversion does not work + + assert clusters.size == 0 -#def test_cluster_file(): +def test_cluster_collector(): + """Test ClusterCollector""" -#def test_cluster_finder(): - #"""Test ClusterFinder""" + clusterfinder = aare.ClusterFinderMT_Cluster3x3i([100,100]) #TODO: no idea what the data is in InputQueue not zero - #clusterfinder = ClusterFinder_Cluster3x3i([100,100]) + clustercollector = aare.ClusterCollector_Cluster3x3i(clusterfinder) - #clusterfinder.find_clusters() + cluster_vectors = clustercollector.steal_clusters() - #clusters = clusterfinder.steal_clusters() - - #print("cluster size: ", clusters.size()) + assert len(cluster_vectors) == 1 #single thread execution + assert cluster_vectors[0].size == 0 #