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