1use crate::prelude::*;
13
14#[derive(Debug, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
16pub enum ParameterSetStrategy {
17 ControlServer,
19 Board
21}
22
23#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
25pub struct MTBSettings {
26 pub trigger_type : TriggerType,
28 pub trigger_prescale : f32,
35 pub use_combo_trigger : bool,
37 pub global_trigger_type : TriggerType,
40 pub global_trigger_prescale : f32,
42
43 pub poisson_trigger_rate : u32,
45 pub gaps_trigger_use_beta : bool,
48 pub trace_suppression : bool,
64 pub mtb_timeout_sec : u64,
68 pub mtb_moni_interval : u64,
71 pub rb_int_window : u8,
72 pub tiu_emulation_mode : bool,
73 pub tiu_ignore_busy : bool,
74 pub tofbot_webhook : String,
75 pub hb_send_interval : u64,
76 pub use_fixed_deadtime : Option<bool>,
81}
82
83impl MTBSettings {
84 pub fn new() -> Self {
85 Self {
86 trigger_type : TriggerType::Unknown,
87 trigger_prescale : 0.0,
88 poisson_trigger_rate : 0,
89 gaps_trigger_use_beta : true,
90 trace_suppression : true,
91 mtb_timeout_sec : 60,
92 mtb_moni_interval : 30,
93 rb_int_window : 1,
94 tiu_emulation_mode : false,
95 tiu_ignore_busy : false,
96 tofbot_webhook : String::from(""),
97 hb_send_interval : 30,
98 use_combo_trigger : false,
99 global_trigger_type : TriggerType::Unknown,
100 global_trigger_prescale : 1.0,
101 use_fixed_deadtime : None,
102 }
103 }
104
105 pub fn emit_triggerconfig(&self) -> TriggerConfig {
108 let mut cfg = TriggerConfig::new();
109 cfg.active_fields = u32::MAX;
113 cfg.gaps_trigger_use_beta = Some(self.gaps_trigger_use_beta);
114 cfg.prescale = Some(self.trigger_prescale);
115 cfg.trigger_type = Some(self.trigger_type);
116 cfg.use_combo_trigger = Some(self.use_combo_trigger);
117 cfg.combo_trigger_type = Some(self.global_trigger_type);
118 cfg.combo_trigger_prescale = Some(self.global_trigger_prescale);
119 cfg.trace_suppression = Some(self.trace_suppression);
120 cfg.mtb_moni_interval = Some((self.mtb_moni_interval & 0xffff) as u16);
121 cfg.tiu_ignore_busy = Some(self.tiu_ignore_busy);
122 cfg.hb_send_interval = Some((self.hb_send_interval & 0xffff) as u16);
123 cfg
124 }
125
126 pub fn from_triggerconfig(&mut self, cfg : &TriggerConfig) {
128 if cfg.gaps_trigger_use_beta.is_some() {
129 self.gaps_trigger_use_beta = cfg.gaps_trigger_use_beta.unwrap() ;
130 }
131 if cfg.prescale.is_some() {
132 self.trigger_prescale = cfg.prescale.unwrap() ;
133 }
134 if cfg.trigger_type.is_some() {
135 self.trigger_type = cfg.trigger_type.unwrap() ;
136 }
137 if cfg.use_combo_trigger.is_some() {
138 self.use_combo_trigger = cfg.use_combo_trigger.unwrap() ;
139 }
140 if cfg.combo_trigger_type.is_some() {
141 self.global_trigger_type = cfg.combo_trigger_type.unwrap() ;
142 }
143 if cfg.combo_trigger_prescale.is_some() {
144 self.global_trigger_prescale = cfg.combo_trigger_prescale.unwrap();
145 }
146 if cfg.trace_suppression.is_some() {
147 self.trace_suppression = cfg.trace_suppression.unwrap() ;
148 }
149 if cfg.mtb_moni_interval.is_some() {
150 self.mtb_moni_interval = cfg.mtb_moni_interval.unwrap() as u64;
151 }
152 if cfg.tiu_ignore_busy.is_some() {
153 self.tiu_ignore_busy = cfg.tiu_ignore_busy.unwrap() ;
154 }
155 if cfg.hb_send_interval.is_some() {
156 self.hb_send_interval = cfg.hb_send_interval.unwrap() as u64;
157 }
158 }
159}
160
161impl fmt::Display for MTBSettings {
162 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
163 let disp = toml::to_string(self).unwrap_or(
164 String::from("-- DESERIALIZATION ERROR! --"));
165 write!(f, "<MTBSettings :\n{}>", disp)
166 }
167}
168
169impl Default for MTBSettings {
170 fn default() -> Self {
171 Self::new()
172 }
173}
174
175#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
176pub struct PreampSettings {
177 pub set_preamp_voltages : bool,
179 pub set_strategy : ParameterSetStrategy,
182 pub rat_preamp_biases : HashMap<String, [f32;16]>
184}
185
186impl PreampSettings {
187 pub fn new() -> Self {
188 let default_biases = HashMap::from([
190 (String::from("RAT01"), [58.0;16]),
191 (String::from("RAT02"), [58.0;16]),
192 (String::from("RAT03"), [58.0;16]),
193 (String::from("RAT04"), [58.0;16]),
194 (String::from("RAT05"), [58.0;16]),
195 (String::from("RAT06"), [58.0;16]),
196 (String::from("RAT07"), [58.0;16]),
197 (String::from("RAT08"), [58.0;16]),
198 (String::from("RAT09"), [58.0;16]),
199 (String::from("RAT10"), [58.0;16]),
200 (String::from("RAT11"), [58.0;16]),
201 (String::from("RAT12"), [58.0;16]),
202 (String::from("RAT13"), [58.0;16]),
203 (String::from("RAT14"), [58.0;16]),
204 (String::from("RAT15"), [58.0;16]),
205 (String::from("RAT16"), [58.0;16]),
206 (String::from("RAT17"), [58.0;16]),
207 (String::from("RAT18"), [58.0;16]),
208 (String::from("RAT19"), [58.0;16]),
209 (String::from("RAT20"), [58.0;16])]);
210
211 Self {
212 set_preamp_voltages : false,
213 set_strategy : ParameterSetStrategy::ControlServer,
214 rat_preamp_biases : default_biases,
215 }
216 }
217
218 #[cfg(feature="database")]
219 pub fn emit_pb_settings_packets(&self, rats : &HashMap<u8,RAT>) -> Vec<TofPacket> {
220 let mut packets = Vec::<TofPacket>::new();
221 for k in rats.keys() {
222 let rat = &rats[&k];
223 let rat_key = format!("RAT{:2}", rat);
224 let mut cmd = TofCommand::new();
225 cmd.command_code = TofCommandCode::SetPreampBias;
226 let mut payload = PreampBiasConfig::new();
227 payload.rb_id = rat.rb2_id as u8;
228 if *k as usize >= self.rat_preamp_biases.len() {
229 error!("RAT ID {k} larger than 20!");
230 continue;
231 }
232 payload.biases = self.rat_preamp_biases[&rat_key];
233 cmd.payload = payload.to_bytestream();
234 let tp = cmd.pack();
235 packets.push(tp);
236 }
237 packets
238 }
239}
240
241impl fmt::Display for PreampSettings {
242 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
243 let disp : String;
244 match toml::to_string(self) {
245 Err(err) => {
246 error!("Deserialization error! {err}");
247 disp = String::from("-- DESERIALIZATION ERROR! --");
248 }
249 Ok(_disp) => {
250 disp = _disp;
251 }
252 }
253 write!(f, "<PreampBiasSettings :\n{}>", disp)
254 }
255}
256
257impl Default for PreampSettings {
258 fn default() -> Self {
259 Self::new()
260 }
261}
262
263#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
264pub struct LTBThresholdSettings {
265 pub set_ltb_thresholds : bool,
267 pub set_strategy : ParameterSetStrategy,
270 pub rat_ltb_thresholds : HashMap<String, [f32;3]>
272}
273
274impl LTBThresholdSettings {
275 pub fn new() -> Self {
276 let default_thresholds = HashMap::from([
277 (String::from("RAT01"), [40.0,32.0,375.0]),
278 (String::from("RAT02"), [40.0,32.0,375.0]),
279 (String::from("RAT03"), [40.0,32.0,375.0]),
280 (String::from("RAT04"), [40.0,32.0,375.0]),
281 (String::from("RAT05"), [40.0,32.0,375.0]),
282 (String::from("RAT06"), [40.0,32.0,375.0]),
283 (String::from("RAT07"), [40.0,32.0,375.0]),
284 (String::from("RAT08"), [40.0,32.0,375.0]),
285 (String::from("RAT09"), [40.0,32.0,375.0]),
286 (String::from("RAT10"), [40.0,32.0,375.0]),
287 (String::from("RAT11"), [40.0,32.0,375.0]),
288 (String::from("RAT12"), [40.0,32.0,375.0]),
289 (String::from("RAT13"), [40.0,32.0,375.0]),
290 (String::from("RAT14"), [40.0,32.0,375.0]),
291 (String::from("RAT15"), [40.0,32.0,375.0]),
292 (String::from("RAT16"), [40.0,32.0,375.0]),
293 (String::from("RAT17"), [40.0,32.0,375.0]),
294 (String::from("RAT18"), [40.0,32.0,375.0]),
295 (String::from("RAT19"), [40.0,32.0,375.0]),
296 (String::from("RAT20"), [40.0,32.0,375.0])]);
297
298 Self {
299 set_ltb_thresholds : false,
300 set_strategy : ParameterSetStrategy::ControlServer,
301 rat_ltb_thresholds : default_thresholds,
302 }
303 }
304
305 #[cfg(feature="database")]
306 pub fn emit_ltb_settings_packets(&self, rats : &HashMap<u8,RAT>) -> Vec<TofPacket> {
307 let mut packets = Vec::<TofPacket>::new();
308 for k in rats.keys() {
309 let rat = &rats[&k];
310 let rat_key = format!("RAT{:2}", rat);
311 let mut cmd = TofCommand::new();
312 cmd.command_code = TofCommandCode::SetLTBThresholds;
313 let mut payload = LTBThresholdConfig::new();
314 payload.rb_id = rat.rb1_id as u8;
315 if *k as usize >= self.rat_ltb_thresholds.len() {
316 error!("RAT ID {k} larger than 20!");
317 continue;
318 }
319 payload.thresholds = self.rat_ltb_thresholds[&rat_key];
320 cmd.payload = payload.to_bytestream();
321 let tp = cmd.pack();
322 packets.push(tp);
323 }
324 packets
325 }
326}
327
328impl fmt::Display for LTBThresholdSettings {
329 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
330 let disp : String;
331 match toml::to_string(self) {
332 Err(err) => {
333 error!("Deserialization error! {err}");
334 disp = String::from("-- DESERIALIZATION ERROR! --");
335 }
336 Ok(_disp) => {
337 disp = _disp;
338 }
339 }
340 write!(f, "<LTBThresholdSettings :\n{}>", disp)
341 }
342}
343
344impl Default for LTBThresholdSettings {
345 fn default() -> Self {
346 Self::new()
347 }
348}
349
350#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
351pub struct CommandDispatcherSettings {
352 pub cmd_log_path : String,
357 pub cc_server_address : String,
363 pub fc_sub_address : String,
367 pub cmd_listener_interval_sec : u64,
369 pub deny_all_requests : bool
372}
373
374impl CommandDispatcherSettings {
375 pub fn new() -> Self {
376 Self {
377 cmd_log_path : String::from("/home/gaps/log"),
378 cc_server_address : String::from("tcp://10.0.1.10:42000"),
379 fc_sub_address : String::from("tcp://192.168.37.200:41662"),
380 cmd_listener_interval_sec : 1,
381 deny_all_requests : false
382 }
383 }
384}
385
386impl fmt::Display for CommandDispatcherSettings {
387 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
388 let disp = toml::to_string(self).unwrap_or(
389 String::from("-- DESERIALIZATION ERROR! --"));
390 write!(f, "<CommandDispatcherSettings :\n{}>", disp)
391 }
392}
393
394impl Default for CommandDispatcherSettings {
395 fn default() -> Self {
396 Self::new()
397 }
398}
399
400#[derive(Clone, Copy, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
402pub enum RBBufferStrategy {
403 NEvents(u16),
406 AdaptToRate(u16),
410}
411
412impl fmt::Display for RBBufferStrategy {
413 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
414 let r = serde_json::to_string(self).unwrap_or(
415 String::from("N.A. - Invalid RBBufferStrategy (error)"));
416 write!(f, "<RBBufferStrategy: {}>", r)
417 }
418}
419
420
421#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
423pub struct RBSettings {
424 pub only_perfect_events : bool,
428 pub calc_crc32 : bool,
431 pub tof_op_mode : TofOperationMode,
434 pub trigger_poisson_rate : u32,
437 pub trigger_fixed_rate : u32,
440 pub data_type : DataType,
450 pub rb_buff_strategy : RBBufferStrategy,
461 pub rb_moni_interval : f32,
464 pub pb_moni_every_x : f32,
466 pub pa_moni_every_x : f32,
468 pub ltb_moni_every_x : f32,
470 pub drs_deadtime_instead_fpga_temp : bool
472}
473
474impl RBSettings {
475 pub fn new() -> Self {
476 Self {
477 only_perfect_events : false,
478 calc_crc32 : false,
479 tof_op_mode : TofOperationMode::Default,
480 trigger_fixed_rate : 0,
481 trigger_poisson_rate : 0,
482 data_type : DataType::Physics,
483 rb_buff_strategy : RBBufferStrategy::AdaptToRate(5),
484 rb_moni_interval : 0.0,
485 pb_moni_every_x : 0.0,
486 pa_moni_every_x : 0.0,
487 ltb_moni_every_x : 0.0,
488 drs_deadtime_instead_fpga_temp : false
489 }
490 }
491
492 pub fn from_tofrbconfig(&mut self, cfg : &TofRBConfig) {
493 if cfg.rb_moni_interval.is_some() {
494 self.rb_moni_interval = cfg.rb_moni_interval.unwrap() as f32;
495 }
496 if cfg.rb_moni_interval.is_some() {
497 self.pb_moni_every_x = cfg.pb_moni_every_x.unwrap() as f32;
498 }
499 if cfg.rb_moni_interval.is_some() {
500 self.pa_moni_every_x = cfg.pa_moni_every_x.unwrap() as f32;
501 }
502 if cfg.rb_moni_interval.is_some() {
503 self.ltb_moni_every_x = cfg.ltb_moni_every_x.unwrap() as f32;
504 }
505 if cfg.rb_moni_interval.is_some() {
506 self.drs_deadtime_instead_fpga_temp = cfg.drs_deadtime_instead_fpga_temp.unwrap();
507 }
508 }
509
510 pub fn get_runconfig(&self) -> RunConfig {
511 let mut rcfg = RunConfig::new();
514 rcfg.is_active = true;
515 rcfg.tof_op_mode = self.tof_op_mode.clone();
516 rcfg.trigger_fixed_rate = self.trigger_fixed_rate;
517 rcfg.trigger_poisson_rate = self.trigger_poisson_rate;
518 rcfg.data_type = self.data_type.clone();
519 let buffer_trip : u16;
520 match self.rb_buff_strategy {
521 RBBufferStrategy::NEvents(buff_size) => {
522 buffer_trip = buff_size;
523 },
524 RBBufferStrategy::AdaptToRate(_) => {
525 buffer_trip = 50;
528 }
538 }
539 rcfg.rb_buff_size = buffer_trip as u16;
540 rcfg
541 }
542}
543
544impl fmt::Display for RBSettings {
545 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
546 let disp = toml::to_string(self).unwrap_or(
547 String::from("-- DESERIALIZATION ERROR! --"));
548 write!(f, "<RBSettings :\n{}>", disp)
549 }
550}
551
552impl Default for RBSettings {
553 fn default() -> Self {
554 Self::new()
555 }
556}
557
558
559#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
562pub struct AnalysisEngineSettings {
563 pub integration_start : f32,
565 pub integration_window : f32,
567 pub pedestal_thresh : f32,
569 pub pedestal_begin_bin : usize,
571 pub pedestal_win_bins : usize,
573 pub use_zscore : bool,
576 pub find_pks_t_start : f32,
578 pub find_pks_t_window : f32,
580 pub min_peak_size : usize,
582 pub find_pks_thresh : f32,
584 pub max_peaks : usize,
586 pub cfd_fraction : f32,
588 pub tot_threshold : Option<f32>
590}
591
592impl AnalysisEngineSettings {
593 pub fn new() -> Self {
594 Self {
595 integration_start : 270.0,
596 integration_window : 70.0,
597 pedestal_thresh : 10.0,
598 pedestal_begin_bin : 10,
599 pedestal_win_bins : 50,
600 use_zscore : false,
601 find_pks_t_start : 270.0,
602 find_pks_t_window : 70.0,
603 min_peak_size : 3,
604 find_pks_thresh : 10.0,
605 max_peaks : 5,
606 cfd_fraction : 0.2,
607 tot_threshold : Some(500.0),
608 }
609 }
610}
611
612impl fmt::Display for AnalysisEngineSettings {
613 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
614 let disp = toml::to_string(self).unwrap_or(
615 String::from("-- DESERIALIZATION ERROR! --"));
616 write!(f, "<AnalysisEngineSettings :\n{}>", disp)
617 }
618}
619
620impl Default for AnalysisEngineSettings {
621 fn default() -> Self {
622 Self::new()
623 }
624}
625
626#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
628pub struct TofEventBuilderSettings {
629 pub cachesize : u32,
630 pub n_mte_per_loop : u32,
631 pub n_rbe_per_loop : u32,
632 pub te_timeout_sec : u32,
635 pub sort_events : bool,
637 pub build_strategy : BuildStrategy,
638 pub greediness : u8,
639 pub wait_nrb : u8,
640 pub hb_send_interval : u16,
641 pub only_save_interesting : bool,
645 pub thr_n_hits_umb : u8,
646 pub thr_n_hits_cbe : u8,
647 pub thr_n_hits_cor : u8,
648 pub thr_tot_edep_umb : f32,
649 pub thr_tot_edep_cbe : f32,
650 pub thr_tot_edep_cor : f32,
651}
652
653impl TofEventBuilderSettings {
654 pub fn new() -> TofEventBuilderSettings {
655 TofEventBuilderSettings {
656 cachesize : 100000,
657 n_mte_per_loop : 1,
658 n_rbe_per_loop : 40,
659 te_timeout_sec : 30,
660 sort_events : false,
661 build_strategy : BuildStrategy::Adaptive,
662 greediness : 3,
663 wait_nrb : 40,
664 hb_send_interval : 30,
665 only_save_interesting : false,
666 thr_n_hits_umb : 0,
667 thr_n_hits_cbe : 0,
668 thr_n_hits_cor : 0,
669 thr_tot_edep_umb : 0.0,
670 thr_tot_edep_cbe : 0.0,
671 thr_tot_edep_cor : 0.0,
672 }
673 }
674
675 pub fn from_tofeventbuilderconfig(&mut self, cfg : &TOFEventBuilderConfig) {
676 if cfg.cachesize.is_some() {
677 self.cachesize = cfg.cachesize.unwrap();
678 }
679 if cfg.n_mte_per_loop.is_some() {
680 self.n_mte_per_loop = cfg.n_mte_per_loop.unwrap();
681 }
682 if cfg.n_rbe_per_loop.is_some() {
683 self.n_rbe_per_loop = cfg.n_rbe_per_loop.unwrap();
684 }
685 if cfg.te_timeout_sec.is_some() {
686 self.te_timeout_sec = cfg.te_timeout_sec.unwrap();
687 }
688 if cfg.sort_events.is_some() {
689 self.sort_events = cfg.sort_events.unwrap();
690 }
691 if cfg.build_strategy.is_some() {
692 self.build_strategy = cfg.build_strategy.unwrap();
693 }
694 if cfg.greediness.is_some() {
695 self.greediness = cfg.greediness.unwrap();
696 }
697 if cfg.wait_nrb.is_some() {
698 self.wait_nrb = cfg.wait_nrb.unwrap();
699 }
700 if cfg.hb_send_interval.is_some() {
701 self.hb_send_interval = cfg.hb_send_interval.unwrap();
702 }
703 if cfg.only_save_interesting.is_some() {
704 self.only_save_interesting = cfg.only_save_interesting.unwrap();
705 }
706 if cfg.thr_n_hits_umb.is_some() {
707 self.thr_n_hits_umb = cfg.thr_n_hits_umb.unwrap();
708 }
709 if cfg.thr_n_hits_cbe.is_some() {
710 self.thr_n_hits_cbe = cfg.thr_n_hits_cbe.unwrap();
711 }
712 if cfg.thr_n_hits_cor.is_some() {
713 self.thr_n_hits_cor = cfg.thr_n_hits_cor.unwrap();
714 }
715 if cfg.thr_tot_edep_umb.is_some() {
716 self.thr_tot_edep_umb = cfg.thr_tot_edep_umb.unwrap();
717 }
718 if cfg.thr_tot_edep_cbe.is_some() {
719 self.thr_tot_edep_cbe = cfg.thr_tot_edep_cbe.unwrap();
720 }
721 if cfg.thr_tot_edep_cor.is_some() {
722 self.thr_tot_edep_cor = cfg.thr_tot_edep_cor.unwrap();
723 }
724 }
725}
726
727impl fmt::Display for TofEventBuilderSettings {
728 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
729 let disp = toml::to_string(self).unwrap_or(
730 String::from("-- DESERIALIZATION ERROR! --"));
731 write!(f, "<TofEventBuilderSettings :\n{}>", disp)
732 }
733}
734
735impl Default for TofEventBuilderSettings {
736 fn default() -> Self {
737 Self::new()
738 }
739}
740
741#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
743pub struct DataPublisherSettings {
744 pub data_dir : String,
746 pub mbytes_per_file : usize,
749 pub fc_pub_address : String,
752 pub discard_event_fraction : f32,
756 pub send_mtb_event_packets : bool,
766 pub send_rbwaveform_packets : bool,
769 pub send_rbwf_every_x_event : u32,
772 pub send_tof_summary_packets : bool,
773 pub send_tof_event_packets : bool,
774 pub send_cali_packets : bool,
776 pub hb_send_interval : u16,
777}
778
779impl DataPublisherSettings {
780 pub fn new() -> Self {
781 Self {
782 data_dir : String::from(""),
783 mbytes_per_file : 420,
784 fc_pub_address : String::from(""),
785 discard_event_fraction : 0.0,
786 send_mtb_event_packets : false,
787 send_rbwaveform_packets : false,
788 send_rbwf_every_x_event : 1,
789 send_tof_summary_packets : true,
790 send_tof_event_packets : false,
791 send_cali_packets : true,
792 hb_send_interval : 30,
793 }
794 }
795
796 pub fn from_datapublisherconfig(&mut self, cfg : &DataPublisherConfig) {
797 if cfg.mbytes_per_file.is_some() {
798 self.mbytes_per_file = cfg.mbytes_per_file.unwrap() as usize;
799 }
800 if cfg.discard_event_fraction.is_some() {
801 self.discard_event_fraction = cfg.discard_event_fraction.unwrap();
802 }
803 if cfg.send_mtb_event_packets.is_some() {
804 self.send_mtb_event_packets = cfg.send_mtb_event_packets.unwrap();
805 }
806 if cfg.send_rbwaveform_packets.is_some() {
807 self.send_rbwaveform_packets = cfg.send_rbwaveform_packets.unwrap();
808 }
809 if cfg.send_rbwf_every_x_event.is_some() {
810 self.send_rbwf_every_x_event = cfg.send_rbwf_every_x_event.unwrap();
811 }
812 if cfg.send_tof_summary_packets.is_some() {
813 self.send_tof_summary_packets = cfg.send_tof_summary_packets.unwrap();
814 }
815 if cfg.send_tof_event_packets.is_some() {
816 self.send_tof_event_packets = cfg.send_tof_event_packets.unwrap();
817 }
818 if cfg.hb_send_interval.is_some() {
819 self.hb_send_interval = cfg.hb_send_interval.unwrap();
820 }
821 }
822}
823
824impl fmt::Display for DataPublisherSettings {
825 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
826 let disp = toml::to_string(self).unwrap_or(
827 String::from("-- DESERIALIZATION ERROR! --"));
828 write!(f, "<DataPublisherSettings :\n{}>", disp)
829 }
830}
831
832impl Default for DataPublisherSettings {
833 fn default() -> Self {
834 Self::new()
835 }
836}
837
838
839#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
840#[cfg_attr(feature="pybindings", pyclass)]
841pub struct LiftofSettings {
842 pub staging_dir : String,
845 pub calibration_dir : String,
847 pub db_path : String,
849 pub runtime_sec : u64,
851 pub mtb_address : String,
854 pub cpu_moni_interval_sec : u64,
857 pub rb_ignorelist_always : Vec<u8>,
860 pub rb_ignorelist_run : Vec<u8>,
862 pub run_analysis_engine : bool,
864 pub rb_controls_pb_and_ltb : Option<Vec<u8>>,
866 pub pre_run_calibration : bool,
869 pub save_cali_wf : bool,
872 #[deprecated(since = "0.11", note = "Use flag verfication_rnn and runtime instead!")]
878 pub verification_runtime_sec : Option<u32>,
879 pub verification_run : Option<bool>,
882 pub mtb_settings : MTBSettings,
884 pub event_builder_settings : TofEventBuilderSettings,
886 pub analysis_engine_settings : AnalysisEngineSettings,
888 pub data_publisher_settings : DataPublisherSettings,
890 pub cmd_dispatcher_settings : CommandDispatcherSettings,
892 pub rb_settings : RBSettings,
894 pub rb_channel_mask : ChannelMaskSettings,
897 pub preamp_settings : PreampSettings,
899 pub ltb_settings : LTBThresholdSettings
901}
902
903impl LiftofSettings {
904 pub fn new() -> Self {
905 LiftofSettings {
906 staging_dir : String::from("/home/gaps/liftof-staging"),
907 calibration_dir : String::from(""),
908 db_path : String::from("/home/gaps/config/gaps_flight.db"),
909 runtime_sec : 0,
910 mtb_address : String::from("10.0.1.10:50001"),
911 cpu_moni_interval_sec : 60,
912 rb_ignorelist_always : Vec::<u8>::new(),
913 rb_ignorelist_run : Vec::<u8>::new(),
914 rb_controls_pb_and_ltb : None,
915 run_analysis_engine : true,
916 pre_run_calibration : false,
917 save_cali_wf : false,
918 verification_runtime_sec : None, verification_run : None,
920 mtb_settings : MTBSettings::new(),
921 event_builder_settings : TofEventBuilderSettings::new(),
922 analysis_engine_settings : AnalysisEngineSettings::new(),
923 data_publisher_settings : DataPublisherSettings::new(),
924 cmd_dispatcher_settings : CommandDispatcherSettings::new(),
925 rb_settings : RBSettings::new(),
926 rb_channel_mask : ChannelMaskSettings::new(),
927 preamp_settings : PreampSettings::new(),
928 ltb_settings : LTBThresholdSettings::new(),
929 }
930 }
931
932 pub fn from_tofrunconfig(&mut self, cfg : &TofRunConfig) {
935 if cfg.runtime.is_some() {
936 self.runtime_sec = cfg.runtime.unwrap() as u64;
937 }
938 }
939
940 pub fn to_toml(&self, mut filename : String) {
942 if !filename.ends_with(".toml") {
943 filename += ".toml";
944 }
945 info!("Will write to file {}!", filename);
946 match File::create(&filename) {
947 Err(err) => {
948 error!("Unable to open file {}! {}", filename, err);
949 }
950 Ok(mut file) => {
951 match toml::to_string_pretty(&self) {
952 Err(err) => {
953 error!("Unable to serialize toml! {err}");
954 }
955 Ok(toml_string) => {
956 match file.write_all(toml_string.as_bytes()) {
957 Err(err) => error!("Unable to write to file {}! {}", filename, err),
958 Ok(_) => debug!("Wrote settings to {}!", filename)
959 }
960 }
961 }
962 }
963 }
964 }
965
966 pub fn to_json(&self, mut filename : String) {
968 if !filename.ends_with(".json") {
969 filename += ".json";
970 }
971 info!("Will write to file {}!", filename);
972 match File::create(&filename) {
973 Err(err) => {
974 error!("Unable to open file {}! {}", filename, err);
975 }
976 Ok(file) => {
977 match serde_json::to_writer_pretty(file, &self) {
978 Err(err) => {
979 error!("Unable to serialize json! {err}");
980 }
981 Ok(_) => debug!("Wrote settings to {}!", filename)
982 }
983 }
984 }
985 }
986
987 pub fn from_toml(filename : &str) -> Result<LiftofSettings, SerializationError> {
988 match File::open(filename) {
989 Err(err) => {
990 error!("Unable to open {}! {}", filename, err);
991 return Err(SerializationError::TomlDecodingError);
992 }
993 Ok(mut file) => {
994 let mut toml_string = String::from("");
995 match file.read_to_string(&mut toml_string) {
996 Err(err) => {
997 error!("Unable to read {}! {}", filename, err);
998 return Err(SerializationError::TomlDecodingError);
999 }
1000 Ok(_) => {
1001 match toml::from_str(&toml_string) {
1002 Err(err) => {
1003 error!("Can't interpret toml! {}", err);
1004 return Err(SerializationError::TomlDecodingError);
1005 }
1006 Ok(settings) => {
1007 return Ok(settings);
1008 }
1009 }
1010 }
1011 }
1012 }
1013 }
1014 }
1015}
1016
1017impl fmt::Display for LiftofSettings {
1018 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1019 let disp : String;
1020 match toml::to_string(self) {
1021 Err(err) => {
1022 println!("Deserialization error! {err}");
1023 disp = String::from("-- DESERIALIZATION ERROR! --");
1024 }
1025 Ok(_disp) => {
1026 disp = _disp;
1027 }
1028 }
1029 write!(f, "<LiftofSettings :\n{}>", disp)
1030 }
1031}
1032
1033impl Default for LiftofSettings {
1034 fn default() -> Self {
1035 Self::new()
1036 }
1037}
1038
1039#[cfg(feature="pybindings")]
1040#[pymethods]
1041impl LiftofSettings {
1042
1043 #[staticmethod]
1050 fn from_file(filename : &str) -> PyResult<Self> {
1051 match LiftofSettings::from_toml(filename) {
1052 Ok(settings) => {
1053 return Ok(settings);
1054 }
1055 Err(err) => {
1056 return Err(PyValueError::new_err(err.to_string()));
1057 }
1058 }
1059 }
1060}
1061
1062#[cfg(feature="pybindings")]
1063pythonize!(LiftofSettings);
1064
1065#[derive(Debug, Copy, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
1069pub struct LiftofRBConfig {
1070 pub nseconds : u32,
1072 pub tof_op_mode : TofOperationMode,
1075 pub trigger_poisson_rate : u32,
1078 pub trigger_fixed_rate : u32,
1081 pub data_type : DataType,
1085 pub rb_buff_size : u16
1091}
1092
1093impl LiftofRBConfig {
1094
1095 pub fn new() -> Self {
1096 Self {
1097 nseconds : 0,
1098 tof_op_mode : TofOperationMode::Default,
1099 trigger_poisson_rate : 0,
1100 trigger_fixed_rate : 0,
1101 data_type : DataType::Unknown,
1102 rb_buff_size : 0,
1103 }
1104 }
1105}
1106
1107impl Serialization for LiftofRBConfig {
1108 const HEAD : u16 = 43690; const TAIL : u16 = 21845; const SIZE : usize = 24; fn from_bytestream(bytestream : &Vec<u8>,
1113 pos : &mut usize)
1114 -> Result<Self, SerializationError> {
1115 let mut pars = Self::new();
1116 Self::verify_fixed(bytestream, pos)?;
1117 pars.nseconds = parse_u32 (bytestream, pos);
1118 pars.tof_op_mode
1119 = TofOperationMode::try_from(
1120 parse_u8(bytestream, pos))
1121 .unwrap_or_else(|_| TofOperationMode::Unknown);
1122 pars.trigger_poisson_rate = parse_u32 (bytestream, pos);
1123 pars.trigger_fixed_rate = parse_u32 (bytestream, pos);
1124 pars.data_type
1125 = DataType::try_from(parse_u8(bytestream, pos))
1126 .unwrap_or_else(|_| DataType::Unknown);
1127 pars.rb_buff_size = parse_u16(bytestream, pos);
1128 *pos += 2; Ok(pars)
1131 }
1132
1133 fn to_bytestream(&self) -> Vec<u8> {
1134 let mut stream = Vec::<u8>::with_capacity(Self::SIZE);
1135 stream.extend_from_slice(&Self::HEAD.to_le_bytes());
1136 stream.extend_from_slice(&self. nseconds.to_le_bytes());
1137 stream.extend_from_slice(&(self.tof_op_mode as u8).to_le_bytes());
1138 stream.extend_from_slice(&self.trigger_poisson_rate.to_le_bytes());
1139 stream.extend_from_slice(&self.trigger_fixed_rate.to_le_bytes());
1140 stream.extend_from_slice(&(self.data_type as u8).to_le_bytes());
1141 stream.extend_from_slice(&self.rb_buff_size.to_le_bytes());
1142 stream.extend_from_slice(&Self::TAIL.to_le_bytes());
1143 stream
1144 }
1145}
1146
1147impl Default for LiftofRBConfig {
1148 fn default() -> Self {
1149 Self::new()
1150 }
1151}
1152
1153impl fmt::Display for LiftofRBConfig {
1154 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1155 write!(f,
1156"<LiftofRBConfig -- is_active : true
1157 nseconds : {}
1158 TOF op. mode : {}
1159 data type : {}
1160 tr_poi_rate : {}
1161 tr_fix_rate : {}
1162 buff size : {} [events]>",
1163 self.nseconds,
1164 self.tof_op_mode,
1165 self.data_type,
1166 self.trigger_poisson_rate,
1167 self.trigger_fixed_rate,
1168 self.rb_buff_size)
1169 }
1170}
1171
1172#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
1221pub struct ChannelMaskSettings {
1222 pub set_channel_mask : bool,
1224 pub set_strategy : ParameterSetStrategy,
1230 pub rb_channel_mask : HashMap<String, [bool;9]>
1234}
1235
1236impl ChannelMaskSettings {
1237 pub fn new() -> Self {
1238 let mut default_thresholds = HashMap::<String, [bool; 9]>::new();
1239 for k in 1..51 {
1240 let key = format!("RB{k:02}");
1241 default_thresholds.insert(key, [true;9]);
1242 }
1243Self {
1266 set_channel_mask : false,
1267 set_strategy : ParameterSetStrategy::ControlServer,
1268 rb_channel_mask : default_thresholds,
1269 }
1270 }
1271
1272 #[cfg(feature="database")]
1273 pub fn emit_ch_mask_packets(&self, rbs : &HashMap<u8,RAT>) -> Vec<TofPacket> {
1274 let mut packets = Vec::<TofPacket>::new();
1275 for k in rbs.keys() {
1276 let rb = &rbs[&k];
1277 let rb_key = format!("RB{:2}", rb);
1278 let mut cmd = TofCommand::new();
1279 cmd.command_code = TofCommandCode::SetRBChannelMask;
1280 let mut payload = RBChannelMaskConfig::new();
1281 payload.rb_id = rb.rb2_id as u8;
1282 if *k as usize >= self.rb_channel_mask.len() {
1283 error!("RB ID {k} larger than 46!");
1284 continue;
1285 }
1286 payload.channels = self.rb_channel_mask[&rb_key];
1287 cmd.payload = payload.to_bytestream();
1288 let tp = cmd.pack();
1289 packets.push(tp);
1290 }
1291 packets
1292 }
1293}
1294impl fmt::Display for ChannelMaskSettings {
1295 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1296 let disp : String;
1297 match toml::to_string(self) {
1298 Err(err) => {
1299 error!("Deserialization error! {err}");
1300 disp = String::from("-- DESERIALIZATION ERROR! --");
1301 }
1302 Ok(_disp) => {
1303 disp = _disp;
1304 }
1305 }
1306 write!(f, "<RBChannelMaskConfig :\n{}>", disp)
1307 }
1308}
1309
1310impl Default for ChannelMaskSettings {
1311 fn default() -> Self {
1312 Self::new()
1313 }
1314}
1315
1316#[cfg(feature="random")]
1317#[test]
1318fn mtb_config() {
1319
1320 for _ in 0..100 {
1321 let cfg = TriggerConfig::from_random();
1322 let mut settings = MTBSettings::new();
1323 settings.from_triggerconfig(&cfg);
1324 let test = settings.emit_triggerconfig();
1325 if cfg.gaps_trigger_use_beta.is_some() {
1326 assert_eq!(cfg.gaps_trigger_use_beta, test.gaps_trigger_use_beta);
1327 }
1328 if cfg.prescale.is_some() {
1329 assert_eq!(cfg.prescale, test.prescale);
1330 }
1331 if cfg.trigger_type.is_some() {
1332 assert_eq!(cfg.trigger_type, test.trigger_type);
1333 }
1334 if cfg.use_combo_trigger.is_some() {
1335 assert_eq!(cfg.use_combo_trigger, test.use_combo_trigger);
1336 }
1337 if cfg.combo_trigger_type.is_some() {
1338 assert_eq!(cfg.combo_trigger_type, test.combo_trigger_type);
1339 }
1340 if cfg.combo_trigger_prescale.is_some() {
1341 assert_eq!(cfg.combo_trigger_prescale, test.combo_trigger_prescale);
1342 }
1343 if cfg.trace_suppression.is_some() {
1344 assert_eq!(cfg.trace_suppression, test.trace_suppression);
1345 }
1346 if cfg.mtb_moni_interval.is_some() {
1347 assert_eq!(cfg.mtb_moni_interval, test.mtb_moni_interval);
1348 }
1349 if cfg.tiu_ignore_busy.is_some() {
1350 assert_eq!(cfg.tiu_ignore_busy, test.tiu_ignore_busy);
1351 }
1352 if cfg.hb_send_interval.is_some() {
1353 assert_eq!(cfg.hb_send_interval, test.hb_send_interval);
1354 }
1355 }
1356}
1357
1358#[test]
1359fn write_config_file() {
1360 let settings = LiftofSettings::new();
1361 settings.to_toml(String::from("liftof-config-test.toml"));
1363}
1364
1365#[test]
1366fn read_config_file() {
1367 let _settings = LiftofSettings::from_toml("liftof-config-test.toml");
1368}
1369
1370