545 KiB
545 KiB
In [17]:
%matplotlib widget isdark = False from rayoptics.environment import *
In [18]:
opm = OpticalModel() sm = opm['seq_model'] osp = opm['optical_spec'] pm = opm['parax_model'] osp['pupil'] = PupilSpec(osp, key=['object', 'pupil'], value=16) osp['fov'] = FieldSpec(osp, key=['object', 'angle'], value=1.5, flds=[0., 0.707, 1.], is_relative=True) osp['wvls'] = WvlSpec([('F', 0.5), (587.5618, 1.0), ('C', 0.5)], ref_wl=1) opm.radius_mode = True sm.gaps[0].thi=1e10 sm.add_surface([246, 3, 'N-LASF9', 'Schott', 42/2]) sm.add_surface([1e9, 290+36]) gap0_idx = sm.cur_surface sm.add_surface([1e9, 3, 'N-LASF9', 'Schott', 16/2]) sm.add_surface([-30.6, 36+36]) gap1_idx = sm.cur_surface sm.add_surface([30.6, 3, 'N-LASF9', 'Schott', 16/2]) sm.add_surface([1e9, 36+36]) gap2_idx = sm.cur_surface sm.add_surface([1e9, 3, 'N-LASF9', 'Schott', 16/2]) sm.add_surface([-30.6, 36])
In [19]:
opm.update_model() layout_plt = plt.figure(FigureClass=InteractiveLayout, opt_model=opm, is_dark=isdark).plot()
Figure
In [20]:
pm.first_order_data()
efl 1448 ffl -1.193e+04 pp1 -1.048e+04 bfl 216.1 ppk 1232 f/# 90.51 m -1.448e-07 red -6.905e+06 obj_dist 1e+10 obj_ang 1.5 enp_dist -0 enp_radius 8 na obj 8e-10 n obj 1 img_dist 216.1 img_ht 37.92 exp_dist 220.5 exp_radius 0.971 na img -0.005524 n img 1 optical invariant 0.2095
In [21]:
# add a focusing mirror sm.insert_surface_and_gap() cur = sm.cur_surface sm.ifcs[cur] = ThinLens(power=1/30.) sm.gaps[cur].thi = 30. opm.update_model() opm.seq_model.gaps[-1].thi = opm.optical_spec.parax_data.fod.bfl opm.update_model() layout_plt = plt.figure(FigureClass=InteractiveLayout, opt_model=opm, is_dark=isdark).plot()
Figure
In [22]:
#spot_plt = plt.figure(FigureClass=SpotDiagramFigure, opt_model=opm, scale_type=Fit.User_Scale, # user_scale_value=0.1, is_dark=isdark).plot() abr_plt = plt.figure(FigureClass=RayFanFigure, opt_model=opm, data_type='Ray', scale_type=Fit.All_Same).plot()
Figure
In [23]:
opm.seq_model.gaps[-1].thi = opm.optical_spec.parax_data.fod.bfl opm.update_model() #spot_plt = plt.figure(FigureClass=SpotDiagramFigure, opt_model=opm, scale_type=Fit.User_Scale, # user_scale_value=0.1, is_dark=isdark).plot()T spot_plt = plt.figure(FigureClass=SpotDiagramFigure, opt_model=opm, is_dark=isdark).plot()
Figure
In [24]:
# hey it's me from the future, I made these functions import rayoptics.optical.model_constants as mc def dump_dist(p, wi, ray_pkg, fld, wvl, foc): if ray_pkg is not None: image_pt = fld.ref_sphere[0] ray = ray_pkg[mc.ray] dist = foc / ray[-1][mc.d][2] defocused_pt = ray[-1][mc.p] + dist*ray[-1][mc.d] t_abr = defocused_pt - image_pt return np.sqrt(np.sum(t_abr*t_abr)) def spot_rms(sm, fld_idx=0): return np.sqrt(np.mean(np.square(sm.trace_grid(dump_dist, fld_idx, form='list', append_if_none=False)[0]), axis=1)) def dump_rays(p, wi, ray_pkg, fld, wvl, foc): if ray_pkg is not None: image_pt = fld.ref_sphere[0] ray = ray_pkg[mc.ray] v = ray[-1][mc.d][0:2] / ray[-1][mc.d][2] return [ray[-1][mc.p][0:2] - image_pt[0:2], v] def get_focus(sm, offset=False, weights=np.array([0.25, 0.5, 0.25])): offsets = np.linspace(-40, 40, 2000) vals, colors = sm.trace_grid(dump_rays, 0, form='list', append_if_none=False) rms = np.zeros((offsets.size, len(vals)), dtype=float) for i in range(offsets.size): for j in range(len(vals)): rms[i][j] = np.sqrt(np.mean(np.square(vals[j][:,0]+vals[j][:,1]*offsets[i]))) if offset: return offsets[np.argmin(np.sum(rms*weights, axis=1))] else: return sm.gaps[-1].thi + offsets[np.argmin(np.sum(rms*weights, axis=1))] get_focus(sm)
Out[24]:
23.655706218096086
In [25]:
opm.seq_model.gaps[-1].thi = get_focus(sm) opm.update_model() #spot_plt = plt.figure(FigureClass=SpotDiagramFigure, opt_model=opm, scale_type=Fit.User_Scale, # user_scale_value=0.1, is_dark=isdark).plot()T spot_plt = plt.figure(FigureClass=SpotDiagramFigure, opt_model=opm, is_dark=isdark).plot() spot_rms(sm, 0), spot_rms(sm, 1), spot_rms(sm, 2)
Out[25]:
(array([0.00418596, 0.01665802, 0.00529431]), array([0.25632774, 0.0865608 , 0.10988704]), array([0.47439537, 0.14863163, 0.25140339]))
Figure
In [ ]:
import numpy as np def get_focus_val(sm, nflds=3, weights=np.array([0.25, 0.5, 0.25]), fld_weights=np.array([0.6, 0.2, 0.2])): offsets = np.linspace(-40, 40, 2000) valss = [] try: for i in range(nflds): vals, colors = sm.trace_grid(dump_rays, i, form='list', append_if_none=False) valss.append(vals) rms = np.zeros((offsets.size, len(valss)), dtype=float) for i in range(offsets.size): for j in range(len(valss)): for k in range(len(valss[j])): rms[i][j] += fld_weights[j]*np.sqrt(np.mean(np.square(valss[j][k][:,0]+valss[j][k][:,1]*offsets[i]))) return np.min(np.sum(rms*fld_weights, axis=1)) except: return 1e+9 idxs = [gap0_idx, gap1_idx, gap2_idx] orig_gaps = [sm.gaps[idx].thi for idx in idxs]
In [26]:
# twiddle with all the gaps and see what happens from numpy.random import default_rng rng = default_rng() offsets = (2*rng.random((1000, 3))-0.5)*np.array([50., 20., 20.]) rms = np.zeros(offsets.shape[0]) for i in range(offsets.shape[0]): for j in range(len(idxs)): sm.gaps[idxs[j]].thi = orig_gaps[j] + offsets[i][j] sm.update_model() if i % 100 == 0: print("sim {}".format(i)) rms[i] = get_focus_val(sm) for i in range(len(idxs)): sm.gaps[idxs[i]].thi = orig_gaps[i] sm.update_model() offsets[np.argmin(rms)], rms[np.argmin(rms)]
sim 0 sim 100 sim 200 sim 300 sim 400 sim 500 sim 600 sim 700 sim 800 sim 900
Out[26]:
(array([-19.73943222, -0.84497351, 20.18892131]), 0.03587481358868996)
In [27]:
for j in range(len(idxs)): sm.gaps[idxs[j]].thi = orig_gaps[j] + offsets[np.argmin(rms)][j] opm.update_model() sm.gaps[-1].thi = get_focus(sm) opm.update_model() spot_plt = plt.figure(FigureClass=SpotDiagramFigure, opt_model=opm, is_dark=isdark).plot() spot_rms(sm, 0), spot_rms(sm, 1), spot_rms(sm, 2)
Out[27]:
(array([0.00465224, 0.01644699, 0.00241372]), array([0.13847349, 0.10443455, 0.11971615]), array([0.23461643, 0.22702221, 0.25881069]))
Figure
In [28]:
abr_plt = plt.figure(FigureClass=RayFanFigure, opt_model=opm, data_type='Ray', scale_type=Fit.All_Same).plot()
Figure
In [29]:
layout_plt = plt.figure(FigureClass=InteractiveLayout, opt_model=opm, is_dark=isdark).plot()
Figure
In [ ]: