Skip to content

Experiment and illumination

Experiment objects separate physical source geometry, stable source calibration, and sparse acquisition structure. Lengths are in metres and angle units are explicit in constructor names. A complete Illumination resolves atomically with Optics before compilation.

PupilAberration

PupilAberration(
    *,
    astigmatism: float = 0.0,
    coma: float = 0.0,
    spherical: float = 0.0,
    edge_apodization: float = 0.0,
)

Direct radian weights for sampled pupil-polynomial terms.

All four coefficients default to zero. The astigmatism, coma, and spherical values are direct phase weights in radians. edge_apodization controls radial amplitude decay and is not a normalized Zernike coefficient.

astigmatism property

astigmatism: float

Return the astigmatism phase weight in radians.

coma property

coma: float

Return the coma phase weight in radians.

spherical property

spherical: float

Return the spherical-aberration phase weight in radians.

edge_apodization property

edge_apodization: float

Return the nonnegative radial pupil-amplitude decay coefficient.

Optics

Optics(
    wavelength_vacuum_m: float,
    objective_na: float,
    magnification: float,
    camera_pixel_size: float,
    *,
    illumination_refractive_index: float = 1.0,
    objective_medium_refractive_index: float = 1.0,
    defocus_distance: float | None = None,
    pupil_aberration: PupilAberration | None = None,
)

Physical microscope parameters used to compile an image-plane model.

Parameters:

Name Type Description Default
wavelength_vacuum_m float

Positive vacuum illumination wavelength in metres.

required
objective_na float

Positive, dimensionless objective numerical aperture, no greater than objective_medium_refractive_index.

required
magnification float

Positive, dimensionless microscope magnification.

required
camera_pixel_size float

Positive detector-plane pixel pitch in metres. The object-plane pitch camera_pixel_size / magnification must be strictly less than wavelength_vacuum_m / (2 * objective_na) for coherent-field sampling; equality is rejected.

required
illumination_refractive_index float

Positive refractive index between the sources and sample.

1.0
objective_medium_refractive_index float

Positive refractive index on the objective side of the sample.

1.0
defocus_distance float | None

Optional signed propagation distance in metres.

None
pupil_aberration PupilAberration | None

Optional sampled pupil-aberration coefficients.

None

Raises:

Type Description
InvalidParameterError

If a parameter is non-finite or outside its physical domain, or if the object-plane detector pitch does not satisfy the coherent-field sampling condition.

wavelength_vacuum_m property

wavelength_vacuum_m: float

Return the vacuum illumination wavelength in metres.

objective_na property

objective_na: float

Return the objective numerical aperture.

magnification property

magnification: float

Return the microscope magnification.

camera_pixel_size property

camera_pixel_size: float

Return the detector-plane pixel pitch in metres.

illumination_refractive_index property

illumination_refractive_index: float

Return the source-to-sample refractive index.

objective_medium_refractive_index property

objective_medium_refractive_index: float

Return the objective-side medium refractive index.

defocus_distance property

defocus_distance: float | None

Return the optional signed propagation distance in metres.

object_pixel_size property

object_pixel_size: float

Return the validated sample-plane detector pitch in metres.

ArrayPose

Rigid array-local to sample-coordinate transform.

Rotation is active, right-handed, and extrinsic about fixed sample x, y, then z axes; the matrix acting on a column vector is Rz @ Ry @ Rx.

translation_m property

translation_m: tuple[float, float, float]

Return sample-coordinate XYZ translation in metres.

rotation_rad property

rotation_rad: tuple[float, float, float]

Return fixed-axis extrinsic XYZ rotation in radians.

identity staticmethod

identity() -> ArrayPose

Return the identity rigid transform.

from_translation staticmethod

from_translation(
    translation_m: tuple[float, float, float],
) -> ArrayPose

Create a pure translation in metres.

from_translation_and_extrinsic_xyz_radians staticmethod

from_translation_and_extrinsic_xyz_radians(
    translation_m: tuple[float, float, float],
    rotation_rad: tuple[float, float, float],
) -> ArrayPose

