Line data Source code
1 : /**
2 : * @file WIBEthUnpacker.cc Fast C++ -> numpy WIBEth format unpacker
3 : *
4 : * This is part of the DUNE DAQ , copyright 2020.
5 : * Licensing/copyright details are in the COPYING file that you should have
6 : * received with this code.
7 : */
8 :
9 : #include "daqdataformats/Fragment.hpp"
10 : #include "fddetdataformats/WIBEthFrame.hpp"
11 :
12 : #include <cstdint>
13 : #include <pybind11/numpy.h>
14 : // #include <fmt/core.h>
15 : // #include <iostream>
16 :
17 : namespace py = pybind11;
18 : namespace dunedaq::rawdatautils::wibeth {
19 :
20 : /**
21 : * @brief Gets number of WIBEthFrames in a fragment
22 : */
23 : uint32_t
24 0 : get_n_frames(daqdataformats::Fragment const& frag)
25 : {
26 0 : return (frag.get_size() - sizeof(daqdataformats::FragmentHeader)) / sizeof(fddetdataformats::WIBEthFrame);
27 : }
28 :
29 : /**
30 : * @brief Unpacks data containing WIBEthFrames into a numpy array with the ADC
31 : * values and dimension (number of WIBEthFrames, 64)
32 : * Warning: It doesn't check that n_frames is a sensible value (can read out of bounds)
33 : */
34 : py::array_t<uint16_t>
35 0 : np_array_adc_data(void* data, uint32_t n_frames)
36 : {
37 :
38 0 : uint32_t n_ch = fddetdataformats::WIBEthFrame::s_num_channels;
39 0 : uint32_t n_smpl = fddetdataformats::WIBEthFrame::s_time_samples_per_frame;
40 :
41 0 : py::array_t<uint16_t> result(n_ch * n_smpl * n_frames);
42 :
43 0 : py::buffer_info buf_res = result.request();
44 :
45 0 : auto ptr_res = static_cast<uint16_t*>(buf_res.ptr);
46 :
47 0 : for (size_t i = 0; i < n_frames; ++i) {
48 :
49 0 : auto fr = reinterpret_cast<fddetdataformats::WIBEthFrame*>(static_cast<char*>(data) +
50 0 : i * sizeof(fddetdataformats::WIBEthFrame));
51 :
52 0 : for (size_t j = 0; j < n_smpl; ++j) {
53 0 : for (size_t k = 0; k < n_ch; ++k) {
54 0 : ptr_res[(n_smpl * n_ch) * i + n_ch * j + k] = fr->get_adc(k, j);
55 : }
56 : }
57 : }
58 0 : result.resize({ n_frames * n_smpl, n_ch });
59 :
60 0 : return result;
61 0 : }
62 :
63 : /**
64 : * @brief Unpacks data containing WIBEthFrames into a numpy array with the
65 : * timestamps with dimension (number of WIBEthFrames)
66 : * Warning: It doesn't check that n_frames is a sensible value (can read out of bounds)
67 : */
68 : py::array_t<uint64_t>
69 0 : np_array_timestamp_data(void* data, uint32_t n_frames)
70 : {
71 :
72 0 : uint32_t n_smpl = fddetdataformats::WIBEthFrame::s_time_samples_per_frame;
73 :
74 0 : py::array_t<uint64_t> result(n_smpl * n_frames);
75 :
76 0 : auto ptr = static_cast<uint64_t*>(result.request().ptr);
77 :
78 0 : for (size_t i = 0; i < n_frames; ++i) {
79 0 : auto fr = reinterpret_cast<fddetdataformats::WIBEthFrame*>(static_cast<char*>(data) +
80 0 : i * sizeof(fddetdataformats::WIBEthFrame));
81 0 : uint64_t ts_0 = fr->get_timestamp();
82 0 : for (size_t j = 0; j < n_smpl; ++j)
83 0 : ptr[i * n_smpl + j] = ts_0 + 32 * j;
84 : }
85 :
86 0 : return result;
87 0 : }
88 :
89 : /**
90 : * @brief Unpacks a Fragment containing WIBEthFrames into a numpy array with the
91 : * ADC values and dimension (number of WIBEthFrames in the Fragment, 64)
92 : */
93 : py::array_t<uint16_t>
94 0 : np_array_adc(daqdataformats::Fragment const& frag)
95 : {
96 0 : return np_array_adc_data(frag.get_data(), get_n_frames(frag));
97 : }
98 :
99 : /**
100 : * @brief Unpacks the timestamps in a Fragment containing WIBFrames into a numpy
101 : * array with dimension (number of WIBEthFrames in the Fragment)
102 : */
103 : py::array_t<uint64_t>
104 0 : np_array_timestamp(daqdataformats::Fragment const& frag)
105 : {
106 0 : return np_array_timestamp_data(frag.get_data(), get_n_frames(frag));
107 : }
108 :
109 : } // namespace dunedaq::rawdatautils::wibeth // NOLINT
|