DistortionResidual#

class esis.optics.DistortionResidual(instrument, parameters, scene, observation, pupil=None, axis_wavelength=None, axis_field=None, axis_channel=None, weight_correlation=1000, weight_distance=1.0, smoothing=1, sigma_psf=None, seed=0)[source]#

Bases: Printable

A least-squares residual comparing modeled images to an observation.

This is the residual-vector counterpart of DistortionObjective, suitable for scipy.optimize.least_squares(): each evaluation returns a flat vector of per-pixel residuals rather than a single scalar, which lets a Gauss-Newton optimizer exploit the structure of the problem.

The residual is built from the same comparison as DistortionObjective. For images standardized to zero mean and unit deviation, the sum of squared residuals is a monotonic function of the Pearson correlation (\(\lVert\hat a - \hat b\rVert^2 = 2N(1 - \mathrm{corr})\)), so minimizing it maximizes the correlation. The squared off-target penalty of DistortionObjective is appended as extra residual rows.

Two features make this objective usable with a derivative-based optimizer, where DistortionObjective is not:

  • Determinism. The imaging model jitters each ray within its scene cell using the global numpy random state, so it is stochastic by default. Re-seeding that state with seed before every evaluation freezes the jitter realization, making the residual a deterministic function of the parameters that finite-difference Jacobians can read. Note that this mutates the global numpy random state as a side effect; it is intended for serial use.

  • Smoothing. The images are sparse, so a sub-pixel shift can leave the residual unchanged until a feature crosses a pixel boundary. Convolving the modeled image with a sigma_psf-wide Gaussian point-spread function widens the features so that small parameter changes produce a readable gradient, while also modeling the blur that the real optics imprint on the observation. A smoothing-wide box filter applied to both images is retained as a purely numerical alternative.

Notes

In practice, scipy.optimize.least_squares() was found to under-converge on this residual for realistic scenes even with the features above: the smoothed correlation surface remains locally flat enough that the optimizer terminates after moving a small fraction of the distance to the true peak. fit_distortion_scan(), which reads the shape of the merit basin directly instead of differentiating it, is the recommended driver.

Attributes

axis_channel

The logical axis of the observation corresponding to changing camera channel.

axis_field

The logical axes of the scene corresponding to changing field position.

axis_wavelength

The logical axis of the scene corresponding to changing wavelength.

pupil

The vertices of the pupil grid used to image the scene.

seed

The seed used to freeze the imaging model's random ray jitter, so that the residual is a deterministic function of the parameters.

sigma_psf

The standard deviation, in detector pixels, of a Gaussian point-spread function convolved with the modeled image only.

smoothing

The width, in detector pixels, of the box filter applied to both images before comparing.

weight_correlation

The weight of the correlation residual relative to the off-target penalty.

weight_distance

The weight of the off-target penalty residual.

instrument

The instrument model being fit to the observation.

parameters

The prototype which defines the units and structure of the flat parameter vector, usually the initial guess of the fit.

scene

The spectral radiance of the scene as a function of wavelength and field position, imaged through the instrument on every evaluation.

observation

The observed image that the modeled image is compared against.

Methods

__init__(instrument, parameters, scene, ...)

to_string([prefix])

Public-facing version of the __repr__ method that allows for defining a prefix string, which can be used to calculate how much whitespace to add to the beginning of each line of the result.

Inheritance Diagram

Inheritance diagram of esis.optics.DistortionResidual
Parameters:
to_string(prefix=None)#

Public-facing version of the __repr__ method that allows for defining a prefix string, which can be used to calculate how much whitespace to add to the beginning of each line of the result.

Parameters:

prefix (None | str) – an optional string, the length of which is used to calculate how much whitespace to add to the result.

Return type:

str

axis_channel: None | str = None#

The logical axis of the observation corresponding to changing camera channel.

If given, each channel is standardized independently before the residual is formed, so that brightness differences between the channels do not dominate the fit. See DistortionObjective.axis_channel.

axis_field: None | tuple[str, str] = None#

The logical axes of the scene corresponding to changing field position.

axis_wavelength: None | str = None#

The logical axis of the scene corresponding to changing wavelength.

instrument: AbstractInstrument#

The instrument model being fit to the observation.

observation: AbstractScalar#

The observed image that the modeled image is compared against.

Any axes of the modeled image which are not present in this array are summed over before comparing.

parameters: DistortionParameters#

The prototype which defines the units and structure of the flat parameter vector, usually the initial guess of the fit.

pupil: None | AbstractCartesian2dVectorArray = None#

The vertices of the pupil grid used to image the scene.

scene: FunctionArray#

The spectral radiance of the scene as a function of wavelength and field position, imaged through the instrument on every evaluation.

seed: int = 0#

The seed used to freeze the imaging model’s random ray jitter, so that the residual is a deterministic function of the parameters.

sigma_psf: None | float = None#

The standard deviation, in detector pixels, of a Gaussian point-spread function convolved with the modeled image only.

The observation already carries the blur of the real optics, so applying the point-spread function to the modeled image makes the two directly comparable while also letting a sparsely-sampled raytraced image produce a smooth, differentiable residual. A value of None disables the convolution.

smoothing: None | int = 1#

The width, in detector pixels, of the box filter applied to both images before comparing. A value of None or \(\leq 1\) disables smoothing.

weight_correlation: float = 1000#

The weight of the correlation residual relative to the off-target penalty.

weight_distance: float = 1.0#

The weight of the off-target penalty residual.