Create a translation and active extrinsic XYZ rotation in radians.

from_translation_and_extrinsic_xyz_degrees staticmethod

from_translation_and_extrinsic_xyz_degrees(
    translation_m: tuple[float, float, float],
    rotation_deg: tuple[float, float, float],
) -> ArrayPose

Create a translation and active extrinsic XYZ rotation in degrees.

PlanarLEDArray

PlanarLEDArray(
    shape: Shape2D,
    pitch_m: float | tuple[float, float],
    reference_index: tuple[float, float],
    pose: ArrayPose,
    *,
    position_offsets_m: FloatArray | None = None,
)

Planar LED geometry on the normally negative-z illumination side.

Parameters:

Name Type Description Default
shape Shape2D

Number of LEDs as (rows, columns).

required
pitch_m float | tuple[float, float]

Scalar equal pitch or canonical (pitch_x, pitch_y) metres.

required
reference_index tuple[float, float]

Fractional (column, row) lattice coordinate at the pose origin.

required
pose ArrayPose

Array-local to sample-coordinate rigid transform.

required
position_offsets_m FloatArray | None

Optional float64 (sources, 3) array-local XYZ corrections in metres.

None

shape property

shape: Shape2D

Return the LED-grid shape as (rows, columns).

pitch_m property

pitch_m: tuple[float, float]

Return canonical (pitch_x, pitch_y) in metres.

reference_index property

reference_index: tuple[float, float]

Return fractional (column, row) reference coordinate.

pose property

pose: ArrayPose

Return the array-local to sample-coordinate pose.

position_offsets_m property

position_offsets_m: FloatArray

Return a copy of canonical local XYZ corrections in metres.

source_count property

source_count: int

Return the number of LEDs in the grid.

source_index

source_index(row: int, column: int) -> int

Convert a lattice location to its row-major source index.

source_row_column

source_row_column(index: int) -> tuple[int, int]

Convert a row-major source index to (row, column).

resolve

resolve(optics: Optics) -> ResolvedSources

Resolve physical positions, directions, and transverse vectors.

SphericalLEDArray

SphericalLEDArray(
    angles: FloatArray,
    radius: float,
    *,
    center_offset: tuple[float, float, float] = (
        0.0,
        0.0,
        0.0,
    ),
    orientation_degrees: tuple[float, float, float] = (
        0.0,
        0.0,
        0.0,
    ),
    angular_corrections: FloatArray | None = None,
)

Fixed LEDs at arbitrary polar and azimuthal positions on a sphere.

Parameters:

Name Type Description Default
angles FloatArray

Float64 array shaped (sources, 2) containing natural-order (theta, phi) radians. theta is polar angle from positive z; phi is azimuth from positive x toward positive y.

required
radius float

Positive nominal sphere radius in metres.

required
center_offset tuple[float, float, float]

Sphere-centre displacement (x, y, z) from the sample, in metres.

(0.0, 0.0, 0.0)
orientation_degrees tuple[float, float, float]

Extrinsic mount rotations (rx, ry, rz) in degrees, applied as Rz * Ry * Rx.

(0.0, 0.0, 0.0)
angular_corrections FloatArray | None

Optional float64 (sources, 2) array of (delta_theta, delta_phi) placement corrections in radians.

None

source_count property

source_count: int

Return the number of fixed LEDs.

resolve

resolve(optics: Optics) -> ResolvedSources

Resolve physical positions, directions, and transverse vectors.

SphericalLEDArm

SphericalLEDArm(
    commanded_angles: FloatArray,
    arm_length: float,
    *,
    pivot_offset: tuple[float, float, float] = (
        0.0,
        0.0,
        0.0,
    ),
    orientation_degrees: tuple[float, float, float] = (
        0.0,
        0.0,
        0.0,
    ),
    theta_zero_degrees: float = 0.0,
    phi_zero_degrees: float = 0.0,
    theta_scale: float = 1.0,
    phi_scale: float = 1.0,
    elevation_axis_tilt_degrees: float = 0.0,
    theta_backlash_degrees: float = 0.0,
    phi_backlash_degrees: float = 0.0,
)

