Newer
Older
analyzer::AnalyzerType,
error::OpossumError,
lightdata::{DataEnergy, LightData},
optic_node::{Dottable, LightResult, Optical},
type Result<T> = std::result::Result<T, OpossumError>;
///
/// ## Optical Ports
/// - Inputs
/// - `input1`
/// - `input2`
/// - Outputs
/// - `out1_trans1_refl2`
/// - `out2_trans2_refl1`
impl BeamSplitter {
/// Creates a new [`BeamSplitter`] with a given splitting ratio.
///
/// ## Errors
/// This function returns an [`OpossumError::Other`] if the splitting ratio is outside the closed interval
/// [0.0..1.0].
pub fn new(ratio: f64) -> Result<Self> {
Ok(Self { ratio })
} else {
Err(OpossumError::Other(
"splitting ration must be within (0.0..1.0)".into(),
))
}
/// Returns the splitting ratio of this [`BeamSplitter`].
/// Sets the splitting ratio of this [`BeamSplitter`].
///
/// ## Errors
/// This function returns an [`OpossumError::Other`] if the splitting ratio is outside the closed interval
/// [0.0..1.0].
pub fn set_ratio(&mut self, ratio: f64) -> Result<()> {
self.ratio = ratio;
Ok(())
} else {
Err(OpossumError::Other(
"splitting ration must be within (0.0..1.0)".into(),
))
}
fn analyze_energy(&mut self, incoming_data: LightResult) -> Result<LightResult> {
let in1 = incoming_data.get("input1");
let in2 = incoming_data.get("input2");
let mut out1_1_spectrum: Option<Spectrum> = None;
let mut out1_2_spectrum: Option<Spectrum> = None;
let mut out2_1_spectrum: Option<Spectrum> = None;
let mut out2_2_spectrum: Option<Spectrum> = None;
if let Some(Some(in1)) = in1 {
match in1 {
LightData::Energy(e) => {
let mut s = e.spectrum.clone();
s.scale_vertical(self.ratio).unwrap();
out1_1_spectrum = Some(s);
let mut s = e.spectrum.clone();
s.scale_vertical(1.0 - self.ratio).unwrap();
out1_2_spectrum = Some(s);
_ => return Err(OpossumError::Analysis("expected DataEnergy value".into())),
if let Some(Some(in2)) = in2 {
match in2 {
LightData::Energy(e) => {
let mut s = e.spectrum.clone();
s.scale_vertical(self.ratio).unwrap();
out2_1_spectrum = Some(s);
let mut s = e.spectrum.clone();
s.scale_vertical(1.0 - self.ratio).unwrap();
out2_2_spectrum = Some(s);
}
_ => return Err(OpossumError::Analysis("expected DataEnergy value".into())),
let out1_spec = merge_spectra(out1_1_spectrum, out2_2_spectrum);
let out2_spec = merge_spectra(out1_2_spectrum, out2_1_spectrum);
let mut out1_data: Option<LightData> = None;
let mut out2_data: Option<LightData> = None;
if let Some(out1_spec) = out1_spec {
out1_data = Some(LightData::Energy(DataEnergy {
spectrum: out1_spec,
}))
if let Some(out2_spec) = out2_spec {
out2_data = Some(LightData::Energy(DataEnergy {
spectrum: out2_spec,
}))
("out1_trans1_refl2".into(), out1_data),
("out2_trans2_refl1".into(), out2_data),
/// Create a 50:50 beamsplitter.
fn default() -> Self {
Self { ratio: 0.5 }
}
}
}
fn ports(&self) -> OpticPorts {
let mut ports = OpticPorts::new();
ports.add_input("input1").unwrap();
ports.add_input("input2").unwrap();
ports.add_output("out1_trans1_refl2").unwrap();
ports.add_output("out2_trans2_refl1").unwrap();
ports
}
fn analyze(
&mut self,
incoming_data: LightResult,
analyzer_type: &AnalyzerType,
) -> Result<LightResult> {
match analyzer_type {
AnalyzerType::Energy => self.analyze_energy(incoming_data),
_ => Err(OpossumError::Analysis(
"analysis type not yet implemented".into(),
)),
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#[cfg(test)]
mod test {
use super::*;
#[test]
fn new() {
let splitter=BeamSplitter::new(0.5);
assert!(splitter.is_ok());
assert_eq!(splitter.unwrap().ratio, 0.5);
assert!(BeamSplitter::new(-0.01).is_err());
assert!(BeamSplitter::new(1.01).is_err());
}
#[test]
fn default() {
let splitter=BeamSplitter::default();
assert_eq!(splitter.ratio, 0.5);
}
#[test]
fn ratio() {
let splitter=BeamSplitter::new(0.5).unwrap();
assert_eq!(splitter.ratio(), 0.5);
}
#[test]
fn set_ratio() {
let mut splitter=BeamSplitter::new(0.0).unwrap();
assert!(splitter.set_ratio(1.0).is_ok());
assert_eq!(splitter.ratio, 1.0);
assert!(splitter.set_ratio(-0.1).is_err());
assert!(splitter.set_ratio(1.1).is_err());
}
#[test]
fn node_type() {
let splitter=BeamSplitter::new(0.0).unwrap();
assert_eq!(splitter.node_type(), "beam splitter");
}
#[test]
fn node_color() {
let splitter=BeamSplitter::new(0.0).unwrap();
assert_eq!(splitter.node_color(), "lightpink");
}
}