#include #include #include #include #include #include "aare/core/Frame.hpp" #include "aare/core/NDView.hpp" #include "aare/core/defs.hpp" #include "aare/file_io/ClusterFileV2.hpp" #include "aare/file_io/File.hpp" #include "aare/processing/ClusterFinder.hpp" #include "aare/processing/Pedestal.hpp" namespace py = pybind11; template void define_pedestal_push_bindings(py::class_> &p) { p.def("push", [](Pedestal &pedestal, py::array_t &np_array) { py::buffer_info info = np_array.request(); if (info.format != py::format_descriptor::format()) throw std::runtime_error( "Incompatible format: different formats! (Are you sure the arrays are of the same type?)"); if (info.ndim != 2) throw std::runtime_error("Incompatible dimension: expected a 2D array!"); std::array arr_shape; std::move(info.shape.begin(), info.shape.end(), arr_shape.begin()); NDView a(static_cast(info.ptr), arr_shape); pedestal.push(a); }); p.def("push", [](Pedestal &pedestal, const int row, const int col, const T val) { pedestal.push(row, col, val); }); } template void define_pedestal_bindings(py::module &m) { auto p = py::class_>(m, "Pedestal"); // TODO: add DType to Frame so that we can define def_buffer() // and we can know what type of values are stored in the frame p.def(py::init()) .def(py::init()) .def("set_freeze", &Pedestal::set_freeze) .def("mean", py::overload_cast<>(&Pedestal::mean)) .def("mean", [](Pedestal &pedestal, const uint32_t row, const uint32_t col) { return pedestal.mean(row, col); }) .def("variance", py::overload_cast<>(&Pedestal::variance)) .def("variance", [](Pedestal &pedestal, const uint32_t row, const uint32_t col) { return pedestal.variance(row, col); }) .def("standard_deviation", py::overload_cast<>(&Pedestal::standard_deviation)) .def("standard_deviation", [](Pedestal &pedestal, const int row, const int col) { return pedestal.standard_deviation(row, col); }) .def("clear", py::overload_cast<>(&Pedestal::clear)) .def("clear", py::overload_cast(&Pedestal::clear)) .def_property_readonly("rows", &Pedestal::rows) .def_property_readonly("cols", &Pedestal::cols) .def_property_readonly("n_samples", &Pedestal::n_samples) .def_property_readonly("index", &Pedestal::index) .def_property_readonly("sum", &Pedestal::get_sum) .def_property_readonly("sum2", &Pedestal::get_sum2); p.def("push", [](Pedestal &pedestal, Frame &f) { if (f.bitdepth() == 8) { pedestal.template push(f); } else if (f.bitdepth() == 16) { pedestal.template push(f); } else if (f.bitdepth() == 32) { pedestal.template push(f); } else if (f.bitdepth() == 64) { pedestal.template push(f); } else { throw std::runtime_error("Unsupported bitdepth"); } }); define_pedestal_push_bindings(p); define_pedestal_push_bindings(p); define_pedestal_push_bindings(p); define_pedestal_push_bindings(p); define_pedestal_push_bindings(p); define_pedestal_push_bindings(p); define_pedestal_push_bindings(p); define_pedestal_push_bindings(p); define_pedestal_push_bindings(p); define_pedestal_push_bindings(p); } template void define_cluster_finder_template_bindings(py::class_ &cf) { cf.def("find_clusters_without_threshold", py::overload_cast, Pedestal &, bool>( &ClusterFinder::find_clusters_without_threshold)); cf.def("find_clusters_with_threshold", py::overload_cast, Pedestal &>( &ClusterFinder::find_clusters_with_threshold)); cf.def("find_clusters_without_threshold", [](ClusterFinder &self, py::array_t &np_array, Pedestal &pedestal, bool late_update) { py::buffer_info info = np_array.request(); if (info.format != Dtype(typeid(VIEW_TYPE)).numpy_descr()) throw std::runtime_error( "Incompatible format: different formats! (Are you sure the arrays are of the same type?)"); if (info.ndim != 2) throw std::runtime_error("Incompatible dimension: expected a 2D array!"); std::array arr_shape; std::copy(info.shape.begin(), info.shape.end(), arr_shape.begin()); NDView a(static_cast(info.ptr), arr_shape); return self.find_clusters_without_threshold(a, pedestal, late_update); }); cf.def("find_clusters_with_threshold", [](ClusterFinder &self, py::array_t &np_array, Pedestal &pedestal) { py::buffer_info info = np_array.request(); if (info.format != py::format_descriptor::format()) throw std::runtime_error( "Incompatible format: different formats! (Are you sure the arrays are of the same type?)"); if (info.ndim != 2) throw std::runtime_error("Incompatible dimension: expected a 2D array!"); std::array arr_shape; std::copy(info.shape.begin(), info.shape.end(), arr_shape.begin()); NDView a(static_cast(info.ptr), arr_shape); return self.find_clusters_with_threshold(a, pedestal); }); } void define_cluster_finder_bindings(py::module &m) { py::class_ cf(m, "ClusterFinder"); cf.def(py::init()); define_cluster_finder_template_bindings(cf); define_cluster_finder_template_bindings(cf); define_cluster_finder_template_bindings(cf); define_cluster_finder_template_bindings(cf); define_cluster_finder_template_bindings(cf); define_cluster_finder_template_bindings(cf); define_cluster_finder_template_bindings(cf); define_cluster_finder_template_bindings(cf); define_cluster_finder_template_bindings(cf); define_cluster_finder_template_bindings(cf); } void define_processing_bindings(py::module &m) { define_pedestal_bindings(m); py::class_(m, "Cluster",py::buffer_protocol()) .def(py::init()) .def("size", &Cluster::size) .def("begin", &Cluster::begin) .def("end", &Cluster::end) .def_readwrite("x", &Cluster::x) .def_readwrite("y", &Cluster::y) .def_buffer([](Cluster &c) -> py::buffer_info { return py::buffer_info(c.data(), c.dt.bytes(), c.dt.format_descr(), 1, {c.size()}, {c.dt.bytes()}); }) .def("__repr__", [](const Cluster &a) { return ""; }); define_cluster_finder_bindings(m); }