dsfb_semiconductor/
config.rs1#[cfg(feature = "std")]
2use crate::precursor::DsaConfig;
3use serde::{Deserialize, Serialize};
4#[cfg(not(feature = "std"))]
5use alloc::string::String;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct PipelineConfig {
9 pub healthy_pass_runs: usize,
10 pub drift_window: usize,
11 pub envelope_sigma: f64,
12 pub boundary_fraction_of_rho: f64,
13 pub state_confirmation_steps: usize,
14 pub persistent_state_steps: usize,
15 pub density_window: usize,
16 pub ewma_alpha: f64,
17 pub ewma_sigma_multiplier: f64,
18 pub cusum_kappa_sigma_multiplier: f64,
19 pub cusum_alarm_sigma_multiplier: f64,
20 pub run_energy_sigma_multiplier: f64,
21 pub pca_variance_explained: f64,
22 pub pca_t2_sigma_multiplier: f64,
23 pub pca_spe_sigma_multiplier: f64,
24 pub drift_sigma_multiplier: f64,
25 pub slew_sigma_multiplier: f64,
26 pub grazing_window: usize,
27 pub grazing_min_hits: usize,
28 pub pre_failure_lookback_runs: usize,
29 pub minimum_healthy_observations: usize,
30 pub epsilon: f64,
31 #[cfg(feature = "std")]
32 pub dsa: DsaConfig,
33}
34
35impl Default for PipelineConfig {
36 fn default() -> Self {
37 Self {
38 healthy_pass_runs: 100,
39 drift_window: 5,
40 envelope_sigma: 3.0,
41 boundary_fraction_of_rho: 0.5,
42 state_confirmation_steps: 2,
43 persistent_state_steps: 2,
44 density_window: 10,
45 ewma_alpha: 0.2,
46 ewma_sigma_multiplier: 3.0,
47 cusum_kappa_sigma_multiplier: 0.5,
48 cusum_alarm_sigma_multiplier: 5.0,
49 run_energy_sigma_multiplier: 3.0,
50 pca_variance_explained: 0.95,
51 pca_t2_sigma_multiplier: 3.0,
52 pca_spe_sigma_multiplier: 3.0,
53 drift_sigma_multiplier: 3.0,
54 slew_sigma_multiplier: 3.0,
55 grazing_window: 10,
56 grazing_min_hits: 3,
57 pre_failure_lookback_runs: 20,
58 minimum_healthy_observations: 2,
59 epsilon: 1.0e-9,
60 #[cfg(feature = "std")]
61 dsa: DsaConfig::default(),
62 }
63 }
64}
65
66impl PipelineConfig {
67 pub fn validate(&self) -> Result<(), String> {
68 if self.healthy_pass_runs < 2 {
69 return Err("healthy_pass_runs must be at least 2".into());
70 }
71 if self.drift_window == 0 {
72 return Err("drift_window must be positive".into());
73 }
74 if self.envelope_sigma <= 0.0 {
75 return Err("envelope_sigma must be positive".into());
76 }
77 if !(0.0..=1.0).contains(&self.boundary_fraction_of_rho) {
78 return Err("boundary_fraction_of_rho must be in [0, 1]".into());
79 }
80 if self.state_confirmation_steps == 0 {
81 return Err("state_confirmation_steps must be positive".into());
82 }
83 if self.persistent_state_steps == 0 {
84 return Err("persistent_state_steps must be positive".into());
85 }
86 if self.density_window == 0 {
87 return Err("density_window must be positive".into());
88 }
89 if !(0.0..=1.0).contains(&self.ewma_alpha) || self.ewma_alpha == 0.0 {
90 return Err("ewma_alpha must be in (0, 1]".into());
91 }
92 if self.ewma_sigma_multiplier <= 0.0 {
93 return Err("ewma_sigma_multiplier must be positive".into());
94 }
95 if self.cusum_kappa_sigma_multiplier <= 0.0 {
96 return Err("cusum_kappa_sigma_multiplier must be positive".into());
97 }
98 if self.cusum_alarm_sigma_multiplier <= 0.0 {
99 return Err("cusum_alarm_sigma_multiplier must be positive".into());
100 }
101 if self.run_energy_sigma_multiplier <= 0.0 {
102 return Err("run_energy_sigma_multiplier must be positive".into());
103 }
104 if !(0.0..=1.0).contains(&self.pca_variance_explained) || self.pca_variance_explained == 0.0
105 {
106 return Err("pca_variance_explained must be in (0, 1]".into());
107 }
108 if self.pca_t2_sigma_multiplier <= 0.0 {
109 return Err("pca_t2_sigma_multiplier must be positive".into());
110 }
111 if self.pca_spe_sigma_multiplier <= 0.0 {
112 return Err("pca_spe_sigma_multiplier must be positive".into());
113 }
114 if self.minimum_healthy_observations < 2 {
115 return Err("minimum_healthy_observations must be at least 2".into());
116 }
117 #[cfg(feature = "std")]
118 self.dsa.validate().map_err(|err| err.to_string())?;
119 Ok(())
120 }
121}
122
123#[cfg(feature = "std")]
124#[derive(Debug, Clone, Serialize, Deserialize)]
125pub struct RunConfiguration {
126 pub dataset: String,
127 pub config: PipelineConfig,
128 pub data_root: String,
129 pub output_root: String,
130 pub secom_fetch_if_missing: bool,
131}