1use std::collections::HashMap;
8
9use std::sync::Arc;
10
11use pyo3::prelude::*;
12use pyo3::types::{
13 PyBytes,
14};
15
16use caraspace::prelude::*;
18use tof_dataclasses::database::{
19 Paddle,
20 TrackerStrip,
21 get_tofpaddles,
22 get_trackerstrips
23};
24use tof_dataclasses::packets::TofPacket;
25use tof_dataclasses::events::{
27 TofEvent,
28 TofEventSummary
29};
30use telemetry_dataclasses::packets::{
31 TelemetryPacket,
32 MergedEvent
33};
34
35use crate::dataclasses::{
36 PyTofPacket,
37 PyTofEvent,
38 PyTofEventSummary,
39};
40
41use crate::telemetry::{
42 PyTelemetryPacket,
43 PyMergedEvent,
44};
45
46use pyo3::exceptions::PyValueError;
47
48#[pyfunction]
55#[pyo3(name="parse_u8")]
56pub fn py_parse_u8<'_py>(stream: Bound<'_py, PyBytes>, start_pos : usize) -> (u8, usize) {
57 let bs : Vec<u8> = stream.extract().expect("Don't understand input!");
58 let mut pos = start_pos;
59 let value = parse_u8(&bs, &mut pos);
60 (value, pos)
61}
62
63#[pyfunction]
70#[pyo3(name="parse_u16")]
71pub fn py_parse_u16<'_py>(stream: Bound<'_py, PyBytes>, start_pos : usize) -> (u16, usize) {
72 let bs : Vec<u8> = stream.extract().expect("Don't understand input!");
73 let mut pos = start_pos;
74 let value = parse_u16(&bs, &mut pos);
75 (value, pos)
76}
77
78#[pyfunction]
85#[pyo3(name="parse_u32")]
86pub fn py_parse_u32<'_py>(stream: Bound<'_py, PyBytes>, start_pos : usize) -> (u32, usize) {
87 let bs : Vec<u8> = stream.extract().expect("Don't understand input!");
88 let mut pos = start_pos;
89 let value = parse_u32(&bs, &mut pos);
90 (value, pos)
91}
92
93#[pyfunction]
100#[pyo3(name="parse_u64")]
101pub fn py_parse_u64<'_py>(stream: Bound<'_py, PyBytes>, start_pos : usize) -> (u64, usize) {
102 let bs : Vec<u8> = stream.extract().expect("Don't understand input!");
103 let mut pos = start_pos;
104 let value = parse_u64(&bs, &mut pos);
105 (value, pos)
106}
107
108#[pyclass]
114#[pyo3(name="CRFrameObject")]
115#[derive(Clone, Debug)]
116pub struct PyCRFrameObject {
117 frame_object : CRFrameObject
118}
119
120#[pymethods]
121impl PyCRFrameObject {
122 #[new]
123 fn new() -> Self {
124 Self {
125 frame_object : CRFrameObject::new(),
126 }
127 }
128
129 fn __repr__(&self) -> PyResult<String> {
130 Ok(format!("<PyO3Wrapper: {}>", self.frame_object))
131 }
132}
133
134#[pyclass]
140#[pyo3(name="CRFrame")]
141#[derive(Clone, Debug)]
142pub struct PyCRFrame{
143 frame : CRFrame,
144 paddles : Arc<HashMap<u8, Paddle>>,
145 strips : Arc<HashMap<u32, TrackerStrip>>
146}
147
148#[pymethods]
159impl PyCRFrame {
160 #[new]
161 fn new() -> Self {
162 Self {
163 frame : CRFrame::new(),
164 paddles : Arc::new(HashMap::<u8, Paddle>::new()),
165 strips : Arc::new(HashMap::<u32, TrackerStrip>::new()),
166 }
167 }
168
169 pub fn delete(&self, name : &str) -> PyResult<PyCRFrame> {
181 match self.frame.delete(name) {
182 Ok(new_frame) => {
183 let mut new_pyframe = PyCRFrame::new();
184 new_pyframe.frame = new_frame;
185 new_pyframe.paddles = Arc::clone(&self.paddles);
186 new_pyframe.strips = Arc::clone(&self.strips);
187 Ok(new_pyframe)
188 }
189 Err(err) => {
190 return Err(PyValueError::new_err(err.to_string()));
191 }
192 }
193 }
194
195 fn put_telemetrypacket(&mut self, packet : PyTelemetryPacket, name : String) {
197 let packet = packet.packet;
198 self.frame.put(packet, name)
199 }
201
202 #[pyo3(signature = (packet, name = None))]
211 fn put_tofpacket(&mut self, packet : PyTofPacket, name : Option<String>) -> PyResult<()> {
212 let packet = packet.packet;
213 if let Some(p_name) = name {
214 self.frame.put(packet, p_name);
215 Ok(())
216 } else {
217 return Err(PyValueError::new_err("Currently this is not yet implemented. Please specify a name for the TofPacket to be registered within the frame's index!"));
218 }
219 }
220
221 fn get_telemetrypacket(&mut self, name : String) -> PyResult<PyTelemetryPacket> {
222 let mut py_packet = PyTelemetryPacket::new();
223 let packet = self.frame.get::<TelemetryPacket>(name).unwrap();
224 py_packet.packet = packet;
225 Ok(py_packet)
226 }
227
228 fn get_mergedevent(&mut self, name : String) -> PyResult<PyMergedEvent> {
229 let mut py_event = PyMergedEvent::new();
230 let packet = self.frame.get::<TelemetryPacket>(name).map_err(|_| pyo3::exceptions::PyValueError::new_err("Merged Event not found"))?;
231 match MergedEvent::from_bytestream(&packet.payload, &mut 0) {
232 Ok(mut event) => {
233 event.tof_event.set_paddles(&self.paddles);
234 event.tof_event.normalize_hit_times();
235 py_event.event = event;
236 py_event.event.header = packet.header.clone();
237 }
238 Err(err) => {
239 return Err(PyValueError::new_err(err.to_string()));
240 }
241 }
242 for h in &mut py_event.event.tracker_hitsv2 {
243 h.set_coordinates(&self.strips);
244 }
245 Ok(py_event)
246 }
247
248 fn get_tofevent(&mut self, name : String) -> PyResult<PyTofEvent> {
249 let mut py_event = PyTofEvent::new();
250 let packet = self.frame.get::<TofPacket>(name).unwrap();
252 let mut event = packet.unpack::<TofEvent>().unwrap();
253 event.set_paddles(&self.paddles);
254 py_event.event = event;
255 Ok(py_event)
256 }
257
258 fn get_tofeventsummary(&mut self, name : String) -> PyResult<PyTofEventSummary> {
259 let mut py_event = PyTofEventSummary::new();
260 let packet = self.frame.get::<TofPacket>(name).unwrap();
262 let mut event = packet.unpack::<TofEventSummary>().unwrap();
263 event.set_paddles(&self.paddles);
264 py_event.event = event;
265 Ok(py_event)
266 }
267
268 fn get_tofpacket(&mut self, name : String) -> PyResult<PyTofPacket> {
269 let mut py_packet = PyTofPacket::new();
270 let packet = self.frame.get::<TofPacket>(name).unwrap();
272 py_packet.packet = packet;
273 Ok(py_packet)
274 }
275 fn has(&self, name : &str) -> bool {
285 self.frame.has(name)
286 }
287
288 #[getter]
289 fn index(&self) -> HashMap<String, (u64, CRFrameObjectType)> {
290 self.frame.index.clone()
291 }
292
293 fn __repr__(&self) -> PyResult<String> {
294 Ok(format!("<PyO3Wrapper: {}>", self.frame))
295 }
296}
297
298#[pyclass]
310#[pyo3(name="CRReader")]
311pub struct PyCRReader {
312 reader : CRReader,
313 paddles : Arc<HashMap<u8,Paddle>>,
314 strips : Arc<HashMap<u32, TrackerStrip>>
315}
316
317#[pymethods]
318impl PyCRReader {
319 #[new]
320 fn new(filename_or_directory : &Bound<'_,PyAny>) -> PyResult<Self> {
321 let mut string_value = String::from("foo");
322 if let Ok(s) = filename_or_directory.extract::<String>() {
323 string_value = s;
324 } if let Ok(fspath_method) = filename_or_directory.getattr("__fspath__") {
326 if let Ok(fspath_result) = fspath_method.call0() {
327 if let Ok(py_string) = fspath_result.extract::<String>() {
328 string_value = py_string;
329 }
330 }
331 }
332
333 let mut paddles = HashMap::<u8, Paddle>::new();
340 let mut strips = HashMap::<u32, TrackerStrip>::new();
341 match get_tofpaddles() {
342 Ok(pdls) => {
343 paddles = pdls;
344 }
345 Err(_err) => {
346 }
349 }
350 match get_trackerstrips() {
351 Ok(_strips) => {
352 strips = _strips;
353 }
354 Err(_err) => {
355 }
358 }
359 Ok(Self {
360 reader : CRReader::new(string_value)?,
361 paddles : Arc::new(paddles),
362 strips : Arc::new(strips),
363 })
364 }
365
366 #[getter]
369 fn get_current_filename(&self) -> Option<String> {
370 self.reader.get_current_filename()
371 }
372
373 fn rewind(&mut self) -> PyResult<()> {
377 match self.reader.rewind() {
378 Err(err) => {
379 return Err(PyValueError::new_err(err.to_string()));
380 }
381 Ok(_) => Ok(())
382 }
383 }
384
385 fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
386 slf
387 }
388
389 fn __next__(mut slf: PyRefMut<'_, Self>) -> Option<PyCRFrame> {
390 match slf.reader.next() {
391 Some(frame) => {
392 let mut pyframe = PyCRFrame::new();
393 pyframe.frame = frame;
394 pyframe.paddles = Arc::clone(&slf.paddles);
397 pyframe.strips = Arc::clone(&slf.strips);
398 return Some(pyframe)
399 }
400 None => {
401 return None;
402 }
403 }
404 }
405
406 fn count_frames(&mut self) -> usize {
410 self.reader.get_n_frames()
411 }
412
413 #[getter]
414 fn get_first_frame(&mut self) -> Option<PyCRFrame> {
415 match self.reader.first_frame() {
416 Some(frame) => {
417 let mut pyframe = PyCRFrame::new();
418 pyframe.frame = frame;
419 return Some(pyframe);
420 }
421 None => {
422 return None;
423 }
424 }
425 }
426
427 #[getter]
428 fn get_last_frame(&mut self) -> Option<PyCRFrame> {
429 match self.reader.last_frame() {
430 Some(frame) => {
431 let mut pyframe = PyCRFrame::new();
432 pyframe.frame = frame;
433 return Some(pyframe);
434 }
435 None => {
436 return None;
437 }
438 }
439 }
440
441 fn __repr__(&self) -> PyResult<String> {
442 Ok(format!("<PyO3Wrapper: {}>", self.reader))
443 }
444}
445
446#[pyclass]
447#[pyo3(name="CRWriter")]
448pub struct PyCRWriter {
449 writer : CRWriter
450}
451
452#[pymethods]
453impl PyCRWriter {
454 #[new]
455 #[pyo3(signature = (filename, run_id, subrun_id = None, timestamp = None))]
456 fn new(filename : String, run_id : u32, subrun_id : Option<u64>, timestamp : Option<String>) -> Self {
457 Self {
458 writer : CRWriter::new(filename, run_id, subrun_id, timestamp ),
459 }
460 }
461
462 fn set_mbytes_per_file(&mut self, fsize : usize) {
463 self.writer.mbytes_per_file = fsize;
464 }
465
466 fn set_file_timestamp(&mut self, timestamp : String) {
467 self.writer.file_timestamp = Some(timestamp);
468 }
469
470 fn add_frame(&mut self, frame : PyCRFrame) {
471 self.writer.add_frame(&frame.frame);
472 }
473}
474
475