#include "aare/calibration.hpp" #include #include #include #include #include #include namespace py = pybind11; template py::array_t pybind_apply_calibration( py::array_t data, py::array_t pedestal, py::array_t calibration, int n_threads = 4) { auto data_span = make_view_3d(data); // data is always 3D /* No pointer is passed, so NumPy will allocate the buffer */ auto result = py::array_t(data_span.shape()); auto res = make_view_3d(result); if (data.ndim() == 3 && pedestal.ndim() == 3 && calibration.ndim() == 3) { auto ped = make_view_3d(pedestal); auto cal = make_view_3d(calibration); aare::apply_calibration(res, data_span, ped, cal, n_threads); } else if (data.ndim() == 3 && pedestal.ndim() == 2 && calibration.ndim() == 2) { auto ped = make_view_2d(pedestal); auto cal = make_view_2d(calibration); aare::apply_calibration(res, data_span, ped, cal, n_threads); } else { throw std::runtime_error( "Invalid number of dimensions for data, pedestal or calibration"); } return result; } py::array_t pybind_count_switching_pixels( py::array_t data, ssize_t n_threads = 4) { auto data_span = make_view_3d(data); auto arr = new NDArray{}; *arr = aare::count_switching_pixels(data_span, n_threads); return return_image_data(arr); } template py::array_t pybind_calculate_pedestal( py::array_t data, ssize_t n_threads) { auto data_span = make_view_3d(data); auto arr = new NDArray{}; *arr = aare::calculate_pedestal(data_span, n_threads); return return_image_data(arr); } template py::array_t pybind_calculate_pedestal_g0( py::array_t data, ssize_t n_threads) { auto data_span = make_view_3d(data); auto arr = new NDArray{}; *arr = aare::calculate_pedestal(data_span, n_threads); return return_image_data(arr); } void bind_calibration(py::module &m) { m.def("apply_calibration", &pybind_apply_calibration, py::arg("raw_data").noconvert(), py::kw_only(), py::arg("pd").noconvert(), py::arg("cal").noconvert(), py::arg("n_threads") = 4); m.def("apply_calibration", &pybind_apply_calibration, py::arg("raw_data").noconvert(), py::kw_only(), py::arg("pd").noconvert(), py::arg("cal").noconvert(), py::arg("n_threads") = 4); m.def("count_switching_pixels", &pybind_count_switching_pixels, R"( Count the number of time each pixel switches to G1 or G2. Parameters ---------- raw_data : array_like 3D array of shape (frames, rows, cols) to count the switching pixels from. n_threads : int The number of threads to use for the calculation. )", py::arg("raw_data").noconvert(), py::kw_only(), py::arg("n_threads") = 4); m.def("calculate_pedestal", &pybind_calculate_pedestal, R"( Calculate the pedestal for all three gains and return the result as a 3D array of doubles. Parameters ---------- raw_data : array_like 3D array of shape (frames, rows, cols) to calculate the pedestal from. Needs to contain data for all three gains (G0, G1, G2). n_threads : int The number of threads to use for the calculation. )", py::arg("raw_data").noconvert(), py::arg("n_threads") = 4); m.def("calculate_pedestal_float", &pybind_calculate_pedestal, R"( Same as `calculate_pedestal` but returns a 3D array of floats. Parameters ---------- raw_data : array_like 3D array of shape (frames, rows, cols) to calculate the pedestal from. Needs to contain data for all three gains (G0, G1, G2). n_threads : int The number of threads to use for the calculation. )", py::arg("raw_data").noconvert(), py::arg("n_threads") = 4); m.def("calculate_pedestal_g0", &pybind_calculate_pedestal_g0, R"( Calculate the pedestal for G0 and return the result as a 2D array of doubles. Pixels in G1 and G2 are ignored. Parameters ---------- raw_data : array_like 3D array of shape (frames, rows, cols) to calculate the pedestal from. n_threads : int The number of threads to use for the calculation. )", py::arg("raw_data").noconvert(), py::arg("n_threads") = 4); m.def("calculate_pedestal_g0_float", &pybind_calculate_pedestal_g0, R"( Same as `calculate_pedestal_g0` but returns a 2D array of floats. Parameters ---------- raw_data : array_like 3D array of shape (frames, rows, cols) to calculate the pedestal from. n_threads : int The number of threads to use for the calculation. )", py::arg("raw_data").noconvert(), py::arg("n_threads") = 4); }