A single LED moved along a calibrated spherical-arm trajectory.

Parameters:

Name Type Description Default
commanded_angles FloatArray

Float64 array shaped (sources, 2) of movement-order (theta, phi) encoder commands in radians. Unwrap azimuth across branch cuts when backlash direction must remain unambiguous.

required
arm_length float

Positive pivot-to-LED distance in metres.

required
pivot_offset tuple[float, float, float]

Pivot displacement (x, y, z) from the sample, in metres.

(0.0, 0.0, 0.0)
orientation_degrees tuple[float, float, float]

Extrinsic mount rotations (rx, ry, rz) in degrees.

(0.0, 0.0, 0.0)
theta_zero_degrees float

Additive encoder-zero offsets in degrees.

0.0
phi_zero_degrees float

Additive encoder-zero offsets in degrees.

0.0
theta_scale float

Positive dimensionless encoder scales.

1.0
phi_scale float

Positive dimensionless encoder scales.

1.0
elevation_axis_tilt_degrees float

Elevation-axis non-orthogonality in degrees.

0.0
theta_backlash_degrees float

Total separation of increasing and decreasing branches in degrees.

0.0
phi_backlash_degrees float

Total separation of increasing and decreasing branches in degrees.

0.0

source_count property

source_count: int

Return the number of commanded source positions.

resolve

resolve(optics: Optics) -> ResolvedSources

Resolve movement-order positions, directions, and transverse vectors.

RotatingLEDArc

RotatingLEDArc(
    led_thetas: Sequence[float],
    rotation_angles: Sequence[float],
    radius: float,
    *,
    axis_origin_offset: tuple[float, float, float] = (
        0.0,
        0.0,
        0.0,
    ),
    axis_tilt_degrees: tuple[float, float] = (0.0, 0.0),
    led_angular_corrections: FloatArray | None = None,
    led_radial_offsets: Sequence[float] | None = None,
    rotation_zero_degrees: float = 0.0,
    rotation_scale: float = 1.0,
    rotation_backlash_degrees: float = 0.0,
)

A quarter-circle LED arc sampled at commanded axial rotations.

Every LED is compiled at every rotation. Sources are ordered rotation-major, then in led_thetas order.

Parameters:

Name Type Description Default
led_thetas Sequence[float]

Natural-order LED polar angles from positive z, in radians.

required
rotation_angles Sequence[float]

Movement-order arm azimuth commands in radians.

required
radius float

Positive nominal arc radius in metres.

required
axis_origin_offset tuple[float, float, float]

Point on the rotation axis relative to the sample, in metres.

(0.0, 0.0, 0.0)
axis_tilt_degrees tuple[float, float]

Extrinsic (x, y) rotation-axis tilts in degrees.

(0.0, 0.0)
led_angular_corrections FloatArray | None

Optional (leds, 2) array of (delta_theta, delta_phi) radians.

None
led_radial_offsets Sequence[float] | None

Optional per-LED radial corrections in metres.

None
rotation_zero_degrees float

Additive rotation-encoder zero offset in degrees.

0.0
rotation_scale float

Positive dimensionless rotation-encoder scale.

1.0
rotation_backlash_degrees float

Total separation of increasing and decreasing branches in degrees.

0.0

led_count property

led_count: int

Return the number of LEDs along the arc.

rotation_count property

rotation_count: int

Return the number of commanded arc rotations.

source_count property

source_count: int

Return led_count * rotation_count compiled source positions.

resolve

resolve(optics: Optics) -> ResolvedSources

Resolve rotation-major positions, directions, and transverse vectors.

SourcePositionList

SourcePositionList(positions_m: FloatArray)

Wavelength-independent physical source positions in sample coordinates.

The sample is at z=0, illumination sources are normally at z<0, and propagation points from each source toward the sample origin.

