gondola_core/database/
tof_paddle_temps.rs1use crate::prelude::*;
5use crate::database::schema;
6
7use diesel::prelude::*;
8use std::io::BufRead;
9
10#[cfg_attr(feature="pybindings", pyfunction)]
11pub fn create_tof_paddle_temp_table( db_path: &str, paddle_temps: Vec<TofPaddleTemp>) {
12 use schema::tof_db_tofpaddletemp::dsl::*;
13 let mut conn = SqliteConnection::establish(db_path).ok().unwrap();
14
15 let mut _query_result = diesel::sql_query("
16 CREATE TABLE IF NOT EXISTS tof_db_tofpaddletemp (
17 data_id INTEGER PRIMARY KEY AUTOINCREMENT,
18 paddle_id SMALLINT NOT NULL,
19 utc_timestamp BIGINT NOT NULL,
20 temp_a FLOAT NOT NULL,
21 temp_b FLOAT NOT NULL,
22 meta TEXT
23 )
24 ").execute(&mut conn);
25 match _query_result {
26 Ok(_) => {
27 println!("Created table successfully!");
28 }
29 Err(err) => {
30 println!("Error occured when creating tof_db_tofpaddletemp table! {err}");
31 }
32 }
33 _query_result = diesel::insert_into(tof_db_tofpaddletemp)
34 .values(&paddle_temps)
35 .execute(&mut conn);
36 match _query_result {
37 Ok(_) => {
38 println!("Entered data into db successfully!");
39 }
40 Err(err) => {
41 println!("Error occured when entering data in the db! {err}");
42 }
43 }
44}
45
46#[derive(Debug, PartialEq, Clone)]
47#[allow(non_snake_case)]
48#[cfg_attr(feature="pybindings", pyclass)]
49pub struct TofPaddleTempDataSeries {
50 pub temp_a : Vec<f32>,
51 pub temp_b : Vec<f32>,
52 pub utc_timestamps : Vec<u64>,
53 pub paddle_id : u8
54}
55
56impl TofPaddleTempDataSeries {
57 pub fn new() -> Self {
58 Self {
59 temp_a : Vec::<f32>::new(),
60 temp_b : Vec::<f32>::new(),
61 utc_timestamps : Vec::<u64>::new(),
62 paddle_id : 0
63 }
64 }
65
66 pub fn add(&mut self, pdl_t : &TofPaddleTemp) {
67 if pdl_t.paddle_id == self.paddle_id as i16 {
68 self.temp_a.push(pdl_t.temp_a);
69 self.temp_b.push(pdl_t.temp_b);
70 self.utc_timestamps.push(pdl_t.utc_timestamp as u64);
71 }
72 }
73
74 pub fn get_for_ts(&self, utc_timestamp : u64) -> (f32, f32) {
75 let mut result = (-273.0, -273.0);
76 let idx_opt = self.utc_timestamps.partition_point(|&t| t < utc_timestamp)
77 .checked_sub(1);
78 if let Some(idx) = idx_opt {
79 if self.temp_a.len() > idx as usize && self.temp_b.len() > idx {
80 result.0 = self.temp_a[idx];
81 result.1 = self.temp_b[idx];
82 }
83 }
84 result
85 }
86
87 pub fn sort(&mut self) {
88 let mut indices: Vec<usize> = (0..self.utc_timestamps.len()).collect();
89 indices.sort_unstable_by_key(|&i| self.utc_timestamps[i]);
90 let timestamps_sorted: Vec<u64> =
91 indices.iter().map(|&i| self.utc_timestamps[i]).collect();
92 let values_a_sorted: Vec<f32> =
93 indices.iter().map(|&i| self.temp_a[i]).collect();
94 let values_b_sorted: Vec<f32> =
95 indices.iter().map(|&i| self.temp_b[i]).collect();
96 self.utc_timestamps = timestamps_sorted;
97 self.temp_a = values_a_sorted;
98 self.temp_b = values_b_sorted;
99 }
101}
102
103impl fmt::Display for TofPaddleTempDataSeries {
104 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105 let mut repr = String::from("<TofPaddleTempDataSeries:");
106 repr += &(format!("\n Paddle ID : {}", self.paddle_id));
107 repr += &(format!("\n Values : {}", self.temp_a.len()));
108 repr += ">";
109 write!(f, "{}", repr)
110 }
111}
112
113#[derive(Debug,PartialEq, Clone, Queryable, Selectable, Insertable, serde::Serialize, serde::Deserialize)]
117#[diesel(table_name = schema::tof_db_tofpaddletemp)]
118#[diesel(primary_key(data_id))]
119#[allow(non_snake_case)]
120#[cfg_attr(feature="pybindings", pyclass)]
121pub struct TofPaddleTemp {
122 #[diesel(deserialize_as = i32)]
123 pub data_id : Option<i32>,
124 pub paddle_id : i16,
125 pub utc_timestamp : i64,
126 pub temp_a : f32,
127 pub temp_b : f32,
128 pub meta : Option<String>,
129}
130
131impl TofPaddleTemp {
132
133 pub fn new() -> Self {
134 Self {
135 data_id : None,
136 paddle_id : 0,
137 utc_timestamp : 0,
138 temp_a : 0.0,
139 temp_b : 0.0,
140 meta : None,
141 }
142 }
143
144 pub fn all() -> Option<Vec<Self>> {
151 use schema::tof_db_tofpaddletemp::dsl::*;
152 let mut conn = connect_to_db().ok()?;
153 match tof_db_tofpaddletemp.load::<Self>(&mut conn) {
154 Err(err) => {
155 error!("Unable to load TOF paddle temperature data from db! {err}");
156 return None;
157 }
158 Ok(tpts) => {
159 return Some(tpts);
160 }
161 }
162 }
163
164 pub fn all_data() -> Option<HashMap<u8,TofPaddleTempDataSeries>> {
170 use schema::tof_db_tofpaddletemp::dsl::*;
171 let mut conn = connect_to_db().ok()?;
172 let results = tof_db_tofpaddletemp
173 .load::<Self>(&mut conn);
175 let mut all_ds = HashMap::<u8, TofPaddleTempDataSeries>::new();
176 for k in 1..161u8 {
177 let mut new_series = TofPaddleTempDataSeries::new();
178 new_series.paddle_id = k;
179 all_ds.insert(k, new_series);
180 }
181
182 match results {
183 Err(err) => {
184 error!("Unable to load TOF paddle temperature data from db! {err}");
185 return None;
186 }
187 Ok(tpts) => {
188 for tp in tpts {
189 all_ds.get_mut(&(tp.paddle_id as u8)).unwrap().add(&tp);
190 }
192 }
193 }
194 for k in 1..161 {
195 all_ds.get_mut(&k).unwrap().sort();
196 }
197 return Some(all_ds);
199 }
200
201 }
214
215impl Default for TofPaddleTemp {
216 fn default() -> Self {
217 Self::new()
218 }
219}
220
221impl fmt::Display for TofPaddleTemp {
222 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
223 let mut repr = String::from("<TofPaddleTemp:");
224 repr += &(format!("\n Paddle ID : {}", self.paddle_id));
225 repr += &(format!("\n UTC Timstamp : {} [{}|]", self.utc_timestamp, get_utc_timestamp_from_unix(self.utc_timestamp as f64).unwrap_or(String::from("0"))));
226 repr += &(format!("\n Temp [C] : A {} // B {}", self.temp_a, self.temp_b));
227 if self.meta.is_some() {
228 repr += &(format!("\n meta info : {}", self.meta.clone().unwrap()));
229 }
230 repr += ">";
231 write!(f, "{}", repr)
232 }
233}
234
235#[cfg(feature="pybindings")]
236#[pymethods]
237impl TofPaddleTempDataSeries {
238 #[pyo3(name="get_for_ts")]
239 pub fn get_for_ts_py(&self, timestamp : u64) -> (f32, f32) {
240 self.get_for_ts(timestamp)
241 }
242
243 #[getter]
244 fn get_first_ts(&self) -> Option<&u64> {
245 self.utc_timestamps.first()
246 }
247
248 #[getter]
249 fn get_last_ts(&self) -> Option<&u64> {
250 self.utc_timestamps.last()
251 }
252}
253
254#[cfg(feature="pybindings")]
255pythonize!(TofPaddleTempDataSeries);
256
257#[cfg(feature="pybindings")]
258#[pymethods]
259impl TofPaddleTemp {
260
261 #[staticmethod]
262 #[pyo3(name="all")]
263 pub fn all_py() -> Option<Vec<Self>> {
264 Self::all()
265 }
266
267 #[staticmethod]
273 #[pyo3(name="all_data")]
274 fn all_data_py() -> Option<HashMap<u8,TofPaddleTempDataSeries>> {
275 Self::all_data()
276 }
277
278 #[getter]
279 fn get_utc_timestamp(&self) -> i64 {
280 self.utc_timestamp
281 }
282
283 #[setter]
284 fn set_utc_timestamp(&mut self, ts : i64) {
285 self.utc_timestamp = ts;
286 }
287
288 #[getter]
289 fn get_meta (&self) -> Option<String> {
290 self.meta.clone()
291 }
292
293 #[getter]
294 fn get_paddle_id(&self) -> i16 {
295 self.paddle_id
296 }
297
298 #[getter]
299 fn get_temp_a(&self) -> f32 {
300 self.temp_a
301 }
302
303 #[getter]
304 fn get_temp_b(&self) -> f32 {
305 self.temp_b
306 }
307
308 #[setter]
309 fn set_paddle_id(&mut self, pid : i16) {
310 self.paddle_id = pid;
311 }
312
313 #[setter]
314 fn set_temp_a(&mut self, t : f32) {
315 self.temp_a = t;
316 }
317
318 #[setter]
319 fn set_temp_b(&mut self, t : f32) {
320 self.temp_b = t;
321 }
322}
323
324#[cfg(feature="pybindings")]
325pythonize!(TofPaddleTemp);
326