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