6.3. tracer Submodule

6.3.1. tracer.base_class

class optrace.tracer.base_class.BaseClass(desc='', long_desc='')

common parent class for almost all optrace.tracer classes. Features description properties as well as methods for making the object read-only (kind of)

Parameters:
  • desc (str) – compact description

  • long_desc (str) – verbose description

copy()
Returns:

a fully independent copy

Return type:

Self

crepr()

Compact state representation using only lists and immutable types. Used to compare states of BaseClass objects. np.ndarray is only compared for a size < 20, so either ignore these changes or make the arrays read only.

Returns:

compact representation list

Return type:

list

get_desc(fallback='')

get a short description :param fallback: description string if the object has no desc :return: compact description

Parameters:

fallback (str)

Return type:

str

get_long_desc(fallback='')

get a longer, more verbose description :param fallback: description string if the object has no desc and long_desc :return: verbose description

Parameters:

fallback (str)

Return type:

str

lock()

make storage and object read only

Return type:

None

6.3.2. tracer.convolve

optrace.tracer.convolve.convolve(img, psf, m=1, keep_size=False, padding_mode='constant', padding_value=None, cargs={})

Convolve an image with a point spread function.

Different convolution cases: 1. Grayscale image and PSF: Img and PSF are GrayscaleImage -> result is also GrayscaleImage 2. Image grayscale or spectrally homogeneous, PSF has color information: Img GrayscaleImage, PSF RenderImage -> result is RGBImage 3. Image has color information, PSF is color independent: Image RGBImage, PSF GrayscaleImage -> result is RGBImage 4. Image has color information, PSF has color information: Image RGBImage, PSF list of R, G, B RenderImage rendered for the sRGB primary R, G, B preset spectra with the correct power ratios -> result is RGBImage

The system magnification factor m scales the image before convolution. abs(m) > 1 means enlargement, abs(m) < 1 size reduction, m < 0 image flipping, m > 0 an upright image.

See the documentation for more details.

As the convolution requires values outside the initial image, a suitable padding method must be set. By default, padding_mode=’constant’ and padding_value are zeros. Padding modes from numpy.pad are supported. padding_value is only needed for the ‘constant’ mode. It must have three elements if img is an RGBImage, and one otherwise.

If a result with the same side lengths and pixel count as the input is desired, parameter keep_size must be set to True so the image is cropped back to its original shape.

Provide cargs=dict(normalize=False) so the output image intensities are not normalized automatically. Useful for images without bright regions.

In the internals of this function the convolution is done in linear sRGB values, while also using values outside the sRGB gamut. To remove this out-of-gamut colors in the resulting image, color transformations are performed. Parameter cargs overwrites parameters for color.xyz_to_srgb. By default these parameters are: dict(rendering_intent=”Absolute”, normalize=True, clip=True, L_th=0, chroma_scale=None). For instance, specify cargs=dict(normalize=False) to turn off normalization, but all other parameters unchanged

Parameters:
  • img (RGBImage | GrayscaleImage) – initial image as either RGBImage or GrayscaleImage

  • psf (GrayscaleImage | RenderImage | list[RenderImage]) – point spread function, GrayscaleImage, RenderImage or three element list of R, G, B RenderImage

  • m (float) – magnification factor

  • keep_size (bool) – if output image should be cropped back to size of the input image

  • padding_mode (str) – padding mode (from numpy.pad) for image padding before convolution.

  • padding_value (list | float) – padding value for padding_mode=’constant’. Three elements if img is a RGBImage, single element otherwise. Defaults to zeros.

  • cargs (dict) – overwrite for parameters for color.xyz_to_srgb. By default these parameters are: dict(rendering_intent=”Absolute”, normalize=True, clip=True, L_th=0, chroma_scale=None). For instance, specify cargs=dict(normalize=False) to turn off normalization, but all other parameters unchanged

Returns:

GrayscaleImage or RGBImage, see above

Return type:

RGBImage | GrayscaleImage

6.3.3. tracer.load

optrace.tracer.load.load_agf(path)

Load an .agf material catalogue

Parameters:

path (str) – filepath

Returns:

dictionary of refractive media, keys are names, values are RefractionIndex objects

