Skip to content

v3.5.0

Choose a tag to compare

@roytsmart roytsmart released this 22 Oct 14:03
750803a

This release lets the pieces of an aperture act as one aperture, and stops the warnings that every model of a silicon sensor printed. It has the same requirements as 3.4.

It changes the interface for subclasses of AbstractAperture outside optika (see below). Code that only uses optika's apertures is unaffected.

Compound apertures (#264)

AbstractAperture has a new keyword-only field, axis_compound. When it names an axis that the parameters of an aperture vary along, the pieces along that axis act as one aperture instead of an array of separate ones. Closes #261.

  • The rule: a point passes if it is inside at least one active, non-inverted piece (or there are none) and outside every active, inverted one. Openings form a union, like the segments of a mirror. Obscurations all have to be cleared, like the fiducials on a slit mask. An inverted that varies along the axis mixes the two, as in an opening with an obscuration in it.
  • Shape and bounds: shape leaves the compound axis out, and bound_lower and bound_upper are the min and max over it, so the axis never reaches the rays of a surface. wire and vertices keep it, so plots and DXF files draw every piece, and LinearSystem.footprint of a compound field stop gives one outline per piece.
  • Checks: an aperture raises a ValueError if none of its parameters vary along axis_compound, so a misspelled name is caught, and if the points it is called with vary along it. SequentialSystem raises a ValueError for a field or pupil stop with a compound axis, since a stop is solved from a single outline.
  • Without it: with axis_compound=None, the default, an aperture behaves as before, and an axis it varies along is still an array of separate apertures, such as a slit array.
  • Example: the Giant Magellan Telescope example of CircularAperture now sets axis_compound="segment" and draws the combined mask.
  • Speed: on the slit mask of MUSE, one surface carrying its six fiducials as a compound RectangularAperture traces identically to six surfaces, ray for ray, and the fiducials cost 2.3 s of the trace instead of 9.6 s. An aperture that is not active anywhere now skips the test for every kind of aperture, not only polygons. An aperture without a compound axis is as fast as in 3.4 or faster: a circle takes the same time, and a rectangle less than half.

For subclasses of AbstractAperture outside optika: __call__, shape, bound_lower and bound_upper are now concrete, and apply the transformation, inverted, active and axis_compound of every aperture in one place. A subclass now implements these instead:

  • _inside(position): whether points in the local coordinates of the aperture are inside its outline, regardless of active and inverted;
  • _shape_parameters: the broadcast shape of its parameters, including axis_compound;
  • _bound_lower and _bound_upper: the bounds of each piece.

No package in sun-data subclasses an aperture.

Limitations:

  • Same kind of piece: the pieces are one kind of aperture with different parameters. A circle and a square can't be combined yet.
  • Stops: a field or pupil stop can't have a compound axis.
  • Bounds span every piece, including obscurations and inactive pieces, as they do for an aperture without a compound axis.

Quieter sensor models and imports (#263)

  • energy_pair and fano_factor in optika.sensors no longer warn of a divide by zero or an invalid value on every call, and nor does everything built on them: quantum_yield_ideal, vmr_signal, the sensor materials, and LinearSystem.image_from_weights. The warnings came from table entries below the band gap that are never interpolated. The results are unchanged. Closes #257.
  • optika.materials.snells_law_scalar strips the units from the refractive indices, as it already did from the cosine of the angle of incidence, so astropy no longer warns that sqrt is not known to Quantity. The results are unchanged.
  • import optika no longer loads PyMuPDF, which loads ONNX Runtime, which is slow and logs GetPciBusId on GitHub's runners. optika.targets.airforce() imports it when called.

Full Changelog: v3.4.0...v3.5.0