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