Return type:

dict

optrace.tracer.load.load_zmx(filename, n_dict=None, no_marker=False)

Load a ZEMAX geometry from a .zmx into a Group. See the documentation on the limitations of the import.

Parameters:
  • filename (str) – filepath

  • n_dict (dict) – dictionary of RefractiveIndex in the geometry

  • no_marker (bool) – if there should be no marker created for the .zmx description

Returns:

Group including the geometry from the .zmx

Return type:

Group

6.3.4. tracer.misc

optrace.tracer.misc.cpu_count()

Number of logical cpu cores assigned to this process (Python >= 3.13) Number of logical cpu cores (Python < 3.13) Can be overriden by setting the PYTHON_CPU_COUNT environment variable or running python -X cpucores Setting by PYTHON_CPU_COUNT must be between 1-64.

Returns:

cpu count

Return type:

int

optrace.tracer.misc.cross(a, b)

faster alternative to numpy.cross() for 3 element vectors and axis=1

Parameters:
  • a (ndarray) – first array, shape (N, 3)

  • b (ndarray) – second array, shape (N, 3)

Returns:

cross product, shape (N, 3)

Return type:

ndarray

>>> cross(np.array([[1., 2., 3.], [4., 5., 6.]]), np.array([[-1., 2., -3.], [7., 8., 9.]]))
array([[-12.,   0.,   4.],
       [ -3.,   6.,  -3.]])
optrace.tracer.misc.masked_assign(cond1, cond2)

set True values of bool mask cond1 to values of cond2, returns resulting mask

Parameters:
Returns:

1D array with shape of cond1

Return type:

ndarray

>>> masked_assign(np.array([True, False, False, True]), np.array([True, False]))
array([ True, False, False, False], dtype=bool)
optrace.tracer.misc.normalize(a)

faster vector normalization for vectors in axis=1. Zero length vectors can normalized to np.nan.

Parameters:

a (ndarray) – array to normalize, shape (N, 3)

Returns:

normalized values, shape (N, 3)

Return type:

ndarray

>>> a = np.array([[1., 2., 3.], [4., 5., 6.]])
>>> normalize(a)
array([[...0.26726124, 0.53452248, 0.80178373],
       [...0.45584231, 0.56980288, 0.68376346]])
optrace.tracer.misc.rdot(a, b)

row wise scalar product for two or three dimension. Coordinate values in matrix columns. For (N, 2) and (N, 3) faster than np.einsum(‘ij,ij->i’, a, b) and (a*b).sum(axis=1)

Parameters:
  • a (ndarray) – 2D matrix, with shape (N, 2) or (N, 3)

  • b (ndarray) – 2D matrix, with shape (N, 2) or (N, 3)

Returns:

result vector, shape (N, )

Return type:

ndarray

>>> rdot(np.array([[1., 2., 3.], [4., 5., 6.]]), np.array([[-1., 2., -3.], [7., 8., 9.]]))
array([ -6., 122.])
>>> rdot(np.array([[2., 3.], [4., 5.]]), np.array([[-1., 2.], [8., 9.]]))
array([ 4., 77.])
optrace.tracer.misc.timer(func)

timing wrapper for function timings write a @timer decorator around a function to time it

Parameters:

func (Callable) – function to wrap

Returns:

function return value

Return type:

Any

6.3.5. tracer.ray_storage

class optrace.tracer.ray_storage.RayStorage(**kwargs)

RayStorage is a class storing all rays and their properties

Parameters:

kwargs – additional keyword arguments for the parent class

static storage_size(N, nt, no_pol)

Calculate required RAM used for the ray properties (without actually creating anything).

Parameters:
  • N (int) – number of rays

  • nt (int) – number of sections per ray

  • no_pol (bool) – polarization calculation turned off

Returns:

approximate size in bytes

Return type:

int

direction_vectors(normalize=True)

Normalized or unnormalized direction ray vectors for each ray and ray section

Parameters:

normalize (bool) – if direction vectors should be normalized

Returns:

direction vectors, shape (N, 3)

Return type:

ndarray

init(ray_source_list, N, nt, no_pol)

Initialize the Storage

