1use std::collections::{
7 HashMap,
8 VecDeque,
9};
10use std::sync::{
11 Arc,
12 Mutex,
13};
14
15use crossbeam_channel::{
16 Receiver,
17 };
19
20use crate::WaveformCache;
21
22use ratatui::prelude::*;
23use ratatui::symbols::Marker;
24
25use ratatui::Frame;
26use ratatui::layout::Rect;
27use ratatui::widgets::{
28 Block,
29 BorderType,
30 Borders,
31 Paragraph,
32 List,
33 ListItem,
34 ListState,
35 canvas::{
36 Canvas,
37 Points},
40};
41
42use ndhistogram::{
43 ndhistogram,
44 Histogram,
45 Hist1D,
46};
47use ndhistogram::axis::{
48 Uniform,
49};
50
51use gondola_core::prelude::*;
52
53use crate::colors::ColorTheme;
54use crate::menu::{
55 PaddleMenu,
56 UIMenu,
57 UIMenuItem
58};
59
60use crate::widgets::{
61 prep_data,
62 create_labels,
63 histogram,
64 timeseries,
65};
66
67#[derive(Debug, Clone)]
68pub struct PaddleTab<'a> {
69 pub theme : ColorTheme,
70 pub te_receiver : Receiver<TofEvent>,
71 pub event_queue : VecDeque<TofEvent>,
72 pub wf_cache : Box<WaveformCache>,
74 pub queue_size : usize,
75 pub menu : PaddleMenu<'a>,
76 pub wf : HashMap<u8, RBWaveform>,
77 pub last_wf_ch_a : HashMap<u8, VecDeque<(f64, f64)>>,
78 pub last_wf_ch_b : HashMap<u8, VecDeque<(f64, f64)>>,
79 pub wf_label_a : String,
80 pub wf_label_b : String,
81 pub calibrations : HashMap<u8, RBCalibrations>,
83 pub baseline_ch_a : HashMap<u8, Hist1D<Uniform<f32>>>,
84 pub baseline_ch_b : HashMap<u8, Hist1D<Uniform<f32>>>,
85 pub baseline_rms_ch_a : HashMap<u8, Hist1D<Uniform<f32>>>,
86 pub baseline_rms_ch_b : HashMap<u8, Hist1D<Uniform<f32>>>,
87
88 pub h_edep : HashMap<u8, Hist1D<Uniform<f32>>>,
90 pub h_rel_pos : HashMap<u8, Hist1D<Uniform<f32>>>,
91
92 pub pca_histo : HashMap<u8, Hist1D<Uniform<f32>>>,
93 pub pcb_histo : HashMap<u8, Hist1D<Uniform<f32>>>,
94 pub pha_histo : HashMap<u8, Hist1D<Uniform<f32>>>,
95 pub phb_histo : HashMap<u8, Hist1D<Uniform<f32>>>,
96 pub pta_histo : HashMap<u8, Hist1D<Uniform<f32>>>,
97 pub ptb_histo : HashMap<u8, Hist1D<Uniform<f32>>>,
98
99 pub charge_a : HashMap<u8, VecDeque<f64>>,
101 pub charge_b : HashMap<u8, VecDeque<f64>>,
102
103 pub all_paddles : HashMap<u8, TofPaddle>,
105 pub pdl_state : ListState,
106 pub current_paddle : TofPaddle,
108 pub pdl_items : Vec::<ListItem<'a>>,
109 pub pdl_active : bool,
110 pub pdl_selector : usize,
111 pub pdl_changed : bool,
112 pub rb_ch_map : RbChPidMapping,
113 pub last_hit : String,
114}
115
116impl PaddleTab<'_> {
117 pub fn new(te_receiver : Receiver<TofEvent>,
118 wf_cache : Box<WaveformCache>,
120 all_paddles : HashMap<u8, TofPaddle>,
121 calibrations: Arc<Mutex<HashMap<u8, RBCalibrations>>>,
122 theme : ColorTheme) -> Self {
123 let theme_c = theme.clone();
124 let mut pd_select_items = Vec::<ListItem>::new();
125 for k in 1..161 {
126 let this_item = format!(" Paddle{:0>3}", k);
127 pd_select_items.push(ListItem::new(Line::from(this_item)));
128 }
129 let mut calibrations_cloned = HashMap::<u8, RBCalibrations>::new();
131 match calibrations.lock() {
132 Err(_err) => error!("Unable to get lock on rbcalibrations!"),
133 Ok(cali) => {
134 calibrations_cloned = cali.clone();
135 }
136 }
137 let mut charge_a = HashMap::<u8, VecDeque<f64>>::new();
138 let mut charge_b = HashMap::<u8, VecDeque<f64>>::new();
139 let mut wf = HashMap::<u8, RBWaveform>::new();
140 let mut bl_ch_a = HashMap::<u8, Hist1D<Uniform<f32>>>::new();
141 let mut bl_ch_b = HashMap::<u8, Hist1D<Uniform<f32>>>::new();
142 let mut blrms_ch_a = HashMap::<u8, Hist1D<Uniform<f32>>>::new();
143 let mut blrms_ch_b = HashMap::<u8, Hist1D<Uniform<f32>>>::new();
144 let mut h_edep_ = HashMap::<u8, Hist1D<Uniform<f32>>>::new();
145 let mut h_rel_pos_ = HashMap::<u8, Hist1D<Uniform<f32>>>::new();
146 let mut pca_histo = HashMap::<u8, Hist1D<Uniform<f32>>>::new();
147 let mut pcb_histo = HashMap::<u8, Hist1D<Uniform<f32>>>::new();
148 let mut pha_histo = HashMap::<u8, Hist1D<Uniform<f32>>>::new();
149 let mut phb_histo = HashMap::<u8, Hist1D<Uniform<f32>>>::new();
150 let mut pta_histo = HashMap::<u8, Hist1D<Uniform<f32>>>::new();
151 let mut ptb_histo = HashMap::<u8, Hist1D<Uniform<f32>>>::new();
152 let bins_bl = Uniform::new(20, -2.0, 2.0).unwrap();
153 let bins_bl_rms = Uniform::new(20, 0.0, 2.0).unwrap();
154 let bins_edep = Uniform::new(50, 0.0, 25.0).unwrap();
155 let bins_relpos = Uniform::new(50, 0.0, 1.2).unwrap();
156 let bins_ph = Uniform::new(50, 0.0, 200.0).unwrap();
157 let bins_pt = Uniform::new(50, 25.0, 350.0).unwrap();
158 let bins_pc = Uniform::new(30, 0.0, 40.0).unwrap();
159 let mut lwf_ch_a = HashMap::<u8, VecDeque<(f64, f64)>>::new();
160 let mut lwf_ch_b = HashMap::<u8, VecDeque<(f64, f64)>>::new();
161 for pid in 1..161 {
162 charge_a.insert(pid, VecDeque::<f64>::new());
163 charge_b.insert(pid, VecDeque::<f64>::new());
164 wf.insert(pid, RBWaveform::new());
166 bl_ch_a.insert(pid, ndhistogram!(bins_bl.clone()));
167 bl_ch_b.insert(pid, ndhistogram!(bins_bl.clone()));
168 blrms_ch_a.insert(pid, ndhistogram!(bins_bl_rms.clone()));
169 blrms_ch_b.insert(pid, ndhistogram!(bins_bl_rms.clone()));
170 h_edep_.insert(pid, ndhistogram!(bins_edep.clone()));
171 h_rel_pos_.insert(pid, ndhistogram!(bins_relpos.clone()));
172 pca_histo.insert(pid, ndhistogram!(bins_pc .clone()));
173 pcb_histo.insert(pid, ndhistogram!(bins_pc .clone()));
174 pha_histo.insert(pid, ndhistogram!(bins_ph .clone()));
175 phb_histo.insert(pid, ndhistogram!(bins_ph .clone()));
176 pta_histo.insert(pid, ndhistogram!(bins_pt .clone()));
177 ptb_histo.insert(pid, ndhistogram!(bins_pt .clone()));
178 lwf_ch_a.insert(pid, VecDeque::<(f64,f64)>::new());
179 lwf_ch_b.insert(pid, VecDeque::<(f64,f64)>::new());
180 }
181 let rb_ch_map = get_rb_ch_pid().unwrap();
182 Self {
183 theme,
184 te_receiver,
185 wf_cache,
186 event_queue : VecDeque::<TofEvent>::new(),
187 queue_size : 10000, menu : PaddleMenu::new(theme_c),
190 wf : wf,
191 wf_label_a : String::from("A"),
192 wf_label_b : String::from("B"),
193 last_wf_ch_a : lwf_ch_a,
194 last_wf_ch_b : lwf_ch_b,
195 calibrations : calibrations_cloned,
196 baseline_ch_a : bl_ch_a,
197 baseline_ch_b : bl_ch_b,
198 baseline_rms_ch_a : blrms_ch_a,
199 baseline_rms_ch_b : blrms_ch_b,
200 h_edep : h_edep_,
201 h_rel_pos : h_rel_pos_,
202 pca_histo,
203 pcb_histo,
204 pha_histo,
205 phb_histo,
206 pta_histo,
207 ptb_histo,
208 charge_a ,
209 charge_b ,
210 all_paddles,
211 pdl_items : pd_select_items,
212 pdl_state : ListState::default(),
213 current_paddle : TofPaddle::new(),
214 pdl_active : false,
215 pdl_selector : 1,
216 pdl_changed : false,
217 rb_ch_map : rb_ch_map,
218 last_hit : String::from(""),
219 }
220 }
221
222 pub fn next_pd(&mut self) {
223 let i = match self.pdl_state.selected() {
224 Some(i) => {
225 if i >= self.pdl_items.len() - 1 {
226 self.pdl_items.len() - 1
227 } else {
228 i + 1
229 }
230 }
231 None => 0,
232 };
233 self.pdl_state.select(Some(i));
234 }
235
236 pub fn prev_pd(&mut self) {
237 let i = match self.pdl_state.selected() {
238 Some(i) => {
239 if i == 0 {
240 0
241 } else {
242 i - 1
243 }
244 }
245 None => 0,
246 };
247 self.pdl_state.select(Some(i));
248 }
249
250 pub fn unselect_pdl(&mut self) {
251 self.pdl_state.select(None);
252 }
253
254 pub fn receive_packet(&mut self) -> Result<(), SerializationError> {
255 match self.te_receiver.try_recv() {
256 Err(_err) => {
257 return Ok(());
258 },
259 Ok(mut ev) => {
260 ev.set_paddles(&self.all_paddles);
263 ev.normalize_hit_times();
264 for h in &mut ev.hits {
265 if h.paddle_id == self.current_paddle.paddle_id as u8 {
266 self.last_hit = format!("{}", h);
267 }
268 self.h_edep.get_mut(&(h.paddle_id as u8)).unwrap().fill(&h.get_edep());
269 h.set_paddle(&self.current_paddle);
270 let rel_pos = h.get_pos()/(self.current_paddle.length*10.0);
271 self.h_rel_pos.get_mut(&h.paddle_id).unwrap().fill(&rel_pos);
272 self.pha_histo.get_mut(&h.paddle_id).unwrap().fill(&h.get_peak_a());
273 self.phb_histo.get_mut(&h.paddle_id).unwrap().fill(&h.get_peak_b());
274 self.pca_histo.get_mut(&h.paddle_id).unwrap().fill(&h.get_charge_a());
275 self.pcb_histo.get_mut(&h.paddle_id).unwrap().fill(&h.get_charge_b());
276 self.pta_histo.get_mut(&h.paddle_id).unwrap().fill(&h.get_time_a());
277 self.ptb_histo.get_mut(&h.paddle_id).unwrap().fill(&h.get_time_a());
278
279 self.charge_a.get_mut(&(h.paddle_id as u8)).unwrap().push_back(h.get_charge_a() as f64);
280 self.charge_b.get_mut(&(h.paddle_id as u8)).unwrap().push_back(h.get_charge_b() as f64);
281 if self.charge_a.get_mut(&(h.paddle_id as u8)).unwrap().len() > self.queue_size {
282 self.charge_a.get_mut(&(h.paddle_id as u8)).unwrap().pop_front();
283 }
284 if self.charge_b.get_mut(&(h.paddle_id as u8)).unwrap().len() > self.queue_size {
285 self.charge_b.get_mut(&(h.paddle_id as u8)).unwrap().pop_front();
286 }
287 let ch_a_bl = h.get_bl_a();
288 let ch_b_bl = h.get_bl_b();
289 if -2.0 < ch_a_bl && ch_b_bl < 2.0 {
293 self.baseline_ch_a.get_mut(&(h.paddle_id as u8)).unwrap().fill(&ch_a_bl);
294 }
295 if -2.0 < ch_b_bl && ch_b_bl < 2.0 {
296 self.baseline_ch_b.get_mut(&(h.paddle_id as u8)).unwrap().fill(&ch_b_bl);
297 }
298 self.baseline_rms_ch_a.get_mut(&(h.paddle_id as u8)).unwrap().fill(&h.get_bl_a_rms());
300 self.baseline_rms_ch_b.get_mut(&(h.paddle_id as u8)).unwrap().fill(&h.get_bl_b_rms());
302 }
303 return Ok(());
304 }
305 }
306 }
307
308 pub fn render(&mut self, main_window : &Rect, frame : &mut Frame) {
310
311 match self.menu.get_active_menu_item() {
312 UIMenuItem::Back => {
313 let main_lo = Layout::default()
315 .direction(Direction::Horizontal)
316 .constraints(
317 [Constraint::Percentage(15), Constraint::Percentage(40), Constraint::Percentage(45)].as_ref(),
318 )
319 .split(*main_window);
320 let pdl = Block::default()
321 .borders(Borders::ALL)
322 .style(self.theme.style())
323 .title("Select Paddle")
324 .border_type(BorderType::Plain);
325 let pd_select_list = List::new(self.pdl_items.clone()).block(pdl)
326 .highlight_style(self.theme.highlight().add_modifier(Modifier::BOLD))
327 .highlight_symbol(">>")
328 .repeat_highlight_symbol(true);
329 match self.pdl_state.selected() {
330 None => {
331 let selector = 1;
332 if self.pdl_selector != selector {
333 self.pdl_changed = true;
334 self.pdl_selector = selector;
335 } else {
336 self.pdl_changed = false;
337 }
338 },
339 Some(_pid) => {
340 let selector = _pid + 1;
341 if self.pdl_selector != selector {
342 self.pdl_changed = true;
343 self.pdl_selector = selector;
344 } else {
345 self.pdl_changed = false;
346 }
347 }
348 }
349 let view_string : String;
350 match self.all_paddles.get(&(self.pdl_selector as u8)) {
351 Some(_pd) => {
352 view_string = format!("{}", _pd);
353 self.current_paddle = _pd.clone();
354 }
355 None => {
356 view_string = format!("No information for Paddle {} in DB or DB not available!", self.pdl_selector);
357 }
358 }
359 let pd_view = Paragraph::new(view_string)
360 .style(self.theme.style())
361 .alignment(Alignment::Left)
362 .block(
364 Block::default()
365 .borders(Borders::ALL)
366 .style(self.theme.style())
367 .title("Paddle")
368 .border_type(BorderType::Rounded),
369 );
370 let hit_view = Paragraph::new(self.last_hit.clone())
371 .style(self.theme.style())
372 .alignment(Alignment::Left)
373 .block(
375 Block::default()
376 .borders(Borders::ALL)
377 .style(self.theme.style())
378 .title("Hits")
379 .border_type(BorderType::Rounded),
380 );
381
382 frame.render_stateful_widget(pd_select_list, main_lo[0], &mut self.pdl_state );
384 frame.render_widget(pd_view, main_lo[1]);
385 frame.render_widget(hit_view, main_lo[2]);
386 }
387 UIMenuItem::Signal => {
388 let main_lo = Layout::default()
389 .direction(Direction::Horizontal)
390 .constraints(
391 [Constraint::Percentage(50),
392 Constraint::Percentage(50)].as_ref(),
393 )
394 .split(*main_window);
395 let wf_lo = Layout::default()
396 .direction(Direction::Vertical)
397 .constraints(
398 [Constraint::Percentage(40),
399 Constraint::Percentage(40),
400 Constraint::Percentage(20)].as_ref(),
401 )
402 .split(main_lo[0]);
403 let ch_lo = Layout::default()
404 .direction(Direction::Vertical)
405 .constraints(
406 [Constraint::Percentage(80),
407 Constraint::Percentage(20)].as_ref(),
408 )
409 .split(main_lo[1]);
410 let bla_lo = Layout::default()
411 .direction(Direction::Horizontal)
412 .constraints(
413 [Constraint::Percentage(50),
414 Constraint::Percentage(50)].as_ref(),
415 )
416 .split(wf_lo[2]);
417 let blb_lo = Layout::default()
418 .direction(Direction::Horizontal)
419 .constraints(
420 [Constraint::Percentage(50),
421 Constraint::Percentage(50)].as_ref(),
422 )
423 .split(ch_lo[1]);
424
425 let wf_theme = self.theme.clone();
428
429 let rb_id = self.current_paddle.rb_id as u8;
433 let ch = self.current_paddle.rb_chA;
434 let pid = self.current_paddle.paddle_id as u8;
435 if pid == 1 {
436 if rb_id != 25 {
437 panic!("Che cazzo fai?!");
438 }
439 }
440 let mut wf = RBWaveform::new();
441 let mut valid = true;
442 if rb_id == 0 || rb_id > 49 {
443 error!("Wrong RB id! {rb_id}");
444 valid = false;
445 }
446 if ch == 0 || ch > 9 {
447 error!("Wrong channel {ch}!");
448 valid = false;
449 }
450 if valid {
451 match self.wf_cache.get(&rb_id).unwrap().get(&(ch as u8)).unwrap().lock() {
452 Err(_) => {
453 error!("Unable to lock waveform cache!");
454 }
455 Ok(mut cache) => {
456 if cache.len() > 0 {
457 wf = cache.pop_front().unwrap();
458 if wf.rb_id != rb_id {
459 error!("{} {} {}", wf.rb_id, rb_id, pid);
460 }
462 } else {
463 error!("Empty waveform cache");
464 valid = false;
465 }
467 }
468 } }
473 if valid {
474 match self.calibrations.get(&wf.rb_id) {
505 None => error!("RBCalibrations for board {} not available!", wf.rb_id),
506 Some(rbcal) => {
507 match wf.calibrate(rbcal) {
508 Err(err) => error!("Calibration error! {err}"),
509 Ok(_) => debug!("Successfully calibrated wf for board {}", &wf.rb_id)
510 }
511 }
512 }
513 let rb_channel_a = wf.rb_channel_a + 1;
525 let rb_channel_b = wf.rb_channel_b + 1;
526 if (rb_channel_a != self.current_paddle.rb_chA as u8 )
527 || (rb_channel_b != self.current_paddle.rb_chB as u8 ) {
528 error!("Inconsistent paddle RB channels! Maybe A and B are switched!");
529 }
530 info!("rb {} A {} B {}", wf.rb_id, wf.rb_channel_a + 1, wf.rb_channel_b + 1);
532 *self.wf.get_mut(&pid).unwrap() = wf;
533 } match self.wf.get_mut(&(self.current_paddle.paddle_id as u8)) {
535 None => {
536 error!("No waveform available for {}", self.current_paddle.paddle_id);
537 }
538 Some(wf) => {
539 let mut wf_data_a = VecDeque::<(f64, f64)>::new();
541 let mut wf_data_b = VecDeque::<(f64, f64)>::new();
542 if wf.voltages_a.len() == 0 {
543 for (i,k) in wf.adc_a.iter().enumerate() {
544 wf_data_a.push_back((i as f64, *k as f64));
545 }
546 } else {
547 for k in 0..wf.nanoseconds_a.len() {
548 wf_data_a.push_back((wf.nanoseconds_a[k] as f64, wf.voltages_a[k] as f64));
549 }
550 }
551 if wf.voltages_b.len() == 0 {
554 for (i,k) in wf.adc_b.iter().enumerate() {
555 wf_data_b.push_back((i as f64, *k as f64));
556 }
557 } else {
558 for k in 0..wf.nanoseconds_b.len() {
559 wf_data_b.push_back((wf.nanoseconds_b[k] as f64, wf.voltages_b[k] as f64));
560 }
561 }
562 let wf_chart_a = timeseries(&mut wf_data_a,
564 self.wf_label_a.clone(),
565 self.wf_label_a.clone(),
566 &wf_theme);
567 let wf_chart_b = timeseries(&mut wf_data_b,
568 self.wf_label_b.clone(),
569 self.wf_label_b.clone(),
570 &wf_theme);
571 frame.render_widget(wf_chart_a, wf_lo[0]);
572 frame.render_widget(wf_chart_b, wf_lo[1]);
573 }
574 }
575
576
577 let mut ch2d_points = Vec::<(f64, f64)>::new();
579 for k in 0..self.charge_a.get(&(self.current_paddle.paddle_id as u8)).unwrap().len() {
580 ch2d_points.push((self.charge_a.get(&(self.current_paddle.paddle_id as u8)).unwrap()[k],
581 self.charge_b.get(&(self.current_paddle.paddle_id as u8)).unwrap()[k]));
582 }
583
584 let charge_plot = Canvas::default()
585 .block(Block::bordered().title("Charge AvsB"))
586 .marker(Marker::Braille)
587 .paint(|ctx| {
588 let points = Points {
603 coords : &ch2d_points.as_slice(),
604 color : self.theme.hc,
605 };
606 ctx.draw(&points);
607 })
610 .x_bounds([0.0, 200.0])
611 .y_bounds([0.0, 200.0]);
612 frame.render_widget(charge_plot, ch_lo[0]);
613
614 let bl_a_labels = create_labels(&self.baseline_ch_a.get(&(self.current_paddle.paddle_id as u8)).unwrap());
617 let bl_a_data = prep_data(&self.baseline_ch_a.get(&(self.current_paddle.paddle_id as u8)).unwrap(), &bl_a_labels, 1, false);
618 let bl_a_chart = histogram(bl_a_data, String::from("Baseline Side A [mV]"), 2, 0, &self.theme);
619 frame.render_widget(bl_a_chart, bla_lo[0]);
620
621 let bl_a_rms_data = prep_data(&self.baseline_rms_ch_a.get(&(self.current_paddle.paddle_id as u8)).unwrap(), &bl_a_labels, 1, false);
622 let bl_a_rms_chart = histogram(bl_a_rms_data, String::from("Baseline RMS Side A [mV]"), 2, 0, &self.theme);
623 frame.render_widget(bl_a_rms_chart, bla_lo[1]);
624
625 let bl_b_data = prep_data(&self.baseline_ch_b.get(&(self.current_paddle.paddle_id as u8)).unwrap(), &bl_a_labels, 1, false);
628 let bl_b_chart = histogram(bl_b_data, String::from("Baseline Side B [mV]"), 2, 0, &self.theme);
629 frame.render_widget(bl_b_chart, blb_lo[0]);
630
631 let bl_b_rms_data = prep_data(&self.baseline_rms_ch_b.get(&(self.current_paddle.paddle_id as u8)).unwrap(), &bl_a_labels, 1, false);
633 let bl_b_rms_chart = histogram(bl_b_rms_data, String::from("Baseline RMS Side B [mV]"), 2, 0, &self.theme);
634 frame.render_widget(bl_b_rms_chart, blb_lo[1]);
635 }
636 UIMenuItem::RecoVars => {
637 let main_lo = Layout::default()
638 .direction(Direction::Horizontal)
639 .constraints(
640 [Constraint::Percentage(60), Constraint::Percentage(40)].as_ref(),
641 )
642 .split(*main_window);
643 let col_left = Layout::default()
644 .direction(Direction::Horizontal)
645 .constraints(
646 [Constraint::Percentage(50), Constraint::Percentage(50)].as_ref(),
647 )
648 .split(main_lo[0]);
649 let rows_right = Layout::default()
650 .direction(Direction::Vertical)
651 .constraints(
652 [Constraint::Percentage(33),
653 Constraint::Percentage(33),
654 Constraint::Percentage(34)].as_ref(),
655 )
656 .split(main_lo[1]);
657 let rows_left_left = Layout::default()
658 .direction(Direction::Vertical)
659 .constraints(
660 [Constraint::Percentage(33),
661 Constraint::Percentage(33),
662 Constraint::Percentage(34)].as_ref(),
663 )
664 .split(col_left[0]);
665 let rows_left_right = Layout::default()
666 .direction(Direction::Vertical)
667 .constraints(
668 [Constraint::Percentage(33),
669 Constraint::Percentage(33),
670 Constraint::Percentage(34)].as_ref(),
671 )
672 .split(col_left[1]);
673
674 let pid = self.current_paddle.paddle_id as u8;
676
677 let ph_labels = create_labels(&self.pha_histo.get(&pid).unwrap());
678 let pha_data = prep_data(&self.pha_histo.get(&pid).unwrap(), &ph_labels, 5, false);
679 let pha_chart = histogram(pha_data, String::from("Pulse height SideA [mV]"), 2, 0, &self.theme);
680 frame.render_widget(pha_chart, rows_left_left[0]);
681 let phb_data = prep_data(&self.phb_histo.get(&pid).unwrap(), &ph_labels, 5, false);
682 let phb_chart = histogram(phb_data, String::from("Pulse height SideB [mV]"), 2, 0, &self.theme);
683 frame.render_widget(phb_chart, rows_left_right[0]);
684
685 let pt_labels = create_labels(&self.pta_histo.get(&pid).unwrap());
686 let pta_data = prep_data(&self.pta_histo.get(&pid).unwrap(), &pt_labels, 5, false);
687 let pta_chart = histogram(pta_data, String::from("Pulse time SideA [a.u.]"), 2, 0, &self.theme);
688 frame.render_widget(pta_chart, rows_left_left[1]);
689
690 let ptb_data = prep_data(&self.ptb_histo.get(&pid).unwrap(), &pt_labels, 5, false);
691 let ptb_chart = histogram(ptb_data, String::from("Pulse time SideB [a.u.]"), 2, 0, &self.theme);
692 frame.render_widget(ptb_chart, rows_left_right[1]);
693
694 let pc_labels = create_labels(&self.pca_histo.get(&pid).unwrap());
695 let pca_data = prep_data(&self.pca_histo.get(&pid).unwrap(), &pc_labels, 5, false);
696 let pca_chart = histogram(pca_data, String::from("Pulse charge SideA [mC]"), 2, 0, &self.theme);
697 frame.render_widget(pca_chart, rows_left_left[2]);
698
699 let pcb_data = prep_data(&self.pcb_histo.get(&pid).unwrap(), &pc_labels, 5, false);
700 let pcb_chart = histogram(pcb_data, String::from("Pulse charge SideB [mC]"), 2, 0, &self.theme);
701 frame.render_widget(pcb_chart, rows_left_right[2]);
702
703 let edep_labels = create_labels(&self.h_edep.get(&(self.current_paddle.paddle_id as u8)).unwrap());
705 let edep_data = prep_data(&self.h_edep.get (&(self.current_paddle.paddle_id as u8)).unwrap(), &edep_labels, 1, false);
706 let edep_chart = histogram(edep_data, String::from("Reco. Energy Deposition [minI]"), 1, 0, &self.theme);
707 frame.render_widget(edep_chart, rows_right[0]);
708 let relpos_labels = create_labels(&self.h_rel_pos.get(&(self.current_paddle.paddle_id as u8)).unwrap());
710 let relpos_data = prep_data(&self.h_rel_pos.get (&(self.current_paddle.paddle_id as u8)).unwrap(), &relpos_labels, 1, false);
711 let relpos_chart = histogram(relpos_data, String::from("Rel. pos. (1 = B side)"), 1, 0, &self.theme);
712 frame.render_widget(relpos_chart, rows_right[1]);
713 }
714 _ => ()
715 } }
717}