1pub mod tof_hit;
5pub use tof_hit::TofHit;
6
7pub mod rb_waveform;
8pub use rb_waveform::RBWaveform;
9
10pub mod rb_event_header;
11pub use rb_event_header::RBEventHeader;
12
13pub mod tof_event;
14pub use tof_event::TofEvent;
15
16pub mod rb_event;
17pub use rb_event::{
18 RBEvent,
19 unpack_traces
20};
21
22pub mod tracker_hit;
23pub use tracker_hit::TrackerHit;
24
25pub mod telemetry_event;
26pub use telemetry_event::TelemetryEvent;
27
28use std::fmt;
29
30use strum_macros::{
31 AsRefStr,
32 FromRepr,
33 EnumIter
34};
35#[cfg(feature="random")]
38use strum::IntoEnumIterator;
39use crate::expand_and_test_enum;
40
41#[cfg(feature="pybindings")]
42use pyo3::prelude::*;
43
44#[cfg(feature="random")]
45use crate::random::FromRandom;
46#[cfg(feature="random")]
47use rand::Rng;
48
49pub const LTB_CH0 : u16 = 0x3 ;
51pub const LTB_CH1 : u16 = 0xc ;
53pub const LTB_CH2 : u16 = 0x30 ;
55pub const LTB_CH3 : u16 = 0xc0 ;
57pub const LTB_CH4 : u16 = 0x300 ;
59pub const LTB_CH5 : u16 = 0xc00 ;
61pub const LTB_CH6 : u16 = 0x3000;
63pub const LTB_CH7 : u16 = 0xc000;
65pub const LTB_CHANNELS : [u16;8] = [
67 LTB_CH0,
68 LTB_CH1,
69 LTB_CH2,
70 LTB_CH3,
71 LTB_CH4,
72 LTB_CH5,
73 LTB_CH6,
74 LTB_CH7
75];
76
77pub const PHYSICAL_CHANNELS : [(u8, u8); 8] = [(1u8, 2u8), (3u8,4u8), (5u8, 6u8), (7u8, 8u8),
79 (9u8, 10u8), (11u8,12u8), (13u8, 14u8), (15u8, 16u8)];
80
81
82#[cfg_attr(feature="pybindings", pyfunction)]
93pub fn strip_id(layer : u8, row :u8, module : u8, channel : u8) -> u32 {
94 channel as u32 + (module as u32)*100 + (row as u32)*10000 + (layer as u32)*100000
95}
96
97#[cfg_attr(feature="pybindings", pyfunction)]
100pub fn mt_event_get_timestamp_abs48(mtb_timestamp : u32, gps_timestamp : u32, tiu_timestamp : u32) -> u64 {
101 let gps = gps_timestamp as u64;
102 let mut timestamp = mtb_timestamp as u64;
103 if timestamp < tiu_timestamp as u64 {
104 timestamp += u32::MAX as u64 + 1;
106 }
107 let gps_mult = match 100_000_000u64.checked_mul(gps) {
108 Some(result) => result,
110 None => {
111 0 }
115 };
116
117 let ts = gps_mult + (timestamp - tiu_timestamp as u64);
118 ts
119}
120
121#[derive(Debug, Copy, Clone, PartialEq,FromRepr, AsRefStr, EnumIter)]
122#[repr(u8)]
123#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
124pub enum EventQuality {
125 Unknown = 0u8,
126 Silver = 10u8,
127 Gold = 20u8,
128 Diamond = 30u8,
129 FourLeafClover = 40u8,
130}
131
132expand_and_test_enum!(EventQuality, test_eventquality_repr);
133
134#[derive(Debug, Copy, Clone, PartialEq,FromRepr, AsRefStr, EnumIter, serde::Serialize, serde::Deserialize)]
138#[repr(u8)]
139#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
140pub enum TriggerType {
141 Unknown = 0u8,
142 Any = 1u8,
144 Track = 2u8,
145 TrackCentral = 3u8,
146 Gaps = 4u8,
147 Gaps633 = 5u8,
148 Gaps422 = 6u8,
149 Gaps211 = 7u8,
150 TrackUmbCentral = 8u8,
151 Gaps1044 = 9u8,
152 UmbCube = 21u8,
155 UmbCubeZ = 22u8,
157 UmbCorCube = 23u8,
159 CorCubeSide = 24u8,
161 Umb3Cube = 25u8,
163 Poisson = 100u8,
165 Forced = 101u8,
166 FixedRate = 102u8,
167 ConfigurableTrigger = 200u8,
171}
172
173impl TriggerType {
174
175 pub fn transcode_trigger_sources(trigger_sources : u16) -> Vec<Self> {
178 let mut t_types = Vec::<Self>::new();
179 let gaps_trigger = trigger_sources >> 5 & 0x1 == 1;
180 if gaps_trigger {
181 t_types.push(TriggerType::Gaps);
182 }
183 let any_trigger = trigger_sources >> 6 & 0x1 == 1;
184 if any_trigger {
185 t_types.push(TriggerType::Any);
186 }
187 let forced_trigger = trigger_sources >> 7 & 0x1 == 1;
188 if forced_trigger {
189 t_types.push(TriggerType::Forced);
190 }
191 let track_trigger = trigger_sources >> 8 & 0x1 == 1;
192 if track_trigger {
193 t_types.push(TriggerType::Track);
194 }
195 let central_track_trigger
196 = trigger_sources >> 9 & 0x1 == 1;
197 if central_track_trigger {
198 t_types.push(TriggerType::TrackCentral);
199 }
200 t_types
201 }
202}
203
204#[cfg(feature="pybindings")]
205#[pymethods]
206impl TriggerType {
207 #[staticmethod]
208 #[pyo3(name="transcode_trigger_sources")]
209 fn transcode_trigger_sources_py(trigger_sources : u16) -> Vec<Self> {
210 TriggerType::transcode_trigger_sources(trigger_sources)
211 }
212}
213
214expand_and_test_enum!(TriggerType, test_triggertype_repr);
215
216#[derive(Debug, Copy, Clone, PartialEq,FromRepr, AsRefStr, EnumIter)]
221#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
222#[repr(u8)]
223pub enum LTBThreshold {
224 NoHit = 0u8,
225 Hit = 1u8,
227 Beta = 2u8,
229 Veto = 3u8,
231 Unknown = 255u8
234}
235
236expand_and_test_enum!(LTBThreshold, test_ltbthreshold_repr);
237
238#[derive(Debug, Copy, Clone, PartialEq,FromRepr, AsRefStr, EnumIter)]
241#[repr(u8)]
242#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
243pub enum EventStatus {
244 Unknown = 0u8,
245 CRC32Wrong = 10u8,
246 TailWrong = 11u8,
247 ChannelIDWrong = 12u8,
248 CellSyncErrors = 13u8,
251 ChnSyncErrors = 14u8,
254 CellAndChnSyncErrors = 15u8,
257 AnyDataMangling = 16u8,
260 IncompleteReadout = 21u8,
261 IncompatibleData = 22u8,
264 EventTimeOut = 23u8,
266 NoChannel9 = 24u8,
268 GoodNoCRCOrErrBitCheck = 39u8,
269 GoodNoCRCCheck = 40u8,
272 GoodNoErrBitCheck = 41u8,
275 Perfect = 42u8
276}
277
278#[cfg(feature = "pybindings")]
282#[pymethods]
283impl EventStatus {
284
285 #[getter]
286 fn __hash__(&self) -> usize {
287 (*self as u8) as usize
288 }
289}
290
291
292expand_and_test_enum!(EventStatus, test_eventstatus_repr);
293
294#[derive(Debug, Copy, Clone, PartialEq,FromRepr, AsRefStr, EnumIter, serde::Deserialize, serde::Serialize)]
301#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
302#[repr(u8)]
303pub enum DataType {
304 Unknown = 0u8,
305 VoltageCalibration = 10u8,
306 TimingCalibration = 20u8,
307 Noi = 30u8,
308 Physics = 40u8,
309 RBTriggerPeriodic = 50u8,
310 RBTriggerPoisson = 60u8,
311 MTBTriggerPoisson = 70u8,
312 }
314
315expand_and_test_enum!(DataType, test_datatype_repr);
316
317