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 pub fn to_u8(&self) -> u8 {
204 match self {
205 TriggerType::Unknown => {
206 return 0;
207 }
208 TriggerType::Poisson => {
209 return 100;
210 }
211 TriggerType::Forced => {
212 return 101;
213 }
214 TriggerType::FixedRate => {
215 return 102;
216 }
217 TriggerType::Any => {
218 return 1;
219 }
220 TriggerType::Track => {
221 return 2;
222 }
223 TriggerType::TrackCentral => {
224 return 3;
225 }
226 TriggerType::Gaps => {
227 return 4;
228 }
229 TriggerType::Gaps633 => {
230 return 5;
231 }
232 TriggerType::Gaps422 => {
233 return 6;
234 }
235 TriggerType::Gaps211 => {
236 return 7;
237 }
238 TriggerType::TrackUmbCentral => {
239 return 8;
240 }
241 TriggerType::Gaps1044 => {
242 return 9;
243 }
244 TriggerType::UmbCube => {
245 return 21;
246 }
247 TriggerType::UmbCubeZ => {
248 return 22;
249 }
250 TriggerType::UmbCorCube => {
251 return 23;
252 }
253 TriggerType::CorCubeSide => {
254 return 24;
255 }
256 TriggerType::Umb3Cube => {
257 return 25;
258 }
259 TriggerType::ConfigurableTrigger => {
260 return 200;
261 }
262 }
263 }
264}
265
266#[cfg(feature="pybindings")]
267#[pymethods]
268impl TriggerType {
269 #[staticmethod]
270 #[pyo3(name="transcode_trigger_sources")]
271 fn transcode_trigger_sources_py(trigger_sources : u16) -> Vec<Self> {
272 TriggerType::transcode_trigger_sources(trigger_sources)
273 }
274}
275
276expand_and_test_enum!(TriggerType, test_triggertype_repr);
277
278#[derive(Debug, Copy, Clone, PartialEq,FromRepr, AsRefStr, EnumIter)]
283#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
284#[repr(u8)]
285pub enum LTBThreshold {
286 NoHit = 0u8,
287 Hit = 1u8,
289 Beta = 2u8,
291 Veto = 3u8,
293 Unknown = 255u8
296}
297
298expand_and_test_enum!(LTBThreshold, test_ltbthreshold_repr);
299
300#[derive(Debug, Copy, Clone, PartialEq, Hash, Eq, FromRepr, AsRefStr, EnumIter)]
303#[repr(u8)]
304#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
305pub enum EventStatus {
306 Unknown = 0u8,
307 CRC32Wrong = 10u8,
308 TailWrong = 11u8,
309 ChannelIDWrong = 12u8,
310 CellSyncErrors = 13u8,
313 ChnSyncErrors = 14u8,
316 CellAndChnSyncErrors = 15u8,
319 AnyDataMangling = 16u8,
322 KnownDeadRB = 17u8,
326 IncompleteReadout = 21u8,
327 IncompatibleData = 22u8,
330 EventTimeOut = 23u8,
332 NoChannel9 = 24u8,
334 RBEventWacky = 25u8,
336 GoodNoCRCOrErrBitCheck = 39u8,
337 GoodNoCRCCheck = 40u8,
340 GoodNoErrBitCheck = 41u8,
343 Perfect = 42u8
344}
345
346#[cfg(feature = "pybindings")]
350#[pymethods]
351impl EventStatus {
352
353 #[getter]
354 fn __hash__(&self) -> usize {
355 (*self as u8) as usize
356 }
357}
358
359
360expand_and_test_enum!(EventStatus, test_eventstatus_repr);
361
362#[derive(Debug, Copy, Clone, PartialEq,FromRepr, AsRefStr, EnumIter, serde::Deserialize, serde::Serialize)]
369#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
370#[repr(u8)]
371pub enum DataType {
372 Unknown = 0u8,
373 VoltageCalibration = 10u8,
374 TimingCalibration = 20u8,
375 Noi = 30u8,
376 Physics = 40u8,
377 RBTriggerPeriodic = 50u8,
378 RBTriggerPoisson = 60u8,
379 MTBTriggerPoisson = 70u8,
380 }
382
383expand_and_test_enum!(DataType, test_datatype_repr);
384
385