Parameters:
  • ray_source_list (list[RaySource]) – list of ray sources

  • N (int) – number of rays

  • nt (int) – number of ray sections per ray

  • no_pol (bool) – if polarizations are generated

Return type:

None

optical_lengths(ch=None, ch2=None)

Optical lengths of the ray sections

Parameters:
  • ch (ndarray) – bool array selecting the desired rays, shape N. Default to None, meaning all rays are selected

  • ch2 (ndarray) – int array selecting the desired ray sections. Needs to be the same shape as the number of true values in ch. Defaults to None, meaning all sections per ray are selected

Returns:

Optical path length for each ray section, shape (N, nt)

Return type:

ndarray

ray_lengths(ch=None, ch2=None)

Euclidean lengths of the ray sections.

Parameters:
  • ch (ndarray) – bool array selecting the desired rays, shape N. Default to None, meaning all rays are selected

  • ch2 (ndarray) – int array selecting the desired ray sections. Needs to be the same shape as the number of true values in ch. Defaults to None, meaning all sections per ray are selected

Returns:

length array with shape (N, nt)

Return type:

ndarray

rays_by_mask(ch=None, ch2=None, ret=None, normalize=True)

Get ray properties for the selected rays and ray sections.

Parameters:
  • ch (ndarray) – bool array selecting the desired rays, shape N. Default to None, meaning all rays are selected

  • ch2 (ndarray) – int array selecting the desired ray sections. Needs to be the same shape as the number of true values in ch. Defaults to None, meaning all sections per ray are selected

  • ret (list[bool | int]) – a list of seven boolean elements, specifying if the corresponding return value needs to be masked/calculated. Generally it is recommended to only set values to True, if they are needed

  • normalize (bool) – if ray directions should be normalized

Returns:

list of properties (p, s, pol, w, wl, snum, n) with shape resulting from choices of ch and ch2

Return type:

tuple[ndarray | None, ndarray | None, ndarray | None, ndarray | None, ndarray | None, ndarray | None, ndarray | None]

source_numbers()

Ray source numbers for each ray

Returns:

ray source numbers

Return type:

ndarray

source_sections(index=None)

Return the source sections of each ray.

Parameters:

index (int) – source index, None if all rays should be returned

Returns:

tuple of ray properties (p, s, pol, w, wl)

Return type:

tuple[ndarray, ndarray, ndarray, ndarray, ndarray]

thread_rays(N_threads, Nt)

Create the rays for the current thread

Parameters:
  • N_threads (int) – number of threads

  • Nt (int) – current thread

Returns:

references to the ray properties (p, s, pol, w, wl, n)

Return type:

tuple[ndarray, ndarray, ndarray, ndarray, ndarray, ndarray]

B_list

list of boundary positions between sources

property N: int

number of rays

N_list

list of rays assigned to each source

property Nt: int

number of ray sections per ray

n_list

refractive index values, shape (N, nt)

p_list

ray positions, shape (N, nt, 3)

pol_list

ray polarizations, shape (N, nt, 3)

ray_source_list

list of ray sources

s0_list

initial ray directions, shape (N, 3)

w_list

ray weights, shape (N, nt)

wl_list

ray wavelengths, shape (N, )

6.3.6. tracer.raytracer

class optrace.tracer.raytracer.Raytracer(outline, n0=None, no_pol=False, use_hurb=False, **kwargs)

Initialize the raytracer

Parameters:
  • outline (list | ndarray) – outline of raytracer space [x1, x2, y1, y2, z1, z2] (numpy 1D array or list)

  • n0 (RefractionIndex) – refraction index of the raytracer environment (RefractionIndex object)

  • no_pol (bool) – if polarization should be neglected to speed things up

  • use_hurb (bool)

class INFOS(*values)
ABSORB_MISSING = 0
HURB_NEG_DIR = 5
ILL_COND = 3
OUTLINE_INTERSECTION = 4
TIR = 1
T_BELOW_TTH = 2
static check_collision(front, back, res=100)

Check for surface/point/line collisions. A collision is defined as the front surface havin a higher z-value than the back surface, at a point where both surfaces are defined

Parameters:
  • front (Surface | Line | Point) – first object (in regards to z-position)

  • back (Surface | Line | Point) – second object

  • res (int) – resolution measure, increase for better detection

