1use crate::prelude::*;
5use std::f32::consts::PI;
6
7#[derive(Debug,Copy,Clone,PartialEq)]
11pub struct Peak {
12 pub paddle_end_id : u16,
13 pub time : f32,
14 pub charge : f32,
15 pub height : f32
16}
17
18impl Peak {
19 pub fn new() -> Self {
20 Self {
21 paddle_end_id : 40,
23 time : 0.0,
24 charge : 0.0,
25 height : 0.0,
26 }
27 }
28}
29
30impl Default for Peak {
31 fn default() -> Self {
32 Self::new()
33 }
34}
35
36impl fmt::Display for Peak {
37 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38 write!(f, "<Peak:
39 p_end_id : {:.2}
40 time // charge // height : {:.2} // {:.2} // {:.2}>",
41 self.paddle_end_id,
42 self.time,
43 self.charge,
44 self.height)
45 }
46}
47
48#[derive(Debug,Copy,Clone,PartialEq)]
63#[cfg_attr(feature = "pybindings", pyclass)]
64pub struct TofHit {
65
66 pub paddle_id : u8,
71 pub time_a : f16,
72 pub time_b : f16,
73 pub peak_a : f16,
74 pub peak_b : f16,
75 pub charge_a : f16,
76 pub charge_b : f16,
77 pub version : ProtocolVersion,
78 pub baseline_a : f16,
80 pub baseline_a_rms : f16,
81 pub baseline_b : f16,
82 pub baseline_b_rms : f16,
83 pub phase : f16,
85 pub tot_low_a : f16,
86 pub tot_low_b : f16,
87 pub tot_high_a : f16,
88 pub tot_high_b : f16,
89 pub tot_slp_low_a : f16,
90 pub tot_slp_low_b : f16,
91 pub tot_slp_high_a : f16,
92 pub tot_slp_high_b : f16,
93 pub paddle_len : f32,
100 pub timing_offset : f32,
102 pub coax_cable_time: f32,
103 pub hart_cable_time: f32,
104 pub event_t0 : f32,
107 pub x : f32,
108 pub y : f32,
109 pub z : f32,
110
111 pub valid : bool,
114}
115
116impl TofHit {
118 pub fn new() -> Self {
119 Self{
120 paddle_id : 0,
121 time_a : f16::from_f32(0.0),
122 time_b : f16::from_f32(0.0),
123 peak_a : f16::from_f32(0.0),
124 peak_b : f16::from_f32(0.0),
125 charge_a : f16::from_f32(0.0),
126 charge_b : f16::from_f32(0.0),
127 paddle_len : f32::NAN,
128 timing_offset : 0.0,
129 coax_cable_time : f32::NAN,
130 hart_cable_time : f32::NAN,
131 event_t0 : f32::NAN,
132 x : f32::NAN,
133 y : f32::NAN,
134 z : f32::NAN,
135
136 valid : true,
137 version : ProtocolVersion::V1,
139 baseline_a : f16::from_f32(0.0),
140 baseline_a_rms : f16::from_f32(0.0),
141 baseline_b : f16::from_f32(0.0),
142 baseline_b_rms : f16::from_f32(0.0),
143 phase : f16::from_f32(0.0),
144 tot_low_a : f16::from_f32(0.0),
145 tot_low_b : f16::from_f32(0.0),
146 tot_high_a : f16::from_f32(0.0),
147 tot_high_b : f16::from_f32(0.0),
148 tot_slp_low_a : f16::from_f32(0.0),
149 tot_slp_low_b : f16::from_f32(0.0),
150 tot_slp_high_a : f16::from_f32(0.0),
151 tot_slp_high_b : f16::from_f32(0.0),
152 }
153 }
154
155 pub fn add_peak(&mut self, peak : &Peak) {
159 if self.paddle_id != TofHit::get_pid(peak.paddle_end_id) {
160 }
162 if peak.paddle_end_id < 1000 {
163 error!("Invalide paddle end id {}", peak.paddle_end_id);
164 }
165 if peak.paddle_end_id > 2000 {
166 self.set_time_b (peak.time);
167 self.set_peak_b (peak.height);
168 self.set_charge_b(peak.charge);
169 } else if peak.paddle_end_id < 2000 {
170 self.set_time_a (peak.time);
171 self.set_peak_a (peak.height);
172 self.set_charge_a(peak.charge);
173 }
174 }
175
176 pub fn set_time_b(&mut self, t : f32) {
178 self.time_b = f16::from_f32(t)
179 }
180
181 pub fn set_time_a(&mut self, t : f32) {
182 self.time_a = f16::from_f32(t);
183 }
184
185 pub fn set_peak_a(&mut self, p : f32) {
186 self.peak_a = f16::from_f32(p)
187 }
188
189 pub fn set_peak_b(&mut self, p : f32) {
190 self.peak_b = f16::from_f32(p)
191 }
192
193 pub fn set_charge_a(&mut self, c : f32) {
194 self.charge_a = f16::from_f32(c)
195 }
196
197 pub fn set_charge_b(&mut self, c : f32) {
198 self.charge_b = f16::from_f32(c)
199 }
200}
201
202#[cfg(feature="pybindings")]
206#[pymethods]
207impl TofHit {
208
209 #[getter]
211 #[pyo3(name="paddle_id")]
212 fn paddle_id_py(&self) -> u8 {
213 self.paddle_id
214 }
215
216 #[getter]
217 #[pyo3(name="timing_offset")]
218 fn get_timing_offset(&self) -> f32 {
219 self.timing_offset
220 }
221
222 #[getter]
226 #[pyo3(name="paddle_len")]
227 fn get_paddle_len_py(&self) -> f32 {
228 self.paddle_len
229 }
230
231 #[pyo3(name="set_paddle")]
234 fn set_paddle_py(&mut self, plen : f32, coax_cbl_time : f32, hart_cbl_time : f32 ) {
235 self.paddle_len = plen;
236 self.coax_cable_time = coax_cbl_time;
237 self.hart_cable_time = hart_cbl_time;
238 }
239
240 #[getter]
243 #[pyo3(name="coax_cbl_time")]
244 fn get_coax_cbl_time(&self) -> f32 {
245 self.coax_cable_time
246 }
247
248 #[getter]
251 #[pyo3(name="hart_cbl_time")]
252 fn get_hart_cbl_time(&self) -> f32 {
253 self.hart_cable_time
254 }
255
256 #[getter]
265 #[pyo3(name="pos")]
266 fn get_pos_py(&self) -> f32 {
267 self.get_pos()
268 }
269
270 #[getter]
271 #[pyo3(name="x")]
272 fn x_py(&self) -> f32 {
273 self.x
274 }
275
276 #[getter]
277 #[pyo3(name="y")]
278 fn y_py(&self) -> f32 {
279 self.y
280 }
281
282 #[getter]
283 #[pyo3(name="z")]
284 fn z_py(&self) -> f32 {
285 self.z
286 }
287
288 #[getter]
289 #[pyo3(name="version")]
290 fn version_py(&self) -> ProtocolVersion {
291 self.version
292 }
293
294 #[getter]
295 #[pyo3(name="phase")]
296 fn phase_py(&self) -> f32 {
297 self.phase.to_f32()
298 }
299
300 #[getter]
301 #[pyo3(name="phase_ns")]
302 fn phase_ns_py(&self) -> f32 {
303 self.get_phase_ns()
304 }
305
306 #[getter]
307 #[pyo3(name="cable_delay")]
308 fn get_cable_delay_py(&self) -> f32 {
310 self.get_cable_delay()
311 }
312
313 #[getter]
316 #[pyo3(name="phase_delay")]
317 fn get_phase_delay_py(&self) -> f32 {
318 self.get_phase_delay()
319 }
320
321 #[getter]
326 #[pyo3(name="t0")]
327 fn get_t0_py(&self) -> f32 {
328 self.get_global_t0()
329 }
330
331 #[getter]
343 #[pyo3(name="event_t0")]
344 fn get_event_t0_py(&self) -> f32 {
345 self.get_global_t0()
347 }
348
349 #[getter]
355 #[pyo3(name="t0_uncorrected")]
356 fn get_t0_uncorrected_py(&self) -> f32 {
357 self.get_t0_uncorrected()
358 }
359
360 #[getter]
362 #[pyo3(name="edep")]
363 fn get_edep_py(&self) -> f32 {
364 self.get_edep()
365 }
366
367 #[getter]
369 #[pyo3(name="edep_att")]
370 fn get_edep_att_py(&self) -> f32 {
371 self.get_edep_att()
372 }
373
374 #[getter]
376 #[pyo3(name="time_a")]
377 fn get_time_a_py(&self) -> f32 {
378 self.get_time_a()
379 }
380
381 #[getter]
383 #[pyo3(name="time_b")]
384 fn get_time_b_py(&self) -> f32 {
385 self.get_time_b()
386 }
387
388 #[getter]
389 #[pyo3(name="TOT_low_a")]
390 fn get_tot_low_a_py(&self) -> f32 {
391 self.get_tot_low_a()
392 }
393
394 #[getter]
395 #[pyo3(name="TOT_low_b")]
396 fn get_tot_low_b_py(&self) -> f32 {
397 self.get_tot_low_b()
398 }
399
400 #[getter]
401 #[pyo3(name="TOT_high_a")]
402 fn get_tot_high_a_py(&self) -> f32 {
403 self.get_tot_high_a()
404 }
405
406 #[getter]
407 #[pyo3(name="TOT_high_b")]
408 fn get_tot_high_b_py(&self) -> f32 {
409 self.get_tot_high_b()
410 }
411
412 #[getter]
413 #[pyo3(name="TOT_slp_low_a")]
414 fn get_tot_slp_low_a_py(&self) -> f32 {
415 self.get_tot_slp_low_a()
416 }
417
418 #[getter]
419 #[pyo3(name="TOT_slp_low_b")]
420 fn get_tot_slp_low_b_py(&self) -> f32 {
421 self.get_tot_slp_low_b()
422 }
423
424 #[getter]
425 #[pyo3(name="TOT_slp_high_a")]
426 fn get_tot_slp_high_a_py(&self) -> f32 {
427 self.get_tot_slp_high_a()
428 }
429
430 #[getter]
431 #[pyo3(name="TOT_slp_high_b")]
432 fn get_tot_slp_high_b_py(&self) -> f32 {
433 self.get_tot_slp_high_b()
434 }
435
436 #[getter]
437 #[pyo3(name="peak_a")]
438 fn get_peak_a_py(&self) -> f32 {
439 self.get_peak_a()
440 }
441
442 #[getter]
443 #[pyo3(name="peak_b")]
444 fn get_peak_b_py(&self) -> f32 {
445 self.get_peak_b()
446 }
447
448 #[getter]
449 #[pyo3(name="charge_a")]
450 fn get_charge_a_py(&self) -> f32 {
451 self.get_charge_a()
452 }
453
454 #[getter]
455 #[pyo3(name="charge_b")]
456 fn get_charge_b_py(&self) -> f32 {
457 self.get_charge_b()
458 }
459
460 #[getter]
461 #[pyo3(name="baseline_a")]
462 fn get_bl_a_py(&self) -> f32 {
463 self.get_bl_a()
464 }
465
466 #[getter]
467 #[pyo3(name="baseline_b")]
468 fn get_bl_b_py(&self) -> f32 {
469 self.get_bl_b()
470 }
471
472 #[getter]
473 #[pyo3(name="baseline_a_rms")]
474 fn get_bl_a_rms_py(&self) -> f32 {
475 self.get_bl_a_rms()
476 }
477
478 #[getter]
479 #[pyo3(name="baseline_b_rms")]
480 fn get_bl_b_rms_py(&self) -> f32 {
481 self.get_bl_b_rms()
482 }
483}
484
485#[cfg_attr(feature="pybindings", pymethods)]
489impl TofHit {
490 pub fn distance(&self, other : &TofHit) -> f32 {
496 ((self.x - other.x).powi(2) + (self.y - other.y).powi(2) + (self.z - other.z).powi(2)).sqrt()
497 }
498
499 pub fn obeys_causality(&self) -> bool {
503 (self.paddle_len/(10.0*C_LIGHT_PADDLE)) - f32::abs(self.time_a.to_f32() - self.time_b.to_f32()) > 0.0
504 && self.get_t0_uncorrected() > 0.0
505 }
506}
507
508#[cfg(feature="pybindings")]
509pythonize!(TofHit);
510
511impl TofHit {
513
514 pub fn get_pos(&self) -> f32 {
523 let t0 = self.get_t0_uncorrected();
524 let clean_t_a = self.time_a.to_f32() - t0;
525 return clean_t_a*C_LIGHT_PADDLE*10.0;
526 }
527
528 pub fn get_cable_delay(&self) -> f32 {
530 self.hart_cable_time - self.coax_cable_time
531 }
532
533 pub fn get_phase_delay(&self) -> f32 {
536 let freq : f32 = 20.0e6;
537 let phase = self.phase.to_f32();
538 (phase/(2.0*PI*freq))*1.0e9f32
549 }
550
551 pub fn get_global_t0(&self) -> f32 {
556 self.event_t0 }
559
560 pub fn get_t0_uncorrected(&self) -> f32 {
566 0.5*(self.time_a.to_f32() + self.time_b.to_f32() - (self.paddle_len/(10.0*C_LIGHT_PADDLE)))
567 }
568
569 pub fn get_edep(&self) -> f32 {
571 (1.29/34.3)*(self.peak_a.to_f32() + self.peak_b.to_f32()) / 2.0
572 }
573
574 pub fn get_edep_att(&self) -> f32 {
576 let x0 = self.get_pos();
577 let att_a = ((3.9-0.00126*( x0+self.paddle_len/2.))+22.15).exp() / ((3.9)+22.15).exp();
578 let att_b = ((3.9-0.00126*(-x0+self.paddle_len/2.))+22.15).exp() / ((3.9)+22.15).exp();
579 let edep = 0.0159 * (self.get_peak_a()/att_a + self.get_peak_b()/att_b) / 2.; return edep;
581 }
582
583 pub fn get_time_a(&self) -> f32 {
585 self.time_a.to_f32()
586 }
587
588 pub fn get_time_b(&self) -> f32 {
590 self.time_b.to_f32()
591 }
592
593 pub fn get_tot_low_a(&self) -> f32 {
594 self.tot_low_a.to_f32()
595 }
596
597 pub fn get_tot_low_b(&self) -> f32 {
598 self.tot_low_b.to_f32()
599 }
600
601 pub fn get_tot_high_a(&self) -> f32 {
602 self.tot_high_a.to_f32()
603 }
604
605 pub fn get_tot_high_b(&self) -> f32 {
606 self.tot_high_b.to_f32()
607 }
608
609 pub fn get_tot_slp_low_a(&self) -> f32 {
610 self.tot_slp_low_a.to_f32()
611 }
612
613 pub fn get_tot_slp_low_b(&self) -> f32 {
614 self.tot_slp_low_b.to_f32()
615 }
616
617 pub fn get_tot_slp_high_a(&self) -> f32 {
618 self.tot_slp_high_a.to_f32()
619 }
620 pub fn get_tot_slp_high_b(&self) -> f32 {
621 self.tot_slp_high_b.to_f32()
622 }
623 pub fn get_peak_a(&self) -> f32 {
624 self.peak_a.to_f32()
625 }
626
627 pub fn get_peak_b(&self) -> f32 {
628 self.peak_b.to_f32()
629 }
630
631 pub fn get_charge_a(&self) -> f32 {
632 self.charge_a.to_f32()
633 }
634
635 pub fn get_charge_b(&self) -> f32 {
636 self.charge_b.to_f32()
637 }
638
639 pub fn get_bl_a(&self) -> f32 {
640 self.baseline_a.to_f32()
641 }
642
643 pub fn get_bl_b(&self) -> f32 {
644 self.baseline_b.to_f32()
645 }
646
647 pub fn get_bl_a_rms(&self) -> f32 {
648 self.baseline_a_rms.to_f32()
649 }
650
651 pub fn get_bl_b_rms(&self) -> f32 {
652 self.baseline_b_rms.to_f32()
653 }
654
655
656 pub fn get_pid(paddle_end_id : u16) -> u8 {
667 if paddle_end_id < 1000 {
668 return 0;
669 }
670 if paddle_end_id > 2000 {
671 return (paddle_end_id - 2000) as u8;
672 }
673 if paddle_end_id < 2000 {
674 return (paddle_end_id - 1000) as u8;
675 }
676 return 0;
677 }
678
679 pub fn get_phase_ns(&self) -> f32 {
682 let mut phase_ns = 50.0*self.phase.to_f32()/(2.0*PI);
683 phase_ns += 50.0;
689 phase_ns
690 }
691
692 pub fn get_phase_rollovers(&self) -> i16 {
693 let mut phase = self.phase.to_f32();
694 let mut ro = 0i16;
695 while phase < PI/2.0 {
696 phase += PI/2.0;
697 ro += 1;
698 }
699 while phase > PI/2.0 {
700 phase -= PI/2.0;
701 ro -= 1;
702 }
703 ro
704 }
705
706
707}
708
709#[cfg(feature="database")]
710impl TofHit {
711 pub fn set_paddle(&mut self, paddle : &TofPaddle) {
712 self.coax_cable_time = paddle.coax_cable_time;
713 self.hart_cable_time = paddle.harting_cable_time;
714 self.paddle_len = paddle.length * 10.0; let pr = paddle.principal();
716 let rel_pos = self.get_pos();
718 let pos = (paddle.global_pos_x_l0_A*10.0 + pr.0*rel_pos,
719 paddle.global_pos_y_l0_A*10.0 + pr.1*rel_pos,
720 paddle.global_pos_z_l0_A*10.0 + pr.2*rel_pos);
721 self.x = pos.0;
722 self.y = pos.1;
723 self.z = pos.2;
724 }
725}
726
727impl TofHit {
731 pub fn get_t0_with_local_corrections(&self) -> f32 {
732 self.get_t0_uncorrected() + self.get_cable_delay() + self.get_phase_ns()
733 }
734}
735
736
737impl Default for TofHit {
741 fn default() -> Self {
742 Self::new()
743 }
744}
745
746impl fmt::Display for TofHit {
747 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
748 let mut paddle_info = String::from("");
749 if self.paddle_len == 0.0 {
750 paddle_info = String::from("NOT SET!");
751 }
752 write!(f, "<TofHit (version : {}):
753 Paddle ID {}
754 Peak:
755 LE Time A/B {:.2} {:.2}
756 Height A/B {:.2} {:.2}
757 Charge A/B {:.2} {:.2}
758 ** time over threshold information
759 Lo TOT A/B {:.2} {:.2}
760 Hi TOT A/B {:.2} {:.2}
761 Lo Slope A/B {:.2} {:.2}
762 Hi Slope A/B {:.2} {:.2}
763 ** paddle {} **
764 Length {:.2}
765 Timing offset {:.2} (ns)
766 Coax cbl time {:.2}
767 Hart cbl time {:.2}
768 ** reconstructed interaction
769 energy_dep {:.2}
770 edep_att {:.2}
771 pos_across {:.2}
772 t0 (uncorr) {:.2}
773 t0 (local c) {:.2}
774 t0 (global c) {:.2}
775 ev t0 [DEPR] {:.2}
776 x, y, z {:.2} {:.2} {:.2}
777 ** V1 variables
778 phase (ch9) {:.4}
779 n phs ro {}
780 baseline A/B {:.2} {:.2}
781 bl. RMS A/B {:.2} {:.2}>",
782 self.version,
783 self.paddle_id,
784 self.get_time_a(),
785 self.get_time_b(),
786 self.get_peak_a(),
787 self.get_peak_b(),
788 self.get_charge_a(),
789 self.get_charge_b(),
790 self.get_tot_low_a(),
791 self.get_tot_low_b(),
792 self.get_tot_high_a(),
793 self.get_tot_high_b(),
794 self.get_tot_slp_low_a(),
795 self.get_tot_slp_low_b(),
796 self.get_tot_slp_high_a(),
797 self.get_tot_slp_high_b(),
798 paddle_info,
799 self.paddle_len,
800 self.timing_offset,
801 self.coax_cable_time,
802 self.hart_cable_time,
803 self.get_edep(),
804 self.get_edep_att(),
805 self.get_pos(),
806 self.get_t0_uncorrected(),
808 self.get_t0_with_local_corrections(),
809 self.get_global_t0(),
810 self.event_t0,
811 self.x,
812 self.y,
813 self.z,
814 self.phase,
815 self.get_phase_rollovers(),
816 self.baseline_a,
817 self.baseline_b,
818 self.baseline_a_rms,
819 self.baseline_b_rms,
820 )
821 }
822}
823
824impl Serialization for TofHit {
825
826 const HEAD : u16 = 61680; const TAIL : u16 = 3855;
828 const SIZE : usize = 44; fn to_bytestream(&self) -> Vec<u8> {
841
842 let mut bytestream = Vec::<u8>::with_capacity(Self::SIZE);
843 bytestream.extend_from_slice(&Self::HEAD.to_le_bytes());
844 bytestream.push(self.paddle_id);
845 bytestream.extend_from_slice(&self.time_a .to_le_bytes());
846 bytestream.extend_from_slice(&self.time_b .to_le_bytes());
847 bytestream.extend_from_slice(&self.peak_a .to_le_bytes());
848 bytestream.extend_from_slice(&self.peak_b .to_le_bytes());
849 bytestream.extend_from_slice(&self.charge_a .to_le_bytes());
850 bytestream.extend_from_slice(&self.charge_b .to_le_bytes());
851 bytestream.extend_from_slice(&self.tot_low_a .to_le_bytes());
852 bytestream.extend_from_slice(&self.baseline_a .to_le_bytes());
853 bytestream.extend_from_slice(&self.baseline_a_rms.to_le_bytes());
854 bytestream.extend_from_slice(&self.phase .to_le_bytes());
855 bytestream.push(self.version.to_u8());
856 bytestream.extend_from_slice(&self.baseline_b .to_le_bytes());
857 bytestream.extend_from_slice(&self.baseline_b_rms.to_le_bytes());
858 bytestream.extend_from_slice(&self.tot_low_b .to_le_bytes());
859 bytestream.extend_from_slice(&self.tot_high_a .to_le_bytes());
860 bytestream.extend_from_slice(&self.tot_high_b .to_le_bytes());
861 bytestream.extend_from_slice(&self.tot_slp_low_a.to_le_bytes());
862 bytestream.extend_from_slice(&self.tot_slp_low_b.to_le_bytes());
863 bytestream.extend_from_slice(&self.tot_slp_high_a.to_le_bytes());
864 bytestream.extend_from_slice(&self.tot_slp_high_b.to_le_bytes());
865 bytestream.extend_from_slice(&Self::TAIL .to_le_bytes());
866 bytestream
867 }
868
869
870 fn from_bytestream(stream : &Vec<u8>, pos : &mut usize)
877 -> Result<Self, SerializationError> {
878 let mut pp = Self::new();
879 let mut version_lt_011 = false;
880 let (size,_,__) = Self::guess_size(stream, *pos, 28)?;
881 if size == 30 {
882 version_lt_011 = true;
883 let head = parse_u16(stream, pos);
884 if head != Self::HEAD {
885 error!("Decoding of HEAD failed! Got {} instead!", head);
886 return Err(SerializationError::HeadInvalid);
887 }
888 } else {
889 Self::verify_fixed(stream, pos)?;
890 }
891 pp.valid = true;
894 pp.paddle_id = parse_u8(stream, pos);
895 pp.time_a = parse_f16(stream, pos);
896 pp.time_b = parse_f16(stream, pos);
897 pp.peak_a = parse_f16(stream, pos);
898 pp.peak_b = parse_f16(stream, pos);
899 pp.charge_a = parse_f16(stream, pos);
900 pp.charge_b = parse_f16(stream, pos);
901 pp.tot_low_a = parse_f16(stream, pos);
902 pp.baseline_a = parse_f16(stream, pos);
903 pp.baseline_a_rms = parse_f16(stream, pos);
904 let mut phase_vec = Vec::<u8>::new();
905 phase_vec.push(parse_u8(stream, pos));
906 phase_vec.push(parse_u8(stream, pos));
907 pp.phase = parse_f16(&phase_vec, &mut 0);
908 let version = ProtocolVersion::from(parse_u8(stream, pos));
909 pp.version = version;
910 match pp.version {
911 ProtocolVersion::V1 => {
912 }
913 _ => ()
914 }
915 pp.baseline_b = parse_f16(stream, pos);
916 pp.baseline_b_rms = parse_f16(stream, pos);
917 if !version_lt_011 {
918 pp.tot_low_b = parse_f16(stream, pos);
919 pp.tot_high_a = parse_f16(stream, pos);
920 pp.tot_high_b = parse_f16(stream, pos);
921 pp.tot_slp_low_a = parse_f16(stream, pos);
922 pp.tot_slp_low_b = parse_f16(stream, pos);
923 pp.tot_slp_high_a = parse_f16(stream, pos);
924 pp.tot_slp_high_b = parse_f16(stream, pos);
925 *pos += 2; } else {
927 let tail = parse_u16(stream, pos);
928 if tail != Self::TAIL {
929 error!("Decoding of TAIL failed for version {}! Got {} instead!", version, tail);
930 return Err(SerializationError::TailInvalid);
931 }
932 }
933 Ok(pp)
934 }
935}
936
937#[cfg(feature="random")]
938impl FromRandom for TofHit {
939 fn from_random() -> TofHit {
940 let mut pp = TofHit::new();
941 let mut rng = rand::rng();
942 let version_lt_011 = rng.random::<bool>();
944
945 pp.paddle_id = rng.random_range(0..161);
946 pp.time_a = f16::from_f32(rng.random::<f32>());
947 pp.time_b = f16::from_f32(rng.random::<f32>());
948 pp.peak_a = f16::from_f32(rng.random::<f32>());
949 pp.peak_b = f16::from_f32(rng.random::<f32>());
950 pp.charge_a = f16::from_f32(rng.random::<f32>());
951 pp.charge_b = f16::from_f32(rng.random::<f32>());
952 pp.version = ProtocolVersion::from(rng.random::<u8>());
953 pp.baseline_a = f16::from_f32(rng.random::<f32>());
954 pp.baseline_a_rms = f16::from_f32(rng.random::<f32>());
955 pp.baseline_b = f16::from_f32(rng.random::<f32>());
956 pp.baseline_b_rms = f16::from_f32(rng.random::<f32>());
957 pp.phase = f16::from_f32(rng.random::<f32>());
958
959 if !version_lt_011 {
960 pp.tot_low_a = f16::from_f32(rng.random::<f32>());
961 pp.tot_low_b = f16::from_f32(rng.random::<f32>());
962 pp.tot_high_a = f16::from_f32(rng.random::<f32>());
963 pp.tot_high_b = f16::from_f32(rng.random::<f32>());
964 pp.tot_slp_low_a = f16::from_f32(rng.random::<f32>());
965 pp.tot_slp_low_b = f16::from_f32(rng.random::<f32>());
966 pp.tot_slp_high_a = f16::from_f32(rng.random::<f32>());
967 pp.tot_slp_high_b = f16::from_f32(rng.random::<f32>());
968 }
969 pp.paddle_len = 0.0;
970 pp.coax_cable_time = 0.0;
971 pp.hart_cable_time = 0.0;
972 pp.x = 0.0;
973 pp.y = 0.0;
974 pp.z = 0.0;
975 pp.event_t0 = 0.0;
976 pp
977 }
978}
979
980#[cfg(feature = "random")]
983#[test]
984fn serialization_tofhit() {
985 for _ in 0..100 {
986 let mut pos = 0;
987 let data = TofHit::from_random();
988 let mut test = TofHit::from_bytestream(&data.to_bytestream(),&mut pos).unwrap();
989 test.paddle_len = 0.0;
992 test.coax_cable_time = 0.0;
993 test.hart_cable_time = 0.0;
994 test.x = 0.0;
995 test.y = 0.0;
996 test.z = 0.0;
997 test.event_t0 = 0.0;
998 assert_eq!(pos, TofHit::SIZE);
999 assert_eq!(data, test);
1000 }
1001}