Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions crates/cherry-rs/src/examples/wf_epi_excitation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::{

pub fn sequential_model(
n_air: Rc<dyn RefractiveIndexSpec>,
n_oil: Rc<dyn RefractiveIndexSpec>,
wavelengths: &[f64],
) -> SequentialModel {
let gap_0 = GapSpec {
Expand All @@ -33,11 +34,11 @@ pub fn sequential_model(
};
let gap_2 = GapSpec {
thickness: 50.0,
refractive_index: n_air.clone(),
refractive_index: n_air,
};
let gap_3 = GapSpec {
thickness: 1.0,
refractive_index: n_air,
refractive_index: n_oil,
};
let gaps = vec![gap_0, gap_1, gap_2, gap_3];

Expand All @@ -50,7 +51,7 @@ pub fn sequential_model(
rotation_offset: Rotation3D::None,
};
let surf_2 = SurfaceSpec::Conic {
semi_diameter: 23.2,
semi_diameter: 36.0,
radius_of_curvature: Float::INFINITY,
conic_constant: 0.0,
surf_kind: BoundaryKind::Reflecting,
Expand All @@ -63,7 +64,7 @@ pub fn sequential_model(
rotation_offset: Rotation3D::None,
};
let surf_3 = SurfaceSpec::ThinLens {
semi_diameter: 4.75,
semi_diameter: 4.25,
focal_length: 3.3333,
rotation: Rotation3D::None,
decenter: Vec3::new(0.0, 0.0, 0.0),
Expand Down
9 changes: 3 additions & 6 deletions crates/cherry-rs/src/views/paraxial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,17 +836,14 @@ impl ParaxialSubView {
let y_1 = parallel_ray.rays_at_surface(1)[0].height;
let u_final = parallel_ray.rays_at_surface(parallel_ray.num_surfaces() - 2)[0].angle;

// There should be a negative sign here for lens only systems, but we take abs
// later so it's not needed
let efl = y_1 / u_final;
let efl = -y_1 / u_final;

// Handle edge case for negatively infinite EFL
if efl.is_infinite() {
return Float::INFINITY;
}

// abs() handles edge case of apparent negative EFLs in reflecting systems
efl.abs()
efl
}

#[allow(clippy::too_many_arguments)]
Expand Down Expand Up @@ -918,7 +915,7 @@ impl ParaxialSubView {

Ok(Pupil {
location,
semi_diameter,
semi_diameter: semi_diameter.abs(), // semi-diameter is always positive
})
}

Expand Down
75 changes: 66 additions & 9 deletions crates/cherry-rs/tests/wf_epi_excitation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,71 @@ use cherry_rs::examples::wf_epi_excitation::sequential_model;
use cherry_rs::{FieldSpec, ParaxialView, n};

const WAVELENGTHS: [f64; 1] = [0.5876];
const FIELD_SPECS: [FieldSpec; 1] = [FieldSpec::PointSource { x: 0.0, y: 0.0 }];

// Hand calculation: the stop (second thin lens) is 150 mm (100 mm + 50 mm,
// the fold mirror has no power) downstream of the first thin lens
// (f = 40 mm). Treating the stop as a real object and solving the thin lens
// equation 1/s' = 1/f - 1/s with s = 150 mm gives s' = 600/11 = 54.5455 mm,
// with the resulting image (the entrance pupil) on the object-space side of
// the first thin lens.
const FIELD_SPECS: [FieldSpec; 1] = [FieldSpec::PointSource { x: 0.0, y: 1.5 }];

// Paraxial property values
const APERTURE_STOP: usize = 3;
const BACK_FOCAL_DISTANCE: f64 = 5.1562;
const BACK_PRINCIPAL_PLANE: f64 = 7.0312;
const EFFECTIVE_FOCAL_LENGTH: f64 = -1.8750;
const ENTRANCE_PUPIL_LOCATION: f64 = -54.5455;
const ENTRANCE_PUPIL_SIZE: f64 = 1.5454;

#[test]
fn wf_epi_excitation_paraxial_aperture_stop() {
let model = sequential_model(n!(1.0), n!(1.5), &WAVELENGTHS);
let view =
ParaxialView::new(&model, &FIELD_SPECS, false).expect("Could not create paraxial view");

for sub_view in view.iter() {
let result = sub_view.aperture_stop();

assert_eq!(APERTURE_STOP, *result)
}
}

#[test]
fn wf_epi_excitation_paraxial_back_principal_plane() {
let model = sequential_model(n!(1.0), n!(1.5), &WAVELENGTHS);
let view =
ParaxialView::new(&model, &FIELD_SPECS, false).expect("Could not create paraxial view");

for sub_view in view.iter() {
let result = sub_view.back_principal_plane();

assert_abs_diff_eq!(BACK_PRINCIPAL_PLANE, *result, epsilon = 1e-4)
}
}

#[test]
fn wf_epi_excitation_paraxial_back_focal_distance() {
let model = sequential_model(n!(1.0), n!(1.5), &WAVELENGTHS);
let view =
ParaxialView::new(&model, &FIELD_SPECS, false).expect("Could not create paraxial view");

for sub_view in view.iter() {
let result = sub_view.back_focal_distance();

assert_abs_diff_eq!(BACK_FOCAL_DISTANCE, *result, epsilon = 1e-4)
}
}

#[test]
fn wf_epi_excitation_paraxial_effective_focal_length() {
let model = sequential_model(n!(1.0), n!(1.5), &WAVELENGTHS);
let view =
ParaxialView::new(&model, &FIELD_SPECS, false).expect("Could not create paraxial view");

for sub_view in view.iter() {
let result = sub_view.effective_focal_length();

assert_abs_diff_eq!(EFFECTIVE_FOCAL_LENGTH, *result, epsilon = 1e-4)
}
}

#[test]
fn wf_epi_excitation_entrance_pupil_location() {
let model = sequential_model(n!(1.0), &WAVELENGTHS);
let model = sequential_model(n!(1.0), n!(1.5), &WAVELENGTHS);
let view =
ParaxialView::new(&model, &FIELD_SPECS, false).expect("Could not create paraxial view");

Expand All @@ -27,5 +79,10 @@ fn wf_epi_excitation_entrance_pupil_location() {
ENTRANCE_PUPIL_LOCATION,
epsilon = 1e-3
);
assert_abs_diff_eq!(
entrance_pupil.semi_diameter,
ENTRANCE_PUPIL_SIZE,
epsilon = 1e-3
);
}
}
Loading