cherry_rs/
lib.rs

1//! Cherry is a library for sequential optical system design.
2//!
3//! The core structure of sequential optical design is the
4//! [SequentialModel](struct@SequentialModel) which is a set of submodels
5//! containing surfaces and gaps between surfaces. Each
6//! [SequentialSubModel](trait@SequentialSubModel) corresponds to a unique set
7//! of system parameters, i.e. a wavelength and a transverse axis. A submodel
8//! provides an interface to iterate over the surfaces and gaps in the system.
9//!
10//! Inputs to the system are provided by specs, of which there are several
11//! types:
12//!
13//! - [SurfaceSpec](enum@SurfaceSpec) - Describes a surface in the system for
14//!   which surface sag or paraxial ray trace matrices can be calculated.
15//! - [GapSpec](struct@GapSpec) - Describes a gap between surfaces in the
16//!   system. Refractive index data is located here.
17//! - [ApertureSpec](enum@ApertureSpec) - Describes the aperture of the system.
18//!   This may differ from any pupils that can be derived directly from the
19//!   surfaces and gaps.
20//! - [FieldSpec](enum@FieldSpec) - Describes the field points of the system.
21//! - [RefractiveIndexSpec](struct@RefractiveIndexSpec) - Describes the
22//!   refractive index of a gap.
23//! - Wavelength - Describes a single wavelength to model.
24//!
25//! The outputs of the system are provided by views, such as:
26//!
27//! - [ParaxialView](struct@ParaxialView) - A paraxial view of the system.
28//!   Contains information such as focal length, principal planes, etc.
29//! - [RayTrace3DView](fn@ray_trace_3d_view) - A 3D ray trace view of the
30//!   system.
31//! - [CutawayView](struct@CutawayView) - A cutaway view of the system. Used
32//!   primarily for drawing the system.
33//! - [ComponentsView](fn@components_view) - A view of the components of the
34//!   system. Used for grouping surfaces into lenses.
35//!
36//! # Quick Start
37//! ```rust
38//! use cherry_rs::{
39//!     n, ray_trace_3d_view, ApertureSpec, FieldSpec, GapSpec, ImagePlane, ParaxialView, Pupil, PupilSampling, RealSpec, RefractiveIndexSpec,
40//!     SequentialModel, SurfaceSpec, SurfaceType,
41//! };
42//!
43//! // Create a convexplano lens with an object at infinity.
44//! let air = n!(1.0);
45//! let nbk7 = n!(1.515);
46//!
47//! // Define a set of gaps between surfaces.
48//! let gaps = vec![
49//!     GapSpec {
50//!         thickness: f64::INFINITY,
51//!         refractive_index: air.clone(),
52//!     },
53//!     GapSpec {
54//!         thickness: 5.3,
55//!         refractive_index: nbk7,
56//!     },
57//!     GapSpec {
58//!        thickness: 46.6,
59//!        refractive_index: air,
60//!     },
61//! ];
62//!
63//! // Define a set of surfaces in the system.
64//! let surfaces = vec![
65//!     SurfaceSpec::Object,
66//!     SurfaceSpec::Conic {
67//!         semi_diameter: 12.5,
68//!         radius_of_curvature: 25.8,
69//!         conic_constant: 0.0,
70//!         surf_type: SurfaceType::Refracting,
71//!     },
72//!     SurfaceSpec::Conic {
73//!         semi_diameter: 12.5,
74//!         radius_of_curvature: f64::INFINITY,
75//!         conic_constant: 0.0,
76//!         surf_type: SurfaceType::Refracting,
77//!     },
78//!     SurfaceSpec::Image,
79//! ];
80//!
81//! // Define a set of wavelengths to model.
82//! let wavelengths: Vec<f64> = vec![0.567];
83//!
84//! // Create a sequential model from the gaps, surfaces, and wavelengths.
85//! let sequential_model = SequentialModel::new(&gaps, &surfaces, &wavelengths).unwrap();
86//!
87//! // Define a user-defined system aperture.
88//! let aperture_spec = ApertureSpec::EntrancePupil { semi_diameter: 5.0 };
89//!
90//! // Analyze the system at two different field points, sampling the pupil
91//! // with a square grid with a spacing of 0.1 in normalized pupil coordinates.
92//! let field_specs = vec![
93//!     FieldSpec::Angle {
94//!         angle: 0.0,
95//!         pupil_sampling: PupilSampling::SquareGrid { spacing: 0.1 },
96//!     },
97//!     FieldSpec::Angle {
98//!         angle: 5.0,
99//!         pupil_sampling: PupilSampling::SquareGrid { spacing: 0.1 },
100//!     },
101//! ];
102//!
103//! // Compute the paraxial view of the system.
104//! let paraxial_view = ParaxialView::new(&sequential_model, &field_specs, false).unwrap();
105//!
106//! // Compute the effective focal length of the lens for each submodel.
107//! for (sub_model_id, _) in sequential_model.submodels() {
108//!     let sub_view = paraxial_view.subviews().get(sub_model_id).unwrap();
109//!     let result = sub_view.effective_focal_length();
110//!
111//!     println!("Submodel ID: {:?}, Effective focal length: {}", sub_model_id, result);
112//! }
113//!
114//! // Compute a 3D ray trace of the system.
115//! let rays = ray_trace_3d_view(
116//!     &aperture_spec, &field_specs,
117//!     &sequential_model,
118//!     &paraxial_view,
119//!     None,
120//! ).unwrap();
121//! ```
122
123mod core;
124mod specs;
125mod views;
126
127// API
128pub mod examples;
129pub use core::{
130    math::vec3::Vec3,
131    sequential_model::{Axis, SequentialModel, SequentialSubModel, Step, SubModelID},
132};
133pub use specs::{
134    aperture::ApertureSpec,
135    fields::{FieldSpec, PupilSampling},
136    gaps::{GapSpec, ImagSpec, RealSpec, RefractiveIndexSpec},
137    surfaces::SurfaceSpec,
138    surfaces::SurfaceType,
139};
140pub use views::{
141    components::{components_view, Component},
142    cutaway::CutawayView,
143    paraxial::{
144        ImagePlane, ParaxialSubView, ParaxialSubViewDescription, ParaxialView,
145        ParaxialViewDescription, Pupil,
146    },
147    ray_trace_3d::{ray_trace_3d_view, Ray, TraceResults},
148};