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 tracker_daq_event;
26pub use tracker_daq_event::TrackerDAQEvent;
27
28pub mod tracker_daq_event_packet;
29pub use tracker_daq_event_packet::TrackerDAQEventPacket;
30
31pub mod telemetry_event;
32pub use telemetry_event::TelemetryEvent;
33
34pub mod mc_hit;
35pub use mc_hit::McHit;
36
37pub mod mc_track;
38pub use mc_track::McTrack;
39
40pub mod mc_event;
41pub use mc_event::McEvent;
42
43pub mod mc_tree;
44pub use mc_tree::McTree;
45
46use std::fmt;
47
48use strum_macros::{
49 AsRefStr,
50 FromRepr,
51 EnumIter
52};
53#[cfg(feature="random")]
56use strum::IntoEnumIterator;
57use crate::expand_and_test_enum;
58
59#[cfg(feature="pybindings")]
60use pyo3::prelude::*;
61
62#[cfg(feature="random")]
63use crate::random::FromRandom;
64#[cfg(feature="random")]
65use rand::Rng;
66
67pub const LTB_CH0 : u16 = 0x3 ;
69pub const LTB_CH1 : u16 = 0xc ;
71pub const LTB_CH2 : u16 = 0x30 ;
73pub const LTB_CH3 : u16 = 0xc0 ;
75pub const LTB_CH4 : u16 = 0x300 ;
77pub const LTB_CH5 : u16 = 0xc00 ;
79pub const LTB_CH6 : u16 = 0x3000;
81pub const LTB_CH7 : u16 = 0xc000;
83pub const LTB_CHANNELS : [u16;8] = [
85 LTB_CH0,
86 LTB_CH1,
87 LTB_CH2,
88 LTB_CH3,
89 LTB_CH4,
90 LTB_CH5,
91 LTB_CH6,
92 LTB_CH7
93];
94
95pub const PHYSICAL_CHANNELS : [(u8, u8); 8] = [(1u8, 2u8), (3u8,4u8), (5u8, 6u8), (7u8, 8u8),
97 (9u8, 10u8), (11u8,12u8), (13u8, 14u8), (15u8, 16u8)];
98
99
100#[cfg_attr(feature="pybindings", pyfunction)]
111pub fn strip_id(layer : u8, row :u8, module : u8, channel : u8) -> u32 {
112 channel as u32 + (module as u32)*100 + (row as u32)*10000 + (layer as u32)*100000
113}
114
115#[cfg_attr(feature="pybindings", pyfunction)]
118pub fn mt_event_get_timestamp_abs48(mtb_timestamp : u32, gps_timestamp : u32, tiu_timestamp : u32) -> u64 {
119 let gps = gps_timestamp as u64;
120 let mut timestamp = mtb_timestamp as u64;
121 if timestamp < tiu_timestamp as u64 {
122 timestamp += u32::MAX as u64 + 1;
124 }
125 let gps_mult = match 100_000_000u64.checked_mul(gps) {
126 Some(result) => result,
128 None => {
129 0 }
133 };
134
135 let ts = gps_mult + (timestamp - tiu_timestamp as u64);
136 ts
137}
138
139#[derive(Debug, Copy, Clone, PartialEq,FromRepr, AsRefStr, EnumIter)]
140#[repr(u8)]
141#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
142pub enum EventQuality {
143 Unknown = 0u8,
144 Silver = 10u8,
145 Gold = 20u8,
146 Diamond = 30u8,
147 FourLeafClover = 40u8,
148}
149
150expand_and_test_enum!(EventQuality, test_eventquality_repr);
151
152#[derive(Debug, Copy, Clone, PartialEq,FromRepr, AsRefStr, EnumIter, serde::Serialize, serde::Deserialize)]
161#[repr(u8)]
162#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
163pub enum TriggerType {
164 Unknown = 0u8,
165 Any = 1u8,
167 Track = 2u8,
169 TrackCentral = 3u8,
170 Gaps = 4u8,
175 Gaps633 = 5u8,
176 Gaps422 = 6u8,
177 Gaps211 = 7u8,
178 TrackUmbCentral = 8u8,
179 Gaps1044 = 9u8,
180 UmbCube = 21u8,
183 UmbCubeZ = 22u8,
185 UmbCorCube = 23u8,
187 CorCubeSide = 24u8,
189 Umb3Cube = 25u8,
191 Poisson = 100u8,
193 Forced = 101u8,
194 FixedRate = 102u8,
195 ConfigurableTrigger = 200u8,
199}
200
201impl TriggerType {
202
203 pub fn transcode_trigger_sources(trigger_sources : u16) -> Vec<Self> {
206 let mut t_types = Vec::<Self>::new();
207 let gaps_trigger = trigger_sources >> 5 & 0x1 == 1;
208 if gaps_trigger {
209 t_types.push(TriggerType::Gaps);
210 }
211 let any_trigger = trigger_sources >> 6 & 0x1 == 1;
212 if any_trigger {
213 t_types.push(TriggerType::Any);
214 }
215 let forced_trigger = trigger_sources >> 7 & 0x1 == 1;
216 if forced_trigger {
217 t_types.push(TriggerType::Forced);
218 }
219 let track_trigger = trigger_sources >> 8 & 0x1 == 1;
220 if track_trigger {
221 t_types.push(TriggerType::Track);
222 }
223 let central_track_trigger
224 = trigger_sources >> 9 & 0x1 == 1;
225 if central_track_trigger {
226 t_types.push(TriggerType::TrackCentral);
227 }
228 t_types
229 }
230
231 pub fn to_u8(&self) -> u8 {
232 match self {
233 TriggerType::Unknown => {
234 return 0;
235 }
236 TriggerType::Poisson => {
237 return 100;
238 }
239 TriggerType::Forced => {
240 return 101;
241 }
242 TriggerType::FixedRate => {
243 return 102;
244 }
245 TriggerType::Any => {
246 return 1;
247 }
248 TriggerType::Track => {
249 return 2;
250 }
251 TriggerType::TrackCentral => {
252 return 3;
253 }
254 TriggerType::Gaps => {
255 return 4;
256 }
257 TriggerType::Gaps633 => {
258 return 5;
259 }
260 TriggerType::Gaps422 => {
261 return 6;
262 }
263 TriggerType::Gaps211 => {
264 return 7;
265 }
266 TriggerType::TrackUmbCentral => {
267 return 8;
268 }
269 TriggerType::Gaps1044 => {
270 return 9;
271 }
272 TriggerType::UmbCube => {
273 return 21;
274 }
275 TriggerType::UmbCubeZ => {
276 return 22;
277 }
278 TriggerType::UmbCorCube => {
279 return 23;
280 }
281 TriggerType::CorCubeSide => {
282 return 24;
283 }
284 TriggerType::Umb3Cube => {
285 return 25;
286 }
287 TriggerType::ConfigurableTrigger => {
288 return 200;
289 }
290 }
291 }
292}
293
294#[cfg(feature="pybindings")]
295#[pymethods]
296impl TriggerType {
297 #[staticmethod]
298 #[pyo3(name="transcode_trigger_sources")]
299 fn transcode_trigger_sources_py(trigger_sources : u16) -> Vec<Self> {
300 TriggerType::transcode_trigger_sources(trigger_sources)
301 }
302}
303
304expand_and_test_enum!(TriggerType, test_triggertype_repr);
305
306#[derive(Debug, Copy, Clone, PartialEq,FromRepr, AsRefStr, EnumIter)]
311#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
312#[repr(u8)]
313pub enum LTBThreshold {
314 NoHit = 0u8,
315 Hit = 1u8,
317 Beta = 2u8,
319 Veto = 3u8,
321 Unknown = 255u8
324}
325
326expand_and_test_enum!(LTBThreshold, test_ltbthreshold_repr);
327
328#[derive(Debug, Copy, Clone, PartialEq, Hash, Eq, FromRepr, AsRefStr, EnumIter)]
331#[repr(u8)]
332#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
333pub enum EventStatus {
334 Unknown = 0u8,
335 CRC32Wrong = 10u8,
336 TailWrong = 11u8,
337 ChannelIDWrong = 12u8,
338 CellSyncErrors = 13u8,
341 ChnSyncErrors = 14u8,
344 CellAndChnSyncErrors = 15u8,
347 AnyDataMangling = 16u8,
350 KnownDeadRB = 17u8,
354 IncompleteReadout = 21u8,
355 IncompatibleData = 22u8,
358 EventTimeOut = 23u8,
360 NoChannel9 = 24u8,
362 RBEventWacky = 25u8,
364 GoodNoCRCOrErrBitCheck = 39u8,
365 GoodNoCRCCheck = 40u8,
368 GoodNoErrBitCheck = 41u8,
371 Perfect = 42u8
372}
373
374#[cfg(feature = "pybindings")]
378#[pymethods]
379impl EventStatus {
380
381 #[getter]
382 fn __hash__(&self) -> usize {
383 (*self as u8) as usize
384 }
385}
386
387
388expand_and_test_enum!(EventStatus, test_eventstatus_repr);
389
390#[derive(Debug, Copy, Clone, PartialEq,FromRepr, AsRefStr, EnumIter, serde::Deserialize, serde::Serialize)]
397#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
398#[repr(u8)]
399pub enum DataType {
400 Unknown = 0u8,
401 VoltageCalibration = 10u8,
402 TimingCalibration = 20u8,
403 Noi = 30u8,
404 Physics = 40u8,
405 RBTriggerPeriodic = 50u8,
406 RBTriggerPoisson = 60u8,
407 MTBTriggerPoisson = 70u8,
408 }
410
411expand_and_test_enum!(DataType, test_datatype_repr);
412
413