Returns:

bool value if there is a collision, collision x-value array, collision y-value array, collision z-value array

Return type:

tuple[bool, ndarray, ndarray, ndarray]

check_if_rays_are_current()

Check if anything tracing relevant changed since the last trace.

Return type:

bool

clear()

clear geometry and rays

Return type:

None

compare_property_snapshot(h1, h2)

Compare two snapshots of property_snapshot and detect changes

Parameters:
  • h1 (dict) – snapshot 1

  • h2 (dict) – snapshot 2

Returns:

dictionary of changes

Return type:

dict

detector_image(detector_index=0, source_index=None, extent=None, limit=None, projection_method='Equidistant', **kwargs)

Render a detector image for a traced geometry

Parameters:
  • detector_index (int) – index/number of the detector

  • source_index (int) – index/number of the source. By default all sources are used.

  • extent (list | ndarray) – rectangular extent [x0, x1, y0, y1] to detect to intersections in. By default the whole detector are is used.

  • projection_method (str) – sphere projection method for a SphericalSurface detector

  • limit (float) – resolution limit filter constant, see the documentation. Defaults to no filter.

  • kwargs – keyword arguments for creating the RenderImage

Returns:

rendered RenderImage

Return type:

RenderImage

detector_spectrum(detector_index=0, source_index=None, extent=None, **kwargs)

Render a detector spectrum for a traced geometry.

Parameters:
  • detector_index (int) – index/number of the detector

  • source_index (int) – index/number of the source. By default all sources are used.

  • extent (list | ndarray) – rectangular extent [x0, x1, y0, y1] to detect to intersections in. By default the whole detector are is used.

  • kwargs – optional keyword arguments for the created LightSpectrum

Returns:

rendered LightSpectrum

Return type:

LightSpectrum

Find the focal point using different methods. z_start defines the starting point, the search range is the region between a lens, filter, aperture or the outline. Outline intersections of rays are ignored.

Parameters:
  • method (str) – focussing method from “focus_search_methods”

  • z_start (float) – starting position z (float)

  • source_index (int) – source number, defaults to None, so rays from all sources are used

  • return_cost (bool) – If a cost function value array should be included in the output dictionary. Needed for plotting of the cost function. Deactivate to increase performance for some methods.

Returns:

scipy optimize result and property dictionary

Return type:

tuple[OptimizeResult, dict]

iterative_render(N, detector_index=0, limit=None, projection_method='Equidistant', pos=None, extent=None)

Image render with N_rays rays. First returned value is a list of rendered sources, the second a list of rendered detector images.

If pos is not provided, a single detector image is rendered at the position of the detector specified by detector_index. >> RT.iterative_render(N=10000, detector_index=1)

If pos is provided as coordinate, the detector is moved beforehand. >> RT.iterative_render(N=10000, pos=[0, 1, 0], detector_index=1)

If pos is a list, len(pos) detector images are rendered. All other parameters are either automatically repeated len(pos) times or can be specified as list with the same length as pos. Exemplary calls: >> RT.iterative_render(N=10000, pos=[[0, 1, 0], [2, 2, 10]], detector_index=1) >> RT.iterative_render(N=10000, pos=[[0, 1, 0], [2, 2, 10]], detector_index=[0, 1], extent=[None, [-2, 2, -2, 2]])

N_px_S can also be provided as list, note however, that when provided as list it needs to have the same length as the number of sources.

This functions raises an exception if the geometry is incorrect.

Parameters:
  • N (int | float) – number of rays

  • detector_index (int | list) – number/list of detector indices

  • pos (int | list) – 3D position(s) of the detector(s)

  • limit (float | list) – list/resolution limits for detector images

  • projection_method (str | list) – type/list of projection methods for SphericalSurface

  • extent (list | ndarray) – list/value for the extent of the detector images

Returns:

list of rendered detector images

Return type:

list[RenderImage]

property_snapshot()

Creates a snapshot of properties of Elements and rays. Needed to detect changes.

Returns:

dictionary of properties

Return type:

dict

source_image(source_index=0, limit=None, **kwargs)

Render a source image for a source in a traced geometry.

