Line data Source code
1 : /**
2 : * @file trigger_primitive.cpp Python bindings for the trigger primitive formats
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 "trgdataformats/TriggerObjectOverlay.hpp"
10 :
11 : #include <pybind11/pybind11.h>
12 : #include <pybind11/stl.h>
13 : #include <cstring>
14 :
15 : namespace py = pybind11;
16 :
17 : // NOLINTBEGIN(build/unsigned)
18 :
19 : namespace dunedaq::trgdataformats::python {
20 :
21 : /*
22 : Doesn't work
23 : */
24 : struct TriggerActivityHolder {
25 :
26 :
27 0 : TriggerActivityHolder(void* ptr, size_t size) {
28 0 : m_size = size;
29 0 : m_data.reset(new uint8_t[m_size]);
30 0 : std::memcpy(m_data.get(), ptr, size);
31 0 : }
32 :
33 0 : TriggerActivity* ptr() { return reinterpret_cast<TriggerActivity*>(m_data.get()); }
34 :
35 : size_t m_size;
36 : std::unique_ptr<uint8_t[]> m_data;
37 :
38 : };
39 :
40 : void
41 0 : register_trigger_activity(py::module& m)
42 : {
43 :
44 :
45 0 : py::class_<TriggerActivityData> trigger_activity_data(m, "TriggerActivityData", py::buffer_protocol());
46 0 : trigger_activity_data
47 0 : .def(py::init())
48 0 : .def(py::init([](py::capsule capsule) {
49 0 : auto tp = *static_cast<TriggerActivityData*>(capsule.get_pointer());
50 0 : return tp;
51 : } ))
52 0 : .def(py::init([](py::bytes bytes){
53 0 : py::buffer_info info(py::buffer(bytes).request());
54 0 : auto tp = *static_cast<TriggerActivityData*>(info.ptr);
55 0 : return tp;
56 0 : }))
57 0 : .def_property_readonly_static("s_trigger_activity_version", [](py::object /*self*/) { return TriggerActivityData::s_trigger_activity_version; })
58 0 : .def_property_readonly_static("s_invalid_channel", [](py::object /*self*/) { return TriggerActivityData::s_invalid_channel; })
59 0 : .def_property_readonly("version", [](TriggerActivityData& self) -> uint16_t {return self.version;})
60 0 : .def_property_readonly("time_start", [](TriggerActivityData& self) -> uint64_t {return self.time_start;})
61 0 : .def_property_readonly("time_end", [](TriggerActivityData& self) -> uint64_t {return self.time_end;})
62 0 : .def_property_readonly("time_peak", [](TriggerActivityData& self) -> uint64_t {return self.time_peak;})
63 0 : .def_property_readonly("time_activity", [](TriggerActivityData& self) -> uint64_t {return self.time_activity;})
64 0 : .def_property_readonly("channel_start", [](TriggerActivityData& self) -> channel_t {return self.channel_start;})
65 0 : .def_property_readonly("channel_end", [](TriggerActivityData& self) -> channel_t {return self.channel_end;})
66 0 : .def_property_readonly("channel_peak", [](TriggerActivityData& self) -> channel_t {return self.channel_peak;})
67 0 : .def_property_readonly("adc_integral", [](TriggerActivityData& self) -> uint32_t {return self.adc_integral;})
68 0 : .def_property_readonly("adc_peak", [](TriggerActivityData& self) -> uint32_t {return self.adc_peak;})
69 0 : .def_property_readonly("detid", [](TriggerActivityData& self) -> uint16_t {return self.detid;})
70 0 : .def_property_readonly("type", [](TriggerActivityData& self) -> TriggerActivityData::Type {return self.type;})
71 0 : .def_property_readonly("algorithm", [](TriggerActivityData& self) -> TriggerActivityData::Algorithm {return self.algorithm;})
72 0 : .def_static("sizeof", [](){ return sizeof(TriggerActivityData); })
73 : ;
74 :
75 :
76 0 : py::enum_<TriggerActivityData::Type>(trigger_activity_data, "Type")
77 0 : .value("kUnknown", TriggerActivityData::Type::kUnknown)
78 0 : .value("kTPC", TriggerActivityData::Type::kTPC)
79 0 : .value("kPDS", TriggerActivityData::Type::kPDS);
80 :
81 0 : py::enum_<TriggerActivityData::Algorithm>(trigger_activity_data, "Algorithm")
82 0 : .value("kUnknown", TriggerActivityData::Algorithm::kUnknown)
83 0 : .value("kSupernova", TriggerActivityData::Algorithm::kSupernova)
84 0 : .value("kPrescale", TriggerActivityData::Algorithm::kPrescale)
85 0 : .value("kADCSimpleWindow", TriggerActivityData::Algorithm::kADCSimpleWindow)
86 0 : .value("kHorizontalMuon", TriggerActivityData::Algorithm::kHorizontalMuon)
87 0 : .value("kMichelElectron", TriggerActivityData::Algorithm::kMichelElectron)
88 0 : .value("kDBSCAN", TriggerActivityData::Algorithm::kDBSCAN)
89 0 : .value("kPlaneCoincidence", TriggerActivityData::Algorithm::kPlaneCoincidence)
90 0 : .value("kBundle", TriggerActivityData::Algorithm::kBundle)
91 0 : .value("kChannelDistance", TriggerActivityData::Algorithm::kChannelDistance)
92 0 : .value("kChannelAdjacency", TriggerActivityData::Algorithm::kChannelAdjacency)
93 0 : .value("kSWIFT", TriggerActivityData::Algorithm::kSWIFT)
94 0 : .value("kProtoDUNEBSMWindow", TriggerActivityData::Algorithm::kProtoDUNEBSMWindow);
95 :
96 0 : py::class_<TriggerActivity>(m, "TriggerActivityOverlay", py::buffer_protocol())
97 0 : .def(py::init())
98 0 : .def(py::init([](py::capsule capsule) {
99 0 : auto tp = *static_cast<TriggerActivity*>(capsule.get_pointer());
100 0 : return tp;
101 : } ))
102 0 : .def_property_readonly("data", [](TriggerActivity& self) -> TriggerActivityData& {return self.data;})
103 0 : .def("__len__", [](TriggerActivity& self){ return self.n_inputs; })
104 0 : .def("sizeof", [](TriggerActivity& self){ return sizeof(TriggerActivity)+self.n_inputs*sizeof(TriggerPrimitive); })
105 : ;
106 :
107 :
108 0 : py::class_<TriggerActivityHolder>(m, "TriggerActivity", py::buffer_protocol())
109 : // .def(py::init())
110 0 : .def(py::init([](py::capsule capsule) {
111 0 : auto ta_ptr = static_cast<TriggerActivity*>(capsule.get_pointer());
112 0 : TriggerActivityHolder tah(ta_ptr, sizeof(TriggerActivity)+ta_ptr->n_inputs*sizeof(TriggerPrimitive));
113 0 : return tah;
114 : }))
115 0 : .def(py::init([](py::bytes bytes){
116 0 : py::buffer_info info(py::buffer(bytes).request());
117 0 : TriggerActivityHolder tah(info.ptr, info.size);
118 :
119 0 : return tah;
120 0 : }))
121 :
122 0 : .def("get_bytes",
123 0 : [](TriggerActivityHolder& tah) -> py::bytes {
124 0 : return py::bytes(reinterpret_cast<char*>(tah.ptr()), tah.m_size);
125 0 : }, py::return_value_policy::reference_internal
126 : )
127 0 : .def_property_readonly("data", [](TriggerActivityHolder& self) -> TriggerActivityData& {return self.ptr()->data;})
128 0 : .def("n_inputs", [](TriggerActivityHolder& self){ return self.ptr()->n_inputs; })
129 0 : .def("__len__", [](TriggerActivityHolder& self){ return self.ptr()->n_inputs; })
130 0 : .def("__getitem__",
131 0 : [](TriggerActivityHolder &self, size_t i) -> const TriggerPrimitive& {
132 0 : if (i >= self.ptr()->n_inputs) {
133 0 : throw py::index_error();
134 : }
135 0 : return self.ptr()->inputs[i];
136 0 : }, py::return_value_policy::reference_internal)
137 0 : .def("sizeof", [](TriggerActivityHolder& self){ return self.m_size; })
138 :
139 : ;
140 0 : } // NOLINT function length, while long enough to trip the linter, is fine
141 :
142 : } // namespace dunedaq::trgdataformats::python
143 :
144 : static_assert(
145 : dunedaq::trgdataformats::TriggerActivityData::s_trigger_activity_version == 2,
146 : "Version of TriggerActivityData appears to have changed; as a developer please update the Python bindings in this file before updating this static_assert");
147 :
148 : // NOLINTEND(build/unsigned)
|