1use std::fmt;
2use std::f32::consts::PI;
3
4use half::f16;
5
6use crate::errors::SerializationError;
7use crate::serialization::{
8 parse_u8,
9 parse_u16,
10 parse_f16,
11 Serialization
12};
13use crate::ProtocolVersion;
14
15use crate::constants::{
16 C_LIGHT_PADDLE,
17};
18
19#[cfg(feature="random")]
20use rand::Rng;
21
22#[cfg(feature="database")]
23use crate::database::Paddle;
24
25#[derive(Debug,Copy,Clone,PartialEq)]
52pub struct Peak {
53 pub paddle_end_id : u16,
54 pub time : f32,
55 pub charge : f32,
56 pub height : f32
57}
58
59impl Peak {
60 pub fn new() -> Self {
61 Self {
62 paddle_end_id : 40,
63 time : 0.0,
64 charge : 0.0,
65 height : 0.0,
66 }
67 }
68}
69
70impl Default for Peak {
71 fn default() -> Self {
72 Self::new()
73 }
74}
75
76impl fmt::Display for Peak {
77 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78 write!(f, "<Peak:
79 p_end_id : {}
80 time : {}
81 charge : {}
82 height : {}>",
83 self.paddle_end_id,
84 self.time,
85 self.charge,
86 self.height)
87 }
88}
89
90#[derive(Debug,Copy,Clone,PartialEq)]
97pub struct TofHit {
98
99 pub paddle_id : u8,
102 pub time_a : f16,
103 pub time_b : f16,
104 pub peak_a : f16,
105 pub peak_b : f16,
106 pub charge_a : f16,
107 pub charge_b : f16,
108
109 pub paddle_len : f32,
113 pub cable_len : f32,
118 pub x : f32,
122 pub y : f32,
123 pub z : f32,
124 pub coax_cable_time: f32,
126 pub hart_cable_time: f32,
127 pub event_t0 : f32,
130
131 pub timestamp32 : u32,
133 pub timestamp16 : u16,
134 pub ctr_etx : u8,
135 pub charge_min_i : u16,
136
137 pub pos_across : u16,
141 pub t0 : u16,
144
145 pub reserved : u8,
147 pub version : ProtocolVersion,
150 pub baseline_a : f16,
152 pub baseline_a_rms : f16,
153 pub baseline_b : f16,
154 pub baseline_b_rms : f16,
155 pub phase : f16,
157 pub valid : bool,
160 pub ftime_a : f32,
162 pub ftime_b : f32,
163 pub fpeak_a : f32,
164 pub fpeak_b : f32,
165}
166
167impl Default for TofHit {
168 fn default() -> Self {
169 Self::new()
170 }
171}
172
173impl fmt::Display for TofHit {
174 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
175 let mut paddle_info = String::from("");
176 if self.paddle_len == 0.0 {
177 paddle_info = String::from("NOT SET!");
178 }
179 write!(f, "<TofHit (version : {}):
180 Paddle ID {}
181 Peak:
182 LE Time A/B {:.2} {:.2}
183 Height A/B {:.2} {:.2}
184 Charge A/B {:.2} {:.2}
185 ** paddle {} **
186 Length {:.2}
187 Harting cable length {:.2}
188 Coax cbl time {:.2}
189 Hart cbl time {:.2}
190 ** reconstructed interaction
191 energy_dep {:.2}
192 pos_across {:.2}
193 t0 {:.2}
194 x, y, z {:.2} {:.2} {:.2}
195 ** V1 variables
196 phase (ch9) {:.4}
197 n phs ro {}
198 baseline A/B {:.2} {:.2}
199 bl. RMS A/B {:.2} {:.2}>",
200 self.version,
201 self.paddle_id,
202 self.get_time_a(),
203 self.get_time_b(),
204 self.get_peak_a(),
205 self.get_peak_b(),
206 self.get_charge_a(),
207 self.get_charge_b(),
208 paddle_info,
209 self.paddle_len,
210 self.cable_len,
211 self.coax_cable_time,
212 self.hart_cable_time,
213 self.get_edep(),
214 self.get_pos(),
215 self.get_t0(),
216 self.x,
217 self.y,
218 self.z,
219 self.phase,
220 self.get_phase_rollovers(),
221 self.baseline_a,
222 self.baseline_b,
223 self.baseline_a_rms,
224 self.baseline_b_rms,
225 )
226 }
227}
228
229impl Serialization for TofHit {
230
231 const HEAD : u16 = 61680; const TAIL : u16 = 3855;
233 const SIZE : usize = 30; fn to_bytestream(&self) -> Vec<u8> {
246
247 let mut bytestream = Vec::<u8>::with_capacity(Self::SIZE);
248 bytestream.extend_from_slice(&Self::HEAD.to_le_bytes());
249 bytestream.push(self.paddle_id);
250 bytestream.extend_from_slice(&self.time_a .to_le_bytes());
251 bytestream.extend_from_slice(&self.time_b .to_le_bytes());
252 bytestream.extend_from_slice(&self.peak_a .to_le_bytes());
253 bytestream.extend_from_slice(&self.peak_b .to_le_bytes());
254 bytestream.extend_from_slice(&self.charge_a .to_le_bytes());
255 bytestream.extend_from_slice(&self.charge_b .to_le_bytes());
256 bytestream.extend_from_slice(&self.charge_min_i.to_le_bytes());
257 bytestream.extend_from_slice(&self.baseline_a .to_le_bytes());
260 bytestream.extend_from_slice(&self.baseline_a_rms.to_le_bytes());
261 bytestream.extend_from_slice(&self.phase .to_le_bytes());
263 bytestream.push(self.version.to_u8());
268 bytestream.extend_from_slice(&self.baseline_b.to_le_bytes());
269 bytestream.extend_from_slice(&self.baseline_b_rms.to_le_bytes());
270 bytestream.extend_from_slice(&Self::TAIL .to_le_bytes());
271 bytestream
272 }
273
274
275 fn from_bytestream(stream : &Vec<u8>, pos : &mut usize)
282 -> Result<Self, SerializationError> {
283 let mut pp = Self::new();
284 Self::verify_fixed(stream, pos)?;
285 pp.valid = true;
288 pp.paddle_id = parse_u8(stream, pos);
289 pp.time_a = parse_f16(stream, pos);
290 pp.time_b = parse_f16(stream, pos);
291 pp.peak_a = parse_f16(stream, pos);
292 pp.peak_b = parse_f16(stream, pos);
293 pp.charge_a = parse_f16(stream, pos);
294 pp.charge_b = parse_f16(stream, pos);
295 pp.charge_min_i = parse_u16(stream, pos);
296 pp.baseline_a = parse_f16(stream, pos);
297 pp.baseline_a_rms = parse_f16(stream, pos);
298 let mut phase_vec = Vec::<u8>::new();
308 phase_vec.push(parse_u8(stream, pos));
309 phase_vec.push(parse_u8(stream, pos));
310 pp.phase = parse_f16(&phase_vec, &mut 0);
311 let version = ProtocolVersion::from(parse_u8(stream, pos));
314 pp.version = version;
315 match pp.version {
316 ProtocolVersion::V1 => {
317 }
324 _ => ()
325 }
326 pp.baseline_b = parse_f16(stream, pos);
327 pp.baseline_b_rms = parse_f16(stream, pos);
328
329 *pos += 2; Ok(pp)
333 }
334}
335
336impl TofHit {
337
338 pub fn new() -> Self {
339 Self{
340 paddle_id : 0,
341 time_a : f16::from_f32(0.0),
342 time_b : f16::from_f32(0.0),
343 peak_a : f16::from_f32(0.0),
344 peak_b : f16::from_f32(0.0),
345 charge_a : f16::from_f32(0.0),
346 charge_b : f16::from_f32(0.0),
347 paddle_len : f32::NAN,
348 cable_len : f32::NAN,
349 coax_cable_time : f32::NAN,
350 hart_cable_time : f32::NAN,
351 event_t0 : f32::NAN,
352 x : f32::NAN,
353 y : f32::NAN,
354 z : f32::NAN,
355
356 charge_min_i : 0,
357 pos_across : 0,
359 t0 : 0,
360 ctr_etx : 0,
361 timestamp32 : 0,
362 timestamp16 : 0,
363 valid : true,
364 version : ProtocolVersion::V1,
366 reserved : 0,
367 baseline_a : f16::from_f32(0.0),
368 baseline_a_rms : f16::from_f32(0.0),
369 baseline_b : f16::from_f32(0.0),
370 baseline_b_rms : f16::from_f32(0.0),
371 phase : f16::from_f32(0.0),
372 ftime_a : 0.0,
374 ftime_b : 0.0,
375 fpeak_a : 0.0,
376 fpeak_b : 0.0,
377 }
378 }
379
380 #[cfg(feature="database")]
381 pub fn set_paddle(&mut self, paddle : &Paddle) {
382 self.cable_len = paddle.cable_len;
383 self.coax_cable_time = paddle.coax_cable_time;
384 self.hart_cable_time = paddle.harting_cable_time;
385 self.paddle_len = paddle.length * 10.0; let pr = paddle.principal();
387 let rel_pos = self.get_pos();
389 let pos = (paddle.global_pos_x_l0_A*10.0 + pr.0*rel_pos,
390 paddle.global_pos_y_l0_A*10.0 + pr.1*rel_pos,
391 paddle.global_pos_z_l0_A*10.0 + pr.2*rel_pos);
392 self.x = pos.0;
393 self.y = pos.1;
394 self.z = pos.2;
395 }
396
397 pub fn get_pid(paddle_end_id : u16) -> u8 {
407 if paddle_end_id < 1000 {
408 return 0;
409 }
410 if paddle_end_id > 2000 {
411 return (paddle_end_id - 2000) as u8;
412 }
413 if paddle_end_id < 2000 {
414 return (paddle_end_id - 1000) as u8;
415 }
416 return 0;
417 }
418
419 pub fn add_peak(&mut self, peak : &Peak) {
420 if self.paddle_id != TofHit::get_pid(peak.paddle_end_id) {
421 }
423 if peak.paddle_end_id < 1000 {
424 error!("Invalide paddle end id {}", peak.paddle_end_id);
425 }
426 if peak.paddle_end_id > 2000 {
427 self.set_time_b (peak.time);
428 self.set_peak_b (peak.height);
429 self.set_charge_b(peak.charge);
430 } else if peak.paddle_end_id < 2000 {
431 self.set_time_a (peak.time);
432 self.set_peak_a (peak.height);
433 self.set_charge_a(peak.charge);
434 }
435 }
436
437
438 pub fn get_pos(&self) -> f32 {
451 let t0 = self.get_t0_uncorrected();
452 let clean_t_a = self.time_a.to_f32() - t0;
453 return clean_t_a*C_LIGHT_PADDLE*10.0;
454 }
455
456 pub fn obeys_causality(&self) -> bool {
460 (self.paddle_len/(10.0*C_LIGHT_PADDLE)) - f32::abs(self.time_a.to_f32() - self.time_b.to_f32()) > 0.0
461 && self.get_t0_uncorrected() > 0.0
462 }
463
464 pub fn get_cable_delay(&self) -> f32 {
466 self.hart_cable_time - self.coax_cable_time
467 }
468
469 pub fn get_phase_delay(&self) -> f32 {
472 let freq : f32 = 20.0e6;
473 let phase = self.phase.to_f32();
474 (phase/(2.0*PI*freq))*1.0e9f32
485 }
486
487 pub fn get_phase_rollovers(&self) -> i16 {
488 let mut phase = self.phase.to_f32();
489 let mut ro = 0i16;
490 while phase < PI/2.0 {
491 phase += PI/2.0;
492 ro += 1;
493 }
494 while phase > PI/2.0 {
495 phase -= PI/2.0;
496 ro -= 1;
497 }
498 ro
499 }
500
501 pub fn get_t0(&self) -> f32 {
506 self.event_t0
508 }
509
510 pub fn get_t0_uncorrected(&self) -> f32 {
516 0.5*(self.time_a.to_f32() + self.time_b.to_f32() - (self.paddle_len/(10.0*C_LIGHT_PADDLE)))}
518
519 pub fn get_edep(&self) -> f32 {
521 (1.29/34.3)*(self.peak_a.to_f32() + self.peak_b.to_f32()) / 2.0
522 }
523
524 pub fn get_time_a(&self) -> f32 {
525 self.time_a.to_f32()
526 }
527
528 pub fn set_time_a(&mut self, t : f32) {
529 self.time_a = f16::from_f32(t);
530 }
531
532 pub fn get_time_b(&self) -> f32 {
533 self.time_b.to_f32()
534 }
535
536 pub fn set_time_b(&mut self, t : f32) {
537 self.time_b = f16::from_f32(t)
538 }
539
540 pub fn get_peak_a(&self) -> f32 {
541 self.peak_a.to_f32()
542 }
543
544 pub fn set_peak_a(&mut self, p : f32) {
545 self.peak_a = f16::from_f32(p)
546 }
547
548 pub fn get_peak_b(&self) -> f32 {
549 self.peak_b.to_f32()
550 }
551
552 pub fn set_peak_b(&mut self, p : f32) {
553 self.peak_b = f16::from_f32(p)
554 }
555
556 pub fn get_charge_a(&self) -> f32 {
557 self.charge_a.to_f32()
558 }
559
560 pub fn set_charge_a(&mut self, c : f32) {
561 self.charge_a = f16::from_f32(c)
562 }
563
564 pub fn get_charge_b(&self) -> f32 {
565 self.charge_b.to_f32()
566 }
567
568 pub fn set_charge_b(&mut self, c : f32) {
569 self.charge_b = f16::from_f32(c)
570 }
571
572 pub fn get_bl_a(&self) -> f32 {
573 self.baseline_a.to_f32()
574 }
575
576 pub fn get_bl_b(&self) -> f32 {
577 self.baseline_b.to_f32()
578 }
579
580 pub fn get_bl_a_rms(&self) -> f32 {
581 self.baseline_a_rms.to_f32()
582 }
583
584 pub fn get_bl_b_rms(&self) -> f32 {
585 self.baseline_b_rms.to_f32()
586 }
587
588 #[cfg(feature="random")]
589 pub fn from_random() -> TofHit {
590 let mut pp = TofHit::new();
591 let mut rng = rand::thread_rng();
592
593 pp.paddle_id = rng.gen::<u8> ();
594 pp.time_a = f16::from_f32(rng.gen::<f32>());
595 pp.time_b = f16::from_f32(rng.gen::<f32>());
596 pp.peak_a = f16::from_f32(rng.gen::<f32>());
597 pp.peak_b = f16::from_f32(rng.gen::<f32>());
598 pp.charge_a = f16::from_f32(rng.gen::<f32>());
599 pp.charge_b = f16::from_f32(rng.gen::<f32>());
600 pp.version = ProtocolVersion::from(rng.gen::<u8>());
601 pp.baseline_a = f16::from_f32(rng.gen::<f32>());
602 pp.baseline_a_rms = f16::from_f32(rng.gen::<f32>());
603 pp.baseline_b = f16::from_f32(rng.gen::<f32>());
604 pp.baseline_b_rms = f16::from_f32(rng.gen::<f32>());
605 pp.phase = f16::from_f32(rng.gen::<f32>());
606
607 pp.paddle_len = 0.0;
608 pp.cable_len = 0.0;
609 pp.coax_cable_time = 0.0;
610 pp.hart_cable_time = 0.0;
611 pp.x = 0.0;
612 pp.y = 0.0;
613 pp.z = 0.0;
614 pp.event_t0 = 0.0;
615 pp
640 }
641}
642
643#[cfg(feature = "random")]
644#[test]
645fn serialization_tofhit() {
646 for _ in 0..100 {
647 let mut pos = 0;
648 let data = TofHit::from_random();
649 let mut test = TofHit::from_bytestream(&data.to_bytestream(),&mut pos).unwrap();
650 test.paddle_len = 0.0;
653 test.cable_len = 0.0;
654 test.coax_cable_time = 0.0;
655 test.hart_cable_time = 0.0;
656 test.x = 0.0;
657 test.y = 0.0;
658 test.z = 0.0;
659 test.event_t0 = 0.0;
660 assert_eq!(pos, TofHit::SIZE);
661 assert_eq!(data, test);
662 }
663}