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 : u16
338}
339
340impl RunConfig {
341
342 pub fn new() -> Self {
343 Self {
344 runid : 0,
345 is_active : false,
346 nevents : 0,
347 nseconds : 0,
348 tof_op_mode : TofOperationMode::Default,
349 trigger_poisson_rate : 0,
350 trigger_fixed_rate : 0,
351 data_type : DataType::Unknown,
352 rb_buff_size : 0,
353 }
354 }
355}
356
357impl Serialization for RunConfig {
358 const HEAD : u16 = 43690; const TAIL : u16 = 21845; const SIZE : usize = 29; fn from_bytestream(bytestream : &Vec<u8>,
363 pos : &mut usize)
364 -> Result<Self, SerializationError> {
365 let mut pars = Self::new();
366 Self::verify_fixed(bytestream, pos)?;
367 pars.runid = parse_u32 (bytestream, pos);
368 pars.is_active = parse_bool(bytestream, pos);
369 pars.nevents = parse_u32 (bytestream, pos);
370 pars.nseconds = parse_u32 (bytestream, pos);
371 pars.tof_op_mode
372 = TofOperationMode::try_from(
373 parse_u8(bytestream, pos))
374 .unwrap_or_else(|_| TofOperationMode::Unknown);
375 pars.trigger_poisson_rate = parse_u32 (bytestream, pos);
376 pars.trigger_fixed_rate = parse_u32 (bytestream, pos);
377 pars.data_type
378 = DataType::try_from(parse_u8(bytestream, pos))
379 .unwrap_or_else(|_| DataType::Unknown);
380 pars.rb_buff_size = parse_u16(bytestream, pos);
381 *pos += 2; Ok(pars)
384 }
385
386 fn to_bytestream(&self) -> Vec<u8> {
387 let mut stream = Vec::<u8>::with_capacity(Self::SIZE);
388 stream.extend_from_slice(&Self::HEAD.to_le_bytes());
389 stream.extend_from_slice(&self.runid.to_le_bytes());
390 stream.push(self. is_active as u8);
391 stream.extend_from_slice(&self.nevents.to_le_bytes());
392 stream.extend_from_slice(&self. nseconds.to_le_bytes());
393 stream.extend_from_slice(&(self.tof_op_mode as u8).to_le_bytes());
394 stream.extend_from_slice(&self.trigger_poisson_rate.to_le_bytes());
395 stream.extend_from_slice(&self.trigger_fixed_rate.to_le_bytes());
396 stream.push(self.data_type as u8);
397 stream.extend_from_slice(&self.rb_buff_size.to_le_bytes());
398 stream.extend_from_slice(&Self::TAIL.to_le_bytes());
399 stream
400 }
401}
402
403impl Default for RunConfig {
404 fn default() -> Self {
405 Self::new()
406 }
407}
408
409impl fmt::Display for RunConfig {
410 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
411 if !self.is_active {
412 return write!(f, "<RunConfig -- is_active : false>");
413 } else {
414 write!(f,
415"<RunConfig -- is_active : true
416 nevents : {}
417 nseconds : {}
418 TOF op. mode : {}
419 data type : {}
420 tr_poi_rate : {}
421 tr_fix_rate : {}
422 buff size : {} [events]>",
423 self.nevents,
424 self.nseconds,
425 self.tof_op_mode,
426 self.data_type,
427 self.trigger_poisson_rate,
428 self.trigger_fixed_rate,
429 self.rb_buff_size)
430 }
431 }
432}
433
434impl TofPackable for RunConfig {
435 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::RunConfig;
436}
437
438#[cfg(feature = "random")]
439impl FromRandom for RunConfig {
440
441 fn from_random() -> Self {
442 let mut cfg = Self::new();
443 let mut rng = rand::rng();
444 cfg.runid = rng.random::<u32>();
445 cfg.is_active = rng.random::<bool>();
446 cfg.nevents = rng.random::<u32>();
447 cfg.nseconds = rng.random::<u32>();
448 cfg.tof_op_mode = TofOperationMode::from_random();
449 cfg.trigger_poisson_rate = rng.random::<u32>();
450 cfg.trigger_fixed_rate = rng.random::<u32>();
451 cfg.data_type = DataType::from_random();
452 cfg.rb_buff_size = rng.random::<u16>();
453 cfg
454 }
455}
456
457#[derive(Copy, Clone, Debug, PartialEq)]
461#[cfg_attr(feature="pybindings", pyclass)]
462pub struct TriggerConfig{
463 pub active_fields : u32,
468 pub gaps_trigger_use_beta : Option<bool>, pub prescale : Option<f32>, pub trigger_type : Option<TriggerType>, pub use_combo_trigger : Option<bool>,
473 pub combo_trigger_type : Option<TriggerType>,
474 pub combo_trigger_prescale : Option<f32>,
475 pub trace_suppression : Option<bool>,
476 pub mtb_moni_interval : Option<u16>,
477 pub tiu_ignore_busy : Option<bool>,
478 pub hb_send_interval : Option<u16>,
479}
480
481impl TriggerConfig {
482 pub fn new() -> Self {
483 Self {
484 active_fields : 0,
485 gaps_trigger_use_beta : None,
486 prescale : None,
487 trigger_type : None,
488 use_combo_trigger : None,
489 combo_trigger_type : None,
490 combo_trigger_prescale : None,
491 trace_suppression : None,
492 mtb_moni_interval : None,
493 tiu_ignore_busy : None,
494 hb_send_interval : None,
495 }
496 }
497
498 pub fn set_gaps_trigger_use_beta(&mut self, use_it : bool) {
499 self.active_fields |= 1;
500 self.gaps_trigger_use_beta = Some(use_it);
501 }
502
503 pub fn set_prescale(&mut self, prescale : f32) {
504 self.active_fields |= 2;
505 self.prescale = Some(prescale);
506 }
507
508 pub fn set_trigger_type(&mut self, ttype : TriggerType) {
509 self.active_fields |= 4;
510 self.trigger_type = Some(ttype);
511 }
512
513 pub fn set_use_combo_trigger(&mut self, combo : bool) {
514 self.active_fields |= 8;
515 self.use_combo_trigger = Some(combo);
516 }
517
518 pub fn set_combo_trigger_type(&mut self, ttype : TriggerType) {
519 self.active_fields |= 16;
520 self.combo_trigger_type = Some(ttype)
521 }
522
523 pub fn set_combo_trigger_prescale(&mut self, prescale : f32) {
524 self.active_fields |= 32;
525 self.combo_trigger_prescale = Some(prescale);
526 }
527
528 pub fn set_trace_suppression(&mut self, tsup : bool) {
529 self.active_fields |= 64;
530 self.trace_suppression = Some(tsup);
531 }
532
533 pub fn set_mtb_moni_interval(&mut self, interval : u16) {
534 self.active_fields |= 128;
535 self.mtb_moni_interval = Some(interval);
536 }
537
538 pub fn set_tiu_ignore_busy(&mut self, busy : bool) {
539 self.active_fields |= 256;
540 self.tiu_ignore_busy = Some(busy);
541 }
542
543 pub fn set_hb_send_interval(&mut self, interval : u16) {
544 self.active_fields |= 512;
545 self.hb_send_interval = Some(interval);
546 }
547}
548
549impl Default for TriggerConfig {
550 fn default() -> Self {
551 Self::new()
552 }
553}
554
555impl fmt::Display for TriggerConfig {
556 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
557 let mut repr = String::from("<TriggerConfig: ");
558 repr += &(format!("(active fields {:x})", self.active_fields));
559 if self. gaps_trigger_use_beta.is_some() {
560 repr += &(format!("\n Beta is used by trigger : {}", self.gaps_trigger_use_beta.unwrap()));
561 }
562 if self. prescale.is_some() {
563 repr += &(format!("\n Prescale : {:.3}", self.prescale.unwrap()));
564 }
565 if self.trigger_type.is_some() {
566 repr += &(format!("\n Trigger type : {}", self.trigger_type.unwrap()));
567 }
568 if self.use_combo_trigger.is_some() {
569 if self.use_combo_trigger.unwrap() {
570 repr += &(format!("\n -- using combo trigger!"));
571 }
572 }
573 if self.combo_trigger_prescale.is_some() {
574 repr += &(format!("\n -- -- Combo Prescale : {:.3}", self.combo_trigger_prescale.unwrap()));
575 }
576 if self.combo_trigger_type.is_some() {
577 repr += &(format!("\n -- -- Combo Trigger type : {}", self.combo_trigger_type.unwrap()));
578 }
579 if self. trace_suppression.is_some() {
580 repr += &(format!("\n trace_suppression : {}", self.trace_suppression.unwrap()));
581 }
582 if self.mtb_moni_interval.is_some() {
583 repr += &(format!("\n mtb_moni_interval : {}", self.mtb_moni_interval.unwrap()));
584 }
585 if self.tiu_ignore_busy.is_some() {
586 repr += &(format!("\n tiu_ignore_busy : {}", self.tiu_ignore_busy.unwrap()));
587 }
588 if self.hb_send_interval.is_some() {
589 repr += &(format!("\n hb_send_interval : {}", self.hb_send_interval.unwrap()));
590 }
591 repr += ">";
592 write!(f, "{}", repr)
593 }
594}
595
596impl TofPackable for TriggerConfig {
597 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::TriggerConfig;
598}
599
600impl Serialization for TriggerConfig {
601
602 const HEAD : u16 = 0xAAAA;
603 const TAIL : u16 = 0x5555;
604 const SIZE : usize = 26;
605
606 fn from_bytestream(stream : &Vec<u8>,
607 pos : &mut usize)
608 -> Result<Self, SerializationError>{
609 Self::verify_fixed(stream, pos)?;
610 let mut cfg = TriggerConfig::new();
611 cfg.active_fields = parse_u32(stream, pos);
612 cfg.gaps_trigger_use_beta = Some(parse_bool(stream, pos));
613 cfg.prescale = Some(parse_f32 (stream, pos));
614 cfg.trigger_type = Some(TriggerType::from(parse_u8(stream, pos)));
615 cfg.use_combo_trigger = Some(parse_bool(stream, pos));
616 cfg.combo_trigger_type = Some(TriggerType::from(parse_u8(stream, pos)));
617 cfg.combo_trigger_prescale = Some(parse_f32(stream, pos));
618 cfg.trace_suppression = Some(parse_bool(stream, pos));
619 cfg.mtb_moni_interval = Some(parse_u16(stream, pos));
620 cfg.tiu_ignore_busy = Some(parse_bool(stream, pos));
621 cfg.hb_send_interval = Some(parse_u16(stream, pos));
622 if cfg.active_fields & 1 != 1 {
625 cfg.gaps_trigger_use_beta = None;
626 }
627 if cfg.active_fields & 2 != 2 {
628 cfg.prescale = None;
629 }
630 if cfg.active_fields & 4 != 4 {
631 cfg.trigger_type = None;
632 }
633 if cfg.active_fields & 8 != 8 {
634 cfg.use_combo_trigger = None;
635 }
636 if cfg.active_fields & 16 != 16 {
637 cfg.combo_trigger_type = None;
638 }
639 if cfg.active_fields & 32 != 32 {
640 cfg.combo_trigger_prescale = None;
641 }
642 if cfg.active_fields & 64 != 64 {
643 cfg.trace_suppression = None;
644 }
645 if cfg.active_fields & 128 != 128 {
646 cfg.mtb_moni_interval = None;
647 }
648 if cfg.active_fields & 256 != 256 {
649 cfg.tiu_ignore_busy = None;
650 }
651 if cfg.active_fields & 512 != 512 {
652 cfg.hb_send_interval = None;
653 }
654 *pos += 2;
655 Ok(cfg)
656 }
657
658 fn to_bytestream(&self) -> Vec<u8> {
659 let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
660 bs.extend_from_slice(&Self::HEAD .to_le_bytes());
661 bs.extend_from_slice(&self.active_fields.to_le_bytes());
662 bs.push (self.gaps_trigger_use_beta.unwrap_or(false) as u8);
663 bs.extend_from_slice(&self.prescale.unwrap_or(0.0) .to_le_bytes());
664 bs.push (self.trigger_type.unwrap_or(TriggerType::Unknown) as u8);
665 bs.push (self.use_combo_trigger.unwrap_or(false) as u8);
666 bs.push (self.combo_trigger_type.unwrap_or(TriggerType::Unknown) as u8);
667 bs.extend_from_slice(&self.combo_trigger_prescale.unwrap_or(0.0).to_le_bytes());
668 bs.push (self.trace_suppression.unwrap_or(false) as u8);
669 bs.extend_from_slice(&self.mtb_moni_interval.unwrap_or(30).to_le_bytes());
670 bs.push (self.tiu_ignore_busy.unwrap_or(false) as u8);
671 bs.extend_from_slice(&self.hb_send_interval.unwrap_or(30).to_le_bytes());
672 bs.extend_from_slice(&Self::TAIL.to_le_bytes());
673 bs
674 }
675}
676
677#[cfg(feature = "random")]
678impl FromRandom for TriggerConfig {
679 fn from_random() -> Self {
680 let mut cfg = TriggerConfig::new();
681 let mut rng = rand::rng();
682 let active_fields = rng.random::<u32>();
683 cfg.active_fields = active_fields;
684 if active_fields & 1 == 1 {
685 cfg.gaps_trigger_use_beta = Some(rng.random::<bool>());
686 } else {
687 cfg.gaps_trigger_use_beta = None;
688 }
689 if active_fields & 2 == 2 {
690 cfg.prescale = Some(rng.random::<f32>());
691 } else {
692 cfg.prescale = None;
693 }
694 if active_fields & 4 == 4 {
695 cfg.trigger_type = Some(TriggerType::from_random());
696 } else {
697 cfg.trigger_type = None;
698 }
699 if active_fields & 8 == 8 {
700 cfg.use_combo_trigger = Some(rng.random::<bool>());
701 } else {
702 cfg.use_combo_trigger = None;
703 }
704 if active_fields & 16 == 16 {
705 cfg.combo_trigger_type = Some(TriggerType::from_random());
706 } else {
707 cfg.combo_trigger_type = None;
708 }
709 if active_fields & 32 == 32 {
710 cfg.combo_trigger_prescale = Some(rng.random::<f32>());
711 } else {
712 cfg.combo_trigger_prescale = None;
713 }
714 if active_fields & 64 == 64 {
715 cfg.trace_suppression = Some(rng.random::<bool>());
716 } else {
717 cfg.trace_suppression = None;
718 }
719 if active_fields & 128 == 128 {
720 cfg.mtb_moni_interval = Some(rng.random::<u16>());
721 } else {
722 cfg.mtb_moni_interval = None;
723 }
724 if active_fields & 256 == 256 {
725 cfg.tiu_ignore_busy = Some(rng.random::<bool>());
726 } else {
727 cfg.tiu_ignore_busy = None;
728 }
729 if active_fields & 512 == 512 {
730 cfg.hb_send_interval = Some(rng.random::<u16>());
731 } else {
732 cfg.hb_send_interval = None;
733 }
734 cfg
735 }
736}
737
738#[cfg(feature="pybindings")]
739#[pymethods]
740impl TriggerConfig {
741
742 #[getter]
743 fn get_prescale(&self) -> Option<f32> {
744 self.prescale
745 }
746
747 #[setter]
748 #[pyo3(name="set_prescale")]
749 fn set_prescale_py(&mut self, prescale: f32) -> PyResult<()> {
750 self.set_prescale (prescale);
751 Ok(())
752 }
753
754 #[getter]
755 fn get_gaps_trigger_use_beta(&self) -> Option<bool> {
756 self.gaps_trigger_use_beta
757 }
758
759 #[setter]
760 #[pyo3(name="set_gaps_trigger_use_beta")]
761 fn set_gaps_trigger_use_beta_py(&mut self, gaps_trigger_use_beta: bool) -> PyResult<()> {
762 self.set_gaps_trigger_use_beta(gaps_trigger_use_beta);
763 Ok(())
764 }
765
766 #[getter]
767 fn get_trigger_type(&self) -> Option<TriggerType> {
768 self.trigger_type
769 }
770
771 #[setter]
772 #[pyo3(name="set_trigger_type")]
773 fn set_trigger_type_py(&mut self, trigger_type: TriggerType) -> PyResult<()> {
774 self.set_trigger_type(trigger_type);
775 Ok(())
776 }
777
778 #[getter]
779 fn get_use_combo_trigger(&self) -> Option<bool> {
780 self.use_combo_trigger
781 }
782 #[setter]
783 #[pyo3(name="set_use_combo_trigger")]
784 fn set_use_combo_trigger_py(&mut self, combo : bool) {
785 self.set_use_combo_trigger(combo);
786 }
787 #[getter]
788 fn get_combo_trigger_type(&self) -> Option<TriggerType> {
789 self.combo_trigger_type
790 }
791 #[setter]
792 #[pyo3(name="set_combo_trigger_type")]
793 fn set_combo_trigger_type_py(&mut self, combo_trigger_type : TriggerType) {
794 self.set_combo_trigger_type(combo_trigger_type);
795 }
796 #[getter]
797 fn get_combo_trigger_prescale(&self) -> Option<f32> {
798 self.combo_trigger_prescale
799 }
800 #[setter]
801 #[pyo3(name="set_combo_trigger_prescale")]
802 fn set_combo_trigger_prescale_py(&mut self, prescale : f32) {
803 self.set_combo_trigger_prescale(prescale);
804 }
805 #[getter]
806 fn get_trace_suppression(&self) -> Option<bool> {
807 self.trace_suppression
808 }
809 #[setter]
810 #[pyo3(name="set_trace_suppression")]
811 fn set_trace_suppression_py(&mut self, tsup : bool) {
812 self.set_trace_suppression(tsup);
813 }
814 #[getter]
815 fn get_mtb_moni_interval(&mut self) -> Option<u16> {
816 self.mtb_moni_interval
817 }
818 #[setter]
819 #[pyo3(name="set_mtb_moni_interval")]
820 fn set_mtb_moni_interval_py(&mut self, moni_int : u16) {
821 self.set_mtb_moni_interval(moni_int);
822 }
823 #[getter]
824 fn get_tiu_ignore_busy(&self) -> Option<bool> {
825 self.tiu_ignore_busy
826 }
827
828 #[setter]
829 #[pyo3(name="set_tiu_ignore_busy")]
830 fn set_tiu_ignore_busy_py(&mut self, ignore_busy : bool) {
831 self.set_tiu_ignore_busy(ignore_busy);
832 }
833 #[getter]
834 fn get_hb_send_interval(&self) -> Option<u16> {
835 self.hb_send_interval
836 }
837
838 #[pyo3(name="to_bytestream")]
839 fn to_bytestream_py(&self) -> Vec<u8> {
840 self.to_bytestream()
841 }
842
843 #[setter]
844 #[pyo3(name="set_hb_send_interval")]
845 fn set_hb_send_interval_py(&mut self, hb_int : Option<u16>) {
846 self.hb_send_interval = hb_int;
847 }
848
849 fn __getitem__<'a>(&self, py: Python<'a>, key: &str) -> PyResult<Option<Bound<'a,PyAny>>> {
850 match key {
851 "gaps_trigger_use_beta" => Ok(Some(self.gaps_trigger_use_beta .into_pyobject(py).unwrap())),
852 "prescale" => Ok(Some(self.prescale .into_pyobject(py).unwrap())),
853 "trigger_type" => Ok(Some(self.trigger_type .into_pyobject(py).unwrap())),
854 "use_combo_trigger" => Ok(Some(self.use_combo_trigger .into_pyobject(py).unwrap())),
855 "combo_trigger_type" => Ok(Some(self.combo_trigger_type .into_pyobject(py).unwrap())),
856 "combo_trigger_prescale" => Ok(Some(self.combo_trigger_prescale.into_pyobject(py).unwrap())),
857 "trace_suppression" => Ok(Some(self.trace_suppression .into_pyobject(py).unwrap())),
858 "mtb_moni_interval" => Ok(Some(self.mtb_moni_interval .into_pyobject(py).unwrap())),
859 "tiu_ignore_busy" => Ok(Some(self.tiu_ignore_busy .into_pyobject(py).unwrap())),
860 "hb_send_interval" => Ok(Some(self.hb_send_interval .into_pyobject(py).unwrap())),
861 _ => Err(PyKeyError::new_err(format!("Key '{}' not found", key)))
862 }
863 }
864
865 fn __setitem__(&mut self, key: &str, value: &Bound<'_, PyAny>) -> PyResult<()> {
866 match key {
867 "gaps_trigger_use_beta" => {
868 self.active_fields |= 1;
869 self.gaps_trigger_use_beta = Some(value.extract::<bool>()?);
870 Ok(())
871 }
872 "prescale" => {
873 self.active_fields |= 2;
874 self.prescale = Some(value.extract::<f32>()?);
875 Ok(())
876 }
877 "trigger_type" => {
878 self.active_fields |= 4;
879 self.trigger_type = Some(value.extract::<TriggerType>()?);
880 Ok(())
881 }
882 "use_combo_trigger" => {
883 self.active_fields |= 8;
884 self.use_combo_trigger = Some(value.extract::<bool>()?);
885 Ok(())
886 }
887 "combo_trigger_type" => {
888 self.active_fields |= 16;
889 self.combo_trigger_type = Some(value.extract::<TriggerType>()?);
890 Ok(())
891 }
892 "combo_trigger_prescale" => {
893 self.active_fields |= 32;
894 self.combo_trigger_prescale = Some(value.extract::<f32>()?);
895 Ok(())
896 }
897 "trace_suppression" => {
898 self.active_fields |= 64;
899 self.trace_suppression = Some(value.extract::<bool>()?);
900 Ok(())
901 }
902 "mtb_moni_interval" => {
903 self.active_fields |= 128;
904 self.mtb_moni_interval = Some(value.extract::<u16>()?);
905 Ok(())
906 }
907 "tiu_ignore_busy" => {
908 self.active_fields |= 256;
909 self.tiu_ignore_busy = Some(value.extract::<bool>()?);
910 Ok(())
911 }
912 "hb_send_interval" => {
913 self.active_fields |= 512;
914 self.hb_send_interval = Some(value.extract::<u16>()?);
915 Ok(())
916 }
917 _ => Err(PyKeyError::new_err(format!("Key '{}' not found", key))),
918 }
919 }
920}
921
922#[cfg(feature="pybindings")]
923pythonize_packable!(TriggerConfig);
924
925#[derive(Copy, Clone, Debug, PartialEq)]
928#[cfg_attr(feature="pybindings", pyclass)]
929pub struct TofRunConfig {
930 pub active_fields : u32,
931 pub runtime : Option<u32>,
932}
933
934impl TofRunConfig {
935 pub fn new() -> Self {
936 Self {
937 active_fields : 0,
938 runtime : None
939 }
940 }
941
942 pub fn set_runtime(&mut self, runtime : u32) {
943 self.active_fields |= 1;
944 self.runtime = Some(runtime);
945 }
946}
947
948impl Default for TofRunConfig {
949 fn default() -> Self {
950 Self::new()
951 }
952}
953
954impl fmt::Display for TofRunConfig {
955 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
956 let mut repr = String::from("<TofRunConfig: ");
957 repr += &(format!("(active fields {:x})", self.active_fields));
958 if self.runtime.is_some() {
959 repr += &(format!("\n Run time : {} [s]", self.runtime.unwrap()));
960 }
961 repr += ">";
962 write!(f, "{}", repr)
963 }
964}
965
966impl TofPackable for TofRunConfig {
967 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::TofRunConfig;
968}
969
970impl Serialization for TofRunConfig {
971
972 const HEAD : u16 = 0xAAAA;
973 const TAIL : u16 = 0x5555;
974 const SIZE : usize = 12;
975
976 fn from_bytestream(stream : &Vec<u8>,
977 pos : &mut usize)
978 -> Result<Self, SerializationError>{
979 Self::verify_fixed(stream, pos)?;
980 let mut cfg = TofRunConfig::new();
981 cfg.active_fields = parse_u32(stream, pos);
982 cfg.runtime = Some(parse_u32 (stream, pos));
983 if cfg.active_fields & 1 != 1 {
986 cfg.runtime = None;
987 }
988 *pos += 2;
989 Ok(cfg)
990 }
991
992 fn to_bytestream(&self) -> Vec<u8> {
993 let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
994 bs.extend_from_slice(&Self::HEAD .to_le_bytes());
995 bs.extend_from_slice(&self.active_fields.to_le_bytes());
996 bs.extend_from_slice(&self.runtime.unwrap_or(0).to_le_bytes());
997 bs.extend_from_slice(&Self::TAIL.to_le_bytes());
998 bs
999 }
1000}
1001
1002#[cfg(feature = "random")]
1003impl FromRandom for TofRunConfig {
1004 fn from_random() -> Self {
1005 let mut cfg = Self::new();
1006 let mut rng = rand::rng();
1007 let active_fields = rng.random::<u32>();
1008 cfg.active_fields = active_fields;
1009 if active_fields & 1 == 1 {
1010 cfg.runtime = Some(rng.random::<u32>());
1011 }
1012 cfg
1013 }
1014}
1015
1016#[cfg(feature="pybindings")]
1017#[pymethods]
1018impl TofRunConfig {
1019
1020 #[getter]
1021 fn get_runtime(&self) -> Option<u32> {
1022 self.runtime
1023 }
1024
1025 #[setter]
1026 #[pyo3(name="set_runtime")]
1027 fn set_runtime_py(&mut self, runtime : u32) {
1028 self.set_runtime(runtime);
1029 }
1030}
1031
1032#[cfg(feature="pybindings")]
1033pythonize_packable!(TofRunConfig);
1034
1035#[derive(Copy, Clone, Debug, PartialEq)]
1038#[cfg_attr(feature="pybindings", pyclass)]
1039pub struct TofRBConfig {
1040 pub active_fields : u32,
1041 pub rb_moni_interval : Option<u32>,
1042 pub pb_moni_every_x : Option<u32>,
1043 pub pa_moni_every_x : Option<u32>,
1044 pub ltb_moni_every_x : Option<u32>,
1045 pub drs_deadtime_instead_fpga_temp : Option<bool>,
1046}
1047
1048impl TofRBConfig {
1049 pub fn new() -> Self {
1050 Self {
1051 active_fields : 0,
1052 rb_moni_interval : None,
1053 pb_moni_every_x : None,
1054 pa_moni_every_x : None,
1055 ltb_moni_every_x : None,
1056 drs_deadtime_instead_fpga_temp : None,
1057 }
1058 }
1059
1060 pub fn set_rb_moni_interval(&mut self, interval : u32) {
1061 self.active_fields |= 1;
1062 self.rb_moni_interval = Some(interval);
1063 }
1064
1065 pub fn set_pb_moni_every_x(&mut self, interval : u32) {
1066 self.active_fields |= 2;
1067 self.pb_moni_every_x = Some(interval);
1068 }
1069
1070 pub fn set_pa_moni_every_x(&mut self, interval : u32) {
1071 self.active_fields |= 4;
1072 self.pa_moni_every_x = Some(interval);
1073 }
1074
1075 pub fn set_ltb_moni_every_x(&mut self, interval : u32) {
1076 self.active_fields |= 8;
1077 self.ltb_moni_every_x = Some(interval);
1078 }
1079
1080 pub fn set_drs_deadtime_instead_fpga_temp(&mut self, apply : bool) {
1081 self.active_fields |= 16;
1082 self.drs_deadtime_instead_fpga_temp = Some(apply);
1083 }
1084}
1085
1086impl Default for TofRBConfig {
1087 fn default() -> Self {
1088 Self::new()
1089 }
1090}
1091
1092impl fmt::Display for TofRBConfig {
1093 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1094 let mut repr = String::from("<TofRBConfig: ");
1095 repr += &(format!("(active fields {:x})", self.active_fields));
1096 if self.rb_moni_interval.is_some() {
1097 repr += &(format!("\n RBMoni interval : {} [s]", self.rb_moni_interval.unwrap()));
1098 }
1099 if self.pa_moni_every_x.is_some() {
1100 repr += &(format!("\n PAMoni interval : {} [xRBMoni]", self.pa_moni_every_x.unwrap()));
1101 }
1102 if self.pb_moni_every_x.is_some() {
1103 repr += &(format!("\n PBMoni interval : {} [xRBMoni]", self.pb_moni_every_x.unwrap()));
1104 }
1105 if self.ltb_moni_every_x.is_some() {
1106 repr += &(format!("\n LTBMoni interval : {} [xRBMoni]", self.ltb_moni_every_x.unwrap()));
1107 }
1108 if self.drs_deadtime_instead_fpga_temp.is_some() {
1109 if self.drs_deadtime_instead_fpga_temp.unwrap() {
1110 repr += &(format!("\n -- using the fpga temp field to store drs deadtime values"));
1111 }
1112 }
1113 repr += ">";
1114 write!(f, "{}", repr)
1115 }
1116}
1117
1118impl TofPackable for TofRBConfig {
1119 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::TofRBConfig;
1120}
1121
1122impl Serialization for TofRBConfig {
1123
1124 const HEAD : u16 = 0xAAAA;
1125 const TAIL : u16 = 0x5555;
1126 const SIZE : usize = 25;
1127
1128 fn from_bytestream(stream : &Vec<u8>,
1129 pos : &mut usize)
1130 -> Result<Self, SerializationError>{
1131 Self::verify_fixed(stream, pos)?;
1132 let mut cfg = Self::new();
1133 cfg.active_fields = parse_u32(stream, pos);
1134 cfg.rb_moni_interval = Some(parse_u32 (stream, pos));
1135 cfg.pa_moni_every_x = Some(parse_u32 (stream, pos));
1136 cfg.pb_moni_every_x = Some(parse_u32 (stream, pos));
1137 cfg.ltb_moni_every_x = Some(parse_u32 (stream, pos));
1138 cfg.drs_deadtime_instead_fpga_temp = Some(parse_bool (stream, pos));
1139 if cfg.active_fields & 1 != 1 {
1142 cfg.rb_moni_interval = None;
1143 }
1144 if cfg.active_fields & 2 != 2 {
1145 cfg.pa_moni_every_x = None;
1146 }
1147 if cfg.active_fields & 4 != 4 {
1148 cfg.pb_moni_every_x = None;
1149 }
1150 if cfg.active_fields & 8 != 8 {
1151 cfg.ltb_moni_every_x = None;
1152 }
1153 if cfg.active_fields & 16 != 16 {
1154 cfg.drs_deadtime_instead_fpga_temp = None;
1155 }
1156 *pos += 2;
1157 Ok(cfg)
1158 }
1159
1160 fn to_bytestream(&self) -> Vec<u8> {
1161 let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
1162 bs.extend_from_slice(&Self::HEAD .to_le_bytes());
1163 bs.extend_from_slice(&self.active_fields.to_le_bytes());
1164 bs.extend_from_slice(&self.rb_moni_interval.unwrap_or(0).to_le_bytes());
1165 bs.extend_from_slice(&self.pa_moni_every_x.unwrap_or(0).to_le_bytes());
1166 bs.extend_from_slice(&self.pb_moni_every_x.unwrap_or(0).to_le_bytes());
1167 bs.extend_from_slice(&self.ltb_moni_every_x.unwrap_or(0).to_le_bytes());
1168 bs.push (self.drs_deadtime_instead_fpga_temp.unwrap_or(false) as u8);
1169 bs.extend_from_slice(&Self::TAIL.to_le_bytes());
1170 bs
1171 }
1172}
1173
1174#[cfg(feature = "random")]
1175impl FromRandom for TofRBConfig {
1176 fn from_random() -> Self {
1177 let mut cfg = Self::new();
1178 let mut rng = rand::rng();
1179 let active_fields = rng.random::<u32>();
1180 cfg.active_fields = active_fields;
1181 if active_fields & 1 == 1 {
1182 cfg.rb_moni_interval = Some(rng.random::<u32>());
1183 }
1184 if active_fields & 2 == 2 {
1185 cfg.pa_moni_every_x = Some(rng.random::<u32>());
1186 }
1187 if active_fields & 4 == 4 {
1188 cfg.pb_moni_every_x = Some(rng.random::<u32>());
1189 }
1190 if active_fields & 8 == 8 {
1191 cfg.ltb_moni_every_x = Some(rng.random::<u32>());
1192 }
1193 if active_fields & 16 == 16 {
1194 cfg.drs_deadtime_instead_fpga_temp = Some(rng.random::<bool>());
1195 }
1196 cfg
1197 }
1198}
1199
1200#[derive(Copy, Clone, Debug, PartialEq)]
1205#[cfg_attr(feature="pybindings", pyclass)]
1206pub struct DataPublisherConfig {
1207 pub active_fields : u32,
1208 pub mbytes_per_file : Option<u16>,
1209 pub discard_event_fraction : Option<f32>,
1210 pub send_mtb_event_packets : Option<bool>,
1211 pub send_rbwaveform_packets : Option<bool>,
1212 pub send_rbwf_every_x_event : Option<u32>,
1213 pub send_tof_summary_packets : Option<bool>,
1214 pub send_tof_event_packets : Option<bool>,
1215 pub hb_send_interval : Option<u16>,
1216}
1217
1218impl DataPublisherConfig {
1219 pub fn new() -> Self {
1220 Self {
1221 active_fields : 0,
1222 mbytes_per_file : None,
1223 discard_event_fraction : None,
1224 send_mtb_event_packets : None,
1225 send_rbwaveform_packets : None,
1226 send_rbwf_every_x_event : None,
1227 send_tof_summary_packets : None,
1228 send_tof_event_packets : None,
1229 hb_send_interval : None,
1230 }
1231 }
1232
1233 pub fn set_mbytes_per_file(&mut self, mbytes : u16) {
1234 self.active_fields |= 1;
1235 self.mbytes_per_file = Some(mbytes);
1236 }
1237
1238 pub fn set_discard_event_fraction(&mut self, frac : f32) {
1239 self.active_fields |= 2;
1240 self.discard_event_fraction = Some(frac);
1241 }
1242
1243 pub fn set_send_mtb_event_packets(&mut self, send : bool) {
1244 self.active_fields |= 4;
1245 self.send_mtb_event_packets = Some(send);
1246 }
1247
1248 pub fn set_send_rbwaveform_packets(&mut self, send : bool) {
1249 self.active_fields |= 8;
1250 self.send_rbwaveform_packets = Some(send);
1251 }
1252
1253 pub fn set_send_rbwf_every_x_event(&mut self, x : u32) {
1254 self.active_fields |= 16;
1255 self.send_rbwf_every_x_event = Some(x);
1256 }
1257
1258 pub fn set_send_tof_summary_packets(&mut self, send : bool) {
1259 self.active_fields |= 32;
1260 self.send_tof_summary_packets = Some(send);
1261 }
1262
1263 pub fn send_tof_event_packets(&mut self, send : bool) {
1264 self.active_fields |= 64;
1265 self.send_tof_event_packets = Some(send);
1266 }
1267
1268 pub fn set_hb_send_interval(&mut self, interval : u16) {
1269 self.active_fields |= 128;
1270 self.hb_send_interval = Some(interval);
1271 }
1272}
1273
1274impl Default for DataPublisherConfig {
1275 fn default() -> Self {
1276 Self::new()
1277 }
1278}
1279
1280impl fmt::Display for DataPublisherConfig {
1281 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1282 let mut repr = String::from("<DataPublisherConfig: ");
1283 repr += &(format!("(active fields {:x})", self.active_fields));
1284 if self.mbytes_per_file.is_some() {
1285 repr += &(format!("\n MBytes/FIle : {}", self.mbytes_per_file.unwrap()));
1286 }
1287 if self.discard_event_fraction.is_some() {
1288 repr += &(format!("\n DIsc. event frac : {}", self.discard_event_fraction.unwrap()));
1289 }
1290 if self.send_mtb_event_packets.is_some() {
1291 repr += &(format!("\n Send MTBPack : {}", self.send_mtb_event_packets.unwrap()));
1292 }
1293 if self.send_rbwaveform_packets.is_some() {
1294 repr += &(format!("\n Send RBWfPack : {}", self.send_rbwaveform_packets.unwrap()));
1295 }
1296 if self.send_rbwf_every_x_event.is_some() {
1297 repr += &(format!("\n RBWf every x event : {}", self.send_rbwf_every_x_event.unwrap()));
1298 }
1299 if self.send_tof_summary_packets.is_some() {
1300 repr += &(format!("\n Send TofSum : {}", self.send_tof_summary_packets.unwrap()));
1301 }
1302 if self.send_tof_event_packets.is_some() {
1303 repr += &(format!("\n Send TOfEvent : {}", self.send_tof_event_packets.unwrap()));
1304 }
1305 if self.hb_send_interval.is_some() {
1306 repr += &(format!("\n HeartBeat send int : {}", self.hb_send_interval.unwrap()));
1307 }
1308 repr += ">";
1309 write!(f, "{}", repr)
1310 }
1311}
1312
1313impl TofPackable for DataPublisherConfig {
1314 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::DataPublisherConfig;
1315}
1316
1317impl Serialization for DataPublisherConfig {
1318
1319 const HEAD : u16 = 0xAAAA;
1320 const TAIL : u16 = 0x5555;
1321 const SIZE : usize = 24;
1322
1323 fn from_bytestream(stream : &Vec<u8>,
1324 pos : &mut usize)
1325 -> Result<Self, SerializationError>{
1326 Self::verify_fixed(stream, pos)?;
1327 let mut cfg = DataPublisherConfig::new();
1328 cfg.active_fields = parse_u32(stream, pos);
1329 cfg.mbytes_per_file = Some(parse_u16 (stream, pos));
1330 cfg.discard_event_fraction = Some(parse_f32 (stream, pos));
1331 cfg.send_mtb_event_packets = Some(parse_bool(stream, pos));
1332 cfg.send_rbwaveform_packets = Some(parse_bool(stream, pos));
1333 cfg.send_rbwf_every_x_event = Some(parse_u32 (stream, pos));
1334 cfg.send_tof_summary_packets = Some(parse_bool(stream, pos));
1335 cfg.send_tof_event_packets = Some(parse_bool(stream, pos));
1336 cfg.hb_send_interval = Some(parse_u16 (stream, pos));
1337 if cfg.active_fields & 1 != 1 {
1340 cfg.mbytes_per_file = None;
1341 }
1342 if cfg.active_fields & 2 != 2 {
1343 cfg.discard_event_fraction = None;
1344 }
1345 if cfg.active_fields & 4 != 4 {
1346 cfg.send_mtb_event_packets = None;
1347 }
1348 if cfg.active_fields & 8 != 8 {
1349 cfg.send_rbwaveform_packets = None;
1350 }
1351 if cfg.active_fields & 16 != 16 {
1352 cfg.send_rbwf_every_x_event = None;
1353 }
1354 if cfg.active_fields & 32 != 32 {
1355 cfg.send_tof_summary_packets = None;
1356 }
1357 if cfg.active_fields & 64 != 64 {
1358 cfg.send_tof_event_packets = None;
1359 }
1360 if cfg.active_fields & 128 != 128 {
1361 cfg.hb_send_interval = None;
1362 }
1363 *pos += 2;
1364 Ok(cfg)
1365 }
1366
1367 fn to_bytestream(&self) -> Vec<u8> {
1368 let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
1369 bs.extend_from_slice(&Self::HEAD .to_le_bytes());
1370 bs.extend_from_slice(&self.active_fields.to_le_bytes());
1371 bs.extend_from_slice(&self.mbytes_per_file.unwrap_or(0).to_le_bytes());
1372 bs.extend_from_slice(&self.discard_event_fraction.unwrap_or(0.0).to_le_bytes());
1373 bs.push (self .send_mtb_event_packets.unwrap_or(false) as u8);
1374 bs.push (self .send_rbwaveform_packets.unwrap_or(false) as u8);
1375 bs.extend_from_slice(&self.send_rbwf_every_x_event.unwrap_or(0).to_le_bytes());
1376 bs.push (self.send_tof_summary_packets.unwrap_or(false) as u8);
1377 bs.push (self .send_tof_event_packets.unwrap_or(false) as u8);
1378 bs.extend_from_slice(&self.hb_send_interval.unwrap_or(30).to_le_bytes());
1379 bs.extend_from_slice(&Self::TAIL.to_le_bytes());
1380 bs
1381 }
1382}
1383
1384#[cfg(feature = "random")]
1385impl FromRandom for DataPublisherConfig {
1386 fn from_random() -> Self {
1387 let mut cfg = DataPublisherConfig::new();
1388 let mut rng = rand::rng();
1389 let active_fields = rng.random::<u32>();
1390 cfg.active_fields = active_fields;
1391 if active_fields & 1 == 1 {
1392 cfg.mbytes_per_file = Some(rng.random::<u16>());
1393 } else {
1394 cfg.mbytes_per_file = None;
1395 }
1396 if active_fields & 2 == 2 {
1397 cfg.discard_event_fraction = Some(rng.random::<f32>());
1398 } else {
1399 cfg.discard_event_fraction = None;
1400 }
1401 if active_fields & 4 == 4 {
1402 cfg.send_mtb_event_packets = Some(rng.random::<bool>());
1403 } else {
1404 cfg.send_mtb_event_packets = None;
1405 }
1406 if active_fields & 8 == 8 {
1407 cfg.send_rbwaveform_packets = Some(rng.random::<bool>());
1408 } else {
1409 cfg.send_rbwaveform_packets = None;
1410 }
1411 if active_fields & 16 == 16 {
1412 cfg.send_rbwf_every_x_event = Some(rng.random::<u32>());
1413 } else {
1414 cfg.send_rbwf_every_x_event = None;
1415 }
1416 if active_fields & 32 == 32 {
1417 cfg.send_tof_summary_packets = Some(rng.random::<bool>());
1418 } else {
1419 cfg.send_tof_summary_packets = None;
1420 }
1421 if active_fields & 64 == 64 {
1422 cfg.send_tof_event_packets = Some(rng.random::<bool>());
1423 } else {
1424 cfg.send_tof_event_packets = None;
1425 }
1426 if active_fields & 128 == 128 {
1427 cfg.hb_send_interval = Some(rng.random::<u16>());
1428 } else {
1429 cfg.hb_send_interval = None;
1430 }
1431 cfg
1432 }
1433}
1434
1435
1436
1437#[derive(Copy, Clone, Debug, PartialEq)]
1441#[cfg_attr(feature="pybindings", pyclass)]
1442pub struct AnalysisEngineConfig{
1443 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 }
1456
1457impl AnalysisEngineConfig {
1458 pub fn new() -> Self {
1459 Self {
1460 integration_start : 270.0,
1461 integration_window : 70.0,
1462 pedestal_thresh : 10.0,
1463 pedestal_begin_bin : 10,
1464 pedestal_win_bins : 50,
1465 use_zscore : false,
1466 find_pks_t_start : 270.0,
1467 find_pks_t_window : 70.0,
1468 min_peak_size : 3,
1469 find_pks_thresh : 10.0,
1470 max_peaks : 5, cfd_fraction : 0.2
1472 }
1473 }
1474}
1475
1476impl Default for AnalysisEngineConfig {
1477 fn default() -> Self {
1478 Self::new()
1479 }
1480}
1481
1482impl fmt::Display for AnalysisEngineConfig {
1483 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1484 let mut repr: String = String::from("<AnalysisEngineConfig");
1485 repr += &(format!("\n Integration start : {:.1}", self.integration_start));
1486 repr += &(format!("\n Integration window : {:.1}", self.integration_window));
1487 repr += &(format!("\n Pedestal threshold : {:.1}", self.pedestal_thresh));
1488 repr += &(format!("\n Pedestal start bin : {}", self.pedestal_begin_bin));
1489 repr += &(format!("\n Pedestal window num. bins : {}", self.pedestal_win_bins));
1490 repr += &(format!("\n Use zscore? : {}", self.use_zscore));
1491 repr += &(format!("\n Peakfinder start time : {:.1}", self.find_pks_t_start));
1492 repr += &(format!("\n Peakfinder window : {:.1}", self.find_pks_t_window));
1493 repr += &(format!("\n Peakfinder threshold : {:.1}", self.find_pks_thresh));
1494 repr += &(format!("\n Min. peak size : {}", self.min_peak_size));
1495 repr += &(format!("\n Max num. peaks : {}", self.max_peaks));
1496 repr += &(format!("\n CFD fraction : {:.2}", self.cfd_fraction));
1497 write!(f, "{}", repr)
1498 }
1499}
1500
1501impl TofPackable for AnalysisEngineConfig {
1502 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::AnalysisEngineConfig;
1503}
1504
1505impl Serialization for AnalysisEngineConfig {
1506
1507 const HEAD : u16 = 0xAAAA; const TAIL : u16 = 0x5555; const SIZE : usize = 65; fn from_bytestream(stream : &Vec<u8>,
1512 pos : &mut usize)
1513 -> Result<Self, SerializationError>{
1514 Self::verify_fixed(stream, pos)?;
1515 let mut cfg: AnalysisEngineConfig = AnalysisEngineConfig::new();
1516 cfg.integration_start = parse_f32(stream, pos);
1517 cfg.integration_window = parse_f32(stream, pos);
1518 cfg.pedestal_thresh = parse_f32(stream, pos);
1519 cfg.pedestal_begin_bin = parse_u64(stream, pos) as usize;
1520 cfg.pedestal_win_bins = parse_u64(stream, pos) as usize;
1521 cfg.use_zscore = parse_bool(stream, pos);
1522 cfg.find_pks_t_start = parse_f32(stream, pos);
1523 cfg.find_pks_t_window = parse_f32(stream, pos);
1524 cfg.find_pks_thresh = parse_f32(stream, pos);
1525 cfg.min_peak_size = parse_u64(stream, pos) as usize;
1526 cfg.max_peaks = parse_u64(stream, pos) as usize;
1527 cfg.cfd_fraction = parse_f32(stream, pos);
1528 *pos += 2;
1529 Ok(cfg)
1530 }
1531
1532 fn to_bytestream(&self) -> Vec<u8> {
1533 let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
1534 bs.extend_from_slice(&Self::HEAD.to_le_bytes());
1535 bs.extend_from_slice(&self.integration_start.to_le_bytes());
1536 bs.extend_from_slice(&self.integration_window.to_le_bytes());
1537 bs.extend_from_slice(&self.pedestal_thresh.to_le_bytes());
1538 bs.extend_from_slice(&(self.pedestal_begin_bin as u64).to_le_bytes());
1539 bs.extend_from_slice(&(self.pedestal_win_bins as u64).to_le_bytes());
1540 bs.push(self.use_zscore as u8);
1541 bs.extend_from_slice(&self.find_pks_t_start.to_le_bytes());
1542 bs.extend_from_slice(&self.find_pks_t_window.to_le_bytes());
1543 bs.extend_from_slice(&self.find_pks_thresh.to_le_bytes());
1544 bs.extend_from_slice(&(self.min_peak_size as u64).to_le_bytes());
1545 bs.extend_from_slice(&(self.max_peaks as u64).to_le_bytes());
1546 bs.extend_from_slice(&self.cfd_fraction.to_le_bytes());
1547 bs.extend_from_slice(&Self::TAIL.to_le_bytes());
1548 bs
1549 }
1550}
1551
1552#[cfg(feature = "random")]
1553impl FromRandom for AnalysisEngineConfig {
1554 fn from_random() -> Self {
1555 let mut cfg = AnalysisEngineConfig::new();
1556 let mut rng = rand::rng();
1557 cfg.integration_start = rng.random::<f32>();
1558 cfg.integration_window = rng.random::<f32>();
1559 cfg.pedestal_thresh = rng.random::<f32>();
1560 cfg.pedestal_begin_bin = rng.random::<u64>() as usize;
1561 cfg.pedestal_win_bins = rng.random::<u64>() as usize;
1562 cfg.use_zscore = rng.random::<bool>();
1563 cfg.find_pks_t_start = rng.random::<f32>();
1564 cfg.find_pks_t_window = rng.random::<f32>();
1565 cfg.find_pks_thresh = rng.random::<f32>();
1566 cfg.min_peak_size = rng.random::<u64>() as usize;
1567 cfg.max_peaks = rng.random::<u64>() as usize;
1568 cfg.cfd_fraction = rng.random::<f32>();
1569 cfg
1570 }
1571}
1572
1573
1574
1575#[derive(Copy, Clone, Debug, PartialEq)]
1580#[cfg_attr(feature="pybindings", pyclass)]
1581pub struct TOFEventBuilderConfig{
1582 pub active_fields : u32, pub cachesize : Option<u32>,
1584 pub n_mte_per_loop : Option<u32>,
1585 pub n_rbe_per_loop : Option<u32>,
1586 pub te_timeout_sec : Option<u32>,
1587 pub sort_events : Option<bool>,
1588 pub build_strategy : Option<BuildStrategy>,
1589 pub wait_nrb : Option<u8>,
1590 pub greediness : Option<u8>,
1591 pub hb_send_interval : Option<u16>,
1592 pub only_save_interesting : Option<bool>,
1594 pub thr_n_hits_umb : Option<u8>,
1595 pub thr_n_hits_cbe : Option<u8>,
1596 pub thr_n_hits_cor : Option<u8>,
1597 pub thr_tot_edep_umb : Option<f32>,
1598 pub thr_tot_edep_cbe : Option<f32>,
1599 pub thr_tot_edep_cor : Option<f32>
1600}
1601
1602impl TOFEventBuilderConfig {
1603 pub fn new() -> Self {
1604 Self {
1605 active_fields : 0,
1606 cachesize : None,
1607 n_mte_per_loop : None,
1608 n_rbe_per_loop : None,
1609 te_timeout_sec : None,
1610 sort_events : None,
1611 build_strategy : None,
1612 wait_nrb : None,
1613 greediness : None,
1614 hb_send_interval : None,
1615 only_save_interesting : None,
1616 thr_n_hits_umb : None,
1617 thr_n_hits_cbe : None,
1618 thr_n_hits_cor : None,
1619 thr_tot_edep_umb : None,
1620 thr_tot_edep_cbe : None,
1621 thr_tot_edep_cor : None,
1622 }
1623 }
1624
1625 pub fn set_cachesize(&mut self, csize : u32) {
1626 self.active_fields |= 1;
1627 self.cachesize = Some(csize);
1628 }
1629
1630 pub fn set_n_mte_per_loop(&mut self, n : u32) {
1631 self.active_fields |= 2;
1632 self.n_mte_per_loop = Some(n);
1633 }
1634
1635 pub fn set_n_rbe_per_loop(&mut self, n : u32) {
1636 self.active_fields |= 4;
1637 self.n_rbe_per_loop = Some(n);
1638 }
1639
1640 pub fn set_te_timeout_sec(&mut self, te : u32) {
1641 self.active_fields |= 8;
1642 self.te_timeout_sec = Some(te);
1643 }
1644
1645 pub fn set_sort_events(&mut self, sort : bool) {
1646 self.active_fields |= 16;
1647 self.sort_events = Some(sort);
1648 }
1649
1650 pub fn set_build_strategy(&mut self, bs : BuildStrategy) {
1651 self.active_fields |= 32;
1652 self.build_strategy = Some(bs);
1653 }
1654
1655 pub fn set_wait_nrb(&mut self, nrb : u8) {
1656 self.active_fields |= 64;
1657 self.wait_nrb = Some(nrb);
1658 }
1659
1660 pub fn set_greediness(&mut self, greed : u8) {
1661 self.active_fields |= 128;
1662 self.greediness = Some(greed);
1663 }
1664
1665 pub fn set_hb_send_interval(&mut self, interval : u16) {
1666 self.active_fields |= 256;
1667 self.hb_send_interval = Some(interval);
1668 }
1669
1670 pub fn set_only_save_interesting(&mut self, do_it : bool) {
1671 self.active_fields |= 512;
1672 self.only_save_interesting = Some(do_it);
1673 }
1674
1675 pub fn thr_n_hits_umb(&mut self, nhit : u8) {
1676 self.active_fields |= 1024;
1677 self.thr_n_hits_umb = Some(nhit);
1678 }
1679
1680 pub fn thr_n_hits_cbe(&mut self, nhit : u8) {
1681 self.active_fields |= 2048;
1682 self.thr_n_hits_cbe = Some(nhit);
1683 }
1684
1685 pub fn thr_n_hits_cor(&mut self, nhit : u8) {
1686 self.active_fields |= 2u32.pow(12);
1687 self.thr_n_hits_cor = Some(nhit);
1688 }
1689
1690 pub fn thr_tot_edep_umb(&mut self, thr : f32) {
1691 self.active_fields |= 2u32.pow(13);
1692 self.thr_tot_edep_umb = Some(thr);
1693 }
1694
1695 pub fn thr_tot_edep_cbe(&mut self, thr : f32) {
1696 self.active_fields |= 2u32.pow(14);
1697 self.thr_tot_edep_cbe = Some(thr);
1698 }
1699
1700 pub fn thr_tot_edep_cor(&mut self, thr : f32) {
1701 self.active_fields |= 2u32.pow(15);
1702 self.thr_tot_edep_cor = Some(thr);
1703 }
1704}
1705
1706impl Default for TOFEventBuilderConfig {
1707 fn default() -> Self {
1708 Self::new()
1709 }
1710}
1711
1712impl fmt::Display for TOFEventBuilderConfig {
1713 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1714 let mut repr = String::from("<TOFEventBuilderConfig");
1715 repr += &(format!(" (active_fields {:x}", self.active_fields));
1716 if self.cachesize.is_some() {
1717 repr += &(format!("\n Cache size : {}", self.cachesize.unwrap()));
1718 }
1719 if self.n_mte_per_loop.is_some() {
1720 repr += &(format!("\n Num. master trigger events per loop : {}", self.n_mte_per_loop.unwrap()));
1721 }
1722 if self.n_rbe_per_loop.is_some() {
1723 repr += &(format!("\n Num. readout board events per loop : {}", self.n_rbe_per_loop.unwrap()));
1724 }
1725 if self.te_timeout_sec.is_some() {
1726 repr += &(format!("\n TOF Event timeout window [sec] : {:.3}", self.te_timeout_sec.unwrap()));
1727 }
1728 if self.sort_events.is_some() {
1729 repr += &(format!("\n Sort events by ID (high resource load!) : {}", self.sort_events.unwrap()));
1730 }
1731 if self.build_strategy.is_some() {
1732 repr += &(format!("\n Build strategy : {}", self.build_strategy.unwrap()));
1733 if self.build_strategy.unwrap() == BuildStrategy::AdaptiveGreedy {
1734 if self.greediness.is_some() {
1735 repr += &(format!("\n Additional RBs considered (greediness) : {}", self.greediness.unwrap()));
1736 }
1737 } else if self.build_strategy.unwrap() == BuildStrategy::WaitForNBoards {
1738 if self.wait_nrb.is_some() {
1739 repr += &(format!("\n Waiting for {} boards", self.wait_nrb.unwrap()))
1740 }
1741 }
1742 }
1743 if self.hb_send_interval.is_some() {
1744 repr += &(format!("\n Heartbeat send interval : {}", self.hb_send_interval.unwrap()));
1745 }
1746 if self.only_save_interesting.is_some() {
1747 repr += &(format!("\n Saving only interesting events : {}", self.only_save_interesting.unwrap()));
1748 }
1749 if self.thr_n_hits_umb.is_some() {
1750 repr += &(format!("\n Interesting threshold for nhit umb : {}", self.thr_n_hits_umb.unwrap()));
1751 }
1752 if self.thr_n_hits_cbe.is_some() {
1753 repr += &(format!("\n Interesting threshold for nhit cbe : {}", self.thr_n_hits_cbe.unwrap()));
1754 }
1755 if self.thr_n_hits_cor.is_some() {
1756 repr += &(format!("\n Interesting threshold for nhit cor : {}", self.thr_n_hits_cor.unwrap()));
1757 }
1758 if self.thr_tot_edep_umb.is_some() {
1759 repr += &(format!("\n Interesting threshold for tot edep umb : {}", self.thr_tot_edep_umb.unwrap()));
1760 }
1761 if self.thr_tot_edep_cbe.is_some() {
1762 repr += &(format!("\n Interesting threshold for tot edep cbe : {}", self.thr_tot_edep_cbe.unwrap()));
1763 }
1764 if self.thr_tot_edep_cor.is_some() {
1765 repr += &(format!("\n Interesting threshold for tot edep cor : {}", self.thr_tot_edep_cor.unwrap()));
1766 }
1767 write!(f, "{}", repr)
1768 }
1769}
1770
1771impl TofPackable for TOFEventBuilderConfig {
1772 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::TOFEventBuilderConfig;
1773}
1774
1775impl Serialization for TOFEventBuilderConfig {
1776
1777 const HEAD : u16 = 0xAAAA;
1778 const TAIL : u16 = 0x5555;
1779 const SIZE : usize = 46;
1780
1781 fn from_bytestream(stream : &Vec<u8>,
1782 pos : &mut usize)
1783 -> Result<Self, SerializationError> {
1784 Self::verify_fixed(stream, pos)?;
1785 let mut cfg = TOFEventBuilderConfig::new();
1786 cfg.active_fields = parse_u32(stream, pos);
1787 cfg.cachesize = Some(parse_u32(stream, pos));
1788 cfg.n_mte_per_loop = Some(parse_u32(stream, pos));
1789 cfg.n_rbe_per_loop = Some(parse_u32(stream, pos));
1790 cfg.te_timeout_sec = Some(parse_u32(stream, pos));
1791 cfg.sort_events = Some(parse_bool(stream, pos));
1792 cfg.build_strategy = Some(BuildStrategy::from(parse_u8(stream, pos)));
1793 cfg.wait_nrb = Some(parse_u8(stream, pos));
1794 cfg.greediness = Some(parse_u8(stream, pos));
1795 cfg.hb_send_interval = Some(parse_u16(stream, pos));
1796 cfg.only_save_interesting = Some(parse_bool(stream, pos));
1798 cfg.thr_n_hits_umb = Some(parse_u8(stream, pos));
1799 cfg.thr_n_hits_cbe = Some(parse_u8(stream, pos));
1800 cfg.thr_n_hits_cor = Some(parse_u8(stream, pos));
1801 cfg.thr_tot_edep_umb = Some(parse_f32(stream, pos));
1802 cfg.thr_tot_edep_cbe = Some(parse_f32(stream, pos));
1803 cfg.thr_tot_edep_cor = Some(parse_f32(stream, pos));
1804
1805 if cfg.active_fields & 1 != 1 {
1806 cfg.cachesize = None;
1807 }
1808 if cfg.active_fields & 2 != 2 {
1809 cfg.n_mte_per_loop = None;
1810 }
1811 if cfg.active_fields & 4 != 4 {
1812 cfg.n_rbe_per_loop = None;
1813 }
1814 if cfg.active_fields & 8 != 8 {
1815 cfg.te_timeout_sec = None;
1816 }
1817 if cfg.active_fields & 16 != 16 {
1818 cfg.sort_events = None;
1819 }
1820 if cfg.active_fields & 32 != 32 {
1821 cfg.build_strategy = None;
1822 }
1823 if cfg.active_fields & 64 != 64 {
1824 cfg.wait_nrb = None;
1825 }
1826 if cfg.active_fields & 128 != 128 {
1827 cfg.greediness = None;
1828 }
1829 if cfg.active_fields & 256 != 256 {
1830 cfg.hb_send_interval = None;
1831 }
1832 if cfg.active_fields & 512 != 512 {
1833 cfg.only_save_interesting = None;
1834 }
1835 if cfg.active_fields & 1024 != 1024 {
1836 cfg.thr_n_hits_umb = None;
1837 }
1838 if cfg.active_fields & 2048 != 2048 {
1839 cfg.thr_n_hits_cbe = None;
1840 }
1841 if cfg.active_fields & 2u32.pow(12) != 2u32.pow(12) {
1842 cfg.thr_n_hits_cor = None;
1843 }
1844 if cfg.active_fields & 2u32.pow(13) != 2u32.pow(13) {
1845 cfg.thr_tot_edep_umb = None;
1846 }
1847 if cfg.active_fields & 2u32.pow(14) != 2u32.pow(14) {
1848 cfg.thr_tot_edep_cbe = None;
1849 }
1850 if cfg.active_fields & 2u32.pow(15) != 2u32.pow(15) {
1851 cfg.thr_tot_edep_cor = None;
1852 }
1853 *pos += 2;
1854 Ok(cfg)
1855 }
1856
1857 fn to_bytestream(&self) -> Vec<u8> {
1858 let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
1859 bs.extend_from_slice(&Self::HEAD.to_le_bytes());
1860 bs.extend_from_slice(&self.active_fields.to_le_bytes());
1861 bs.extend_from_slice(&self.cachesize.unwrap_or(0).to_le_bytes());
1862 bs.extend_from_slice(&self.n_mte_per_loop.unwrap_or(0).to_le_bytes());
1863 bs.extend_from_slice(&self.n_rbe_per_loop.unwrap_or(0).to_le_bytes());
1864 bs.extend_from_slice(&self.te_timeout_sec.unwrap_or(0).to_le_bytes());
1865 bs.push(self.sort_events.unwrap_or(false) as u8);
1866 bs.push(self.build_strategy.unwrap_or(BuildStrategy::Unknown) as u8);
1867 bs.push(self.wait_nrb.unwrap_or(0));
1868 bs.push(self.greediness.unwrap_or(0));
1869 bs.extend_from_slice(&self.hb_send_interval.unwrap_or(0).to_le_bytes());
1870 bs.push(self.only_save_interesting.unwrap_or(false) as u8);
1872 bs.extend_from_slice(&self.thr_n_hits_umb.unwrap_or(0).to_le_bytes());
1873 bs.extend_from_slice(&self.thr_n_hits_cbe.unwrap_or(0).to_le_bytes());
1874 bs.extend_from_slice(&self.thr_n_hits_cor.unwrap_or(0).to_le_bytes());
1875 bs.extend_from_slice(&self.thr_tot_edep_umb.unwrap_or(0.0).to_le_bytes());
1876 bs.extend_from_slice(&self.thr_tot_edep_cbe.unwrap_or(0.0).to_le_bytes());
1877 bs.extend_from_slice(&self.thr_tot_edep_cor.unwrap_or(0.0).to_le_bytes());
1878 bs.extend_from_slice(&Self::TAIL.to_le_bytes());
1879 bs
1880 }
1881}
1882
1883#[cfg(feature = "random")]
1884impl FromRandom for TOFEventBuilderConfig {
1885 fn from_random() -> Self {
1886 let mut cfg = TOFEventBuilderConfig::new();
1887 let mut rng = rand::rng();
1888 cfg.active_fields = rng.random::<u32>();
1889 if cfg.active_fields & 1 == 1 {
1890 cfg.cachesize = Some(rng.random::<u32>());
1891 }
1892 if cfg.active_fields & 2 == 2 {
1893 cfg.n_mte_per_loop = Some(rng.random::<u32>());
1894 }
1895 if cfg.active_fields & 4 == 4 {
1896 cfg.n_rbe_per_loop = Some(rng.random::<u32>());
1897 }
1898 if cfg.active_fields & 8 == 8 {
1899 cfg.te_timeout_sec = Some(rng.random::<u32>());
1900 }
1901 if cfg.active_fields & 16 == 16 {
1902 cfg.sort_events = Some(rng.random::<bool>());
1903 }
1904 if cfg.active_fields & 32 == 32 {
1905 cfg.build_strategy = Some(BuildStrategy::from_random());
1906 }
1907 if cfg.active_fields & 64 == 64 {
1908 cfg.wait_nrb = Some(rng.random::<u8>());
1909 }
1910 if cfg.active_fields & 128 == 128 {
1911 cfg.greediness = Some(rng.random::<u8>());
1912 }
1913 if cfg.active_fields & 256 == 256 {
1914 cfg.hb_send_interval = Some(rng.random::<u16>());
1915 }
1916 if cfg.active_fields & 512 == 512 {
1917 cfg.only_save_interesting = Some(rng.random::<bool>());
1918 }
1919 if cfg.active_fields & 1024 == 1024 {
1920 cfg.thr_n_hits_umb = Some(rng.random::<u8>());
1921 }
1922 if cfg.active_fields & 2048 == 2048 {
1923 cfg.thr_n_hits_cbe = Some(rng.random::<u8>());
1924 }
1925 if cfg.active_fields & 2u32.pow(12) == 2u32.pow(12) {
1926 cfg.thr_n_hits_cor = Some(rng.random::<u8>());
1927 }
1928 if cfg.active_fields & 2u32.pow(13) == 2u32.pow(13) {
1929 cfg.thr_tot_edep_umb = Some(rng.random::<f32>());
1930 }
1931 if cfg.active_fields & 2u32.pow(14) == 2u32.pow(14) {
1932 cfg.thr_tot_edep_cbe = Some(rng.random::<f32>());
1933 }
1934 if cfg.active_fields & 2u32.pow(15) == 2u32.pow(15) {
1935 cfg.thr_tot_edep_cor = Some(rng.random::<f32>());
1936 }
1937 cfg
1938 }
1939}
1940
1941
1942
1943#[cfg(feature = "random")]
1944#[test]
1945fn pack_analysisengineconfig() {
1946 for _ in 0..100 {
1947 let cfg = AnalysisEngineConfig::from_random();
1948 let test : AnalysisEngineConfig = cfg.pack().unpack().unwrap();
1949 assert_eq!(cfg, test);
1950 }
1951}
1952
1953
1954
1955#[cfg(feature = "random")]
1959#[test]
1960fn pack_preampbiasconfig() {
1961 for _ in 0..100 {
1962 let cfg = PreampBiasConfig::from_random();
1963 let test : PreampBiasConfig = cfg.pack().unpack().unwrap();
1964 assert_eq!(cfg, test);
1965 }
1966}
1967
1968#[cfg(feature = "random")]
1969#[test]
1970fn pack_rb_channel_mask_config() {
1971 for _ in 0..100 {
1972 let cfg = RBChannelMaskConfig::from_random();
1973 let test : RBChannelMaskConfig = cfg.pack().unpack().unwrap();
1974 assert_eq!(cfg, test);
1975 }
1976}
1977
1978
1979#[cfg(feature = "random")]
1980#[test]
1981fn pack_ltbthresholdconfig() {
1982 for _ in 0..100 {
1983 let cfg = LTBThresholdConfig::from_random();
1984 let test : LTBThresholdConfig = cfg.pack().unpack().unwrap();
1985 assert_eq!(cfg, test);
1986 }
1987}
1988
1989#[cfg(feature = "random")]
1990#[test]
1991fn pack_runconfig() {
1992 for _ in 0..100 {
1993 let cfg = RunConfig::from_random();
1994 let test = cfg.pack().unpack().unwrap();
1995 assert_eq!(cfg, test);
1997
1998 let cfg_json = serde_json::to_string(&cfg).unwrap();
1999 let test_json
2000 = serde_json::from_str::<RunConfig>(&cfg_json).unwrap();
2001 assert_eq!(cfg, test_json);
2002 }
2003}
2004
2005#[cfg(feature = "random")]
2006#[test]
2007fn pack_triggerconfig() {
2008 for _ in 0..100 {
2009 let cfg = TriggerConfig::from_random();
2010 let test : TriggerConfig = cfg.pack().unpack().unwrap();
2011 assert_eq!(cfg, test);
2012 }
2013}
2014
2015#[cfg(feature = "random")]
2016#[test]
2017fn pack_tofeventbuilderconfig() {
2018 for _ in 0..100 {
2019 let cfg = TOFEventBuilderConfig::from_random();
2020 let test : TOFEventBuilderConfig = cfg.pack().unpack().unwrap();
2021 assert_eq!(cfg, test);
2022 }
2023}
2024
2025#[cfg(feature = "random")]
2026#[test]
2027fn pack_datapublisherconfig() {
2028 for _ in 0..100 {
2029 let cfg = DataPublisherConfig::from_random();
2030 let test : DataPublisherConfig = cfg.pack().unpack().unwrap();
2031 assert_eq!(cfg, test);
2032 }
2033}
2034
2035#[cfg(feature = "random")]
2036#[test]
2037fn pack_tofrunconfig() {
2038 for _ in 0..100 {
2039 let cfg = TofRunConfig::from_random();
2040 let test : TofRunConfig = cfg.pack().unpack().unwrap();
2041 assert_eq!(cfg, test);
2042 }
2043}
2044
2045#[cfg(feature = "random")]
2046#[test]
2047fn pack_tofrbconfig() {
2048 for _ in 0..100 {
2049 let cfg = TofRBConfig::from_random();
2050 let test : TofRBConfig = cfg.pack().unpack().unwrap();
2051 assert_eq!(cfg, test);
2052 }
2053}
2054