Line data Source code
1 : /**
2 : * @file fragment.cpp
3 : *
4 : * This is part of the DUNE DAQ Software Suite, 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 "daqdataformats/FragmentHeader.hpp"
11 :
12 : #include <pybind11/pybind11.h>
13 : #include <pybind11/stl.h>
14 :
15 : namespace py = pybind11;
16 : using namespace pybind11::literals; // to bring in the `_a` literal
17 :
18 : namespace dunedaq::daqdataformats::python {
19 :
20 : void
21 0 : register_fragment(py::module& m)
22 : {
23 :
24 0 : py::class_<Fragment> py_fragment(m, "Fragment", py::buffer_protocol());
25 :
26 0 : py_fragment.def("get_header", &Fragment::get_header, py::return_value_policy::reference_internal)
27 0 : .def("get_storage_location", &Fragment::get_storage_location, py::return_value_policy::reference_internal)
28 0 : .def("get_trigger_number", &Fragment::get_trigger_number)
29 0 : .def("get_run_number", &Fragment::get_run_number)
30 0 : .def("get_trigger_timestamp", &Fragment::get_trigger_timestamp)
31 0 : .def("get_window_begin", &Fragment::get_window_begin)
32 0 : .def("get_window_end", &Fragment::get_window_end)
33 0 : .def("get_element_id", &Fragment::get_element_id)
34 0 : .def("get_detector_id", &Fragment::get_detector_id)
35 0 : .def("get_status_bits", [](Fragment& self) { return self.get_status_bits().to_ullong(); })
36 0 : .def("get_status_bit", &Fragment::get_status_bit)
37 0 : .def("get_fragment_type_code", &Fragment::get_fragment_type_code)
38 0 : .def("get_fragment_type", &Fragment::get_fragment_type)
39 0 : .def("get_sequence_number", &Fragment::get_sequence_number)
40 0 : .def("get_size", &Fragment::get_size)
41 0 : .def("get_data_size", &Fragment::get_data_size)
42 0 : .def(
43 : "get_data",
44 0 : [](Fragment& self, size_t offset) { return static_cast<void*>(static_cast<char*>(self.get_data()) + offset); }, // NOLINT
45 0 : "offset"_a = 0,
46 0 : py::return_value_policy::reference_internal)
47 0 : .def(
48 : "get_data_bytes",
49 0 : [](Fragment* self, size_t offset) -> py::bytes {
50 0 : if (offset > self->get_data_size()) {
51 0 : throw std::runtime_error("Fragment.get_data_bytes: offset exceeds fragment size.");
52 : }
53 0 : size_t bytes_size = self->get_data_size() - offset;
54 0 : return py::bytes(reinterpret_cast<char*>(self->get_data()) + offset, bytes_size); // NOLINT
55 : },
56 0 : "offset"_a = 0,
57 0 : py::return_value_policy::reference_internal);
58 :
59 0 : py::enum_<Fragment::BufferAdoptionMode>(py_fragment, "BufferAdoptionMode")
60 0 : .value("kReadOnlyMode", Fragment::BufferAdoptionMode::kReadOnlyMode)
61 0 : .value("kTakeOverBuffer", Fragment::BufferAdoptionMode::kTakeOverBuffer)
62 0 : .value("kCopyFromBuffer", Fragment::BufferAdoptionMode::kCopyFromBuffer)
63 0 : .export_values();
64 :
65 0 : py::class_<FragmentHeader>(m, "FragmentHeader")
66 0 : .def_property_readonly(
67 : "fragment_header_marker",
68 0 : [](const FragmentHeader& self) -> uint32_t { return self.fragment_header_marker; }) // NOLINT(build/unsigned)
69 0 : .def_property_readonly(
70 0 : "version", [](const FragmentHeader& self) -> uint32_t { return self.version; }) // NOLINT(build/unsigned)
71 0 : .def_property_readonly("size", [](const FragmentHeader& self) -> fragment_size_t { return self.size; })
72 0 : .def_property_readonly("trigger_number",
73 0 : [](const FragmentHeader& self) -> trigger_number_t { return self.trigger_number; })
74 0 : .def_property_readonly("trigger_timestamp",
75 0 : [](const FragmentHeader& self) -> timestamp_t { return self.trigger_timestamp; })
76 0 : .def_property_readonly("window_begin", [](const FragmentHeader& self) -> timestamp_t { return self.window_begin; })
77 0 : .def_property_readonly("window_end", [](const FragmentHeader& self) -> timestamp_t { return self.window_end; })
78 0 : .def_property_readonly("run_number", [](const FragmentHeader& self) -> run_number_t { return self.run_number; })
79 0 : .def_property_readonly(
80 0 : "status_bits", [](const FragmentHeader& self) -> uint32_t { return self.status_bits; }) // NOLINT(build/unsigned)
81 0 : .def_property_readonly("fragment_type",
82 0 : [](const FragmentHeader& self) -> fragment_type_t { return self.fragment_type; })
83 0 : .def_property_readonly("sequence_number",
84 0 : [](const FragmentHeader& self) -> sequence_number_t { return self.sequence_number; })
85 0 : .def_property_readonly(
86 0 : "detector_id", [](const FragmentHeader& self) -> uint16_t { return self.detector_id; }) // NOLINT(build/unsigned)
87 0 : .def_property_readonly("element_id", [](const FragmentHeader& self) -> SourceID { return self.element_id; })
88 :
89 0 : .def_static("sizeof", []() { return sizeof(FragmentHeader); });
90 :
91 0 : py::enum_<FragmentStatusBits>(m, "FragmentStatusBits")
92 0 : .value("kLatencyBufferEmpty", FragmentStatusBits::kLatencyBufferEmpty)
93 0 : .value("kIncomplete", FragmentStatusBits::kIncomplete)
94 0 : .value("kInvalidRequestWindow", FragmentStatusBits::kInvalidRequestWindow)
95 0 : .value("kRequestTimeout", FragmentStatusBits::kRequestTimeout)
96 0 : .value("kRequestWindowBeforeBuffer", FragmentStatusBits::kRequestWindowBeforeBuffer)
97 0 : .value("kRequestWindowAfterBuffer", FragmentStatusBits::kRequestWindowAfterBuffer)
98 0 : .value("kEmptyFragment", FragmentStatusBits::kEmptyFragment)
99 : // TODO, Alessandro Thea <thea@github.com> Oct-31-2021: Add unassigned
100 0 : .export_values();
101 :
102 0 : py::enum_<FragmentType>(m, "FragmentType")
103 0 : .value("kUnknown", FragmentType::kUnknown)
104 0 : .value("kProtoWIB", FragmentType::kProtoWIB)
105 0 : .value("kWIB", FragmentType::kWIB)
106 0 : .value("kDAPHNE", FragmentType::kDAPHNE)
107 0 : .value("kTDE_AMC", FragmentType::kTDE_AMC)
108 0 : .value("kFW_TriggerPrimitive", FragmentType::kFW_TriggerPrimitive)
109 0 : .value("kTriggerPrimitive", FragmentType::kTriggerPrimitive)
110 0 : .value("kTriggerActivity", FragmentType::kTriggerActivity)
111 0 : .value("kTriggerCandidate", FragmentType::kTriggerCandidate)
112 0 : .value("kHardwareSignal", FragmentType::kHardwareSignal)
113 0 : .value("kPACMAN", FragmentType::kPACMAN)
114 0 : .value("kWIBEth", FragmentType::kWIBEth)
115 0 : .value("kDAPHNEStream", FragmentType::kDAPHNEStream)
116 0 : .value("kCRT", FragmentType::kCRT)
117 0 : .value("kTDEEth", FragmentType::kTDEEth)
118 0 : .value("kCRTBern", FragmentType::kCRTBern)
119 0 : .value("kCRTGrenoble", FragmentType::kCRTGrenoble)
120 0 : .value("kDAPHNEEth", FragmentType::kDAPHNEEth)
121 0 : .value("kDAPHNEEthStream", FragmentType::kDAPHNEEthStream)
122 0 : .export_values();
123 :
124 0 : m.def("fragment_type_to_string", &fragment_type_to_string);
125 0 : m.def("string_to_fragment_type", &string_to_fragment_type);
126 0 : } // NOLINT(readability/fn_size)
127 :
128 : } // namespace dunedaq::daqdataformats::python
|