tof_dataclasses/
events.rs

1//! Events  
2//
3//
4#[cfg(feature = "pybindings")]
5use pyo3::pyclass;
6pub mod tof_event;
7pub mod master_trigger;
8pub mod rb_event;
9#[allow(deprecated)]
10pub mod rb_eventmemoryview;
11pub mod data_type;
12pub mod tof_hit;
13
14pub use master_trigger::{
15  MasterTriggerEvent,
16  TriggerType,
17};
18pub use tof_event::{
19  TofEvent,
20  TofEventHeader,
21  TofEventSummary
22};
23pub use tof_hit::TofHit;
24pub use data_type::DataType;
25
26#[allow(deprecated)]
27pub use rb_eventmemoryview::RBEventMemoryView;
28pub use rb_event::{
29    RBEventHeader,
30    RBEvent,
31    //RBMissingHit,
32    RBWaveform,
33};
34  
35cfg_if::cfg_if! {
36  if #[cfg(feature = "random")]  {
37    use crate::FromRandom;
38    extern crate rand;
39    use rand::Rng;
40  }
41}
42
43use std::fmt;
44
45#[derive(Debug, Copy, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
46#[repr(u8)]
47#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
48pub enum EventStatus {
49  Unknown                = 0u8,
50  CRC32Wrong             = 10u8,
51  TailWrong              = 11u8,
52  ChannelIDWrong         = 12u8,
53  /// one of the channels cells CellSyncError bits 
54  /// has been set (RB)
55  CellSyncErrors         = 13u8,
56  /// one of the channels ChannelSyncError bits 
57  /// has been set (RB)
58  ChnSyncErrors          = 14u8,
59  /// Both of the bits (at least one for the cell sync errors)
60  /// have been set
61  CellAndChnSyncErrors   = 15u8,
62  /// If any of the RBEvents have Sync erros, we flag the tof 
63  /// event summary to indicate there were issues
64  AnyDataMangling        = 16u8,
65  IncompleteReadout      = 21u8,
66  /// This can be used if there is a version
67  /// missmatch and we have to hack something
68  IncompatibleData       = 22u8,
69  /// The TofEvent timed out while waiting for more Readoutboards
70  EventTimeOut           = 23u8,
71  /// A RB misses Ch9 data
72  NoChannel9             = 24u8,
73  GoodNoCRCOrErrBitCheck = 39u8,
74  /// The event status is good, but we did not 
75  /// perform any CRC32 check
76  GoodNoCRCCheck         = 40u8,
77  /// The event is good, but we did not perform
78  /// error checks
79  GoodNoErrBitCheck      = 41u8,
80  Perfect                = 42u8
81}
82
83impl fmt::Display for EventStatus {
84  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85    let r = serde_json::to_string(self).unwrap_or(
86      String::from("Error: cannot unwrap this EventStatus"));
87    write!(f, "<EventStatus: {}>", r)
88  }
89}
90
91impl EventStatus {
92  pub fn to_u8(&self) -> u8 {
93    match self {
94      EventStatus::Unknown => {
95        return 0;
96      }
97      EventStatus::CRC32Wrong => {
98        return 10;
99      }
100      EventStatus::TailWrong => {
101        return 11;
102      }
103      EventStatus::ChannelIDWrong => {
104        return 12;
105      }
106      EventStatus::CellSyncErrors => {
107        return 13;
108      }
109      EventStatus::ChnSyncErrors => {
110        return 14;
111      }
112      EventStatus::CellAndChnSyncErrors => {
113        return 15;
114      }
115      EventStatus::AnyDataMangling => {
116        return 16;
117      }
118      EventStatus::IncompleteReadout => {
119        return 21;
120      }
121      EventStatus::IncompatibleData => {
122        return 22;
123      }
124      EventStatus::EventTimeOut => {
125        return 23;
126      }
127      EventStatus::NoChannel9 => {
128        return 24;
129      }
130      EventStatus::GoodNoCRCOrErrBitCheck => {
131        return 39;
132      }
133      EventStatus::GoodNoCRCCheck => {
134        return 40;
135      }
136      EventStatus::GoodNoErrBitCheck => {
137        return 41;
138      }
139      EventStatus::Perfect => {
140        return 42;
141      }
142    }
143  }
144}
145
146impl From<u8> for EventStatus {
147  fn from(value: u8) -> Self {
148    match value {
149      0  => EventStatus::Unknown,
150      10 => EventStatus::CRC32Wrong,
151      11 => EventStatus::TailWrong,
152      12 => EventStatus::ChannelIDWrong,
153      13 => EventStatus::CellSyncErrors,
154      14 => EventStatus::ChnSyncErrors,
155      15 => EventStatus::CellAndChnSyncErrors,
156      16 => EventStatus::AnyDataMangling,
157      21 => EventStatus::IncompleteReadout,
158      22 => EventStatus::IncompatibleData,
159      23 => EventStatus::EventTimeOut,
160      24 => EventStatus::NoChannel9,
161      39 => EventStatus::GoodNoCRCOrErrBitCheck,
162      40 => EventStatus::GoodNoCRCCheck,
163      41 => EventStatus::GoodNoErrBitCheck,
164      42 => EventStatus::Perfect,
165      _    => EventStatus::Unknown
166    }
167  }
168}
169
170#[cfg(feature = "random")]
171impl FromRandom for EventStatus {
172  
173  fn from_random() -> Self {
174    let choices = [
175      EventStatus::Unknown,
176      EventStatus::CRC32Wrong,
177      EventStatus::TailWrong,
178      EventStatus::ChannelIDWrong,
179      EventStatus::CellSyncErrors,
180      EventStatus::ChnSyncErrors,
181      EventStatus::CellAndChnSyncErrors,
182      EventStatus::AnyDataMangling,
183      EventStatus::IncompleteReadout,
184      EventStatus::IncompatibleData,
185      EventStatus::EventTimeOut,
186      EventStatus::NoChannel9,
187      EventStatus::GoodNoCRCOrErrBitCheck,
188      EventStatus::GoodNoCRCCheck,
189      EventStatus::GoodNoErrBitCheck,
190      EventStatus::Perfect,
191    ];
192    let mut rng  = rand::thread_rng();
193    let idx = rng.gen_range(0..choices.len());
194    choices[idx]
195  }
196}
197
198/// Get the trigger sources from trigger source byte
199/// FIXME! (Does not return anything)
200pub fn transcode_trigger_sources(trigger_sources : u16) -> Vec<TriggerType> {
201  let mut t_types    = Vec::<TriggerType>::new();
202  let gaps_trigger   = trigger_sources >> 5 & 0x1 == 1;
203  if gaps_trigger {
204    t_types.push(TriggerType::Gaps);
205  }
206  let any_trigger    = trigger_sources >> 6 & 0x1 == 1;
207  if any_trigger {
208    t_types.push(TriggerType::Any);
209  }
210  let forced_trigger = trigger_sources >> 7 & 0x1 == 1;
211  if forced_trigger {
212    t_types.push(TriggerType::Forced);
213  }
214  let track_trigger  = trigger_sources >> 8 & 0x1 == 1;
215  if track_trigger {
216    t_types.push(TriggerType::Track);
217  }
218  let central_track_trigger
219                     = trigger_sources >> 9 & 0x1 == 1;
220  if central_track_trigger {
221    t_types.push(TriggerType::TrackCentral);
222  }
223  t_types
224}
225
226
227#[test]
228#[cfg(feature = "random")]
229fn test_event_status() {
230  for _ in 0..100 {
231    let ev_stat    = EventStatus::from_random();
232    let ev_stat_u8 = ev_stat.to_u8();
233    let u8_ev_stat = EventStatus::from(ev_stat_u8);
234    assert_eq!(ev_stat, u8_ev_stat);
235  }
236}
237