1use std::fmt;
12use std::env;
13use std::collections::HashMap;
14
15use glob::glob;
16use regex::Regex;
17use chrono::{
18 DateTime,
19 Utc,
20};
21
22use diesel::prelude::*;
24mod schema;
25
26use schema::tof_db_rat::dsl::*;
27use schema::tof_db_dsicard::dsl::*;
28
29use crate::calibrations::RBCalibrations;
30use crate::DsiLtbRBMapping;
32pub use crate::RbChPidMapping;
33
34pub type DsiJChPidMapping = DsiLtbRBMapping;
36
37pub fn connect_to_db(database_url : String) -> Result<diesel::SqliteConnection, ConnectionError> {
39 SqliteConnection::establish(&database_url)
41}
42
43pub fn get_tofpaddles() -> Result<HashMap<u8,Paddle>, ConnectionError> {
45 let db_path = env::var("DATABASE_URL").unwrap_or_else(|_| "".to_string());
46 let mut conn = connect_to_db(db_path)?;
47 let mut paddles = HashMap::<u8, Paddle>::new();
48 match Paddle::all(&mut conn) {
49 None => {
50 error!("We can't find any paddles in the database!");
51 return Ok(paddles);
52 }
53 Some(pdls) => {
54 for p in pdls {
55 paddles.insert(p.paddle_id as u8, p.clone());
56 }
57 }
58 }
59 return Ok(paddles);
60}
61
62pub fn get_trackerstrips() -> Result<HashMap<u32,TrackerStrip>, ConnectionError> {
64 let db_path = env::var("DATABASE_URL").unwrap_or_else(|_| "".to_string());
65 let mut conn = connect_to_db(db_path)?;
66 let mut strips = HashMap::<u32, TrackerStrip>::new();
67 match TrackerStrip::all(&mut conn) {
68 None => {
69 error!("We can't find any tracker strips in the database!");
70 return Ok(strips);
71 }
72 Some(ts) => {
73 for s in ts {
74 strips.insert(s.get_stripid() as u32, s.clone());
75 }
76 }
77 }
78 return Ok(strips);
79}
80
81pub fn get_linkid_rbid_map(rbs : &Vec<ReadoutBoard>) -> HashMap<u8, u8>{
83 let mut mapping = HashMap::<u8, u8>::new();
84 for rb in rbs {
85 mapping.insert(rb.mtb_link_id, rb.rb_id);
86 }
87 mapping
88}
89
90pub fn get_rbid_linkid_map(rbs : &Vec<ReadoutBoard>) -> HashMap<u8, u8> {
92 let mut mapping = HashMap::<u8, u8>::new();
93 for rb in rbs {
94 mapping.insert(rb.rb_id, rb.mtb_link_id);
95 }
96 mapping
97}
98
99pub fn get_dsi_j_ch_pid_map(paddles : &Vec<Paddle>) -> DsiJChPidMapping {
100 let mut mapping = DsiJChPidMapping::new();
101 for dsi in 1..6 {
102 let mut jmap = HashMap::<u8, HashMap<u8, (u8, u8)>>::new();
103 for j in 1..6 {
104 let mut rbidch_map : HashMap<u8, (u8,u8)> = HashMap::new();
105 for ch in 1..17 {
106 let rbidch = (0,0);
107 rbidch_map.insert(ch,rbidch);
108 }
110 jmap.insert(j,rbidch_map);
111 }
112 mapping.insert(dsi,jmap);
113 }
114 for pdl in paddles {
115 let dsi = pdl.dsi as u8;
116 let j = pdl.j_ltb as u8;
117 let ch_a = pdl.ltb_chA as u8;
118 let ch_b = pdl.ltb_chB as u8;
119 let pid = pdl.paddle_id as u8;
120 let panel_id = pdl.panel_id as u8;
121 mapping.get_mut(&dsi).unwrap().get_mut(&j).unwrap().insert(ch_a,(pid, panel_id));
122 mapping.get_mut(&dsi).unwrap().get_mut(&j).unwrap().insert(ch_b,(pid, panel_id));
123 }
124 return mapping;
125}
126
127pub fn get_rb_ch_pid_map(paddles : &Vec<Paddle>) -> RbChPidMapping {
130 let mut mapping = RbChPidMapping::new();
131 for rbid in 1..51 {
132 let mut chmap = HashMap::<u8, u8>::new();
133 for ch in 1..9 {
134 chmap.insert(ch,0);
135 }
136 mapping.insert(rbid,chmap);
137 }
138 for pdl in paddles {
139 let rb_id = pdl.rb_id as u8;
140 let ch_a = pdl.rb_chA as u8;
141 let ch_b = pdl.rb_chB as u8;
142 let pid = pdl.paddle_id as u8;
143 *mapping.get_mut(&rb_id).unwrap().get_mut(&ch_a).unwrap() = pid;
145 *mapping.get_mut(&rb_id).unwrap().get_mut(&ch_b).unwrap() = pid;
146 }
147 mapping
148}
149
150pub fn get_rb_ch_pid_a_map(paddles : &Vec<Paddle>) -> RbChPidMapping {
154 let mut mapping = RbChPidMapping::new();
155 for rbid in 1..51 {
156 let mut chmap = HashMap::<u8, u8>::new();
157 for ch in 1..9 {
158 chmap.insert(ch,0);
159 }
160 mapping.insert(rbid,chmap);
161 }
162 for pdl in paddles {
163 let rb_id = pdl.rb_id as u8;
164 let ch_a = pdl.rb_chA as u8;
165 let pid = pdl.paddle_id as u8;
166 *mapping.get_mut(&rb_id).unwrap().get_mut(&ch_a).unwrap() = pid;
167 }
168 mapping
169}
170
171
172pub fn get_rb_ch_pid_b_map(paddles : &Vec<Paddle>) -> RbChPidMapping {
176 let mut mapping = RbChPidMapping::new();
177 for rbid in 1..51 {
178 let mut chmap = HashMap::<u8, u8>::new();
179 for ch in 1..9 {
180 chmap.insert(ch,0);
181 }
182 mapping.insert(rbid,chmap);
183 }
184 for pdl in paddles {
185 let rb_id = pdl.rb_id as u8;
186 let ch_b = pdl.rb_chB as u8;
187 let pid = pdl.paddle_id as u8;
188 *mapping.get_mut(&rb_id).unwrap().get_mut(&ch_b).unwrap() = pid;
189 }
190 mapping
191}
192
193#[derive(Debug, Clone, Queryable,Insertable, Selectable, serde::Serialize, serde::Deserialize)]
195#[diesel(table_name = schema::tof_db_run)]
196#[diesel(primary_key(run_id))]
197pub struct Run {
198 pub run_id : i64,
199 pub runtime_secs : Option<i64>,
200 pub calib_before : Option<bool>,
201 pub shifter : Option<i16>,
202 pub run_type : Option<i16>,
203 pub run_path : Option<String>,
204}
205
206impl Run {
207 pub fn new() -> Self {
208 Self {
209 run_id : 0,
210 runtime_secs : Some(0),
211 calib_before : Some(true),
212 shifter : Some(0),
213 run_type : Some(0),
214 run_path : Some(String::from("")),
215 }
216 }
217
218 pub fn get_last_run(conn: &mut SqliteConnection) -> Option<u32> {
219 use schema::tof_db_run::dsl::*;
220 match tof_db_run.load::<Run>(conn) {
221 Err(err) => {
222 error!("Unable to load DSICards from db! {err}");
223 return None;
224 }
225 Ok(_runs) => {
226 }
228 }
229 let _results = tof_db_run
230 .limit(1)
232 .load::<Run>(conn)
234 .expect("Error loading posts");
235 None
236 }
237}
238
239impl fmt::Display for Run {
240 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
241 let mut repr = String::from("<Run");
242 repr += &(format!("\n RunID : {}", self.run_id));
243 repr += &(format!("\n - auto cali : {}", self.calib_before.unwrap_or(false)));
244 repr += &(format!("\n runtime [sec] : {}", self.runtime_secs.unwrap_or(-1)));
245 repr += &(format!("\n shifter : {}", self.shifter.unwrap_or(-1)));
246 repr += &(format!("\n run_type : {}", self.run_type.unwrap_or(-1)));
247 repr += &(format!("\n run_path : {}", self.run_path.clone().unwrap_or(String::from(""))));
248 write!(f, "{}", repr)
249 }
250}
251
252#[derive(Debug,Queryable, Selectable, serde::Serialize, serde::Deserialize)]
278#[diesel(table_name = schema::tof_db_rat)]
279#[diesel(primary_key(rat_id))]
280pub struct RAT {
281 pub rat_id : i16,
282 pub pb_id : i16,
283 pub rb1_id : i16,
284 pub rb2_id : i16,
285 pub ltb_id : i16,
286 pub ltb_harting_cable_length : i16,
287}
288
289impl RAT {
290 pub fn new() -> Self {
291 Self {
292 rat_id : 0,
293 pb_id : 0,
294 rb1_id : 0,
295 rb2_id : 0,
296 ltb_id : 0,
297 ltb_harting_cable_length : 0,
298 }
299 }
300
301 pub fn where_rb2id(conn: &mut SqliteConnection, rb2id : u8) -> Option<Vec<RAT>> {
303 let mut result = Vec::<RAT>::new();
304 match RAT::all(conn) {
305 Some(rats) => {
306 for rat in rats {
307 if rat.rb2_id == rb2id as i16 {
308 result.push(rat);
309 }
310 }
311 return Some(result);
312 }
313 None => ()
314 }
315 Some(result)
316 }
317
318 pub fn where_rb1id(conn: &mut SqliteConnection, rb2id : u8) -> Option<Vec<RAT>> {
320 let mut result = Vec::<RAT>::new();
321 match RAT::all(conn) {
322 Some(rats) => {
323 for rat in rats {
324 if rat.rb1_id == rb2id as i16 {
325 result.push(rat);
326 }
327 }
328 return Some(result);
329 }
330 None => ()
331 }
332 Some(result)
333 }
334
335 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<RAT>> {
336 match tof_db_rat.load::<RAT>(conn) {
337 Err(err) => {
338 error!("Unable to load RATs from db! {err}");
339 return None;
340 }
341 Ok(rats) => {
342 return Some(rats);
343 }
344 }
345 }
346
347}
348
349impl fmt::Display for RAT {
350 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
351 let mut repr = String::from("<RAT");
352 repr += &(format!("\n ID : {}", self.rat_id));
353 repr += &(format!("\n PB : {} ", self.pb_id));
354 repr += &(format!("\n RB1 : {}", self.rb1_id));
355 repr += &(format!("\n RB2 : {}", self.rb2_id));
356 repr += &(format!("\n LTB : {}", self.ltb_id));
357 repr += &(format!("\n H. cable len [cm] : {}>", self.ltb_harting_cable_length));
358 write!(f, "{}", repr)
359 }
360}
361
362
363#[derive(Queryable, Selectable)]
367#[diesel(primary_key(dsi_id))]
368#[diesel(table_name = schema::tof_db_dsicard)]
369pub struct DSICard {
370 pub dsi_id : i16,
371 pub j1_rat_id : Option<i16>,
372 pub j2_rat_id : Option<i16>,
373 pub j3_rat_id : Option<i16>,
374 pub j4_rat_id : Option<i16>,
375 pub j5_rat_id : Option<i16>,
376}
377
378
379impl DSICard {
380 pub fn new() -> Self {
381 Self {
382 dsi_id : 0,
383 j1_rat_id : None,
384 j2_rat_id : None,
385 j3_rat_id : None,
386 j4_rat_id : None,
387 j5_rat_id : None,
388 }
389 }
390
391 pub fn has_rat(&self, r_id : u8) -> bool {
394 if let Some(rid) = self.j1_rat_id {
395 if rid as u8 == r_id {
396 return true;
397 }
398 }
399 if let Some(rid) = self.j2_rat_id {
400 if rid as u8 == r_id {
401 return true;
402 }
403 }
404 if let Some(rid) = self.j3_rat_id {
405 if rid as u8 == r_id {
406 return true;
407 }
408 }
409 if let Some(rid) = self.j4_rat_id {
410 if rid as u8 == r_id {
411 return true;
412 }
413 }
414 if let Some(rid) = self.j5_rat_id {
415 if rid as u8 == r_id {
416 return true;
417 }
418 }
419 return false;
420 }
421
422 pub fn get_j(&self, r_id : u8) -> Option<u8> {
425 if !self.has_rat(r_id) {
426 return None;
427 }
428 if let Some(rid) = self.j1_rat_id {
429 if rid as u8 == r_id {
430 let _j = self.j1_rat_id.unwrap() as u8;
431 return Some(_j);
432 }
433 }
434 if let Some(rid) = self.j2_rat_id {
435 if rid as u8 == r_id {
436 let _j = self.j2_rat_id.unwrap() as u8;
437 return Some(_j);
438 }
439 }
440 if let Some(rid) = self.j3_rat_id {
441 if rid as u8 == r_id {
442 let _j = self.j3_rat_id.unwrap() as u8;
443 return Some(_j);
444 }
445 }
446 if let Some(rid) = self.j4_rat_id {
447 if rid as u8 == r_id {
448 let _j = self.j4_rat_id.unwrap() as u8;
449 return Some(_j);
450 }
451 }
452 if let Some(rid) = self.j5_rat_id {
453 if rid as u8 == r_id {
454 let _j = self.j5_rat_id.unwrap() as u8;
455 return Some(_j);
456 }
457 }
458 None
459 }
460
461 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<DSICard>> {
462 match tof_db_dsicard.load::<DSICard>(conn) {
463 Err(err) => {
464 error!("Unable to load DSICards from db! {err}");
465 return None;
466 }
467 Ok(dsis) => {
468 return Some(dsis);
469 }
470 }
471 }
472}
473
474impl fmt::Display for DSICard {
475 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
476 let mut repr = String::from("<DSI Card:");
477 repr += &(format!("\n ID : {}", self.dsi_id));
478 repr += "\n -- -- -- --";
479 if let Some(_j) = self.j1_rat_id {
480 repr += &(format!("\n J1 RAT : {}",_j));
481 } else {
482 repr += "\n J1 RAT : Not connected";
483 }
484 if let Some(_j) = self.j2_rat_id {
485 repr += &(format!("\n J2 RAT : {}",_j));
486 } else {
487 repr += "\n J2 RAT : Not connected";
488 }
489 if let Some(_j) = self.j3_rat_id {
490 repr += &(format!("\n J3 RAT : {}",_j));
491 } else {
492 repr += "\n J3 RAT : Not connected";
493 }
494 if let Some(_j) = self.j4_rat_id {
495 repr += &(format!("\n J4 RAT : {}",_j));
496 } else {
497 repr += "\n J4 RAT : Not connected";
498 }
499 if let Some(_j) = self.j5_rat_id {
500 repr += &(format!("\n J5 RAT : {}>",_j));
501 } else {
502 repr += "\n J5 RAT : Not connected>";
503 }
504 write!(f, "{}", repr)
505 }
506}
507
508#[derive(Debug,PartialEq, Clone,Queryable, Selectable, serde::Serialize, serde::Deserialize)]
510#[diesel(table_name = schema::tof_db_trackerstrip)]
511#[diesel(primary_key(strip_id))]
512#[allow(non_snake_case)]
513pub struct TrackerStrip {
514 pub strip_id : i32,
515 pub layer : i32,
516 pub row : i32,
517 pub module : i32,
518 pub channel : i32,
519 pub global_pos_x_l0 : f32,
520 pub global_pos_y_l0 : f32,
521 pub global_pos_z_l0 : f32,
522 pub global_pos_x_det_l0 : f32,
523 pub global_pos_y_det_l0 : f32,
524 pub global_pos_z_det_l0 : f32,
525 pub principal_x : f32,
526 pub principal_y : f32,
527 pub principal_z : f32,
528 pub volume_id : i64,
529}
530
531impl TrackerStrip {
532 pub fn new() -> Self {
533 Self {
534 strip_id : 0,
535 layer : 0,
536 row : 0,
537 module : 0,
538 channel : 0,
539 global_pos_x_l0 : 0.0,
540 global_pos_y_l0 : 0.0,
541 global_pos_z_l0 : 0.0,
542 global_pos_x_det_l0 : 0.0,
543 global_pos_y_det_l0 : 0.0,
544 global_pos_z_det_l0 : 0.0,
545 principal_x : 0.0,
546 principal_y : 0.0,
547 principal_z : 0.0,
548 volume_id : 0,
549 }
550 }
551
552 pub fn get_stripid(&self) -> u32 {
553 self.channel as u32 + (self.module as u32)*100 + (self.row as u32)*10000 + (self.layer as u32)*10000
554 }
555
556 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<Self>> {
557 use schema::tof_db_trackerstrip::dsl::*;
558 match tof_db_trackerstrip.load::<Self>(conn) {
559 Err(err) => {
560 error!("Unable to load tracker strips from db! {err}");
561 return None;
562 }
563 Ok(pdls) => {
564 return Some(pdls);
565 }
566 }
567 }
568}
569
570impl fmt::Display for TrackerStrip {
571 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
572 let mut repr = String::from("<TrackerStrip:");
573 repr += &(format!("\n strip id : {}", self.strip_id));
574 repr += &(format!("\n vid : {}", self.volume_id));
575 repr += &(format!("\n layer : {}", self.layer));
576 repr += &(format!("\n row : {}", self.row));
577 repr += &(format!("\n module : {}", self.module));
578 repr += &(format!("\n channel : {}", self.channel));
579 repr += "\n strip center [mm]:";
580 repr += &(format!("\n \u{21B3} [{:.2}, {:.2}, {:.2}]", self.global_pos_x_l0, self.global_pos_y_l0, self.global_pos_z_l0));
581 repr += "\n detector (disk) center [mm]:";
582 repr += &(format!("\n \u{21B3} [{:.2}, {:.2}, {:.2}]", self.global_pos_x_det_l0, self.global_pos_y_det_l0, self.global_pos_z_det_l0));
583 repr += "\n strip principal direction:";
584 repr += &(format!("\n \u{21B3} [{:.2}, {:.2}, {:.2}]", self.principal_x, self.principal_y, self.principal_z));
585 write!(f, "{}", repr)
586 }
587}
588
589
590
591#[derive(Debug,PartialEq, Clone,Queryable, Selectable, serde::Serialize, serde::Deserialize)]
594#[diesel(table_name = schema::tof_db_paddle)]
595#[diesel(primary_key(paddle_id))]
596#[allow(non_snake_case)]
597pub struct Paddle {
598 pub paddle_id : i16,
599 pub volume_id : i64,
600 pub panel_id : i16,
601 pub mtb_link_id : i16,
602 pub rb_id : i16,
603 pub rb_chA : i16,
604 pub rb_chB : i16,
605 pub ltb_id : i16,
606 pub ltb_chA : i16,
607 pub ltb_chB : i16,
608 pub pb_id : i16,
609 pub pb_chA : i16,
610 pub pb_chB : i16,
611 pub cable_len : f32,
612 pub dsi : i16,
613 pub j_rb : i16,
614 pub j_ltb : i16,
615 pub height : f32,
616 pub width : f32,
617 pub length : f32,
618 pub normal_x : f32,
619 pub normal_y : f32,
620 pub normal_z : f32,
621 pub global_pos_x_l0 : f32,
622 pub global_pos_y_l0 : f32,
623 pub global_pos_z_l0 : f32,
624 pub global_pos_x_l0_A : f32,
625 pub global_pos_y_l0_A : f32,
626 pub global_pos_z_l0_A : f32,
627 pub global_pos_x_l0_B : f32,
628 pub global_pos_y_l0_B : f32,
629 pub global_pos_z_l0_B : f32,
630 pub coax_cable_time : f32,
631 pub harting_cable_time: f32,
632}
633
634impl Paddle {
635 pub fn new() -> Self {
636 Self {
637 paddle_id : 0,
638 volume_id : 0,
639 panel_id : 0,
640 mtb_link_id : 0,
641 rb_id : 0,
642 rb_chA : 0,
643 rb_chB : 0,
644 ltb_id : 0,
645 ltb_chA : 0,
646 ltb_chB : 0,
647 pb_id : 0,
648 pb_chA : 0,
649 pb_chB : 0,
650 cable_len : 0.0,
651 dsi : 0,
652 j_rb : 0,
653 j_ltb : 0,
654 height : 0.0,
655 width : 0.0,
656 length : 0.0,
657 normal_x : 0.0,
658 normal_y : 0.0,
659 normal_z : 0.0,
660 global_pos_x_l0 : 0.0,
661 global_pos_y_l0 : 0.0,
662 global_pos_z_l0 : 0.0,
663 global_pos_x_l0_A : 0.0,
664 global_pos_y_l0_A : 0.0,
665 global_pos_z_l0_A : 0.0,
666 global_pos_x_l0_B : 0.0,
667 global_pos_y_l0_B : 0.0,
668 global_pos_z_l0_B : 0.0,
669 coax_cable_time : 0.0,
670 harting_cable_time: 0.0
671 }
672 }
673
674 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<Paddle>> {
675 use schema::tof_db_paddle::dsl::*;
676 match tof_db_paddle.load::<Paddle>(conn) {
677 Err(err) => {
678 error!("Unable to load paddles from db! {err}");
679 return None;
680 }
681 Ok(pdls) => {
682 return Some(pdls);
683 }
684 }
685 }
686
687 pub fn principal(&self) -> (f32,f32,f32) {
690 let mut pr = (self.global_pos_x_l0_B - self.global_pos_x_l0_A,
691 self.global_pos_y_l0_B - self.global_pos_y_l0_A,
692 self.global_pos_z_l0_B - self.global_pos_z_l0_A);
693 let length = f32::sqrt(pr.0.powf(2.0) + pr.1.powf(2.0) + pr.2.powf(2.0));
694 pr = (pr.0/length, pr.1/length, pr.2/length);
695 return pr;
696 }
697
698}
699
700impl fmt::Display for Paddle {
701 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
702 let mut repr = String::from("<Paddle:");
703 repr += "\n** identifiers **";
704 repr += &(format!("\n pid : {}", self.paddle_id));
705 repr += &(format!("\n vid : {}", self.volume_id));
706 repr += &(format!("\n panel id : {}", self.panel_id));
707 repr += "\n ** connedtions **";
708 repr += &(format!("\n DSI/J/CH (LG) [A] : {} | {} | {:02}", self.dsi, self.j_ltb, self.ltb_chA));
709 repr += &(format!("\n DSI/J/CH (HG) [A] : {} | {} | {:02}", self.dsi, self.j_rb, self.rb_chA));
710 repr += &(format!("\n DSI/J/CH (LG) [B] : {} | {} | {:02}", self.dsi, self.j_ltb, self.ltb_chB));
711 repr += &(format!("\n DSI/J/CH (HG) [B] : {} | {} | {:02}", self.dsi, self.j_rb, self.rb_chB));
712 repr += &(format!("\n RB/CH [A] : {:02} | {}", self.rb_id, self.rb_chA));
713 repr += &(format!("\n RB/CH [B] : {:02} | {}", self.rb_id, self.rb_chB));
714 repr += &(format!("\n LTB/CH [A] : {:02} | {}", self.ltb_id, self.ltb_chA));
715 repr += &(format!("\n LTB/CH [B] : {:02} | {}", self.ltb_id, self.ltb_chB));
716 repr += &(format!("\n PB/CH [A] : {:02} | {}", self.pb_id, self.pb_chA));
717 repr += &(format!("\n PB/CH [B] : {:02} | {}", self.pb_id, self.pb_chB));
718 repr += &(format!("\n MTB Link ID : {:02}", self.mtb_link_id));
719 repr += "\n cable len [cm] :";
720 repr += &(format!("\n \u{21B3} {:.2}", self.cable_len));
721 repr += "\n (Harting -> RB)";
722 repr += "\n cable times [ns] (JAZ) :";
723 repr += &(format!("\n \u{21B3} {:.2} {:.2}", self.coax_cable_time, self.harting_cable_time));
724 repr += "\n ** Coordinates (L0) & dimensions **";
725 repr += "\n length, width, height [mm]";
726 repr += &(format!("\n \u{21B3} [{:.2}, {:.2}, {:.2}]", self.length, self.width, self.height));
727 repr += "\n center [mm]:";
728 repr += &(format!("\n \u{21B3} [{:.2}, {:.2}, {:.2}]", self.global_pos_x_l0, self.global_pos_y_l0, self.global_pos_z_l0));
729 repr += "\n normal vector:";
730 repr += &(format!("\n \u{21B3} [{:.2}, {:.2}, {:.2}]", self.normal_x, self.normal_y, self.normal_z));
731 repr += "\n A-side [mm]:";
732 repr += &(format!("\n \u{21B3} [{:.2}, {:.2}, {:.2}]>", self.global_pos_x_l0_A, self.global_pos_y_l0_A, self.global_pos_z_l0_A));
733 repr += "\n B-side [mm]:";
734 repr += &(format!("\n \u{21B3} [{:.2}, {:.2}, {:.2}]>", self.global_pos_x_l0_B, self.global_pos_y_l0_B, self.global_pos_z_l0_B));
735 write!(f, "{}", repr)
736 }
737}
738
739#[derive(Debug,PartialEq,Queryable, Selectable)]
743#[diesel(table_name = schema::tof_db_mtbchannel)]
744#[diesel(primary_key(mtb_ch))]
745#[allow(non_snake_case)]
746pub struct MTBChannel {
747 pub mtb_ch : i64,
748 pub dsi : Option<i16>,
749 pub j : Option<i16>,
750 pub ltb_id : Option<i16>,
751 pub ltb_ch : Option<i16>,
752 pub rb_id : Option<i16>,
753 pub rb_ch : Option<i16>,
754 pub mtb_link_id : Option<i16>,
755 pub paddle_id : Option<i16>,
756 pub paddle_isA : Option<bool>,
757 pub hg_ch : Option<i16>,
758 pub lg_ch : Option<i16>,
759}
760
761impl MTBChannel {
762
763 pub fn new() -> Self {
764 Self {
765 mtb_ch : -1,
766 dsi : None,
767 j : None,
768 ltb_id : None,
769 ltb_ch : None,
770 rb_id : None,
771 rb_ch : None,
772 mtb_link_id : None,
773 paddle_id : None,
774 paddle_isA : None,
775 hg_ch : None,
776 lg_ch : None,
777 }
778 }
779
780 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<MTBChannel>> {
781 use schema::tof_db_mtbchannel::dsl::*;
782 match tof_db_mtbchannel.load::<MTBChannel>(conn) {
783 Err(err) => {
784 error!("Unable to load RATs from db! {err}");
785 return None;
786 }
787 Ok(mtbch) => {
788 return Some(mtbch);
789 }
790 }
791 }
792}
793
794
795impl fmt::Display for MTBChannel {
796 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
797 let mut repr = String::from("<MTBChannel");
798 repr += &(format!("\n Channel ID : {}", self.mtb_ch));
799 repr += &(format!("\n DSI/J/ : {}/{}", self.dsi.unwrap_or(-1), self.j.unwrap_or(-1)));
800 repr += "\n LTB ID/CH => RB ID/CH";
801 repr += &(format!("\n |-> {}/{} => {}/{}", self.ltb_id.unwrap_or(-1), self.ltb_ch.unwrap_or(-1), self.rb_id.unwrap_or(-1), self.rb_ch.unwrap_or(-1)));
802 repr += &(format!("\n MTB Link ID [RB] : {}", self.mtb_link_id.unwrap_or(-1)));
803 repr += "\n LG CH => HG CH";
804 repr += &(format!("\n |-> {} => {}", self.lg_ch.unwrap_or(-1), self.hg_ch.unwrap_or(-1)));
805 repr += &(format!("\n Paddle Id: {}", self.paddle_id.unwrap_or(-1)));
806 let mut pend = "None";
807 if !self.paddle_isA.is_none() {
808 if self.paddle_isA.unwrap() {
809 pend = "A";
810 } else {
811 pend = "B";
812 }
813 }
814 repr += &(format!("\n Paddle End: {}>", pend));
815 write!(f, "{}", repr)
816 }
817}
818
819
820#[derive(Queryable, Selectable, Identifiable, Associations)]
841#[diesel(table_name = schema::tof_db_localtriggerboard)]
842#[diesel(primary_key(board_id))]
843#[diesel(belongs_to(Paddle, foreign_key=paddle1_id))]
844pub struct DBLocalTriggerBoard {
845 pub board_id : i16,
846 pub dsi : Option<i16>,
847 pub j : Option<i16>,
848 pub rat : Option<i16>,
849 pub ltb_id : Option<i16>,
850 pub cable_len : f32,
851 pub paddle1_id : Option<i16>,
852 pub paddle2_id : Option<i16>,
853 pub paddle3_id : Option<i16>,
854 pub paddle4_id : Option<i16>,
855 pub paddle5_id : Option<i16>,
856 pub paddle6_id : Option<i16>,
857 pub paddle7_id : Option<i16>,
858 pub paddle8_id : Option<i16>,
859}
860
861impl DBLocalTriggerBoard {
862
863 pub fn connected(&self) -> bool {
885 self.dsi != None && self.j != None
886 }
887
888 pub fn valid(&self) -> bool {
891 self.board_id > 0 &&
892 self.dsi .is_some() &&
893 self.j .is_some() &&
894 self.rat .is_some() &&
895 self.cable_len > 0.0 &&
899 self.paddle1_id.is_some() &&
900 self.paddle2_id.is_some() &&
901 self.paddle3_id.is_some() &&
902 self.paddle4_id.is_some() &&
903 self.paddle5_id.is_some() &&
904 self.paddle6_id.is_some() &&
905 self.paddle7_id.is_some() &&
906 self.paddle8_id.is_some()
907 }
908
909 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<DBLocalTriggerBoard>> {
910 use schema::tof_db_localtriggerboard::dsl::*;
911 match tof_db_localtriggerboard
912 .load::<DBLocalTriggerBoard>(conn) {
914 Err(err) => {
915 error!("Unable to load LocalTriggerBoards from db! {err}");
916 return None;
917 }
918 Ok(ltbs) => {
919 return Some(ltbs);
920 }
921 }
922 }
923}
924
925impl fmt::Display for DBLocalTriggerBoard {
926 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
927 let mut repr : String;
928 if !self.connected() {
929 repr = format!("<DBLocalTriggerBoard: ID {} - UNCONNECTED>", self.board_id);
930 } else {
931 repr = String::from("<DBLocalTriggerBoard:");
932 repr += &(format!("\n LTB ID : {}", self.board_id));
933 }
934 repr += &(format!("\n DSI/J : {}/{}", self.dsi.unwrap(), self.j.unwrap()));
935 repr += &(format!("\n RAT ID : {}", self.rat.unwrap()));
936 repr += "\n H. cable len (MTB connection):";
937 repr += &(format!("\n -> {}", self.cable_len));
938 repr += "\n -- -- -- -- -- -- -- -- -- -- -- -- -- --";
939 repr += "\n Paddle IDs:";
940 repr += &(format!("\n {:02}", self.paddle1_id.unwrap_or(-1)));
941 repr += &(format!("\n {:02}", self.paddle2_id.unwrap_or(-1)));
942 repr += &(format!("\n {:02}", self.paddle3_id.unwrap_or(-1)));
943 repr += &(format!("\n {:02}", self.paddle4_id.unwrap_or(-1)));
944 repr += &(format!("\n {:02}", self.paddle5_id.unwrap_or(-1)));
945 repr += &(format!("\n {:02}", self.paddle6_id.unwrap_or(-1)));
946 repr += &(format!("\n {:02}", self.paddle7_id.unwrap_or(-1)));
947 repr += &(format!("\n {:02}", self.paddle8_id.unwrap_or(-1)));
948 write!(f, "{}", repr)
949 }
950}
951
952#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
953pub struct LocalTriggerBoard {
954 pub board_id : u8,
955 pub dsi : u8,
956 pub j : u8,
957 pub rat : u8,
958 pub ltb_id : u8,
959 pub cable_len : f32,
960 pub paddle1 : Paddle,
961 pub paddle2 : Paddle,
962 pub paddle3 : Paddle,
963 pub paddle4 : Paddle,
964 pub paddle5 : Paddle,
965 pub paddle6 : Paddle,
966 pub paddle7 : Paddle,
967 pub paddle8 : Paddle,
968}
969
970impl LocalTriggerBoard {
971
972 pub fn new() -> Self {
973 Self {
974 board_id : 0,
975 dsi : 0,
976 j : 0,
977 rat : 0,
978 ltb_id : 0,
979 cable_len : 0.0,
980 paddle1 : Paddle::new(),
981 paddle2 : Paddle::new(),
982 paddle3 : Paddle::new(),
983 paddle4 : Paddle::new(),
984 paddle5 : Paddle::new(),
985 paddle6 : Paddle::new(),
986 paddle7 : Paddle::new(),
987 paddle8 : Paddle::new(),
988 }
989 }
990
991 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<LocalTriggerBoard>> {
992 use schema::tof_db_localtriggerboard::dsl::*;
993 let db_ltbs : Vec<DBLocalTriggerBoard>;
994 match tof_db_localtriggerboard
995 .load::<DBLocalTriggerBoard>(conn) {
997 Err(err) => {
998 error!("Unable to load LocalTriggerBoards from db! {err}");
999 return None;
1000 }
1001 Ok(ltbs) => {
1002 db_ltbs = ltbs;
1003 }
1004 }
1005 let paddles_op = Paddle::all(conn);
1006 match paddles_op {
1007 None => {
1008 return None;
1009 }
1010 Some(_) => ()
1011 }
1012 let paddles = paddles_op.unwrap();
1013 let mut ltbs = Vec::<LocalTriggerBoard>::new();
1016 for dbltb in db_ltbs {
1018 let mut ltb = LocalTriggerBoard::new();
1019 for pdl in paddles.iter() {
1020 if !dbltb.valid() {
1023 error!("Got unpopulated LTB from DB for LTB {}", dbltb);
1024 continue;
1025 }
1026 if pdl.paddle_id == dbltb.paddle1_id.unwrap() {
1027 ltb.board_id = dbltb.board_id as u8;
1028 ltb.dsi = dbltb.dsi.unwrap_or(0) as u8;
1029 ltb.j = dbltb.j.unwrap_or(0) as u8;
1030 ltb.rat = dbltb.rat.unwrap_or(0) as u8;
1031 ltb.ltb_id = dbltb.ltb_id.unwrap_or(0) as u8;
1032 ltb.cable_len = dbltb.cable_len;
1033 ltb.paddle1 = pdl.clone();
1034 }
1035 if pdl.paddle_id == dbltb.paddle2_id.unwrap() {
1036 ltb.paddle2 = pdl.clone();
1037 }
1038 if pdl.paddle_id == dbltb.paddle3_id.unwrap() {
1039 ltb.paddle3 = pdl.clone();
1040 }
1041 if pdl.paddle_id == dbltb.paddle4_id.unwrap() {
1042 ltb.paddle4 = pdl.clone();
1043 }
1044 if pdl.paddle_id == dbltb.paddle5_id.unwrap() {
1045 ltb.paddle5 = pdl.clone();
1046 }
1047 if pdl.paddle_id == dbltb.paddle6_id.unwrap() {
1048 ltb.paddle6 = pdl.clone();
1049 }
1050 if pdl.paddle_id == dbltb.paddle7_id.unwrap() {
1051 ltb.paddle7 = pdl.clone();
1052 }
1053 if pdl.paddle_id == dbltb.paddle8_id.unwrap() {
1054 ltb.paddle8 = pdl.clone();
1055 }
1056 }
1057 ltbs.push(ltb);
1058 }
1059 Some(ltbs)
1060 }
1061}
1062
1063impl fmt::Display for LocalTriggerBoard {
1064 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1065 let mut repr : String;
1066 repr = String::from("<LocalTriggerBoard:");
1067 repr += &(format!("\n LTB ID : {}", self.board_id));
1068 repr += &(format!("\n DSI/J : {}/{}", self.dsi, self.j));
1069 repr += &(format!("\n RAT ID : {}", self.rat));
1070 repr += "\n H. cable len (MTB connection):";
1071 repr += &(format!("\n -> {}", self.cable_len));
1072 repr += "\n -- -- -- -- -- -- -- -- -- -- -- -- -- --";
1073 repr += "\n LTB Ch -> RB Id, RB chn, Pdl ID, Pan ID:";
1074 repr += &(format!("\n {:02} | {},{} | {:03} | {:02}", self.paddle1.rb_id, self.paddle1.rb_chA, self.paddle1.rb_chB, self.paddle1.paddle_id, self.paddle1.panel_id));
1075 repr += &(format!("\n {:02} | {},{} | {:03} | {:02}", self.paddle2.rb_id, self.paddle2.rb_chA, self.paddle2.rb_chB, self.paddle2.paddle_id, self.paddle2.panel_id));
1076 repr += &(format!("\n {:02} | {},{} | {:03} | {:02}", self.paddle3.rb_id, self.paddle3.rb_chA, self.paddle3.rb_chB, self.paddle3.paddle_id, self.paddle3.panel_id));
1077 repr += &(format!("\n {:02} | {},{} | {:03} | {:02}", self.paddle4.rb_id, self.paddle4.rb_chA, self.paddle4.rb_chB, self.paddle4.paddle_id, self.paddle4.panel_id));
1078 repr += &(format!("\n {:02} | {},{} | {:03} | {:02}", self.paddle5.rb_id, self.paddle5.rb_chA, self.paddle5.rb_chB, self.paddle5.paddle_id, self.paddle5.panel_id));
1079 repr += &(format!("\n {:02} | {},{} | {:03} | {:02}", self.paddle6.rb_id, self.paddle6.rb_chA, self.paddle6.rb_chB, self.paddle6.paddle_id, self.paddle6.panel_id));
1080 repr += &(format!("\n {:02} | {},{} | {:03} | {:02}", self.paddle7.rb_id, self.paddle7.rb_chA, self.paddle7.rb_chB, self.paddle7.paddle_id, self.paddle7.panel_id));
1081 repr += &(format!("\n {:02} | {},{} | {:03} | {:02}>", self.paddle8.rb_id, self.paddle8.rb_chA, self.paddle8.rb_chB, self.paddle8.paddle_id, self.paddle8.panel_id));
1082 write!(f, "{}", repr)
1083 }
1084}
1085
1086#[derive(Debug,PartialEq, Clone,Queryable, Selectable, serde::Serialize, serde::Deserialize)]
1089#[diesel(table_name = schema::tof_db_readoutboard)]
1090#[diesel(primary_key(rb_id_id))]
1091#[allow(non_snake_case)]
1092pub struct DBReadoutBoard {
1093 pub rb_id : i16,
1096 pub dsi : i16,
1097 pub j : i16,
1098 pub mtb_link_id : i16,
1099 pub paddle12_chA : Option<i16>,
1100 pub paddle34_chA : Option<i16>,
1101 pub paddle56_chA : Option<i16>,
1102 pub paddle78_chA : Option<i16>,
1103 pub paddle12_id : Option<i16>,
1104 pub paddle34_id : Option<i16>,
1105 pub paddle56_id : Option<i16>,
1106 pub paddle78_id : Option<i16>,
1107}
1108
1109impl DBReadoutBoard {
1110 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<DBReadoutBoard>> {
1111 use schema::tof_db_readoutboard::dsl::*;
1112 match tof_db_readoutboard
1113 .load::<DBReadoutBoard>(conn) {
1115 Err(err) => {
1116 error!("Unable to load ReadoutBoards from db! {err}");
1117 return None;
1118 }
1119 Ok(rbs) => {
1120 return Some(rbs);
1121 }
1122 }
1123 }
1124}
1125
1126impl fmt::Display for DBReadoutBoard {
1127 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1128 let mut repr = String::from("<ReadoutBoard:");
1129 repr += &(format!("\n Board id : {}",self.rb_id));
1130 repr += &(format!("\n MTB Link ID : {}",self.mtb_link_id));
1131 repr += &(format!("\n DSI/J : {}/{}",self.dsi,self.j));
1132 repr += "\n **Connected paddles**";
1133 repr += &(format!("\n Ch0/1(1/2) : {}", self.paddle12_id.unwrap_or(-1)));
1134 repr += &(format!("\n Ch1/2(2/3) : {}", self.paddle34_id.unwrap_or(-1)));
1135 repr += &(format!("\n Ch2/3(3/4) : {}", self.paddle56_id.unwrap_or(-1)));
1136 repr += &(format!("\n Ch3/4(4/5) : {}>",self.paddle78_id.unwrap_or(-1)));
1137 write!(f, "{}", repr)
1138 }
1139}
1140
1141#[derive(Debug, Clone)]
1143#[allow(non_snake_case)]
1144pub struct ReadoutBoard {
1145 pub rb_id : u8,
1146 pub dsi : u8,
1147 pub j : u8,
1148 pub mtb_link_id : u8,
1149 pub paddle12 : Paddle,
1150 pub paddle12_chA : u8,
1151 pub paddle34 : Paddle,
1152 pub paddle34_chA : u8,
1153 pub paddle56 : Paddle,
1154 pub paddle56_chA : u8,
1155 pub paddle78 : Paddle,
1156 pub paddle78_chA : u8,
1157 pub calib_file_path : String,
1160 pub calibration : RBCalibrations,
1161}
1162
1163impl ReadoutBoard {
1164
1165 pub fn new() -> Self {
1166 Self {
1167 rb_id : 0,
1168 dsi : 0,
1169 j : 0,
1170 mtb_link_id : 0,
1171 paddle12 : Paddle::new(),
1172 paddle12_chA : 0,
1173 paddle34 : Paddle::new(),
1174 paddle34_chA : 0,
1175 paddle56 : Paddle::new(),
1176 paddle56_chA : 0,
1177 paddle78 : Paddle::new(),
1178 paddle78_chA : 0,
1179 calib_file_path : String::from(""),
1180 calibration : RBCalibrations::new(0),
1181 }
1182 }
1183
1184 pub fn guess_address(&self) -> String {
1188 format!("tcp://10.0.1.1{:02}:42000", self.rb_id)
1189 }
1190
1191 pub fn get_paddle_ids(&self) -> [u8;4] {
1192 let pid0 = self.paddle12.paddle_id as u8;
1193 let pid1 = self.paddle34.paddle_id as u8;
1194 let pid2 = self.paddle56.paddle_id as u8;
1195 let pid3 = self.paddle78.paddle_id as u8;
1196 [pid0, pid1, pid2, pid3]
1197 }
1198
1199 #[allow(non_snake_case)]
1200 pub fn get_A_sides(&self) -> [u8;4] {
1201 let pa_0 = self.paddle12_chA;
1202 let pa_1 = self.paddle34_chA;
1203 let pa_2 = self.paddle56_chA;
1204 let pa_3 = self.paddle78_chA;
1205 [pa_0, pa_1, pa_2, pa_3]
1206 }
1207
1208 #[allow(non_snake_case)]
1209 pub fn get_pid_rbchA(&self, pid : u8) -> Option<u8> {
1210 if self.paddle12.paddle_id as u8 == pid {
1211 let rv = self.paddle12.rb_chA as u8;
1212 return Some(rv);
1213 } else if self.paddle34.paddle_id as u8 == pid {
1214 let rv = self.paddle34.rb_chA as u8;
1215 return Some(rv);
1216 } else if self.paddle56.paddle_id as u8 == pid {
1217 let rv = self.paddle56.rb_chA as u8;
1218 return Some(rv);
1219 } else if self.paddle78.paddle_id as u8== pid {
1220 let rv = self.paddle78.rb_chA as u8;
1221 return Some(rv);
1222 } else {
1223 return None;
1224 }
1225 }
1226
1227 #[allow(non_snake_case)]
1228 pub fn get_pid_rbchB(&self, pid : u8) -> Option<u8> {
1229 if self.paddle12.paddle_id as u8 == pid {
1230 let rv = self.paddle12.rb_chB as u8;
1231 return Some(rv);
1232 } else if self.paddle34.paddle_id as u8== pid {
1233 let rv = self.paddle34.rb_chB as u8;
1234 return Some(rv);
1235 } else if self.paddle56.paddle_id as u8== pid {
1236 let rv = self.paddle56.rb_chB as u8;
1237 return Some(rv);
1238 } else if self.paddle78.paddle_id as u8 == pid {
1239 let rv = self.paddle78.rb_chB as u8;
1240 return Some(rv);
1241 } else {
1242 return None;
1243 }
1244 }
1245
1246 pub fn get_paddle_length(&self, pid : u8) -> Option<f32> {
1247 if self.paddle12.paddle_id as u8 == pid {
1248 let rv = self.paddle12.length;
1249 return Some(rv);
1250 } else if self.paddle34.paddle_id as u8== pid {
1251 let rv = self.paddle34.length;
1252 return Some(rv);
1253 } else if self.paddle56.paddle_id as u8== pid {
1254 let rv = self.paddle56.length;
1255 return Some(rv);
1256 } else if self.paddle78.paddle_id as u8 == pid {
1257 let rv = self.paddle78.length;
1258 return Some(rv);
1259 } else {
1260 return None;
1261 }
1262 }
1263
1264 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<ReadoutBoard>> {
1265 use schema::tof_db_readoutboard::dsl::*;
1266 let db_rbs : Vec<DBReadoutBoard>;
1267 match tof_db_readoutboard
1268 .load::<DBReadoutBoard>(conn) {
1270 Err(err) => {
1271 error!("Unable to load ReadoutBoards from db! {err}");
1272 return None;
1273 }
1274 Ok(rbs) => {
1275 db_rbs = rbs;
1276 }
1277 }
1278 let paddles_op = Paddle::all(conn);
1279 match paddles_op {
1280 None => {
1281 return None;
1282 }
1283 Some(_) => ()
1284 }
1285 let paddles = paddles_op.unwrap();
1286 let mut rbs = Vec::<ReadoutBoard>::new();
1289 for dbrb in db_rbs {
1291 let mut rb = ReadoutBoard::new();
1292 rb.rb_id = dbrb.rb_id as u8;
1293 rb.dsi = dbrb.dsi as u8;
1294 rb.j = dbrb.j as u8;
1295 rb.mtb_link_id = dbrb.mtb_link_id as u8;
1296 rb.paddle12_chA = dbrb.paddle12_chA.unwrap() as u8;
1297 rb.paddle34_chA = dbrb.paddle34_chA.unwrap() as u8;
1298 rb.paddle56_chA = dbrb.paddle56_chA.unwrap() as u8;
1299 rb.paddle78_chA = dbrb.paddle78_chA.unwrap() as u8;
1300 for pdl in paddles.iter() {
1301 if pdl.paddle_id == dbrb.paddle12_id.unwrap_or(0) {
1308 rb.paddle12 = pdl.clone();
1309 }
1310 if pdl.paddle_id == dbrb.paddle34_id.unwrap_or(0) {
1311 rb.paddle34 = pdl.clone();
1312 }
1313 if pdl.paddle_id == dbrb.paddle56_id.unwrap_or(0) {
1314 rb.paddle56 = pdl.clone();
1315 }
1316 if pdl.paddle_id == dbrb.paddle78_id.unwrap_or(0) {
1317 rb.paddle78 = pdl.clone();
1318 }
1319 }
1320 rbs.push(rb);
1321 }
1322 Some(rbs)
1323 }
1324
1325 pub fn where_rbid(conn: &mut SqliteConnection, rb_id : u8) -> Option<ReadoutBoard> {
1327 let all = ReadoutBoard::all(conn)?;
1328 for rb in all {
1329 if rb.rb_id == rb_id {
1330 return Some(rb);
1331 }
1332 }
1333 None
1334 }
1335
1336 pub fn to_summary_str(&self) -> String {
1337 let mut repr = String::from("<ReadoutBoard:");
1338 repr += &(format!("\n Board id : {}",self.rb_id));
1339 repr += &(format!("\n MTB Link ID : {}",self.mtb_link_id));
1340 repr += &(format!("\n RAT : {}",self.paddle12.ltb_id));
1341 repr += &(format!("\n DSI/J : {}/{}",self.dsi,self.j));
1342 repr += "\n **Connected paddles**";
1343 repr += &(format!("\n Channel 1/2 : {:02} (panel {:01})", self.paddle12.paddle_id, self.paddle12.panel_id));
1344 repr += &(format!("\n Channel 3/4 : {:02} (panel {:01})", self.paddle34.paddle_id, self.paddle34.panel_id));
1345 repr += &(format!("\n Channel 5/6 : {:02} (panel {:01})", self.paddle56.paddle_id, self.paddle56.panel_id));
1346 repr += &(format!("\n Channel 7/8 : {:02} (panel {:01})", self.paddle78.paddle_id, self.paddle78.panel_id));
1347 repr
1348 }
1349
1350 pub fn load_latest_calibration(&mut self) -> Result<(), Box<dyn std::error::Error>> {
1352 let re = Regex::new(r"(\d{6}_\d{6})")?;
1355 let pattern = format!("{}/RB{:02}_*", self.calib_file_path, self.rb_id); let timestamp = DateTime::<Utc>::from_timestamp(0,0).unwrap(); let mut newest_file = (String::from(""), timestamp);
1362
1363 let mut filename : String;
1365 for entry in glob(&pattern)? {
1366 if let Ok(path) = entry {
1367 match path.file_name() {
1370 None => continue,
1371 Some(fname) => {
1372 filename = fname.to_os_string().into_string().expect("Unwrapping filename failed!");
1374 }
1375 }
1376 if let Some(caps) = re.captures(&filename) {
1377 if let Some(timestamp_str) = caps.get(0).map(|m| m.as_str()) {
1378 let footzstring = format!("{}+0000", timestamp_str);
1382 let timestamp = DateTime::parse_from_str(&footzstring, "%y%m%d_%H%M%S%z")?;
1383 if timestamp > newest_file.1 {
1387 newest_file.1 = timestamp.into();
1389 newest_file.0 = filename.clone();
1390 }
1391 }
1392 }
1393 }
1394 }
1395
1396 if newest_file.0.is_empty() {
1397 error!("No matching calibration available for board {}!", self.rb_id);
1398 } else {
1399 let file_to_load = format!("{}/{}", self.calib_file_path, newest_file.0);
1400 info!("Loading calibration from file: {}", file_to_load);
1401 self.calibration = RBCalibrations::from_file(file_to_load, true)?;
1402 }
1403 Ok(())
1404 }
1405}
1406
1407impl fmt::Display for ReadoutBoard {
1408 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1409 let mut repr = String::from("<ReadoutBoard:");
1410 repr += &(format!("\n Board id : {}",self.rb_id));
1411 repr += &(format!("\n MTB Link ID : {}",self.mtb_link_id));
1412 repr += &(format!("\n DSI/J : {}/{}",self.dsi,self.j));
1413 repr += "\n **Connected paddles**";
1414 repr += &(format!("\n Ch0/1(1/2) : {}",self.paddle12));
1415 repr += &(format!("\n A-side : {}", self.paddle12_chA));
1416 repr += &(format!("\n Ch1/2(2/3) : {}",self.paddle34));
1417 repr += &(format!("\n A-side : {}", self.paddle34_chA));
1418 repr += &(format!("\n Ch2/3(3/4) : {}",self.paddle56));
1419 repr += &(format!("\n A-side : {}", self.paddle56_chA));
1420 repr += &(format!("\n Ch3/4(4/5) : {}>",self.paddle78));
1421 repr += &(format!("\n A-side : {}", self.paddle78_chA));
1422 repr += "** calibration will be loaded from this path:";
1423 repr += &(format!("\n \u{021B3} {}", self.calib_file_path));
1424 repr += &(format!("\n calibration : {}>", self.calibration));
1425 write!(f, "{}", repr)
1426 }
1427}
1428
1429
1430#[derive(Debug, Clone,Queryable, Selectable)]
1434#[diesel(table_name = schema::tof_db_panel)]
1435#[diesel(primary_key(panel_id))]
1436pub struct DBPanel {
1437 pub panel_id : i16 ,
1439 pub description : String ,
1440 pub normal_x : i16 ,
1441 pub normal_y : i16 ,
1442 pub normal_z : i16 ,
1443 pub dw_paddle : Option<i16>,
1444 pub dh_paddle : Option<i16>,
1445 pub paddle0_id : Option<i16>,
1446 pub paddle1_id : Option<i16>,
1447 pub paddle10_id : Option<i16>,
1448 pub paddle11_id : Option<i16>,
1449 pub paddle2_id : Option<i16>,
1450 pub paddle3_id : Option<i16>,
1451 pub paddle4_id : Option<i16>,
1452 pub paddle5_id : Option<i16>,
1453 pub paddle6_id : Option<i16>,
1454 pub paddle7_id : Option<i16>,
1455 pub paddle8_id : Option<i16>,
1456 pub paddle9_id : Option<i16>,
1457}
1458
1459impl DBPanel {
1460
1461 pub fn valid(&self) -> bool {
1462 self.panel_id > 0 &&
1463 self.description != String::from("") &&
1464 self.paddle0_id.is_some()
1465 }
1466
1467 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<DBPanel>> {
1468 use schema::tof_db_panel::dsl::*;
1469 match tof_db_panel
1470 .load::<DBPanel>(conn) {
1472 Err(err) => {
1473 error!("Unable to load Panels from db! {err}");
1474 return None;
1475 }
1476 Ok(pnls) => {
1478 return Some(pnls);
1479 }
1480 }
1481 }
1482
1483 pub fn get_npaddles(&self) -> u8 {
1484 let mut npaddles = 0u8;
1485 if self.paddle0_id.is_some() {
1486 npaddles += 1;
1487 }
1488 if self.paddle1_id.is_some() {
1489 npaddles += 1;
1490 }
1491 if self.paddle2_id.is_some() {
1492 npaddles += 1;
1493 }
1494 if self.paddle3_id.is_some() {
1495 npaddles += 1;
1496 }
1497 if self.paddle4_id.is_some() {
1498 npaddles += 1;
1499 }
1500 if self.paddle5_id.is_some() {
1501 npaddles += 1;
1502 }
1503 if self.paddle6_id.is_some() {
1504 npaddles += 1;
1505 }
1506 if self.paddle7_id.is_some() {
1507 npaddles += 1;
1508 }
1509 if self.paddle8_id.is_some() {
1510 npaddles += 1;
1511 }
1512 if self.paddle9_id.is_some() {
1513 npaddles += 1;
1514 }
1515 if self.paddle10_id.is_some() {
1516 npaddles += 1;
1517 }
1518 if self.paddle11_id.is_some() {
1519 npaddles += 1;
1520 }
1521 npaddles
1522 }
1523}
1524
1525impl fmt::Display for DBPanel {
1526 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1527 let mut repr = String::from("<DBPanel");
1528 repr += &(format!("\n id : {}",self.panel_id));
1529 repr += &(format!("\n descr : {}",self.description));
1530 repr += "\n orientation:";
1531 repr += &(format!("\n [{},{},{}]", self.normal_x, self.normal_y, self.normal_z));
1532 repr += &(format!("\n paddle list ({}) paddles)", self.get_npaddles()));
1533 if self.paddle0_id.is_some() {
1534 repr += &(format!("\n {}",self.paddle0_id.unwrap()));
1535 }
1536 if self.paddle1_id.is_some() {
1537 repr += &(format!("\n {}",self.paddle1_id.unwrap()));
1538 }
1539 if self.paddle2_id.is_some() {
1540 repr += &(format!("\n {}",self.paddle2_id.unwrap()));
1541 }
1542 if self.paddle3_id.is_some() {
1543 repr += &(format!("\n {}",self.paddle3_id.unwrap()));
1544 }
1545 if self.paddle4_id.is_some() {
1546 repr += &(format!("\n {}",self.paddle4_id.unwrap()));
1547 }
1548 if self.paddle5_id.is_some() {
1549 repr += &(format!("\n {}",self.paddle5_id.unwrap()));
1550 }
1551 if self.paddle6_id.is_some() {
1552 repr += &(format!("\n {}",self.paddle6_id.unwrap()));
1553 }
1554 if self.paddle7_id.is_some() {
1555 repr += &(format!("\n {}",self.paddle7_id.unwrap()));
1556 }
1557 if self.paddle8_id.is_some() {
1558 repr += &(format!("\n {}",self.paddle8_id.unwrap()));
1559 }
1560 if self.paddle9_id.is_some() {
1561 repr += &(format!("\n {}",self.paddle9_id.unwrap()));
1562 }
1563 if self.paddle10_id.is_some() {
1564 repr += &(format!("\n {}",self.paddle10_id.unwrap()));
1565 }
1566 if self.paddle11_id.is_some() {
1567 repr += &(format!("\n {}",self.paddle11_id.unwrap()));
1568 }
1569 repr += ">";
1570 write!(f, "{}", repr)
1571 }
1572}
1573
1574pub struct Panel {
1575 pub panel_id : u8 ,
1576 pub description : String ,
1577 pub normal_x : u8 ,
1578 pub normal_y : u8 ,
1579 pub normal_z : u8 ,
1580 pub paddle0 : Paddle,
1581 pub paddle1 : Option<Paddle>,
1582 pub paddle2 : Option<Paddle>,
1583 pub paddle3 : Option<Paddle>,
1584 pub paddle4 : Option<Paddle>,
1585 pub paddle5 : Option<Paddle>,
1586 pub paddle6 : Option<Paddle>,
1587 pub paddle7 : Option<Paddle>,
1588 pub paddle8 : Option<Paddle>,
1589 pub paddle9 : Option<Paddle>,
1590 pub paddle10 : Option<Paddle>,
1591 pub paddle11 : Option<Paddle>,
1592 }
1598
1599impl Panel {
1600
1601 pub fn new() -> Self {
1602 Self {
1603 panel_id : 0 ,
1604 description : String::from(""),
1605 normal_x : 0 ,
1606 normal_y : 0 ,
1607 normal_z : 0 ,
1608 paddle0 : Paddle::new(),
1609 paddle1 : None,
1610 paddle2 : None,
1611 paddle3 : None,
1612 paddle4 : None,
1613 paddle5 : None,
1614 paddle6 : None,
1615 paddle7 : None,
1616 paddle8 : None,
1617 paddle9 : None,
1618 paddle10 : None,
1619 paddle11 : None,
1620 }
1621 }
1622
1623
1624 pub fn get_npaddles(&self) -> u8 {
1625 let mut npaddles = 1u8;
1626 if self.paddle1.is_some() {
1627 npaddles += 1;
1628 }
1629 if self.paddle2.is_some() {
1630 npaddles += 1;
1631 }
1632 if self.paddle3.is_some() {
1633 npaddles += 1;
1634 }
1635 if self.paddle4.is_some() {
1636 npaddles += 1;
1637 }
1638 if self.paddle5.is_some() {
1639 npaddles += 1;
1640 }
1641 if self.paddle6.is_some() {
1642 npaddles += 1;
1643 }
1644 if self.paddle7.is_some() {
1645 npaddles += 1;
1646 }
1647 if self.paddle8.is_some() {
1648 npaddles += 1;
1649 }
1650 if self.paddle9.is_some() {
1651 npaddles += 1;
1652 }
1653 if self.paddle10.is_some() {
1654 npaddles += 1;
1655 }
1656 if self.paddle11.is_some() {
1657 npaddles += 1;
1658 }
1659 npaddles
1660 }
1661
1662 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<Panel>> {
1663 use schema::tof_db_panel::dsl::*;
1664 let db_panels : Vec<DBPanel>;
1665 match tof_db_panel
1666 .load::<DBPanel>(conn) {
1668 Err(err) => {
1669 error!("Unable to load Panels from db! {err}");
1670 return None;
1671 }
1672 Ok(pnls) => {
1673 db_panels = pnls;
1674 }
1675 }
1676 let paddles_op = Paddle::all(conn);
1677 match paddles_op {
1678 None => {
1679 return None;
1680 }
1681 Some(_) => ()
1682 }
1683 let paddles = paddles_op.unwrap();
1684 let mut panels = Vec::<Panel>::new();
1687 println!("Iterating over {} panels in the DB!", db_panels.len());
1688 for dbpanel in db_panels {
1689 let mut pnl = Panel::new();
1690 for pdl in paddles.iter() {
1691 if !dbpanel.valid() {
1694 error!("Got unpopulated Panel from DB for Panel {}", dbpanel);
1695 continue;
1696 }
1697 if pdl.paddle_id == dbpanel.paddle0_id.unwrap() {
1698 pnl.panel_id = dbpanel.panel_id as u8;
1699 pnl.description = dbpanel.description.clone();
1700 pnl.normal_x = dbpanel.normal_x as u8;
1701 pnl.normal_y = dbpanel.normal_y as u8;
1702 pnl.normal_z = dbpanel.normal_z as u8;
1703 pnl.paddle0 = pdl.clone();
1704 }
1705 if pdl.paddle_id == dbpanel.paddle1_id.unwrap() {
1706 pnl.paddle1 = Some(pdl.clone());
1707 }
1708 if pdl.paddle_id == dbpanel.paddle2_id.unwrap() {
1709 pnl.paddle2 = Some(pdl.clone());
1710 }
1711 if pdl.paddle_id == dbpanel.paddle3_id.unwrap() {
1712 pnl.paddle3 = Some(pdl.clone());
1713 }
1714 if pdl.paddle_id == dbpanel.paddle4_id.unwrap() {
1715 pnl.paddle4 = Some(pdl.clone());
1716 }
1717 if pdl.paddle_id == dbpanel.paddle5_id.unwrap() {
1718 pnl.paddle5 = Some(pdl.clone());
1719 }
1720 if pdl.paddle_id == dbpanel.paddle6_id.unwrap() {
1721 pnl.paddle6 = Some(pdl.clone());
1722 }
1723 if pdl.paddle_id == dbpanel.paddle7_id.unwrap() {
1724 pnl.paddle7 = Some(pdl.clone());
1725 }
1726 if pdl.paddle_id == dbpanel.paddle8_id.unwrap() {
1727 pnl.paddle8 = Some(pdl.clone());
1728 }
1729 if pdl.paddle_id == dbpanel.paddle9_id.unwrap() {
1730 pnl.paddle9 = Some(pdl.clone());
1731 }
1732 if pdl.paddle_id == dbpanel.paddle10_id.unwrap() {
1733 pnl.paddle10 = Some(pdl.clone());
1734 }
1735 if pdl.paddle_id == dbpanel.paddle11_id.unwrap() {
1736 pnl.paddle11 = Some(pdl.clone());
1737 }
1738 }
1739 panels.push(pnl);
1740 }
1741 Some(panels)
1742 }
1743}
1744
1745impl fmt::Display for Panel {
1746 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1747 let mut repr = String::from("<Panel");
1748 repr += &(format!("\n id : {}",self.panel_id));
1749 repr += &(format!("\n descr : {}",self.description));
1750 repr += "\n orientation:";
1751 repr += &(format!("\n [{},{},{}]", self.normal_x, self.normal_y, self.normal_z));
1752 repr += &(format!("\n paddle list ({}) paddles)", self.get_npaddles()));
1753 repr += &(format!("\n {}",self.paddle0));
1754 if self.paddle1.is_some() {
1755 repr += &(format!("\n {}",self.paddle1.as_ref().unwrap()));
1756 }
1757 if self.paddle2.is_some() {
1758 repr += &(format!("\n {}",self.paddle2.as_ref().unwrap()));
1759 }
1760 if self.paddle3.is_some() {
1761 repr += &(format!("\n {}",self.paddle3.as_ref().unwrap()));
1762 }
1763 if self.paddle4.is_some() {
1764 repr += &(format!("\n {}",self.paddle4.as_ref().unwrap()));
1765 }
1766 if self.paddle5.is_some() {
1767 repr += &(format!("\n {}",self.paddle5.as_ref().unwrap()));
1768 }
1769 if self.paddle6.is_some() {
1770 repr += &(format!("\n {}",self.paddle6.as_ref().unwrap()));
1771 }
1772 if self.paddle7.is_some() {
1773 repr += &(format!("\n {}",self.paddle7.as_ref().unwrap()));
1774 }
1775 if self.paddle8.is_some() {
1776 repr += &(format!("\n {}",self.paddle8.as_ref().unwrap()));
1777 }
1778 if self.paddle9.is_some() {
1779 repr += &(format!("\n {}",self.paddle9.as_ref().unwrap()));
1780 }
1781 if self.paddle10.is_some() {
1782 repr += &(format!("\n {}",self.paddle10.as_ref().unwrap()));
1783 }
1784 if self.paddle11.is_some() {
1785 repr += &(format!("\n {}",self.paddle11.as_ref().unwrap()));
1786 }
1787 repr += ">";
1788 write!(f, "{}", repr)
1789 }
1790}
1791
1792
1793
1794