Parameters:
  • source_index (int) – source number, defaults to 0

  • limit (float) – resolution filter limit constant, see the documentation. Defaults to not filter

  • kwargs – optional keyword arguments for creating the RenderImage

Returns:

rendered RenderImage

Return type:

RenderImage

source_spectrum(source_index=0, **kwargs)

Render a LightSpectrum for a source in a traced geometry.

Parameters:
  • source_index (int) – source number, default to 0

  • kwargs – optional keyword arguments for the creation of the LightSpectrum

Returns:

rendered LightSpectrum

Return type:

LightSpectrum

trace(N)

Execute raytracing for the current geometry

Shows a warning on geometry errors, but does not throw an exception. This is useful in the TraceGUI, as the broken geometry can be displayed.

Parameters:

N (int) – number of rays (int)

Return type:

None

tracing_snapshot()

Creates a snapshot of properties of rays and Elements relevant for tracing. Needed to detect changes since the last trace.

Returns:

dictionary of properties

Return type:

dict

HURB_FACTOR: float = 1.4142135623730951

HURB uncertainty factor. Scales the tangent uncertainty expression. Original sources use 1, but sqrt(2) matches the envelope better. See the documentation for details.

ITER_RAYS_STEP: int = 1000000

number of rays per iteration in Raytracer.iterative_render()

MAX_RAY_STORAGE_RAM: int = 8000000000

Maximum available RAM for the stored rays

N_EPS: float = 1e-11

numerical epsilon. Used for floating number comparisions in some places or adding small differences

T_TH: float = 1e-05

threshold for the transmission Filter values below this are handled as absorbed needed to avoid ghost rays, meaning rays that have a non-zero, but negligible power

property extent

equals the outline of the raytracer

focus_search_methods: list[str, str, str] = ['RMS Spot Size', 'Irradiance Variance', 'Image Sharpness', 'Image Center Sharpness']

available focus_search methods

geometry_error

if geometry checks returned an error

no_pol

polarization calculation flag

outline

geometrical raytracer outline

property pos

center position of front xy-outline plane

rays

traced rays

use_hurb

flag for using Heisenberg uncertainty ray bending on apertures

6.3.7. tracer.refraction_index

class optrace.tracer.refraction_index.RefractionIndex(n_type='Constant', n=1.0, coeff=None, lines=None, V=None, **kwargs)

Create a RefractionIndex object of type “n_type”. See the documentation on information on how to provide all parameters correctly.

Parameters:
  • n_type (str) – one of “n_types”

  • n (float) – refraction index for n_type=”Constant”

  • V (float) – Abbe number for n_type=”Abbe”

  • coeff (list) – list of coefficients for the model, see the documentation

  • lines (ndarray | list) – spectral lines to use for n_type=”Abbe”, list of 3 wavelengths [short wavelength, center wavelength, long wavelength]

__call__(wl)

Returns the refractive index at specified wavelengths. Call on obj using obj(wavelengths).

Parameters:

wl (list | ndarray | float) – wavelengths in nm (numpy 1D array)

Returns:

array of refraction indices

Return type:

ndarray

__eq__(other)

Equal operator. Compares self to ‘other’.

Parameters:

other (Any) – object to compare to

Returns:

if both are equal

Return type:

bool

__ne__(other)

Not-equal operator. Compares self to ‘other’.

Parameters:

other (Any) – object to compare to

Returns:

if both are not equal

Return type:

bool

abbe_number(lines=None)

Calculates the Abbe Number. The spectral lines can be overwritten with the parameter. Otherwise the RefractionIndex.lines parameter is used from its initialization, which defaults to FDC lines.

Parameters:

lines (list) – list of 3 wavelengths [short, center, long]

Returns:

Return type:

float

is_dispersive()
Returns:

if the refractive index is dispersive, determined by the Abbe Number

Return type:

bool

coeff_count = {'Cauchy': 4, 'Conrady': 3, 'Extended': 8, 'Extended2': 8, 'Extended3': 9, 'Handbook of Optics 1': 4, 'Handbook of Optics 2': 4, 'Herzberger': 6, 'Schott': 6, 'Sellmeier1': 6, 'Sellmeier2': 5, 'Sellmeier3': 8, 'Sellmeier4': 5, 'Sellmeier5': 10}

