sim_lib_interference_solve/
multitone_error.rs1use std::fmt;
4
5use sim_lib_interference_core::SamplingPlane;
6
7use crate::ReferenceSolveError;
8
9#[derive(Clone, Debug, PartialEq)]
11pub enum MultiToneError {
12 InvalidWeight {
14 frequency_hz: f64,
16 weight: f64,
18 },
19 ComponentSolve {
21 frequency_hz: f64,
23 cause: Box<ReferenceSolveError>,
25 },
26 EmptyStudy,
28 DuplicateFrequency {
30 frequency_hz: f64,
32 },
33 MismatchedPlane {
35 frequency_hz: f64,
37 expected: Box<SamplingPlane>,
39 actual: Box<SamplingPlane>,
41 },
42 InvalidSeconds {
44 seconds: f64,
46 },
47 NonFiniteAngularTime {
49 frequency_hz: f64,
51 seconds: f64,
53 angular_time: f64,
55 },
56 NonFiniteContribution {
58 frequency_hz: f64,
60 row: usize,
62 column: usize,
64 value: f64,
66 },
67 NonFiniteAccumulation {
69 row: usize,
71 column: usize,
73 value: f64,
75 },
76 AllocationFailed {
78 cells: usize,
80 },
81 NonFiniteTemporalSamplingRequirement {
83 highest_frequency_hz: f64,
85 samples_per_second: f64,
87 },
88 CertificateAllocationFailed {
90 tones: usize,
92 },
93}
94
95impl fmt::Display for MultiToneError {
96 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
97 match self {
98 Self::InvalidWeight {
99 frequency_hz,
100 weight,
101 } => write!(
102 formatter,
103 "tone at {frequency_hz} Hz requires a finite positive weight: {weight:?}"
104 ),
105 Self::ComponentSolve {
106 frequency_hz,
107 cause,
108 } => write!(
109 formatter,
110 "tone at {frequency_hz} Hz could not be certified: {cause}"
111 ),
112 Self::EmptyStudy => formatter.write_str("multi-tone study requires at least one tone"),
113 Self::DuplicateFrequency { frequency_hz } => write!(
114 formatter,
115 "frequency {frequency_hz} Hz occurs more than once; equal-frequency sources belong in one coherent problem"
116 ),
117 Self::MismatchedPlane {
118 frequency_hz,
119 expected,
120 actual,
121 } => write!(
122 formatter,
123 "tone at {frequency_hz} Hz uses plane {actual:?}, not the shared plane {expected:?}"
124 ),
125 Self::InvalidSeconds { seconds } => write!(
126 formatter,
127 "multi-tone observation time must be finite: {seconds:?}"
128 ),
129 Self::NonFiniteAngularTime {
130 frequency_hz,
131 seconds,
132 angular_time,
133 } => write!(
134 formatter,
135 "tone at {frequency_hz} Hz and time {seconds} s produced non-finite angular time {angular_time:?}"
136 ),
137 Self::NonFiniteContribution {
138 frequency_hz,
139 row,
140 column,
141 value,
142 } => write!(
143 formatter,
144 "tone at {frequency_hz} Hz produced non-finite weighted scalar {value:?} at ({row}, {column})"
145 ),
146 Self::NonFiniteAccumulation { row, column, value } => write!(
147 formatter,
148 "multi-tone scalar accumulation became non-finite at ({row}, {column}): {value:?}"
149 ),
150 Self::AllocationFailed { cells } => {
151 write!(
152 formatter,
153 "could not reserve {cells} multi-tone scalar cells"
154 )
155 }
156 Self::NonFiniteTemporalSamplingRequirement {
157 highest_frequency_hz,
158 samples_per_second,
159 } => write!(
160 formatter,
161 "highest frequency {highest_frequency_hz} Hz produced non-finite Nyquist rate {samples_per_second:?}"
162 ),
163 Self::CertificateAllocationFailed { tones } => write!(
164 formatter,
165 "could not reserve provenance for {tones} multi-tone components"
166 ),
167 }
168 }
169}
170
171impl std::error::Error for MultiToneError {
172 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
173 match self {
174 Self::ComponentSolve { cause, .. } => Some(cause.as_ref()),
175 Self::InvalidWeight { .. }
176 | Self::EmptyStudy
177 | Self::DuplicateFrequency { .. }
178 | Self::MismatchedPlane { .. }
179 | Self::InvalidSeconds { .. }
180 | Self::NonFiniteAngularTime { .. }
181 | Self::NonFiniteContribution { .. }
182 | Self::NonFiniteAccumulation { .. }
183 | Self::AllocationFailed { .. }
184 | Self::NonFiniteTemporalSamplingRequirement { .. }
185 | Self::CertificateAllocationFailed { .. } => None,
186 }
187 }
188}