From 3a5ede11a75578744f6e6f2d87449ba443156a5a Mon Sep 17 00:00:00 2001 From: Udo Eisenbarth <udo.eisenbarth@web.de> Date: Mon, 10 Jul 2023 16:16:13 +0200 Subject: [PATCH] Add Spectrum structure and a first example --- examples/source_detector_test.rs | 4 +-- examples/spectrum_test.rs | 10 ++++++ src/lib.rs | 4 ++- src/lightdata.rs | 8 ++--- src/nodes/ideal_filter.rs | 4 +-- src/nodes/node_beam_splitter.rs | 6 ++-- src/spectrum.rs | 52 ++++++++++++++++++++++++++++++++ 7 files changed, 76 insertions(+), 12 deletions(-) create mode 100644 examples/spectrum_test.rs create mode 100644 src/spectrum.rs diff --git a/examples/source_detector_test.rs b/examples/source_detector_test.rs index 72618307..cee7df72 100644 --- a/examples/source_detector_test.rs +++ b/examples/source_detector_test.rs @@ -3,7 +3,7 @@ use std::io::Write; use uom::si::{f64::Energy, energy::joule}; use opossum::{ - lightdata::{LightData, LightDataEnergy}, + lightdata::{LightData, DataEnergy}, nodes::{Detector, Source, BeamSplitter, IdealFilter}, optic_scenery::OpticScenery, analyzer::AnalyzerEnergy, }; @@ -14,7 +14,7 @@ fn main() { let i_s = scenery.add_element( "Source", - Source::new(LightData::Energy(LightDataEnergy { energy: Energy::new::<joule>(1.0) })), + Source::new(LightData::Energy(DataEnergy { energy: Energy::new::<joule>(1.0) })), ); let i_bs=scenery.add_element("Beam splitter", BeamSplitter::new(0.6)); let i_f=scenery.add_element("Filter", IdealFilter::new(0.5).unwrap()); diff --git a/examples/spectrum_test.rs b/examples/spectrum_test.rs new file mode 100644 index 00000000..f6dd9cea --- /dev/null +++ b/examples/spectrum_test.rs @@ -0,0 +1,10 @@ +use opossum::spectrum::Spectrum; +use uom::si::energy::joule; +use uom::si::{f64::Length, length::nanometer}; +use uom::si::f64::Energy; + +fn main() { + let mut s=Spectrum::new(Length::new::<nanometer>(400.0)..Length::new::<nanometer>(410.0),Length::new::<nanometer>(1.0)); + s.set_single_peak(Length::new::<nanometer>(405.0), Energy::new::<joule>(1.0)); + println!("{}",s); +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 1fff6d42..ed4f674f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,4 +13,6 @@ pub mod nodes; pub mod analyzer; -pub mod error; \ No newline at end of file +pub mod error; + +pub mod spectrum; \ No newline at end of file diff --git a/src/lightdata.rs b/src/lightdata.rs index be516021..b2ebfa4a 100644 --- a/src/lightdata.rs +++ b/src/lightdata.rs @@ -4,8 +4,8 @@ use uom::fmt::DisplayStyle::Abbreviation; #[derive(Debug, PartialEq, Clone)] pub enum LightData { - Energy(LightDataEnergy), - Geometric(LightDataGeometric), + Energy(DataEnergy), + Geometric(DataGeometric), Fourier, } @@ -22,11 +22,11 @@ impl Display for LightData { } } #[derive(Debug, PartialEq, Clone)] -pub struct LightDataEnergy { +pub struct DataEnergy { pub energy: Energy, } #[derive(Debug, PartialEq, Clone)] -pub struct LightDataGeometric { +pub struct DataGeometric { ray: i32, } diff --git a/src/nodes/ideal_filter.rs b/src/nodes/ideal_filter.rs index 733d0a94..e7378cf5 100644 --- a/src/nodes/ideal_filter.rs +++ b/src/nodes/ideal_filter.rs @@ -1,6 +1,6 @@ use crate::analyzer::AnalyzerType; use crate::error::OpossumError; -use crate::lightdata::{LightData, LightDataEnergy}; +use crate::lightdata::{LightData, DataEnergy}; use crate::optic_node::{Dottable, LightResult, Optical}; use crate::optic_ports::OpticPorts; use std::collections::HashMap; @@ -73,7 +73,7 @@ impl IdealFilter { _ => return Err(OpossumError::Analysis("expected energy value".into())), } } - let output_energy = Some(LightData::Energy(LightDataEnergy { + let output_energy = Some(LightData::Energy(DataEnergy { energy: input_energy * self.transmission, })); Ok(HashMap::from([("rear".into(), output_energy)])) diff --git a/src/nodes/node_beam_splitter.rs b/src/nodes/node_beam_splitter.rs index 344e09f1..bd1f60c6 100644 --- a/src/nodes/node_beam_splitter.rs +++ b/src/nodes/node_beam_splitter.rs @@ -4,7 +4,7 @@ use uom::{si::f64::Energy, num_traits::Zero}; use crate::{ analyzer::AnalyzerType, error::OpossumError, - lightdata::{LightData, LightDataEnergy}, + lightdata::{LightData, DataEnergy}, optic_node::{Dottable, LightResult, Optical}, optic_ports::OpticPorts, }; @@ -51,10 +51,10 @@ impl BeamSplitter { _ => return Err(OpossumError::Analysis("expected energy value".into())), } } - let out1_energy = Some(LightData::Energy(LightDataEnergy { + let out1_energy = Some(LightData::Energy(DataEnergy { energy: in1_energy * self.ratio + in2_energy * (1.0 - self.ratio), })); - let out2_energy = Some(LightData::Energy(LightDataEnergy { + let out2_energy = Some(LightData::Energy(DataEnergy { energy: in1_energy * (1.0 - self.ratio) + in2_energy * self.ratio, })); Ok(HashMap::from([ diff --git a/src/spectrum.rs b/src/spectrum.rs new file mode 100644 index 00000000..826dd05d --- /dev/null +++ b/src/spectrum.rs @@ -0,0 +1,52 @@ +use std::fmt::Display; +use std::ops::Range; +use uom::fmt::DisplayStyle::Abbreviation; +use uom::num_traits::Zero; +use uom::si::energy::joule; +use uom::si::{ + f64::{Energy, Length}, + length::nanometer, +}; +pub struct Spectrum { + start: Length, + dlambda: Length, + data: Vec<Energy>, +} + +impl Spectrum { + pub fn new(range: Range<Length>, resolution: Length) -> Self { + Self { + start: range.start, + dlambda: resolution, + data: vec![Energy::zero(); ((range.end-range.start)/resolution).value as usize] + } + } + pub fn set_single_peak(&mut self, wavelength: Length, energy: Energy) { + let index=((wavelength-self.start) / self.dlambda).value as usize; + self.data[index]=energy; + } + pub fn total_energy(&self) -> Energy { + let mut total_energy=Energy::zero(); + for data in self.data.iter() { + total_energy+=*data; + } + total_energy + } +} + +impl Display for Spectrum { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let fmt_length = Length::format_args(nanometer, Abbreviation); + let fmt_energy = Energy::format_args(joule, Abbreviation); + for value in self.data.iter().enumerate() { + let wavelength=self.start + value.0 as f64 * self.dlambda; + write!( + f, + "{:7.2} -> {}\n", + fmt_length.with(wavelength), + fmt_energy.with(*value.1) + ).unwrap(); + } + write!(f, "\nTotal energy: {}",fmt_energy.with(self.total_energy())) + } +} -- GitLab