You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Import OSLO Cartesian Jones elements with consistent native polarized power transport #955
OSLO LEN prescriptions can attach a Cartesian Jones polarization element to a surface through JAA/JAB/JAC/JAD amplitudes and JPA/JPB/JPC/JPD phases. The importer currently diagnoses those commands rather than retaining the element. Existing native polarization infrastructure can represent this without a parallel file-format-specific ray model, but several core transport behaviors must also be corrected for imported elements to be reliable.
The required native behavior is:
A reusable CartesianJonesCoating applies finite complex X/Y field coefficients in the surface's local Cartesian frame, retaining its local Z field. This is distinct from a matrix in the ray's incidence-plane s/p basis. Reuse existing ConstantJones construction and BaseCoating native dispatch, and serialize the four complex coefficients as real/imaginary pairs.
Coordinate transformations rotate the output-field rows of PolarizedRays.p along with positions and directions, while keeping the initial source-field basis fixed. A tilted local element must therefore act in the correct physical axes.
Polarization-independent intensity losses and clipping must update retained scalar power, so update_intensity or get_exit_fields cannot restore absorbed or clipped light. Add one shared attenuate operation used by simple coatings, homogeneous propagation and phase efficiency.
Distinguish a polarizer blocking one incident state from a permanently extinguished ray. Re-evaluating a different input state may transmit through the former, but must never revive the latter. Extinguished rays remain dark after later invalid intersections, while invalid powered-ray results remain visible. Keep supported live-field gradients finite.
These native changes and independent NumPy/Torch tests should be kept in a core commit, followed by an OSLO mapping commit in the same feature PR. The importer converts phase degrees to complex coefficients with identity defaults, validates finite scalar values and nonnegative amplitudes, and rejects object-surface elements. Source polarization remains an explicit caller choice. Native save/reload retains the element; the OSLO writer must reject unsupported coating export before overwriting a destination.
Reuse the native polarization JSON work already delivered by #947 unchanged. Do not introduce another source-state representation or compatibility code for older unmerged iterations. Document field frames, intensity-versus-amplitude units, component responsibilities and callers in the API/developer/OSLO guides.
Validation should cover independent analytic field and intensity expectations, refraction/reflection, tilted elements, per-ray rotations, scalar absorption and efficiency, repeated source-state evaluation, clipping before geometry misses, native persistence and malformed matrices, NumPy/Torch and Torch-free operation, gradients and unchanged golden optical regressions. Review CI-configured changed-line coverage separately from supplementary branch coverage.
The OSLO Program Reference, printed pp. 106–107 defines its coefficient order, degree phases, identity defaults and unchanged Z convention. Existing closed #502 concerns earlier native polarizer API/axis issues, and closed #823 concerns visualization of extinct rays; neither covers this OSLO mapping and retained-power work. The issue search found no matching current issue.
These examples show why the native transport changes are needed. The tutorial will teach the two designs and their intended behavior; the before/after evidence is recorded here.
1. A single ideal fold mirror
A vertically polarized collimated beam travels along global +Z, reflects from a plane mirror tilted by -45 degrees about X, and leaves along -Y. The mirror has unit scalar reflectance in this comparison.
Expected: the outgoing electric field is transverse to the outgoing ray. In the scalar-coating transport convention it points along +Z, with unit power and |E dot k| = 0 (with floating point accuracy this becomes < 1e-14 in practice).
Current incorrect behavior in the measured master revision: the field remains along +Y, parallel to the outgoing ray: |E dot k| = 1. Power and ray geometry alone look correct. This example exercises field-frame rotation together with transport of the reflection bend through a scalar coating.
2. A polarizer in the existing Cooke triplet
An ideal polarizer is inserted midway through the first air gap of the three-element CookeTriplet sample, retaining the original lens spacings, six refracting faces and glass absorption. The input is horizontal. Rotating the polarizer's surface frame about Z rotates its local-X transmission axis.
Expected: the on-axis chief ray follows Malus's law: normalized power is 1, 0.75, 0.5, 0.25 and 0 at 0, 30, 45, 60 and 90 degrees.
Current incorrect behavior in the measured master revision: rotating the surface frame leaves normalized chief-ray power at 1 for every angle. Rotating the coating axis explicitly in an unrotated frame already responds to angle; the corrected implementation makes these physically equivalent descriptions agree.
The comparison uses actual traces of master 302f8f4a65c2c0eef51e0be406825ede0e8e78e3 and the candidate core at local revision 29c79d37, in NumPy and CPU Torch float64, at 0.55 microns. “Before” denotes that master revision; “after” denotes the corrected candidate. Each triplet curve is normalized by its own aligned result, separating the orientation error from the retained scalar-loss correction. Equivalent-axis descriptions are also checked for four half-radius pupil rays; the simple Malus formula applies to the chief ray at normal incidence. Geometry and optical paths agree before/after. These are idealized simulations, not measurements of manufactured optics.
Activity
fix(polarization): preserve native field frames and scalar power (#985)