number of coefficients for the different refractive index models

n_types: list[str] = ['Abbe', 'Cauchy', 'Conrady', 'Constant', 'Data', 'Extended', 'Extended2', 'Extended3', 'Function', 'Handbook of Optics 1', 'Handbook of Optics 2', 'Sellmeier1', 'Sellmeier2', 'Sellmeier3', 'Sellmeier4', 'Sellmeier5', 'Herzberger', 'Schott']

possible refractive index types

quantity: str = 'Refraction Index n'

physical quantity

spectrum_types: list[str] = ['Abbe', 'Cauchy', 'Conrady', 'Constant', 'Data', 'Extended', 'Extended2', 'Extended3', 'Function', 'Handbook of Optics 1', 'Handbook of Optics 2', 'Sellmeier1', 'Sellmeier2', 'Sellmeier3', 'Sellmeier4', 'Sellmeier5', 'Herzberger', 'Schott']

possible spectrum types. Can be changed by subclasses

unit: str = ''

physical unit

6.3.8. tracer.transfer_matrix_analysis

class optrace.tracer.transfer_matrix_analysis.TMA(lenses, wl=555.0, n0=None, **kwargs)

Create an ray transfer matrix analysis object. This is a snapshot of properties for when the object gets created, nothing is updated after that.

With no lenses the abcd matrix is a unity matrix and all other properties are set to nan

Parameters:
  • lenses (list) – list of Lens

  • wl (float) – wavelength to create the analysis for

  • n0 (RefractionIndex) – ambient medium before the lens setup

  • kwargs – additional keyword arguments for the parent class

image_magnification(z_g)

get the image magnification at the image plane for a given object distance

Parameters:

z_g – z-position of object

Returns:

magnification factor (image size divided by object size)

Return type:

float

image_position(z_g)

get the image position for a object distance

Parameters:

z_g – z-position of object

Returns:

absolute image z-position

Return type:

float

matrix_at(z_g, z_b)

Calculate the ABCD matrix for an object position z_g and image position z_b

Parameters:
  • z_g (float) – object z-position

  • z_b (float) – image z-position

Returns:

ABCD matrix, 2x2 numpy array

Return type:

ndarray

object_magnification(z_b)

get the object magnification at the object plane for a given image distance

Parameters:

z_g – z-position of object

Returns:

magnification factor (image size divided by object size)

Return type:

float

object_position(z_b)

get the object position for a given image position

Parameters:

z_b – z-position of image

Returns:

z-position of object

Return type:

float

pupil_magnification(z_s)

Calculate the entrance and exit pupil magnifications for a given aperture stop position.

Parameters:
  • z_p – absolute stop position

  • z_s (float)

Returns:

entrance and exit pupil magnifications

Return type:

tuple[float, float]

pupil_position(z_s)

Calculate the entrance and exit pupil positions for a given aperture stop position.

Parameters:
  • z_p – absolute stop position

  • z_s (float)

Returns:

entrance and exit pupil positions

Return type:

tuple[float, float]

abcd

abcd matrix for matrix ray optics calculations

bfl: float

front focal length, Distance between front focal point and front surface vertex

d: float

center thickness of the lens

efl: float

effective focal length

efl_n: float

effective focal length

ffl: float

back focal length, Distance between back focal point and back surface vertex point

focal_lengths: tuple[float, float]

focal lengths of the lens

focal_lengths_n: tuple[float, float]

focal lengths with different definition, see the documentation

focal_points: tuple[float, float]

z-position of focal points

n1: float

refraction index value before the lens setup

n2: float

refraction index value after the lens setup

nodal_points: tuple[float, float]

z-position of nodal points

optical_center

optical center of the setup

powers: tuple[float, float]

optical powers of the lens, inverse of focal length

powers_n: tuple[float, float]

different definition for the optical powers. The optical powers is scaled with the ambient index for each side. Mainly used in ophthalmic optics. This definition has the advantage, that both powers always have the same magnitude, but only different signs.

principal_points: tuple[float, float]

z-position of principal points

vertex_points: tuple[float, float]

z-position of vertex points

wl

wavelength for the analysis