positions_m property

positions_m: FloatArray

Return a copy shaped (sources, 3) in metres.

source_count property

source_count: int

Return the number of positions.

resolve

resolve(optics: Optics) -> ResolvedSources

Resolve source-to-sample directions and transverse vectors.

DirectionList

DirectionList(unit_vectors: FloatArray)

Canonical positive-z propagation unit vectors in sample coordinates.

source_count property

source_count: int

Return the number of canonical directions.

unit_vectors property

unit_vectors: FloatArray

Return a float64 copy shaped (sources, 3).

direction_cosines property

direction_cosines: FloatArray

Return derived float64 (dx, dy) direction cosines.

component_angles_rad property

component_angles_rad: FloatArray

Return derived independent component angles in radians.

component_angles_deg property

component_angles_deg: FloatArray

Return derived independent component angles in degrees.

polar_angles_rad property

polar_angles_rad: FloatArray

Return derived positive-z polar angles in radians.

polar_angles_deg property

polar_angles_deg: FloatArray

Return derived positive-z polar angles in degrees.

from_unit_vectors staticmethod

from_unit_vectors(values: FloatArray) -> DirectionList

Validate and store float64 (sources, 3) unit vectors.

from_vectors staticmethod

from_vectors(
    values: FloatArray, *, normalize: bool = True
) -> DirectionList

Store vectors, normalizing each row when requested.

from_direction_cosines staticmethod

from_direction_cosines(values: FloatArray) -> DirectionList

Construct from (dx, dy) and the positive square-root dz.

from_component_angles_radians staticmethod

from_component_angles_radians(
    values: FloatArray,
) -> DirectionList

Construct from independent (theta_x, theta_y) radians.

from_component_angles_degrees staticmethod

from_component_angles_degrees(
    values: FloatArray,
) -> DirectionList

Construct from independent (theta_x, theta_y) degrees.

from_polar_angles_radians staticmethod

from_polar_angles_radians(
    values: FloatArray,
) -> DirectionList

Construct from positive-z polar (theta, phi) radians.

from_polar_angles_degrees staticmethod

from_polar_angles_degrees(
    values: FloatArray,
) -> DirectionList

Construct from positive-z polar (theta, phi) degrees.

resolve

resolve(optics: Optics) -> ResolvedSources

Resolve directions using the optics illumination wavenumber.

KVectorList

KVectorList(k_vectors: FloatArray)

Calibrated transverse illumination vectors in acquisition order.

k_vectors must have float64 shape (sources, 2) and units of radians per metre. Compilation validates that each vector represents a propagating wave for the supplied optics.

source_count property

source_count: int

Return the number of calibrated source vectors.

k_vectors property

k_vectors: FloatArray

Return a float64 (sources, 2) copy in radians per metre.

resolve

resolve(optics: Optics) -> ResolvedSources

Validate propagation and derive positive-z directions.

Geometry module-attribute

Geometry: TypeAlias

Concrete source geometry accepted by SourceGeometry and Illumination.

SourceGeometry

SourceGeometry(value: Geometry)

Inspectable enum wrapper around one concrete source geometry.

source_count property

source_count: int

Return the physical or direct source count.

kind property

kind: str

Return the canonical serialized geometry-kind string.

resolve

resolve(optics: Optics) -> ResolvedSources

Resolve this geometry with the supplied optical configuration.

SourceCalibration

SourceCalibration(
    *, relative_power: Sequence[float] | None = None
)

Stable source power independent of geometry and frame ordering.

Relative power is dimensionless, non-negative, not normalized, and multiplies predicted intensity rather than field amplitude.

relative_power property

relative_power: list[float] | None

Return explicit powers, or None for default unit power.

unity staticmethod

unity() -> SourceCalibration

Return calibration that resolves to unit power for every source.

SourceContribution

SourceContribution(source: int, intensity_weight: float)

One source index and non-negative intensity weight.

source property

source: int

Return the zero-based physical source index.

intensity_weight property

intensity_weight: float

