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}
77
78impl MTBSettings {
79 pub fn new() -> Self {
80 Self {
81 trigger_type : TriggerType::Unknown,
82 trigger_prescale : 0.0,
83 poisson_trigger_rate : 0,
84 gaps_trigger_use_beta : true,
85 trace_suppression : true,
86 mtb_timeout_sec : 60,
87 mtb_moni_interval : 30,
88 rb_int_window : 1,
89 tiu_emulation_mode : false,
90 tiu_ignore_busy : false,
91 tofbot_webhook : String::from(""),
92 hb_send_interval : 30,
93 use_combo_trigger : false,
94 global_trigger_type : TriggerType::Unknown,
95 global_trigger_prescale : 1.0,
96 }
97 }
98
99 pub fn emit_triggerconfig(&self) -> TriggerConfig {
102 let mut cfg = TriggerConfig::new();
103 cfg.active_fields = u32::MAX;
107 cfg.gaps_trigger_use_beta = Some(self.gaps_trigger_use_beta);
108 cfg.prescale = Some(self.trigger_prescale);
109 cfg.trigger_type = Some(self.trigger_type);
110 cfg.use_combo_trigger = Some(self.use_combo_trigger);
111 cfg.combo_trigger_type = Some(self.global_trigger_type);
112 cfg.combo_trigger_prescale = Some(self.global_trigger_prescale);
113 cfg.trace_suppression = Some(self.trace_suppression);
114 cfg.mtb_moni_interval = Some((self.mtb_moni_interval & 0xffff) as u16);
115 cfg.tiu_ignore_busy = Some(self.tiu_ignore_busy);
116 cfg.hb_send_interval = Some((self.hb_send_interval & 0xffff) as u16);
117 cfg
118 }
119
120 pub fn from_triggerconfig(&mut self, cfg : &TriggerConfig) {
122 if cfg.gaps_trigger_use_beta.is_some() {
123 self.gaps_trigger_use_beta = cfg.gaps_trigger_use_beta.unwrap() ;
124 }
125 if cfg.prescale.is_some() {
126 self.trigger_prescale = cfg.prescale.unwrap() ;
127 }
128 if cfg.trigger_type.is_some() {
129 self.trigger_type = cfg.trigger_type.unwrap() ;
130 }
131 if cfg.use_combo_trigger.is_some() {
132 self.use_combo_trigger = cfg.use_combo_trigger.unwrap() ;
133 }
134 if cfg.combo_trigger_type.is_some() {
135 self.global_trigger_type = cfg.combo_trigger_type.unwrap() ;
136 }
137 if cfg.combo_trigger_prescale.is_some() {
138 self.global_trigger_prescale = cfg.combo_trigger_prescale.unwrap();
139 }
140 if cfg.trace_suppression.is_some() {
141 self.trace_suppression = cfg.trace_suppression.unwrap() ;
142 }
143 if cfg.mtb_moni_interval.is_some() {
144 self.mtb_moni_interval = cfg.mtb_moni_interval.unwrap() as u64;
145 }
146 if cfg.tiu_ignore_busy.is_some() {
147 self.tiu_ignore_busy = cfg.tiu_ignore_busy.unwrap() ;
148 }
149 if cfg.hb_send_interval.is_some() {
150 self.hb_send_interval = cfg.hb_send_interval.unwrap() as u64;
151 }
152 }
153}
154
155impl fmt::Display for MTBSettings {
156 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
157 let disp = toml::to_string(self).unwrap_or(
158 String::from("-- DESERIALIZATION ERROR! --"));
159 write!(f, "<MTBSettings :\n{}>", disp)
160 }
161}
162
163impl Default for MTBSettings {
164 fn default() -> Self {
165 Self::new()
166 }
167}
168
169#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
170pub struct PreampSettings {
171 pub set_preamp_voltages : bool,
173 pub set_strategy : ParameterSetStrategy,
176 pub rat_preamp_biases : HashMap<String, [f32;16]>
178}
179
180impl PreampSettings {
181 pub fn new() -> Self {
182 let default_biases = HashMap::from([
184 (String::from("RAT01"), [58.0;16]),
185 (String::from("RAT02"), [58.0;16]),
186 (String::from("RAT03"), [58.0;16]),
187 (String::from("RAT04"), [58.0;16]),
188 (String::from("RAT05"), [58.0;16]),
189 (String::from("RAT06"), [58.0;16]),
190 (String::from("RAT07"), [58.0;16]),
191 (String::from("RAT08"), [58.0;16]),
192 (String::from("RAT09"), [58.0;16]),
193 (String::from("RAT10"), [58.0;16]),
194 (String::from("RAT11"), [58.0;16]),
195 (String::from("RAT12"), [58.0;16]),
196 (String::from("RAT13"), [58.0;16]),
197 (String::from("RAT14"), [58.0;16]),
198 (String::from("RAT15"), [58.0;16]),
199 (String::from("RAT16"), [58.0;16]),
200 (String::from("RAT17"), [58.0;16]),
201 (String::from("RAT18"), [58.0;16]),
202 (String::from("RAT19"), [58.0;16]),
203 (String::from("RAT20"), [58.0;16])]);
204
205 Self {
206 set_preamp_voltages : false,
207 set_strategy : ParameterSetStrategy::ControlServer,
208 rat_preamp_biases : default_biases,
209 }
210 }
211
212 #[cfg(feature="database")]
213 pub fn emit_pb_settings_packets(&self, rats : &HashMap<u8,RAT>) -> Vec<TofPacket> {
214 let mut packets = Vec::<TofPacket>::new();
215 for k in rats.keys() {
216 let rat = &rats[&k];
217 let rat_key = format!("RAT{:2}", rat);
218 let mut cmd = TofCommand::new();
219 cmd.command_code = TofCommandCode::SetPreampBias;
220 let mut payload = PreampBiasConfig::new();
221 payload.rb_id = rat.rb2_id as u8;
222 if *k as usize >= self.rat_preamp_biases.len() {
223 error!("RAT ID {k} larger than 20!");
224 continue;
225 }
226 payload.biases = self.rat_preamp_biases[&rat_key];
227 cmd.payload = payload.to_bytestream();
228 let tp = cmd.pack();
229 packets.push(tp);
230 }
231 packets
232 }
233}
234
235impl fmt::Display for PreampSettings {
236 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
237 let disp : String;
238 match toml::to_string(self) {
239 Err(err) => {
240 error!("Deserialization error! {err}");
241 disp = String::from("-- DESERIALIZATION ERROR! --");
242 }
243 Ok(_disp) => {
244 disp = _disp;
245 }
246 }
247 write!(f, "<PreampBiasSettings :\n{}>", disp)
248 }
249}
250
251impl Default for PreampSettings {
252 fn default() -> Self {
253 Self::new()
254 }
255}
256
257#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
258pub struct LTBThresholdSettings {
259 pub set_ltb_thresholds : bool,
261 pub set_strategy : ParameterSetStrategy,
264 pub rat_ltb_thresholds : HashMap<String, [f32;3]>
266}
267
268impl LTBThresholdSettings {
269 pub fn new() -> Self {
270 let default_thresholds = HashMap::from([
271 (String::from("RAT01"), [40.0,32.0,375.0]),
272 (String::from("RAT02"), [40.0,32.0,375.0]),
273 (String::from("RAT03"), [40.0,32.0,375.0]),
274 (String::from("RAT04"), [40.0,32.0,375.0]),
275 (String::from("RAT05"), [40.0,32.0,375.0]),
276 (String::from("RAT06"), [40.0,32.0,375.0]),
277 (String::from("RAT07"), [40.0,32.0,375.0]),
278 (String::from("RAT08"), [40.0,32.0,375.0]),
279 (String::from("RAT09"), [40.0,32.0,375.0]),
280 (String::from("RAT10"), [40.0,32.0,375.0]),
281 (String::from("RAT11"), [40.0,32.0,375.0]),
282 (String::from("RAT12"), [40.0,32.0,375.0]),
283 (String::from("RAT13"), [40.0,32.0,375.0]),
284 (String::from("RAT14"), [40.0,32.0,375.0]),
285 (String::from("RAT15"), [40.0,32.0,375.0]),
286 (String::from("RAT16"), [40.0,32.0,375.0]),
287 (String::from("RAT17"), [40.0,32.0,375.0]),
288 (String::from("RAT18"), [40.0,32.0,375.0]),
289 (String::from("RAT19"), [40.0,32.0,375.0]),
290 (String::from("RAT20"), [40.0,32.0,375.0])]);
291
292 Self {
293 set_ltb_thresholds : false,
294 set_strategy : ParameterSetStrategy::ControlServer,
295 rat_ltb_thresholds : default_thresholds,
296 }
297 }
298
299 #[cfg(feature="database")]
300 pub fn emit_ltb_settings_packets(&self, rats : &HashMap<u8,RAT>) -> Vec<TofPacket> {
301 let mut packets = Vec::<TofPacket>::new();
302 for k in rats.keys() {
303 let rat = &rats[&k];
304 let rat_key = format!("RAT{:2}", rat);
305 let mut cmd = TofCommand::new();
306 cmd.command_code = TofCommandCode::SetLTBThresholds;
307 let mut payload = LTBThresholdConfig::new();
308 payload.rb_id = rat.rb1_id as u8;
309 if *k as usize >= self.rat_ltb_thresholds.len() {
310 error!("RAT ID {k} larger than 20!");
311 continue;
312 }
313 payload.thresholds = self.rat_ltb_thresholds[&rat_key];
314 cmd.payload = payload.to_bytestream();
315 let tp = cmd.pack();
316 packets.push(tp);
317 }
318 packets
319 }
320}
321
322impl fmt::Display for LTBThresholdSettings {
323 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
324 let disp : String;
325 match toml::to_string(self) {
326 Err(err) => {
327 error!("Deserialization error! {err}");
328 disp = String::from("-- DESERIALIZATION ERROR! --");
329 }
330 Ok(_disp) => {
331 disp = _disp;
332 }
333 }
334 write!(f, "<LTBThresholdSettings :\n{}>", disp)
335 }
336}
337
338impl Default for LTBThresholdSettings {
339 fn default() -> Self {
340 Self::new()
341 }
342}
343
344#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
345pub struct CommandDispatcherSettings {
346 pub cmd_log_path : String,
351 pub cc_server_address : String,
357 pub fc_sub_address : String,
361 pub cmd_listener_interval_sec : u64,
363 pub deny_all_requests : bool
366}
367
368impl CommandDispatcherSettings {
369 pub fn new() -> Self {
370 Self {
371 cmd_log_path : String::from("/home/gaps/log"),
372 cc_server_address : String::from("tcp://10.0.1.10:42000"),
373 fc_sub_address : String::from("tcp://192.168.37.200:41662"),
374 cmd_listener_interval_sec : 1,
375 deny_all_requests : false
376 }
377 }
378}
379
380impl fmt::Display for CommandDispatcherSettings {
381 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
382 let disp = toml::to_string(self).unwrap_or(
383 String::from("-- DESERIALIZATION ERROR! --"));
384 write!(f, "<CommandDispatcherSettings :\n{}>", disp)
385 }
386}
387
388impl Default for CommandDispatcherSettings {
389 fn default() -> Self {
390 Self::new()
391 }
392}
393
394#[derive(Clone, Copy, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
396pub enum RBBufferStrategy {
397 NEvents(u16),
400 AdaptToRate(u16),
404}
405
406impl fmt::Display for RBBufferStrategy {
407 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
408 let r = serde_json::to_string(self).unwrap_or(
409 String::from("N.A. - Invalid RBBufferStrategy (error)"));
410 write!(f, "<RBBufferStrategy: {}>", r)
411 }
412}
413
414
415#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
417pub struct RBSettings {
418 pub only_perfect_events : bool,
422 pub calc_crc32 : bool,
425 pub tof_op_mode : TofOperationMode,
428 pub trigger_poisson_rate : u32,
431 pub trigger_fixed_rate : u32,
434 pub data_type : DataType,
444 pub rb_buff_strategy : RBBufferStrategy,
455 pub rb_moni_interval : f32,
458 pub pb_moni_every_x : f32,
460 pub pa_moni_every_x : f32,
462 pub ltb_moni_every_x : f32,
464 pub drs_deadtime_instead_fpga_temp : bool
466}
467
468impl RBSettings {
469 pub fn new() -> Self {
470 Self {
471 only_perfect_events : false,
472 calc_crc32 : false,
473 tof_op_mode : TofOperationMode::Default,
474 trigger_fixed_rate : 0,
475 trigger_poisson_rate : 0,
476 data_type : DataType::Physics,
477 rb_buff_strategy : RBBufferStrategy::AdaptToRate(5),
478 rb_moni_interval : 0.0,
479 pb_moni_every_x : 0.0,
480 pa_moni_every_x : 0.0,
481 ltb_moni_every_x : 0.0,
482 drs_deadtime_instead_fpga_temp : false
483 }
484 }
485
486 pub fn from_tofrbconfig(&mut self, cfg : &TofRBConfig) {
487 if cfg.rb_moni_interval.is_some() {
488 self.rb_moni_interval = cfg.rb_moni_interval.unwrap() as f32;
489 }
490 if cfg.rb_moni_interval.is_some() {
491 self.pb_moni_every_x = cfg.pb_moni_every_x.unwrap() as f32;
492 }
493 if cfg.rb_moni_interval.is_some() {
494 self.pa_moni_every_x = cfg.pa_moni_every_x.unwrap() as f32;
495 }
496 if cfg.rb_moni_interval.is_some() {
497 self.ltb_moni_every_x = cfg.ltb_moni_every_x.unwrap() as f32;
498 }
499 if cfg.rb_moni_interval.is_some() {
500 self.drs_deadtime_instead_fpga_temp = cfg.drs_deadtime_instead_fpga_temp.unwrap();
501 }
502 }
503
504 pub fn get_runconfig(&self) -> RunConfig {
505 let mut rcfg = RunConfig::new();
508 rcfg.is_active = true;
509 rcfg.tof_op_mode = self.tof_op_mode.clone();
510 rcfg.trigger_fixed_rate = self.trigger_fixed_rate;
511 rcfg.trigger_poisson_rate = self.trigger_poisson_rate;
512 rcfg.data_type = self.data_type.clone();
513 let buffer_trip : u16;
514 match self.rb_buff_strategy {
515 RBBufferStrategy::NEvents(buff_size) => {
516 buffer_trip = buff_size;
517 },
518 RBBufferStrategy::AdaptToRate(_) => {
519 buffer_trip = 50;
522 }
532 }
533 rcfg.rb_buff_size = buffer_trip as u16;
534 rcfg
535 }
536}
537
538impl fmt::Display for RBSettings {
539 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
540 let disp = toml::to_string(self).unwrap_or(
541 String::from("-- DESERIALIZATION ERROR! --"));
542 write!(f, "<RBSettings :\n{}>", disp)
543 }
544}
545
546impl Default for RBSettings {
547 fn default() -> Self {
548 Self::new()
549 }
550}
551
552
553#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
556pub struct AnalysisEngineSettings {
557 pub integration_start : f32,
559 pub integration_window : f32,
561 pub pedestal_thresh : f32,
563 pub pedestal_begin_bin : usize,
565 pub pedestal_win_bins : usize,
567 pub use_zscore : bool,
570 pub find_pks_t_start : f32,
572 pub find_pks_t_window : f32,
574 pub min_peak_size : usize,
576 pub find_pks_thresh : f32,
578 pub max_peaks : usize,
580 pub cfd_fraction : f32,
582 pub tot_threshold : Option<f32>
584}
585
586impl AnalysisEngineSettings {
587 pub fn new() -> Self {
588 Self {
589 integration_start : 270.0,
590 integration_window : 70.0,
591 pedestal_thresh : 10.0,
592 pedestal_begin_bin : 10,
593 pedestal_win_bins : 50,
594 use_zscore : false,
595 find_pks_t_start : 270.0,
596 find_pks_t_window : 70.0,
597 min_peak_size : 3,
598 find_pks_thresh : 10.0,
599 max_peaks : 5,
600 cfd_fraction : 0.2,
601 tot_threshold : Some(500.0),
602 }
603 }
604}
605
606impl fmt::Display for AnalysisEngineSettings {
607 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
608 let disp = toml::to_string(self).unwrap_or(
609 String::from("-- DESERIALIZATION ERROR! --"));
610 write!(f, "<AnalysisEngineSettings :\n{}>", disp)
611 }
612}
613
614impl Default for AnalysisEngineSettings {
615 fn default() -> Self {
616 Self::new()
617 }
618}
619
620#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
622pub struct TofEventBuilderSettings {
623 pub cachesize : u32,
624 pub n_mte_per_loop : u32,
625 pub n_rbe_per_loop : u32,
626 pub te_timeout_sec : u32,
629 pub sort_events : bool,
631 pub build_strategy : BuildStrategy,
632 pub greediness : u8,
633 pub wait_nrb : u8,
634 pub hb_send_interval : u16,
635 pub only_save_interesting : bool,
639 pub thr_n_hits_umb : u8,
640 pub thr_n_hits_cbe : u8,
641 pub thr_n_hits_cor : u8,
642 pub thr_tot_edep_umb : f32,
643 pub thr_tot_edep_cbe : f32,
644 pub thr_tot_edep_cor : f32,
645}
646
647impl TofEventBuilderSettings {
648 pub fn new() -> TofEventBuilderSettings {
649 TofEventBuilderSettings {
650 cachesize : 100000,
651 n_mte_per_loop : 1,
652 n_rbe_per_loop : 40,
653 te_timeout_sec : 30,
654 sort_events : false,
655 build_strategy : BuildStrategy::Adaptive,
656 greediness : 3,
657 wait_nrb : 40,
658 hb_send_interval : 30,
659 only_save_interesting : false,
660 thr_n_hits_umb : 0,
661 thr_n_hits_cbe : 0,
662 thr_n_hits_cor : 0,
663 thr_tot_edep_umb : 0.0,
664 thr_tot_edep_cbe : 0.0,
665 thr_tot_edep_cor : 0.0,
666 }
667 }
668
669 pub fn from_tofeventbuilderconfig(&mut self, cfg : &TOFEventBuilderConfig) {
670 if cfg.cachesize.is_some() {
671 self.cachesize = cfg.cachesize.unwrap();
672 }
673 if cfg.n_mte_per_loop.is_some() {
674 self.n_mte_per_loop = cfg.n_mte_per_loop.unwrap();
675 }
676 if cfg.n_rbe_per_loop.is_some() {
677 self.n_rbe_per_loop = cfg.n_rbe_per_loop.unwrap();
678 }
679 if cfg.te_timeout_sec.is_some() {
680 self.te_timeout_sec = cfg.te_timeout_sec.unwrap();
681 }
682 if cfg.sort_events.is_some() {
683 self.sort_events = cfg.sort_events.unwrap();
684 }
685 if cfg.build_strategy.is_some() {
686 self.build_strategy = cfg.build_strategy.unwrap();
687 }
688 if cfg.greediness.is_some() {
689 self.greediness = cfg.greediness.unwrap();
690 }
691 if cfg.wait_nrb.is_some() {
692 self.wait_nrb = cfg.wait_nrb.unwrap();
693 }
694 if cfg.hb_send_interval.is_some() {
695 self.hb_send_interval = cfg.hb_send_interval.unwrap();
696 }
697 if cfg.only_save_interesting.is_some() {
698 self.only_save_interesting = cfg.only_save_interesting.unwrap();
699 }
700 if cfg.thr_n_hits_umb.is_some() {
701 self.thr_n_hits_umb = cfg.thr_n_hits_umb.unwrap();
702 }
703 if cfg.thr_n_hits_cbe.is_some() {
704 self.thr_n_hits_cbe = cfg.thr_n_hits_cbe.unwrap();
705 }
706 if cfg.thr_n_hits_cor.is_some() {
707 self.thr_n_hits_cor = cfg.thr_n_hits_cor.unwrap();
708 }
709 if cfg.thr_tot_edep_umb.is_some() {
710 self.thr_tot_edep_umb = cfg.thr_tot_edep_umb.unwrap();
711 }
712 if cfg.thr_tot_edep_cbe.is_some() {
713 self.thr_tot_edep_cbe = cfg.thr_tot_edep_cbe.unwrap();
714 }
715 if cfg.thr_tot_edep_cor.is_some() {
716 self.thr_tot_edep_cor = cfg.thr_tot_edep_cor.unwrap();
717 }
718 }
719}
720
721impl fmt::Display for TofEventBuilderSettings {
722 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
723 let disp = toml::to_string(self).unwrap_or(
724 String::from("-- DESERIALIZATION ERROR! --"));
725 write!(f, "<TofEventBuilderSettings :\n{}>", disp)
726 }
727}
728
729impl Default for TofEventBuilderSettings {
730 fn default() -> Self {
731 Self::new()
732 }
733}
734
735#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
737pub struct DataPublisherSettings {
738 pub data_dir : String,
740 pub mbytes_per_file : usize,
743 pub fc_pub_address : String,
746 pub discard_event_fraction : f32,
750 pub send_mtb_event_packets : bool,
760 pub send_rbwaveform_packets : bool,
763 pub send_rbwf_every_x_event : u32,
766 pub send_tof_summary_packets : bool,
767 pub send_tof_event_packets : bool,
768 pub send_cali_packets : bool,
770 pub hb_send_interval : u16,
771}
772
773impl DataPublisherSettings {
774 pub fn new() -> Self {
775 Self {
776 data_dir : String::from(""),
777 mbytes_per_file : 420,
778 fc_pub_address : String::from(""),
779 discard_event_fraction : 0.0,
780 send_mtb_event_packets : false,
781 send_rbwaveform_packets : false,
782 send_rbwf_every_x_event : 1,
783 send_tof_summary_packets : true,
784 send_tof_event_packets : false,
785 send_cali_packets : true,
786 hb_send_interval : 30,
787 }
788 }
789
790 pub fn from_datapublisherconfig(&mut self, cfg : &DataPublisherConfig) {
791 if cfg.mbytes_per_file.is_some() {
792 self.mbytes_per_file = cfg.mbytes_per_file.unwrap() as usize;
793 }
794 if cfg.discard_event_fraction.is_some() {
795 self.discard_event_fraction = cfg.discard_event_fraction.unwrap();
796 }
797 if cfg.send_mtb_event_packets.is_some() {
798 self.send_mtb_event_packets = cfg.send_mtb_event_packets.unwrap();
799 }
800 if cfg.send_rbwaveform_packets.is_some() {
801 self.send_rbwaveform_packets = cfg.send_rbwaveform_packets.unwrap();
802 }
803 if cfg.send_rbwf_every_x_event.is_some() {
804 self.send_rbwf_every_x_event = cfg.send_rbwf_every_x_event.unwrap();
805 }
806 if cfg.send_tof_summary_packets.is_some() {
807 self.send_tof_summary_packets = cfg.send_tof_summary_packets.unwrap();
808 }
809 if cfg.send_tof_event_packets.is_some() {
810 self.send_tof_event_packets = cfg.send_tof_event_packets.unwrap();
811 }
812 if cfg.hb_send_interval.is_some() {
813 self.hb_send_interval = cfg.hb_send_interval.unwrap();
814 }
815 }
816}
817
818impl fmt::Display for DataPublisherSettings {
819 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
820 let disp = toml::to_string(self).unwrap_or(
821 String::from("-- DESERIALIZATION ERROR! --"));
822 write!(f, "<DataPublisherSettings :\n{}>", disp)
823 }
824}
825
826impl Default for DataPublisherSettings {
827 fn default() -> Self {
828 Self::new()
829 }
830}
831
832
833#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
834#[cfg_attr(feature="pybindings", pyclass)]
835pub struct LiftofSettings {
836 pub staging_dir : String,
839 pub calibration_dir : String,
841 pub db_path : String,
843 pub runtime_sec : u64,
845 pub mtb_address : String,
848 pub cpu_moni_interval_sec : u64,
851 pub rb_ignorelist_always : Vec<u8>,
854 pub rb_ignorelist_run : Vec<u8>,
856 pub run_analysis_engine : bool,
858 pub rb_controls_pb_and_ltb : Option<Vec<u8>>,
860 pub pre_run_calibration : bool,
863 pub save_cali_wf : bool,
866 pub verification_runtime_sec : u32,
872 pub mtb_settings : MTBSettings,
874 pub event_builder_settings : TofEventBuilderSettings,
876 pub analysis_engine_settings : AnalysisEngineSettings,
878 pub data_publisher_settings : DataPublisherSettings,
880 pub cmd_dispatcher_settings : CommandDispatcherSettings,
882 pub rb_settings : RBSettings,
884 pub rb_channel_mask : ChannelMaskSettings,
887 pub preamp_settings : PreampSettings,
889 pub ltb_settings : LTBThresholdSettings
891}
892
893impl LiftofSettings {
894 pub fn new() -> Self {
895 LiftofSettings {
896 staging_dir : String::from("/home/gaps/liftof-staging"),
897 calibration_dir : String::from(""),
898 db_path : String::from("/home/gaps/config/gaps_flight.db"),
899 runtime_sec : 0,
900 mtb_address : String::from("10.0.1.10:50001"),
901 cpu_moni_interval_sec : 60,
902 rb_ignorelist_always : Vec::<u8>::new(),
903 rb_ignorelist_run : Vec::<u8>::new(),
904 rb_controls_pb_and_ltb : None,
905 run_analysis_engine : true,
906 pre_run_calibration : false,
907 save_cali_wf : false,
908 verification_runtime_sec : 0, mtb_settings : MTBSettings::new(),
910 event_builder_settings : TofEventBuilderSettings::new(),
911 analysis_engine_settings : AnalysisEngineSettings::new(),
912 data_publisher_settings : DataPublisherSettings::new(),
913 cmd_dispatcher_settings : CommandDispatcherSettings::new(),
914 rb_settings : RBSettings::new(),
915 rb_channel_mask : ChannelMaskSettings::new(),
916 preamp_settings : PreampSettings::new(),
917 ltb_settings : LTBThresholdSettings::new(),
918 }
919 }
920
921 pub fn from_tofrunconfig(&mut self, cfg : &TofRunConfig) {
924 if cfg.runtime.is_some() {
925 self.runtime_sec = cfg.runtime.unwrap() as u64;
926 }
927 }
928
929 #[deprecated(since="0.10.0", note="This is a dev deadend and will be nuked!")]
933 pub fn set_by_key(&mut self, key : &str, value : String) {
934 match key {
935 "runtime_sec" => {
936 if let Ok(val) = value.parse::<u64>() {
937 self.runtime_sec = val;
938 } else {
939 error!("Unable to parse {value}!");
940 }
941 }
942 "cpu_moni_interval_sec" => {
943 if let Ok(val) = value.parse::<u64>() {
944 self.cpu_moni_interval_sec = val;
945 } else {
946 error!("Unable to parse {value}!");
947 }
948 }
949 "rb_ignorelist_run" => {
950 }
951 "run_analysis_engine" => {
952 if let Ok(val) = value.parse::<bool>() {
953 self.run_analysis_engine = val;
954 } else {
955 error!("Unable to parse {value}!");
956 }
957 }
958 "pre_run_calibration" => {
959 if let Ok(val) = value.parse::<bool>() {
960 self.pre_run_calibration = val;
961 } else {
962 error!("Unable to parse {value}!");
963 }
964 }
965 "save_cali_wf" => {
966 if let Ok(val) = value.parse::<bool>() {
967 self.save_cali_wf = val;
968 } else {
969 error!("Unable to parse {value}!");
970 }
971 }
972 "verification_runtime_sec" => {
973 if let Ok(val) = value.parse::<u32>() {
974 self.verification_runtime_sec = val;
975 } else {
976 error!("Unable to parse {value}!");
977 }
978 }
979 _ => error!("Set by key for {} is not implemented!", key)
980 }
981 }
982
983 pub fn to_toml(&self, mut filename : String) {
985 if !filename.ends_with(".toml") {
986 filename += ".toml";
987 }
988 info!("Will write to file {}!", filename);
989 match File::create(&filename) {
990 Err(err) => {
991 error!("Unable to open file {}! {}", filename, err);
992 }
993 Ok(mut file) => {
994 match toml::to_string_pretty(&self) {
995 Err(err) => {
996 error!("Unable to serialize toml! {err}");
997 }
998 Ok(toml_string) => {
999 match file.write_all(toml_string.as_bytes()) {
1000 Err(err) => error!("Unable to write to file {}! {}", filename, err),
1001 Ok(_) => debug!("Wrote settings to {}!", filename)
1002 }
1003 }
1004 }
1005 }
1006 }
1007 }
1008
1009 pub fn to_json(&self, mut filename : String) {
1011 if !filename.ends_with(".json") {
1012 filename += ".json";
1013 }
1014 info!("Will write to file {}!", filename);
1015 match File::create(&filename) {
1016 Err(err) => {
1017 error!("Unable to open file {}! {}", filename, err);
1018 }
1019 Ok(file) => {
1020 match serde_json::to_writer_pretty(file, &self) {
1021 Err(err) => {
1022 error!("Unable to serialize json! {err}");
1023 }
1024 Ok(_) => debug!("Wrote settings to {}!", filename)
1025 }
1026 }
1027 }
1028 }
1029
1030 pub fn from_toml(filename : &str) -> Result<LiftofSettings, SerializationError> {
1031 match File::open(filename) {
1032 Err(err) => {
1033 error!("Unable to open {}! {}", filename, err);
1034 return Err(SerializationError::TomlDecodingError);
1035 }
1036 Ok(mut file) => {
1037 let mut toml_string = String::from("");
1038 match file.read_to_string(&mut toml_string) {
1039 Err(err) => {
1040 error!("Unable to read {}! {}", filename, err);
1041 return Err(SerializationError::TomlDecodingError);
1042 }
1043 Ok(_) => {
1044 match toml::from_str(&toml_string) {
1045 Err(err) => {
1046 error!("Can't interpret toml! {}", err);
1047 return Err(SerializationError::TomlDecodingError);
1048 }
1049 Ok(settings) => {
1050 return Ok(settings);
1051 }
1052 }
1053 }
1054 }
1055 }
1056 }
1057 }
1058}
1059
1060impl fmt::Display for LiftofSettings {
1061 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1062 let disp : String;
1063 match toml::to_string(self) {
1064 Err(err) => {
1065 println!("Deserialization error! {err}");
1066 disp = String::from("-- DESERIALIZATION ERROR! --");
1067 }
1068 Ok(_disp) => {
1069 disp = _disp;
1070 }
1071 }
1072 write!(f, "<LiftofSettings :\n{}>", disp)
1073 }
1074}
1075
1076impl Default for LiftofSettings {
1077 fn default() -> Self {
1078 Self::new()
1079 }
1080}
1081
1082#[cfg(feature="pybindings")]
1083#[pymethods]
1084impl LiftofSettings {
1085
1086 #[staticmethod]
1093 fn from_file(filename : &str) -> PyResult<Self> {
1094 match LiftofSettings::from_toml(filename) {
1095 Ok(settings) => {
1096 return Ok(settings);
1097 }
1098 Err(err) => {
1099 return Err(PyValueError::new_err(err.to_string()));
1100 }
1101 }
1102 }
1103}
1104
1105#[cfg(feature="pybindings")]
1106pythonize!(LiftofSettings);
1107
1108#[derive(Debug, Copy, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
1112pub struct LiftofRBConfig {
1113 pub nseconds : u32,
1115 pub tof_op_mode : TofOperationMode,
1118 pub trigger_poisson_rate : u32,
1121 pub trigger_fixed_rate : u32,
1124 pub data_type : DataType,
1128 pub rb_buff_size : u16
1134}
1135
1136impl LiftofRBConfig {
1137
1138 pub fn new() -> Self {
1139 Self {
1140 nseconds : 0,
1141 tof_op_mode : TofOperationMode::Default,
1142 trigger_poisson_rate : 0,
1143 trigger_fixed_rate : 0,
1144 data_type : DataType::Unknown,
1145 rb_buff_size : 0,
1146 }
1147 }
1148}
1149
1150impl Serialization for LiftofRBConfig {
1151 const HEAD : u16 = 43690; const TAIL : u16 = 21845; const SIZE : usize = 24; fn from_bytestream(bytestream : &Vec<u8>,
1156 pos : &mut usize)
1157 -> Result<Self, SerializationError> {
1158 let mut pars = Self::new();
1159 Self::verify_fixed(bytestream, pos)?;
1160 pars.nseconds = parse_u32 (bytestream, pos);
1161 pars.tof_op_mode
1162 = TofOperationMode::try_from(
1163 parse_u8(bytestream, pos))
1164 .unwrap_or_else(|_| TofOperationMode::Unknown);
1165 pars.trigger_poisson_rate = parse_u32 (bytestream, pos);
1166 pars.trigger_fixed_rate = parse_u32 (bytestream, pos);
1167 pars.data_type
1168 = DataType::try_from(parse_u8(bytestream, pos))
1169 .unwrap_or_else(|_| DataType::Unknown);
1170 pars.rb_buff_size = parse_u16(bytestream, pos);
1171 *pos += 2; Ok(pars)
1174 }
1175
1176 fn to_bytestream(&self) -> Vec<u8> {
1177 let mut stream = Vec::<u8>::with_capacity(Self::SIZE);
1178 stream.extend_from_slice(&Self::HEAD.to_le_bytes());
1179 stream.extend_from_slice(&self. nseconds.to_le_bytes());
1180 stream.extend_from_slice(&(self.tof_op_mode as u8).to_le_bytes());
1181 stream.extend_from_slice(&self.trigger_poisson_rate.to_le_bytes());
1182 stream.extend_from_slice(&self.trigger_fixed_rate.to_le_bytes());
1183 stream.extend_from_slice(&(self.data_type as u8).to_le_bytes());
1184 stream.extend_from_slice(&self.rb_buff_size.to_le_bytes());
1185 stream.extend_from_slice(&Self::TAIL.to_le_bytes());
1186 stream
1187 }
1188}
1189
1190impl Default for LiftofRBConfig {
1191 fn default() -> Self {
1192 Self::new()
1193 }
1194}
1195
1196impl fmt::Display for LiftofRBConfig {
1197 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1198 write!(f,
1199"<LiftofRBConfig -- is_active : true
1200 nseconds : {}
1201 TOF op. mode : {}
1202 data type : {}
1203 tr_poi_rate : {}
1204 tr_fix_rate : {}
1205 buff size : {} [events]>",
1206 self.nseconds,
1207 self.tof_op_mode,
1208 self.data_type,
1209 self.trigger_poisson_rate,
1210 self.trigger_fixed_rate,
1211 self.rb_buff_size)
1212 }
1213}
1214
1215#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
1264pub struct ChannelMaskSettings {
1265 pub set_channel_mask : bool,
1267 pub set_strategy : ParameterSetStrategy,
1273 pub rb_channel_mask : HashMap<String, [bool;9]>
1277}
1278
1279impl ChannelMaskSettings {
1280 pub fn new() -> Self {
1281 let mut default_thresholds = HashMap::<String, [bool; 9]>::new();
1282 for k in 1..51 {
1283 let key = format!("RB{k:02}");
1284 default_thresholds.insert(key, [true;9]);
1285 }
1286Self {
1309 set_channel_mask : false,
1310 set_strategy : ParameterSetStrategy::ControlServer,
1311 rb_channel_mask : default_thresholds,
1312 }
1313 }
1314
1315 #[cfg(feature="database")]
1316 pub fn emit_ch_mask_packets(&self, rbs : &HashMap<u8,RAT>) -> Vec<TofPacket> {
1317 let mut packets = Vec::<TofPacket>::new();
1318 for k in rbs.keys() {
1319 let rb = &rbs[&k];
1320 let rb_key = format!("RB{:2}", rb);
1321 let mut cmd = TofCommand::new();
1322 cmd.command_code = TofCommandCode::SetRBChannelMask;
1323 let mut payload = RBChannelMaskConfig::new();
1324 payload.rb_id = rb.rb2_id as u8;
1325 if *k as usize >= self.rb_channel_mask.len() {
1326 error!("RB ID {k} larger than 46!");
1327 continue;
1328 }
1329 payload.channels = self.rb_channel_mask[&rb_key];
1330 cmd.payload = payload.to_bytestream();
1331 let tp = cmd.pack();
1332 packets.push(tp);
1333 }
1334 packets
1335 }
1336}
1337impl fmt::Display for ChannelMaskSettings {
1338 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1339 let disp : String;
1340 match toml::to_string(self) {
1341 Err(err) => {
1342 error!("Deserialization error! {err}");
1343 disp = String::from("-- DESERIALIZATION ERROR! --");
1344 }
1345 Ok(_disp) => {
1346 disp = _disp;
1347 }
1348 }
1349 write!(f, "<RBChannelMaskConfig :\n{}>", disp)
1350 }
1351}
1352
1353impl Default for ChannelMaskSettings {
1354 fn default() -> Self {
1355 Self::new()
1356 }
1357}
1358
1359#[cfg(feature="random")]
1360#[test]
1361fn mtb_config() {
1362
1363 for _ in 0..100 {
1364 let cfg = TriggerConfig::from_random();
1365 let mut settings = MTBSettings::new();
1366 settings.from_triggerconfig(&cfg);
1367 let test = settings.emit_triggerconfig();
1368 if cfg.gaps_trigger_use_beta.is_some() {
1369 assert_eq!(cfg.gaps_trigger_use_beta, test.gaps_trigger_use_beta);
1370 }
1371 if cfg.prescale.is_some() {
1372 assert_eq!(cfg.prescale, test.prescale);
1373 }
1374 if cfg.trigger_type.is_some() {
1375 assert_eq!(cfg.trigger_type, test.trigger_type);
1376 }
1377 if cfg.use_combo_trigger.is_some() {
1378 assert_eq!(cfg.use_combo_trigger, test.use_combo_trigger);
1379 }
1380 if cfg.combo_trigger_type.is_some() {
1381 assert_eq!(cfg.combo_trigger_type, test.combo_trigger_type);
1382 }
1383 if cfg.combo_trigger_prescale.is_some() {
1384 assert_eq!(cfg.combo_trigger_prescale, test.combo_trigger_prescale);
1385 }
1386 if cfg.trace_suppression.is_some() {
1387 assert_eq!(cfg.trace_suppression, test.trace_suppression);
1388 }
1389 if cfg.mtb_moni_interval.is_some() {
1390 assert_eq!(cfg.mtb_moni_interval, test.mtb_moni_interval);
1391 }
1392 if cfg.tiu_ignore_busy.is_some() {
1393 assert_eq!(cfg.tiu_ignore_busy, test.tiu_ignore_busy);
1394 }
1395 if cfg.hb_send_interval.is_some() {
1396 assert_eq!(cfg.hb_send_interval, test.hb_send_interval);
1397 }
1398 }
1399}
1400
1401#[test]
1402fn write_config_file() {
1403 let settings = LiftofSettings::new();
1404 settings.to_toml(String::from("liftof-config-test.toml"));
1406}
1407
1408#[test]
1409fn read_config_file() {
1410 let _settings = LiftofSettings::from_toml("liftof-config-test.toml");
1411}
1412
1413