Skip to content

Commit

Permalink
Modified optika.systems.SequentialSystem.rayfunction() to return re…
Browse files Browse the repository at this point in the history
…sults in sensor coordinates instead of global coordinates. (#94)
  • Loading branch information
byrdie authored Oct 11, 2024
1 parent 4c58433 commit 3d9f081
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 12 deletions.
1 change: 1 addition & 0 deletions optika/_tests/test_systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ def test_rayfunction_default(self, a: optika.systems.AbstractSequentialSystem):
axis_pixel=na.Cartesian2dVectorArray("detector_x", "detector_y"),
timedelta_exposure=1 * u.s,
num_pixel=na.Cartesian2dVectorArray(128, 128),
transformation=na.transformations.Cartesian3dTranslation(z=1 * u.mm),
is_field_stop=True,
)

Expand Down
5 changes: 1 addition & 4 deletions optika/sensors/_sensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def readout(
Parameters
----------
rays
A set of incident rays in global coordinates to measure.
A set of incident rays in local coordinates to measure.
timedelta
The exposure time of the measurement.
If :obj:`None` (the default), the value in :attr:`timedelta_exposure`
Expand All @@ -114,9 +114,6 @@ def readout(
if timedelta is None:
timedelta = self.timedelta_exposure

if self.transformation is not None:
rays = self.transformation.inverse(rays)

where = where & rays.unvignetted

rays = dataclasses.replace(
Expand Down
30 changes: 22 additions & 8 deletions optika/systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,8 +603,8 @@ def raytrace(
) -> optika.rays.RayFunctionArray:
"""
Given the wavelength, field position, and pupil position of some input
rays, trace those rays through the system and return the result,
including all intermediate rays.
rays, trace those rays through the system and return the result in
global coordinates, including all intermediate rays.
Parameters
----------
Expand Down Expand Up @@ -634,7 +634,8 @@ def raytrace(
See Also
--------
rayfunction : Similar to `raytrace` except it only returns the rays at the last surface.
rayfunction : Similar to `raytrace` except it only returns the rays at
the last surface in local coordinates.
"""

if axis is None:
Expand Down Expand Up @@ -683,7 +684,7 @@ def rayfunction(
"""
Given the wavelength, field position, and pupil position of some input
rays, trace those rays through the system and return the resulting
rays at the last surface.
rays in local coordinates at the last surface.
Parameters
----------
Expand All @@ -710,7 +711,8 @@ def rayfunction(
See Also
--------
raytrace : Similar to `rayfunction` except it computes all the intermediate rays.
raytrace : Similar to `rayfunction` except it computes all the
intermediate rays, and it returns results in global coordinates.
"""

axis = "_dummy"
Expand All @@ -723,13 +725,25 @@ def rayfunction(
normalized_field=normalized_field,
normalized_pupil=normalized_pupil,
)
return raytrace[{axis: ~0}]
rayfunction = raytrace[{axis: ~0}]
rays = rayfunction.outputs

if self.sensor.transformation is not None:
rays = self.sensor.transformation.inverse(rays)

rayfunction.outputs = rays

return rayfunction

@functools.cached_property
def rayfunction_default(self) -> optika.rays.RayFunctionArray:
"""
Computes the rays at the last surface in the system as a function of
input wavelength and position using :attr:`grid_input`.
Computes the rays in local coordinates at the last surface in the system
as a function of input wavelength and position using :attr:`grid_input`.
This property is cached to increase performance.
If :attr:`grid_input` is updated, the cache must be cleared with
``del system.rayfunction_default`` before calling property.
"""
return self.rayfunction()

Expand Down

0 comments on commit 3d9f081

Please sign in to comment.