1use std::time::Instant;
5use std::fmt;
6use std::f32::consts::PI;
7
8cfg_if::cfg_if! {
9 if #[cfg(feature = "random")] {
10 use crate::FromRandom;
11 use rand::Rng;
12 }
13}
14
15use crate::serialization::{
16 Serialization,
17 Packable,
18 parse_u8,
19 parse_u16,
20 parse_u32,
21 parse_u64,
22 parse_f32,
23 search_for_u16
24};
25
26use crate::packets::{
27 TofPacket,
28 PacketType
29};
30
31use crate::errors::SerializationError;
32
33use crate::events::{
34 MasterTriggerEvent,
35 RBEvent,
36 TofHit,
37 RBWaveform,
38 TriggerType,
40 EventStatus,
41 transcode_trigger_sources,
42};
43
44use crate::events::master_trigger::{
45 LTBThreshold,
46 LTB_CHANNELS
47};
48
49use crate::ProtocolVersion;
50
51cfg_if::cfg_if! {
52 if #[cfg(feature = "database")] {
53 use crate::database::DsiJChPidMapping;
54 use crate::database::Paddle;
55 use std::collections::HashMap;
56 }
57}
58
59#[derive(Debug, Copy, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
64#[repr(u8)]
65pub enum CompressionLevel {
66 Unknown = 0u8,
67 None = 10u8,
68}
69
70impl fmt::Display for CompressionLevel {
71 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72 let r = serde_json::to_string(self).unwrap_or(
73 String::from("Error: cannot unwrap this CompressionLevel"));
74 write!(f, "<CompressionLevel: {}>", r)
75 }
76}
77
78impl From<u8> for CompressionLevel {
79 fn from(value: u8) -> Self {
80 match value {
81 0u8 => CompressionLevel::Unknown,
82 10u8 => CompressionLevel::None,
83 _ => CompressionLevel::Unknown
84 }
85 }
86}
87
88#[derive(Debug, Copy, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
89#[repr(u8)]
90pub enum EventQuality {
91 Unknown = 0u8,
92 Silver = 10u8,
93 Gold = 20u8,
94 Diamond = 30u8,
95 FourLeafClover = 40u8,
96}
97
98impl fmt::Display for EventQuality {
99 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
100 let r = serde_json::to_string(self).unwrap_or(
101 String::from("Error: cannot unwrap this EventQuality"));
102 write!(f, "<EventQuality: {}>", r)
103 }
104}
105
106impl From<u8> for EventQuality {
107 fn from(value: u8) -> Self {
108 match value {
109 0u8 => EventQuality::Unknown,
110 10u8 => EventQuality::Silver,
111 20u8 => EventQuality::Gold,
112 30u8 => EventQuality::Diamond,
113 40u8 => EventQuality::FourLeafClover,
114 _ => EventQuality::Unknown
115 }
116 }
117}
118
119#[derive(Debug, Clone)]
122pub struct TofEvent {
123
124 pub compression_level : CompressionLevel,
125 pub quality : EventQuality,
126 pub header : TofEventHeader,
127 pub mt_event : MasterTriggerEvent,
128 pub rb_events : Vec::<RBEvent>,
129 pub creation_time : Instant,
133 pub write_to_disk : bool,
134 pub paddles_set : bool
135}
136
137impl fmt::Display for TofEvent {
138 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
139 write!(f,
140"<TofEvent:
141 quality : {}
142 {}
143 {}
144 n RBEvents : {}>"
145 ,self.quality,
146 self.header,
147 self.mt_event,
148 self.rb_events.len())
149 }
150}
151
152impl Default for TofEvent {
153 fn default() -> Self {
154 Self::new()
155 }
156}
157
158impl TofEvent {
159
160 pub fn new() -> Self {
161 let creation_time = Instant::now();
162 Self {
163 compression_level : CompressionLevel::Unknown,
164 quality : EventQuality::Unknown,
165 header : TofEventHeader::new(),
166 mt_event : MasterTriggerEvent::new(),
167 rb_events : Vec::<RBEvent>::new(),
168 creation_time : creation_time,
170 write_to_disk : true,
171 paddles_set : false
172 }
173 }
174
175
176 #[cfg(feature="database")]
177 pub fn set_paddles(&mut self, paddles : &HashMap<u8, Paddle>) {
178 let mut nerror = 0u8;
179 for ev in &mut self.rb_events {
180 for h in &mut ev.hits {
181 match paddles.get(&h.paddle_id) {
182 None => {
183 error!("Got paddle id {} which is not in given map!", h.paddle_id);
184 nerror += 1;
185 continue;
186 }
187 Some(pdl) => {
188 h.set_paddle(pdl);
189 }
190 }
191 }
192 }
193 if nerror == 0 {
194 self.paddles_set = true;
195 }
196 }
197
198 pub fn get_pointcloud(&self) -> Option<Vec<(f32,f32,f32,f32,f32)>> {
203 let mut pc = Vec::<(f32,f32,f32,f32,f32)>::new();
204 if !self.paddles_set {
205 error!("Before getting the pointcloud, paddle information needs to be set for this event. Call TofEventSummary;:set_paddle");
206 return None;
207 }
208 for rbev in &self.rb_events {
209 for h in &rbev.hits {
210 let result = (h.x, h.y, h.z, h.get_t0(), h.get_edep());
211 pc.push(result);
212 }
213 }
214 Some(pc)
215 }
216
217 #[cfg(feature="database")]
226 pub fn get_missing_paddles_hg(&self, pid_map : &DsiJChPidMapping) -> Vec<u8> {
227 let mut missing = Vec::<u8>::new();
228 for th in self.mt_event.get_trigger_hits() {
229 let pid = pid_map.get(&th.0).unwrap().get(&th.1).unwrap().get(&th.2.0).unwrap().0;
230 let mut found = false;
231 for h in self.get_hits() {
232 if h.paddle_id == pid {
233 found = true;
234 break
235 }
236 }
237 if !found {
238 missing.push(pid);
239 }
240 }
241 missing
242 }
243
244 #[cfg(feature="database")]
253 pub fn get_extra_paddles_hg(&self, pid_map : &DsiJChPidMapping) -> Vec<u8> {
254 let mut extra = Vec::<u8>::new();
255 let mut trigger_pids = Vec::<u8>::new();
256 for th in self.mt_event.get_trigger_hits() {
257 let pid = pid_map.get(&th.0).unwrap().get(&th.1).unwrap().get(&th.2.0).unwrap().0;
258 trigger_pids.push(pid);
259 }
260 for h in self.get_hits() {
261 if !trigger_pids.contains(&h.paddle_id) {
262 extra.push(h.paddle_id);
263 }
264 }
265 extra
266 }
267
268 #[cfg(feature="database")]
274 pub fn get_missing_paddles_wf(&self, pid_map : &DsiJChPidMapping) -> Vec<u8> {
275 let mut missing = Vec::<u8>::new();
276 let wf_pids = self.get_waveform_pids();
277 for th in self.mt_event.get_trigger_hits() {
278 let pid = pid_map.get(&th.0).unwrap().get(&th.1).unwrap().get(&th.2.0).unwrap().0;
279 let mut found = false;
281 for wf_pid in &wf_pids {
282 if *wf_pid == pid {
283 found = true;
284 break
285 }
286 }
287 if !found {
288 missing.push(pid);
289 }
290 }
291 missing
292 }
293
294 #[cfg(feature="database")]
298 pub fn get_triggered_paddles(&self, pid_map : DsiJChPidMapping) -> Vec<u8> {
299 let mut paddles = Vec::<u8>::new();
300 for th in self.mt_event.get_trigger_hits() {
301 let pid = pid_map.get(&th.0).unwrap().get(&th.1).unwrap().get(&th.2.0).unwrap().0;
302 paddles.push(pid);
303 }
304 paddles
305 }
306
307
308 pub fn extract_event_id_from_stream(stream : &Vec<u8>)
309 -> Result<u32, SerializationError> {
310 let evid = parse_u32(stream, &mut 12);
312 Ok(evid)
313 }
314
315 pub fn age(&self) -> u64 {
316 self.creation_time.elapsed().as_secs()
317 }
318
319 pub fn is_complete(&self) -> bool {
322 self.mt_event.get_rb_link_ids().len() == self.rb_events.len()
323 }
324
325 pub fn is_complete_masked(&self, mtb_link_ids_excluded : &Vec::<u8>) -> bool {
328 let mut expected_events = 0usize;
329 for k in &self.mt_event.get_rb_link_ids() {
330 if !mtb_link_ids_excluded.contains(k) {
331 expected_events += 1
332 }
333 }
334 self.rb_events.len() == expected_events
335 }
336
337 pub fn construct_sizes_header(&self) -> u32 {
342 let rb_event_len = self.rb_events.len() as u32;
343 let miss_len = 0u32;
346 let mut mask = 0u32;
347 mask = mask | rb_event_len;
348 mask = mask | (miss_len << 8);
349 mask
350 }
351
352 pub fn decode_size_header(mask : &u32)
353 -> (usize, usize) {
354 let rb_event_len = (mask & 0xFF) as usize;
355 let miss_len = ((mask & 0xFF00) >> 8) as usize;
356 (rb_event_len, miss_len)
357 }
358
359 pub fn get_combined_vector_sizes(&self) -> usize {
360 self.rb_events.len()
361 }
363
364 pub fn get_rbwaveforms(&self) -> Vec<RBWaveform> {
366 let mut wf = Vec::<RBWaveform>::new();
367 for ev in &self.rb_events {
368 wf.extend_from_slice(&ev.get_rbwaveforms());
369 }
370 wf
371 }
372
373 pub fn get_waveforms(&self) -> Vec<RBWaveform> {
378 let mut wfs = Vec::<RBWaveform>::new();
379 for ev in &self.rb_events {
380 for wf in &ev.get_rbwaveforms() {
381 wfs.push(wf.clone());
382 }
383 }
384 wfs
385 }
386
387 pub fn get_waveform_pids(&self) -> Vec<u8> {
389 let mut pids = Vec::<u8>::new();
390 for ev in &self.rb_events {
391 for wf in &ev.get_rbwaveforms() {
392 pids.push(wf.paddle_id)
393 }
394 }
395 pids
396 }
397
398 pub fn get_hits(&self) -> Vec<TofHit> {
400 let mut hits = Vec::<TofHit>::new();
401 for ev in &self.rb_events {
402 for h in &ev.hits {
403 hits.push(*h);
404 }
405 }
406 hits
407 }
408
409 pub fn has_any_mangling(&self) -> bool {
412 for rbev in &self.rb_events {
413 if rbev.status == EventStatus::CellAndChnSyncErrors
414 || rbev.status == EventStatus::CellSyncErrors
415 || rbev.status == EventStatus::ChnSyncErrors {
416 return true;
417 }
418 }
419 false
420 }
421
422 pub fn get_summary(&self) -> TofEventSummary {
423 let mut summary = TofEventSummary::new();
424 summary.status = self.mt_event.event_status;
426 if self.has_any_mangling() {
427 summary.status = EventStatus::AnyDataMangling;
428 }
429 summary.trigger_sources = self.mt_event.trigger_source;
431 summary.n_trigger_paddles = self.mt_event.get_trigger_hits().len() as u8;
432 summary.event_id = self.header.event_id;
433 summary.run_id = (self.header.run_id & 0x0000ffff) as u16;
435 summary.version = ProtocolVersion::V1;
438 let mt_timestamp = (self.mt_event.get_timestamp_abs48() as f64/1000.0).floor() as u64;
439 summary.timestamp32 = (mt_timestamp & 0x00000000ffffffff ) as u32;
440 summary.timestamp16 = ((mt_timestamp & 0x0000ffff00000000 ) >> 32) as u16;
441 summary.dsi_j_mask = self.mt_event.dsi_j_mask;
444 summary.channel_mask = self.mt_event.channel_mask.clone();
445 summary.mtb_link_mask = self.mt_event.mtb_link_mask;
446 summary.drs_dead_lost_hits = self.get_lost_hits();
447 summary.hits = Vec::<TofHit>::new();
448 for ev in &self.rb_events {
449 for hit in &ev.hits {
450 let h = hit.clone();
451 if summary.version == ProtocolVersion::V1 {
452 if h.paddle_id <= 60 {
453 summary.n_hits_cbe += 1;
454 summary.tot_edep_cbe += h.get_edep();
455 }
456 else if h.paddle_id <= 108 && h.paddle_id > 60 {
457 summary.n_hits_umb += 1;
458 summary.tot_edep_umb += h.get_edep();
459 }
460 else {
461 summary.n_hits_cor += 1;
462 summary.tot_edep_cor += h.get_edep();
463 }
464 }
465 summary.hits.push(h);
466 }
467 }
468 #[cfg(feature="database")]
469 summary.normalize_hit_times();
470 summary
471 }
472
473 pub fn get_lost_hits(&self) -> u16 {
476 let mut lost_hits = 0u16;
477 for rbev in &self.rb_events {
478 if rbev.header.drs_lost_trigger() {
479 let mut nhits = rbev.header.get_nchan() as u16;
480 if nhits > 0 {
481 nhits -= 1;
482 }
483 lost_hits += nhits;
484 }
485 }
486 lost_hits
487 }
488
489 pub fn get_nhits_umb(&self) -> usize {
490 let mut nhit = 0;
491 for h in &self.get_hits() {
492 if h.paddle_id > 60 && h.paddle_id < 109 {
493 nhit += 1;
494 }
495 }
496 nhit
497 }
498
499 pub fn get_nhits(&self) -> usize {
500 self.get_hits().len()
501 }
502}
503
504impl Packable for TofEvent {
505 const PACKET_TYPE : PacketType = PacketType::TofEvent;
506}
507
508impl Serialization for TofEvent {
509
510 const HEAD : u16 = 43690; const TAIL : u16 = 21845; fn to_bytestream(&self) -> Vec<u8> {
515 let mut stream = Vec::<u8>::new();
516 stream.extend_from_slice(&Self::HEAD.to_le_bytes());
517 stream.extend_from_slice(&(self.compression_level as u8).to_le_bytes());
518 stream.extend_from_slice(&(self.quality as u8).to_le_bytes());
519 stream.extend_from_slice(&self.header.to_bytestream());
520 stream.extend_from_slice(&self.mt_event.to_bytestream());
521 let sizes_header = self.construct_sizes_header();
522 stream.extend_from_slice(&sizes_header.to_le_bytes());
523 for k in 0..self.rb_events.len() {
524 stream.extend_from_slice(&self.rb_events[k].to_bytestream());
525 }
526 stream.extend_from_slice(&Self::TAIL.to_le_bytes());
530 stream
531 }
532
533 fn from_bytestream(stream : &Vec<u8>,
534 pos : &mut usize)
535 -> Result<Self, SerializationError>{
536 let mut event = Self::new();
537 let head_pos = search_for_u16(Self::HEAD, stream, *pos)?;
538 *pos = head_pos + 2;
539 event.compression_level = CompressionLevel::try_from(parse_u8(stream, pos)).unwrap();
540 event.quality = EventQuality::try_from(parse_u8(stream, pos)).unwrap();
541 event.header = TofEventHeader::from_bytestream(stream, pos)?;
542 event.mt_event = MasterTriggerEvent::from_bytestream(stream, pos)?;
543 let v_sizes = Self::decode_size_header(&parse_u32(stream, pos));
544 for k in 0..v_sizes.0 {
545 match RBEvent::from_bytestream(stream, pos) {
546 Err(err) => error!("Expected RBEvent {} of {}, but got serialization error {}!", k, v_sizes.0, err),
547 Ok(ev) => {
548 event.rb_events.push(ev);
549 }
550 }
551 }
552 let tail = parse_u16(stream, pos);
553 if tail != Self::TAIL {
554 error!("Decoding of TAIL failed! Got {} instead!", tail);
555 }
556 Ok(event)
557 }
558}
559
560#[cfg(feature="random")]
561impl FromRandom for TofEvent {
562
563 fn from_random() -> Self {
564 let mut event = Self::new();
565 event.mt_event = MasterTriggerEvent::from_random();
566 event.header = TofEventHeader::from_random();
567 let mut rng = rand::thread_rng();
568 let n_boards = rng.gen_range(1..41) as u8;
569 for _ in 0..n_boards {
572 event.rb_events.push(RBEvent::from_random());
573 }
574 event
581 }
582}
583
584impl From<MasterTriggerEvent> for TofEvent {
585 fn from(mte : MasterTriggerEvent) -> Self {
586 let mut te : TofEvent = Default::default();
587 te.mt_event = mte;
588 te.header.event_id = te.mt_event.event_id;
589 te
590 }
591}
592
593#[derive(Debug, Clone, PartialEq)]
595pub struct TofEventHeader {
596
597 pub run_id : u32,
598 pub event_id : u32,
599 pub drs_dead_lost_hits : u8,
601 pub rsvd0 : u8,
602 pub timestamp_32 : u32,
604 pub timestamp_16 : u16, pub primary_beta : u16,
609 pub primary_beta_unc : u16,
610 pub primary_charge : u16,
611 pub primary_charge_unc : u16,
612 pub primary_outer_tof_x : u16,
613 pub primary_outer_tof_y : u16,
614 pub primary_outer_tof_z : u16,
615 pub primary_inner_tof_x : u16,
616 pub primary_inner_tof_y : u16,
617 pub primary_inner_tof_z : u16, pub trigger_info : u8,
625 pub ctr_etx : u8,
626
627 pub n_paddles : u8, }
635
636impl TofEventHeader {
637
638 pub fn new() -> Self {
639 Self {
640 run_id : 0,
641 event_id : 0,
642 drs_dead_lost_hits : 0,
643 rsvd0 : 0,
644 timestamp_32 : 0,
645 timestamp_16 : 0,
646 primary_beta : 0,
647 primary_beta_unc : 0,
648 primary_charge : 0,
649 primary_charge_unc : 0,
650 primary_outer_tof_x : 0,
651 primary_outer_tof_y : 0,
652 primary_outer_tof_z : 0,
653 primary_inner_tof_x : 0,
654 primary_inner_tof_y : 0,
655 primary_inner_tof_z : 0,
656 trigger_info : 0,
659 ctr_etx : 0,
660 n_paddles : 0
661 }
662 }
663}
664
665impl Serialization for TofEventHeader {
666 const HEAD : u16 = 0xAAAA;
667 const TAIL : u16 = 0x5555;
668 const SIZE : usize = 43;
669
670 fn from_bytestream(stream : &Vec<u8>, pos : &mut usize)
671 -> Result<Self, SerializationError> {
672 Self::verify_fixed(stream, pos)?;
673 let mut event = Self::new();
674 event.run_id = parse_u32(stream, pos);
675 event.event_id = parse_u32(stream, pos);
676 event.timestamp_32 = parse_u32(stream, pos);
677 event.timestamp_16 = parse_u16(stream, pos);
678 event.primary_beta = parse_u16(stream, pos);
679 event.primary_beta_unc = parse_u16(stream, pos);
680 event.primary_charge = parse_u16(stream, pos);
681 event.primary_charge_unc = parse_u16(stream, pos);
682 event.primary_outer_tof_x = parse_u16(stream, pos);
683 event.primary_outer_tof_y = parse_u16(stream, pos);
684 event.primary_outer_tof_z = parse_u16(stream, pos);
685 event.primary_inner_tof_x = parse_u16(stream, pos);
686 event.primary_inner_tof_y = parse_u16(stream, pos);
687 event.primary_inner_tof_z = parse_u16(stream, pos);
688 event.drs_dead_lost_hits = parse_u8(stream, pos);
689 event.rsvd0 = parse_u8(stream, pos);
690 event.trigger_info = parse_u8(stream, pos);
693 event.ctr_etx = parse_u8(stream, pos);
694 event.n_paddles = parse_u8(stream, pos);
695 *pos += 2;
696 Ok(event)
697 }
698
699 fn to_bytestream(&self) -> Vec<u8> {
700 let mut bytestream = Vec::<u8>::with_capacity(Self::SIZE);
701 bytestream.extend_from_slice(&Self::HEAD .to_le_bytes());
702 bytestream.extend_from_slice(&self.run_id .to_le_bytes());
703 bytestream.extend_from_slice(&self.event_id .to_le_bytes());
704 bytestream.extend_from_slice(&self.timestamp_32 .to_le_bytes());
705 bytestream.extend_from_slice(&self.timestamp_16 .to_le_bytes());
706 bytestream.extend_from_slice(&self.primary_beta .to_le_bytes());
707 bytestream.extend_from_slice(&self.primary_beta_unc .to_le_bytes());
708 bytestream.extend_from_slice(&self.primary_charge .to_le_bytes());
709 bytestream.extend_from_slice(&self.primary_charge_unc .to_le_bytes());
710 bytestream.extend_from_slice(&self.primary_outer_tof_x .to_le_bytes());
711 bytestream.extend_from_slice(&self.primary_outer_tof_y .to_le_bytes());
712 bytestream.extend_from_slice(&self.primary_outer_tof_z .to_le_bytes());
713 bytestream.extend_from_slice(&self.primary_inner_tof_x .to_le_bytes());
714 bytestream.extend_from_slice(&self.primary_inner_tof_y .to_le_bytes());
715 bytestream.extend_from_slice(&self.primary_inner_tof_z .to_le_bytes());
716 bytestream.extend_from_slice(&self.drs_dead_lost_hits .to_le_bytes());
720 bytestream.extend_from_slice(&self.rsvd0 .to_le_bytes());
721 bytestream.extend_from_slice(&self.trigger_info .to_le_bytes());
722 bytestream.extend_from_slice(&self.ctr_etx .to_le_bytes());
723 bytestream.extend_from_slice(&self.n_paddles .to_le_bytes());
724 bytestream.extend_from_slice(&Self::TAIL .to_le_bytes());
725 bytestream
726 }
727}
728
729
730impl Default for TofEventHeader {
731 fn default() -> Self {
732 Self::new()
733 }
734}
735
736impl From<&MasterTriggerEvent> for TofEventHeader {
737 fn from(mte : &MasterTriggerEvent) -> Self {
738 let mut te = Self::new();
739 te.event_id = mte.event_id;
740 te.timestamp_32 = mte.timestamp;
741 te.n_paddles = mte.get_trigger_hits().len() as u8;
742 te
743 }
744}
745
746impl fmt::Display for TofEventHeader {
747 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
748 let mut repr = String::from("<TofEventHeader");
749 repr += &(format!("\n Run ID : {}", self.run_id ));
750 repr += &(format!("\n Event ID : {}", self.event_id ));
751 repr += &(format!("\n Timestamp 32 : {}", self.timestamp_32 ));
752 repr += &(format!("\n Timestamp 16 : {}", self.timestamp_16 ));
753 repr += &(format!("\n DRS LOST HITS : {}", self.drs_dead_lost_hits ));
754 repr += &(format!("\n Prim. Beta : {}", self.primary_beta ));
755 repr += &(format!("\n Prim. Beta Unc : {}", self.primary_beta_unc ));
756 repr += &(format!("\n Prim. Charge : {}", self.primary_charge ));
757 repr += &(format!("\n Prim. Charge unc : {}", self.primary_charge_unc ));
758 repr += &(format!("\n Prim. Outer Tof X : {}", self.primary_outer_tof_x ));
759 repr += &(format!("\n Prim. Outer Tof Y : {}", self.primary_outer_tof_y ));
760 repr += &(format!("\n Prim. Outer Tof Z : {}", self.primary_outer_tof_z ));
761 repr += &(format!("\n Prim. Inner Tof X : {}", self.primary_inner_tof_x ));
762 repr += &(format!("\n Prim. Inner Tof Y : {}", self.primary_inner_tof_y ));
763 repr += &(format!("\n Prim. Inner Tof Z : {}", self.primary_inner_tof_z ));
764 repr += &(format!("\n TriggerInfo : {}", self.trigger_info ));
767 repr += &(format!("\n Ctr ETX : {}", self.ctr_etx ));
768 repr += &(format!("\n NPaddles : {}", self.n_paddles ));
769 repr += ">";
770 write!(f,"{}", repr)
771 }
772}
773
774#[cfg(feature="random")]
775impl FromRandom for TofEventHeader {
776
777 fn from_random() -> Self {
778 let mut rng = rand::thread_rng();
779 Self {
780 run_id : rng.gen::<u32>(),
781 event_id : rng.gen::<u32>(),
782 drs_dead_lost_hits : rng.gen::<u8>(),
783 rsvd0 : rng.gen::<u8>(),
784 timestamp_32 : rng.gen::<u32>(),
785 timestamp_16 : rng.gen::<u16>(),
786 primary_beta : rng.gen::<u16>(),
787 primary_beta_unc : rng.gen::<u16>(),
788 primary_charge : rng.gen::<u16>(),
789 primary_charge_unc : rng.gen::<u16>(),
790 primary_outer_tof_x : rng.gen::<u16>(),
791 primary_outer_tof_y : rng.gen::<u16>(),
792 primary_outer_tof_z : rng.gen::<u16>(),
793 primary_inner_tof_x : rng.gen::<u16>(),
794 primary_inner_tof_y : rng.gen::<u16>(),
795 primary_inner_tof_z : rng.gen::<u16>(),
796 trigger_info : rng.gen::<u8>(),
797 ctr_etx : rng.gen::<u8>(),
798 n_paddles : rng.gen::<u8>()
799 }
800 }
801}
802
803#[derive(Debug, Clone, PartialEq)]
809pub struct TofEventSummary {
810 pub status : EventStatus,
811 pub version : ProtocolVersion,
812 pub quality : u8,
813 pub trigger_sources : u16,
814
815 pub n_trigger_paddles : u8,
819 pub event_id : u32,
820 pub run_id : u16,
823 pub timestamp32 : u32,
824 pub timestamp16 : u16,
825 pub primary_beta : u16,
828 pub primary_charge : u16,
831 pub drs_dead_lost_hits : u16,
835 pub dsi_j_mask : u32,
836 pub channel_mask : Vec<u16>,
837 pub mtb_link_mask : u64,
838 pub hits : Vec<TofHit>,
839 pub n_hits_umb : u8,
843 pub n_hits_cbe : u8,
844 pub n_hits_cor : u8,
845 pub tot_edep_umb : f32,
846 pub tot_edep_cbe : f32,
847 pub tot_edep_cor : f32,
848 pub paddles_set : bool,
849}
850
851impl TofEventSummary {
852
853 pub fn new() -> Self {
854 Self {
855 status : EventStatus::Unknown,
856 version : ProtocolVersion::Unknown,
857 n_hits_umb : 0,
858 n_hits_cbe : 0,
859 n_hits_cor : 0,
860 tot_edep_umb : 0.0,
861 tot_edep_cbe : 0.0,
862 tot_edep_cor : 0.0,
863 quality : 0,
864 trigger_sources : 0,
865 n_trigger_paddles : 0,
866 event_id : 0,
867 run_id : 0,
868 timestamp32 : 0,
869 timestamp16 : 0,
870 primary_beta : 0,
871 primary_charge : 0,
872 drs_dead_lost_hits : 0,
873 dsi_j_mask : 0,
874 channel_mask : Vec::<u16>::new(),
875 mtb_link_mask : 0,
876 hits : Vec::<TofHit>::new(),
877 paddles_set : false,
878 }
879 }
880
881 #[cfg(feature="database")]
882 pub fn normalize_hit_times(&mut self) {
883 if self.hits.len() == 0 {
884 return;
885 }
886 let phase0 = self.hits[0].phase.to_f32();
887 for h in &mut self.hits {
888 let t0 = h.get_t0_uncorrected() + h.get_cable_delay();
889 let mut phase_diff = h.phase.to_f32() - phase0;
890 while phase_diff < - PI/2.0 {
891 phase_diff += 2.0*PI;
892 }
893 while phase_diff > PI/2.0 {
894 phase_diff -= 2.0*PI;
895 }
896 let t_shift = 50.0*phase_diff/(2.0*PI);
897 h.event_t0 = t0 + t_shift;
898 }
899 }
900
901 #[cfg(feature="database")]
902 pub fn set_paddles(&mut self, paddles : &HashMap<u8, Paddle>) {
903 let mut nerror = 0u8;
904 for h in &mut self.hits {
905 match paddles.get(&h.paddle_id) {
906 None => {
907 error!("Got paddle id {} which is not in given map!", h.paddle_id);
908 nerror += 1;
909 continue;
910 }
911 Some(pdl) => {
912 h.set_paddle(pdl);
913 }
914 }
915 }
916 if nerror == 0 {
917 self.paddles_set = true;
918 }
919 }
920
921 pub fn get_pointcloud(&self) -> Option<Vec<(f32,f32,f32,f32,f32)>> {
926 let mut pc = Vec::<(f32,f32,f32,f32,f32)>::new();
927 if !self.paddles_set {
928 error!("Before getting the pointcloud, paddle information needs to be set for this event. Call TofEventSummary;:set_paddle");
929 return None;
930 }
931 for h in &self.hits {
932 let result = (h.x, h.y, h.z, h.get_t0(), h.get_edep());
933 pc.push(result);
934 }
935 Some(pc)
936 }
937
938 #[cfg(feature="database")]
947 pub fn get_missing_paddles_hg(&self, pid_map : &DsiJChPidMapping) -> Vec<u8> {
948 let mut missing = Vec::<u8>::new();
949 for th in self.get_trigger_hits() {
950 let pid = pid_map.get(&th.0).unwrap().get(&th.1).unwrap().get(&th.2.0).unwrap().0;
951 let mut found = false;
952 for h in &self.hits {
953 if h.paddle_id == pid {
954 found = true;
955 break
956 }
957 }
958 if !found {
959 missing.push(pid);
960 }
961 }
962 missing
963 }
964
965 #[cfg(feature="database")]
969 pub fn get_triggered_paddles(&self, pid_map : DsiJChPidMapping) -> Vec<u8> {
970 let mut paddles = Vec::<u8>::new();
971 for th in self.get_trigger_hits() {
972 let pid = pid_map.get(&th.0).unwrap().get(&th.1).unwrap().get(&th.2.0).unwrap().0;
973 paddles.push(pid);
974 }
975 paddles
976 }
977
978 pub fn get_rb_link_ids(&self) -> Vec<u8> {
980 let mut links = Vec::<u8>::new();
981 for k in 0..64 {
982 if (self.mtb_link_mask >> k) as u64 & 0x1 == 1 {
983 links.push(k as u8);
984 }
985 }
986 links
987 }
988
989 pub fn get_trigger_hits(&self) -> Vec<(u8, u8, (u8, u8), LTBThreshold)> {
1002 let mut hits = Vec::<(u8,u8,(u8,u8),LTBThreshold)>::with_capacity(5);
1003 let physical_channels = [(1u8, 2u8), (3u8,4u8), (5u8, 6u8), (7u8, 8u8),
1004 (9u8, 10u8), (11u8,12u8), (13u8, 14u8), (15u8, 16u8)];
1005 let n_masks_needed = self.dsi_j_mask.count_ones();
1007 if self.channel_mask.len() < n_masks_needed as usize {
1008 error!("We need {} hit masks, but only have {}! This is bad!", n_masks_needed, self.channel_mask.len());
1009 return hits;
1010 }
1011 let mut n_mask = 0;
1012 trace!("Expecting {} hit masks", n_masks_needed);
1013 trace!("ltb channels {:?}", self.dsi_j_mask);
1014 trace!("hit masks {:?}", self.channel_mask);
1015 for k in 0..32 {
1019 if (self.dsi_j_mask >> k) as u32 & 0x1 == 1 {
1020 let mut dsi = 0u8;
1021 let mut j = 0u8;
1022 if k < 5 {
1023 dsi = 1;
1024 j = k as u8 + 1;
1025 } else if k < 10 {
1026 dsi = 2;
1027 j = k as u8 - 5 + 1;
1028 } else if k < 15 {
1029 dsi = 3;
1030 j = k as u8- 10 + 1;
1031 } else if k < 20 {
1032 dsi = 4;
1033 j = k as u8- 15 + 1;
1034 } else if k < 25 {
1035 dsi = 5;
1036 j = k as u8 - 20 + 1;
1037 }
1038 let channels = self.channel_mask[n_mask];
1042 for (i,ch) in LTB_CHANNELS.iter().enumerate() {
1043 let ph_chn = physical_channels[i];
1045 let thresh_bits = ((channels & ch) >> (i*2)) as u8;
1048 if thresh_bits > 0 { hits.push((dsi, j, ph_chn, LTBThreshold::from(thresh_bits)));
1051 }
1052 }
1053 n_mask += 1;
1054 } }
1056 hits
1057 }
1058
1059 pub fn get_trigger_sources(&self) -> Vec<TriggerType> {
1061 transcode_trigger_sources(self.trigger_sources)
1062 }
1063
1064 pub fn get_timestamp48(&self) -> u64 {
1065 ((self.timestamp16 as u64) << 32) | self.timestamp32 as u64
1066 }
1067
1068 pub fn get_edep_umbrella(&self) -> f32 {
1073 let mut tot_edep = 0.0f32;
1074 for h in &self.hits {
1075 if h.paddle_id < 61 || h.paddle_id > 108 {
1076 continue;
1077 }
1078 tot_edep += h.get_edep();
1079 }
1080 tot_edep
1081 }
1082
1083 pub fn get_edep_cube(&self) -> f32 {
1088 let mut tot_edep = 0.0f32;
1089 for h in &self.hits {
1090 if h.paddle_id > 60 {
1091 continue;
1092 }
1093 tot_edep += h.get_edep();
1094 }
1095 tot_edep
1096 }
1097
1098 pub fn get_edep_cortina(&self) -> f32 {
1103 let mut tot_edep = 0.0f32;
1104 for h in &self.hits {
1105 if h.paddle_id < 109 {
1106 continue;
1107 }
1108 tot_edep += h.get_edep();
1109 }
1110 tot_edep
1111 }
1112
1113 pub fn get_edep(&self) -> f32 {
1118 let mut tot_edep = 0.0f32;
1119 for h in &self.hits {
1120 tot_edep += h.get_edep();
1121 }
1122 tot_edep
1123 }
1124
1125 pub fn get_nhits_umb(&self) -> usize {
1126 let mut nhit = 0;
1127 for h in &self.hits {
1128 if h.paddle_id > 60 && h.paddle_id < 109 {
1129 nhit += 1;
1130 }
1131 }
1132 nhit
1133 }
1134
1135 pub fn get_nhits(&self) -> usize {
1136 self.hits.len()
1137 }
1138
1139 pub fn from_tofeventpacket(pack : &TofPacket)
1143 -> Result<Self, SerializationError> {
1144 if pack.packet_type != PacketType::TofEvent {
1145 return Err(SerializationError::IncorrectPacketType);
1146 }
1147 let mut pos = 0usize;
1148 let stream = &pack.payload;
1149 let head = parse_u16(stream, &mut pos);
1150 if head != TofEvent::HEAD {
1151 return Err(SerializationError::HeadInvalid);
1152 }
1153 let mut te = TofEvent::new();
1154 te.compression_level = CompressionLevel::try_from(parse_u8(stream, &mut pos)).unwrap();
1155 te.quality = EventQuality::try_from(parse_u8(stream, &mut pos)).unwrap();
1156 te.header = TofEventHeader::from_bytestream(stream, &mut pos)?;
1157 te.mt_event = MasterTriggerEvent::from_bytestream(stream, &mut pos)?;
1158
1159 let v_sizes = TofEvent::decode_size_header(&parse_u32(stream, &mut pos));
1160 for k in 0..v_sizes.0 {
1161 match RBEvent::from_bytestream_nowaveforms(stream, &mut pos) {
1162 Err(err) => error!("Expected RBEvent {} of {}, but got serialization error {}!", k, v_sizes.0, err),
1163 Ok(ev) => {
1164 te.rb_events.push(ev);
1165 }
1166 }
1167 }
1168 let tail = parse_u16(stream, &mut pos);
1169 if tail != Self::TAIL {
1170 error!("Decoding of TAIL failed! Got {} instead!", tail);
1171 return Err(SerializationError::TailInvalid);
1172 }
1173 let summary = te.get_summary();
1174 return Ok(summary);
1175 }
1176}
1177
1178impl Packable for TofEventSummary {
1179 const PACKET_TYPE : PacketType = PacketType::TofEventSummary;
1180}
1181
1182impl Serialization for TofEventSummary {
1183
1184 const HEAD : u16 = 43690; const TAIL : u16 = 21845; fn to_bytestream(&self) -> Vec<u8> {
1188 let mut stream = Vec::<u8>::new();
1189 stream.extend_from_slice(&Self::HEAD.to_le_bytes());
1190 let status_version = self.status.to_u8() | self.version.to_u8();
1191 stream.push(status_version);
1192 stream.extend_from_slice(&self.trigger_sources.to_le_bytes());
1193 stream.extend_from_slice(&self.n_trigger_paddles.to_le_bytes());
1194 stream.extend_from_slice(&self.event_id.to_le_bytes());
1195 if self.version == ProtocolVersion::V1 {
1197 stream.extend_from_slice(&self.n_hits_umb .to_le_bytes());
1198 stream.extend_from_slice(&self.n_hits_cbe .to_le_bytes());
1199 stream.extend_from_slice(&self.n_hits_cor .to_le_bytes());
1200 stream.extend_from_slice(&self.tot_edep_umb.to_le_bytes());
1201 stream.extend_from_slice(&self.tot_edep_cbe.to_le_bytes());
1202 stream.extend_from_slice(&self.tot_edep_cor.to_le_bytes());
1203 }
1204 stream.extend_from_slice(&self.quality.to_le_bytes());
1205 stream.extend_from_slice(&self.timestamp32.to_le_bytes());
1206 stream.extend_from_slice(&self.timestamp16.to_le_bytes());
1207 stream.extend_from_slice(&self.run_id.to_le_bytes());
1209 stream.extend_from_slice(&self.drs_dead_lost_hits.to_le_bytes());
1210 stream.extend_from_slice(&self.dsi_j_mask.to_le_bytes());
1212 let n_channel_masks = self.channel_mask.len();
1213 stream.push(n_channel_masks as u8);
1214 for k in 0..n_channel_masks {
1215 stream.extend_from_slice(&self.channel_mask[k].to_le_bytes());
1216 }
1217 stream.extend_from_slice(&self.mtb_link_mask.to_le_bytes());
1218 let nhits = self.hits.len() as u16;
1219 stream.extend_from_slice(&nhits.to_le_bytes());
1220 for k in 0..self.hits.len() {
1221 stream.extend_from_slice(&self.hits[k].to_bytestream());
1222 }
1223 stream.extend_from_slice(&Self::TAIL.to_le_bytes());
1224 stream
1225 }
1226
1227 fn from_bytestream(stream : &Vec<u8>,
1228 pos : &mut usize)
1229 -> Result<Self, SerializationError>{
1230 let mut summary = Self::new();
1231 let head = parse_u16(stream, pos);
1232 if head != Self::HEAD {
1233 error!("Decoding of HEAD failed! Got {} instead!", head);
1234 return Err(SerializationError::HeadInvalid);
1235 }
1236 let status_version_u8 = parse_u8(stream, pos);
1237 let status = EventStatus::from(status_version_u8 & 0x3f);
1238 let version = ProtocolVersion::from(status_version_u8 & 0xc0);
1239 summary.status = status;
1240 summary.version = version;
1241 summary.trigger_sources = parse_u16(stream, pos);
1242 summary.n_trigger_paddles = parse_u8(stream, pos);
1243 summary.event_id = parse_u32(stream, pos);
1244 if summary.version == ProtocolVersion::V1 {
1245 summary.n_hits_umb = parse_u8(stream, pos);
1246 summary.n_hits_cbe = parse_u8(stream, pos);
1247 summary.n_hits_cor = parse_u8(stream, pos);
1248 summary.tot_edep_umb = parse_f32(stream, pos);
1249 summary.tot_edep_cbe = parse_f32(stream, pos);
1250 summary.tot_edep_cor = parse_f32(stream, pos);
1251 }
1252 summary.quality = parse_u8(stream, pos);
1253 summary.timestamp32 = parse_u32(stream, pos);
1254 summary.timestamp16 = parse_u16(stream, pos);
1255 summary.run_id = parse_u16(stream, pos);
1256 summary.drs_dead_lost_hits = parse_u16(stream, pos);
1257 summary.dsi_j_mask = parse_u32(stream, pos);
1258 let n_channel_masks = parse_u8(stream, pos);
1259 for _ in 0..n_channel_masks {
1260 summary.channel_mask.push(parse_u16(stream, pos));
1261 }
1262 summary.mtb_link_mask = parse_u64(stream, pos);
1263 let nhits = parse_u16(stream, pos);
1264 for _ in 0..nhits {
1265 summary.hits.push(TofHit::from_bytestream(stream, pos)?);
1266 }
1267 let tail = parse_u16(stream, pos);
1268 if tail != Self::TAIL {
1269 error!("Decoding of TAIL failed for version {}! Got {} instead!", version, tail);
1270 return Err(SerializationError::TailInvalid);
1271 }
1272 Ok(summary)
1273 }
1274}
1275
1276impl Default for TofEventSummary {
1277 fn default() -> Self {
1278 Self::new()
1279 }
1280}
1281
1282impl fmt::Display for TofEventSummary {
1283 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1284 let mut repr = format!("<TofEventSummary (version {})", self.version);
1285 repr += &(format!("\n EventID : {}", self.event_id));
1286 repr += &(format!("\n RunID : {}", self.run_id));
1287 repr += &(format!("\n EventStatus : {}", self.status));
1288 repr += &(format!("\n TriggerSources : {:?}", self.get_trigger_sources()));
1289 repr += &(format!("\n NTrigPaddles : {}", self.n_trigger_paddles));
1290 repr += &(format!("\n DRS dead hits : {}", self.drs_dead_lost_hits));
1291 repr += &(format!("\n timestamp32 : {}", self.timestamp32));
1292 repr += &(format!("\n timestamp16 : {}", self.timestamp16));
1293 repr += &(format!("\n |-> timestamp48 : {}", self.get_timestamp48()));
1294 repr += &(format!("\n ** ** TRIGGER HITS (DSI/J/CH) [{} LTBS] ** **", self.dsi_j_mask.count_ones()));
1297 for k in self.get_trigger_hits() {
1298 repr += &(format!("\n => {}/{}/({},{}) ({}) ", k.0, k.1, k.2.0, k.2.1, k.3));
1299 }
1300 repr += "\n ** ** MTB LINK IDs ** **";
1301 let mut mtblink_str = String::from("\n => ");
1302 for k in self.get_rb_link_ids() {
1303 mtblink_str += &(format!("{} ", k))
1304 }
1305 repr += &mtblink_str;
1306 repr += &(format!("\n == Trigger hits {}, expected RBEvents {}",
1307 self.get_trigger_hits().len(),
1308 self.get_rb_link_ids().len()));
1309 repr += &String::from("\n ** ** ** HITS ** ** **");
1310 for h in &self.hits {
1311 repr += &(format!("\n {}", h));
1312 }
1313 write!(f, "{}", repr)
1314 }
1315}
1316
1317#[cfg(feature="random")]
1318impl FromRandom for TofEventSummary {
1319
1320 fn from_random() -> Self {
1321 let mut summary = Self::new();
1322 let mut rng = rand::thread_rng();
1323 let status = EventStatus::from_random();
1324 let version = ProtocolVersion::from_random();
1325 if version == ProtocolVersion::V1 {
1326 summary.n_hits_umb = rng.gen::<u8>();
1327 summary.n_hits_cbe = rng.gen::<u8>();
1328 summary.n_hits_cor = rng.gen::<u8>();
1329 summary.tot_edep_umb = rng.gen::<f32>();
1330 summary.tot_edep_cbe = rng.gen::<f32>();
1331 summary.tot_edep_cor = rng.gen::<f32>();
1332 summary.quality = rng.gen::<u8>();
1333 }
1334 summary.status = status;
1335 summary.version = version;
1336 summary.trigger_sources = rng.gen::<u16>();
1338 summary.n_trigger_paddles = rng.gen::<u8>();
1339 summary.event_id = rng.gen::<u32>();
1340 summary.timestamp32 = rng.gen::<u32>();
1341 summary.timestamp16 = rng.gen::<u16>();
1342 summary.drs_dead_lost_hits = rng.gen::<u16>();
1343 summary.dsi_j_mask = rng.gen::<u32>();
1344 let n_channel_masks = rng.gen::<u8>();
1345 for _ in 0..n_channel_masks {
1346 summary.channel_mask.push(rng.gen::<u16>());
1347 }
1348 summary.mtb_link_mask = rng.gen::<u64>();
1349 let nhits = 1;
1351 for _ in 0..nhits {
1352 summary.hits.push(TofHit::from_random());
1353 }
1354 summary
1355 }
1356}
1357
1358#[test]
1364fn packable_tofeventsummary() {
1365 for _ in 0..100 {
1366 let data = TofEventSummary::from_random();
1367 let mut test : TofEventSummary = data.pack().unpack().unwrap();
1368 for h in &mut test.hits {
1373 h.paddle_len = 0.0;
1374 h.cable_len = 0.0;
1375 h.coax_cable_time = 0.0;
1376 h.hart_cable_time = 0.0;
1377 h.x = 0.0;
1378 h.y = 0.0;
1379 h.z = 0.0;
1380 h.event_t0 = 0.0;
1381 }
1382 assert_eq!(data, test);
1383 }
1384}
1385
1386#[test]
1387fn emit_tofeventsummary() {
1388 for _ in 0..100 {
1389 let data = TofEvent::from_random();
1390 let summary = data.get_summary();
1391 let test : TofEventSummary = summary.pack().unpack().unwrap();
1392 assert_eq!(summary, test);
1393 }
1394}
1395
1396#[test]
1397#[cfg(feature = "random")]
1398fn tofevent_sizes_header() {
1399 for _ in 0..100 {
1400 let data = TofEvent::from_random();
1401 let mask = data.construct_sizes_header();
1402 let size = TofEvent::decode_size_header(&mask);
1403 assert_eq!(size.0, data.rb_events.len());
1404 }
1406}
1407
1408#[test]
1409#[cfg(feature = "random")]
1410fn packable_tofevent() {
1411 for _ in 0..5 {
1412 let data = TofEvent::from_random();
1413 let test : TofEvent = data.pack().unpack().unwrap();
1414 assert_eq!(data.header, test.header);
1415 assert_eq!(data.compression_level, test.compression_level);
1416 assert_eq!(data.quality, test.quality);
1417 assert_eq!(data.mt_event, test.mt_event);
1418 assert_eq!(data.rb_events.len(), test.rb_events.len());
1419 assert_eq!(data.rb_events, test.rb_events);
1422 }
1425}
1426
1427#[test]
1428#[cfg(feature = "random")]
1429fn serialize_tofeventheader() {
1430 let data = TofEventHeader::from_random();
1431 let test = TofEventHeader::from_bytestream(&data.to_bytestream(), &mut 0).unwrap();
1432 assert_eq!(data, test);
1433}
1434