go_pybindings/
io.rs

1//! The following file is part of gaps-online-software and published 
2//! under the GPLv3 license
3//!
4//! This file contains the source for pybindings with pyO3 for the 
5//! i/o system to read Tof data files as well as telemetry files
6
7use std::collections::HashMap;
8use std::env;
9//use log::error;
10use tof_dataclasses::io as io_api;
11
12use pyo3::prelude::*;
13use pyo3::exceptions::PyIOError;
14//use pyo3::exceptions::PyValueError;
15
16use tof_dataclasses::packets::PacketType;
17use tof_dataclasses::database::{
18  Paddle,
19  connect_to_db
20};
21
22use crate::dataclasses::{
23  PyTofPacket,
24  PyTofEventSummary
25};
26
27/// Remove the waveforms from a .tof.gaps 
28/// file and replace TofEvents with
29/// TofEventSummary
30#[pyfunction]
31#[pyo3(name="summarize_toffile")]
32pub fn py_summarize_toffile(fname : String) {
33  io_api::summarize_toffile(fname);
34}
35
36///// New style, agnostic reader for events from 
37///// any source
38//#[pyclass]
39//#[pyo3(name="Adapter")]
40//pub struct PyAdapter {
41//  pub paddles  : HashMap<u8, Paddle>,
42//  pub tpreader : Option<PyTofPacketReader>
43//}
44//
45//#[pymethods]
46//impl PyAdapter {
47//
48//  /// Instanciate a new adapter. An adapter can connect to any type of (online) data
49//  /// file - .tof.gaps, .tofsum.gaps, telemetry (.bin), a network port or a directory with 
50//  /// these files
51//  #[new]
52//  #[pyo3(signature = (source, filter=PacketType::Unknown,start=0, nevents=0))]
53//  fn new<'py>(source : Bound<'py, PyAny>, filter : PacketType, start : usize, nevents : usize) -> PyResult<Self> {
54//    let reader  = PyTofPacketReader::new(source, filter, start, nevents).expect("Can not init reader!");
55//    let mut paddles = HashMap::<u8, Paddle>::new();
56//    let db_path = env::var("DATABASE_URL").unwrap_or_else(|_| "".to_string());
57//    match connect_to_db(db_path) {
58//      Err(err) => {
59//        println!("Database can not be found! Did you load the setup-env.sh shell?");
60//        return Err(PyIOError::new_err(err.to_string()));
61//      }
62//      Ok(mut conn) => {
63//        match Paddle::all(&mut conn) {
64//          None => {
65//            return Err(PyIOError::new_err("Unable to retrieve paddle information from DB!"));
66//          }
67//          Some(pdls) => {
68//            for p in pdls {
69//              paddles.insert(p.paddle_id as u8, p.clone());
70//            }
71//          }
72//        }
73//      }
74//    }
75//
76//    Ok(PyAdapter {
77//      paddles  : paddles,
78//      tpreader : Some(reader)
79//    })
80//  }  
81//  
82//  #[getter]
83//  fn packet_index(&mut self) -> PyResult<HashMap<PacketType, usize>> {
84//    if self.tpreader.is_some() {
85//      let idx = self.tpreader.get_packet_index()?;
86//      self.tpreader.rewind()?;
87//      Ok(idx)
88//    }
89//    Err(PyIOError::new_err("No reader is set! Can't return packet index!"));
90//  }
91//
92//  fn rewind(&mut self) {
93//    let _ = self.tpreader.rewind();
94//  }
95//
96//  fn __repr__(&self) -> PyResult<String> {
97//    if self.tpreader.is_some() {
98//      Ok(format!("<PyO3Wrapper: {}>", self.tpreader.unwrap())) 
99//    } else {
100//      Err(PyIOError::new_err("No reader is set! Can't return packet index!"));
101//    }
102//  }
103//  
104//  fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
105//    slf
106//  }
107//  
108//  pub fn __next__(mut slf: PyRefMut<'_, Self>) -> Option<PyTofPacket> {
109//    if slf.tpreader.is_some() {
110//      //match slf.tpreader.unwrap().reader.next() { 
111//      match <Option<PyTofPacketReader> as Clone>::clone(&slf.tpreader).unwrap().reader.next() {
112//        Some(tp) => {
113//          let mut pytp = PyTofPacket::new();
114//          pytp.set_tp(tp);
115//          return Some(pytp)
116//        }
117//        None => {
118//          return None;
119//        }
120//      }
121//    }
122//    None
123//  }
124//}
125
126#[pyclass]
127#[pyo3(name="TofPacketReader")]
128pub struct PyTofPacketReader {
129  pub reader          : io_api::TofPacketReader,
130  pub paddles         : HashMap<u8,Paddle>,
131  //pub with_paddleinfo : bool
132}
133
134#[pymethods]
135impl PyTofPacketReader {
136  
137  /// Create a new instance of a TofPacketReader. 
138  #[new]
139  #[pyo3(signature = (filename, filter=PacketType::Unknown,start=0, nevents=0))]
140  pub fn new<'py>(filename : Bound<'py, PyAny>, filter : PacketType, start : usize, nevents : usize) -> PyResult<Self> {
141    let input_str : String;
142    match filename.extract::<String>() {
143      Ok(_fname) => {
144        input_str = _fname;
145      }
146      Err(_) => {
147        match filename.extract::<std::path::PathBuf>() {
148          Ok(_fname) => {
149            input_str = _fname.to_str().expect("Unable to convert input to string!").to_owned();
150          }
151          Err(_) => {
152          return Err(pyo3::exceptions::PyTypeError::new_err(
153              "Expected str or pathlib.Path",));
154          }
155        }
156      }
157    }
158    let mut paddles = HashMap::<u8, Paddle>::new();
159    let db_path = env::var("DATABASE_URL").unwrap_or_else(|_| "".to_string());
160    match connect_to_db(db_path) {
161      Err(err) => {
162        println!("Database can not be found! Did you load the setup-env.sh shell?");
163        return Err(PyIOError::new_err(err.to_string()));
164      }
165      Ok(mut conn) => {
166        match Paddle::all(&mut conn) {
167          None => {
168            return Err(PyIOError::new_err("Unable to retrieve paddle information from DB!"));
169          }
170          Some(pdls) => {
171            for p in pdls {
172              paddles.insert(p.paddle_id as u8, p.clone());
173            }
174          }
175        }
176      }
177    }
178
179    let mut pyreader = Self {
180      reader          : io_api::TofPacketReader::new(input_str),
181      paddles         : paddles,
182      //with_paddleinfo : false
183    };
184    pyreader.reader.filter     = filter;
185    pyreader.reader.skip_ahead = start;
186    pyreader.reader.stop_after = nevents;
187    Ok(pyreader)
188  }
189 
190  fn add_paddleinfo(&self, event : &mut PyTofEventSummary) {
191    event.event.set_paddles(&self.paddles);
192  }
193
194  #[getter]
195  fn current_filename(&self) -> Option<String> {
196    self.reader.get_current_filename()
197  }
198
199  #[getter]
200  fn first(&mut self) -> Option<PyTofPacket> {
201    let mut ptp = PyTofPacket::new();
202    let tp = self.reader.first_packet()?;
203    ptp.packet = tp;
204    return Some(ptp);
205  }
206
207  #[getter]
208  fn last(&mut self) -> Option<PyTofPacket> {
209    let mut ptp = PyTofPacket::new();
210    let tp = self.reader.last_packet()?;
211    ptp.packet = tp;
212    return Some(ptp);
213  }
214  //#[getter]
215  //fn get_with_paddleinfo(&self) -> PyResult<u32> {
216  //  Ok(self.with_paddleinfo)
217  //}
218  //
219  //#[setter]
220  //fn set_with_paddleinfo(&mut self, pinfo : bool) -> PyResult<()> {
221  //  self.with_paddleinfo = pinfo;
222  //  Ok(())
223  //}
224
225  #[getter]
226  fn get_filenames(&self) -> Vec<String> {
227    self.reader.filenames.clone()
228  }
229
230  #[getter]
231  fn packet_index(&mut self) -> PyResult<HashMap<PacketType, usize>> {
232    let idx = self.reader.get_packet_index()?;
233    self.reader.rewind()?;
234    Ok(idx)
235  }
236
237  fn rewind(&mut self) {
238    let _ = self.reader.rewind();
239  }
240
241  pub fn __repr__(&self) -> PyResult<String> {
242    Ok(format!("<PyO3Wrapper: {}>", self
243            .reader)) 
244  }
245  
246  pub fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
247    slf
248  }
249  
250  pub fn __next__(mut slf: PyRefMut<'_, Self>) -> Option<PyTofPacket> {
251    match slf.reader.next() { 
252      Some(tp) => {
253        let mut pytp = PyTofPacket::new();
254        if tp.packet_type == PacketType::TofEventSummary {
255          //if tp.with_paddleinfo {
256          //
257          //}
258        }
259        pytp.set_tp(tp);
260        return Some(pytp)
261      }
262      None => {
263        return None;
264      }
265    }
266    //  slf.reader.next()
267  }
268}