Return the dimensionless source intensity multiplier.

IlluminationFrame

IlluminationFrame(
    contributions: Sequence[tuple[int, float]],
    *,
    gain: float = 1.0,
)

Sparse mutually incoherent source contributions and a frame gain.

contributions property

contributions: list[SourceContribution]

Return source contributions in stored order.

gain property

gain: float

Return the dimensionless frame intensity gain.

AcquisitionPlan

Canonical sparse source-to-frame acquisition structure.

Duplicate source entries are merged, zero weights removed, and every weight and gain must be finite and non-negative. Weights are not normalized.

frame_count property

frame_count: int

Return the number of acquisition frames.

frames property

frames: list[IlluminationFrame]

Return copies of canonical sparse frames.

all_sources staticmethod

all_sources(source_count: int) -> AcquisitionPlan

Create one unit-gain frame per source in natural order.

sequential staticmethod

sequential(order: Sequence[int]) -> AcquisitionPlan

Create unit-gain frames for an arbitrary subset or repeated order.

from_sparse staticmethod

from_sparse(
    frames: Sequence[IlluminationFrame],
) -> AcquisitionPlan

Validate and canonicalize sparse frame contributions.

from_dense staticmethod

from_dense(weights: FloatArray) -> AcquisitionPlan

Convert a float64 (frames, sources) matrix to sparse storage.

dense_weights

dense_weights(source_count: int) -> FloatArray

Allocate a float64 (frames, sources) weight matrix.

Illumination

Illumination(
    geometry: Geometry | SourceGeometry,
    *,
    calibration: SourceCalibration | None = None,
    acquisition: AcquisitionPlan | None = None,
)

Complete geometry, stable calibration, and acquisition description.

Resolution is atomic. Predicted frame intensity is gain[f] * sum_s(weight[f,s] * relative_power[s] * I_s).

geometry property

geometry: SourceGeometry

Return an inspectable copy of the source geometry wrapper.

calibration property

calibration: SourceCalibration

Return a copy of stable source calibration.

acquisition property

acquisition: AcquisitionPlan

Return a copy of canonical sparse acquisition structure.

resolve

resolve(optics: Optics) -> ResolvedIllumination

Atomically resolve geometry, powers, weights, and gains.

ResolvedSources

Read-only source directions, vectors, and optional physical positions.

source_count property

source_count: int

Return the resolved source count.

directions property

directions: FloatArray

Return float64 propagation unit vectors shaped (sources, 3).

k_vectors property

k_vectors: FloatArray

Return float64 transverse vectors shaped (sources, 2) in rad/m.

positions_m property

positions_m: FloatArray | None

Return physical XYZ positions in metres, or None when undefined.

ResolvedFrame

Validated sparse contributions for one resolved acquisition frame.

contributions property

contributions: list[SourceContribution]

Return canonical source-indexed intensity contributions.

gain property

gain: float

Return the explicit non-negative frame gain.

ResolvedIllumination

Inspectable illumination state resolved for a particular Optics.

sources property

sources: ResolvedSources

Return a copy of resolved source geometry.

source_count property

source_count: int

Return the number of individual sources.

frame_count property

frame_count: int

Return the independently defined acquisition-frame count.

is_multiplexed property

is_multiplexed: bool

Return whether any frame combines multiple incoherent sources.

frames property

frames: list[ResolvedFrame]

Return copies of resolved canonical sparse frames.

source_power property

source_power: FloatArray

Return explicit source powers, including resolved unit defaults.

frame_gains property

frame_gains: FloatArray

Return explicit frame gains, including resolved unit defaults.

directions property

directions: FloatArray

Return float64 propagation directions shaped (sources, 3).

positions_m property

positions_m: FloatArray | None

Return physical XYZ positions in metres when defined.

k_vectors property

k_vectors: FloatArray

Return transverse vectors shaped (sources, 2) in radians/metre.

dense_weights property

dense_weights: FloatArray

Allocate acquisition weights shaped (frames, sources).