-
I am new with ray-optics (python as well). sm.add_surface([7.77, 0.55, 1.493, '', 5.0]) But this will give error If I put v-number value, it goes well. How to add surface with constant refractive_index? Thanks in advance for any help. |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 14 replies
-
Beta Was this translation helpful? Give feedback.
-
Hello and thank you for your well explained question. I think there may be some issues with add_surface and how it's supposed to work. I'm working on addressing this case better.
It appeared from your description that there were 3 different materials used in the model; I used Medium2 in 3 places based on it's placement in your drawing. With regards to your second question, I think the set_vignetting function might be used here. I'll think about that tomorrow. |
Beta Was this translation helpful? Give feedback.
-
Here's a jupyter notebook addressing the 3 parts of this discussion/issue. The notebook is in the ray-optics-notebooks repo. %matplotlib inline from rayoptics.environment import *
from rayoptics.seq import medium # shortcut reference to medium package isdark = False opm = OpticalModel()
sm = opm['seq_model']
osp = opm['optical_spec']
pm = opm['parax_model']
em = opm['ele_model']
pt = opm['part_tree']
ar = opm['analysis_results'] # add analysis results model for paraxial data osp['pupil'] = PupilSpec(osp, key=['object', 'pupil'], value=3)
osp['fov'] = FieldSpec(osp, key=['object', 'angle'], value=5.0, flds=[0.],is_relative=True)
osp['wvls'] = WvlSpec([(546.074, 1.0)], ref_wl=0)
opm.radius_mode = True 1) Model with constant index materialsCreating a model with constant index materialsThe add_surface() fct can't easily be used to create a constant refractive index material. sm.gaps[0].thi=1e10
sm.add_surface([7.77, 0.55, 1.376, 56., 5.])
sm.gaps[sm.cur_surface].medium = medium.Medium(1.376, 'Medium1')
sm.add_surface([6.8, 3.4, 1.336, 56., 5.])
sm.gaps[sm.cur_surface].medium = med2 = medium.Medium(1.336, 'Medium2')
sm.add_surface([0., 1.6, 1.336, 56., 3.])
sm.gaps[sm.cur_surface].medium = med2
sm.set_stop()
sm.add_surface([20., 0.7, 1.5, 56., 3.])
sm.gaps[sm.cur_surface].medium = medium.Medium(1.5, 'Medium3')
sm.add_surface([-20., 21., 1.336, 56., 3.])
sm.gaps[sm.cur_surface].medium = med2
sm.add_surface([0., 0.])
sm.ifcs[sm.cur_surface].max_aperture = 3.
sm.ifcs[-1].max_aperture = 3. sm.do_apertures = False
opm.update_model()
sm.list_model()
2) Setting pupil size based on the stop sizeUse set_vignettingThe set_vignetting function ensures the bundle defining rays at each field point pass thru the edge of the most limiting aperture in the model. In this case the stop surface is the limiting aperture. set_vignetting(opm) Negative vignetting means rays overfill pupil to fill stopListing the object properties for the field points shows negative vignetting values. This means the entrance pupil is undersized and the vignetting is overfilling the pupil to fill the aperture stop. listobj(osp['pupil'])
listobj(osp['fov'])
Marginal ray traceTrace the marginal ray for the axial field point. fi = 0
fld, wvl, foc = osp.lookup_fld_wvl_focus(fi)
pupil = [0., 1.]
ray01, ray_op01, wvl = trace_base(opm, pupil, fld, wvl)
list_ray(ray01)
Revise entrance pupil diameterGet the ray height on the first surface. For an infinite object, this is the pupil radius. rs1 = RaySeg(*ray01[1])
epd = 2*abs(rs1.p[1])
epd
osp['pupil'].value = epd opm.update_model() listobj(osp['fov'])
Finish pupil redefinitionThe pupil size has been redefined so the vignetting needs to be updated as well. The values to overfill the pupil are still in place. set_vignetting can fix this up. set_vignetting(opm) listobj(osp['pupil'])
listobj(osp['fov'])
Lens layoutThe lens layout doesn't look too bad. It considers the model to be a set of cemented elements for the purposes of drawing a picture. layout_plt = plt.figure(FigureClass=InteractiveLayout, opt_model=opm,
do_draw_rays=True, do_draw_ray_fans=True, do_paraxial_layout=False, is_dark=isdark).plot() 3) Longitudinal spherical aberrationCalculation approachThe general approach to calculating longitudinal spherical would be to:
img_seg = RaySeg(*ray01[-1]) img_seg.p, img_seg.d
LSA = -img_seg.p[1]/(img_seg.d[1]/img_seg.d[2])
LSA
efl = ar['parax_data'].fod.efl corrected_efl = efl + LSA/2
efl, corrected_efl
pm.list_model()
pm.first_order_data()
Longitudinal Spherical Aberration plotTrace the raysUse the RayFan primitive to easily trace a fan of rays across the pupil. ray_fan = analyses.RayFan(opm, f=fld, wl=wvl, xyfan='y') ray_list, _ = ray_fan.fan_pkg Postprocess the ray fanLoop over the rays and calculate the LSA for each rays x = []
y = []
for r in ray_list:
px, py, rs = r
ray, _, _ = rs
img = ray[-1]
lsa = -img.p[1]/(img.d[1]/img.d[2])
x.append(lsa)
y.append(ray[3].p[1]) # stop surface ray height Plot using Matplotlibplt.plot(x,y)
|
Beta Was this translation helpful? Give feedback.
-
Dear Michael,
I hope you are doing well. It has been a while since you last provided
guidance on the constant index and setting pupil size based on the stop
size.
I want to thank you for your package, as it has been very helpful for my
work.
Recently, I upgraded my PC and installed an updated version of Python,
including newer versions of various packages. I also upgraded ray-optics to
version 0.8.7. I tried to upgrade to version 0.9.0, but encountered some
errors, so I am currently using version 0.8.7.
According to the changelog, there are new features in this version that are
relevant to my needs:
Move functionality in medium into the opticalglass, especially for working
with a constant index.
The set_pupil() function to set the pupil specification based on the
aperture stop size.
I searched the documentation, but I could not find any examples on how to
implement these features. Could you please provide me with a revised
version of the program using these new features? The program is shown below
and is also available on GitHub:
https://github.com/mjhoptics/ray-optics-notebooks/blob/master/Issue92_const_index.ipynb
.
I look forward to your reply. Thank you for your assistance.
Sincerely,
Tjundewo Lawu
…On Tue, Jul 26, 2022 at 11:23 AM Michael Hayford ***@***.***> wrote:
Here's a jupyter notebook addressing the 3 parts of this discussion/issue.
The notebook is in the ray-optics-notebooks repo
<https://github.com/mjhoptics/ray-optics-notebooks/blob/master/Issue92_const_index.ipynb>
.
%matplotlib inline
from rayoptics.environment import *from rayoptics.seq import medium # shortcut reference to medium package
isdark = False
opm = OpticalModel()sm = opm['seq_model']osp = opm['optical_spec']pm = opm['parax_model']em = opm['ele_model']pt = opm['part_tree']ar = opm['analysis_results'] # add analysis results model for paraxial data
osp['pupil'] = PupilSpec(osp, key=['object', 'pupil'], value=3)osp['fov'] = FieldSpec(osp, key=['object', 'angle'], value=5.0, flds=[0.],is_relative=True)osp['wvls'] = WvlSpec([(546.074, 1.0)], ref_wl=0)
opm.radius_mode = True
1) Model with constant index materials Creating a model with constant
index materials
The add_surface() fct can't easily be used to create a constant refractive
index material.
Use the index and a "fake" V-number to satisfy add_surface().
Then directly create and assign the constant index Medium to the
appropriate gaps.
sm.gaps[0].thi=1e10sm.add_surface([7.77, 0.55, 1.376, 56., 5.])sm.gaps[sm.cur_surface].medium = medium.Medium(1.376, 'Medium1')sm.add_surface([6.8, 3.4, 1.336, 56., 5.])sm.gaps[sm.cur_surface].medium = med2 = medium.Medium(1.336, 'Medium2')sm.add_surface([0., 1.6, 1.336, 56., 3.])sm.gaps[sm.cur_surface].medium = med2sm.set_stop()sm.add_surface([20., 0.7, 1.5, 56., 3.])sm.gaps[sm.cur_surface].medium = medium.Medium(1.5, 'Medium3')sm.add_surface([-20., 21., 1.336, 56., 3.])sm.gaps[sm.cur_surface].medium = med2sm.add_surface([0., 0.])sm.ifcs[sm.cur_surface].max_aperture = 3.sm.ifcs[-1].max_aperture = 3.
sm.do_apertures = Falseopm.update_model()sm.list_model()
r t medium mode zdr sd
Obj: 0.000000 1.00000e+10 air 1 1.0000
1: 7.770000 0.550000 Medium1 1 5.0000
2: 6.800000 3.40000 Medium2 1 5.0000
Stop: 0.000000 1.60000 Medium2 1 3.0000
4: 20.000000 0.700000 Medium3 1 3.0000
5: -20.000000 21.0000 Medium2 1 3.0000
6: 0.000000 0.00000 air 1 3.0000
Img: 0.000000 0.00000 1 3.0000
2) Setting pupil size based on the stop size Use set_vignetting
The set_vignetting function ensures the bundle defining rays at each field
point pass thru the edge of the most limiting aperture in the model. In
this case the stop surface is the limiting aperture.
set_vignetting(opm)
Negative vignetting means rays overfill pupil to fill stop
Listing the object properties for the field points shows negative
vignetting values. This means the entrance pupil is undersized and the
vignetting is overfilling the pupil to fill the aperture stop.
listobj(osp['pupil'])listobj(osp['fov'])
aperture: object pupil; value=3
field: object angle; value=0.0
x,y=0.0 vlx=-1.253 vux=-1.253 vly=-1.253 vuy=-1.253
Marginal ray trace
Trace the marginal ray for the axial field point.
fi = 0fld, wvl, foc = osp.lookup_fld_wvl_focus(fi)
pupil = [0., 1.]ray01, ray_op01, wvl = trace_base(opm, pupil, fld, wvl)list_ray(ray01)
X Y Z L M N Len
0: 0.00000 0.00000 0 0.000000 0.000000 1.000000 1e+10
1: 0.00000 3.37918 0.77329 0.000000 -0.128001 0.991774 0.63518
2: 0.00000 3.29788 0.85324 0.000000 -0.116173 0.993229 2.5641
3: 0.00000 3.00000 0 0.000000 -0.116173 0.993229 1.8078
4: 0.00000 2.78998 0.19556 0.000000 -0.118727 0.992927 0.31638
5: 0.00000 2.75242 -0.1903 0.000000 -0.150843 0.988558 21.436
6: 0.00000 -0.48100 0 0.000000 -0.201527 0.979483 0
7: 0.00000 -0.48100 0 0.000000 -0.201527 0.979483 0
Revise entrance pupil diameter
Get the ray height on the first surface. For an infinite object, this is
the pupil radius.
rs1 = RaySeg(*ray01[1])epd = 2*abs(rs1.p[1])epd
6.758369049845509
osp['pupil'].value = epd
opm.update_model()
listobj(osp['fov'])
field: object angle; value=0.0
x,y=0.0 vlx=-1.253 vux=-1.253 vly=-1.253 vuy=-1.253
Finish pupil redefinition
The pupil size has been redefined so the vignetting needs to be updated as
well. The values to overfill the pupil are still in place. set_vignetting
can fix this up.
set_vignetting(opm)
listobj(osp['pupil'])listobj(osp['fov'])
aperture: object pupil; value=6.758369049845509
field: object angle; value=0.0
x,y=0.0 vlx=-0.000 vux=-0.000 vly=-0.000 vuy=-0.000
Lens layout
The lens layout doesn't look too bad. It considers the model to be a set
of cemented elements for the purposes of drawing a picture.
layout_plt = plt.figure(FigureClass=InteractiveLayout, opt_model=opm,
do_draw_rays=True, do_draw_ray_fans=True, do_paraxial_layout=False, is_dark=isdark).plot()
[image: output_25_0]
<https://user-images.githubusercontent.com/33294031/180906681-30952f18-a3ed-433f-aa28-220e7c74dce2.png>
3) Longitudinal spherical aberration Calculation approach
The general approach to calculating longitudinal spherical would be to:
1. get the ray data at the image plane
img_seg = RaySeg(*ray01[-1])
img_seg.p, img_seg.d
(array([ 0. , -0.48099593, 0. ]),
array([ 0. , -0.20152687, 0.97948299]))
2.
divide the ray height at the image plane by the ray direction tangent.
3.
I assume negative means inward from the image plane for LSA
LSA = -img_seg.p[1]/(img_seg.d[1]/img_seg.d[2])LSA
-2.337789122532606
efl = ar['parax_data'].fod.efl
corrected_efl = efl + LSA/2efl, corrected_efl
(17.888918967654664, 16.72002440638836)
pm.list_model()
ax_ht pr_ht ax_slp pr_slp power tau index type
0: 0 -1.74551e+08 3.37918e-10 0.0174551 0 1e+10 1.00000 dummy
1: 3.37918 -0.0590504 -0.163523 0.0203126 0.04839125 0.399709 1.37600 transmit
2: 3.31382 -0.0509313 -0.14403 0.020013 -0.005882353 2.54491 1.33600 transmit
3: 2.94728 1.31406e-08 -0.14403 0.020013 0 1.1976 1.33600 transmit
4: 2.77479 0.0239677 -0.166783 0.0198165 0.0082 0.466667 1.50000 transmit
5: 2.69696 0.0332153 -0.188898 0.0195441 0.0082 15.7186 1.33600 transmit
6: -0.272251 0.34042 -0.188898 0.0195441 -0 0 1.00000 transmit
7: -0.272251 0.34042 -0.188898 0.0195441 0 0 1.00000 dummy
pm.first_order_data()
efl 17.89
ffl -16.65
pp1 1.242
bfl -1.441
ppk 19.33
f/# 2.647
m -1.789e-09
red -5.59e+08
obj_dist 1e+10
obj_ang 1
enp_dist 3.383
enp_radius 3.379
na obj 3.379e-10
n obj 1
img_dist -1.441
img_ht 0.3123
exp_dist -18.86
exp_radius 3.018
na img -0.1856
n img 1
optical invariant 0.05898
Longitudinal Spherical Aberration plot Trace the rays
Use the RayFan primitive to easily trace a fan of rays across the pupil.
ray_fan = analyses.RayFan(opm, f=fld, wl=wvl, xyfan='y')
ray_list, _ = ray_fan.fan_pkg
Postprocess the ray fan
Loop over the rays and calculate the LSA for each rays
x = []y = []for r in ray_list:
px, py, rs = r
ray, _, _ = rs
img = ray[-1]
lsa = -img.p[1]/(img.d[1]/img.d[2])
x.append(lsa)
y.append(ray[3].p[1]) # stop surface ray height
Plot using Matplotlib
plt.plot(x,y)
[<matplotlib.lines.Line2D at 0x7f9631e22fd0>]
[image: output_43_1]
<https://user-images.githubusercontent.com/33294031/180906559-a6f82107-2a80-4263-97da-ae1cd151d753.png>
—
Reply to this email directly, view it on GitHub
<#92 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AZ7WNCKHSJ54KDDMFOG2KMLVV5D2PANCNFSM54NSLRUQ>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Dear Mike,
Take your time.
My main issue was not the version, but more with the usage of set_pupil()
and opticalglass.
I have done with opticalglass, but still don't know how to implement
set_pupil() for pupil based on STOP size.
Now, I am using your past response approach using set_vignetting()
It works, but I think it could be a more straightforward and easy approach
using set_pupil().
I hope you can assist me.
I am not in a hurry, take your time.
Thank you.
Tjundewo Lawu
…On Thu, Jun 27, 2024 at 1:59 PM Michael Hayford ***@***.***> wrote:
I am on the road and unable to perform any tests. Please see this response
<#150 (comment)>
for a problem that has been reported on numpy version.
Thanks,
Mike Hayford
—
Reply to this email directly, view it on GitHub
<#92 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AZ7WNCL2E2D3ZXFQMQFCTP3ZJOL4HAVCNFSM6AAAAABJYFCKTOVHI2DSMVQWIX3LMV43SRDJONRXK43TNFXW4Q3PNVWWK3TUHM4TQOBZGYZTM>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Dear Mike,
Thank you for your kindness to help me out.
I will work with your advice and will reach you again if I am facing any
problems.
I think it will be good for now.
Best regards,
Tjundewo Lawu
…On Thu, Jul 18, 2024 at 2:10 PM Michael Hayford ***@***.***> wrote:
Hello @TLawu <https://github.com/TLawu>,
Thank you for your patience. Below is a notebook that shows the use of
set_pupil and the resulting lens layout and longitudinal spherical
aberration calculation. Please let me know if you have any questions or
encounter any problems.
Mike
%matplotlib inlinefrom rayoptics.environment import *isdark = False
opm = OpticalModel()sm = opm['seq_model']osp = opm['optical_spec']pm = opm['parax_model']em = opm['ele_model']pt = opm['part_tree']ar = opm['analysis_results'] # add analysis results model for paraxial data
osp['pupil'] = PupilSpec(osp, key=['object', 'epd'], value=3)osp['fov'] = FieldSpec(osp, key=['object', 'angle'], value=5.0, flds=[0.], is_relative=True)osp['wvls'] = WvlSpec([(546.074, 1.0)], ref_wl=0)
opm.radius_mode = True
1) Model with constant index materials Creating a model with constant
index materials
The add_surface() fct can' now be used to create a constant refractive
index material.
In this mode, the surface semi-diameter must be entered as a keyword
argument.
Note that the object and image surface are created when the OpticalModel
is created, and don't need an add_surface to add them.
sm.do_apertures = Falsesm.gaps[0].thi=1e10sm.add_surface([7.77, 0.55, 1.376], sd=5.)sm.add_surface([6.8, 3.4, 1.336], sd=5.)sm.add_surface([0., 1.6, 1.336], sd=3.)sm.set_stop()sm.add_surface([20., 0.7, 1.5], sd=3.)sm.add_surface([-20., 21., 1.336], sd=3.)
opm.update_model()sm.list_model()
r t medium mode zdr sd
Obj: 0.000000 1.00000e+10 air 1 1.0000
1: 7.770000 0.550000 n:1.376 1 5.0000
2: 6.800000 3.40000 n:1.336 1 5.0000
Stop: 0.000000 1.60000 n:1.336 1 3.0000
4: 20.000000 0.700000 n:1.500 1 3.0000
5: -20.000000 21.0000 n:1.336 1 3.0000
Img: 0.000000 0.00000 1 1.0000
2) Setting pupil size based on the stop size
There's a specific function for this now!
set_pupil(opm)
[0. 2.25278968]
Listing the aperture and field data indicates there pupil size has been
adjusted and the field shows no vignetting.
listobj(osp['pupil'])listobj(osp['fov'])
aperture: object epd; value=6.758369051519793
field: object angle; value=0.0
x,y=0.0 vlx= 0.000 vux= 0.000 vly= 0.000 vuy= 0.000
Lens layout
The lens layout doesn't look too bad. It considers the model to be a set
of cemented elements for the purposes of drawing a picture.
layout_plt = plt.figure(FigureClass=InteractiveLayout, opt_model=opm,
do_draw_rays=True, do_draw_ray_fans=True, do_paraxial_layout=False, is_dark=isdark).plot()
output_14_0.png (view on web)
<https://github.com/user-attachments/assets/edabd0b9-14b3-4ae6-857d-c9ef0c991881>
3) Longitudinal spherical aberration Calculation approach
The general approach to calculating longitudinal spherical would be to:
1. get the ray data at the image plane
fi = 0fld, wvl, foc = osp.lookup_fld_wvl_focus(fi)
pupil = [0., 1.]ray_pkg01 = trace_ray(opm, pupil, fld, wvl, output_filter=None, rayerr_filter=None)ray01, ray_op01, wvl = ray_pkg01[0]list_ray(ray01)
X Y Z L M N Len
0: 0.00000 3.37918 0 0.000000 0.000000 1.000000 1e+10
1: 0.00000 3.37918 0.77329 0.000000 -0.128001 0.991774 0.63518
2: 0.00000 3.29788 0.85324 0.000000 -0.116173 0.993229 2.5641
3: 0.00000 3.00000 0 0.000000 -0.116173 0.993229 1.8078
4: 0.00000 2.78998 0.19556 0.000000 -0.118727 0.992927 0.31638
5: 0.00000 2.75242 -0.1903 0.000000 -0.150843 0.988558 21.436
6: 0.00000 -0.48100 0 0.000000 -0.150843 0.988558 0
img_seg = ray01[-1]
img_seg.p, img_seg.d
(array([ 0. , -0.48099593, 0. ]),
array([ 0. , -0.15084347, 0.98855766]))
2.
divide the ray height at the image plane by the ray direction tangent.
3.
I assume negative means inward from the image plane for LSA
LSA = -img_seg.p[1]/(img_seg.d[1]/img_seg.d[2])print(f"{LSA=:10.4f}")
LSA= -3.1522
efl = ar['parax_data'].fod.efl
corrected_efl = efl + LSA/2print(f"{efl=:8.4f} {corrected_efl=:8.4f}")
efl= 23.8996 corrected_efl= 22.3235
pm.list_model()
ax_ht pr_ht ax_slp pr_slp power tau index type
0: 0 -1.74551e+08 3.37918e-10 0.0174551 0 1e+10 1.00000 dummy
1: 3.37918 -0.0590504 -0.163523 0.0203126 0.04839125 0.399709 1.37600 transmit
2: 3.31382 -0.0509313 -0.14403 0.020013 -0.005882353 2.54491 1.33600 transmit
3: 2.94728 1.31406e-08 -0.14403 0.020013 0 1.1976 1.33600 transmit
4: 2.77479 0.0239677 -0.166783 0.0198165 0.0082 0.466667 1.50000 transmit
5: 2.69696 0.0332153 -0.188898 0.0195441 0.0082 15.7186 1.33600 transmit
6: -0.272251 0.34042 -0.188898 0.0195441 0 0 1.33600 dummy
pm.first_order_data()
efl 23.9
f 17.89
f' 23.9
ffl -16.65
pp1 1.242
bfl 19.07
ppk -4.825
pp sep 0.1828
f/# 2.647
m -1.789e-09
red -5.59e+08
obj_dist 1e+10
obj_ang 1
enp_dist 3.383
enp_radius 3.379
na obj 3.379e-10
n obj 1
img_dist 19.07
img_ht 0.3123
exp_dist -4.196
exp_radius 3.018
na img -0.187
n img 1.336
optical invariant 0.05898
Longitudinal Spherical Aberration plot Trace the rays
Use the RayFan primitive to easily trace a fan of rays across the pupil.
ray_fan = analyses.RayFan(opm, f=fld, wl=wvl, xyfan='y')
ray_list, _ = ray_fan.fan_pkg
Postprocess the ray fan
Loop over the rays and calculate the LSA for each rays
x = []y = []for r in ray_list:
px, py, rs = r
ray, _, _ = rs
img = ray[-1]
lsa = -img.p[1]/(img.d[1]/img.d[2])
x.append(lsa)
y.append(ray[3].p[1]) # stop surface ray height
Plot using Matplotlib
plt.plot(x,y)plt.show()
output_33_0.png (view on web)
<https://github.com/user-attachments/assets/a94ed9be-7de6-4477-aa24-63f0ea51f6a8>
shift image plane to paraxial focus
ax_ray = ar['parax_data'].ax_ray
prx_img_dist = -ax_ray[-1][mc.ht]/ax_ray[-1][mc.slp]print(f"{prx_img_dist=:10.4f}")
prx_img_dist= -1.9255
sm.gaps[-1].thi += prx_img_distopm.update_model()
sm.list_model()
r t medium mode zdr sd
Obj: 0.000000 1.00000e+10 air 1 1.0000
1: 7.770000 0.550000 n:1.376 1 5.0000
2: 6.800000 3.40000 n:1.336 1 5.0000
Stop: 0.000000 1.60000 n:1.336 1 3.0000
4: 20.000000 0.700000 n:1.500 1 3.0000
5: -20.000000 19.0745 n:1.336 1 3.0000
Img: 0.000000 0.00000 1 1.0000
ray_fan = analyses.RayFan(opm, f=fld, wl=wvl, xyfan='y')
ray_list, _ = ray_fan.fan_pkg
Postprocess the ray fan
Loop over the rays and calculate the LSA for each rays
x = []y = []for r in ray_list:
px, py, rs = r
ray, _, _ = rs
img = ray[-1]
lsa = -img.p[1]/(img.d[1]/img.d[2])
x.append(lsa)
y.append(ray[3].p[1]) # stop surface ray height
Plot using Matplotlib
plt.plot(x,y)plt.show()
output_45_0.png (view on web)
<https://github.com/user-attachments/assets/6ce348e9-fe23-4c68-be83-11ee670c702d>
—
Reply to this email directly, view it on GitHub
<#92 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AZ7WNCKXOHUF4VD6BPEYWUDZM5E2RAVCNFSM6AAAAABJYFCKTOVHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTAMBYGAYDSNY>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
Here's a jupyter notebook addressing the 3 parts of this discussion/issue. The notebook is in the ray-optics-notebooks repo.