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//! ¶xial_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};