// SPDX-License-Identifier: MPL-2.0 #include "aare/CtbRawFile.hpp" #include "aare/File.hpp" #include "aare/Frame.hpp" #include "aare/RawFile.hpp" #include "aare/RawMasterFile.hpp" #include "aare/RawSubFile.hpp" #include "aare/decode.hpp" #include "aare/defs.hpp" // #include "aare/fClusterFileV2.hpp" #include "np_helper.hpp" #include #include #include #include #include #include #include #include namespace py = pybind11; using namespace ::aare; void define_ctb_raw_file_io_bindings(py::module &m) { m.def("adc_sar_05_06_07_08decode64to16", [](py::array_t input) { if (input.ndim() != 2) { throw std::runtime_error( "Only 2D arrays are supported at this moment"); } // Create a 2D output array with the same shape as the input std::vector shape{input.shape(0), input.shape(1) / static_cast(bits_per_byte)}; py::array_t output(shape); // Create a view of the input and output arrays NDView input_view( reinterpret_cast(input.mutable_data()), {output.shape(0), output.shape(1)}); NDView output_view(output.mutable_data(), {output.shape(0), output.shape(1)}); adc_sar_05_06_07_08decode64to16(input_view, output_view); return output; }); m.def("adc_sar_05_decode64to16", [](py::array_t input) { if (input.ndim() != 2) { throw std::runtime_error( "Only 2D arrays are supported at this moment"); } // Create a 2D output array with the same shape as the input std::vector shape{input.shape(0), input.shape(1) / static_cast(bits_per_byte)}; py::array_t output(shape); // Create a view of the input and output arrays NDView input_view( reinterpret_cast(input.mutable_data()), {output.shape(0), output.shape(1)}); NDView output_view(output.mutable_data(), {output.shape(0), output.shape(1)}); adc_sar_05_decode64to16(input_view, output_view); return output; }); m.def("adc_sar_04_decode64to16", [](py::array_t input) { if (input.ndim() != 2) { throw std::runtime_error( "Only 2D arrays are supported at this moment"); } // Create a 2D output array with the same shape as the input std::vector shape{input.shape(0), input.shape(1) / static_cast(bits_per_byte)}; py::array_t output(shape); // Create a view of the input and output arrays NDView input_view( reinterpret_cast(input.mutable_data()), {output.shape(0), output.shape(1)}); NDView output_view(output.mutable_data(), {output.shape(0), output.shape(1)}); adc_sar_04_decode64to16(input_view, output_view); return output; }); m.def("apply_custom_weights", [](py::array_t &input, py::array_t &weights) { // Create new array with same shape as the input array // (uninitialized values) py::buffer_info buf = input.request(); py::array_t output(buf.shape); // Use NDViews to call into the C++ library auto weights_view = make_view_1d(weights); NDView input_view(input.mutable_data(), {input.size()}); NDView output_view(output.mutable_data(), {output.size()}); apply_custom_weights(input_view, output_view, weights_view); return output; }); m.def("expand24to32bit", [](py::array_t &input, uint32_t offset) { aare::BitOffset bitoff(offset); py::buffer_info buf = input.request(); constexpr uint32_t bytes_per_channel = 3; // 24 bit py::array_t output(buf.size / bytes_per_channel); NDView input_view(input.mutable_data(), {input.size()}); NDView output_view(output.mutable_data(), {output.size()}); aare::expand24to32bit(input_view, output_view, bitoff); return output; }); m.def("expand4to8bit", [](py::array_t &input) { py::buffer_info buf = input.request(); py::array_t output(buf.size * 2); NDView input_view(input.mutable_data(), {input.size()}); NDView output_view(output.mutable_data(), {output.size()}); aare::expand4to8bit(input_view, output_view); return output; }); m.def("decode_my302", [](py::array_t &input, uint32_t offset) { // Physical layout of the chip constexpr size_t channels = 64; constexpr size_t counters = 3; constexpr size_t bytes_per_channel = 3; // 24 bit constexpr int n_outputs = 2; ssize_t expected_size = channels * counters * bytes_per_channel; // If whe have an offset we need one extra byte per output aare::BitOffset bitoff(offset); if (bitoff.value()) expected_size += n_outputs; if (input.size() != expected_size) { throw std::runtime_error(fmt::format( "{} Expected an input size of {} bytes. Called " "with input size of {}", LOCATION, expected_size, input.size())); } py::buffer_info buf = input.request(); py::array_t output(channels * counters); for (int i = 0; i != n_outputs; ++i) { auto step = input.size() / n_outputs; auto out_step = output.size() / n_outputs; NDView input_view(input.mutable_data() + step * i, {input.size() / n_outputs}); NDView output_view(output.mutable_data() + out_step * i, {output.size() / n_outputs}); aare::expand24to32bit(input_view, output_view, bitoff); } return output; }); py::class_(m, "CtbRawFile") .def(py::init()) .def("read_frame", [](CtbRawFile &self) { size_t image_size = self.image_size_in_bytes(); py::array image; std::vector shape; shape.reserve(2); shape.push_back(1); shape.push_back(image_size); py::array_t header(1); // always read bytes image = py::array_t(shape); self.read_into( reinterpret_cast(image.mutable_data()), header.mutable_data()); return py::make_tuple(header, image); }) .def("seek", &CtbRawFile::seek) .def("tell", &CtbRawFile::tell) .def("master", &CtbRawFile::master) .def_property_readonly("image_size_in_bytes", &CtbRawFile::image_size_in_bytes) .def_property_readonly("frames_in_file", &CtbRawFile::frames_in_file); }