v2.4.0
A system can show the outline of its field and its pupil, not only the corners. field_boundary and pupil_boundary return the traced edge, and field_min/field_max and their pupil counterparts are now reductions over it. This is what lets a caller measure a field of view edge to edge rather than corner to corner (#209).
A multilayer stack can be interpolated over the angle of incidence. Solving the transfer matrices costs far more than the raytrace it belongs to, and the response is smooth over the small range of angle any one surface covers, so a handful of nodes stands in for it (#210).
area_effective averages over the field positions inside the field stop rather than over every position in the grid, including those wholly outside it which contribute zero. vignetting was already doing this, and LinearSystem multiplies the two, so the product only reconstructs the effective area if both are taken over the same set of positions (#207).
A depletion model is no longer shaped by the measurement it was fitted to (#213). Together with named-arrays 2.8, which honours a shape a class declares for itself, this is what lets a sensor material carry a measured quantum efficiency and a measured charge capture sampled at different wavelengths. That release is now the minimum this package requires.
linearize solves for the stops once instead of four times, and traces once for the distortion, the vignetting, and the angle at which light strikes the sensor, instead of three times (#211, #212). A test checks that linearizing a system conserves flux (#208).
Releases from here on are published through Trusted Publishing and carry PEP 740 provenance (#215).