Newer
Older
analyzer::AnalyzerType,
error::OpossumError,
lightdata::{DataEnergy, LightData},
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.
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`].
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(),
)),
#[cfg(test)]
mod test {
use super::*;
#[test]
fn new() {
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() {
assert_eq!(splitter.ratio, 0.5);
}
#[test]
fn ratio() {
assert_eq!(splitter.ratio(), 0.5);
}
#[test]
fn set_ratio() {
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() {
assert_eq!(splitter.node_type(), "beam splitter");
}
#[test]
fn node_color() {
assert_eq!(splitter.node_color(), "lightpink");
}