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