1use crate::prelude::*;
8
9#[derive(Debug, Copy, Clone, PartialEq, FromRepr, AsRefStr, EnumIter, serde::Deserialize, serde::Serialize)]
15#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
16#[repr(u8)]
17pub enum TofOperationMode {
18 Unknown = 0u8,
19 Default = 1u8,
20 RBHighThroughput = 30u8,
24 RBCalcCRC32 = 40u8,
25 RBWaveform = 50u8,
26}
27
28expand_and_test_enum!(TofOperationMode, test_tofoperationmode_repr);
29
30#[derive(Debug, Copy, Clone, PartialEq, serde::Serialize, serde::Deserialize, FromRepr, AsRefStr, EnumIter)]
35#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
36#[repr(u8)]
37pub enum BuildStrategy {
38 Unknown = 0,
39 Smart = 100,
40 Adaptive = 101,
42 AdaptiveThorough = 102,
45 AdaptiveGreedy = 1,
47 WaitForNBoards = 2,
48}
49
50expand_and_test_enum!(BuildStrategy, test_buildstrategy_repr);
51
52#[derive(Copy, Clone, Debug, PartialEq)]
56#[cfg_attr(feature="pybindings", pyclass)]
57pub struct PreampBiasConfig {
58 pub rb_id : u8,
59 pub biases : [f32;16]
60}
61
62impl PreampBiasConfig {
63 pub fn new() -> Self {
64 Self {
65 rb_id : 0,
66 biases : [0.0;16]
67 }
68 }
69}
70
71impl Default for PreampBiasConfig {
72 fn default() -> Self {
73 Self::new()
74 }
75}
76
77impl fmt::Display for PreampBiasConfig {
78 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
79 let mut repr = String::from("<PreampBiasConfig");
81 repr += &(format!("\n RB ID : {}", self.rb_id));
82 repr += " -- biases per channel:";
83 for k in 0..self.biases.len() {
84 repr += &(format!("\n Ch{} : {:.2}", k+1, self.biases[k]));
85 }
86 write!(f, "{}", repr)
87 }
88}
89
90impl TofPackable for PreampBiasConfig {
91 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::PreampBiasConfig;
92}
93
94impl Serialization for PreampBiasConfig {
95
96 const HEAD : u16 = 0xAAAA;
97 const TAIL : u16 = 0x5555;
98 const SIZE : usize = 69; fn from_bytestream(stream : &Vec<u8>,
101 pos : &mut usize)
102 -> Result<Self, SerializationError>{
103 Self::verify_fixed(stream, pos)?;
104 let mut cfg = PreampBiasConfig::new();
105 cfg.rb_id = parse_u8(stream, pos);
106 for k in 0..16 {
107 cfg.biases[k] = parse_f32(stream, pos);
108 }
109 *pos += 2;
110 Ok(cfg)
111 }
112
113 fn to_bytestream(&self) -> Vec<u8> {
114 let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
115 bs.extend_from_slice(&Self::HEAD.to_le_bytes());
116 bs.push(self.rb_id);
117 for k in 0..16 {
118 bs.extend_from_slice(&self.biases[k].to_le_bytes());
119 }
120 bs.extend_from_slice(&Self::TAIL.to_le_bytes());
121 bs
122 }
123}
124
125#[cfg(feature = "random")]
126impl FromRandom for PreampBiasConfig {
127 fn from_random() -> Self {
128 let mut cfg = PreampBiasConfig::new();
129 let mut rng = rand::rng();
130 cfg.rb_id = rng.random::<u8>();
131 for k in 0..16 {
132 cfg.biases[k] = rng.random::<f32>();
133 }
134 cfg
135 }
136}
137
138#[derive(Copy, Clone, Debug, PartialEq)]
141#[cfg_attr(feature="pybindings", pyclass)]
142pub struct RBChannelMaskConfig {
143 pub rb_id : u8,
144 pub channels : [bool;9],
145}
146
147impl RBChannelMaskConfig {
148 pub fn new() -> Self {
149 Self {
150 rb_id : 0,
151 channels : [false;9],
152 }
153 }
154}
155
156impl Default for RBChannelMaskConfig {
157 fn default() -> Self {
158 Self::new()
159 }
160}
161
162impl fmt::Display for RBChannelMaskConfig {
163 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
164 let mut repr = String::from("<RBCHannelMaskConfig");
165 repr += &(format!("\n RB ID : {}", self.rb_id));
166 repr += &(format!("\n Problematic Channels >:( {:?}", self.channels));
167 write!(f, "{}", repr)
168 }
169}
170
171impl TofPackable for RBChannelMaskConfig {
172 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::RBChannelMaskConfig;
173}
174
175impl Serialization for RBChannelMaskConfig {
176
177 const HEAD : u16 = 0xAAAA;
178 const TAIL : u16 = 0x5555;
179 const SIZE : usize = 14;
180
181 fn from_bytestream(stream : &Vec<u8>,
182 pos : &mut usize)
183 -> Result<Self, SerializationError>{
184 Self::verify_fixed(stream, pos)?;
185 let mut cfg = RBChannelMaskConfig::new();
186 cfg.rb_id = parse_u8(stream, pos);
187 for k in 0..9 {
188 cfg.channels[k] = parse_bool(stream, pos);
189 }
190 *pos += 2;
191 Ok(cfg)
192 }
193
194 fn to_bytestream(&self) -> Vec<u8> {
195 let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
196 bs.extend_from_slice(&Self::HEAD.to_le_bytes());
197 bs.push(self.rb_id);
198 for k in 0..9 {
199 bs.push(self.channels[k] as u8);
200 }
201 bs.extend_from_slice(&Self::TAIL.to_le_bytes());
202 bs
203 }
204}
205
206#[cfg(feature = "random")]
207impl FromRandom for RBChannelMaskConfig {
208 fn from_random() -> Self {
209 let mut cfg = RBChannelMaskConfig::new();
210 let mut rng = rand::rng();
211 cfg.rb_id = rng.random::<u8>();
212 for k in 0..9 {
213 cfg.channels[k] = rng.random::<bool>();
214 }
215 cfg
216 }
217}
218
219#[derive(Copy, Clone, Debug, PartialEq)]
224#[cfg_attr(feature="pybindings", pyclass)]
225pub struct LTBThresholdConfig {
226 pub rb_id : u8,
227 pub thresholds : [f32;3]
228}
229
230impl LTBThresholdConfig {
231 pub fn new() -> Self {
232 Self {
233 rb_id : 0,
234 thresholds : [0.0;3]
235 }
236 }
237}
238
239impl Default for LTBThresholdConfig {
240 fn default() -> Self {
241 Self::new()
242 }
243}
244
245impl fmt::Display for LTBThresholdConfig {
246 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
247 let mut repr = String::from("<LTBThresholdConfig");
248 repr += &(format!("\n RB ID : {}", self.rb_id));
249 repr += " -- thresholds per channel:";
250 for k in 0..self.thresholds.len() {
251 repr += &(format!("\n Ch{} : {:.3}", k, self.thresholds[k]));
252 }
253 write!(f, "{}", repr)
254 }
255}
256
257impl TofPackable for LTBThresholdConfig {
258 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::LTBThresholdConfig;
259}
260
261impl Serialization for LTBThresholdConfig {
262
263 const HEAD : u16 = 0xAAAA;
264 const TAIL : u16 = 0x5555;
265 const SIZE : usize = 17;
266
267 fn from_bytestream(stream : &Vec<u8>,
268 pos : &mut usize)
269 -> Result<Self, SerializationError>{
270 Self::verify_fixed(stream, pos)?;
271 let mut cfg = LTBThresholdConfig::new();
272 cfg.rb_id = parse_u8(stream, pos);
273 for k in 0..3 {
274 cfg.thresholds[k] = parse_f32(stream, pos);
275 }
276 *pos += 2;
277 Ok(cfg)
278 }
279
280 fn to_bytestream(&self) -> Vec<u8> {
281 let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
282 bs.extend_from_slice(&Self::HEAD.to_le_bytes());
283 bs.push(self.rb_id);
284 for k in 0..3 {
285 bs.extend_from_slice(&self.thresholds[k].to_le_bytes());
286 }
287 bs.extend_from_slice(&Self::TAIL.to_le_bytes());
288 bs
289 }
290}
291
292#[cfg(feature = "random")]
293impl FromRandom for LTBThresholdConfig {
294 fn from_random() -> Self {
295 let mut cfg = LTBThresholdConfig::new();
296 let mut rng = rand::rng();
297 cfg.rb_id = rng.random::<u8>();
298 for k in 0..3 {
299 cfg.thresholds[k] = rng.random::<f32>();
300 }
301 cfg
302 }
303}
304
305
306#[derive(Debug, Copy, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
308#[cfg_attr(feature="pybindings", pyclass)]
309pub struct RunConfig {
310 pub runid : u32,
312 pub is_active : bool,
315 pub nevents : u32,
317 pub nseconds : u32,
319 pub tof_op_mode : TofOperationMode,
322 pub trigger_poisson_rate : u32,
325 pub trigger_fixed_rate : u32,
328 pub data_type : DataType,
332 pub rb_buff_size : Option<u16>,
338 pub rb_buff_empty_interval : Option<f32>,
340 pub rb_buff_strategy_smart : bool
342}
343
344impl RunConfig {
345
346 pub fn new() -> Self {
347 Self {
348 runid : 0,
349 is_active : false,
350 nevents : 0,
351 nseconds : 0,
352 tof_op_mode : TofOperationMode::Default,
353 trigger_poisson_rate : 0,
354 trigger_fixed_rate : 0,
355 data_type : DataType::Unknown,
356 rb_buff_size : None,
357 rb_buff_empty_interval : None,
358 rb_buff_strategy_smart : true,
359 }
360 }
361}
362
363impl Default for RunConfig {
410 fn default() -> Self {
411 Self::new()
412 }
413}
414
415impl fmt::Display for RunConfig {
416 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
417 if !self.is_active {
418 return write!(f, "<RunConfig -- is_active : false>");
419 } else {
420 write!(f,
421"<RunConfig -- is_active : true
422 nevents : {}
423 nseconds : {}
424 TOF op. mode : {}
425 data type : {}
426 tr_poi_rate : {}
427 tr_fix_rate : {}
428 buff size : {} [events],
429 buff_empty_interv : {} [seconds],
430 buff_strat_smart : {}>",
431 self.nevents,
432 self.nseconds,
433 self.tof_op_mode,
434 self.data_type,
435 self.trigger_poisson_rate,
436 self.trigger_fixed_rate,
437 self.rb_buff_size.unwrap_or(0),
438 self.rb_buff_empty_interval.unwrap_or(0.0),
439 self.rb_buff_strategy_smart)
440 }
441 }
442}
443
444impl TofPackable for RunConfig {
445 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::RunConfig;
446}
447
448#[derive(Copy, Clone, Debug, PartialEq)]
472#[cfg_attr(feature="pybindings", pyclass)]
473pub struct TriggerConfig{
474 pub active_fields : u32,
479 pub gaps_trigger_use_beta : Option<bool>, pub prescale : Option<f32>, pub trigger_type : Option<TriggerType>, pub use_combo_trigger : Option<bool>,
484 pub combo_trigger_type : Option<TriggerType>,
485 pub combo_trigger_prescale : Option<f32>,
486 pub trace_suppression : Option<bool>,
487 pub mtb_moni_interval : Option<u16>,
488 pub tiu_ignore_busy : Option<bool>,
489 pub hb_send_interval : Option<u16>,
490}
491
492impl TriggerConfig {
493 pub fn new() -> Self {
494 Self {
495 active_fields : 0,
496 gaps_trigger_use_beta : None,
497 prescale : None,
498 trigger_type : None,
499 use_combo_trigger : None,
500 combo_trigger_type : None,
501 combo_trigger_prescale : None,
502 trace_suppression : None,
503 mtb_moni_interval : None,
504 tiu_ignore_busy : None,
505 hb_send_interval : None,
506 }
507 }
508
509 pub fn set_gaps_trigger_use_beta(&mut self, use_it : bool) {
510 self.active_fields |= 1;
511 self.gaps_trigger_use_beta = Some(use_it);
512 }
513
514 pub fn set_prescale(&mut self, prescale : f32) {
515 self.active_fields |= 2;
516 self.prescale = Some(prescale);
517 }
518
519 pub fn set_trigger_type(&mut self, ttype : TriggerType) {
520 self.active_fields |= 4;
521 self.trigger_type = Some(ttype);
522 }
523
524 pub fn set_use_combo_trigger(&mut self, combo : bool) {
525 self.active_fields |= 8;
526 self.use_combo_trigger = Some(combo);
527 }
528
529 pub fn set_combo_trigger_type(&mut self, ttype : TriggerType) {
530 self.active_fields |= 16;
531 self.combo_trigger_type = Some(ttype)
532 }
533
534 pub fn set_combo_trigger_prescale(&mut self, prescale : f32) {
535 self.active_fields |= 32;
536 self.combo_trigger_prescale = Some(prescale);
537 }
538
539 pub fn set_trace_suppression(&mut self, tsup : bool) {
540 self.active_fields |= 64;
541 self.trace_suppression = Some(tsup);
542 }
543
544 pub fn set_mtb_moni_interval(&mut self, interval : u16) {
545 self.active_fields |= 128;
546 self.mtb_moni_interval = Some(interval);
547 }
548
549 pub fn set_tiu_ignore_busy(&mut self, busy : bool) {
550 self.active_fields |= 256;
551 self.tiu_ignore_busy = Some(busy);
552 }
553
554 pub fn set_hb_send_interval(&mut self, interval : u16) {
555 self.active_fields |= 512;
556 self.hb_send_interval = Some(interval);
557 }
558}
559
560impl Default for TriggerConfig {
561 fn default() -> Self {
562 Self::new()
563 }
564}
565
566impl fmt::Display for TriggerConfig {
567 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
568 let mut repr = String::from("<TriggerConfig: ");
569 repr += &(format!("(active fields {:x})", self.active_fields));
570 if self. gaps_trigger_use_beta.is_some() {
571 repr += &(format!("\n Beta is used by trigger : {}", self.gaps_trigger_use_beta.unwrap()));
572 }
573 if self. prescale.is_some() {
574 repr += &(format!("\n Prescale : {:.3}", self.prescale.unwrap()));
575 }
576 if self.trigger_type.is_some() {
577 repr += &(format!("\n Trigger type : {}", self.trigger_type.unwrap()));
578 }
579 if self.use_combo_trigger.is_some() {
580 if self.use_combo_trigger.unwrap() {
581 repr += &(format!("\n -- using combo trigger!"));
582 }
583 }
584 if self.combo_trigger_prescale.is_some() {
585 repr += &(format!("\n -- -- Combo Prescale : {:.3}", self.combo_trigger_prescale.unwrap()));
586 }
587 if self.combo_trigger_type.is_some() {
588 repr += &(format!("\n -- -- Combo Trigger type : {}", self.combo_trigger_type.unwrap()));
589 }
590 if self. trace_suppression.is_some() {
591 repr += &(format!("\n trace_suppression : {}", self.trace_suppression.unwrap()));
592 }
593 if self.mtb_moni_interval.is_some() {
594 repr += &(format!("\n mtb_moni_interval : {}", self.mtb_moni_interval.unwrap()));
595 }
596 if self.tiu_ignore_busy.is_some() {
597 repr += &(format!("\n tiu_ignore_busy : {}", self.tiu_ignore_busy.unwrap()));
598 }
599 if self.hb_send_interval.is_some() {
600 repr += &(format!("\n hb_send_interval : {}", self.hb_send_interval.unwrap()));
601 }
602 repr += ">";
603 write!(f, "{}", repr)
604 }
605}
606
607impl TofPackable for TriggerConfig {
608 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::TriggerConfig;
609}
610
611impl Serialization for TriggerConfig {
612
613 const HEAD : u16 = 0xAAAA;
614 const TAIL : u16 = 0x5555;
615 const SIZE : usize = 26;
616
617 fn from_bytestream(stream : &Vec<u8>,
618 pos : &mut usize)
619 -> Result<Self, SerializationError>{
620 Self::verify_fixed(stream, pos)?;
621 let mut cfg = TriggerConfig::new();
622 cfg.active_fields = parse_u32(stream, pos);
623 cfg.gaps_trigger_use_beta = Some(parse_bool(stream, pos));
624 cfg.prescale = Some(parse_f32 (stream, pos));
625 cfg.trigger_type = Some(TriggerType::from(parse_u8(stream, pos)));
626 cfg.use_combo_trigger = Some(parse_bool(stream, pos));
627 cfg.combo_trigger_type = Some(TriggerType::from(parse_u8(stream, pos)));
628 cfg.combo_trigger_prescale = Some(parse_f32(stream, pos));
629 cfg.trace_suppression = Some(parse_bool(stream, pos));
630 cfg.mtb_moni_interval = Some(parse_u16(stream, pos));
631 cfg.tiu_ignore_busy = Some(parse_bool(stream, pos));
632 cfg.hb_send_interval = Some(parse_u16(stream, pos));
633 if cfg.active_fields & 1 != 1 {
636 cfg.gaps_trigger_use_beta = None;
637 }
638 if cfg.active_fields & 2 != 2 {
639 cfg.prescale = None;
640 }
641 if cfg.active_fields & 4 != 4 {
642 cfg.trigger_type = None;
643 }
644 if cfg.active_fields & 8 != 8 {
645 cfg.use_combo_trigger = None;
646 }
647 if cfg.active_fields & 16 != 16 {
648 cfg.combo_trigger_type = None;
649 }
650 if cfg.active_fields & 32 != 32 {
651 cfg.combo_trigger_prescale = None;
652 }
653 if cfg.active_fields & 64 != 64 {
654 cfg.trace_suppression = None;
655 }
656 if cfg.active_fields & 128 != 128 {
657 cfg.mtb_moni_interval = None;
658 }
659 if cfg.active_fields & 256 != 256 {
660 cfg.tiu_ignore_busy = None;
661 }
662 if cfg.active_fields & 512 != 512 {
663 cfg.hb_send_interval = None;
664 }
665 *pos += 2;
666 Ok(cfg)
667 }
668
669 fn to_bytestream(&self) -> Vec<u8> {
670 let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
671 bs.extend_from_slice(&Self::HEAD .to_le_bytes());
672 bs.extend_from_slice(&self.active_fields.to_le_bytes());
673 bs.push (self.gaps_trigger_use_beta.unwrap_or(false) as u8);
674 bs.extend_from_slice(&self.prescale.unwrap_or(0.0) .to_le_bytes());
675 bs.push (self.trigger_type.unwrap_or(TriggerType::Unknown) as u8);
676 bs.push (self.use_combo_trigger.unwrap_or(false) as u8);
677 bs.push (self.combo_trigger_type.unwrap_or(TriggerType::Unknown) as u8);
678 bs.extend_from_slice(&self.combo_trigger_prescale.unwrap_or(0.0).to_le_bytes());
679 bs.push (self.trace_suppression.unwrap_or(false) as u8);
680 bs.extend_from_slice(&self.mtb_moni_interval.unwrap_or(30).to_le_bytes());
681 bs.push (self.tiu_ignore_busy.unwrap_or(false) as u8);
682 bs.extend_from_slice(&self.hb_send_interval.unwrap_or(30).to_le_bytes());
683 bs.extend_from_slice(&Self::TAIL.to_le_bytes());
684 bs
685 }
686}
687
688#[cfg(feature = "random")]
689impl FromRandom for TriggerConfig {
690 fn from_random() -> Self {
691 let mut cfg = TriggerConfig::new();
692 let mut rng = rand::rng();
693 let active_fields = rng.random::<u32>();
694 cfg.active_fields = active_fields;
695 if active_fields & 1 == 1 {
696 cfg.gaps_trigger_use_beta = Some(rng.random::<bool>());
697 } else {
698 cfg.gaps_trigger_use_beta = None;
699 }
700 if active_fields & 2 == 2 {
701 cfg.prescale = Some(rng.random::<f32>());
702 } else {
703 cfg.prescale = None;
704 }
705 if active_fields & 4 == 4 {
706 cfg.trigger_type = Some(TriggerType::from_random());
707 } else {
708 cfg.trigger_type = None;
709 }
710 if active_fields & 8 == 8 {
711 cfg.use_combo_trigger = Some(rng.random::<bool>());
712 } else {
713 cfg.use_combo_trigger = None;
714 }
715 if active_fields & 16 == 16 {
716 cfg.combo_trigger_type = Some(TriggerType::from_random());
717 } else {
718 cfg.combo_trigger_type = None;
719 }
720 if active_fields & 32 == 32 {
721 cfg.combo_trigger_prescale = Some(rng.random::<f32>());
722 } else {
723 cfg.combo_trigger_prescale = None;
724 }
725 if active_fields & 64 == 64 {
726 cfg.trace_suppression = Some(rng.random::<bool>());
727 } else {
728 cfg.trace_suppression = None;
729 }
730 if active_fields & 128 == 128 {
731 cfg.mtb_moni_interval = Some(rng.random::<u16>());
732 } else {
733 cfg.mtb_moni_interval = None;
734 }
735 if active_fields & 256 == 256 {
736 cfg.tiu_ignore_busy = Some(rng.random::<bool>());
737 } else {
738 cfg.tiu_ignore_busy = None;
739 }
740 if active_fields & 512 == 512 {
741 cfg.hb_send_interval = Some(rng.random::<u16>());
742 } else {
743 cfg.hb_send_interval = None;
744 }
745 cfg
746 }
747}
748
749#[cfg(feature="pybindings")]
750#[pymethods]
751impl TriggerConfig {
752
753 #[getter]
754 fn get_prescale(&self) -> Option<f32> {
755 self.prescale
756 }
757
758 #[setter]
759 #[pyo3(name="set_prescale")]
760 fn set_prescale_py(&mut self, prescale: f32) -> PyResult<()> {
761 self.set_prescale (prescale);
762 Ok(())
763 }
764
765 #[getter]
766 fn get_gaps_trigger_use_beta(&self) -> Option<bool> {
767 self.gaps_trigger_use_beta
768 }
769
770 #[setter]
771 #[pyo3(name="set_gaps_trigger_use_beta")]
772 fn set_gaps_trigger_use_beta_py(&mut self, gaps_trigger_use_beta: bool) -> PyResult<()> {
773 self.set_gaps_trigger_use_beta(gaps_trigger_use_beta);
774 Ok(())
775 }
776
777 #[getter]
778 fn get_trigger_type(&self) -> Option<TriggerType> {
779 self.trigger_type
780 }
781
782 #[setter]
783 #[pyo3(name="set_trigger_type")]
784 fn set_trigger_type_py(&mut self, trigger_type: TriggerType) -> PyResult<()> {
785 self.set_trigger_type(trigger_type);
786 Ok(())
787 }
788
789 #[getter]
790 fn get_use_combo_trigger(&self) -> Option<bool> {
791 self.use_combo_trigger
792 }
793 #[setter]
794 #[pyo3(name="set_use_combo_trigger")]
795 fn set_use_combo_trigger_py(&mut self, combo : bool) {
796 self.set_use_combo_trigger(combo);
797 }
798 #[getter]
799 fn get_combo_trigger_type(&self) -> Option<TriggerType> {
800 self.combo_trigger_type
801 }
802 #[setter]
803 #[pyo3(name="set_combo_trigger_type")]
804 fn set_combo_trigger_type_py(&mut self, combo_trigger_type : TriggerType) {
805 self.set_combo_trigger_type(combo_trigger_type);
806 }
807 #[getter]
808 fn get_combo_trigger_prescale(&self) -> Option<f32> {
809 self.combo_trigger_prescale
810 }
811 #[setter]
812 #[pyo3(name="set_combo_trigger_prescale")]
813 fn set_combo_trigger_prescale_py(&mut self, prescale : f32) {
814 self.set_combo_trigger_prescale(prescale);
815 }
816 #[getter]
817 fn get_trace_suppression(&self) -> Option<bool> {
818 self.trace_suppression
819 }
820 #[setter]
821 #[pyo3(name="set_trace_suppression")]
822 fn set_trace_suppression_py(&mut self, tsup : bool) {
823 self.set_trace_suppression(tsup);
824 }
825 #[getter]
826 fn get_mtb_moni_interval(&mut self) -> Option<u16> {
827 self.mtb_moni_interval
828 }
829 #[setter]
830 #[pyo3(name="set_mtb_moni_interval")]
831 fn set_mtb_moni_interval_py(&mut self, moni_int : u16) {
832 self.set_mtb_moni_interval(moni_int);
833 }
834 #[getter]
835 fn get_tiu_ignore_busy(&self) -> Option<bool> {
836 self.tiu_ignore_busy
837 }
838
839 #[setter]
840 #[pyo3(name="set_tiu_ignore_busy")]
841 fn set_tiu_ignore_busy_py(&mut self, ignore_busy : bool) {
842 self.set_tiu_ignore_busy(ignore_busy);
843 }
844 #[getter]
845 fn get_hb_send_interval(&self) -> Option<u16> {
846 self.hb_send_interval
847 }
848
849 #[pyo3(name="to_bytestream")]
850 fn to_bytestream_py(&self) -> Vec<u8> {
851 self.to_bytestream()
852 }
853
854 #[setter]
855 #[pyo3(name="set_hb_send_interval")]
856 fn set_hb_send_interval_py(&mut self, hb_int : Option<u16>) {
857 self.hb_send_interval = hb_int;
858 }
859
860 fn __getitem__<'a>(&self, py: Python<'a>, key: &str) -> PyResult<Option<Bound<'a,PyAny>>> {
861 match key {
862 "gaps_trigger_use_beta" => Ok(Some(self.gaps_trigger_use_beta .into_pyobject(py).unwrap())),
863 "prescale" => Ok(Some(self.prescale .into_pyobject(py).unwrap())),
864 "trigger_type" => Ok(Some(self.trigger_type .into_pyobject(py).unwrap())),
865 "use_combo_trigger" => Ok(Some(self.use_combo_trigger .into_pyobject(py).unwrap())),
866 "combo_trigger_type" => Ok(Some(self.combo_trigger_type .into_pyobject(py).unwrap())),
867 "combo_trigger_prescale" => Ok(Some(self.combo_trigger_prescale.into_pyobject(py).unwrap())),
868 "trace_suppression" => Ok(Some(self.trace_suppression .into_pyobject(py).unwrap())),
869 "mtb_moni_interval" => Ok(Some(self.mtb_moni_interval .into_pyobject(py).unwrap())),
870 "tiu_ignore_busy" => Ok(Some(self.tiu_ignore_busy .into_pyobject(py).unwrap())),
871 "hb_send_interval" => Ok(Some(self.hb_send_interval .into_pyobject(py).unwrap())),
872 _ => Err(PyKeyError::new_err(format!("Key '{}' not found", key)))
873 }
874 }
875
876 fn __setitem__(&mut self, key: &str, value: &Bound<'_, PyAny>) -> PyResult<()> {
877 match key {
878 "gaps_trigger_use_beta" => {
879 self.active_fields |= 1;
880 self.gaps_trigger_use_beta = Some(value.extract::<bool>()?);
881 Ok(())
882 }
883 "prescale" => {
884 self.active_fields |= 2;
885 self.prescale = Some(value.extract::<f32>()?);
886 Ok(())
887 }
888 "trigger_type" => {
889 self.active_fields |= 4;
890 self.trigger_type = Some(value.extract::<TriggerType>()?);
891 Ok(())
892 }
893 "use_combo_trigger" => {
894 self.active_fields |= 8;
895 self.use_combo_trigger = Some(value.extract::<bool>()?);
896 Ok(())
897 }
898 "combo_trigger_type" => {
899 self.active_fields |= 16;
900 self.combo_trigger_type = Some(value.extract::<TriggerType>()?);
901 Ok(())
902 }
903 "combo_trigger_prescale" => {
904 self.active_fields |= 32;
905 self.combo_trigger_prescale = Some(value.extract::<f32>()?);
906 Ok(())
907 }
908 "trace_suppression" => {
909 self.active_fields |= 64;
910 self.trace_suppression = Some(value.extract::<bool>()?);
911 Ok(())
912 }
913 "mtb_moni_interval" => {
914 self.active_fields |= 128;
915 self.mtb_moni_interval = Some(value.extract::<u16>()?);
916 Ok(())
917 }
918 "tiu_ignore_busy" => {
919 self.active_fields |= 256;
920 self.tiu_ignore_busy = Some(value.extract::<bool>()?);
921 Ok(())
922 }
923 "hb_send_interval" => {
924 self.active_fields |= 512;
925 self.hb_send_interval = Some(value.extract::<u16>()?);
926 Ok(())
927 }
928 _ => Err(PyKeyError::new_err(format!("Key '{}' not found", key))),
929 }
930 }
931}
932
933#[cfg(feature="pybindings")]
934pythonize_packable!(TriggerConfig);
935
936#[derive(Copy, Clone, Debug, PartialEq)]
939#[cfg_attr(feature="pybindings", pyclass)]
940pub struct TofRunConfig {
941 pub active_fields : u32,
942 pub runtime : Option<u32>,
943}
944
945impl TofRunConfig {
946 pub fn new() -> Self {
947 Self {
948 active_fields : 0,
949 runtime : None
950 }
951 }
952
953 pub fn set_runtime(&mut self, runtime : u32) {
954 self.active_fields |= 1;
955 self.runtime = Some(runtime);
956 }
957}
958
959impl Default for TofRunConfig {
960 fn default() -> Self {
961 Self::new()
962 }
963}
964
965impl fmt::Display for TofRunConfig {
966 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
967 let mut repr = String::from("<TofRunConfig: ");
968 repr += &(format!("(active fields {:x})", self.active_fields));
969 if self.runtime.is_some() {
970 repr += &(format!("\n Run time : {} [s]", self.runtime.unwrap()));
971 }
972 repr += ">";
973 write!(f, "{}", repr)
974 }
975}
976
977impl TofPackable for TofRunConfig {
978 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::TofRunConfig;
979}
980
981impl Serialization for TofRunConfig {
982
983 const HEAD : u16 = 0xAAAA;
984 const TAIL : u16 = 0x5555;
985 const SIZE : usize = 12;
986
987 fn from_bytestream(stream : &Vec<u8>,
988 pos : &mut usize)
989 -> Result<Self, SerializationError>{
990 Self::verify_fixed(stream, pos)?;
991 let mut cfg = TofRunConfig::new();
992 cfg.active_fields = parse_u32(stream, pos);
993 cfg.runtime = Some(parse_u32 (stream, pos));
994 if cfg.active_fields & 1 != 1 {
997 cfg.runtime = None;
998 }
999 *pos += 2;
1000 Ok(cfg)
1001 }
1002
1003 fn to_bytestream(&self) -> Vec<u8> {
1004 let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
1005 bs.extend_from_slice(&Self::HEAD .to_le_bytes());
1006 bs.extend_from_slice(&self.active_fields.to_le_bytes());
1007 bs.extend_from_slice(&self.runtime.unwrap_or(0).to_le_bytes());
1008 bs.extend_from_slice(&Self::TAIL.to_le_bytes());
1009 bs
1010 }
1011}
1012
1013#[cfg(feature = "random")]
1014impl FromRandom for TofRunConfig {
1015 fn from_random() -> Self {
1016 let mut cfg = Self::new();
1017 let mut rng = rand::rng();
1018 let active_fields = rng.random::<u32>();
1019 cfg.active_fields = active_fields;
1020 if active_fields & 1 == 1 {
1021 cfg.runtime = Some(rng.random::<u32>());
1022 }
1023 cfg
1024 }
1025}
1026
1027#[cfg(feature="pybindings")]
1028#[pymethods]
1029impl TofRunConfig {
1030
1031 #[getter]
1032 fn get_runtime(&self) -> Option<u32> {
1033 self.runtime
1034 }
1035
1036 #[setter]
1037 #[pyo3(name="set_runtime")]
1038 fn set_runtime_py(&mut self, runtime : u32) {
1039 self.set_runtime(runtime);
1040 }
1041}
1042
1043#[cfg(feature="pybindings")]
1044pythonize_packable!(TofRunConfig);
1045
1046#[derive(Copy, Clone, Debug, PartialEq)]
1049#[cfg_attr(feature="pybindings", pyclass)]
1050pub struct TofRBConfig {
1051 pub active_fields : u32,
1052 pub rb_moni_interval : Option<u32>,
1053 pub pb_moni_every_x : Option<u32>,
1054 pub pa_moni_every_x : Option<u32>,
1055 pub ltb_moni_every_x : Option<u32>,
1056 pub drs_deadtime_instead_fpga_temp : Option<bool>,
1057}
1058
1059impl TofRBConfig {
1060 pub fn new() -> Self {
1061 Self {
1062 active_fields : 0,
1063 rb_moni_interval : None,
1064 pb_moni_every_x : None,
1065 pa_moni_every_x : None,
1066 ltb_moni_every_x : None,
1067 drs_deadtime_instead_fpga_temp : None,
1068 }
1069 }
1070
1071 pub fn set_rb_moni_interval(&mut self, interval : u32) {
1072 self.active_fields |= 1;
1073 self.rb_moni_interval = Some(interval);
1074 }
1075
1076 pub fn set_pb_moni_every_x(&mut self, interval : u32) {
1077 self.active_fields |= 2;
1078 self.pb_moni_every_x = Some(interval);
1079 }
1080
1081 pub fn set_pa_moni_every_x(&mut self, interval : u32) {
1082 self.active_fields |= 4;
1083 self.pa_moni_every_x = Some(interval);
1084 }
1085
1086 pub fn set_ltb_moni_every_x(&mut self, interval : u32) {
1087 self.active_fields |= 8;
1088 self.ltb_moni_every_x = Some(interval);
1089 }
1090
1091 pub fn set_drs_deadtime_instead_fpga_temp(&mut self, apply : bool) {
1092 self.active_fields |= 16;
1093 self.drs_deadtime_instead_fpga_temp = Some(apply);
1094 }
1095}
1096
1097impl Default for TofRBConfig {
1098 fn default() -> Self {
1099 Self::new()
1100 }
1101}
1102
1103impl fmt::Display for TofRBConfig {
1104 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1105 let mut repr = String::from("<TofRBConfig: ");
1106 repr += &(format!("(active fields {:x})", self.active_fields));
1107 if self.rb_moni_interval.is_some() {
1108 repr += &(format!("\n RBMoni interval : {} [s]", self.rb_moni_interval.unwrap()));
1109 }
1110 if self.pa_moni_every_x.is_some() {
1111 repr += &(format!("\n PAMoni interval : {} [xRBMoni]", self.pa_moni_every_x.unwrap()));
1112 }
1113 if self.pb_moni_every_x.is_some() {
1114 repr += &(format!("\n PBMoni interval : {} [xRBMoni]", self.pb_moni_every_x.unwrap()));
1115 }
1116 if self.ltb_moni_every_x.is_some() {
1117 repr += &(format!("\n LTBMoni interval : {} [xRBMoni]", self.ltb_moni_every_x.unwrap()));
1118 }
1119 if self.drs_deadtime_instead_fpga_temp.is_some() {
1120 if self.drs_deadtime_instead_fpga_temp.unwrap() {
1121 repr += &(format!("\n -- using the fpga temp field to store drs deadtime values"));
1122 }
1123 }
1124 repr += ">";
1125 write!(f, "{}", repr)
1126 }
1127}
1128
1129impl TofPackable for TofRBConfig {
1130 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::TofRBConfig;
1131}
1132
1133impl Serialization for TofRBConfig {
1134
1135 const HEAD : u16 = 0xAAAA;
1136 const TAIL : u16 = 0x5555;
1137 const SIZE : usize = 25;
1138
1139 fn from_bytestream(stream : &Vec<u8>,
1140 pos : &mut usize)
1141 -> Result<Self, SerializationError>{
1142 Self::verify_fixed(stream, pos)?;
1143 let mut cfg = Self::new();
1144 cfg.active_fields = parse_u32(stream, pos);
1145 cfg.rb_moni_interval = Some(parse_u32 (stream, pos));
1146 cfg.pa_moni_every_x = Some(parse_u32 (stream, pos));
1147 cfg.pb_moni_every_x = Some(parse_u32 (stream, pos));
1148 cfg.ltb_moni_every_x = Some(parse_u32 (stream, pos));
1149 cfg.drs_deadtime_instead_fpga_temp = Some(parse_bool (stream, pos));
1150 if cfg.active_fields & 1 != 1 {
1153 cfg.rb_moni_interval = None;
1154 }
1155 if cfg.active_fields & 2 != 2 {
1156 cfg.pa_moni_every_x = None;
1157 }
1158 if cfg.active_fields & 4 != 4 {
1159 cfg.pb_moni_every_x = None;
1160 }
1161 if cfg.active_fields & 8 != 8 {
1162 cfg.ltb_moni_every_x = None;
1163 }
1164 if cfg.active_fields & 16 != 16 {
1165 cfg.drs_deadtime_instead_fpga_temp = None;
1166 }
1167 *pos += 2;
1168 Ok(cfg)
1169 }
1170
1171 fn to_bytestream(&self) -> Vec<u8> {
1172 let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
1173 bs.extend_from_slice(&Self::HEAD .to_le_bytes());
1174 bs.extend_from_slice(&self.active_fields.to_le_bytes());
1175 bs.extend_from_slice(&self.rb_moni_interval.unwrap_or(0).to_le_bytes());
1176 bs.extend_from_slice(&self.pa_moni_every_x.unwrap_or(0).to_le_bytes());
1177 bs.extend_from_slice(&self.pb_moni_every_x.unwrap_or(0).to_le_bytes());
1178 bs.extend_from_slice(&self.ltb_moni_every_x.unwrap_or(0).to_le_bytes());
1179 bs.push (self.drs_deadtime_instead_fpga_temp.unwrap_or(false) as u8);
1180 bs.extend_from_slice(&Self::TAIL.to_le_bytes());
1181 bs
1182 }
1183}
1184
1185#[cfg(feature = "random")]
1186impl FromRandom for TofRBConfig {
1187 fn from_random() -> Self {
1188 let mut cfg = Self::new();
1189 let mut rng = rand::rng();
1190 let active_fields = rng.random::<u32>();
1191 cfg.active_fields = active_fields;
1192 if active_fields & 1 == 1 {
1193 cfg.rb_moni_interval = Some(rng.random::<u32>());
1194 }
1195 if active_fields & 2 == 2 {
1196 cfg.pa_moni_every_x = Some(rng.random::<u32>());
1197 }
1198 if active_fields & 4 == 4 {
1199 cfg.pb_moni_every_x = Some(rng.random::<u32>());
1200 }
1201 if active_fields & 8 == 8 {
1202 cfg.ltb_moni_every_x = Some(rng.random::<u32>());
1203 }
1204 if active_fields & 16 == 16 {
1205 cfg.drs_deadtime_instead_fpga_temp = Some(rng.random::<bool>());
1206 }
1207 cfg
1208 }
1209}
1210
1211#[derive(Copy, Clone, Debug, PartialEq)]
1216#[cfg_attr(feature="pybindings", pyclass)]
1217pub struct DataPublisherConfig {
1218 pub active_fields : u32,
1219 pub mbytes_per_file : Option<u16>,
1220 pub discard_event_fraction : Option<f32>,
1221 pub send_mtb_event_packets : Option<bool>,
1222 pub send_rbwaveform_packets : Option<bool>,
1223 pub send_rbwf_every_x_event : Option<u32>,
1224 pub send_tof_summary_packets : Option<bool>,
1225 pub send_tof_event_packets : Option<bool>,
1226 pub hb_send_interval : Option<u16>,
1227}
1228
1229impl DataPublisherConfig {
1230 pub fn new() -> Self {
1231 Self {
1232 active_fields : 0,
1233 mbytes_per_file : None,
1234 discard_event_fraction : None,
1235 send_mtb_event_packets : None,
1236 send_rbwaveform_packets : None,
1237 send_rbwf_every_x_event : None,
1238 send_tof_summary_packets : None,
1239 send_tof_event_packets : None,
1240 hb_send_interval : None,
1241 }
1242 }
1243
1244 pub fn set_mbytes_per_file(&mut self, mbytes : u16) {
1245 self.active_fields |= 1;
1246 self.mbytes_per_file = Some(mbytes);
1247 }
1248
1249 pub fn set_discard_event_fraction(&mut self, frac : f32) {
1250 self.active_fields |= 2;
1251 self.discard_event_fraction = Some(frac);
1252 }
1253
1254 pub fn set_send_mtb_event_packets(&mut self, send : bool) {
1255 self.active_fields |= 4;
1256 self.send_mtb_event_packets = Some(send);
1257 }
1258
1259 pub fn set_send_rbwaveform_packets(&mut self, send : bool) {
1260 self.active_fields |= 8;
1261 self.send_rbwaveform_packets = Some(send);
1262 }
1263
1264 pub fn set_send_rbwf_every_x_event(&mut self, x : u32) {
1265 self.active_fields |= 16;
1266 self.send_rbwf_every_x_event = Some(x);
1267 }
1268
1269 pub fn set_send_tof_summary_packets(&mut self, send : bool) {
1270 self.active_fields |= 32;
1271 self.send_tof_summary_packets = Some(send);
1272 }
1273
1274 pub fn send_tof_event_packets(&mut self, send : bool) {
1275 self.active_fields |= 64;
1276 self.send_tof_event_packets = Some(send);
1277 }
1278
1279 pub fn set_hb_send_interval(&mut self, interval : u16) {
1280 self.active_fields |= 128;
1281 self.hb_send_interval = Some(interval);
1282 }
1283}
1284
1285impl Default for DataPublisherConfig {
1286 fn default() -> Self {
1287 Self::new()
1288 }
1289}
1290
1291impl fmt::Display for DataPublisherConfig {
1292 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1293 let mut repr = String::from("<DataPublisherConfig: ");
1294 repr += &(format!("(active fields {:x})", self.active_fields));
1295 if self.mbytes_per_file.is_some() {
1296 repr += &(format!("\n MBytes/FIle : {}", self.mbytes_per_file.unwrap()));
1297 }
1298 if self.discard_event_fraction.is_some() {
1299 repr += &(format!("\n DIsc. event frac : {}", self.discard_event_fraction.unwrap()));
1300 }
1301 if self.send_mtb_event_packets.is_some() {
1302 repr += &(format!("\n Send MTBPack : {}", self.send_mtb_event_packets.unwrap()));
1303 }
1304 if self.send_rbwaveform_packets.is_some() {
1305 repr += &(format!("\n Send RBWfPack : {}", self.send_rbwaveform_packets.unwrap()));
1306 }
1307 if self.send_rbwf_every_x_event.is_some() {
1308 repr += &(format!("\n RBWf every x event : {}", self.send_rbwf_every_x_event.unwrap()));
1309 }
1310 if self.send_tof_summary_packets.is_some() {
1311 repr += &(format!("\n Send TofSum : {}", self.send_tof_summary_packets.unwrap()));
1312 }
1313 if self.send_tof_event_packets.is_some() {
1314 repr += &(format!("\n Send TOfEvent : {}", self.send_tof_event_packets.unwrap()));
1315 }
1316 if self.hb_send_interval.is_some() {
1317 repr += &(format!("\n HeartBeat send int : {}", self.hb_send_interval.unwrap()));
1318 }
1319 repr += ">";
1320 write!(f, "{}", repr)
1321 }
1322}
1323
1324impl TofPackable for DataPublisherConfig {
1325 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::DataPublisherConfig;
1326}
1327
1328impl Serialization for DataPublisherConfig {
1329
1330 const HEAD : u16 = 0xAAAA;
1331 const TAIL : u16 = 0x5555;
1332 const SIZE : usize = 24;
1333
1334 fn from_bytestream(stream : &Vec<u8>,
1335 pos : &mut usize)
1336 -> Result<Self, SerializationError>{
1337 Self::verify_fixed(stream, pos)?;
1338 let mut cfg = DataPublisherConfig::new();
1339 cfg.active_fields = parse_u32(stream, pos);
1340 cfg.mbytes_per_file = Some(parse_u16 (stream, pos));
1341 cfg.discard_event_fraction = Some(parse_f32 (stream, pos));
1342 cfg.send_mtb_event_packets = Some(parse_bool(stream, pos));
1343 cfg.send_rbwaveform_packets = Some(parse_bool(stream, pos));
1344 cfg.send_rbwf_every_x_event = Some(parse_u32 (stream, pos));
1345 cfg.send_tof_summary_packets = Some(parse_bool(stream, pos));
1346 cfg.send_tof_event_packets = Some(parse_bool(stream, pos));
1347 cfg.hb_send_interval = Some(parse_u16 (stream, pos));
1348 if cfg.active_fields & 1 != 1 {
1351 cfg.mbytes_per_file = None;
1352 }
1353 if cfg.active_fields & 2 != 2 {
1354 cfg.discard_event_fraction = None;
1355 }
1356 if cfg.active_fields & 4 != 4 {
1357 cfg.send_mtb_event_packets = None;
1358 }
1359 if cfg.active_fields & 8 != 8 {
1360 cfg.send_rbwaveform_packets = None;
1361 }
1362 if cfg.active_fields & 16 != 16 {
1363 cfg.send_rbwf_every_x_event = None;
1364 }
1365 if cfg.active_fields & 32 != 32 {
1366 cfg.send_tof_summary_packets = None;
1367 }
1368 if cfg.active_fields & 64 != 64 {
1369 cfg.send_tof_event_packets = None;
1370 }
1371 if cfg.active_fields & 128 != 128 {
1372 cfg.hb_send_interval = None;
1373 }
1374 *pos += 2;
1375 Ok(cfg)
1376 }
1377
1378 fn to_bytestream(&self) -> Vec<u8> {
1379 let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
1380 bs.extend_from_slice(&Self::HEAD .to_le_bytes());
1381 bs.extend_from_slice(&self.active_fields.to_le_bytes());
1382 bs.extend_from_slice(&self.mbytes_per_file.unwrap_or(0).to_le_bytes());
1383 bs.extend_from_slice(&self.discard_event_fraction.unwrap_or(0.0).to_le_bytes());
1384 bs.push (self .send_mtb_event_packets.unwrap_or(false) as u8);
1385 bs.push (self .send_rbwaveform_packets.unwrap_or(false) as u8);
1386 bs.extend_from_slice(&self.send_rbwf_every_x_event.unwrap_or(0).to_le_bytes());
1387 bs.push (self.send_tof_summary_packets.unwrap_or(false) as u8);
1388 bs.push (self .send_tof_event_packets.unwrap_or(false) as u8);
1389 bs.extend_from_slice(&self.hb_send_interval.unwrap_or(30).to_le_bytes());
1390 bs.extend_from_slice(&Self::TAIL.to_le_bytes());
1391 bs
1392 }
1393}
1394
1395#[cfg(feature = "random")]
1396impl FromRandom for DataPublisherConfig {
1397 fn from_random() -> Self {
1398 let mut cfg = DataPublisherConfig::new();
1399 let mut rng = rand::rng();
1400 let active_fields = rng.random::<u32>();
1401 cfg.active_fields = active_fields;
1402 if active_fields & 1 == 1 {
1403 cfg.mbytes_per_file = Some(rng.random::<u16>());
1404 } else {
1405 cfg.mbytes_per_file = None;
1406 }
1407 if active_fields & 2 == 2 {
1408 cfg.discard_event_fraction = Some(rng.random::<f32>());
1409 } else {
1410 cfg.discard_event_fraction = None;
1411 }
1412 if active_fields & 4 == 4 {
1413 cfg.send_mtb_event_packets = Some(rng.random::<bool>());
1414 } else {
1415 cfg.send_mtb_event_packets = None;
1416 }
1417 if active_fields & 8 == 8 {
1418 cfg.send_rbwaveform_packets = Some(rng.random::<bool>());
1419 } else {
1420 cfg.send_rbwaveform_packets = None;
1421 }
1422 if active_fields & 16 == 16 {
1423 cfg.send_rbwf_every_x_event = Some(rng.random::<u32>());
1424 } else {
1425 cfg.send_rbwf_every_x_event = None;
1426 }
1427 if active_fields & 32 == 32 {
1428 cfg.send_tof_summary_packets = Some(rng.random::<bool>());
1429 } else {
1430 cfg.send_tof_summary_packets = None;
1431 }
1432 if active_fields & 64 == 64 {
1433 cfg.send_tof_event_packets = Some(rng.random::<bool>());
1434 } else {
1435 cfg.send_tof_event_packets = None;
1436 }
1437 if active_fields & 128 == 128 {
1438 cfg.hb_send_interval = Some(rng.random::<u16>());
1439 } else {
1440 cfg.hb_send_interval = None;
1441 }
1442 cfg
1443 }
1444}
1445
1446
1447
1448#[derive(Copy, Clone, Debug, PartialEq)]
1452#[cfg_attr(feature="pybindings", pyclass)]
1453pub struct AnalysisEngineConfig{
1454 pub integration_start : f32, pub integration_window : f32, pub pedestal_thresh : f32, pub pedestal_begin_bin : usize, pub pedestal_win_bins : usize, pub use_zscore : bool, pub find_pks_t_start : f32, pub find_pks_t_window : f32, pub min_peak_size : usize, pub find_pks_thresh : f32, pub max_peaks : usize, pub cfd_fraction : f32 }
1467
1468impl AnalysisEngineConfig {
1469 pub fn new() -> Self {
1470 Self {
1471 integration_start : 270.0,
1472 integration_window : 70.0,
1473 pedestal_thresh : 10.0,
1474 pedestal_begin_bin : 10,
1475 pedestal_win_bins : 50,
1476 use_zscore : false,
1477 find_pks_t_start : 270.0,
1478 find_pks_t_window : 70.0,
1479 min_peak_size : 3,
1480 find_pks_thresh : 10.0,
1481 max_peaks : 5, cfd_fraction : 0.2
1483 }
1484 }
1485}
1486
1487impl Default for AnalysisEngineConfig {
1488 fn default() -> Self {
1489 Self::new()
1490 }
1491}
1492
1493impl fmt::Display for AnalysisEngineConfig {
1494 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1495 let mut repr: String = String::from("<AnalysisEngineConfig");
1496 repr += &(format!("\n Integration start : {:.1}", self.integration_start));
1497 repr += &(format!("\n Integration window : {:.1}", self.integration_window));
1498 repr += &(format!("\n Pedestal threshold : {:.1}", self.pedestal_thresh));
1499 repr += &(format!("\n Pedestal start bin : {}", self.pedestal_begin_bin));
1500 repr += &(format!("\n Pedestal window num. bins : {}", self.pedestal_win_bins));
1501 repr += &(format!("\n Use zscore? : {}", self.use_zscore));
1502 repr += &(format!("\n Peakfinder start time : {:.1}", self.find_pks_t_start));
1503 repr += &(format!("\n Peakfinder window : {:.1}", self.find_pks_t_window));
1504 repr += &(format!("\n Peakfinder threshold : {:.1}", self.find_pks_thresh));
1505 repr += &(format!("\n Min. peak size : {}", self.min_peak_size));
1506 repr += &(format!("\n Max num. peaks : {}", self.max_peaks));
1507 repr += &(format!("\n CFD fraction : {:.2}", self.cfd_fraction));
1508 write!(f, "{}", repr)
1509 }
1510}
1511
1512impl TofPackable for AnalysisEngineConfig {
1513 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::AnalysisEngineConfig;
1514}
1515
1516impl Serialization for AnalysisEngineConfig {
1517
1518 const HEAD : u16 = 0xAAAA; const TAIL : u16 = 0x5555; const SIZE : usize = 65; fn from_bytestream(stream : &Vec<u8>,
1523 pos : &mut usize)
1524 -> Result<Self, SerializationError>{
1525 Self::verify_fixed(stream, pos)?;
1526 let mut cfg: AnalysisEngineConfig = AnalysisEngineConfig::new();
1527 cfg.integration_start = parse_f32(stream, pos);
1528 cfg.integration_window = parse_f32(stream, pos);
1529 cfg.pedestal_thresh = parse_f32(stream, pos);
1530 cfg.pedestal_begin_bin = parse_u64(stream, pos) as usize;
1531 cfg.pedestal_win_bins = parse_u64(stream, pos) as usize;
1532 cfg.use_zscore = parse_bool(stream, pos);
1533 cfg.find_pks_t_start = parse_f32(stream, pos);
1534 cfg.find_pks_t_window = parse_f32(stream, pos);
1535 cfg.find_pks_thresh = parse_f32(stream, pos);
1536 cfg.min_peak_size = parse_u64(stream, pos) as usize;
1537 cfg.max_peaks = parse_u64(stream, pos) as usize;
1538 cfg.cfd_fraction = parse_f32(stream, pos);
1539 *pos += 2;
1540 Ok(cfg)
1541 }
1542
1543 fn to_bytestream(&self) -> Vec<u8> {
1544 let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
1545 bs.extend_from_slice(&Self::HEAD.to_le_bytes());
1546 bs.extend_from_slice(&self.integration_start.to_le_bytes());
1547 bs.extend_from_slice(&self.integration_window.to_le_bytes());
1548 bs.extend_from_slice(&self.pedestal_thresh.to_le_bytes());
1549 bs.extend_from_slice(&(self.pedestal_begin_bin as u64).to_le_bytes());
1550 bs.extend_from_slice(&(self.pedestal_win_bins as u64).to_le_bytes());
1551 bs.push(self.use_zscore as u8);
1552 bs.extend_from_slice(&self.find_pks_t_start.to_le_bytes());
1553 bs.extend_from_slice(&self.find_pks_t_window.to_le_bytes());
1554 bs.extend_from_slice(&self.find_pks_thresh.to_le_bytes());
1555 bs.extend_from_slice(&(self.min_peak_size as u64).to_le_bytes());
1556 bs.extend_from_slice(&(self.max_peaks as u64).to_le_bytes());
1557 bs.extend_from_slice(&self.cfd_fraction.to_le_bytes());
1558 bs.extend_from_slice(&Self::TAIL.to_le_bytes());
1559 bs
1560 }
1561}
1562
1563#[cfg(feature = "random")]
1564impl FromRandom for AnalysisEngineConfig {
1565 fn from_random() -> Self {
1566 let mut cfg = AnalysisEngineConfig::new();
1567 let mut rng = rand::rng();
1568 cfg.integration_start = rng.random::<f32>();
1569 cfg.integration_window = rng.random::<f32>();
1570 cfg.pedestal_thresh = rng.random::<f32>();
1571 cfg.pedestal_begin_bin = rng.random::<u64>() as usize;
1572 cfg.pedestal_win_bins = rng.random::<u64>() as usize;
1573 cfg.use_zscore = rng.random::<bool>();
1574 cfg.find_pks_t_start = rng.random::<f32>();
1575 cfg.find_pks_t_window = rng.random::<f32>();
1576 cfg.find_pks_thresh = rng.random::<f32>();
1577 cfg.min_peak_size = rng.random::<u64>() as usize;
1578 cfg.max_peaks = rng.random::<u64>() as usize;
1579 cfg.cfd_fraction = rng.random::<f32>();
1580 cfg
1581 }
1582}
1583
1584
1585
1586#[derive(Copy, Clone, Debug, PartialEq)]
1591#[cfg_attr(feature="pybindings", pyclass)]
1592pub struct TOFEventBuilderConfig{
1593 pub active_fields : u32, pub cachesize : Option<u32>,
1595 pub n_mte_per_loop : Option<u32>,
1596 pub n_rbe_per_loop : Option<u32>,
1597 pub te_timeout_sec : Option<u32>,
1598 pub te_timeout_sec_combo : Option<u32>,
1599 pub holdoff : Option<u32>,
1600 pub sort_events : Option<bool>,
1601 pub build_strategy : Option<BuildStrategy>,
1602 pub wait_nrb : Option<u8>,
1603 pub greediness : Option<u8>,
1604 pub hb_send_interval : Option<u16>,
1605 pub only_save_interesting : Option<bool>,
1607 pub thr_n_hits_umb : Option<u8>,
1608 pub thr_n_hits_cbe : Option<u8>,
1609 pub thr_n_hits_cor : Option<u8>,
1610 pub thr_tot_edep_umb : Option<f32>,
1611 pub thr_tot_edep_cbe : Option<f32>,
1612 pub thr_tot_edep_cor : Option<f32>
1613}
1614
1615impl TOFEventBuilderConfig {
1616 pub fn new() -> Self {
1617 Self {
1618 active_fields : 0,
1619 cachesize : None,
1620 n_mte_per_loop : None,
1621 n_rbe_per_loop : None,
1622 te_timeout_sec : None,
1623 te_timeout_sec_combo : None,
1624 holdoff : None,
1625 sort_events : None,
1626 build_strategy : None,
1627 wait_nrb : None,
1628 greediness : None,
1629 hb_send_interval : None,
1630 only_save_interesting : None,
1631 thr_n_hits_umb : None,
1632 thr_n_hits_cbe : None,
1633 thr_n_hits_cor : None,
1634 thr_tot_edep_umb : None,
1635 thr_tot_edep_cbe : None,
1636 thr_tot_edep_cor : None,
1637 }
1638 }
1639
1640 pub fn set_cachesize(&mut self, csize : u32) {
1641 self.active_fields |= 1;
1642 self.cachesize = Some(csize);
1643 }
1644
1645 pub fn set_n_mte_per_loop(&mut self, n : u32) {
1646 self.active_fields |= 2;
1647 self.n_mte_per_loop = Some(n);
1648 }
1649
1650 pub fn set_n_rbe_per_loop(&mut self, n : u32) {
1651 self.active_fields |= 4;
1652 self.n_rbe_per_loop = Some(n);
1653 }
1654
1655 pub fn set_te_timeout_sec(&mut self, te : u32) {
1656 self.active_fields |= 8;
1657 self.te_timeout_sec = Some(te);
1658 }
1659
1660 pub fn set_sort_events(&mut self, sort : bool) {
1661 self.active_fields |= 16;
1662 self.sort_events = Some(sort);
1663 }
1664
1665 pub fn set_build_strategy(&mut self, bs : BuildStrategy) {
1666 self.active_fields |= 32;
1667 self.build_strategy = Some(bs);
1668 }
1669
1670 pub fn set_wait_nrb(&mut self, nrb : u8) {
1671 self.active_fields |= 64;
1672 self.wait_nrb = Some(nrb);
1673 }
1674
1675 pub fn set_greediness(&mut self, greed : u8) {
1676 self.active_fields |= 128;
1677 self.greediness = Some(greed);
1678 }
1679
1680 pub fn set_hb_send_interval(&mut self, interval : u16) {
1681 self.active_fields |= 256;
1682 self.hb_send_interval = Some(interval);
1683 }
1684
1685 pub fn set_only_save_interesting(&mut self, do_it : bool) {
1686 self.active_fields |= 512;
1687 self.only_save_interesting = Some(do_it);
1688 }
1689
1690 pub fn thr_n_hits_umb(&mut self, nhit : u8) {
1691 self.active_fields |= 1024;
1692 self.thr_n_hits_umb = Some(nhit);
1693 }
1694
1695 pub fn thr_n_hits_cbe(&mut self, nhit : u8) {
1696 self.active_fields |= 2048;
1697 self.thr_n_hits_cbe = Some(nhit);
1698 }
1699
1700 pub fn thr_n_hits_cor(&mut self, nhit : u8) {
1701 self.active_fields |= 2u32.pow(12);
1702 self.thr_n_hits_cor = Some(nhit);
1703 }
1704
1705 pub fn thr_tot_edep_umb(&mut self, thr : f32) {
1706 self.active_fields |= 2u32.pow(13);
1707 self.thr_tot_edep_umb = Some(thr);
1708 }
1709
1710 pub fn thr_tot_edep_cbe(&mut self, thr : f32) {
1711 self.active_fields |= 2u32.pow(14);
1712 self.thr_tot_edep_cbe = Some(thr);
1713 }
1714
1715 pub fn thr_tot_edep_cor(&mut self, thr : f32) {
1716 self.active_fields |= 2u32.pow(15);
1717 self.thr_tot_edep_cor = Some(thr);
1718 }
1719}
1720
1721impl Default for TOFEventBuilderConfig {
1722 fn default() -> Self {
1723 Self::new()
1724 }
1725}
1726
1727impl fmt::Display for TOFEventBuilderConfig {
1728 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1729 let mut repr = String::from("<TOFEventBuilderConfig");
1730 repr += &(format!(" (active_fields {:x}", self.active_fields));
1731 if self.cachesize.is_some() {
1732 repr += &(format!("\n Cache size : {}", self.cachesize.unwrap()));
1733 }
1734 if self.n_mte_per_loop.is_some() {
1735 repr += &(format!("\n Num. master trigger events per loop : {}", self.n_mte_per_loop.unwrap()));
1736 }
1737 if self.n_rbe_per_loop.is_some() {
1738 repr += &(format!("\n Num. readout board events per loop : {}", self.n_rbe_per_loop.unwrap()));
1739 }
1740 if self.te_timeout_sec.is_some() {
1741 repr += &(format!("\n TOF Event timeout window [sec] : {:.3}", self.te_timeout_sec.unwrap()));
1742 }
1743 if self.sort_events.is_some() {
1744 repr += &(format!("\n Sort events by ID (high resource load!) : {}", self.sort_events.unwrap()));
1745 }
1746 if self.build_strategy.is_some() {
1747 repr += &(format!("\n Build strategy : {}", self.build_strategy.unwrap()));
1748 if self.build_strategy.unwrap() == BuildStrategy::AdaptiveGreedy {
1749 if self.greediness.is_some() {
1750 repr += &(format!("\n Additional RBs considered (greediness) : {}", self.greediness.unwrap()));
1751 }
1752 } else if self.build_strategy.unwrap() == BuildStrategy::WaitForNBoards {
1753 if self.wait_nrb.is_some() {
1754 repr += &(format!("\n Waiting for {} boards", self.wait_nrb.unwrap()))
1755 }
1756 }
1757 }
1758 if self.hb_send_interval.is_some() {
1759 repr += &(format!("\n Heartbeat send interval : {}", self.hb_send_interval.unwrap()));
1760 }
1761 if self.only_save_interesting.is_some() {
1762 repr += &(format!("\n Saving only interesting events : {}", self.only_save_interesting.unwrap()));
1763 }
1764 if self.thr_n_hits_umb.is_some() {
1765 repr += &(format!("\n Interesting threshold for nhit umb : {}", self.thr_n_hits_umb.unwrap()));
1766 }
1767 if self.thr_n_hits_cbe.is_some() {
1768 repr += &(format!("\n Interesting threshold for nhit cbe : {}", self.thr_n_hits_cbe.unwrap()));
1769 }
1770 if self.thr_n_hits_cor.is_some() {
1771 repr += &(format!("\n Interesting threshold for nhit cor : {}", self.thr_n_hits_cor.unwrap()));
1772 }
1773 if self.thr_tot_edep_umb.is_some() {
1774 repr += &(format!("\n Interesting threshold for tot edep umb : {}", self.thr_tot_edep_umb.unwrap()));
1775 }
1776 if self.thr_tot_edep_cbe.is_some() {
1777 repr += &(format!("\n Interesting threshold for tot edep cbe : {}", self.thr_tot_edep_cbe.unwrap()));
1778 }
1779 if self.thr_tot_edep_cor.is_some() {
1780 repr += &(format!("\n Interesting threshold for tot edep cor : {}", self.thr_tot_edep_cor.unwrap()));
1781 }
1782 write!(f, "{}", repr)
1783 }
1784}
1785
1786impl TofPackable for TOFEventBuilderConfig {
1787 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::TOFEventBuilderConfig;
1788}
1789
1790impl Serialization for TOFEventBuilderConfig {
1791
1792 const HEAD : u16 = 0xAAAA;
1793 const TAIL : u16 = 0x5555;
1794 const SIZE : usize = 46;
1795
1796 fn from_bytestream(stream : &Vec<u8>,
1797 pos : &mut usize)
1798 -> Result<Self, SerializationError> {
1799 Self::verify_fixed(stream, pos)?;
1800 let mut cfg = TOFEventBuilderConfig::new();
1801 cfg.active_fields = parse_u32(stream, pos);
1802 cfg.cachesize = Some(parse_u32(stream, pos));
1803 cfg.n_mte_per_loop = Some(parse_u32(stream, pos));
1804 cfg.n_rbe_per_loop = Some(parse_u32(stream, pos));
1805 cfg.te_timeout_sec = Some(parse_u32(stream, pos));
1806 cfg.sort_events = Some(parse_bool(stream, pos));
1807 cfg.build_strategy = Some(BuildStrategy::from(parse_u8(stream, pos)));
1808 cfg.wait_nrb = Some(parse_u8(stream, pos));
1809 cfg.greediness = Some(parse_u8(stream, pos));
1810 cfg.hb_send_interval = Some(parse_u16(stream, pos));
1811 cfg.only_save_interesting = Some(parse_bool(stream, pos));
1813 cfg.thr_n_hits_umb = Some(parse_u8(stream, pos));
1814 cfg.thr_n_hits_cbe = Some(parse_u8(stream, pos));
1815 cfg.thr_n_hits_cor = Some(parse_u8(stream, pos));
1816 cfg.thr_tot_edep_umb = Some(parse_f32(stream, pos));
1817 cfg.thr_tot_edep_cbe = Some(parse_f32(stream, pos));
1818 cfg.thr_tot_edep_cor = Some(parse_f32(stream, pos));
1819
1820 if cfg.active_fields & 1 != 1 {
1821 cfg.cachesize = None;
1822 }
1823 if cfg.active_fields & 2 != 2 {
1824 cfg.n_mte_per_loop = None;
1825 }
1826 if cfg.active_fields & 4 != 4 {
1827 cfg.n_rbe_per_loop = None;
1828 }
1829 if cfg.active_fields & 8 != 8 {
1830 cfg.te_timeout_sec = None;
1831 }
1832 if cfg.active_fields & 16 != 16 {
1833 cfg.sort_events = None;
1834 }
1835 if cfg.active_fields & 32 != 32 {
1836 cfg.build_strategy = None;
1837 }
1838 if cfg.active_fields & 64 != 64 {
1839 cfg.wait_nrb = None;
1840 }
1841 if cfg.active_fields & 128 != 128 {
1842 cfg.greediness = None;
1843 }
1844 if cfg.active_fields & 256 != 256 {
1845 cfg.hb_send_interval = None;
1846 }
1847 if cfg.active_fields & 512 != 512 {
1848 cfg.only_save_interesting = None;
1849 }
1850 if cfg.active_fields & 1024 != 1024 {
1851 cfg.thr_n_hits_umb = None;
1852 }
1853 if cfg.active_fields & 2048 != 2048 {
1854 cfg.thr_n_hits_cbe = None;
1855 }
1856 if cfg.active_fields & 2u32.pow(12) != 2u32.pow(12) {
1857 cfg.thr_n_hits_cor = None;
1858 }
1859 if cfg.active_fields & 2u32.pow(13) != 2u32.pow(13) {
1860 cfg.thr_tot_edep_umb = None;
1861 }
1862 if cfg.active_fields & 2u32.pow(14) != 2u32.pow(14) {
1863 cfg.thr_tot_edep_cbe = None;
1864 }
1865 if cfg.active_fields & 2u32.pow(15) != 2u32.pow(15) {
1866 cfg.thr_tot_edep_cor = None;
1867 }
1868 *pos += 2;
1869 Ok(cfg)
1870 }
1871
1872 fn to_bytestream(&self) -> Vec<u8> {
1873 let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
1874 bs.extend_from_slice(&Self::HEAD.to_le_bytes());
1875 bs.extend_from_slice(&self.active_fields.to_le_bytes());
1876 bs.extend_from_slice(&self.cachesize.unwrap_or(0).to_le_bytes());
1877 bs.extend_from_slice(&self.n_mte_per_loop.unwrap_or(0).to_le_bytes());
1878 bs.extend_from_slice(&self.n_rbe_per_loop.unwrap_or(0).to_le_bytes());
1879 bs.extend_from_slice(&self.te_timeout_sec.unwrap_or(0).to_le_bytes());
1880 bs.push(self.sort_events.unwrap_or(false) as u8);
1881 bs.push(self.build_strategy.unwrap_or(BuildStrategy::Unknown) as u8);
1882 bs.push(self.wait_nrb.unwrap_or(0));
1883 bs.push(self.greediness.unwrap_or(0));
1884 bs.extend_from_slice(&self.hb_send_interval.unwrap_or(0).to_le_bytes());
1885 bs.push(self.only_save_interesting.unwrap_or(false) as u8);
1887 bs.extend_from_slice(&self.thr_n_hits_umb.unwrap_or(0).to_le_bytes());
1888 bs.extend_from_slice(&self.thr_n_hits_cbe.unwrap_or(0).to_le_bytes());
1889 bs.extend_from_slice(&self.thr_n_hits_cor.unwrap_or(0).to_le_bytes());
1890 bs.extend_from_slice(&self.thr_tot_edep_umb.unwrap_or(0.0).to_le_bytes());
1891 bs.extend_from_slice(&self.thr_tot_edep_cbe.unwrap_or(0.0).to_le_bytes());
1892 bs.extend_from_slice(&self.thr_tot_edep_cor.unwrap_or(0.0).to_le_bytes());
1893 bs.extend_from_slice(&Self::TAIL.to_le_bytes());
1894 bs
1895 }
1896}
1897
1898#[cfg(feature = "random")]
1899impl FromRandom for TOFEventBuilderConfig {
1900 fn from_random() -> Self {
1901 let mut cfg = TOFEventBuilderConfig::new();
1902 let mut rng = rand::rng();
1903 cfg.active_fields = rng.random::<u32>();
1904 if cfg.active_fields & 1 == 1 {
1905 cfg.cachesize = Some(rng.random::<u32>());
1906 }
1907 if cfg.active_fields & 2 == 2 {
1908 cfg.n_mte_per_loop = Some(rng.random::<u32>());
1909 }
1910 if cfg.active_fields & 4 == 4 {
1911 cfg.n_rbe_per_loop = Some(rng.random::<u32>());
1912 }
1913 if cfg.active_fields & 8 == 8 {
1914 cfg.te_timeout_sec = Some(rng.random::<u32>());
1915 }
1916 if cfg.active_fields & 16 == 16 {
1917 cfg.sort_events = Some(rng.random::<bool>());
1918 }
1919 if cfg.active_fields & 32 == 32 {
1920 cfg.build_strategy = Some(BuildStrategy::from_random());
1921 }
1922 if cfg.active_fields & 64 == 64 {
1923 cfg.wait_nrb = Some(rng.random::<u8>());
1924 }
1925 if cfg.active_fields & 128 == 128 {
1926 cfg.greediness = Some(rng.random::<u8>());
1927 }
1928 if cfg.active_fields & 256 == 256 {
1929 cfg.hb_send_interval = Some(rng.random::<u16>());
1930 }
1931 if cfg.active_fields & 512 == 512 {
1932 cfg.only_save_interesting = Some(rng.random::<bool>());
1933 }
1934 if cfg.active_fields & 1024 == 1024 {
1935 cfg.thr_n_hits_umb = Some(rng.random::<u8>());
1936 }
1937 if cfg.active_fields & 2048 == 2048 {
1938 cfg.thr_n_hits_cbe = Some(rng.random::<u8>());
1939 }
1940 if cfg.active_fields & 2u32.pow(12) == 2u32.pow(12) {
1941 cfg.thr_n_hits_cor = Some(rng.random::<u8>());
1942 }
1943 if cfg.active_fields & 2u32.pow(13) == 2u32.pow(13) {
1944 cfg.thr_tot_edep_umb = Some(rng.random::<f32>());
1945 }
1946 if cfg.active_fields & 2u32.pow(14) == 2u32.pow(14) {
1947 cfg.thr_tot_edep_cbe = Some(rng.random::<f32>());
1948 }
1949 if cfg.active_fields & 2u32.pow(15) == 2u32.pow(15) {
1950 cfg.thr_tot_edep_cor = Some(rng.random::<f32>());
1951 }
1952 cfg
1953 }
1954}
1955
1956
1957
1958#[cfg(feature = "random")]
1959#[test]
1960fn pack_analysisengineconfig() {
1961 for _ in 0..100 {
1962 let cfg = AnalysisEngineConfig::from_random();
1963 let test : AnalysisEngineConfig = cfg.pack().unpack().unwrap();
1964 assert_eq!(cfg, test);
1965 }
1966}
1967
1968
1969
1970#[cfg(feature = "random")]
1974#[test]
1975fn pack_preampbiasconfig() {
1976 for _ in 0..100 {
1977 let cfg = PreampBiasConfig::from_random();
1978 let test : PreampBiasConfig = cfg.pack().unpack().unwrap();
1979 assert_eq!(cfg, test);
1980 }
1981}
1982
1983#[cfg(feature = "random")]
1984#[test]
1985fn pack_rb_channel_mask_config() {
1986 for _ in 0..100 {
1987 let cfg = RBChannelMaskConfig::from_random();
1988 let test : RBChannelMaskConfig = cfg.pack().unpack().unwrap();
1989 assert_eq!(cfg, test);
1990 }
1991}
1992
1993
1994#[cfg(feature = "random")]
1995#[test]
1996fn pack_ltbthresholdconfig() {
1997 for _ in 0..100 {
1998 let cfg = LTBThresholdConfig::from_random();
1999 let test : LTBThresholdConfig = cfg.pack().unpack().unwrap();
2000 assert_eq!(cfg, test);
2001 }
2002}
2003
2004#[cfg(feature = "random")]
2022#[test]
2023fn pack_triggerconfig() {
2024 for _ in 0..100 {
2025 let cfg = TriggerConfig::from_random();
2026 let test : TriggerConfig = cfg.pack().unpack().unwrap();
2027 assert_eq!(cfg, test);
2028 }
2029}
2030
2031#[cfg(feature = "random")]
2032#[test]
2033fn pack_tofeventbuilderconfig() {
2034 for _ in 0..100 {
2035 let cfg = TOFEventBuilderConfig::from_random();
2036 let test : TOFEventBuilderConfig = cfg.pack().unpack().unwrap();
2037 assert_eq!(cfg, test);
2038 }
2039}
2040
2041#[cfg(feature = "random")]
2042#[test]
2043fn pack_datapublisherconfig() {
2044 for _ in 0..100 {
2045 let cfg = DataPublisherConfig::from_random();
2046 let test : DataPublisherConfig = cfg.pack().unpack().unwrap();
2047 assert_eq!(cfg, test);
2048 }
2049}
2050
2051#[cfg(feature = "random")]
2052#[test]
2053fn pack_tofrunconfig() {
2054 for _ in 0..100 {
2055 let cfg = TofRunConfig::from_random();
2056 let test : TofRunConfig = cfg.pack().unpack().unwrap();
2057 assert_eq!(cfg, test);
2058 }
2059}
2060
2061#[cfg(feature = "random")]
2062#[test]
2063fn pack_tofrbconfig() {
2064 for _ in 0..100 {
2065 let cfg = TofRBConfig::from_random();
2066 let test : TofRBConfig = cfg.pack().unpack().unwrap();
2067 assert_eq!(cfg, test);
2068 }
2069}
2070