diff --git a/Cargo.lock b/Cargo.lock index cdcdca78e7718499ef878c1a4324b4eddc3525f7..f3730bb2359e8b4ff353194d9c0a6580dc290dce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -227,9 +227,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "fdeflate" @@ -551,9 +551,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] @@ -690,18 +690,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.64" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.29" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -806,15 +806,15 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.171" +version = "1.0.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" +checksum = "5d25439cd7397d044e2748a6fe2432b5e85db703d6d097bd014b3c0ad1ebff0b" [[package]] name = "serde_derive" -version = "1.0.171" +version = "1.0.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" +checksum = "b23f7ade6f110613c0d63858ddb8b94c1041f550eab58a16b371bdf2c9c80ab4" dependencies = [ "proc-macro2", "quote", @@ -823,15 +823,15 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "syn" -version = "2.0.25" +version = "2.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" dependencies = [ "proc-macro2", "quote", @@ -840,18 +840,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", @@ -889,15 +889,15 @@ checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "uom" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8f50eddd69f656ee545f7663ea5fefb7c789bc1a0d11124e049715f563a16a4" +checksum = "8362194c7a9845a7a7f3562173d6e1da3f24f7132018cb78fe77a5b4474187b2" dependencies = [ "num-traits", "typenum", diff --git a/examples/beam_combine_test.rs b/examples/beam_combine_test.rs index 9e387873624be41783f9e3611cc140a7947737f2..5b5870942f4a8979feea9e092bb05e762ddbdf5b 100644 --- a/examples/beam_combine_test.rs +++ b/examples/beam_combine_test.rs @@ -5,8 +5,9 @@ use opossum::{ analyzer::AnalyzerEnergy, error::OpossumError, lightdata::{DataEnergy, LightData}, - nodes::{BeamSplitter, Detector, IdealFilter, Source, FilterType}, - optic_scenery::OpticScenery, spectrum::{create_he_ne_spectrum, Spectrum, create_nd_glass_spectrum}, + nodes::{BeamSplitter, Detector, FilterType, IdealFilter, Source}, + optic_scenery::OpticScenery, + spectrum::{create_he_ne_spectrum, create_nd_glass_spectrum, Spectrum}, }; fn main() -> Result<(), OpossumError> { @@ -33,7 +34,7 @@ fn main() -> Result<(), OpossumError> { scenery.connect_nodes(i_s1, "out1", i_bs, "input1")?; scenery.connect_nodes(i_s2, "out1", i_bs, "input2")?; scenery.connect_nodes(i_bs, "out1_trans1_refl2", i_d1, "in1")?; - + let path = "beam_combiner.dot"; let mut output = File::create(path).unwrap(); write!(output, "{}", scenery.to_dot()).unwrap(); diff --git a/examples/filter_test.rs b/examples/filter_test.rs index 9598627b055a84eabda3b8e79c95e5ef255895ba..794aeb6b24f1c0fbe5cde39d76653ed7502f4bd6 100644 --- a/examples/filter_test.rs +++ b/examples/filter_test.rs @@ -5,8 +5,9 @@ use opossum::{ analyzer::AnalyzerEnergy, error::OpossumError, lightdata::{DataEnergy, LightData}, - nodes::{BeamSplitter, Detector, IdealFilter, Source, FilterType}, - optic_scenery::OpticScenery, spectrum::{create_he_ne_spectrum, Spectrum}, + nodes::{BeamSplitter, Detector, FilterType, IdealFilter, Source}, + optic_scenery::OpticScenery, + spectrum::{create_he_ne_spectrum, Spectrum}, }; fn main() -> Result<(), OpossumError> { @@ -20,8 +21,11 @@ fn main() -> Result<(), OpossumError> { })), ); let i_bs = scenery.add_element("Beam splitter", BeamSplitter::new(0.6)); - let filter_spectrum=Spectrum::from_csv("NE03B.csv")?; - let i_f = scenery.add_element("Filter", IdealFilter::new(FilterType::Spectrum(filter_spectrum))?); + let filter_spectrum = Spectrum::from_csv("NE03B.csv")?; + let i_f = scenery.add_element( + "Filter", + IdealFilter::new(FilterType::Spectrum(filter_spectrum))?, + ); let i_d1 = scenery.add_element("Detector 1", Detector::default()); let i_d2 = scenery.add_element("Detector 2", Detector::default()); diff --git a/examples/graph_port_test.rs b/examples/graph_port_test.rs index 148524eaee70308536c2732f626c70cc0fc85ee3..18c26715c0bcdc025c38d4eef4845d0b52c10897 100644 --- a/examples/graph_port_test.rs +++ b/examples/graph_port_test.rs @@ -1,12 +1,12 @@ use opossum::error::OpossumError; -use opossum::nodes::{Dummy, BeamSplitter}; +use opossum::nodes::{BeamSplitter, Dummy}; use opossum::optic_node::OpticNode; use opossum::optic_scenery::OpticScenery; use std::fs::File; use std::io::Write; -fn main() -> Result <(), OpossumError> { +fn main() -> Result<(), OpossumError> { let mut scenery = OpticScenery::new(); scenery.set_description("Fancy Graph with Ports"); @@ -16,7 +16,7 @@ fn main() -> Result <(), OpossumError> { let bs2 = scenery.add_node(OpticNode::new("Beamsplitter 2", BeamSplitter::default())); let m1 = scenery.add_node(OpticNode::new("Mirror 1", Dummy)); let m2 = scenery.add_node(OpticNode::new("Mirror 2", Dummy)); - + scenery.connect_nodes(in1, "rear", bs1, "input1")?; scenery.connect_nodes(bs1, "out1_trans1_refl2", m1, "front")?; scenery.connect_nodes(bs1, "out2_trans2_refl1", m2, "front")?; @@ -26,7 +26,6 @@ fn main() -> Result <(), OpossumError> { scenery.connect_nodes(bs2, "out1_trans1_refl2", out1, "front")?; scenery.connect_nodes(bs2, "out2_trans2_refl1", out1, "front")?; - let path = "graph_w_ports.dot"; let mut output = File::create(path).unwrap(); write!(output, "{}", scenery.to_dot()).unwrap(); diff --git a/examples/michaelson.rs b/examples/michaelson.rs index df5f4e29972131d5ee17c764143e89de2cbed63d..341da09ae57de90c71a4f0e29442d4f6edc8da5b 100644 --- a/examples/michaelson.rs +++ b/examples/michaelson.rs @@ -1,6 +1,7 @@ use opossum::{ - nodes::{BeamSplitter, Dummy, NodeReference, Source, Detector}, - optic_scenery::OpticScenery, error::OpossumError, + error::OpossumError, + nodes::{BeamSplitter, Detector, Dummy, NodeReference, Source}, + optic_scenery::OpticScenery, }; use std::fs::File; use std::io::Write; @@ -12,21 +13,20 @@ fn main() -> Result<(), OpossumError> { let bs = scenery.add_element("Beamspliiter", BeamSplitter::default()); let sample = scenery.add_element("sample", Dummy); let rf = NodeReference::new(scenery.node(sample)?); - let r_sample=scenery.add_node(rf); + let r_sample = scenery.add_node(rf); let m1 = scenery.add_element("Mirror", Dummy); let m2 = scenery.add_element("Mirror", Dummy); let rf = NodeReference::new(scenery.node(bs)?); let r_bs = scenery.add_node(rf); - let det=scenery.add_element("Detector", Detector::default()); + let det = scenery.add_element("Detector", Detector::default()); scenery.connect_nodes(src, "out1", bs, "input1")?; - scenery - .connect_nodes(bs, "out1_trans1_refl2", sample, "front")?; + scenery.connect_nodes(bs, "out1_trans1_refl2", sample, "front")?; scenery.connect_nodes(sample, "rear", m1, "front")?; - scenery.connect_nodes(m1,"rear", r_sample, "front")?; + scenery.connect_nodes(m1, "rear", r_sample, "front")?; scenery.connect_nodes(r_sample, "rear", r_bs, "input1")?; - scenery.connect_nodes(bs,"out2_trans2_refl1", m2, "front")?; - scenery.connect_nodes(m2,"rear", r_bs,"input2")?; + scenery.connect_nodes(bs, "out2_trans2_refl1", m2, "front")?; + scenery.connect_nodes(m2, "rear", r_bs, "input2")?; scenery.connect_nodes(r_bs, "out1_trans1_refl2", det, "in1")?; let path = "michaelson.dot"; diff --git a/examples/spectrum_test.rs b/examples/spectrum_test.rs index 8c789c59fa3033189a5d69d736303c444669205f..944cb2f28c9c89902480a4e8e08954620bd27e5b 100644 --- a/examples/spectrum_test.rs +++ b/examples/spectrum_test.rs @@ -1,5 +1,5 @@ use opossum::error::OpossumError; -use opossum::spectrum::{Spectrum, create_visible_spectrum}; +use opossum::spectrum::{create_visible_spectrum, Spectrum}; use uom::si::{f64::Length, length::nanometer}; fn main() -> Result<(), OpossumError> { @@ -7,27 +7,39 @@ fn main() -> Result<(), OpossumError> { Length::new::<nanometer>(400.0)..Length::new::<nanometer>(450.0), Length::new::<nanometer>(0.1), )?; - s.add_lorentzian_peak(Length::new::<nanometer>(415.0), Length::new::<nanometer>(3.2), 2.0)?; + s.add_lorentzian_peak( + Length::new::<nanometer>(415.0), + Length::new::<nanometer>(3.2), + 2.0, + )?; - let mut s2=Spectrum::new( + let mut s2 = Spectrum::new( Length::new::<nanometer>(400.0)..Length::new::<nanometer>(450.0), Length::new::<nanometer>(2.1), )?; - s2.add_lorentzian_peak(Length::new::<nanometer>(430.0), Length::new::<nanometer>(1.2), 0.5)?; + s2.add_lorentzian_peak( + Length::new::<nanometer>(430.0), + Length::new::<nanometer>(1.2), + 0.5, + )?; s.add(&s2); - let mut s3=Spectrum::new( + let mut s3 = Spectrum::new( Length::new::<nanometer>(400.0)..Length::new::<nanometer>(450.0), Length::new::<nanometer>(0.05), )?; - s3.add_lorentzian_peak(Length::new::<nanometer>(420.0), Length::new::<nanometer>(0.3), 0.02)?; + s3.add_lorentzian_peak( + Length::new::<nanometer>(420.0), + Length::new::<nanometer>(0.3), + 0.02, + )?; s.sub(&s3); s.to_plot("spectrum.svg"); - let s4=Spectrum::from_csv("NE03B.csv")?; + let s4 = Spectrum::from_csv("NE03B.csv")?; s4.to_plot("ne03b_raw.svg"); - let mut s5=create_visible_spectrum(); + let mut s5 = create_visible_spectrum(); s5.resample(&s4); s5.to_plot("ne03b.svg"); Ok(()) -} +} diff --git a/src/analyzer.rs b/src/analyzer.rs index fa150ec93b874b62731809f3d2ba56096673be3e..43cf145f2567a1d931322bf6dbbbcbbc50adb109 100644 --- a/src/analyzer.rs +++ b/src/analyzer.rs @@ -1,4 +1,4 @@ -use crate::{optic_scenery::OpticScenery, error::OpossumError}; +use crate::{error::OpossumError, optic_scenery::OpticScenery}; type Result<T> = std::result::Result<T, OpossumError>; #[derive(Debug)] @@ -13,10 +13,10 @@ impl AnalyzerEnergy { } } pub fn analyze(&mut self) -> Result<()> { - self.scene.analyze(&AnalyzerType::Energy) + self.scene.analyze(&AnalyzerType::Energy) } } pub enum AnalyzerType { - Energy -} \ No newline at end of file + Energy, +} diff --git a/src/lib.rs b/src/lib.rs index ed4f674f15b9b0ac701b381ee6b3629dd78afe0e..1f5d6822a3ef97b5db3cc2f62bcaec55a35c80eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,11 @@ //! This is the documentation for the OPOSSUM software package. OPOSSUM stands for OPen-source Optics Simulation Software and Unified Modeller. -//! -/// The basic structure containing the entire optical model -pub mod optic_scenery; -/// The basic structure representing an optical element -pub mod optic_node; +//! pub mod light; pub mod lightdata; +/// The basic structure representing an optical element +pub mod optic_node; +/// The basic structure containing the entire optical model +pub mod optic_scenery; pub mod optic_ports; @@ -15,4 +15,4 @@ pub mod analyzer; pub mod error; -pub mod spectrum; \ No newline at end of file +pub mod spectrum; diff --git a/src/light.rs b/src/light.rs index ee259cfb2ccde8821a85ab45d98b5c73dd816818..d02403ffb9d860bc0fedcfeacf21675bbd2ced9e 100644 --- a/src/light.rs +++ b/src/light.rs @@ -4,7 +4,7 @@ use crate::lightdata::LightData; pub struct Light { src_port: String, target_port: String, - data: Option<LightData> + data: Option<LightData>, } impl Light { @@ -12,7 +12,7 @@ impl Light { Self { src_port: src_port.into(), target_port: target_port.into(), - data: None + data: None, } } pub fn src_port(&self) -> &str { diff --git a/src/lightdata.rs b/src/lightdata.rs index a3c3a96ec66a6f3ded4e1a3a9a002a0741039f75..7d9aa063c9a9dbe8edafe9c0ca284a05c4b7f5e2 100644 --- a/src/lightdata.rs +++ b/src/lightdata.rs @@ -15,8 +15,8 @@ impl LightData { match self { LightData::Energy(d) => { d.spectrum.to_plot(file_name); - }, - _ => println!("no export function defined for this type of LightData") + } + _ => println!("no export function defined for this type of LightData"), } } } diff --git a/src/nodes/ideal_filter.rs b/src/nodes/ideal_filter.rs index b2e7ab627fdc313e2d00c92861d40b9f62a0a5da..b0a8eeb844ddcbf823d858cb8819fc7c859583e8 100644 --- a/src/nodes/ideal_filter.rs +++ b/src/nodes/ideal_filter.rs @@ -26,17 +26,12 @@ impl IdealFilter { /// /// This function will return an error if a transmission factor > 1.0 is given (This would be an amplifiying filter :-) ). pub fn new(filter_type: FilterType) -> Result<Self> { - match filter_type { - FilterType::Constant(transmission) => { - if transmission < 0.0 || transmission > 1.0 { - return Err(OpossumError::Other("attenuation must be <= 1.0".into())) - } - }, - _ => () + if let FilterType::Constant(transmission) = filter_type { + if !(0.0..=1.0).contains(&transmission) { + return Err(OpossumError::Other("attenuation must be <= 1.0".into())); + } } - Ok(Self { - filter_type, - }) + Ok(Self { filter_type }) } /// Returns the filter type of this [`IdealFilter`]. pub fn filter_type(&self) -> FilterType { @@ -92,11 +87,11 @@ impl IdealFilter { } } FilterType::Spectrum(s) => { - out_spec.filter(&s); + out_spec.filter(s); let light_data = - Some(LightData::Energy(DataEnergy { spectrum: out_spec })); - return Ok(HashMap::from([("rear".into(), light_data)])); - }, + Some(LightData::Energy(DataEnergy { spectrum: out_spec })); + return Ok(HashMap::from([("rear".into(), light_data)])); + } } } _ => return Err(OpossumError::Analysis("expected energy value".into())), diff --git a/src/nodes/mod.rs b/src/nodes/mod.rs index 3332ae1857e0ead9345c6d088a097dec10ed5801..4caab1f9a69ee0beab842135933c2a3b639906b4 100644 --- a/src/nodes/mod.rs +++ b/src/nodes/mod.rs @@ -1,17 +1,17 @@ //! This module contains the concrete node types (lenses, filters, etc...) +mod ideal_filter; +mod node_beam_splitter; +mod node_detector; mod node_dummy; -mod node_reference; mod node_group; -mod node_beam_splitter; +mod node_reference; mod node_source; -mod node_detector; -mod ideal_filter; +pub use ideal_filter::FilterType; +pub use ideal_filter::IdealFilter; +pub use node_beam_splitter::BeamSplitter; +pub use node_detector::Detector; pub use node_dummy::Dummy; -pub use node_reference::NodeReference; pub use node_group::NodeGroup; -pub use node_beam_splitter::BeamSplitter; +pub use node_reference::NodeReference; pub use node_source::Source; -pub use node_detector::Detector; -pub use ideal_filter::IdealFilter; -pub use ideal_filter::FilterType; \ No newline at end of file diff --git a/src/nodes/node_beam_splitter.rs b/src/nodes/node_beam_splitter.rs index 1259f282a1addc4c825f9e473359930773ce11dc..fb146276fd0ba927a2981068e9ab0d496b31ced8 100644 --- a/src/nodes/node_beam_splitter.rs +++ b/src/nodes/node_beam_splitter.rs @@ -6,7 +6,7 @@ use crate::{ lightdata::{DataEnergy, LightData}, optic_node::{Dottable, LightResult, Optical}, optic_ports::OpticPorts, - spectrum::{Spectrum, unify_spectrum} + spectrum::{unify_spectrum, Spectrum}, }; type Result<T> = std::result::Result<T, OpossumError>; @@ -43,39 +43,43 @@ impl BeamSplitter { if let Some(Some(in1)) = in1 { match in1 { - LightData::Energy(e) => { - let mut s=e.spectrum.clone(); + 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); + 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(); + 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); - }, + 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= unify_spectrum(out1_1_spectrum, out2_2_spectrum); - let out2_spec= unify_spectrum(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 })) + let out1_spec = unify_spectrum(out1_1_spectrum, out2_2_spectrum); + let out2_spec = unify_spectrum(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 })) + if let Some(out2_spec) = out2_spec { + out2_data = Some(LightData::Energy(DataEnergy { + spectrum: out2_spec, + })) } Ok(HashMap::from([ ("out1_trans1_refl2".into(), out1_data), diff --git a/src/nodes/node_detector.rs b/src/nodes/node_detector.rs index 0c5c06862845a8c5624babfd20c8aaf74c18e8e6..a89297c8e551a4eafdcecd535020e2d899a3aa4d 100644 --- a/src/nodes/node_detector.rs +++ b/src/nodes/node_detector.rs @@ -37,8 +37,8 @@ impl Optical for Detector { Ok(LightResult::default()) } fn export_data(&self, file_name: &str) { - if let Some(data)=&self.light_data { - data.export(file_name) + if let Some(data) = &self.light_data { + data.export(file_name) } } } @@ -46,7 +46,7 @@ impl Optical for Detector { impl Debug for Detector { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match &self.light_data { - Some(data) => write!(f,"{}",data), + Some(data) => write!(f, "{}", data), None => write!(f, "no data"), } } diff --git a/src/nodes/node_dummy.rs b/src/nodes/node_dummy.rs index 805436538a70ed1007759466f25a67ae4c4861fe..793b8eea9934f5ee5c943538b4997ccabeee59c9 100644 --- a/src/nodes/node_dummy.rs +++ b/src/nodes/node_dummy.rs @@ -1,4 +1,4 @@ -use crate::optic_node::{Optical,Dottable}; +use crate::optic_node::{Dottable, Optical}; use crate::optic_ports::OpticPorts; #[derive(Debug)] @@ -11,11 +11,11 @@ impl Optical for Dummy { "dummy" } fn ports(&self) -> OpticPorts { - let mut ports=OpticPorts::new(); + let mut ports = OpticPorts::new(); ports.add_input("front").unwrap(); ports.add_output("rear").unwrap(); ports } } -impl Dottable for Dummy{} \ No newline at end of file +impl Dottable for Dummy {} diff --git a/src/nodes/node_reference.rs b/src/nodes/node_reference.rs index 96da963b13092fe790c1b3367392623d8697848a..2be3769712a55b91488667da451215716ecbfd43 100644 --- a/src/nodes/node_reference.rs +++ b/src/nodes/node_reference.rs @@ -1,7 +1,7 @@ use std::cell::RefCell; -use std::rc::{Weak, Rc}; +use std::rc::{Rc, Weak}; -use crate::optic_node::{OpticNode, Optical, Dottable}; +use crate::optic_node::{Dottable, OpticNode, Optical}; use crate::optic_ports::OpticPorts; #[derive(Debug)] @@ -12,7 +12,9 @@ pub struct NodeReference { impl NodeReference { pub fn new(node: Rc<RefCell<OpticNode>>) -> OpticNode { - let node_ref = Self { reference: Rc::downgrade(&node) }; + let node_ref = Self { + reference: Rc::downgrade(&node), + }; OpticNode::new(&format!("Ref: \"{}\"", &node.borrow().name()), node_ref) } } @@ -23,12 +25,12 @@ impl Optical for NodeReference { } fn ports(&self) -> OpticPorts { - self.reference.upgrade().unwrap().borrow().ports().clone() + self.reference.upgrade().unwrap().borrow().ports().clone() } } -impl Dottable for NodeReference{ +impl Dottable for NodeReference { fn node_color(&self) -> &str { "lightsalmon3" - } + } } diff --git a/src/nodes/node_source.rs b/src/nodes/node_source.rs index 5402d323173984717bc1b859941c3eed99f78b85..1b81afd50db03ca3a3e964824ab1c9659d272f9a 100644 --- a/src/nodes/node_source.rs +++ b/src/nodes/node_source.rs @@ -2,9 +2,10 @@ use std::collections::HashMap; use std::fmt::Debug; use crate::{ + error::OpossumError, lightdata::LightData, - optic_node::{Dottable, Optical, LightResult}, - optic_ports::OpticPorts, error::OpossumError, + optic_node::{Dottable, LightResult, Optical}, + optic_ports::OpticPorts, }; type Result<T> = std::result::Result<T, OpossumError>; @@ -37,7 +38,7 @@ impl Source { impl Debug for Source { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match &self.light_data { - Some(data) => write!(f,"{}",data), + Some(data) => write!(f, "{}", data), None => write!(f, "no data"), } } @@ -53,8 +54,12 @@ impl Optical for Source { ports } - fn analyze(&mut self, _incoming_edges: LightResult, _analyzer_type: &crate::analyzer::AnalyzerType) -> Result<LightResult> { - let data=self.light_data.clone(); + fn analyze( + &mut self, + _incoming_edges: LightResult, + _analyzer_type: &crate::analyzer::AnalyzerType, + ) -> Result<LightResult> { + let data = self.light_data.clone(); if data.is_some() { Ok(HashMap::from([("out1".into(), data)])) } else { diff --git a/src/optic_node.rs b/src/optic_node.rs index b478012a476b554d0ef8aa0509d23e41c9dd124a..a62d7cf42a66e32eec5302b0f1e3f005352a4bf5 100644 --- a/src/optic_node.rs +++ b/src/optic_node.rs @@ -77,7 +77,7 @@ impl OpticNode { self.node.analyze(incoming_data, analyzer_type) } pub fn export_data(&self) { - let file_name=self.name.to_owned() +".svg"; + let file_name = self.name.to_owned() + ".svg"; self.node.export_data(&file_name); } } diff --git a/src/optic_scenery.rs b/src/optic_scenery.rs index 485a02f74bbdcc0e62077b94d8f2613bb71a3910..3739ed9bafce773995caf51a8747ce3133461ee2 100644 --- a/src/optic_scenery.rs +++ b/src/optic_scenery.rs @@ -6,12 +6,12 @@ use crate::analyzer::AnalyzerType; use crate::error::OpossumError; use crate::light::Light; use crate::lightdata::LightData; -use crate::optic_node::{OpticComponent, OpticNode, LightResult}; -use petgraph::Direction::{Incoming, Outgoing}; +use crate::optic_node::{LightResult, OpticComponent, OpticNode}; use petgraph::algo::toposort; use petgraph::algo::*; use petgraph::prelude::{DiGraph, EdgeIndex, NodeIndex}; use petgraph::visit::EdgeRef; +use petgraph::Direction::{Incoming, Outgoing}; type Result<T> = std::result::Result<T, OpossumError>; @@ -210,7 +210,12 @@ impl OpticScenery { }) .collect::<HashMap<String, Option<LightData>>>() } - pub fn set_outgoing_edge_data(&mut self, idx: NodeIndex, port: String, data: Option<LightData>) { + pub fn set_outgoing_edge_data( + &mut self, + idx: NodeIndex, + port: String, + data: Option<LightData>, + ) { let edges = self.g.edges_directed(idx, petgraph::Direction::Outgoing); let edge_ref = edges .into_iter() @@ -227,20 +232,20 @@ impl OpticScenery { } } pub fn report(&self) { - let src_nodes=&self.g.externals(Incoming); - let sink_nodes=&self.g.externals(Outgoing); + let src_nodes = &self.g.externals(Incoming); + let sink_nodes = &self.g.externals(Outgoing); println!("Sources:"); for idx in src_nodes.clone() { - let node=self.node(idx).unwrap(); + let node = self.node(idx).unwrap(); println!("{:?}", node.borrow()); node.borrow().export_data(); } println!("Sinks:"); for idx in sink_nodes.clone() { - let node=self.node(idx).unwrap(); + let node = self.node(idx).unwrap(); println!("{:?}", node.borrow()); node.borrow().export_data(); - } + } } } diff --git a/src/spectrum.rs b/src/spectrum.rs index 485da9d6c98422a9f12166abd180a6aa1d8dac65..84bdd8a165f48a2fb8e9cc3b866c6023910a56b3 100644 --- a/src/spectrum.rs +++ b/src/spectrum.rs @@ -218,45 +218,6 @@ impl Spectrum { self.data = &self.data * factor; Ok(()) } - fn enclosing_interval(&self, x_lower: f64, x_upper: f64) -> Vec<Option<usize>> { - let mut res = self - .lambdas - .iter() - .enumerate() - .filter(|x| *x.1 < x_upper && *x.1 > x_lower) - .map(|x| Some(x.0)) - .collect::<Vec<Option<usize>>>(); - if res.is_empty() { - let mut lower_idx = self.lambdas.iter().position(|x| *x >= x_lower); - let upper_idx = self.lambdas.iter().position(|x| *x >= x_upper); - if let Some(l_i) = lower_idx { - if l_i > 0 && self.lambdas[l_i] > x_lower { - lower_idx = Some(l_i - 1); - } - } - if lower_idx == upper_idx { - res = vec![None, None]; - } else { - res = vec![lower_idx, upper_idx]; - } - } else { - let res_cp = res.clone(); - let first = res_cp.first().unwrap(); - let last = res_cp.last().unwrap(); - if let Some(first) = first { - if *first > 0 { - res.insert(0, Some(first - 1)); - } - } - if let Some(last) = last { - if *last < self.lambdas.len() - 1 { - res.push(Some(last + 1)) - } - } - } - res - } - /// Resample a provided [`Spectrum`] to match the given one. /// /// This function maps values and wavelengths of a provided spectrum to the structure of self. This function conserves the total @@ -266,23 +227,55 @@ impl Spectrum { /// /// Panics if ???. pub fn resample(&mut self, spectrum: &Spectrum) { - let max_idx = self.data.len() - 1; - for x in self.data.iter_mut().enumerate().filter(|x| x.0 < max_idx) { - let lower_bound = *self.lambdas.get(x.0).unwrap(); - let upper_bound = *self.lambdas.get(x.0 + 1).unwrap(); - let interval = spectrum.enclosing_interval(lower_bound, upper_bound); - let mut bucket_value = 0.0; - for src_idx in interval.windows(2) { - if (*src_idx)[0].is_some() && (*src_idx)[1].is_some() { - let source_left = spectrum.lambdas[src_idx[0].unwrap()]; - let source_right = spectrum.lambdas[src_idx[1].unwrap()]; - let ratio = calc_ratio(lower_bound, upper_bound, source_left, source_right); - bucket_value += - spectrum.data[src_idx[0].unwrap()] * ratio * (source_right - source_left) - / (upper_bound - lower_bound); + let mut src_it = spectrum.lambdas.windows(2).into_iter(); + let src_interval = src_it.next(); + if src_interval.is_none() { + return; + } + let mut src_lower = src_interval.unwrap()[0]; + let mut src_upper = src_interval.unwrap()[1]; + let mut src_idx: usize = 0; + let mut bucket_it = self.lambdas.windows(2).into_iter(); + let bucket_interval = bucket_it.next(); + if bucket_interval.is_none() { + return; + } + let mut bucket_lower = bucket_interval.unwrap()[0]; + let mut bucket_upper = bucket_interval.unwrap()[1]; + let mut bucket_idx: usize = 0; + self.data[bucket_idx] = 0.0; + while src_upper < bucket_lower { + if let Some(src_interval) = src_it.next() { + src_lower = src_interval[0]; + src_upper = src_interval[1]; + src_idx += 1; + } else { + break; + } + } + loop { + let ratio = calc_ratio(bucket_lower, bucket_upper, src_lower, src_upper); + let bucket_value = spectrum.data[src_idx] * ratio * (src_upper - src_lower) + / (bucket_upper - bucket_lower); + self.data[bucket_idx] += bucket_value; + if src_upper < bucket_upper { + if let Some(src_interval) = src_it.next() { + src_lower = src_interval[0]; + src_upper = src_interval[1]; + src_idx += 1; + continue; + } else { + break; } + } else if let Some(bucket_interval) = bucket_it.next() { + bucket_lower = bucket_interval[0]; + bucket_upper = bucket_interval[1]; + bucket_idx += 1; + self.data[bucket_idx] = 0.0; + continue; + } else { + break; } - *x.1 = bucket_value; } } /// Filter the spectrum with another given spectrum by multiplying the data values. The given spectrum is resampled before the multiplication. @@ -472,7 +465,12 @@ pub fn unify_spectrum(s1: Option<Spectrum>, s2: Option<Spectrum>) -> Option<Spec .unwrap() .average_resolution() .min(s2.as_ref().unwrap().average_resolution()); - println!("min={}, max={}, res={}", minimum.get::<nanometer>(), maximum.get::<nanometer>(), resolution.get::<nanometer>()); + println!( + "min={}, max={}, res={}", + minimum.get::<nanometer>(), + maximum.get::<nanometer>(), + resolution.get::<nanometer>() + ); let mut s_out = Spectrum::new(minimum..maximum, resolution).unwrap(); println!("resampling..."); s_out.resample(&s1.unwrap()); @@ -672,96 +670,6 @@ mod test { assert!(s.scale_vertical(-0.5).is_err()); } #[test] - fn enclosing_interval() { - let s = Spectrum::new( - Length::new::<meter>(1.0)..Length::new::<meter>(5.0), - Length::new::<meter>(1.0), - ) - .unwrap(); - let v = s.enclosing_interval(2.1, 3.9); - assert_eq!(v, vec![Some(1), Some(2), Some(3)]); - } - #[test] - fn enclosing_interval_exact() { - let s = Spectrum::new( - Length::new::<meter>(1.0)..Length::new::<meter>(5.0), - Length::new::<meter>(1.0), - ) - .unwrap(); - let v = s.enclosing_interval(2.0, 4.0); - assert_eq!(v, vec![Some(1), Some(2), Some(3)]); - } - #[test] - fn enclosing_interval_upper_bound() { - let s = Spectrum::new( - Length::new::<meter>(1.0)..Length::new::<meter>(5.0), - Length::new::<meter>(1.0), - ) - .unwrap(); - let v = s.enclosing_interval(3.0, 5.0); - assert_eq!(v, vec![Some(2), Some(3)]); // ranges are exclusive upper bound ! - } - #[test] - fn enclosing_interval_lower_bound() { - let s = Spectrum::new( - Length::new::<meter>(1.0)..Length::new::<meter>(5.0), - Length::new::<meter>(1.0), - ) - .unwrap(); - let v = s.enclosing_interval(1.0, 3.0); - assert_eq!(v, vec![Some(0), Some(1), Some(2)]); - } - #[test] - fn enclosing_interval_small_range() { - let s = Spectrum::new( - Length::new::<meter>(1.0)..Length::new::<meter>(5.0), - Length::new::<meter>(1.0), - ) - .unwrap(); - let v = s.enclosing_interval(2.6, 2.9); - assert_eq!(v, vec![Some(1), Some(2)]); - } - #[test] - fn enclosing_interval_right_outside() { - let s = Spectrum::new( - Length::new::<meter>(1.0)..Length::new::<meter>(5.0), - Length::new::<meter>(1.0), - ) - .unwrap(); - let v = s.enclosing_interval(5.1, 7.0); - assert_eq!(v, vec![None, None]); - } - #[test] - fn enclosing_interval_right_partly_outside() { - let s = Spectrum::new( - Length::new::<meter>(1.0)..Length::new::<meter>(5.0), - Length::new::<meter>(1.0), - ) - .unwrap(); - let v = s.enclosing_interval(2.1, 7.0); - assert_eq!(v, vec![Some(1), Some(2), Some(3)]); - } - #[test] - fn enclosing_interval_left_outside() { - let s = Spectrum::new( - Length::new::<meter>(5.0)..Length::new::<meter>(10.0), - Length::new::<meter>(1.0), - ) - .unwrap(); - let v = s.enclosing_interval(1.0, 4.9); - assert_eq!(v, vec![None, None]); - } - #[test] - fn enclosing_interval_left_partly_outside() { - let s = Spectrum::new( - Length::new::<meter>(5.0)..Length::new::<meter>(10.0), - Length::new::<meter>(1.0), - ) - .unwrap(); - let v = s.enclosing_interval(2.1, 6.5); - assert_eq!(v, vec![Some(0), Some(1), Some(2)]); - } - #[test] fn calc_ratio_test() { assert_eq!(calc_ratio(1.0, 2.0, 3.0, 4.0), 0.0); // bucket completely outside assert_eq!(calc_ratio(1.0, 4.0, 2.0, 3.0), 1.0); // bucket contains source @@ -781,12 +689,30 @@ mod test { Length::new::<meter>(1.0), ) .unwrap(); - s1.add_single_peak(Length::new::<meter>(2.0), 1.0).unwrap(); - let s2 = Spectrum::new( + let mut s2 = Spectrum::new( Length::new::<meter>(1.0)..Length::new::<meter>(5.0), Length::new::<meter>(1.0), ) .unwrap(); + s2.add_single_peak(Length::new::<meter>(2.0), 1.0).unwrap(); + s1.resample(&s2); + assert_eq!(s1.data, s2.data); + assert_eq!(s1.total_energy(), s2.total_energy()); + } + #[test] + fn resample_delete_old_data() { + let mut s1 = Spectrum::new( + Length::new::<meter>(1.0)..Length::new::<meter>(5.0), + Length::new::<meter>(1.0), + ) + .unwrap(); + s1.add_single_peak(Length::new::<meter>(3.0), 1.0).unwrap(); + let mut s2 = Spectrum::new( + Length::new::<meter>(1.0)..Length::new::<meter>(5.0), + Length::new::<meter>(1.0), + ) + .unwrap(); + s2.add_single_peak(Length::new::<meter>(2.0), 1.0).unwrap(); s1.resample(&s2); assert_eq!(s1.data, s2.data); assert_eq!(s1.total_energy(), s2.total_energy());