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 {
554 self.channel as u32 + (self.module as u32)*100 + (self.row as u32)*10000 + (self.layer as u32)*100000
555 }
556
557 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<Self>> {
558 use schema::tof_db_trackerstrip::dsl::*;
559 match tof_db_trackerstrip.load::<Self>(conn) {
560 Err(err) => {
561 error!("Unable to load tracker strips from db! {err}");
562 return None;
563 }
564 Ok(pdls) => {
565 return Some(pdls);
566 }
567 }
568 }
569}
570
571impl fmt::Display for TrackerStrip {
572 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
573 let mut repr = String::from("<TrackerStrip:");
574 repr += &(format!("\n strip id : {}", self.strip_id));
575 repr += &(format!("\n vid : {}", self.volume_id));
576 repr += &(format!("\n layer : {}", self.layer));
577 repr += &(format!("\n row : {}", self.row));
578 repr += &(format!("\n module : {}", self.module));
579 repr += &(format!("\n channel : {}", self.channel));
580 repr += "\n strip center [mm]:";
581 repr += &(format!("\n \u{21B3} [{:.2}, {:.2}, {:.2}]", self.global_pos_x_l0, self.global_pos_y_l0, self.global_pos_z_l0));
582 repr += "\n detector (disk) center [mm]:";
583 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));
584 repr += "\n strip principal direction:";
585 repr += &(format!("\n \u{21B3} [{:.2}, {:.2}, {:.2}]", self.principal_x, self.principal_y, self.principal_z));
586 write!(f, "{}", repr)
587 }
588}
589
590
591
592#[derive(Debug,PartialEq, Clone,Queryable, Selectable, serde::Serialize, serde::Deserialize)]
595#[diesel(table_name = schema::tof_db_paddle)]
596#[diesel(primary_key(paddle_id))]
597#[allow(non_snake_case)]
598pub struct Paddle {
599 pub paddle_id : i16,
600 pub volume_id : i64,
601 pub panel_id : i16,
602 pub mtb_link_id : i16,
603 pub rb_id : i16,
604 pub rb_chA : i16,
605 pub rb_chB : i16,
606 pub ltb_id : i16,
607 pub ltb_chA : i16,
608 pub ltb_chB : i16,
609 pub pb_id : i16,
610 pub pb_chA : i16,
611 pub pb_chB : i16,
612 pub cable_len : f32,
613 pub dsi : i16,
614 pub j_rb : i16,
615 pub j_ltb : i16,
616 pub height : f32,
617 pub width : f32,
618 pub length : f32,
619 pub normal_x : f32,
620 pub normal_y : f32,
621 pub normal_z : f32,
622 pub global_pos_x_l0 : f32,
623 pub global_pos_y_l0 : f32,
624 pub global_pos_z_l0 : f32,
625 pub global_pos_x_l0_A : f32,
626 pub global_pos_y_l0_A : f32,
627 pub global_pos_z_l0_A : f32,
628 pub global_pos_x_l0_B : f32,
629 pub global_pos_y_l0_B : f32,
630 pub global_pos_z_l0_B : f32,
631 pub coax_cable_time : f32,
632 pub harting_cable_time: f32,
633}
634
635impl Paddle {
636 pub fn new() -> Self {
637 Self {
638 paddle_id : 0,
639 volume_id : 0,
640 panel_id : 0,
641 mtb_link_id : 0,
642 rb_id : 0,
643 rb_chA : 0,
644 rb_chB : 0,
645 ltb_id : 0,
646 ltb_chA : 0,
647 ltb_chB : 0,
648 pb_id : 0,
649 pb_chA : 0,
650 pb_chB : 0,
651 cable_len : 0.0,
652 dsi : 0,
653 j_rb : 0,
654 j_ltb : 0,
655 height : 0.0,
656 width : 0.0,
657 length : 0.0,
658 normal_x : 0.0,
659 normal_y : 0.0,
660 normal_z : 0.0,
661 global_pos_x_l0 : 0.0,
662 global_pos_y_l0 : 0.0,
663 global_pos_z_l0 : 0.0,
664 global_pos_x_l0_A : 0.0,
665 global_pos_y_l0_A : 0.0,
666 global_pos_z_l0_A : 0.0,
667 global_pos_x_l0_B : 0.0,
668 global_pos_y_l0_B : 0.0,
669 global_pos_z_l0_B : 0.0,
670 coax_cable_time : 0.0,
671 harting_cable_time: 0.0
672 }
673 }
674
675 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<Paddle>> {
676 use schema::tof_db_paddle::dsl::*;
677 match tof_db_paddle.load::<Paddle>(conn) {
678 Err(err) => {
679 error!("Unable to load paddles from db! {err}");
680 return None;
681 }
682 Ok(pdls) => {
683 return Some(pdls);
684 }
685 }
686 }
687
688 pub fn principal(&self) -> (f32,f32,f32) {
691 let mut pr = (self.global_pos_x_l0_B - self.global_pos_x_l0_A,
692 self.global_pos_y_l0_B - self.global_pos_y_l0_A,
693 self.global_pos_z_l0_B - self.global_pos_z_l0_A);
694 let length = f32::sqrt(pr.0.powf(2.0) + pr.1.powf(2.0) + pr.2.powf(2.0));
695 pr = (pr.0/length, pr.1/length, pr.2/length);
696 return pr;
697 }
698
699}
700
701impl fmt::Display for Paddle {
702 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
703 let mut repr = String::from("<Paddle:");
704 repr += "\n** identifiers **";
705 repr += &(format!("\n pid : {}", self.paddle_id));
706 repr += &(format!("\n vid : {}", self.volume_id));
707 repr += &(format!("\n panel id : {}", self.panel_id));
708 repr += "\n ** connedtions **";
709 repr += &(format!("\n DSI/J/CH (LG) [A] : {} | {} | {:02}", self.dsi, self.j_ltb, self.ltb_chA));
710 repr += &(format!("\n DSI/J/CH (HG) [A] : {} | {} | {:02}", self.dsi, self.j_rb, self.rb_chA));
711 repr += &(format!("\n DSI/J/CH (LG) [B] : {} | {} | {:02}", self.dsi, self.j_ltb, self.ltb_chB));
712 repr += &(format!("\n DSI/J/CH (HG) [B] : {} | {} | {:02}", self.dsi, self.j_rb, self.rb_chB));
713 repr += &(format!("\n RB/CH [A] : {:02} | {}", self.rb_id, self.rb_chA));
714 repr += &(format!("\n RB/CH [B] : {:02} | {}", self.rb_id, self.rb_chB));
715 repr += &(format!("\n LTB/CH [A] : {:02} | {}", self.ltb_id, self.ltb_chA));
716 repr += &(format!("\n LTB/CH [B] : {:02} | {}", self.ltb_id, self.ltb_chB));
717 repr += &(format!("\n PB/CH [A] : {:02} | {}", self.pb_id, self.pb_chA));
718 repr += &(format!("\n PB/CH [B] : {:02} | {}", self.pb_id, self.pb_chB));
719 repr += &(format!("\n MTB Link ID : {:02}", self.mtb_link_id));
720 repr += "\n cable len [cm] :";
721 repr += &(format!("\n \u{21B3} {:.2}", self.cable_len));
722 repr += "\n (Harting -> RB)";
723 repr += "\n cable times [ns] (JAZ) :";
724 repr += &(format!("\n \u{21B3} {:.2} {:.2}", self.coax_cable_time, self.harting_cable_time));
725 repr += "\n ** Coordinates (L0) & dimensions **";
726 repr += "\n length, width, height [mm]";
727 repr += &(format!("\n \u{21B3} [{:.2}, {:.2}, {:.2}]", self.length, self.width, self.height));
728 repr += "\n center [mm]:";
729 repr += &(format!("\n \u{21B3} [{:.2}, {:.2}, {:.2}]", self.global_pos_x_l0, self.global_pos_y_l0, self.global_pos_z_l0));
730 repr += "\n normal vector:";
731 repr += &(format!("\n \u{21B3} [{:.2}, {:.2}, {:.2}]", self.normal_x, self.normal_y, self.normal_z));
732 repr += "\n A-side [mm]:";
733 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));
734 repr += "\n B-side [mm]:";
735 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));
736 write!(f, "{}", repr)
737 }
738}
739
740#[derive(Debug,PartialEq,Queryable, Selectable)]
744#[diesel(table_name = schema::tof_db_mtbchannel)]
745#[diesel(primary_key(mtb_ch))]
746#[allow(non_snake_case)]
747pub struct MTBChannel {
748 pub mtb_ch : i64,
749 pub dsi : Option<i16>,
750 pub j : Option<i16>,
751 pub ltb_id : Option<i16>,
752 pub ltb_ch : Option<i16>,
753 pub rb_id : Option<i16>,
754 pub rb_ch : Option<i16>,
755 pub mtb_link_id : Option<i16>,
756 pub paddle_id : Option<i16>,
757 pub paddle_isA : Option<bool>,
758 pub hg_ch : Option<i16>,
759 pub lg_ch : Option<i16>,
760}
761
762impl MTBChannel {
763
764 pub fn new() -> Self {
765 Self {
766 mtb_ch : -1,
767 dsi : None,
768 j : None,
769 ltb_id : None,
770 ltb_ch : None,
771 rb_id : None,
772 rb_ch : None,
773 mtb_link_id : None,
774 paddle_id : None,
775 paddle_isA : None,
776 hg_ch : None,
777 lg_ch : None,
778 }
779 }
780
781 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<MTBChannel>> {
782 use schema::tof_db_mtbchannel::dsl::*;
783 match tof_db_mtbchannel.load::<MTBChannel>(conn) {
784 Err(err) => {
785 error!("Unable to load RATs from db! {err}");
786 return None;
787 }
788 Ok(mtbch) => {
789 return Some(mtbch);
790 }
791 }
792 }
793}
794
795
796impl fmt::Display for MTBChannel {
797 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
798 let mut repr = String::from("<MTBChannel");
799 repr += &(format!("\n Channel ID : {}", self.mtb_ch));
800 repr += &(format!("\n DSI/J/ : {}/{}", self.dsi.unwrap_or(-1), self.j.unwrap_or(-1)));
801 repr += "\n LTB ID/CH => RB ID/CH";
802 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)));
803 repr += &(format!("\n MTB Link ID [RB] : {}", self.mtb_link_id.unwrap_or(-1)));
804 repr += "\n LG CH => HG CH";
805 repr += &(format!("\n |-> {} => {}", self.lg_ch.unwrap_or(-1), self.hg_ch.unwrap_or(-1)));
806 repr += &(format!("\n Paddle Id: {}", self.paddle_id.unwrap_or(-1)));
807 let mut pend = "None";
808 if !self.paddle_isA.is_none() {
809 if self.paddle_isA.unwrap() {
810 pend = "A";
811 } else {
812 pend = "B";
813 }
814 }
815 repr += &(format!("\n Paddle End: {}>", pend));
816 write!(f, "{}", repr)
817 }
818}
819
820
821#[derive(Queryable, Selectable, Identifiable, Associations)]
842#[diesel(table_name = schema::tof_db_localtriggerboard)]
843#[diesel(primary_key(board_id))]
844#[diesel(belongs_to(Paddle, foreign_key=paddle1_id))]
845pub struct DBLocalTriggerBoard {
846 pub board_id : i16,
847 pub dsi : Option<i16>,
848 pub j : Option<i16>,
849 pub rat : Option<i16>,
850 pub ltb_id : Option<i16>,
851 pub cable_len : f32,
852 pub paddle1_id : Option<i16>,
853 pub paddle2_id : Option<i16>,
854 pub paddle3_id : Option<i16>,
855 pub paddle4_id : Option<i16>,
856 pub paddle5_id : Option<i16>,
857 pub paddle6_id : Option<i16>,
858 pub paddle7_id : Option<i16>,
859 pub paddle8_id : Option<i16>,
860}
861
862impl DBLocalTriggerBoard {
863
864 pub fn connected(&self) -> bool {
886 self.dsi != None && self.j != None
887 }
888
889 pub fn valid(&self) -> bool {
892 self.board_id > 0 &&
893 self.dsi .is_some() &&
894 self.j .is_some() &&
895 self.rat .is_some() &&
896 self.cable_len > 0.0 &&
900 self.paddle1_id.is_some() &&
901 self.paddle2_id.is_some() &&
902 self.paddle3_id.is_some() &&
903 self.paddle4_id.is_some() &&
904 self.paddle5_id.is_some() &&
905 self.paddle6_id.is_some() &&
906 self.paddle7_id.is_some() &&
907 self.paddle8_id.is_some()
908 }
909
910 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<DBLocalTriggerBoard>> {
911 use schema::tof_db_localtriggerboard::dsl::*;
912 match tof_db_localtriggerboard
913 .load::<DBLocalTriggerBoard>(conn) {
915 Err(err) => {
916 error!("Unable to load LocalTriggerBoards from db! {err}");
917 return None;
918 }
919 Ok(ltbs) => {
920 return Some(ltbs);
921 }
922 }
923 }
924}
925
926impl fmt::Display for DBLocalTriggerBoard {
927 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
928 let mut repr : String;
929 if !self.connected() {
930 repr = format!("<DBLocalTriggerBoard: ID {} - UNCONNECTED>", self.board_id);
931 } else {
932 repr = String::from("<DBLocalTriggerBoard:");
933 repr += &(format!("\n LTB ID : {}", self.board_id));
934 }
935 repr += &(format!("\n DSI/J : {}/{}", self.dsi.unwrap(), self.j.unwrap()));
936 repr += &(format!("\n RAT ID : {}", self.rat.unwrap()));
937 repr += "\n H. cable len (MTB connection):";
938 repr += &(format!("\n -> {}", self.cable_len));
939 repr += "\n -- -- -- -- -- -- -- -- -- -- -- -- -- --";
940 repr += "\n Paddle IDs:";
941 repr += &(format!("\n {:02}", self.paddle1_id.unwrap_or(-1)));
942 repr += &(format!("\n {:02}", self.paddle2_id.unwrap_or(-1)));
943 repr += &(format!("\n {:02}", self.paddle3_id.unwrap_or(-1)));
944 repr += &(format!("\n {:02}", self.paddle4_id.unwrap_or(-1)));
945 repr += &(format!("\n {:02}", self.paddle5_id.unwrap_or(-1)));
946 repr += &(format!("\n {:02}", self.paddle6_id.unwrap_or(-1)));
947 repr += &(format!("\n {:02}", self.paddle7_id.unwrap_or(-1)));
948 repr += &(format!("\n {:02}", self.paddle8_id.unwrap_or(-1)));
949 write!(f, "{}", repr)
950 }
951}
952
953#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
954pub struct LocalTriggerBoard {
955 pub board_id : u8,
956 pub dsi : u8,
957 pub j : u8,
958 pub rat : u8,
959 pub ltb_id : u8,
960 pub cable_len : f32,
961 pub paddle1 : Paddle,
962 pub paddle2 : Paddle,
963 pub paddle3 : Paddle,
964 pub paddle4 : Paddle,
965 pub paddle5 : Paddle,
966 pub paddle6 : Paddle,
967 pub paddle7 : Paddle,
968 pub paddle8 : Paddle,
969}
970
971impl LocalTriggerBoard {
972
973 pub fn new() -> Self {
974 Self {
975 board_id : 0,
976 dsi : 0,
977 j : 0,
978 rat : 0,
979 ltb_id : 0,
980 cable_len : 0.0,
981 paddle1 : Paddle::new(),
982 paddle2 : Paddle::new(),
983 paddle3 : Paddle::new(),
984 paddle4 : Paddle::new(),
985 paddle5 : Paddle::new(),
986 paddle6 : Paddle::new(),
987 paddle7 : Paddle::new(),
988 paddle8 : Paddle::new(),
989 }
990 }
991
992 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<LocalTriggerBoard>> {
993 use schema::tof_db_localtriggerboard::dsl::*;
994 let db_ltbs : Vec<DBLocalTriggerBoard>;
995 match tof_db_localtriggerboard
996 .load::<DBLocalTriggerBoard>(conn) {
998 Err(err) => {
999 error!("Unable to load LocalTriggerBoards from db! {err}");
1000 return None;
1001 }
1002 Ok(ltbs) => {
1003 db_ltbs = ltbs;
1004 }
1005 }
1006 let paddles_op = Paddle::all(conn);
1007 match paddles_op {
1008 None => {
1009 return None;
1010 }
1011 Some(_) => ()
1012 }
1013 let paddles = paddles_op.unwrap();
1014 let mut ltbs = Vec::<LocalTriggerBoard>::new();
1017 for dbltb in db_ltbs {
1019 let mut ltb = LocalTriggerBoard::new();
1020 for pdl in paddles.iter() {
1021 if !dbltb.valid() {
1024 error!("Got unpopulated LTB from DB for LTB {}", dbltb);
1025 continue;
1026 }
1027 if pdl.paddle_id == dbltb.paddle1_id.unwrap() {
1028 ltb.board_id = dbltb.board_id as u8;
1029 ltb.dsi = dbltb.dsi.unwrap_or(0) as u8;
1030 ltb.j = dbltb.j.unwrap_or(0) as u8;
1031 ltb.rat = dbltb.rat.unwrap_or(0) as u8;
1032 ltb.ltb_id = dbltb.ltb_id.unwrap_or(0) as u8;
1033 ltb.cable_len = dbltb.cable_len;
1034 ltb.paddle1 = pdl.clone();
1035 }
1036 if pdl.paddle_id == dbltb.paddle2_id.unwrap() {
1037 ltb.paddle2 = pdl.clone();
1038 }
1039 if pdl.paddle_id == dbltb.paddle3_id.unwrap() {
1040 ltb.paddle3 = pdl.clone();
1041 }
1042 if pdl.paddle_id == dbltb.paddle4_id.unwrap() {
1043 ltb.paddle4 = pdl.clone();
1044 }
1045 if pdl.paddle_id == dbltb.paddle5_id.unwrap() {
1046 ltb.paddle5 = pdl.clone();
1047 }
1048 if pdl.paddle_id == dbltb.paddle6_id.unwrap() {
1049 ltb.paddle6 = pdl.clone();
1050 }
1051 if pdl.paddle_id == dbltb.paddle7_id.unwrap() {
1052 ltb.paddle7 = pdl.clone();
1053 }
1054 if pdl.paddle_id == dbltb.paddle8_id.unwrap() {
1055 ltb.paddle8 = pdl.clone();
1056 }
1057 }
1058 ltbs.push(ltb);
1059 }
1060 Some(ltbs)
1061 }
1062}
1063
1064impl fmt::Display for LocalTriggerBoard {
1065 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1066 let mut repr : String;
1067 repr = String::from("<LocalTriggerBoard:");
1068 repr += &(format!("\n LTB ID : {}", self.board_id));
1069 repr += &(format!("\n DSI/J : {}/{}", self.dsi, self.j));
1070 repr += &(format!("\n RAT ID : {}", self.rat));
1071 repr += "\n H. cable len (MTB connection):";
1072 repr += &(format!("\n -> {}", self.cable_len));
1073 repr += "\n -- -- -- -- -- -- -- -- -- -- -- -- -- --";
1074 repr += "\n LTB Ch -> RB Id, RB chn, Pdl ID, Pan ID:";
1075 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));
1076 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));
1077 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));
1078 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));
1079 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));
1080 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));
1081 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));
1082 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));
1083 write!(f, "{}", repr)
1084 }
1085}
1086
1087#[derive(Debug,PartialEq, Clone,Queryable, Selectable, serde::Serialize, serde::Deserialize)]
1090#[diesel(table_name = schema::tof_db_readoutboard)]
1091#[diesel(primary_key(rb_id_id))]
1092#[allow(non_snake_case)]
1093pub struct DBReadoutBoard {
1094 pub rb_id : i16,
1097 pub dsi : i16,
1098 pub j : i16,
1099 pub mtb_link_id : i16,
1100 pub paddle12_chA : Option<i16>,
1101 pub paddle34_chA : Option<i16>,
1102 pub paddle56_chA : Option<i16>,
1103 pub paddle78_chA : Option<i16>,
1104 pub paddle12_id : Option<i16>,
1105 pub paddle34_id : Option<i16>,
1106 pub paddle56_id : Option<i16>,
1107 pub paddle78_id : Option<i16>,
1108}
1109
1110impl DBReadoutBoard {
1111 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<DBReadoutBoard>> {
1112 use schema::tof_db_readoutboard::dsl::*;
1113 match tof_db_readoutboard
1114 .load::<DBReadoutBoard>(conn) {
1116 Err(err) => {
1117 error!("Unable to load ReadoutBoards from db! {err}");
1118 return None;
1119 }
1120 Ok(rbs) => {
1121 return Some(rbs);
1122 }
1123 }
1124 }
1125}
1126
1127impl fmt::Display for DBReadoutBoard {
1128 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1129 let mut repr = String::from("<ReadoutBoard:");
1130 repr += &(format!("\n Board id : {}",self.rb_id));
1131 repr += &(format!("\n MTB Link ID : {}",self.mtb_link_id));
1132 repr += &(format!("\n DSI/J : {}/{}",self.dsi,self.j));
1133 repr += "\n **Connected paddles**";
1134 repr += &(format!("\n Ch0/1(1/2) : {}", self.paddle12_id.unwrap_or(-1)));
1135 repr += &(format!("\n Ch1/2(2/3) : {}", self.paddle34_id.unwrap_or(-1)));
1136 repr += &(format!("\n Ch2/3(3/4) : {}", self.paddle56_id.unwrap_or(-1)));
1137 repr += &(format!("\n Ch3/4(4/5) : {}>",self.paddle78_id.unwrap_or(-1)));
1138 write!(f, "{}", repr)
1139 }
1140}
1141
1142#[derive(Debug, Clone)]
1144#[allow(non_snake_case)]
1145pub struct ReadoutBoard {
1146 pub rb_id : u8,
1147 pub dsi : u8,
1148 pub j : u8,
1149 pub mtb_link_id : u8,
1150 pub paddle12 : Paddle,
1151 pub paddle12_chA : u8,
1152 pub paddle34 : Paddle,
1153 pub paddle34_chA : u8,
1154 pub paddle56 : Paddle,
1155 pub paddle56_chA : u8,
1156 pub paddle78 : Paddle,
1157 pub paddle78_chA : u8,
1158 pub calib_file_path : String,
1161 pub calibration : RBCalibrations,
1162}
1163
1164impl ReadoutBoard {
1165
1166 pub fn new() -> Self {
1167 Self {
1168 rb_id : 0,
1169 dsi : 0,
1170 j : 0,
1171 mtb_link_id : 0,
1172 paddle12 : Paddle::new(),
1173 paddle12_chA : 0,
1174 paddle34 : Paddle::new(),
1175 paddle34_chA : 0,
1176 paddle56 : Paddle::new(),
1177 paddle56_chA : 0,
1178 paddle78 : Paddle::new(),
1179 paddle78_chA : 0,
1180 calib_file_path : String::from(""),
1181 calibration : RBCalibrations::new(0),
1182 }
1183 }
1184
1185 pub fn guess_address(&self) -> String {
1189 format!("tcp://10.0.1.1{:02}:42000", self.rb_id)
1190 }
1191
1192 pub fn get_paddle_ids(&self) -> [u8;4] {
1193 let pid0 = self.paddle12.paddle_id as u8;
1194 let pid1 = self.paddle34.paddle_id as u8;
1195 let pid2 = self.paddle56.paddle_id as u8;
1196 let pid3 = self.paddle78.paddle_id as u8;
1197 [pid0, pid1, pid2, pid3]
1198 }
1199
1200 #[allow(non_snake_case)]
1201 pub fn get_A_sides(&self) -> [u8;4] {
1202 let pa_0 = self.paddle12_chA;
1203 let pa_1 = self.paddle34_chA;
1204 let pa_2 = self.paddle56_chA;
1205 let pa_3 = self.paddle78_chA;
1206 [pa_0, pa_1, pa_2, pa_3]
1207 }
1208
1209 #[allow(non_snake_case)]
1210 pub fn get_pid_rbchA(&self, pid : u8) -> Option<u8> {
1211 if self.paddle12.paddle_id as u8 == pid {
1212 let rv = self.paddle12.rb_chA as u8;
1213 return Some(rv);
1214 } else if self.paddle34.paddle_id as u8 == pid {
1215 let rv = self.paddle34.rb_chA as u8;
1216 return Some(rv);
1217 } else if self.paddle56.paddle_id as u8 == pid {
1218 let rv = self.paddle56.rb_chA as u8;
1219 return Some(rv);
1220 } else if self.paddle78.paddle_id as u8== pid {
1221 let rv = self.paddle78.rb_chA as u8;
1222 return Some(rv);
1223 } else {
1224 return None;
1225 }
1226 }
1227
1228 #[allow(non_snake_case)]
1229 pub fn get_pid_rbchB(&self, pid : u8) -> Option<u8> {
1230 if self.paddle12.paddle_id as u8 == pid {
1231 let rv = self.paddle12.rb_chB as u8;
1232 return Some(rv);
1233 } else if self.paddle34.paddle_id as u8== pid {
1234 let rv = self.paddle34.rb_chB as u8;
1235 return Some(rv);
1236 } else if self.paddle56.paddle_id as u8== pid {
1237 let rv = self.paddle56.rb_chB as u8;
1238 return Some(rv);
1239 } else if self.paddle78.paddle_id as u8 == pid {
1240 let rv = self.paddle78.rb_chB as u8;
1241 return Some(rv);
1242 } else {
1243 return None;
1244 }
1245 }
1246
1247 pub fn get_paddle_length(&self, pid : u8) -> Option<f32> {
1248 if self.paddle12.paddle_id as u8 == pid {
1249 let rv = self.paddle12.length;
1250 return Some(rv);
1251 } else if self.paddle34.paddle_id as u8== pid {
1252 let rv = self.paddle34.length;
1253 return Some(rv);
1254 } else if self.paddle56.paddle_id as u8== pid {
1255 let rv = self.paddle56.length;
1256 return Some(rv);
1257 } else if self.paddle78.paddle_id as u8 == pid {
1258 let rv = self.paddle78.length;
1259 return Some(rv);
1260 } else {
1261 return None;
1262 }
1263 }
1264
1265 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<ReadoutBoard>> {
1266 use schema::tof_db_readoutboard::dsl::*;
1267 let db_rbs : Vec<DBReadoutBoard>;
1268 match tof_db_readoutboard
1269 .load::<DBReadoutBoard>(conn) {
1271 Err(err) => {
1272 error!("Unable to load ReadoutBoards from db! {err}");
1273 return None;
1274 }
1275 Ok(rbs) => {
1276 db_rbs = rbs;
1277 }
1278 }
1279 let paddles_op = Paddle::all(conn);
1280 match paddles_op {
1281 None => {
1282 return None;
1283 }
1284 Some(_) => ()
1285 }
1286 let paddles = paddles_op.unwrap();
1287 let mut rbs = Vec::<ReadoutBoard>::new();
1290 for dbrb in db_rbs {
1292 let mut rb = ReadoutBoard::new();
1293 rb.rb_id = dbrb.rb_id as u8;
1294 rb.dsi = dbrb.dsi as u8;
1295 rb.j = dbrb.j as u8;
1296 rb.mtb_link_id = dbrb.mtb_link_id as u8;
1297 rb.paddle12_chA = dbrb.paddle12_chA.unwrap() as u8;
1298 rb.paddle34_chA = dbrb.paddle34_chA.unwrap() as u8;
1299 rb.paddle56_chA = dbrb.paddle56_chA.unwrap() as u8;
1300 rb.paddle78_chA = dbrb.paddle78_chA.unwrap() as u8;
1301 for pdl in paddles.iter() {
1302 if pdl.paddle_id == dbrb.paddle12_id.unwrap_or(0) {
1309 rb.paddle12 = pdl.clone();
1310 }
1311 if pdl.paddle_id == dbrb.paddle34_id.unwrap_or(0) {
1312 rb.paddle34 = pdl.clone();
1313 }
1314 if pdl.paddle_id == dbrb.paddle56_id.unwrap_or(0) {
1315 rb.paddle56 = pdl.clone();
1316 }
1317 if pdl.paddle_id == dbrb.paddle78_id.unwrap_or(0) {
1318 rb.paddle78 = pdl.clone();
1319 }
1320 }
1321 rbs.push(rb);
1322 }
1323 Some(rbs)
1324 }
1325
1326 pub fn where_rbid(conn: &mut SqliteConnection, rb_id : u8) -> Option<ReadoutBoard> {
1328 let all = ReadoutBoard::all(conn)?;
1329 for rb in all {
1330 if rb.rb_id == rb_id {
1331 return Some(rb);
1332 }
1333 }
1334 None
1335 }
1336
1337 pub fn to_summary_str(&self) -> String {
1338 let mut repr = String::from("<ReadoutBoard:");
1339 repr += &(format!("\n Board id : {}",self.rb_id));
1340 repr += &(format!("\n MTB Link ID : {}",self.mtb_link_id));
1341 repr += &(format!("\n RAT : {}",self.paddle12.ltb_id));
1342 repr += &(format!("\n DSI/J : {}/{}",self.dsi,self.j));
1343 repr += "\n **Connected paddles**";
1344 repr += &(format!("\n Channel 1/2 : {:02} (panel {:01})", self.paddle12.paddle_id, self.paddle12.panel_id));
1345 repr += &(format!("\n Channel 3/4 : {:02} (panel {:01})", self.paddle34.paddle_id, self.paddle34.panel_id));
1346 repr += &(format!("\n Channel 5/6 : {:02} (panel {:01})", self.paddle56.paddle_id, self.paddle56.panel_id));
1347 repr += &(format!("\n Channel 7/8 : {:02} (panel {:01})", self.paddle78.paddle_id, self.paddle78.panel_id));
1348 repr
1349 }
1350
1351 pub fn load_latest_calibration(&mut self) -> Result<(), Box<dyn std::error::Error>> {
1353 let re = Regex::new(r"(\d{6}_\d{6})")?;
1356 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);
1363
1364 let mut filename : String;
1366 for entry in glob(&pattern)? {
1367 if let Ok(path) = entry {
1368 match path.file_name() {
1371 None => continue,
1372 Some(fname) => {
1373 filename = fname.to_os_string().into_string().expect("Unwrapping filename failed!");
1375 }
1376 }
1377 if let Some(caps) = re.captures(&filename) {
1378 if let Some(timestamp_str) = caps.get(0).map(|m| m.as_str()) {
1379 let footzstring = format!("{}+0000", timestamp_str);
1383 let timestamp = DateTime::parse_from_str(&footzstring, "%y%m%d_%H%M%S%z")?;
1384 if timestamp > newest_file.1 {
1388 newest_file.1 = timestamp.into();
1390 newest_file.0 = filename.clone();
1391 }
1392 }
1393 }
1394 }
1395 }
1396
1397 if newest_file.0.is_empty() {
1398 error!("No matching calibration available for board {}!", self.rb_id);
1399 } else {
1400 let file_to_load = format!("{}/{}", self.calib_file_path, newest_file.0);
1401 info!("Loading calibration from file: {}", file_to_load);
1402 self.calibration = RBCalibrations::from_file(file_to_load, true)?;
1403 }
1404 Ok(())
1405 }
1406}
1407
1408impl fmt::Display for ReadoutBoard {
1409 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1410 let mut repr = String::from("<ReadoutBoard:");
1411 repr += &(format!("\n Board id : {}",self.rb_id));
1412 repr += &(format!("\n MTB Link ID : {}",self.mtb_link_id));
1413 repr += &(format!("\n DSI/J : {}/{}",self.dsi,self.j));
1414 repr += "\n **Connected paddles**";
1415 repr += &(format!("\n Ch0/1(1/2) : {}",self.paddle12));
1416 repr += &(format!("\n A-side : {}", self.paddle12_chA));
1417 repr += &(format!("\n Ch1/2(2/3) : {}",self.paddle34));
1418 repr += &(format!("\n A-side : {}", self.paddle34_chA));
1419 repr += &(format!("\n Ch2/3(3/4) : {}",self.paddle56));
1420 repr += &(format!("\n A-side : {}", self.paddle56_chA));
1421 repr += &(format!("\n Ch3/4(4/5) : {}>",self.paddle78));
1422 repr += &(format!("\n A-side : {}", self.paddle78_chA));
1423 repr += "** calibration will be loaded from this path:";
1424 repr += &(format!("\n \u{021B3} {}", self.calib_file_path));
1425 repr += &(format!("\n calibration : {}>", self.calibration));
1426 write!(f, "{}", repr)
1427 }
1428}
1429
1430
1431#[derive(Debug, Clone,Queryable, Selectable)]
1435#[diesel(table_name = schema::tof_db_panel)]
1436#[diesel(primary_key(panel_id))]
1437pub struct DBPanel {
1438 pub panel_id : i16 ,
1440 pub description : String ,
1441 pub normal_x : i16 ,
1442 pub normal_y : i16 ,
1443 pub normal_z : i16 ,
1444 pub dw_paddle : Option<i16>,
1445 pub dh_paddle : Option<i16>,
1446 pub paddle0_id : Option<i16>,
1447 pub paddle1_id : Option<i16>,
1448 pub paddle10_id : Option<i16>,
1449 pub paddle11_id : Option<i16>,
1450 pub paddle2_id : Option<i16>,
1451 pub paddle3_id : Option<i16>,
1452 pub paddle4_id : Option<i16>,
1453 pub paddle5_id : Option<i16>,
1454 pub paddle6_id : Option<i16>,
1455 pub paddle7_id : Option<i16>,
1456 pub paddle8_id : Option<i16>,
1457 pub paddle9_id : Option<i16>,
1458}
1459
1460impl DBPanel {
1461
1462 pub fn valid(&self) -> bool {
1463 self.panel_id > 0 &&
1464 self.description != String::from("") &&
1465 self.paddle0_id.is_some()
1466 }
1467
1468 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<DBPanel>> {
1469 use schema::tof_db_panel::dsl::*;
1470 match tof_db_panel
1471 .load::<DBPanel>(conn) {
1473 Err(err) => {
1474 error!("Unable to load Panels from db! {err}");
1475 return None;
1476 }
1477 Ok(pnls) => {
1479 return Some(pnls);
1480 }
1481 }
1482 }
1483
1484 pub fn get_npaddles(&self) -> u8 {
1485 let mut npaddles = 0u8;
1486 if self.paddle0_id.is_some() {
1487 npaddles += 1;
1488 }
1489 if self.paddle1_id.is_some() {
1490 npaddles += 1;
1491 }
1492 if self.paddle2_id.is_some() {
1493 npaddles += 1;
1494 }
1495 if self.paddle3_id.is_some() {
1496 npaddles += 1;
1497 }
1498 if self.paddle4_id.is_some() {
1499 npaddles += 1;
1500 }
1501 if self.paddle5_id.is_some() {
1502 npaddles += 1;
1503 }
1504 if self.paddle6_id.is_some() {
1505 npaddles += 1;
1506 }
1507 if self.paddle7_id.is_some() {
1508 npaddles += 1;
1509 }
1510 if self.paddle8_id.is_some() {
1511 npaddles += 1;
1512 }
1513 if self.paddle9_id.is_some() {
1514 npaddles += 1;
1515 }
1516 if self.paddle10_id.is_some() {
1517 npaddles += 1;
1518 }
1519 if self.paddle11_id.is_some() {
1520 npaddles += 1;
1521 }
1522 npaddles
1523 }
1524}
1525
1526impl fmt::Display for DBPanel {
1527 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1528 let mut repr = String::from("<DBPanel");
1529 repr += &(format!("\n id : {}",self.panel_id));
1530 repr += &(format!("\n descr : {}",self.description));
1531 repr += "\n orientation:";
1532 repr += &(format!("\n [{},{},{}]", self.normal_x, self.normal_y, self.normal_z));
1533 repr += &(format!("\n paddle list ({}) paddles)", self.get_npaddles()));
1534 if self.paddle0_id.is_some() {
1535 repr += &(format!("\n {}",self.paddle0_id.unwrap()));
1536 }
1537 if self.paddle1_id.is_some() {
1538 repr += &(format!("\n {}",self.paddle1_id.unwrap()));
1539 }
1540 if self.paddle2_id.is_some() {
1541 repr += &(format!("\n {}",self.paddle2_id.unwrap()));
1542 }
1543 if self.paddle3_id.is_some() {
1544 repr += &(format!("\n {}",self.paddle3_id.unwrap()));
1545 }
1546 if self.paddle4_id.is_some() {
1547 repr += &(format!("\n {}",self.paddle4_id.unwrap()));
1548 }
1549 if self.paddle5_id.is_some() {
1550 repr += &(format!("\n {}",self.paddle5_id.unwrap()));
1551 }
1552 if self.paddle6_id.is_some() {
1553 repr += &(format!("\n {}",self.paddle6_id.unwrap()));
1554 }
1555 if self.paddle7_id.is_some() {
1556 repr += &(format!("\n {}",self.paddle7_id.unwrap()));
1557 }
1558 if self.paddle8_id.is_some() {
1559 repr += &(format!("\n {}",self.paddle8_id.unwrap()));
1560 }
1561 if self.paddle9_id.is_some() {
1562 repr += &(format!("\n {}",self.paddle9_id.unwrap()));
1563 }
1564 if self.paddle10_id.is_some() {
1565 repr += &(format!("\n {}",self.paddle10_id.unwrap()));
1566 }
1567 if self.paddle11_id.is_some() {
1568 repr += &(format!("\n {}",self.paddle11_id.unwrap()));
1569 }
1570 repr += ">";
1571 write!(f, "{}", repr)
1572 }
1573}
1574
1575pub struct Panel {
1576 pub panel_id : u8 ,
1577 pub description : String ,
1578 pub normal_x : u8 ,
1579 pub normal_y : u8 ,
1580 pub normal_z : u8 ,
1581 pub paddle0 : Paddle,
1582 pub paddle1 : Option<Paddle>,
1583 pub paddle2 : Option<Paddle>,
1584 pub paddle3 : Option<Paddle>,
1585 pub paddle4 : Option<Paddle>,
1586 pub paddle5 : Option<Paddle>,
1587 pub paddle6 : Option<Paddle>,
1588 pub paddle7 : Option<Paddle>,
1589 pub paddle8 : Option<Paddle>,
1590 pub paddle9 : Option<Paddle>,
1591 pub paddle10 : Option<Paddle>,
1592 pub paddle11 : Option<Paddle>,
1593 }
1599
1600impl Panel {
1601
1602 pub fn new() -> Self {
1603 Self {
1604 panel_id : 0 ,
1605 description : String::from(""),
1606 normal_x : 0 ,
1607 normal_y : 0 ,
1608 normal_z : 0 ,
1609 paddle0 : Paddle::new(),
1610 paddle1 : None,
1611 paddle2 : None,
1612 paddle3 : None,
1613 paddle4 : None,
1614 paddle5 : None,
1615 paddle6 : None,
1616 paddle7 : None,
1617 paddle8 : None,
1618 paddle9 : None,
1619 paddle10 : None,
1620 paddle11 : None,
1621 }
1622 }
1623
1624
1625 pub fn get_npaddles(&self) -> u8 {
1626 let mut npaddles = 1u8;
1627 if self.paddle1.is_some() {
1628 npaddles += 1;
1629 }
1630 if self.paddle2.is_some() {
1631 npaddles += 1;
1632 }
1633 if self.paddle3.is_some() {
1634 npaddles += 1;
1635 }
1636 if self.paddle4.is_some() {
1637 npaddles += 1;
1638 }
1639 if self.paddle5.is_some() {
1640 npaddles += 1;
1641 }
1642 if self.paddle6.is_some() {
1643 npaddles += 1;
1644 }
1645 if self.paddle7.is_some() {
1646 npaddles += 1;
1647 }
1648 if self.paddle8.is_some() {
1649 npaddles += 1;
1650 }
1651 if self.paddle9.is_some() {
1652 npaddles += 1;
1653 }
1654 if self.paddle10.is_some() {
1655 npaddles += 1;
1656 }
1657 if self.paddle11.is_some() {
1658 npaddles += 1;
1659 }
1660 npaddles
1661 }
1662
1663 pub fn all(conn: &mut SqliteConnection) -> Option<Vec<Panel>> {
1664 use schema::tof_db_panel::dsl::*;
1665 let db_panels : Vec<DBPanel>;
1666 match tof_db_panel
1667 .load::<DBPanel>(conn) {
1669 Err(err) => {
1670 error!("Unable to load Panels from db! {err}");
1671 return None;
1672 }
1673 Ok(pnls) => {
1674 db_panels = pnls;
1675 }
1676 }
1677 let paddles_op = Paddle::all(conn);
1678 match paddles_op {
1679 None => {
1680 return None;
1681 }
1682 Some(_) => ()
1683 }
1684 let paddles = paddles_op.unwrap();
1685 let mut panels = Vec::<Panel>::new();
1688 println!("Iterating over {} panels in the DB!", db_panels.len());
1689 for dbpanel in db_panels {
1690 let mut pnl = Panel::new();
1691 for pdl in paddles.iter() {
1692 if !dbpanel.valid() {
1695 error!("Got unpopulated Panel from DB for Panel {}", dbpanel);
1696 continue;
1697 }
1698 if pdl.paddle_id == dbpanel.paddle0_id.unwrap() {
1699 pnl.panel_id = dbpanel.panel_id as u8;
1700 pnl.description = dbpanel.description.clone();
1701 pnl.normal_x = dbpanel.normal_x as u8;
1702 pnl.normal_y = dbpanel.normal_y as u8;
1703 pnl.normal_z = dbpanel.normal_z as u8;
1704 pnl.paddle0 = pdl.clone();
1705 }
1706 if pdl.paddle_id == dbpanel.paddle1_id.unwrap() {
1707 pnl.paddle1 = Some(pdl.clone());
1708 }
1709 if pdl.paddle_id == dbpanel.paddle2_id.unwrap() {
1710 pnl.paddle2 = Some(pdl.clone());
1711 }
1712 if pdl.paddle_id == dbpanel.paddle3_id.unwrap() {
1713 pnl.paddle3 = Some(pdl.clone());
1714 }
1715 if pdl.paddle_id == dbpanel.paddle4_id.unwrap() {
1716 pnl.paddle4 = Some(pdl.clone());
1717 }
1718 if pdl.paddle_id == dbpanel.paddle5_id.unwrap() {
1719 pnl.paddle5 = Some(pdl.clone());
1720 }
1721 if pdl.paddle_id == dbpanel.paddle6_id.unwrap() {
1722 pnl.paddle6 = Some(pdl.clone());
1723 }
1724 if pdl.paddle_id == dbpanel.paddle7_id.unwrap() {
1725 pnl.paddle7 = Some(pdl.clone());
1726 }
1727 if pdl.paddle_id == dbpanel.paddle8_id.unwrap() {
1728 pnl.paddle8 = Some(pdl.clone());
1729 }
1730 if pdl.paddle_id == dbpanel.paddle9_id.unwrap() {
1731 pnl.paddle9 = Some(pdl.clone());
1732 }
1733 if pdl.paddle_id == dbpanel.paddle10_id.unwrap() {
1734 pnl.paddle10 = Some(pdl.clone());
1735 }
1736 if pdl.paddle_id == dbpanel.paddle11_id.unwrap() {
1737 pnl.paddle11 = Some(pdl.clone());
1738 }
1739 }
1740 panels.push(pnl);
1741 }
1742 Some(panels)
1743 }
1744}
1745
1746impl fmt::Display for Panel {
1747 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1748 let mut repr = String::from("<Panel");
1749 repr += &(format!("\n id : {}",self.panel_id));
1750 repr += &(format!("\n descr : {}",self.description));
1751 repr += "\n orientation:";
1752 repr += &(format!("\n [{},{},{}]", self.normal_x, self.normal_y, self.normal_z));
1753 repr += &(format!("\n paddle list ({}) paddles)", self.get_npaddles()));
1754 repr += &(format!("\n {}",self.paddle0));
1755 if self.paddle1.is_some() {
1756 repr += &(format!("\n {}",self.paddle1.as_ref().unwrap()));
1757 }
1758 if self.paddle2.is_some() {
1759 repr += &(format!("\n {}",self.paddle2.as_ref().unwrap()));
1760 }
1761 if self.paddle3.is_some() {
1762 repr += &(format!("\n {}",self.paddle3.as_ref().unwrap()));
1763 }
1764 if self.paddle4.is_some() {
1765 repr += &(format!("\n {}",self.paddle4.as_ref().unwrap()));
1766 }
1767 if self.paddle5.is_some() {
1768 repr += &(format!("\n {}",self.paddle5.as_ref().unwrap()));
1769 }
1770 if self.paddle6.is_some() {
1771 repr += &(format!("\n {}",self.paddle6.as_ref().unwrap()));
1772 }
1773 if self.paddle7.is_some() {
1774 repr += &(format!("\n {}",self.paddle7.as_ref().unwrap()));
1775 }
1776 if self.paddle8.is_some() {
1777 repr += &(format!("\n {}",self.paddle8.as_ref().unwrap()));
1778 }
1779 if self.paddle9.is_some() {
1780 repr += &(format!("\n {}",self.paddle9.as_ref().unwrap()));
1781 }
1782 if self.paddle10.is_some() {
1783 repr += &(format!("\n {}",self.paddle10.as_ref().unwrap()));
1784 }
1785 if self.paddle11.is_some() {
1786 repr += &(format!("\n {}",self.paddle11.as_ref().unwrap()));
1787 }
1788 repr += ">";
1789 write!(f, "{}", repr)
1790 }
1791}
1792
1793
1794
1795