diff --git a/Cargo.lock b/Cargo.lock index 24b9766308f3cc19e33902d9f2696404b511d5ca..f41dbbd4645c3cafb793546de6e8ad5b91b85ed4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -730,7 +730,7 @@ dependencies = [ "downcast-rs", "either", "petgraph 0.6.5", - "ron", + "ron 0.8.1", "serde", "smallvec", "thread_local", @@ -784,7 +784,7 @@ dependencies = [ "futures-lite", "js-sys", "parking_lot", - "ron", + "ron 0.8.1", "serde", "stackfuture", "uuid", @@ -4945,10 +4945,10 @@ dependencies = [ "rand 0.9.0", "rayon", "regex", + "ron 0.9.0", "roots", "rprompt", "serde", - "serde_yaml", "sobol", "spade", "strum", @@ -5645,6 +5645,19 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "ron" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63f3aa105dea217ef30d89581b65a4d527a19afc95ef5750be3890e8d3c5b837" +dependencies = [ + "base64 0.22.1", + "bitflags 2.8.0", + "serde", + "serde_derive", + "unicode-ident", +] + [[package]] name = "roots" version = "0.0.8" @@ -5878,19 +5891,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap 2.7.1", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", -] - [[package]] name = "sha1" version = "0.10.6" @@ -6655,12 +6655,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" - [[package]] name = "uom" version = "0.36.0" diff --git a/opossum/Cargo.toml b/opossum/Cargo.toml index b4b02976ba8e18143acb07d74e92ac3ab64ba9a1..6ec8db8338d8a83df8f771f031b69cb7868b18bc 100644 --- a/opossum/Cargo.toml +++ b/opossum/Cargo.toml @@ -30,7 +30,8 @@ opm_macros_lib = { path = "opm_macros_lib" } petgraph = { version = "0.7", features = ["serde-1"] } # the graph library uom = {version="0.36", features = ["serde"] } serde = { version = "1", features = ['rc'] } -serde_yaml = "0.9" +#serde_yaml = "0.9" +ron="0.9" csv = "1" plotters = "0.3" @@ -41,6 +42,7 @@ clap = { version = "4", features = ["derive", "string"] } # command line argumen [target.'cfg(not(target_arch = "wasm32"))'.dependencies] rprompt = "2" strum = { version = "0.26", features = ["derive"] } +strum_macros = "0.26" uuid = { version = "1", features = ["v4", "fast-rng", "serde"] } @@ -55,7 +57,7 @@ sobol="1" itertools = "0.14" nalgebra = {version = "0.33", features = ["serde-serialize", "rayon"]} colorous = "1" -strum_macros = "0.26" + delaunator = "1" num = "0.4" kahan = "0.1" diff --git a/opossum/examples/beam_combine_test.rs b/opossum/examples/beam_combine_test.rs index c0608752fef6298d9af89e723bac916af64d598e..f8bba58599b0f20ede6bed496f15b439c8b834a1 100644 --- a/opossum/examples/beam_combine_test.rs +++ b/opossum/examples/beam_combine_test.rs @@ -5,7 +5,7 @@ use num::Zero; use opossum::{ analyzers::AnalyzerType, error::OpmResult, - lightdata::{DataEnergy, LightData}, + lightdata::{energy_spectrum_builder::EnergyDataBuilder, light_data_builder::LightDataBuilder}, nanometer, nodes::{BeamSplitter, Dummy, FilterType, IdealFilter, NodeGroup, Source}, ray::SplittingConfig, @@ -16,18 +16,12 @@ use uom::si::f64::Length; fn main() -> OpmResult<()> { let mut scenery = NodeGroup::new("beam combiner demo"); - let i_s1 = scenery.add_node(Source::new( - "Source 1", - &LightData::Energy(DataEnergy { - spectrum: create_he_ne_spec(1.0).unwrap(), - }), - ))?; - let i_s2 = scenery.add_node(Source::new( - "Source 2", - &LightData::Energy(DataEnergy { - spectrum: create_nd_glass_spec(1.0)?, - }), - ))?; + let light_data_builder = + LightDataBuilder::Energy(EnergyDataBuilder::Raw(create_he_ne_spec(1.0)?)); + let i_s1 = scenery.add_node(Source::new("Source 1", light_data_builder))?; + let light_data_builder = + LightDataBuilder::Energy(EnergyDataBuilder::Raw(create_nd_glass_spec(1.0)?)); + let i_s2 = scenery.add_node(Source::new("Source 2", light_data_builder))?; let i_bs = scenery.add_node(BeamSplitter::new("bs", &SplittingConfig::Ratio(0.5)).unwrap())?; let filter_spectrum = generate_filter_spectrum( nanometer!(400.0)..nanometer!(1100.0), diff --git a/opossum/examples/filter_test.rs b/opossum/examples/filter_test.rs index 8e5a470b5598a518841ca8f9e02803401fda3191..1bbbdb6980c68501b56ca2d24a65eeb8daba88c1 100644 --- a/opossum/examples/filter_test.rs +++ b/opossum/examples/filter_test.rs @@ -4,7 +4,7 @@ use num::Zero; use opossum::{ analyzers::{AnalyzerType, RayTraceConfig}, error::OpmResult, - lightdata::{DataEnergy, LightData}, + lightdata::{energy_spectrum_builder::EnergyDataBuilder, light_data_builder::LightDataBuilder}, nodes::{BeamSplitter, EnergyMeter, FilterType, IdealFilter, NodeGroup, Source, Spectrometer}, ray::SplittingConfig, spectrum::Spectrum, @@ -15,14 +15,11 @@ use uom::si::f64::Length; fn main() -> OpmResult<()> { let mut scenery = NodeGroup::new("filter system demo"); - let i_s = scenery.add_node(Source::new( - "Source", - &LightData::Energy(DataEnergy { - spectrum: create_he_ne_spec(1.0)?, - }), - ))?; + let light_data_builder = + LightDataBuilder::Energy(EnergyDataBuilder::Raw(create_he_ne_spec(1.0)?)); + let i_s = scenery.add_node(Source::new("Source", light_data_builder))?; let i_bs = scenery.add_node(BeamSplitter::new("bs", &SplittingConfig::Ratio(0.6)).unwrap())?; - let filter_spectrum = Spectrum::from_csv("./opossum/opossum/NE03B.csv")?; + let filter_spectrum = Spectrum::from_csv(Path::new("./opossum/opossum/NE03B.csv"))?; let i_f = scenery.add_node(IdealFilter::new( "filter", &FilterType::Spectrum(filter_spectrum), diff --git a/opossum/examples/fluence_helper_test.rs b/opossum/examples/fluence_helper_test.rs index 724d673815e6d8dc5fb503594cdfca0664639c4b..155563b516929ab5d0a3ae4d2b1dd0b6166ebebc 100644 --- a/opossum/examples/fluence_helper_test.rs +++ b/opossum/examples/fluence_helper_test.rs @@ -3,7 +3,7 @@ use opossum::{ error::OpmResult, fluence_distributions::general_gaussian::General2DGaussian, joule, - lightdata::LightData, + lightdata::{light_data_builder::LightDataBuilder, ray_data_builder::RayDataBuilder}, millimeter, nanometer, nodes::{FluenceDetector, NodeGroup, ParaxialSurface, Source}, optic_node::OpticNode, @@ -32,7 +32,8 @@ fn main() -> OpmResult<()> { rays.nr_of_rays(true), peak.get::<joule_per_square_centimeter>() ); - let mut source = Source::new("source", &LightData::Geometric(rays)); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays)); + let mut source = Source::new("source", light_data_builder); source.set_isometry(Isometry::identity())?; let mut scenery = NodeGroup::default(); let i_src = scenery.add_node(source)?; diff --git a/opossum/examples/fluence_test.rs b/opossum/examples/fluence_test.rs index 4f287f6e39c207e28ee4127dc3795e6220ddb09b..c1dbe805ea926e7b5cec28c55a8622bbbc9bdd1b 100644 --- a/opossum/examples/fluence_test.rs +++ b/opossum/examples/fluence_test.rs @@ -6,7 +6,7 @@ use opossum::{ energy_distributions::General2DGaussian, error::OpmResult, joule, - lightdata::LightData, + lightdata::{light_data_builder::LightDataBuilder, ray_data_builder::RayDataBuilder}, millimeter, nanometer, nodes::{FluenceDetector, NodeGroup, Source}, optic_node::OpticNode, @@ -41,7 +41,8 @@ fn main() -> OpmResult<()> { peak.get::<millijoule_per_square_centimeter>() ); } - let mut source = Source::new("source", &LightData::Geometric(rays)); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays)); + let mut source = Source::new("source", light_data_builder); source.set_isometry(Isometry::identity())?; let mut scenery = NodeGroup::default(); let i_src = scenery.add_node(source)?; diff --git a/opossum/examples/folded_telescope.rs b/opossum/examples/folded_telescope.rs index 599bc3afb85ede88f9801e1e962568e6d62de9a0..dbce98b7c2052ed93ff91a0f4379b3e041f6b886 100644 --- a/opossum/examples/folded_telescope.rs +++ b/opossum/examples/folded_telescope.rs @@ -8,7 +8,7 @@ use opossum::{ energy_distributions::UniformDist, error::OpmResult, joule, - lightdata::LightData, + lightdata::{light_data_builder::LightDataBuilder, ray_data_builder::RayDataBuilder}, millimeter, nanometer, nodes::{Lens, NodeGroup, NodeReference, RayPropagationVisualizer, Source, ThinMirror}, optic_node::{Alignable, OpticNode}, @@ -43,9 +43,8 @@ pub fn main() -> OpmResult<()> { &UniformDist::new(joule!(1.))?, &Hexapolar::new(millimeter!(10.), 10)?, )?; - - let light = LightData::Geometric(rays); - let mut src = Source::new("collimated ray source", &light); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays)); + let mut src = Source::new("collimated ray source", light_data_builder); src.set_alignment_wavelength(alignment_wvl)?; src.set_isometry(Isometry::identity())?; diff --git a/opossum/examples/fresnel_coating.rs b/opossum/examples/fresnel_coating.rs index 04b6df61e63c41a4aea71cc5b90fd141ee322521..a0883b9c5dc1906cdaa2264ef83d27ace227a56f 100644 --- a/opossum/examples/fresnel_coating.rs +++ b/opossum/examples/fresnel_coating.rs @@ -4,7 +4,7 @@ use opossum::{ energy_distributions::UniformDist, error::OpmResult, joule, - lightdata::LightData, + lightdata::{light_data_builder::LightDataBuilder, ray_data_builder::RayDataBuilder}, millimeter, nanometer, nodes::{EnergyMeter, FluenceDetector, Lens, NodeGroup, RayPropagationVisualizer, Source}, optic_node::OpticNode, @@ -24,7 +24,8 @@ fn main() -> OpmResult<()> { &UniformDist::new(joule!(1.))?, &Grid::new((millimeter!(9.), millimeter!(9.)), (100, 100))?, )?; - let mut source = Source::new("src", &LightData::Geometric(rays)); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays)); + let mut source = Source::new("src", light_data_builder); source.set_isometry(Isometry::identity())?; let src = scenery.add_node(source)?; let fd1 = scenery.add_node(FluenceDetector::new("before lens"))?; diff --git a/opossum/examples/ghost_focus.rs b/opossum/examples/ghost_focus.rs index 3b432dbb91cf3c78e84d12c0ef4fd217494ff225..0c3bfbd884892ec47e2fc7332b924259026a8e06 100644 --- a/opossum/examples/ghost_focus.rs +++ b/opossum/examples/ghost_focus.rs @@ -5,7 +5,7 @@ use opossum::{ energy_distributions::General2DGaussian, error::OpmResult, joule, - lightdata::LightData, + lightdata::{light_data_builder::LightDataBuilder, ray_data_builder::RayDataBuilder}, millimeter, nanometer, nodes::{Lens, NodeGroup, Source, ThinMirror}, optic_node::{Alignable, OpticNode}, @@ -35,8 +35,8 @@ fn main() -> OpmResult<()> { &HexagonalTiling::new(millimeter!(15.0), 25, millimeter!(0.0, 0.))?, )?; - let light = LightData::Geometric(rays); - let mut src = Source::new("collimated ray source", &light); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays)); + let mut src = Source::new("collimated ray source", light_data_builder); src.set_isometry(Isometry::identity())?; let i_src = scenery.add_node(src)?; let mut lens = Lens::default(); diff --git a/opossum/examples/grating_examples/grating_examples.rs b/opossum/examples/grating_examples/grating_examples.rs index ac781de4aacc9009a53872779d767f47015cbeb0..8d19bed30531af20685cbec13f6304629c73a87d 100644 --- a/opossum/examples/grating_examples/grating_examples.rs +++ b/opossum/examples/grating_examples/grating_examples.rs @@ -1,5 +1,7 @@ use nalgebra::Vector3; use opossum::analyzers::{AnalyzerType, RayTraceConfig}; +use opossum::lightdata::light_data_builder::LightDataBuilder; +use opossum::lightdata::ray_data_builder::RayDataBuilder; use opossum::nodes::{NodeGroup, NodeReference, ParaxialSurface, SpotDiagram, ThinMirror}; use opossum::optic_node::Alignable; use opossum::refractive_index::{RefrIndexConst, RefractiveIndex}; @@ -7,9 +9,7 @@ use opossum::OpmDocument; use opossum::{ energy_distributions::UniformDist, error::OpmResult, - joule, - lightdata::LightData, - millimeter, nanometer, + joule, millimeter, nanometer, nodes::{Lens, RayPropagationVisualizer, Source}, optic_node::OpticNode, position_distributions::Hexapolar, @@ -56,9 +56,8 @@ fn main() -> OpmResult<()> { &UniformDist::new(joule!(1.))?, &Hexapolar::new(millimeter!(1.), 4)?, )?; - let light = LightData::Geometric(rays); - - let mut src = Source::new("collimated ray source", &light); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays)); + let mut src = Source::new("collimated ray source", light_data_builder); src.set_alignment_wavelength(alignment_wvl)?; src.set_isometry(Isometry::identity())?; //////////////////////////////////// @@ -324,9 +323,8 @@ fn main() -> OpmResult<()> { &UniformDist::new(joule!(1.))?, &Hexapolar::new(millimeter!(50.), 8)?, )?; - - let light = LightData::Geometric(rays); - let mut src = Source::new("collimated ray source", &light); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays)); + let mut src = Source::new("collimated ray source", light_data_builder); src.set_alignment_wavelength(alignment_wvl)?; src.set_isometry(Isometry::identity())?; diff --git a/opossum/examples/group_reverse.rs b/opossum/examples/group_reverse.rs index 5715b59555434521dfb50a16e22583893d9b3168..332cadcb1f1e3637cf66631b8cd1d67436e7b424 100644 --- a/opossum/examples/group_reverse.rs +++ b/opossum/examples/group_reverse.rs @@ -4,7 +4,7 @@ use num::Zero; use opossum::{ analyzers::AnalyzerType, error::OpmResult, - lightdata::{DataEnergy, LightData}, + lightdata::{energy_spectrum_builder::EnergyDataBuilder, light_data_builder::LightDataBuilder}, nodes::{Dummy, EnergyMeter, NodeGroup, Source}, optic_node::OpticNode, spectrum_helper::create_he_ne_spec, @@ -14,12 +14,9 @@ use uom::si::f64::Length; fn main() -> OpmResult<()> { let mut scenery = NodeGroup::new("Inverse Group test"); - let i_s = scenery.add_node(Source::new( - "Source", - &LightData::Energy(DataEnergy { - spectrum: create_he_ne_spec(1.0)?, - }), - ))?; + let light_data_builder = + LightDataBuilder::Energy(EnergyDataBuilder::Raw(create_he_ne_spec(1.0)?)); + let i_s = scenery.add_node(Source::new("Source", light_data_builder))?; let mut group = NodeGroup::default(); group.set_expand_view(true)?; diff --git a/opossum/examples/hhts/hhts.rs b/opossum/examples/hhts/hhts.rs index 7a1d12915eed581924f1bae6d900625fd54153df..42d9f979d783f7230429464971052582d54dd878 100644 --- a/opossum/examples/hhts/hhts.rs +++ b/opossum/examples/hhts/hhts.rs @@ -14,7 +14,7 @@ use opossum::{ energy_distributions::General2DGaussian, error::OpmResult, joule, - lightdata::LightData, + lightdata::{light_data_builder::LightDataBuilder, ray_data_builder::RayDataBuilder}, millimeter, nanometer, nodes::{ BeamSplitter, Dummy, EnergyMeter, FilterType, IdealFilter, Lens, Metertype, NodeGroup, @@ -138,7 +138,8 @@ fn main() -> OpmResult<()> { rays.add_rays(&mut rays_2w); let mut scenery = NodeGroup::new("HHT Sensor"); - let mut src = Source::new("Source", &LightData::Geometric(rays)); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays)); + let mut src = Source::new("Source", light_data_builder); src.set_isometry(Isometry::identity())?; let src = scenery.add_node(src)?; let input_group = scenery.add_node(hhts_input()?)?; @@ -224,9 +225,9 @@ fn main() -> OpmResult<()> { let bs = group_bs.add_node(BeamSplitter::new("Dichroic BS HBSY21", &short_pass)?)?; // Long pass filter (1w) - let felh1000 = FilterType::Spectrum(Spectrum::from_csv( + let felh1000 = FilterType::Spectrum(Spectrum::from_csv(Path::new( "opossum/examples/hhts/FELH1000_Transmission.csv", - )?); + ))?); let mut node = IdealFilter::new("1w Longpass filter", &felh1000)?; node.set_aperture(&PortType::Input, "input_1", &a_1inch)?; let filter_1w = group_bs.add_node(node)?; @@ -239,9 +240,9 @@ fn main() -> OpmResult<()> { )?; // Long pass filter (2w) - let fesh0700 = FilterType::Spectrum(Spectrum::from_csv( + let fesh0700 = FilterType::Spectrum(Spectrum::from_csv(Path::new( "opossum/examples/hhts/FESH0700_Transmission.csv", - )?); + ))?); let mut node = IdealFilter::new("2w Shortpass filter", &fesh0700)?; node.set_aperture(&PortType::Input, "input_1", &a_1inch)?; let filter_2w = group_bs.add_node(node)?; diff --git a/opossum/examples/hhts/hhts_input.rs b/opossum/examples/hhts/hhts_input.rs index c87ba072d8044c2c8ecea0441cbf26d19a665115..7a8044ea13e547a6ac1ec7c29bf48824bd3299f1 100644 --- a/opossum/examples/hhts/hhts_input.rs +++ b/opossum/examples/hhts/hhts_input.rs @@ -1,3 +1,5 @@ +use std::path::Path; + use opossum::{ error::OpmResult, millimeter, @@ -6,15 +8,15 @@ use opossum::{ spectrum::Spectrum, }; pub fn hhts_input() -> OpmResult<NodeGroup> { - let dichroic_mirror = SplittingConfig::Spectrum(Spectrum::from_csv( + let dichroic_mirror = SplittingConfig::Spectrum(Spectrum::from_csv(Path::new( "opossum/examples/hhts/MM15_Transmission.csv", - )?); - let window_filter = FilterType::Spectrum(Spectrum::from_csv( + ))?); + let window_filter = FilterType::Spectrum(Spectrum::from_csv(Path::new( "opossum/examples/hhts/HHTS_W1_Transmission.csv", - )?); - let double_mirror = SplittingConfig::Spectrum(Spectrum::from_csv( + ))?); + let double_mirror = SplittingConfig::Spectrum(Spectrum::from_csv(Path::new( "opossum/examples/hhts/HHTS_T1_PM_Transmission.csv", - )?); + ))?); let mut group = NodeGroup::new("HHTS Input"); let d1 = group.add_node(Dummy::new("d1"))?; let mm15 = group.add_node(BeamSplitter::new("MM15", &dichroic_mirror)?)?; diff --git a/opossum/examples/inverse_beam_splitter_test.rs b/opossum/examples/inverse_beam_splitter_test.rs index f40d79142d6f7edcc3a5da13b8ecc8092bef9d26..aa609df5cd658424ffedb0c2885fc1932708b9fb 100644 --- a/opossum/examples/inverse_beam_splitter_test.rs +++ b/opossum/examples/inverse_beam_splitter_test.rs @@ -2,7 +2,7 @@ use num::Zero; use opossum::{ analyzers::AnalyzerType, error::OpmResult, - lightdata::{DataEnergy, LightData}, + lightdata::{energy_spectrum_builder::EnergyDataBuilder, light_data_builder::LightDataBuilder}, nodes::{BeamSplitter, EnergyMeter, NodeGroup, Source}, optic_node::OpticNode, ray::SplittingConfig, @@ -14,12 +14,9 @@ use uom::si::f64::Length; fn main() -> OpmResult<()> { let mut scenery = NodeGroup::new("inverse beam splitter test"); - let i_s = scenery.add_node(Source::new( - "Source", - &LightData::Energy(DataEnergy { - spectrum: create_he_ne_spec(1.0)?, - }), - ))?; + let light_data_builder = + LightDataBuilder::Energy(EnergyDataBuilder::Raw(create_he_ne_spec(1.0)?)); + let i_s = scenery.add_node(Source::new("Source", light_data_builder))?; let mut bs = BeamSplitter::new("bs", &SplittingConfig::Ratio(0.6)).unwrap(); bs.set_inverted(true)?; let i_bs = scenery.add_node(bs)?; diff --git a/opossum/examples/michaelson.rs b/opossum/examples/michaelson.rs index 90d5b42e1e75d0b14b4c7f046dc78c668e2ef489..9d77f2c81ed57f439e0d30e18e382d14eae967f8 100644 --- a/opossum/examples/michaelson.rs +++ b/opossum/examples/michaelson.rs @@ -2,7 +2,7 @@ use num::Zero; use opossum::{ analyzers::AnalyzerType, error::OpmResult, - lightdata::{DataEnergy, LightData}, + lightdata::{energy_spectrum_builder::EnergyDataBuilder, light_data_builder::LightDataBuilder}, nodes::{BeamSplitter, Dummy, NodeGroup, NodeReference, Source}, spectrum_helper::create_he_ne_spec, OpmDocument, @@ -12,12 +12,9 @@ use uom::si::f64::Length; fn main() -> OpmResult<()> { let mut scenery = NodeGroup::new("Michaelson interferomater"); - let src = scenery.add_node(Source::new( - "Source", - &LightData::Energy(DataEnergy { - spectrum: create_he_ne_spec(1.0)?, - }), - ))?; + let light_data_builder = + LightDataBuilder::Energy(EnergyDataBuilder::Raw(create_he_ne_spec(1.0)?)); + let src = scenery.add_node(Source::new("Source", light_data_builder))?; let bs = scenery.add_node(BeamSplitter::default())?; let sample = scenery.add_node(Dummy::new("Sample"))?; let rf = NodeReference::from_node(&scenery.node(sample)?); diff --git a/opossum/examples/off_center_position_distribution.rs b/opossum/examples/off_center_position_distribution.rs index 4295ad75c04b4fbc5efb497de050dca6e10f46b3..9f11a3caca5ee68f81567b1ad4f25d333848bf53 100644 --- a/opossum/examples/off_center_position_distribution.rs +++ b/opossum/examples/off_center_position_distribution.rs @@ -5,7 +5,7 @@ use opossum::{ energy_distributions::General2DGaussian, error::OpmResult, joule, - lightdata::LightData, + lightdata::{light_data_builder::LightDataBuilder, ray_data_builder::RayDataBuilder}, millimeter, nanometer, nodes::{NodeGroup, Source, SpotDiagram}, optic_node::OpticNode, @@ -54,8 +54,8 @@ fn main() -> OpmResult<()> { let mut rays = rays_1w; rays.add_rays(&mut rays_2w); let mut scenery = NodeGroup::new("test"); - - let mut src = Source::new("Source", &LightData::Geometric(rays)); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays)); + let mut src = Source::new("Source", light_data_builder); src.set_isometry(Isometry::identity())?; let src = scenery.add_node(src)?; let i_sd = scenery.add_node(SpotDiagram::default())?; diff --git a/opossum/examples/prism_dispersion.rs b/opossum/examples/prism_dispersion.rs index 73c11d201cc97e9771abbfe71a1aeb0dc72b896c..a0e5e96eab9e463aff5d2b709c62ec053dc1b2fd 100644 --- a/opossum/examples/prism_dispersion.rs +++ b/opossum/examples/prism_dispersion.rs @@ -6,7 +6,7 @@ use opossum::{ degree, error::OpmResult, joule, - lightdata::LightData, + lightdata::{light_data_builder::LightDataBuilder, ray_data_builder::RayDataBuilder}, millimeter, nanometer, nodes::{NodeGroup, RayPropagationVisualizer, Source, SpotDiagram, Wedge}, optic_node::{Alignable, OpticNode}, @@ -46,8 +46,8 @@ fn main() -> OpmResult<()> { rays_1w.add_rays(&mut rays_2w); let mut scenery = NodeGroup::default(); - let light = LightData::Geometric(rays_1w); - let mut light_src = Source::new("collimated ray source", &light); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays_1w)); + let mut light_src = Source::new("collimated ray source", light_data_builder); light_src.set_isometry(Isometry::identity())?; let src = scenery.add_node(light_src)?; diff --git a/opossum/examples/reference_test.rs b/opossum/examples/reference_test.rs index a5ef3db6759bf5e0f4eced60ee3c628019b04803..e87695dc71fc463646556f5de62021cd1bb704ec 100644 --- a/opossum/examples/reference_test.rs +++ b/opossum/examples/reference_test.rs @@ -2,7 +2,7 @@ use num::Zero; use opossum::{ analyzers::AnalyzerType, error::OpmResult, - lightdata::{DataEnergy, LightData}, + lightdata::{energy_spectrum_builder::EnergyDataBuilder, light_data_builder::LightDataBuilder}, nodes::{EnergyMeter, IdealFilter, NodeGroup, NodeReference, Source}, spectrum_helper::create_he_ne_spec, OpmDocument, @@ -12,12 +12,9 @@ use uom::si::f64::Length; fn main() -> OpmResult<()> { let mut scenery = NodeGroup::new("Reference node demo"); - let src = scenery.add_node(Source::new( - "source", - &LightData::Energy(DataEnergy { - spectrum: create_he_ne_spec(1.0)?, - }), - ))?; + let light_data_builder = + LightDataBuilder::Energy(EnergyDataBuilder::Raw(create_he_ne_spec(1.0)?)); + let src = scenery.add_node(Source::new("source", light_data_builder))?; let filt = scenery.add_node(IdealFilter::new( "50 % filter", &opossum::nodes::FilterType::Constant(0.5), diff --git a/opossum/examples/spectrum_test.rs b/opossum/examples/spectrum_test.rs index 3cca53f7e8b89796156edefffa5b8fc5222e7f1e..471f124be7fddf8f29e27cb5c3cf31bad2cdd4d8 100644 --- a/opossum/examples/spectrum_test.rs +++ b/opossum/examples/spectrum_test.rs @@ -20,7 +20,7 @@ fn main() -> OpmResult<()> { PltBackEnd::SVG, )?; - let s4 = Spectrum::from_csv("./opossum/playground/NE03B.csv")?; + let s4 = Spectrum::from_csv(Path::new("./opossum/playground/NE03B.csv"))?; s4.to_plot( Path::new("./opossum/playground/ne03b_raw.svg"), PltBackEnd::SVG, diff --git a/opossum/examples/two_color_rays.rs b/opossum/examples/two_color_rays.rs index bd0773f36d8e01e9eb9320ca6c011a607116ab7a..e183fd59ad4081265471de39c7a9b4f445ac2060 100644 --- a/opossum/examples/two_color_rays.rs +++ b/opossum/examples/two_color_rays.rs @@ -5,7 +5,7 @@ use opossum::{ analyzers::{AnalyzerType, RayTraceConfig}, error::OpmResult, joule, - lightdata::LightData, + lightdata::{light_data_builder::LightDataBuilder, ray_data_builder::RayDataBuilder}, millimeter, nanometer, nodes::{Lens, NodeGroup, RayPropagationVisualizer, Source, SpotDiagram}, position_distributions::{FibonacciEllipse, Hexapolar}, @@ -38,8 +38,8 @@ fn main() -> OpmResult<()> { rays_1w.add_rays(&mut rays_3w); let mut scenery = NodeGroup::default(); - let light = LightData::Geometric(rays_1w); - let src = scenery.add_node(Source::new("collimated ray source", &light))?; + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays_1w)); + let src = scenery.add_node(Source::new("collimated ray source", light_data_builder))?; let l1 = scenery.add_node(Lens::new( "l1", millimeter!(200.0), diff --git a/opossum/files_for_testing/opm/incorrect_opm.opm b/opossum/files_for_testing/opm/incorrect_opm.opm index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..dd626a0f311e80501dee9549fc8e3d1a2ba3d01f 100644 --- a/opossum/files_for_testing/opm/incorrect_opm.opm +++ b/opossum/files_for_testing/opm/incorrect_opm.opm @@ -0,0 +1 @@ +() \ No newline at end of file diff --git a/opossum/files_for_testing/opm/optic_ref.opm b/opossum/files_for_testing/opm/optic_ref.opm index 796c89f368c3e95bca995a4a780999c18d38f58a..229203014623fb80ed05eebde918eade93711744 100644 --- a/opossum/files_for_testing/opm/optic_ref.opm +++ b/opossum/files_for_testing/opm/optic_ref.opm @@ -1,59 +1,44 @@ -attributes: - node_type: dummy - name: test123 - uuid: 587ee70f-6f52-4420-89f6-e1618ff4dbdb - lidt: 10000. - ports: - inputs: - input_1: - anchor_point_iso: - transform: - rotation: - - 0.0 - - 0.0 - - 0.0 - - 1.0 - translation: - - 0.0 - - 0.0 - - 0.0 - inverse: - rotation: - - 0.0 - - 0.0 - - 0.0 - - 1.0 - translation: - - 0.0 - - 0.0 - - 0.0 - coating: IdealAR - lidt: 10000.0 - outputs: - output_1: - anchor_point_iso: - transform: - rotation: - - 0.0 - - 0.0 - - 0.0 - - 1.0 - translation: - - 0.0 - - 0.0 - - 0.0 - inverse: - rotation: - - 0.0 - - 0.0 - - 0.0 - - 1.0 - translation: - - 0.0 - - 0.0 - - 0.0 - coating: IdealAR - lidt: 10000.0 - inverted: false - props: - \ No newline at end of file +( + attributes: ( + node_type: "dummy", + name: "test123", + ports: ( + inputs: { + "input_1": ( + anchor_point_iso: ( + transform: ( + rotation: (0.0, 0.0, 0.0, 1.0), + translation: (0.0, 0.0, 0.0), + ), + inverse: ( + rotation: (0.0, 0.0, 0.0, 1.0), + translation: (0.0, 0.0, 0.0), + ), + ), + coating: IdealAR, + lidt: 10000.0, + ), + }, + outputs: { + "output_1": ( + anchor_point_iso: ( + transform: ( + rotation: (0.0, 0.0, 0.0, 1.0), + translation: (0.0, 0.0, 0.0), + ), + inverse: ( + rotation: (0.0, 0.0, 0.0, 1.0), + translation: (0.0, 0.0, 0.0), + ), + ), + coating: IdealAR, + lidt: 10000.0, + ), + }, + ), + uuid: "98248e7f-dc4c-4131-8710-f3d5be2ff087", + lidt: 10000.0, + props: {}, + inverted: false, + ), +) \ No newline at end of file diff --git a/opossum/files_for_testing/opm/opticscenery.opm b/opossum/files_for_testing/opm/opticscenery.opm index 8e6dd541b47270fa7e4152f8894f7874366bfeaf..306d0b7b70ead4988c0c8b90417ebf3496349ecf 100644 --- a/opossum/files_for_testing/opm/opticscenery.opm +++ b/opossum/files_for_testing/opm/opticscenery.opm @@ -1,148 +1,129 @@ -opm file version: '0' -scenery: - node_attr: - node_type: group - name: OpticScenery demo - ports: - inputs: {} - outputs: {} - uuid: df1fc497-4e6d-413d-8160-d7facb93aa27 - lidt: 10000.0 - props: - expand view: !Bool false - inverted: false - graph: - nodes: - - attributes: - node_type: dummy - name: dummy1 - ports: - inputs: - input_1: - anchor_point_iso: - transform: - rotation: - - 0.0 - - 0.0 - - 0.0 - - 1.0 - translation: - - 0.0 - - 0.0 - - 0.0 - inverse: - rotation: - - 0.0 - - 0.0 - - 0.0 - - 1.0 - translation: - - 0.0 - - 0.0 - - 0.0 - coating: IdealAR - lidt: 10000.0 - outputs: - output_1: - anchor_point_iso: - transform: - rotation: - - 0.0 - - 0.0 - - 0.0 - - 1.0 - translation: - - 0.0 - - 0.0 - - 0.0 - inverse: - rotation: - - 0.0 - - 0.0 - - 0.0 - - 1.0 - translation: - - 0.0 - - 0.0 - - 0.0 - coating: IdealAR - lidt: 10000.0 - uuid: cc2aa814-61f0-470e-8c66-6d611e4e88a0 - lidt: 10000.0 - props: {} - inverted: false - - attributes: - node_type: dummy - name: dummy2 - ports: - inputs: - input_1: - anchor_point_iso: - transform: - rotation: - - 0.0 - - 0.0 - - 0.0 - - 1.0 - translation: - - 0.0 - - 0.0 - - 0.0 - inverse: - rotation: - - 0.0 - - 0.0 - - 0.0 - - 1.0 - translation: - - 0.0 - - 0.0 - - 0.0 - coating: IdealAR - lidt: 10000.0 - outputs: - output_1: - anchor_point_iso: - transform: - rotation: - - 0.0 - - 0.0 - - 0.0 - - 1.0 - translation: - - 0.0 - - 0.0 - - 0.0 - inverse: - rotation: - - 0.0 - - 0.0 - - 0.0 - - 1.0 - translation: - - 0.0 - - 0.0 - - 0.0 - coating: IdealAR - lidt: 10000.0 - uuid: 9e04cd4d-a09b-4300-addb-987d495ca5e3 - lidt: 10000.0 - props: {} - inverted: false - edges: - - - cc2aa814-61f0-470e-8c66-6d611e4e88a0 - - output_1 - - 9e04cd4d-a09b-4300-addb-987d495ca5e3 - - input_1 - - 0.0 - input_map: {} - output_map: {} -global: - ambient_refr_index: !Const - refractive_index: 1.0 -analyzers: -- !RayTrace - min_energy_per_ray: 1e-12 - max_number_of_bounces: 1000 - max_number_of_refractions: 1000 - missed_surface_strategy: Stop +( + opm_file_version: "0", + scenery: ( + node_attr: ( + node_type: "group", + name: "OpticScenery demo", + ports: ( + inputs: {}, + outputs: {}, + ), + uuid: "1369c599-1750-43c4-8ff8-2ad317507397", + lidt: 10000.0, + props: { + "expand view": Bool(false), + }, + inverted: false, + ), + graph: ( + nodes: [ + ( + attributes: ( + node_type: "dummy", + name: "dummy1", + ports: ( + inputs: { + "input_1": ( + anchor_point_iso: ( + transform: ( + rotation: (0.0, 0.0, 0.0, 1.0), + translation: (0.0, 0.0, 0.0), + ), + inverse: ( + rotation: (0.0, 0.0, 0.0, 1.0), + translation: (0.0, 0.0, 0.0), + ), + ), + coating: IdealAR, + lidt: 10000.0, + ), + }, + outputs: { + "output_1": ( + anchor_point_iso: ( + transform: ( + rotation: (0.0, 0.0, 0.0, 1.0), + translation: (0.0, 0.0, 0.0), + ), + inverse: ( + rotation: (0.0, 0.0, 0.0, 1.0), + translation: (0.0, 0.0, 0.0), + ), + ), + coating: IdealAR, + lidt: 10000.0, + ), + }, + ), + uuid: "f9b965c3-0b5b-4d00-8e83-a435ad5b1f8b", + lidt: 10000.0, + props: {}, + inverted: false, + ), + ), + ( + attributes: ( + node_type: "dummy", + name: "dummy2", + ports: ( + inputs: { + "input_1": ( + anchor_point_iso: ( + transform: ( + rotation: (0.0, 0.0, 0.0, 1.0), + translation: (0.0, 0.0, 0.0), + ), + inverse: ( + rotation: (0.0, 0.0, 0.0, 1.0), + translation: (0.0, 0.0, 0.0), + ), + ), + coating: IdealAR, + lidt: 10000.0, + ), + }, + outputs: { + "output_1": ( + anchor_point_iso: ( + transform: ( + rotation: (0.0, 0.0, 0.0, 1.0), + translation: (0.0, 0.0, 0.0), + ), + inverse: ( + rotation: (0.0, 0.0, 0.0, 1.0), + translation: (0.0, 0.0, 0.0), + ), + ), + coating: IdealAR, + lidt: 10000.0, + ), + }, + ), + uuid: "881bad60-f450-4db5-bf96-098896e1edbe", + lidt: 10000.0, + props: {}, + inverted: false, + ), + ), + ], + edges: [ + ("f9b965c3-0b5b-4d00-8e83-a435ad5b1f8b", "output_1", "881bad60-f450-4db5-bf96-098896e1edbe", "input_1", 0.0), + ], + input_map: ({}), + output_map: ({}), + ), + ), + global: ( + ambient_refr_index: Const(( + refractive_index: 1.0, + )), + ), + analyzers: [ + RayTrace(( + min_energy_per_ray: 0.000000000001, + max_number_of_bounces: 1000, + max_number_of_refractions: 1000, + missed_surface_strategy: Stop, + )), + ], +) \ No newline at end of file diff --git a/opossum/src/analyzers/energy.rs b/opossum/src/analyzers/energy.rs index f8799bb8a9d268ab98a2a907f1b028fa259301be..9a743d2d8f34060775b6bb30c5bbef5330eeff9d 100644 --- a/opossum/src/analyzers/energy.rs +++ b/opossum/src/analyzers/energy.rs @@ -45,11 +45,12 @@ mod test { use super::EnergyAnalyzer; use crate::{ analyzers::Analyzer, - lightdata::{DataEnergy, LightData}, + lightdata::{ + energy_spectrum_builder::EnergyDataBuilder, light_data_builder::LightDataBuilder, + }, nodes::{EnergyMeter, NodeGroup, Source}, spectrum_helper::create_he_ne_spec, }; - #[test] fn analyze_empty_scene() { let mut scenery = NodeGroup::default(); @@ -58,11 +59,9 @@ mod test { } fn create_scene() -> NodeGroup { let mut scenery = NodeGroup::default(); - let data_energy = DataEnergy { - spectrum: create_he_ne_spec(1.0).unwrap(), - }; - let light_data = LightData::Energy(data_energy); - let src = Source::new("source", &light_data); + let light_data_builder = + LightDataBuilder::Energy(EnergyDataBuilder::Raw(create_he_ne_spec(1.0).unwrap())); + let src = Source::new("source", light_data_builder); let i_src = scenery.add_node(src).unwrap(); let i_em = scenery.add_node(EnergyMeter::default()).unwrap(); scenery diff --git a/opossum/src/analyzers/raytrace.rs b/opossum/src/analyzers/raytrace.rs index 316a24eedaf8419a706a072048628cf32f4fd981..5b414500c8bfc09901bd242a1ec0b2deaa2a046b 100644 --- a/opossum/src/analyzers/raytrace.rs +++ b/opossum/src/analyzers/raytrace.rs @@ -271,7 +271,7 @@ pub trait AnalysisRayTrace: OpticNode { degree!(0.) }; - Ok((index_model.value.clone(), *center_thickness, angle)) + Ok((index_model.clone(), *center_thickness, angle)) } } diff --git a/opossum/src/dottable.rs b/opossum/src/dottable.rs index 9424cc8b9f03367a5d08caf5f78ac1c37fdb1576..bdad9bfe5c1c62b970b250c486039509ff86e2d2 100644 --- a/opossum/src/dottable.rs +++ b/opossum/src/dottable.rs @@ -332,7 +332,7 @@ pub trait Dottable { #[cfg(test)] mod test { use crate::{ - lightdata::LightData, + lightdata::light_data_builder::LightDataBuilder, nodes::{BeamSplitter, Dummy, EnergyMeter, Metertype, NodeGroup, Source}, ray::SplittingConfig, }; @@ -381,7 +381,7 @@ mod test { let mut scenery = NodeGroup::default(); let i_s = scenery - .add_node(Source::new("Source", &LightData::Fourier)) + .add_node(Source::new("Source", LightDataBuilder::Fourier)) .unwrap(); let bs = BeamSplitter::new("test", &SplittingConfig::Ratio(0.6)).unwrap(); // bs.node_attr_mut().set_name("Beam splitter"); diff --git a/opossum/src/lightdata/energy_spectrum_builder.rs b/opossum/src/lightdata/energy_spectrum_builder.rs new file mode 100644 index 0000000000000000000000000000000000000000..68f392f43f86b2ee35506ec389eb1b731bd72615 --- /dev/null +++ b/opossum/src/lightdata/energy_spectrum_builder.rs @@ -0,0 +1,52 @@ +//! Builder for the generation of energy spectra. +//! +//! This module provides a builder for the generation of energy spectra to be used in `LightData::Energy`. +//! Using this builder allows easier serialization / deserialization in OPM files. +use crate::{error::OpmResult, spectrum::Spectrum}; +use serde::{Deserialize, Serialize}; +use std::{fmt::Display, path::PathBuf}; +use uom::si::f64::{Energy, Length}; + +use super::{DataEnergy, LightData}; + +/// Builder for the generation of energy spectra. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub enum EnergyDataBuilder { + /// Build a spectrum from raw data. + Raw(Spectrum), + /// Build a spectrum from a (CSV) file. + FromFile(PathBuf), + /// Build a spectrum from a set of (narrow) laser lines (center wavelength, energy) and a given spectrum resolution. + LaserLines(Vec<(Length, Energy)>, Length), +} +impl EnergyDataBuilder { + /// Build the spectrum from the builder. + /// + /// # Errors + /// This function will return an error if the concrete implementation of the builder fails. + pub fn build(&self) -> OpmResult<LightData> { + match self { + Self::Raw(s) => Ok(LightData::Energy(DataEnergy { + spectrum: s.clone(), + })), + Self::FromFile(p) => { + let spectrum = Spectrum::from_csv(p)?; + Ok(LightData::Energy(DataEnergy { spectrum })) + } + Self::LaserLines(l, r) => { + let spectrum = Spectrum::from_laser_lines(l.clone(), *r)?; + Ok(LightData::Energy(DataEnergy { spectrum })) + } + } + } +} + +impl Display for EnergyDataBuilder { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Raw(s) => write!(f, "Raw({s})"), + Self::FromFile(p) => write!(f, "FromFile({})", p.display()), + Self::LaserLines(l, r) => write!(f, "LaserLines({:?}, {})", l, r.value), + } + } +} diff --git a/opossum/src/lightdata/light_data_builder.rs b/opossum/src/lightdata/light_data_builder.rs new file mode 100644 index 0000000000000000000000000000000000000000..fe642e3097194ccdc2f0352d30627aac4dff9df1 --- /dev/null +++ b/opossum/src/lightdata/light_data_builder.rs @@ -0,0 +1,52 @@ +//! Builder for [`LightData`] +//! +//! This module provides a builder for the generation of [`LightData`] to be used in `Source`. +//! This builder allows easier serialization / deserialization in OPM files. +use serde::{Deserialize, Serialize}; +use std::fmt::Display; + +use super::{ + energy_spectrum_builder::EnergyDataBuilder, ray_data_builder::RayDataBuilder, LightData, +}; +use crate::{error::OpmResult, properties::Proptype}; + +/// Builder for the generation of [`LightData`]. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub enum LightDataBuilder { + /// Builder for the generation of [`LightData::Energy`]. + Energy(EnergyDataBuilder), + /// Builder for the generation of [`LightData::Geometric`]. + Geometric(RayDataBuilder), + /// Dummy Fourier + Fourier, +} + +impl LightDataBuilder { + /// Create [`LightData`] from the builder definition. + /// + /// # Errors + /// + /// This function will return an error if the concrete implementation of the builder fails. + pub fn build(self) -> OpmResult<LightData> { + match self { + Self::Energy(e) => e.build(), + Self::Geometric(r) => r.build(), + Self::Fourier => Ok(LightData::Fourier), + } + } +} + +impl Display for LightDataBuilder { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Energy(e) => write!(f, "Energy({e})"), + Self::Geometric(r) => write!(f, "Geometric({r})"), + Self::Fourier => write!(f, "Fourier"), + } + } +} +impl From<Option<LightDataBuilder>> for Proptype { + fn from(value: Option<LightDataBuilder>) -> Self { + Self::LightDataBuilder(value) + } +} diff --git a/opossum/src/lightdata.rs b/opossum/src/lightdata/mod.rs similarity index 84% rename from opossum/src/lightdata.rs rename to opossum/src/lightdata/mod.rs index a7dfddfe2dfea65609a01648c0717752655d0daf..a410ffe8053ad2ca8ed56a6abfe4d52c533daeb3 100644 --- a/opossum/src/lightdata.rs +++ b/opossum/src/lightdata/mod.rs @@ -1,5 +1,9 @@ #![warn(missing_docs)] //! Data structures containing the light information flowing between [`OpticNode`s](crate::optic_node::OpticNode). + +pub mod energy_spectrum_builder; +pub mod light_data_builder; +pub mod ray_data_builder; use crate::{error::OpmResult, joule, nodes::FilterType, rays::Rays, spectrum::Spectrum}; use serde::{Deserialize, Serialize}; use std::fmt::Display; @@ -35,6 +39,7 @@ impl Display for LightData { } } } + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] /// Data structure for storing [`LightData::Energy`] data. /// @@ -63,7 +68,10 @@ impl DataEnergy { } #[cfg(test)] mod test { - use crate::{properties::Proptype, spectrum_helper::create_visible_spec, utils::EnumProxy}; + use crate::{ + lightdata::light_data_builder::LightDataBuilder, properties::Proptype, + spectrum_helper::create_visible_spec, + }; use super::*; use assert_matches::assert_matches; @@ -85,23 +93,9 @@ mod test { fn debug() { assert_eq!(format!("{:?}", LightData::Fourier), "Fourier"); } - // #[test] - // fn export_wrong() { - // assert!(LightData::Fourier.export(Path::new("")).is_err()); - // } #[test] fn from() { - let ld = Proptype::from(EnumProxy::<Option<LightData>> { - value: Some(LightData::Fourier), - }); - assert_matches!(ld, Proptype::LightData(_)); + let ld = Proptype::from(Some(LightDataBuilder::Fourier)); + assert_matches!(ld, Proptype::LightDataBuilder(_)); } - // #[test] - // fn data_energy_pdf_report() { - // assert!(DataEnergy { - // spectrum: create_visible_spec() - // } - // .pdf_report() - // .is_ok()); - // } } diff --git a/opossum/src/lightdata/ray_data_builder.rs b/opossum/src/lightdata/ray_data_builder.rs new file mode 100644 index 0000000000000000000000000000000000000000..5ee4d67b74b2b012be5729795f0356689b4beaf5 --- /dev/null +++ b/opossum/src/lightdata/ray_data_builder.rs @@ -0,0 +1,37 @@ +//! Builder for the generation of [`LightData`]. +//! +//! This module provides a builder for the generation of [`LightData`] to be used in `Source`. +//! This builder allows easier serialization / deserialization in OPM files. +use std::fmt::Display; + +use crate::{error::OpmResult, rays::Rays}; +use serde::{Deserialize, Serialize}; + +use super::LightData; + +/// Builder for the generation of [`LightData::Geometric`]. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub enum RayDataBuilder { + /// Raw [`Rays`] data. + Raw(Rays), +} + +impl RayDataBuilder { + /// Create [`LightData::Geometric`] from the builder definition. + /// + /// # Errors + /// This function will return an error if the concrete implementation of the builder fails. + pub fn build(self) -> OpmResult<LightData> { + match self { + Self::Raw(rays) => Ok(LightData::Geometric(rays)), + } + } +} + +impl Display for RayDataBuilder { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Raw(r) => write!(f, "Raw({r})"), + } + } +} diff --git a/opossum/src/main.rs b/opossum/src/main.rs index 6eedfb168c121faa61921d8347e81cf0c0bbe748..a3c2396c43949e954cc4d28cf55e7a533bcca25c 100644 --- a/opossum/src/main.rs +++ b/opossum/src/main.rs @@ -82,8 +82,12 @@ fn create_report_and_data_files( "yaml", "analysis report", )?; - write!(output, "{}", serde_yaml::to_string(&report).unwrap()) - .map_err(|e| OpossumError::Other(format!("writing report file failed: {e}")))?; + write!( + output, + "{}", + ron::ser::to_string_pretty(&report, ron::ser::PrettyConfig::default()).unwrap() + ) + .map_err(|e| OpossumError::Other(format!("writing report file failed: {e}")))?; let mut report_path = report_directory.to_path_buf(); report.export_data(&report_path)?; report_path.push(format!("report_{report_number}.html")); diff --git a/opossum/src/nodes/beam_splitter/mod.rs b/opossum/src/nodes/beam_splitter/mod.rs index 7405a9b16c2555deb6d4edb4c5d9126edae2c31c..9e90c3c8868ac7ec26a40d320ffd0aede923e406 100644 --- a/opossum/src/nodes/beam_splitter/mod.rs +++ b/opossum/src/nodes/beam_splitter/mod.rs @@ -16,7 +16,7 @@ use crate::{ rays::Rays, spectrum::{merge_spectra, Spectrum}, surface::{geo_surface::GeoSurfaceRef, Plane}, - utils::{geom_transformation::Isometry, EnumProxy}, + utils::geom_transformation::Isometry, }; use opm_macros_lib::OpmNode; use std::sync::{Arc, Mutex}; @@ -51,10 +51,7 @@ impl Default for BeamSplitter { .create_property( "splitter config", "config data of the beam splitter", - EnumProxy::<SplittingConfig> { - value: SplittingConfig::Ratio(0.5), - } - .into(), + SplittingConfig::Ratio(0.5).into(), ) .unwrap(); let mut bs = Self { node_attr }; @@ -75,13 +72,8 @@ impl BeamSplitter { } let mut bs = Self::default(); bs.node_attr.set_name(name); - bs.node_attr.set_property( - "splitter config", - EnumProxy::<SplittingConfig> { - value: config.clone(), - } - .into(), - )?; + bs.node_attr + .set_property("splitter config", config.clone().into())?; bs.update_surfaces()?; Ok(bs) } @@ -93,7 +85,7 @@ impl BeamSplitter { #[must_use] pub fn splitting_config(&self) -> SplittingConfig { if let Ok(Proptype::SplitterType(config)) = self.node_attr.get_property("splitter config") { - return config.value.clone(); + return config.clone(); } panic!("property `splitter config` does not exist or has wrong data format") } @@ -102,13 +94,8 @@ impl BeamSplitter { /// # Errors /// This function returns an [`OpossumError::Other`] if the [`SplittingConfig`] is invalid. pub fn set_splitting_config(&mut self, config: &SplittingConfig) -> OpmResult<()> { - self.node_attr.set_property( - "splitter config", - EnumProxy::<SplittingConfig> { - value: config.clone(), - } - .into(), - )?; + self.node_attr + .set_property("splitter config", config.clone().into())?; Ok(()) } fn split_spectrum( @@ -222,7 +209,7 @@ impl BeamSplitter { )); } - let split_rays = rays.split(&splitting_config.value)?; + let split_rays = rays.split(&splitting_config)?; (rays, split_rays) } _ => { @@ -251,7 +238,7 @@ impl BeamSplitter { return Err(OpossumError::OpticPort("input aperture not found".into())); }; - let split_rays = rays.split(&splitting_config.value)?; + let split_rays = rays.split(&splitting_config)?; (rays, split_rays) } else { return Err(OpossumError::OpticPort( diff --git a/opossum/src/nodes/cylindric_lens/mod.rs b/opossum/src/nodes/cylindric_lens/mod.rs index d4fe9ce3f26f3ecf01288dab1e19cba7f3e2a052..0271bc1213244cbe2edd9693d89f8ef2f3f76f01 100644 --- a/opossum/src/nodes/cylindric_lens/mod.rs +++ b/opossum/src/nodes/cylindric_lens/mod.rs @@ -11,7 +11,7 @@ use crate::{ radian, refractive_index::{RefrIndexConst, RefractiveIndex, RefractiveIndexType}, surface::{geo_surface::GeoSurfaceRef, Cylinder, Plane}, - utils::{geom_transformation::Isometry, EnumProxy}, + utils::geom_transformation::Isometry, }; #[cfg(feature = "bevy")] use bevy::{math::primitives::Cuboid, render::mesh::Mesh}; @@ -81,10 +81,7 @@ impl Default for CylindricLens { .create_property( "refractive index", "refractive index of the lens material", - EnumProxy::<RefractiveIndexType> { - value: RefractiveIndexType::Const(RefrIndexConst::new(1.5).unwrap()), - } - .into(), + RefractiveIndexType::Const(RefrIndexConst::new(1.5).unwrap()).into(), ) .unwrap(); let mut cyl_lens = Self { node_attr }; @@ -139,13 +136,9 @@ impl CylindricLens { .node_attr .set_property("center thickness", center_thickness.into())?; - cyl_lens.node_attr.set_property( - "refractive index", - EnumProxy::<RefractiveIndexType> { - value: refractive_index.to_enum(), - } - .into(), - )?; + cyl_lens + .node_attr + .set_property("refractive index", refractive_index.to_enum().into())?; cyl_lens.update_surfaces()?; Ok(cyl_lens) } @@ -285,10 +278,7 @@ mod test { else { panic!() }; - assert_eq!( - (*index).value.get_refractive_index(Length::zero()).unwrap(), - 1.5 - ); + assert_eq!((*index).get_refractive_index(Length::zero()).unwrap(), 1.5); } #[test] fn new() { @@ -334,9 +324,8 @@ mod test { panic!() }; assert_eq!(*roc, millimeter!(11.0)); - let Ok(Proptype::RefractiveIndex(EnumProxy::<RefractiveIndexType> { - value: RefractiveIndexType::Const(ref_index_const), - })) = node.node_attr.get_property("refractive index") + let Ok(Proptype::RefractiveIndex(RefractiveIndexType::Const(ref_index_const))) = + node.node_attr.get_property("refractive index") else { panic!() }; diff --git a/opossum/src/nodes/ideal_filter.rs b/opossum/src/nodes/ideal_filter.rs index 02ad7bfccda0fead355243e5abc7d80450af4168..af8fda9a51adc9070a00208d638d6e555aef0bfd 100644 --- a/opossum/src/nodes/ideal_filter.rs +++ b/opossum/src/nodes/ideal_filter.rs @@ -13,7 +13,6 @@ use crate::{ properties::Proptype, rays::Rays, spectrum::Spectrum, - utils::EnumProxy, }; use opm_macros_lib::OpmNode; use serde::{Deserialize, Serialize}; @@ -26,6 +25,11 @@ pub enum FilterType { /// filter based on given transmission spectrum. Spectrum(Spectrum), } +impl From<FilterType> for Proptype { + fn from(f: FilterType) -> Self { + Self::FilterType(f) + } +} #[derive(OpmNode, Debug, Clone)] #[opm_node("darkgray")] /// An ideal filter with given transmission or optical density. @@ -53,10 +57,7 @@ impl Default for IdealFilter { .create_property( "filter type", "used filter algorithm", - EnumProxy::<FilterType> { - value: FilterType::Constant(1.0), - } - .into(), + FilterType::Constant(1.0).into(), ) .unwrap(); let mut idf = Self { node_attr }; @@ -80,13 +81,9 @@ impl IdealFilter { } } let mut filter = Self::default(); - filter.node_attr.set_property( - "filter type", - EnumProxy::<FilterType> { - value: filter_type.clone(), - } - .into(), - )?; + filter + .node_attr + .set_property("filter type", filter_type.clone().into())?; filter.node_attr.set_name(name); Ok(filter) } @@ -99,7 +96,7 @@ impl IdealFilter { if let Proptype::FilterType(filter_type) = self.node_attr.get_property("filter type").unwrap() { - filter_type.value.clone() + filter_type.clone() } else { panic!("wrong data type") } @@ -112,13 +109,8 @@ impl IdealFilter { /// This function will return an error if a transmission factor > 1.0 is given (This would be an amplifiying filter :-) ). pub fn set_transmission(&mut self, transmission: f64) -> OpmResult<()> { if (0.0..=1.0).contains(&transmission) { - self.node_attr.set_property( - "filter type", - EnumProxy::<FilterType> { - value: FilterType::Constant(transmission), - } - .into(), - )?; + self.node_attr + .set_property("filter type", FilterType::Constant(transmission).into())?; Ok(()) } else { Err(OpossumError::Other( @@ -136,10 +128,7 @@ impl IdealFilter { if density >= 0.0 { self.node_attr.set_property( "filter type", - EnumProxy::<FilterType> { - value: FilterType::Constant(f64::powf(10.0, -1.0 * density)), - } - .into(), + FilterType::Constant(f64::powf(10.0, -1.0 * density)).into(), )?; Ok(()) } else { diff --git a/opossum/src/nodes/lens/mod.rs b/opossum/src/nodes/lens/mod.rs index eda4c73a1957adbe9daa7bdf7e4f8cd6be5fdf2a..becc5f93a9b7a83106bb3020c7e31dde3a39ffb4 100644 --- a/opossum/src/nodes/lens/mod.rs +++ b/opossum/src/nodes/lens/mod.rs @@ -11,7 +11,7 @@ use crate::{ radian, refractive_index::{RefrIndexConst, RefractiveIndex, RefractiveIndexType}, surface::{geo_surface::GeoSurfaceRef, Plane, Sphere}, - utils::{geom_transformation::Isometry, EnumProxy}, + utils::geom_transformation::Isometry, }; #[cfg(feature = "bevy")] use bevy::{math::primitives::Cuboid, render::mesh::Mesh}; @@ -80,10 +80,7 @@ impl Default for Lens { .create_property( "refractive index", "refractive index of the lens material", - EnumProxy::<RefractiveIndexType> { - value: RefractiveIndexType::Const(RefrIndexConst::new(1.5).unwrap()), - } - .into(), + RefractiveIndexType::Const(RefrIndexConst::new(1.5).unwrap()).into(), ) .unwrap(); let mut lens = Self { node_attr }; @@ -133,13 +130,8 @@ impl Lens { lens.node_attr .set_property("center thickness", center_thickness.into())?; - lens.node_attr.set_property( - "refractive index", - EnumProxy::<RefractiveIndexType> { - value: refractive_index.to_enum(), - } - .into(), - )?; + lens.node_attr + .set_property("refractive index", refractive_index.to_enum().into())?; lens.update_surfaces()?; Ok(lens) } @@ -377,10 +369,7 @@ mod test { else { panic!() }; - assert_eq!( - (*index).value.get_refractive_index(Length::zero()).unwrap(), - 1.5 - ); + assert_eq!((*index).get_refractive_index(Length::zero()).unwrap(), 1.5); } #[test] fn new() { @@ -416,9 +405,8 @@ mod test { panic!() }; assert_eq!(*roc, millimeter!(11.0)); - let Ok(Proptype::RefractiveIndex(EnumProxy::<RefractiveIndexType> { - value: RefractiveIndexType::Const(ref_index_const), - })) = node.node_attr.get_property("refractive index") + let Ok(Proptype::RefractiveIndex(RefractiveIndexType::Const(ref_index_const))) = + node.node_attr.get_property("refractive index") else { panic!() }; diff --git a/opossum/src/nodes/node_group/mod.rs b/opossum/src/nodes/node_group/mod.rs index 5e8f955c525e08ad40904e22f65ac314f8a0ed0c..eb72e85290e722cc0e1cbafcf0bdb99ce88cc366 100644 --- a/opossum/src/nodes/node_group/mod.rs +++ b/opossum/src/nodes/node_group/mod.rs @@ -8,7 +8,9 @@ use crate::{ analyzers::Analyzable, dottable::Dottable, error::{OpmResult, OpossumError}, - lightdata::LightData, + lightdata::{ + light_data_builder::LightDataBuilder, ray_data_builder::RayDataBuilder, LightData, + }, optic_node::OpticNode, optic_ports::{OpticPorts, PortType}, optic_ref::OpticRef, @@ -16,7 +18,6 @@ use crate::{ rays::Rays, reporting::{analysis_report::AnalysisReport, node_report::NodeReport}, surface::optic_surface::OpticSurface, - utils::EnumProxy, SceneryResources, }; use num::Zero; @@ -178,23 +179,18 @@ impl NodeGroup { }; let node_props = node_props.clone(); drop(node); - if let Proptype::LightData(ld) = node_props { - if let Some(LightData::Geometric(rays)) = &ld.value { - let mut new_rays = rays.clone(); - new_rays.set_node_origin_uuid(node_id); + if let Proptype::LightData(Some(LightData::Geometric(rays))) = node_props { + let mut new_rays = rays; + new_rays.set_node_origin_uuid(node_id); - let mut node_ref = node_ref - .optical_ref - .lock() - .map_err(|_| OpossumError::Other("Mutex lock failed".to_string()))?; - node_ref.node_attr_mut().set_property( - "light data", - EnumProxy::<Option<LightData>> { - value: Some(LightData::Geometric(new_rays)), - } - .into(), - )?; - } + let mut node_ref = node_ref + .optical_ref + .lock() + .map_err(|_| OpossumError::Other("Mutex lock failed".to_string()))?; + node_ref.node_attr_mut().set_property( + "light data", + Some(LightDataBuilder::Geometric(RayDataBuilder::Raw(new_rays))).into(), + )?; } Ok(()) } @@ -655,7 +651,7 @@ mod test { analyzers::{energy::AnalysisEnergy, raytrace::AnalysisRayTrace, RayTraceConfig}, joule, light_result::LightResult, - lightdata::LightData, + lightdata::{light_data_builder::LightDataBuilder, ray_data_builder::RayDataBuilder}, millimeter, nanometer, nodes::{test_helper::test_helper::*, Dummy, EnergyMeter, Source}, optic_node::OpticNode, @@ -737,7 +733,7 @@ mod test { let mut scenery = NodeGroup::default(); scenery.add_node(Dummy::default()).unwrap(); let report = scenery.toplevel_report().unwrap(); - assert!(serde_yaml::to_string(&report).is_ok()); + assert!(ron::ser::to_string_pretty(&report, ron::ser::PrettyConfig::default()).is_ok()); // How shall we further parse the output? } #[test] @@ -771,8 +767,9 @@ mod test { Ray::new_collimated(millimeter!(0., 0., 0.), nanometer!(1053.0), joule!(0.1)).unwrap(), ); let mut scenery = NodeGroup::default(); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays)); let i_s = scenery - .add_node(Source::new("src", &LightData::Geometric(rays))) + .add_node(Source::new("src", light_data_builder)) .unwrap(); let mut em = EnergyMeter::default(); em.set_isometry(Isometry::identity()).unwrap(); diff --git a/opossum/src/nodes/node_group/optic_graph.rs b/opossum/src/nodes/node_group/optic_graph.rs index de21a4e00c07f310ec3f249c0be1bbcc36657dc6..772e6e9f475cf65ad114aa3874f63b39cd6fb5cc 100644 --- a/opossum/src/nodes/node_group/optic_graph.rs +++ b/opossum/src/nodes/node_group/optic_graph.rs @@ -1647,8 +1647,9 @@ mod test { graph.port_map(&PortType::Input).port_names(), vec!["input_1", "input_2"] ); - let serialized = serde_yaml::to_string(&graph).unwrap(); - let deserialized: OpticGraph = serde_yaml::from_str(&serialized).unwrap(); + let serialized = + ron::ser::to_string_pretty(&graph, ron::ser::PrettyConfig::default()).unwrap(); + let deserialized: OpticGraph = ron::from_str(&serialized).unwrap(); assert_eq!( deserialized.port_map(&PortType::Input).port_names(), vec!["input_1", "input_2"] diff --git a/opossum/src/nodes/source.rs b/opossum/src/nodes/source.rs index ff3e4637eb78591fea2b8667e6d5e60cb95cc6e0..b8c1fefd5c6fd22254c37b6140a6c739fcb76667 100644 --- a/opossum/src/nodes/source.rs +++ b/opossum/src/nodes/source.rs @@ -14,14 +14,13 @@ use crate::{ error::{OpmResult, OpossumError}, joule, light_result::{LightRays, LightResult}, - lightdata::LightData, + lightdata::{light_data_builder::LightDataBuilder, LightData}, millimeter, optic_node::OpticNode, optic_ports::PortType, properties::Proptype, ray::Ray, rays::Rays, - utils::EnumProxy, }; use std::fmt::Debug; @@ -54,7 +53,7 @@ impl Default for Source { .create_property( "light data", "data of the emitted light", - EnumProxy::<Option<LightData>> { value: None }.into(), + Option::<LightDataBuilder>::None.into(), ) .unwrap(); @@ -83,25 +82,20 @@ impl Source { /// /// ```rust /// use opossum::{ - /// lightdata::{DataEnergy, LightData}, + /// lightdata::{light_data_builder::LightDataBuilder, energy_spectrum_builder::EnergyDataBuilder}, /// nodes::Source, /// spectrum_helper::create_he_ne_spec}; /// - /// let source=Source::new("My Source", &LightData::Energy(DataEnergy {spectrum: create_he_ne_spec(1.0).unwrap()})); + /// let light_data_builder = LightDataBuilder::Energy(EnergyDataBuilder::Raw(create_he_ne_spec(1.0).unwrap())); + /// let source=Source::new("My Source", light_data_builder); /// ``` #[must_use] - pub fn new(name: &str, light: &LightData) -> Self { + pub fn new(name: &str, light_data_builder: LightDataBuilder) -> Self { let mut source = Self::default(); source.node_attr.set_name(name); source .node_attr - .set_property( - "light data", - EnumProxy::<Option<LightData>> { - value: Some(light.clone()), - } - .into(), - ) + .set_property("light data", Some(light_data_builder).into()) .unwrap(); source.update_surfaces().unwrap(); source @@ -122,29 +116,24 @@ impl Source { .set_property("alignment wavelength", Proptype::LengthOption(Some(wvl))) } - /// Sets the light data of this [`Source`]. The [`LightData`] provided here represents the input data of an `OpticScenery`. + /// Sets the light data builder of this [`Source`]. The [`LightData`] provided here represents the input data of an `OpticScenery`. /// /// # Attributes - /// * `light_data`: [`LightData`] that shall be set + /// * `light_data_builder`: [`LightDataBuilder`] that shall be set /// /// # Errors /// This function returns an error if the property "light data" can not be set - pub fn set_light_data(&mut self, light_data: &LightData) -> OpmResult<()> { - self.node_attr.set_property( - "light data", - EnumProxy::<Option<LightData>> { - value: Some(light_data.clone()), - } - .into(), - )?; + pub fn set_light_data(&mut self, light_data_builder: LightDataBuilder) -> OpmResult<()> { + self.node_attr + .set_property("light data", Some(light_data_builder).into())?; Ok(()) } } impl Debug for Source { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let light_prop = self.node_attr.get_property("light data").unwrap(); - let data = if let Proptype::LightData(data) = &light_prop { - &data.value + let data = if let Proptype::LightDataBuilder(data) = &light_prop { + data } else { &None }; @@ -170,10 +159,14 @@ impl OpticNode for Source { } impl AnalysisEnergy for Source { fn analyze(&mut self, _incoming_data: LightResult) -> OpmResult<LightResult> { - if let Ok(Proptype::LightData(data)) = self.node_attr.get_property("light data") { - let Some(data) = data.value.clone() else { + if let Ok(Proptype::LightDataBuilder(light_data_builder)) = + self.node_attr.get_property("light data") + { + let data = if let Some(light_data_builder) = light_data_builder.clone() { + light_data_builder.build()? + } else { return Err(OpossumError::Analysis( - "source has empty light data defined".into(), + "source has empty light data builder".into(), )); }; Ok(LightResult::from([("output_1".into(), data)])) @@ -190,10 +183,14 @@ impl AnalysisRayTrace for Source { _incoming_edges: LightResult, config: &RayTraceConfig, ) -> OpmResult<LightResult> { - if let Ok(Proptype::LightData(data)) = self.node_attr.get_property("light data") { - let Some(mut data) = data.value.clone() else { + if let Ok(Proptype::LightDataBuilder(light_data_builder)) = + self.node_attr.get_property("light data") + { + let mut data = if let Some(lightdata_builder) = light_data_builder.clone() { + lightdata_builder.build()? + } else { return Err(OpossumError::Analysis( - "source has empty light data defined".into(), + "source has empty light data builder".into(), )); }; if let LightData::Geometric(rays) = &mut data { @@ -269,10 +266,14 @@ impl AnalysisGhostFocus for Source { }; bouncing_rays.clone() } else if bounce_lvl == 0 { - if let Ok(Proptype::LightData(data)) = self.node_attr.get_property("light data") { - let Some(mut data) = data.value.clone() else { + if let Ok(Proptype::LightDataBuilder(light_data_builder)) = + self.node_attr.get_property("light data") + { + let mut data = if let Some(lightdata_builder) = light_data_builder.clone() { + lightdata_builder.build()? + } else { return Err(OpossumError::Analysis( - "source has empty light data defined".into(), + "source has empty light data builder".into(), )); }; if let LightData::Geometric(rays) = &mut data { @@ -317,8 +318,12 @@ impl AnalysisGhostFocus for Source { mod test { use super::*; use crate::{ - lightdata::DataEnergy, nanometer, optic_ports::PortType, position_distributions::Hexapolar, - spectrum_helper::create_he_ne_spec, utils::geom_transformation::Isometry, + lightdata::{energy_spectrum_builder::EnergyDataBuilder, ray_data_builder::RayDataBuilder}, + nanometer, + optic_ports::PortType, + position_distributions::Hexapolar, + spectrum_helper::create_he_ne_spec, + utils::geom_transformation::Isometry, }; use assert_matches::assert_matches; use core::f64; @@ -328,8 +333,8 @@ mod test { let mut node = Source::default(); assert_eq!(node.name(), "source"); assert_eq!(node.node_type(), "source"); - if let Ok(Proptype::LightData(light_data)) = node.properties().get("light data") { - assert_eq!(light_data.value, None); + if let Ok(Proptype::LightDataBuilder(light_data)) = node.properties().get("light data") { + assert!(light_data.is_none()); } else { panic!("cannot unpack light data property"); }; @@ -339,7 +344,7 @@ mod test { } #[test] fn new() { - let source = Source::new("test", &LightData::Fourier); + let source = Source::new("test", LightDataBuilder::Fourier); assert_eq!(source.name(), "test"); } #[test] @@ -392,12 +397,14 @@ mod test { #[test] fn test_set_light_data() { let mut src = Source::default(); - if let Ok(Proptype::LightData(light_data)) = src.properties().get("light data") { - assert_eq!(light_data.value, None); + if let Proptype::LightDataBuilder(light_data) = src.properties().get("light data").unwrap() + { + assert!(light_data.is_none()); } - src.set_light_data(&LightData::Fourier).unwrap(); - if let Ok(Proptype::LightData(light_data)) = src.properties().get("light data") { - assert_matches!(light_data.value.clone().unwrap(), LightData::Fourier); + src.set_light_data(LightDataBuilder::Fourier).unwrap(); + if let Proptype::LightDataBuilder(light_data) = src.properties().get("light data").unwrap() + { + assert_matches!(light_data.clone().unwrap(), LightDataBuilder::Fourier); } } #[test] @@ -408,17 +415,16 @@ mod test { } #[test] fn analyze_energy_ok() { - let light = LightData::Energy(DataEnergy { - spectrum: create_he_ne_spec(1.0).unwrap(), - }); - let mut node = Source::new("test", &light); + let light_builder = + LightDataBuilder::Energy(EnergyDataBuilder::Raw(create_he_ne_spec(1.0).unwrap())); + let mut node = Source::new("test", light_builder.clone()); let output = AnalysisEnergy::analyze(&mut node, LightResult::default()).unwrap(); assert!(output.contains_key("output_1")); assert_eq!(output.len(), 1); let output = output.get("output_1"); assert!(output.is_some()); let output = output.clone().unwrap(); - assert_eq!(*output, light); + assert_eq!(*output, light_builder.build().unwrap()); } #[test] fn analyze_raytrace_no_light_defined() { @@ -431,7 +437,7 @@ mod test { ); assert_eq!( output.unwrap_err(), - OpossumError::Analysis("source has empty light data defined".into()) + OpossumError::Analysis("source has empty light data builder".into()) ); } #[test] @@ -444,7 +450,8 @@ mod test { &Hexapolar::new(millimeter!(1.0), 1).unwrap(), ) .unwrap(); - node.set_light_data(&LightData::Geometric(rays)).unwrap(); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays)); + node.set_light_data(light_data_builder).unwrap(); let output = AnalysisRayTrace::analyze( &mut node, LightResult::default(), @@ -457,8 +464,8 @@ mod test { let mut node = Source::default(); node.set_isometry(Isometry::identity()).unwrap(); node.set_alignment_wavelength(nanometer!(630.0)).unwrap(); - node.set_light_data(&LightData::Geometric(Rays::default())) - .unwrap(); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(Rays::default())); + node.set_light_data(light_data_builder).unwrap(); let output = AnalysisRayTrace::calc_node_positions( &mut node, LightResult::default(), @@ -487,7 +494,7 @@ mod test { ); assert_eq!( output.unwrap_err(), - OpossumError::Analysis("source has empty light data defined".into()) + OpossumError::Analysis("source has empty light data builder".into()) ); } #[test] @@ -500,8 +507,8 @@ mod test { &Hexapolar::new(millimeter!(1.0), 1).unwrap(), ) .unwrap(); - node.set_light_data(&LightData::Geometric(rays.clone())) - .unwrap(); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays.clone())); + node.set_light_data(light_data_builder).unwrap(); let mut light_rays = LightRays::new(); light_rays.insert("input_1".into(), vec![rays]); let output = AnalysisGhostFocus::analyze( @@ -517,8 +524,8 @@ mod test { fn debug() { assert_eq!(format!("{:?}", Source::default()), "Source: no data"); assert_eq!( - format!("{:?}", Source::new("hallo", &LightData::Fourier)), - "Source: No display defined for this type of LightData" + format!("{:?}", Source::new("hallo", LightDataBuilder::Fourier)), + "Source: Fourier" ); } } diff --git a/opossum/src/nodes/source_helper.rs b/opossum/src/nodes/source_helper.rs index 5ee5db38b015864804ad70560d8b506aefe3d9f1..72a5875ef07a8f99015bf09020a9a1f84d346f39 100644 --- a/opossum/src/nodes/source_helper.rs +++ b/opossum/src/nodes/source_helper.rs @@ -3,7 +3,7 @@ use super::Source; use crate::{ error::OpmResult, - lightdata::LightData, + lightdata::{light_data_builder::LightDataBuilder, ray_data_builder::RayDataBuilder}, nanometer, optic_node::OpticNode, position_distributions::{Grid, Hexapolar}, @@ -34,8 +34,8 @@ pub fn round_collimated_ray_source( energy, &Hexapolar::new(radius, nr_of_rings)?, )?; - let light = LightData::Geometric(rays); - let mut src = Source::new("collimated ray source", &light); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays)); + let mut src = Source::new("collimated line ray source", light_data_builder); src.set_isometry(Isometry::identity())?; Ok(src) } @@ -60,8 +60,8 @@ pub fn collimated_line_ray_source( energy, &Grid::new((Length::zero(), size_y), (1, nr_of_points_y))?, )?; - let light = LightData::Geometric(rays); - let mut src = Source::new("collimated line ray source", &light); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays)); + let mut src = Source::new("collimated line ray source", light_data_builder); src.set_isometry(Isometry::identity())?; Ok(src) } @@ -84,15 +84,18 @@ pub fn point_ray_source(cone_angle: Angle, energy: Energy) -> OpmResult<Source> nanometer!(1000.0), energy, )?; - let light = LightData::Geometric(rays); - let mut src = Source::new("point ray source", &light); + let light_data_builder = LightDataBuilder::Geometric(RayDataBuilder::Raw(rays)); + let mut src = Source::new("point ray source", light_data_builder); src.set_isometry(Isometry::identity())?; Ok(src) } #[cfg(test)] mod test { use super::*; - use crate::{degree, joule, millimeter, optic_node::OpticNode, properties::Proptype, ray::Ray}; + use crate::{ + degree, joule, lightdata::LightData, millimeter, optic_node::OpticNode, + properties::Proptype, ray::Ray, + }; use approx::assert_abs_diff_eq; use uom::si::energy::joule; #[test] @@ -102,8 +105,11 @@ mod test { assert!(round_collimated_ray_source(millimeter!(1.0), joule!(f64::INFINITY), 3).is_err()); assert!(round_collimated_ray_source(millimeter!(-0.1), joule!(1.0), 3).is_err()); let src = round_collimated_ray_source(Length::zero(), joule!(1.0), 3).unwrap(); - if let Proptype::LightData(light_data) = src.properties().get("light data").unwrap() { - if let Some(LightData::Geometric(rays)) = &light_data.value { + if let Proptype::LightDataBuilder(light_data_builder) = + src.properties().get("light data").unwrap() + { + let data = light_data_builder.clone().unwrap().build().unwrap(); + if let LightData::Geometric(rays) = data { assert_eq!(rays.nr_of_rays(true), 1); assert_abs_diff_eq!( rays.total_energy().get::<joule>(), @@ -117,8 +123,11 @@ mod test { panic!("property light data has wrong type"); } let src = round_collimated_ray_source(millimeter!(1.0), joule!(1.0), 3).unwrap(); - if let Proptype::LightData(data) = src.properties().get("light data").unwrap() { - if let Some(LightData::Geometric(rays)) = &data.value { + if let Proptype::LightDataBuilder(light_data_builder) = + src.properties().get("light data").unwrap() + { + let data = light_data_builder.clone().unwrap().build().unwrap(); + if let LightData::Geometric(rays) = data { assert_abs_diff_eq!( rays.total_energy().get::<joule>(), 1.0, @@ -138,8 +147,11 @@ mod test { assert!(point_ray_source(degree!(180.0), Energy::zero()).is_err()); assert!(point_ray_source(degree!(190.0), Energy::zero()).is_err()); let src = point_ray_source(Angle::zero(), joule!(1.0)).unwrap(); - if let Proptype::LightData(data) = src.properties().get("light data").unwrap() { - if let Some(LightData::Geometric(rays)) = &data.value { + if let Proptype::LightDataBuilder(light_data_builder) = + src.properties().get("light data").unwrap() + { + let data = light_data_builder.clone().unwrap().build().unwrap(); + if let LightData::Geometric(rays) = &data { assert_abs_diff_eq!( rays.total_energy().get::<joule>(), 1.0, @@ -154,7 +166,7 @@ mod test { } let src = point_ray_source(degree!(1.0), joule!(1.0)).unwrap(); if let Proptype::LightData(data) = src.properties().get("light data").unwrap() { - if let Some(LightData::Geometric(rays)) = &data.value { + if let Some(LightData::Geometric(rays)) = &data { assert_abs_diff_eq!( rays.total_energy().get::<joule>(), 1.0, @@ -180,7 +192,7 @@ mod test { let s = collimated_line_ray_source(millimeter!(1.0), joule!(1.0), 2).unwrap(); if let Proptype::LightData(data) = s.properties().get("light data").unwrap() { - if let Some(LightData::Geometric(rays)) = &data.value { + if let Some(LightData::Geometric(rays)) = &data { assert_abs_diff_eq!( rays.total_energy().get::<joule>(), 1.0, diff --git a/opossum/src/nodes/wavefront.rs b/opossum/src/nodes/wavefront.rs index 651344f1c7e68650426e9a5f07c32d268327c3db..40708e0b6e25529b6f3ad1732d37358e3fa52c53 100644 --- a/opossum/src/nodes/wavefront.rs +++ b/opossum/src/nodes/wavefront.rs @@ -380,10 +380,12 @@ mod test_wavefront_error_map { #[cfg(test)] mod test { use super::*; + + use crate::lightdata::DataEnergy; use crate::optic_ports::PortType; use crate::utils::geom_transformation::Isometry; use crate::{ - analyzers::RayTraceConfig, joule, lightdata::DataEnergy, millimeter, nanometer, + analyzers::RayTraceConfig, joule, millimeter, nanometer, nodes::test_helper::test_helper::*, position_distributions::Hexapolar, rays::Rays, spectrum_helper::create_he_ne_spec, }; diff --git a/opossum/src/nodes/wedge/mod.rs b/opossum/src/nodes/wedge/mod.rs index 76ce3e417d622578dfb520957061faf5b6f6463a..83a460e497f4e83ec3c05a58d847c358a2a322c1 100644 --- a/opossum/src/nodes/wedge/mod.rs +++ b/opossum/src/nodes/wedge/mod.rs @@ -9,7 +9,7 @@ use crate::{ properties::Proptype, refractive_index::{RefrIndexConst, RefractiveIndex, RefractiveIndexType}, surface::{geo_surface::GeoSurfaceRef, Plane}, - utils::{geom_transformation::Isometry, EnumProxy}, + utils::geom_transformation::Isometry, }; use nalgebra::Point3; use num::Zero; @@ -60,10 +60,7 @@ impl Default for Wedge { .create_property( "refractive index", "refractive index of the lens material", - EnumProxy::<RefractiveIndexType> { - value: RefractiveIndexType::Const(RefrIndexConst::new(1.5).unwrap()), - } - .into(), + RefractiveIndexType::Const(RefrIndexConst::new(1.5).unwrap()).into(), ) .unwrap(); node_attr @@ -100,13 +97,9 @@ impl Wedge { .node_attr .set_property("center thickness", center_thickness.into())?; - wedge.node_attr.set_property( - "refractive index", - EnumProxy::<RefractiveIndexType> { - value: refractive_index.to_enum(), - } - .into(), - )?; + wedge + .node_attr + .set_property("refractive index", refractive_index.to_enum().into())?; if !wedge_angle.is_finite() || wedge_angle.get::<degree>().abs() > 90.0 { return Err(crate::error::OpossumError::Other( "wedge angle must be within the interval ]-90 deg; 90 deg[ and finite".into(), @@ -209,7 +202,7 @@ mod test { assert!(false, "could not read angle."); } if let Ok(Proptype::RefractiveIndex(p)) = node.properties().get("refractive index") { - if let RefractiveIndexType::Const(val) = &p.value { + if let RefractiveIndexType::Const(val) = &p { let idx = val.get_refractive_index(nanometer!(1000.0)).unwrap(); assert_eq!(idx, 1.5); } else { @@ -318,7 +311,7 @@ mod test { assert!(false, "could not read angle."); } if let Ok(Proptype::RefractiveIndex(p)) = n.properties().get("refractive index") { - if let RefractiveIndexType::Const(val) = &p.value { + if let RefractiveIndexType::Const(val) = &p { let idx = val.get_refractive_index(nanometer!(1000.0)).unwrap(); assert_eq!(idx, 1.0); } else { diff --git a/opossum/src/opm_document.rs b/opossum/src/opm_document.rs index 5a54846b9927830312daae5cceaacdd92b1d3d8b..3eb361ee2e080c51e831ca88ee77335bc8b54ea9 100644 --- a/opossum/src/opm_document.rs +++ b/opossum/src/opm_document.rs @@ -29,7 +29,6 @@ use std::{ /// The main structure of an OPOSSUM model. /// It contains the [`NodeGroup`] representing the optical model, a list of analyzers and a global configuration. pub struct OpmDocument { - #[serde(rename = "opm file version")] opm_file_version: String, #[serde(default)] scenery: NodeGroup, @@ -69,23 +68,7 @@ impl OpmDocument { let contents = fs::read_to_string(path).map_err(|e| { OpossumError::OpmDocument(format!("cannot read file {} : {}", path.display(), e)) })?; - let mut document: Self = serde_yaml::from_str(&contents) - .map_err(|e| OpossumError::OpmDocument(format!("parsing of model failed: {e}")))?; - if document.opm_file_version != env!("OPM_FILE_VERSION") { - warn!("OPM file version does not match the used OPOSSUM version."); - warn!( - "read version '{}' <-> program file version '{}'", - document.opm_file_version, - env!("OPM_FILE_VERSION") - ); - warn!("This file might haven been written by an older or newer version of OPOSSUM. The model import might not be correct."); - } - document.scenery.after_deserialization_hook()?; - document - .scenery - .graph_mut() - .update_global_config(&Some(document.global_conf.clone())); - Ok(document) + Self::from_string(&contents) } /// Create a new [`OpmDocument`] from the given `.opm` file string. /// @@ -93,7 +76,7 @@ impl OpmDocument { /// /// This function will return an error if the parsing of the `.opm` file failed. pub fn from_string(file_string: &str) -> OpmResult<Self> { - let mut document: Self = serde_yaml::from_str(file_string) + let mut document: Self = ron::from_str(file_string) .map_err(|e| OpossumError::OpmDocument(format!("parsing of model failed: {e}")))?; if document.opm_file_version != env!("OPM_FILE_VERSION") { warn!("OPM file version does not match the used OPOSSUM version."); @@ -143,7 +126,7 @@ impl OpmDocument { /// /// This function will return an error if the serialization of the internal structures fail. pub fn to_opm_file_string(&self) -> OpmResult<String> { - serde_yaml::to_string(&self).map_err(|e| { + ron::ser::to_string_pretty(&self, ron::ser::PrettyConfig::default()).map_err(|e| { OpossumError::OpticScenery(format!("serialization of OpmDocument failed: {e}")) }) } @@ -273,7 +256,7 @@ mod test { OpmDocument::from_file(&Path::new("./files_for_testing/opm/incorrect_opm.opm")); assert_eq!( result.unwrap_err().to_string(), - "OpmDocument:parsing of model failed: missing field `opm file version`" + "OpmDocument:parsing of model failed: 1:2: Unexpected missing field named `opm_file_version` in `OpmDocument`" ); assert!( OpmDocument::from_file(&PathBuf::from("./files_for_testing/opm/opticscenery.opm")) diff --git a/opossum/src/optic_ref.rs b/opossum/src/optic_ref.rs index b8d9dc1d1f56be6ac3fc4fe2f284174f26d31fdd..70d89d45de6b798289ab588089a671c5bc94ab7f 100644 --- a/opossum/src/optic_ref.rs +++ b/opossum/src/optic_ref.rs @@ -224,8 +224,7 @@ mod test { #[test] fn serialize() { let optic_ref = OpticRef::new(Arc::new(Mutex::new(Dummy::default())), None); - let serialized = serde_yaml::to_string(&optic_ref); - assert!(serialized.is_ok()); + let _ = ron::ser::to_string_pretty(&optic_ref, ron::ser::PrettyConfig::default()).unwrap(); } #[test] fn deserialize() { @@ -233,12 +232,10 @@ mod test { path.push("files_for_testing/opm/optic_ref.opm"); let file_content = &mut "".to_owned(); let _ = File::open(path).unwrap().read_to_string(file_content); - let deserialized: Result<OpticRef, serde_yaml::Error> = serde_yaml::from_str(&file_content); - assert!(deserialized.is_ok()); - let optic_ref = deserialized.unwrap(); + let optic_ref: OpticRef = ron::from_str(&file_content).unwrap(); assert_eq!( optic_ref.uuid(), - uuid!("587ee70f-6f52-4420-89f6-e1618ff4dbdb") + uuid!("98248e7f-dc4c-4131-8710-f3d5be2ff087") ); let optic_ref = optic_ref.optical_ref.lock().expect("Mutex lock failed"); assert_eq!(optic_ref.node_type(), "dummy"); diff --git a/opossum/src/properties/proptype.rs b/opossum/src/properties/proptype.rs index 848c60d5b8a0f657ca385501d58276972d23ed39..a9f4386c471e93b5c52c145c2922c12a8fdcd345 100644 --- a/opossum/src/properties/proptype.rs +++ b/opossum/src/properties/proptype.rs @@ -4,7 +4,7 @@ use crate::{ analyzers::ghostfocus::GhostFocusHistory, aperture::Aperture, error::{OpmResult, OpossumError}, - lightdata::LightData, + lightdata::{light_data_builder::LightDataBuilder, LightData}, nodes::{ fluence_detector::{fluence_data::FluenceData, Fluence}, ray_propagation_visualizer::RayPositionHistories, @@ -19,7 +19,6 @@ use crate::{ utils::{ geom_transformation::Isometry, unit_format::{get_exponent_for_base_unit_in_e3_steps, get_prefix_for_base_unit}, - EnumProxy, }, }; use nalgebra::{Vector2, Vector3}; @@ -52,11 +51,11 @@ pub enum Proptype { /// A boolean property Bool(bool), /// An optional [`LightData`] property - LightData(EnumProxy<Option<LightData>>), + LightData(Option<LightData>), /// Property for storing a [`FilterType`] of an [`IdealFilter`](crate::nodes::IdealFilter) node. - FilterType(EnumProxy<FilterType>), + FilterType(FilterType), /// Property for storing a [`SplittingConfig`] of an [`BeamSplitter`](crate::nodes::BeamSplitter) node. - SplitterType(EnumProxy<SplittingConfig>), + SplitterType(SplittingConfig), /// Property for storing a [`SpectrometerType`] of a [`Sepctrometer`](crate::nodes::Spectrometer) node. SpectrometerType(SpectrometerType), /// Property for storing a [`Metertype`] of an [`Energymeter`](crate::nodes::EnergyMeter) node. @@ -97,9 +96,9 @@ pub enum Proptype { /// a (2D) geometric angle (e.g. component tilt) Angle(Angle), /// an optical refractive index model - RefractiveIndex(EnumProxy<RefractiveIndexType>), + RefractiveIndex(RefractiveIndexType), /// a (node) location / orientation - Isometry(EnumProxy<Option<Isometry>>), + Isometry(Option<Isometry>), /// Three dimensional Vector Vec3(Vector3<f64>), /// an optional length parameter. used, e.g., for the alignment wavelength of the source @@ -108,6 +107,8 @@ pub enum Proptype { HitMap(HitMap), /// 2-dimenstional vector Vec2(Vector2<f64>), + /// [`LightData`] build configuration + LightDataBuilder(Option<LightDataBuilder>), } impl Proptype { /// Generate a html representation of a Proptype. diff --git a/opossum/src/ray.rs b/opossum/src/ray.rs index db7ea3aba5eb7963134e51f3f8b9e1ce62b5a75f..9edae49d996f40835d45610d0880b64ae21851df 100644 --- a/opossum/src/ray.rs +++ b/opossum/src/ray.rs @@ -19,6 +19,7 @@ use crate::{ error::{OpmResult, OpossumError}, joule, meter, nodes::{fluence_detector::Fluence, FilterType}, + properties::Proptype, rays::{FluenceRays, Rays}, spectrum::Spectrum, surface::{ @@ -48,7 +49,11 @@ impl SplittingConfig { } } } - +impl From<SplittingConfig> for Proptype { + fn from(config: SplittingConfig) -> Self { + Self::SplitterType(config) + } +} ///Struct that contains all information about an optical ray #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct Ray { @@ -1451,7 +1456,7 @@ mod test { let mut ray = Ray::new_collimated(position, nanometer!(502.0), e_1j).unwrap(); let mut spec_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); spec_path.push("files_for_testing/spectrum/test_filter.csv"); - let s = Spectrum::from_csv(spec_path.to_str().unwrap()).unwrap(); + let s = Spectrum::from_csv(&spec_path).unwrap(); let filter = FilterType::Spectrum(s); let _ = ray.filter_energy(&filter).unwrap(); assert_eq!(ray.e, e_1j); diff --git a/opossum/src/refractive_index/mod.rs b/opossum/src/refractive_index/mod.rs index 07be32c8edd3cf9ceceba62c278fd86c515f978b..326934a4e4aba7f769f99a5cb3ee28278c08c663 100644 --- a/opossum/src/refractive_index/mod.rs +++ b/opossum/src/refractive_index/mod.rs @@ -15,6 +15,7 @@ pub use refr_index_const::RefrIndexConst; pub use refr_index_sellmeier1::RefrIndexSellmeier1; use crate::error::{OpmResult, OpossumError}; +use crate::properties::Proptype; /// Available models for the calculation of refractive index #[derive(Clone, Serialize, Deserialize, Debug)] @@ -59,6 +60,11 @@ impl RefractiveIndexType { } } +impl From<RefractiveIndexType> for Proptype { + fn from(refr: RefractiveIndexType) -> Self { + Self::RefractiveIndex(refr) + } +} /// All refractive index models must implement this trait. pub trait RefractiveIndex { /// Get the refractive index value of the current model for the given wavelength. diff --git a/opossum/src/spectrum.rs b/opossum/src/spectrum.rs index e0e9268934b1efb399513ddc95e5a8494645a219..bf0fb58abc7c5e669f615d20b0c1a3ec57ace117 100644 --- a/opossum/src/spectrum.rs +++ b/opossum/src/spectrum.rs @@ -17,10 +17,14 @@ use std::{ fmt::{Debug, Display}, fs::File, ops::Range, + path::Path, }; -use uom::fmt::DisplayStyle::Abbreviation; use uom::num_traits::Zero; use uom::si::{f64::Length, length::micrometer, length::nanometer}; +use uom::{ + fmt::DisplayStyle::Abbreviation, + si::{energy::joule, f64::Energy}, +}; /// Structure for handling spectral data. /// @@ -81,7 +85,7 @@ impl Spectrum { /// - the file path is not found or could not be read. /// - the file is empty. /// - the file could not be parsed. - pub fn from_csv(path: &str) -> OpmResult<Self> { + pub fn from_csv(path: &Path) -> OpmResult<Self> { let file = File::open(path).map_err(|e| OpossumError::Spectrum(e.to_string()))?; let mut reader = ReaderBuilder::new() .has_headers(false) @@ -109,6 +113,38 @@ impl Spectrum { } Ok(Self { data: datas }) } + /// Generate a spectrum from a list of narrow laser lines (center wavelength, Energy) and a spectrum resolution. + /// + /// # Errors + /// + /// This function will return an error if + /// - the resolution is not positive + /// - the wavelength is negative + /// - the energy is negative + /// - the list of lines is empty + pub fn from_laser_lines(lines: Vec<(Length, Energy)>, resolution: Length) -> OpmResult<Self> { + if lines.is_empty() { + return Err(OpossumError::Spectrum("no laser lines provided".into())); + } + if resolution <= Length::zero() { + return Err(OpossumError::Spectrum("resolution must be positive".into())); + } + let mut min_lambda = lines[0].0; + let mut max_lambda = lines[0].0; + for line in &lines { + if line.0 < min_lambda { + min_lambda = line.0; + } + if line.0 > max_lambda { + max_lambda = line.0; + } + } + let mut s = Self::new(min_lambda..max_lambda, resolution)?; + for line in lines { + s.add_single_peak(line.0, line.1.get::<joule>())?; + } + Ok(s) + } fn lambda_vec(&self) -> Vec<f64> { self.data.iter().map(|data| data.0).collect() } @@ -657,7 +693,9 @@ mod test { } #[test] fn from_csv_ok() { - let s = Spectrum::from_csv("files_for_testing/spectrum/spec_to_csv_test_01.csv"); + let s = Spectrum::from_csv(Path::new( + "files_for_testing/spectrum/spec_to_csv_test_01.csv", + )); assert!(s.is_ok()); let s = s.unwrap(); let lambdas = s.lambda_vec(); @@ -673,10 +711,19 @@ mod test { } #[test] fn from_csv_err() { - assert!(Spectrum::from_csv("wrong_path.csv").is_err()); - assert!(Spectrum::from_csv("files_for_testing/spectrum/spec_to_csv_test_02.csv").is_err()); - assert!(Spectrum::from_csv("files_for_testing/spectrum/spec_to_csv_test_03.csv").is_err()); - assert!(Spectrum::from_csv("files_for_testing/spectrum/spec_to_csv_test_04.csv").is_err()); + assert!(Spectrum::from_csv(Path::new("wrong_path.csv")).is_err()); + assert!(Spectrum::from_csv(Path::new( + "files_for_testing/spectrum/spec_to_csv_test_02.csv" + )) + .is_err()); + assert!(Spectrum::from_csv(Path::new( + "files_for_testing/spectrum/spec_to_csv_test_03.csv" + )) + .is_err()); + assert!(Spectrum::from_csv(Path::new( + "files_for_testing/spectrum/spec_to_csv_test_04.csv" + )) + .is_err()); } #[test] fn range() { @@ -919,17 +966,18 @@ mod test { #[test] fn serialize() { let s = prep(); - let s_yaml = serde_yaml::to_string(&s); + let s_yaml = ron::ser::to_string_pretty(&s, ron::ser::PrettyConfig::default()); assert!(s_yaml.is_ok()); assert_eq!(s_yaml.unwrap(), - "data:\n- - 1.0\n - 0.0\n- - 1.5\n - 0.0\n- - 2.0\n - 0.0\n- - 2.5\n - 0.0\n- - 3.0\n - 0.0\n- - 3.5\n - 0.0\n".to_string()); + "(\r\n data: [\r\n (1.0, 0.0),\r\n (1.5, 0.0),\r\n (2.0, 0.0),\r\n (2.5, 0.0),\r\n (3.0, 0.0),\r\n (3.5, 0.0),\r\n ],\r\n)".to_string()); } #[test] fn deserialize() { - let s: std::result::Result<Spectrum, serde_yaml::Error>=serde_yaml::from_str("data:\n- - 1.0\n - 0.1\n- - 1.5\n - 0.2\n- - 2.0\n - 0.3\n- - 2.5\n - 0.4\n- - 3.0\n - 0.5\n- - 3.5\n - 0.6\n"); - assert!(s.is_ok()); + let s: Spectrum = + ron::from_str("(data:[(1.0, 0.1),(1.5,0.2),(2.0,0.3),(2.5,0.4),(3.0,0.5),(3.5,0.6)])") + .unwrap(); assert_eq!( - s.unwrap().data, + s.data, vec![ (1.0, 0.1), (1.5, 0.2), diff --git a/opossum/src/utils/enum_proxy.rs b/opossum/src/utils/enum_proxy.rs deleted file mode 100644 index 598fd354b2ea4b1e7617561e88a414e2259744d0..0000000000000000000000000000000000000000 --- a/opossum/src/utils/enum_proxy.rs +++ /dev/null @@ -1,36 +0,0 @@ -//! Helper module for circumventing issues during serialization / deserialization of enum values. - -use crate::{ - lightdata::LightData, nodes::FilterType, properties::Proptype, ray::SplittingConfig, - refractive_index::RefractiveIndexType, -}; -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct EnumProxy<T> { - pub value: T, -} - -impl From<EnumProxy<SplittingConfig>> for Proptype { - fn from(value: EnumProxy<SplittingConfig>) -> Self { - Self::SplitterType(value) - } -} - -impl From<EnumProxy<FilterType>> for Proptype { - fn from(value: EnumProxy<FilterType>) -> Self { - Self::FilterType(value) - } -} - -impl From<EnumProxy<RefractiveIndexType>> for Proptype { - fn from(value: EnumProxy<RefractiveIndexType>) -> Self { - Self::RefractiveIndex(value) - } -} - -impl From<EnumProxy<Option<LightData>>> for Proptype { - fn from(value: EnumProxy<Option<LightData>>) -> Self { - Self::LightData(value) - } -} diff --git a/opossum/src/utils/geom_transformation.rs b/opossum/src/utils/geom_transformation.rs index f3936a6e511cd31980a9eb4bdab175018c983de3..3399fd09bed7f08c810a70bd3d5c9be18c3af140 100644 --- a/opossum/src/utils/geom_transformation.rs +++ b/opossum/src/utils/geom_transformation.rs @@ -2,7 +2,6 @@ #![warn(missing_docs)] use std::fmt::Display; -use super::EnumProxy; use crate::{ degree, error::{OpmResult, OpossumError}, @@ -405,14 +404,9 @@ impl Display for Isometry { ) } } -impl From<EnumProxy<Option<Isometry>>> for Proptype { - fn from(value: EnumProxy<Option<Isometry>>) -> Self { - Self::Isometry(value) - } -} impl From<Option<Isometry>> for Proptype { fn from(value: Option<Isometry>) -> Self { - Self::Isometry(EnumProxy { value }) + Self::Isometry(value) } } #[cfg(feature = "bevy")] @@ -980,12 +974,5 @@ mod test { #[test] fn from() { assert_matches!(Some(Isometry::identity()).into(), Proptype::Isometry(_)); - assert_matches!( - EnumProxy { - value: Some(Isometry::identity()) - } - .into(), - Proptype::Isometry(_) - ); } } diff --git a/opossum/src/utils/mod.rs b/opossum/src/utils/mod.rs index de170643809e89c1cd68e27d03090301e760302a..bf52db7818d937ea65b7cc2889341374fbfcd7de 100644 --- a/opossum/src/utils/mod.rs +++ b/opossum/src/utils/mod.rs @@ -1,5 +1,4 @@ //! Module for additional computational capabilities -pub mod enum_proxy; pub mod filter_data; pub mod geom_transformation; pub mod griddata; @@ -8,5 +7,4 @@ pub mod math_utils; pub mod test_helper; pub mod unit_format; pub mod uom_macros; -pub use enum_proxy::EnumProxy; pub use math_utils::{f64_to_usize, usize_to_f64}; diff --git a/opossum_backend/src/nodes.rs b/opossum_backend/src/nodes.rs index d3639817ec993c681e4b09ad489eff5faf912a91..b69d199d52f37b83cb713f2a2553a1e98c70f20e 100644 --- a/opossum_backend/src/nodes.rs +++ b/opossum_backend/src/nodes.rs @@ -103,33 +103,24 @@ async fn get_subnodes( async fn post_subnode( data: web::Data<AppState>, path: web::Path<Uuid>, - node_type: String, + node_type: web::Json<String>, ) -> Result<Json<NodeInfo>, ErrorResponse> { + let node_type = node_type.into_inner(); let new_node = create_node_ref(&node_type)?; let mut document = data.document.lock().unwrap(); - let scenery = document.scenery_mut(); - let uuid = path.into_inner(); - if uuid.is_nil() { - scenery.add_node_ref(new_node)?; + let uuid = path.into_inner(); + let new_node_uuid=if uuid.is_nil() { + let scenery = document.scenery_mut(); + scenery.add_node_ref(new_node.clone())? } else { - let node_ref = scenery.node_recursive(uuid)?; - node_ref - .optical_ref - .lock() - .unwrap() - .as_group_mut()? - .add_node_ref(new_node)?; - } - let node_ref = scenery.node_recursive(uuid)?; - let node = node_ref.optical_ref.lock().unwrap(); - let name = node.name(); - let node_type = node.node_type(); - drop(node); - drop(document); + let scenery = document.scenery_mut(); + scenery.node_recursive(uuid)?.optical_ref.lock().unwrap().as_group_mut()?.add_node_ref(new_node.clone())? + }; + let node = new_node.optical_ref.lock().unwrap(); let node_info = NodeInfo { - uuid: node_ref.uuid(), - name, - node_type, + uuid: new_node_uuid, + name: node.name(), + node_type: node.node_type(), }; Ok(Json(node_info)) }