@photivra/engine 1.5.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +414 -6
- package/CITATION.cff +1 -1
- package/NODE_SUPPORT.md +64 -12
- package/README.md +301 -182
- package/SECURITY.md +37 -28
- package/THIRD_PARTY.md +148 -4
- package/dist/camera/equivalent-focal-length.d.ts +13 -14
- package/dist/camera/equivalent-focal-length.js +15 -13
- package/dist/camera/equivalent-focal-length.js.map +1 -1
- package/dist/camera/field-of-view.d.ts +30 -19
- package/dist/camera/field-of-view.js +67 -18
- package/dist/camera/field-of-view.js.map +1 -1
- package/dist/camera/lens-projection.d.ts +170 -0
- package/dist/camera/lens-projection.js +444 -0
- package/dist/camera/lens-projection.js.map +1 -0
- package/dist/camera/projected-object-size.d.ts +10 -11
- package/dist/camera/projected-object-size.js +12 -10
- package/dist/camera/projected-object-size.js.map +1 -1
- package/dist/capture/capture-export-metadata.d.ts +9 -10
- package/dist/capture/capture-export-metadata.js +8 -5
- package/dist/capture/capture-export-metadata.js.map +1 -1
- package/dist/capture/dng-import.d.ts +91 -0
- package/dist/capture/dng-import.js +343 -0
- package/dist/capture/dng-import.js.map +1 -0
- package/dist/capture/environment-raw-producer.d.ts +37 -17
- package/dist/capture/environment-raw-producer.js +43 -19
- package/dist/capture/environment-raw-producer.js.map +1 -1
- package/dist/capture/export-jpeg.d.ts +35 -4
- package/dist/capture/export-jpeg.js +133 -47
- package/dist/capture/export-jpeg.js.map +1 -1
- package/dist/capture/export-tiff.d.ts +48 -24
- package/dist/capture/export-tiff.js +91 -31
- package/dist/capture/export-tiff.js.map +1 -1
- package/dist/capture/focus-control.d.ts +42 -65
- package/dist/capture/focus-control.js +56 -75
- package/dist/capture/focus-control.js.map +1 -1
- package/dist/capture/host-yield-cadence.d.ts +25 -0
- package/dist/capture/host-yield-cadence.js +25 -0
- package/dist/capture/host-yield-cadence.js.map +1 -0
- package/dist/capture/linear-encoding.d.ts +14 -12
- package/dist/capture/linear-encoding.js +14 -13
- package/dist/capture/linear-encoding.js.map +1 -1
- package/dist/capture/lossless-jpeg.d.ts +27 -0
- package/dist/capture/lossless-jpeg.js +237 -0
- package/dist/capture/lossless-jpeg.js.map +1 -0
- package/dist/capture/native-environment-lean.d.ts +227 -0
- package/dist/capture/native-environment-lean.js +974 -0
- package/dist/capture/native-environment-lean.js.map +1 -0
- package/dist/capture/native-environment-optical-stage.d.ts +97 -0
- package/dist/capture/native-environment-optical-stage.js +340 -0
- package/dist/capture/native-environment-optical-stage.js.map +1 -0
- package/dist/capture/native-environment-raw.d.ts +140 -6
- package/dist/capture/native-environment-raw.js +435 -34
- package/dist/capture/native-environment-raw.js.map +1 -1
- package/dist/capture/native-raw-development.d.ts +116 -9
- package/dist/capture/native-raw-development.js +221 -62
- package/dist/capture/native-raw-development.js.map +1 -1
- package/dist/capture/native-raw-dng.d.ts +60 -0
- package/dist/capture/native-raw-dng.js +167 -0
- package/dist/capture/native-raw-dng.js.map +1 -0
- package/dist/capture/native-raw.d.ts +65 -12
- package/dist/capture/native-raw.js +81 -19
- package/dist/capture/native-raw.js.map +1 -1
- package/dist/capture/packed-sensor-raw.d.ts +160 -0
- package/dist/capture/packed-sensor-raw.js +221 -0
- package/dist/capture/packed-sensor-raw.js.map +1 -0
- package/dist/capture/photographic-export.d.ts +58 -35
- package/dist/capture/photographic-export.js +177 -70
- package/dist/capture/photographic-export.js.map +1 -1
- package/dist/capture/raw-development-kernel.d.ts +52 -0
- package/dist/capture/raw-development-kernel.js +88 -0
- package/dist/capture/raw-development-kernel.js.map +1 -0
- package/dist/capture/raw-frame-limits.d.ts +7 -7
- package/dist/capture/raw-frame-limits.js +7 -6
- package/dist/capture/raw-frame-limits.js.map +1 -1
- package/dist/capture/raw-frame-reconstruction.d.ts +8 -9
- package/dist/capture/raw-frame-reconstruction.js +9 -8
- package/dist/capture/raw-frame-reconstruction.js.map +1 -1
- package/dist/capture/raw-white-level.d.ts +55 -0
- package/dist/capture/raw-white-level.js +165 -0
- package/dist/capture/raw-white-level.js.map +1 -0
- package/dist/capture/release-sequence.d.ts +5 -7
- package/dist/capture/release-sequence.js +15 -13
- package/dist/capture/release-sequence.js.map +1 -1
- package/dist/capture/sensor-raw-frame.d.ts +5 -6
- package/dist/capture/sensor-raw-frame.js +26 -9
- package/dist/capture/sensor-raw-frame.js.map +1 -1
- package/dist/capture/sensor-raw-producer.d.ts +21 -13
- package/dist/capture/sensor-raw-producer.js +86 -25
- package/dist/capture/sensor-raw-producer.js.map +1 -1
- package/dist/capture/simulated-capture.d.ts +15 -16
- package/dist/capture/simulated-capture.js +22 -12
- package/dist/capture/simulated-capture.js.map +1 -1
- package/dist/color/camera-color-matrix.d.ts +69 -0
- package/dist/color/camera-color-matrix.js +132 -0
- package/dist/color/camera-color-matrix.js.map +1 -0
- package/dist/color/capture-color.d.ts +17 -10
- package/dist/color/capture-color.js +50 -17
- package/dist/color/capture-color.js.map +1 -1
- package/dist/color/chromatic-adaptation.d.ts +63 -0
- package/dist/color/chromatic-adaptation.js +91 -0
- package/dist/color/chromatic-adaptation.js.map +1 -0
- package/dist/color/color-difference.d.ts +104 -0
- package/dist/color/color-difference.js +205 -0
- package/dist/color/color-difference.js.map +1 -0
- package/dist/color/color-matching-functions.d.ts +168 -0
- package/dist/color/color-matching-functions.js +309 -0
- package/dist/color/color-matching-functions.js.map +1 -0
- package/dist/color/colorimetry-math.d.ts +52 -0
- package/dist/color/colorimetry-math.js +144 -0
- package/dist/color/colorimetry-math.js.map +1 -0
- package/dist/color/gamut-mapping.d.ts +54 -0
- package/dist/color/gamut-mapping.js +107 -0
- package/dist/color/gamut-mapping.js.map +1 -0
- package/dist/color/illuminants.d.ts +182 -0
- package/dist/color/illuminants.js +434 -0
- package/dist/color/illuminants.js.map +1 -0
- package/dist/color/rgb-color-spaces.d.ts +79 -0
- package/dist/color/rgb-color-spaces.js +115 -0
- package/dist/color/rgb-color-spaces.js.map +1 -0
- package/dist/color/sensor-color-development.d.ts +33 -11
- package/dist/color/sensor-color-development.js +104 -30
- package/dist/color/sensor-color-development.js.map +1 -1
- package/dist/color/srgb-icc.d.ts +9 -2
- package/dist/color/srgb-icc.js +16 -5
- package/dist/color/srgb-icc.js.map +1 -1
- package/dist/color/srgb-transfer.d.ts +1 -2
- package/dist/color/srgb-transfer.js +1 -1
- package/dist/color/srgb-transfer.js.map +1 -1
- package/dist/color/white-balance.d.ts +68 -19
- package/dist/color/white-balance.js +168 -35
- package/dist/color/white-balance.js.map +1 -1
- package/dist/composition/image-formation-plan.d.ts +152 -128
- package/dist/composition/image-formation-plan.js +292 -138
- package/dist/composition/image-formation-plan.js.map +1 -1
- package/dist/composition/plan-consumer.d.ts +6 -7
- package/dist/composition/plan-consumer.js +14 -11
- package/dist/composition/plan-consumer.js.map +1 -1
- package/dist/core/calculation-result.d.ts +21 -14
- package/dist/core/calculation-result.js +209 -11
- package/dist/core/calculation-result.js.map +1 -1
- package/dist/core/canonical-json.d.ts +13 -8
- package/dist/core/canonical-json.js +34 -15
- package/dist/core/canonical-json.js.map +1 -1
- package/dist/core/configuration-error.d.ts +5 -4
- package/dist/core/configuration-error.js +5 -3
- package/dist/core/configuration-error.js.map +1 -1
- package/dist/core/evidence-provenance.d.ts +12 -12
- package/dist/core/evidence-provenance.js +10 -9
- package/dist/core/evidence-provenance.js.map +1 -1
- package/dist/core/image-formation.d.ts +11 -10
- package/dist/core/image-formation.js +11 -9
- package/dist/core/image-formation.js.map +1 -1
- package/dist/core/owned-data.d.ts +9 -17
- package/dist/core/owned-data.js +9 -16
- package/dist/core/owned-data.js.map +1 -1
- package/dist/core/portable-math.d.ts +15 -0
- package/dist/core/portable-math.js +56 -0
- package/dist/core/portable-math.js.map +1 -0
- package/dist/core/record-validation.d.ts +48 -9
- package/dist/core/record-validation.js +93 -19
- package/dist/core/record-validation.js.map +1 -1
- package/dist/core/scientific-assurance.d.ts +16 -14
- package/dist/core/scientific-assurance.js +22 -18
- package/dist/core/scientific-assurance.js.map +1 -1
- package/dist/core/spectral-composition.d.ts +13 -14
- package/dist/core/spectral-composition.js +30 -27
- package/dist/core/spectral-composition.js.map +1 -1
- package/dist/core/spectral.d.ts +5 -6
- package/dist/core/spectral.js +9 -7
- package/dist/core/spectral.js.map +1 -1
- package/dist/core/validation.d.ts +3 -6
- package/dist/core/validation.js +3 -5
- package/dist/core/validation.js.map +1 -1
- package/dist/core/version.d.ts +6 -6
- package/dist/core/version.js +6 -5
- package/dist/core/version.js.map +1 -1
- package/dist/equipment/exposure-capabilities.d.ts +10 -10
- package/dist/equipment/exposure-capabilities.js +40 -30
- package/dist/equipment/exposure-capabilities.js.map +1 -1
- package/dist/equipment/generic-tier-assets.d.ts +13 -6
- package/dist/equipment/generic-tier-assets.js +34 -15
- package/dist/equipment/generic-tier-assets.js.map +1 -1
- package/dist/equipment/generic-tier-presets.d.ts +5 -6
- package/dist/equipment/generic-tier-presets.js +15 -13
- package/dist/equipment/generic-tier-presets.js.map +1 -1
- package/dist/equipment/iso-capabilities.d.ts +21 -22
- package/dist/equipment/iso-capabilities.js +49 -44
- package/dist/equipment/iso-capabilities.js.map +1 -1
- package/dist/equipment/metering-capabilities.d.ts +5 -6
- package/dist/equipment/metering-capabilities.js +22 -19
- package/dist/equipment/metering-capabilities.js.map +1 -1
- package/dist/equipment/release-capabilities.d.ts +3 -4
- package/dist/equipment/release-capabilities.js +18 -14
- package/dist/equipment/release-capabilities.js.map +1 -1
- package/dist/exposure/exposure-duration-control.d.ts +19 -17
- package/dist/exposure/exposure-duration-control.js +27 -23
- package/dist/exposure/exposure-duration-control.js.map +1 -1
- package/dist/exposure/exposure-mode-resolver.d.ts +42 -39
- package/dist/exposure/exposure-mode-resolver.js +127 -82
- package/dist/exposure/exposure-mode-resolver.js.map +1 -1
- package/dist/exposure/exposure.d.ts +17 -16
- package/dist/exposure/exposure.js +22 -15
- package/dist/exposure/exposure.js.map +1 -1
- package/dist/exposure/flash-ttl.d.ts +135 -0
- package/dist/exposure/flash-ttl.js +193 -0
- package/dist/exposure/flash-ttl.js.map +1 -0
- package/dist/exposure/flash.d.ts +144 -36
- package/dist/exposure/flash.js +259 -59
- package/dist/exposure/flash.js.map +1 -1
- package/dist/exposure/metering-scene-radiance.d.ts +10 -10
- package/dist/exposure/metering-scene-radiance.js +42 -23
- package/dist/exposure/metering-scene-radiance.js.map +1 -1
- package/dist/exposure/metering-target.d.ts +8 -8
- package/dist/exposure/metering-target.js +30 -20
- package/dist/exposure/metering-target.js.map +1 -1
- package/dist/exposure/metering-temporal.d.ts +16 -15
- package/dist/exposure/metering-temporal.js +41 -19
- package/dist/exposure/metering-temporal.js.map +1 -1
- package/dist/exposure/metering.d.ts +64 -17
- package/dist/exposure/metering.js +159 -30
- package/dist/exposure/metering.js.map +1 -1
- package/dist/exposure/program-line.d.ts +5 -5
- package/dist/exposure/program-line.js +20 -13
- package/dist/exposure/program-line.js.map +1 -1
- package/dist/facade/camera-preset.d.ts +8 -0
- package/dist/facade/camera-preset.js +102 -0
- package/dist/facade/camera-preset.js.map +1 -0
- package/dist/facade/chart-radiance-batch.d.ts +57 -0
- package/dist/facade/chart-radiance-batch.js +121 -0
- package/dist/facade/chart-radiance-batch.js.map +1 -0
- package/dist/facade/chart-scenes.d.ts +177 -0
- package/dist/facade/chart-scenes.js +232 -0
- package/dist/facade/chart-scenes.js.map +1 -0
- package/dist/facade/diffraction-provider.d.ts +30 -0
- package/dist/facade/diffraction-provider.js +127 -0
- package/dist/facade/diffraction-provider.js.map +1 -0
- package/dist/facade/host-yield.d.ts +7 -0
- package/dist/facade/host-yield.js +19 -0
- package/dist/facade/host-yield.js.map +1 -0
- package/dist/facade/scene-radiance.d.ts +117 -0
- package/dist/facade/scene-radiance.js +205 -0
- package/dist/facade/scene-radiance.js.map +1 -0
- package/dist/facade/simulate-capture.d.ts +363 -0
- package/dist/facade/simulate-capture.js +1281 -0
- package/dist/facade/simulate-capture.js.map +1 -0
- package/dist/gpu/chart-radiance-gpu.d.ts +17 -0
- package/dist/gpu/chart-radiance-gpu.js +176 -0
- package/dist/gpu/chart-radiance-gpu.js.map +1 -0
- package/dist/gpu/image-kernel-accelerator.d.ts +132 -0
- package/dist/gpu/image-kernel-accelerator.js +720 -0
- package/dist/gpu/image-kernel-accelerator.js.map +1 -0
- package/dist/gpu/image-kernel-execution.d.ts +92 -0
- package/dist/gpu/image-kernel-execution.js +84 -0
- package/dist/gpu/image-kernel-execution.js.map +1 -0
- package/dist/gpu/sensor-stage-gpu.d.ts +44 -0
- package/dist/gpu/sensor-stage-gpu.js +317 -0
- package/dist/gpu/sensor-stage-gpu.js.map +1 -0
- package/dist/gpu/temporal-sum-gpu.d.ts +23 -0
- package/dist/gpu/temporal-sum-gpu.js +150 -0
- package/dist/gpu/temporal-sum-gpu.js.map +1 -0
- package/dist/gpu/webgpu-runtime.d.ts +63 -0
- package/dist/gpu/webgpu-runtime.js +215 -0
- package/dist/gpu/webgpu-runtime.js.map +1 -0
- package/dist/gpu/wgsl-chart-kernel.d.ts +30 -0
- package/dist/gpu/wgsl-chart-kernel.js +165 -0
- package/dist/gpu/wgsl-chart-kernel.js.map +1 -0
- package/dist/gpu/wgsl-kernels.d.ts +53 -0
- package/dist/gpu/wgsl-kernels.js +365 -0
- package/dist/gpu/wgsl-kernels.js.map +1 -0
- package/dist/gpu/wgsl-sensor-kernel.d.ts +64 -0
- package/dist/gpu/wgsl-sensor-kernel.js +409 -0
- package/dist/gpu/wgsl-sensor-kernel.js.map +1 -0
- package/dist/index.d.ts +91 -25
- package/dist/index.js +60 -15
- package/dist/index.js.map +1 -1
- package/dist/motion/camera-rotation.d.ts +92 -40
- package/dist/motion/camera-rotation.js +84 -47
- package/dist/motion/camera-rotation.js.map +1 -1
- package/dist/motion/capture-rotation-inverse-mapping.d.ts +37 -34
- package/dist/motion/capture-rotation-inverse-mapping.js +32 -24
- package/dist/motion/capture-rotation-inverse-mapping.js.map +1 -1
- package/dist/motion/capture-rotation-temporal-quadrature.d.ts +39 -35
- package/dist/motion/capture-rotation-temporal-quadrature.js +37 -28
- package/dist/motion/capture-rotation-temporal-quadrature.js.map +1 -1
- package/dist/motion/capture-rotation-trajectory.d.ts +32 -28
- package/dist/motion/capture-rotation-trajectory.js +36 -26
- package/dist/motion/capture-rotation-trajectory.js.map +1 -1
- package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts +23 -21
- package/dist/motion/capture-translation-parallax-temporal-quadrature.js +33 -14
- package/dist/motion/capture-translation-parallax-temporal-quadrature.js.map +1 -1
- package/dist/motion/extended-object-projection.d.ts +19 -16
- package/dist/motion/extended-object-projection.js +38 -18
- package/dist/motion/extended-object-projection.js.map +1 -1
- package/dist/motion/projected-motion.d.ts +18 -17
- package/dist/motion/projected-motion.js +25 -17
- package/dist/motion/projected-motion.js.map +1 -1
- package/dist/motion/temporal-exposure-sum.d.ts +55 -0
- package/dist/motion/temporal-exposure-sum.js +141 -0
- package/dist/motion/temporal-exposure-sum.js.map +1 -0
- package/dist/motion/video-sequence.d.ts +111 -0
- package/dist/motion/video-sequence.js +179 -0
- package/dist/motion/video-sequence.js.map +1 -0
- package/dist/optics/aperture.d.ts +14 -15
- package/dist/optics/aperture.js +13 -11
- package/dist/optics/aperture.js.map +1 -1
- package/dist/optics/atmospheric-haze.d.ts +83 -0
- package/dist/optics/atmospheric-haze.js +113 -0
- package/dist/optics/atmospheric-haze.js.map +1 -0
- package/dist/optics/brown-conrady-distortion.d.ts +116 -0
- package/dist/optics/brown-conrady-distortion.js +291 -0
- package/dist/optics/brown-conrady-distortion.js.map +1 -0
- package/dist/optics/circle-of-confusion.d.ts +10 -10
- package/dist/optics/circle-of-confusion.js +15 -11
- package/dist/optics/circle-of-confusion.js.map +1 -1
- package/dist/optics/complex-pupil-psf.d.ts +64 -33
- package/dist/optics/complex-pupil-psf.js +190 -98
- package/dist/optics/complex-pupil-psf.js.map +1 -1
- package/dist/optics/depth-of-field.d.ts +25 -15
- package/dist/optics/depth-of-field.js +67 -27
- package/dist/optics/depth-of-field.js.map +1 -1
- package/dist/optics/diffraction-psf-profile.d.ts +118 -0
- package/dist/optics/diffraction-psf-profile.js +252 -0
- package/dist/optics/diffraction-psf-profile.js.map +1 -0
- package/dist/optics/diffraction.d.ts +14 -13
- package/dist/optics/diffraction.js +14 -10
- package/dist/optics/diffraction.js.map +1 -1
- package/dist/optics/focus-breathing.d.ts +88 -27
- package/dist/optics/focus-breathing.js +114 -23
- package/dist/optics/focus-breathing.js.map +1 -1
- package/dist/optics/focus-state.d.ts +18 -18
- package/dist/optics/focus-state.js +21 -15
- package/dist/optics/focus-state.js.map +1 -1
- package/dist/optics/front-of-lens-filter.d.ts +45 -14
- package/dist/optics/front-of-lens-filter.js +259 -88
- package/dist/optics/front-of-lens-filter.js.map +1 -1
- package/dist/optics/illumination-vignetting.d.ts +16 -17
- package/dist/optics/illumination-vignetting.js +40 -17
- package/dist/optics/illumination-vignetting.js.map +1 -1
- package/dist/optics/irradiance-convolution.d.ts +59 -0
- package/dist/optics/irradiance-convolution.js +138 -0
- package/dist/optics/irradiance-convolution.js.map +1 -0
- package/dist/optics/lateral-chromatic-aberration.d.ts +33 -30
- package/dist/optics/lateral-chromatic-aberration.js +33 -23
- package/dist/optics/lateral-chromatic-aberration.js.map +1 -1
- package/dist/optics/lens-psf-kernels.d.ts +89 -0
- package/dist/optics/lens-psf-kernels.js +175 -0
- package/dist/optics/lens-psf-kernels.js.map +1 -0
- package/dist/optics/lens-psf-profile.d.ts +78 -46
- package/dist/optics/lens-psf-profile.js +335 -124
- package/dist/optics/lens-psf-profile.js.map +1 -1
- package/dist/optics/longitudinal-chromatic-aberration.d.ts +102 -0
- package/dist/optics/longitudinal-chromatic-aberration.js +210 -0
- package/dist/optics/longitudinal-chromatic-aberration.js.map +1 -0
- package/dist/optics/polygon-diffraction.d.ts +80 -23
- package/dist/optics/polygon-diffraction.js +130 -25
- package/dist/optics/polygon-diffraction.js.map +1 -1
- package/dist/optics/profile-contract.d.ts +5 -6
- package/dist/optics/profile-contract.js +14 -11
- package/dist/optics/profile-contract.js.map +1 -1
- package/dist/optics/psf-foundation.d.ts +23 -23
- package/dist/optics/psf-foundation.js +24 -21
- package/dist/optics/psf-foundation.js.map +1 -1
- package/dist/optics/pupil-vignetting.d.ts +118 -0
- package/dist/optics/pupil-vignetting.js +264 -0
- package/dist/optics/pupil-vignetting.js.map +1 -0
- package/dist/optics/radial-distortion.d.ts +34 -33
- package/dist/optics/radial-distortion.js +37 -30
- package/dist/optics/radial-distortion.js.map +1 -1
- package/dist/optics/scene-to-sensor-irradiance.d.ts +47 -33
- package/dist/optics/scene-to-sensor-irradiance.js +73 -45
- package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
- package/dist/optics/scene-to-sensor-quadrature.d.ts +23 -18
- package/dist/optics/scene-to-sensor-quadrature.js +16 -11
- package/dist/optics/scene-to-sensor-quadrature.js.map +1 -1
- package/dist/optics/sensor-aperture-rays.d.ts +20 -4
- package/dist/optics/sensor-aperture-rays.js +32 -14
- package/dist/optics/sensor-aperture-rays.js.map +1 -1
- package/dist/optics/sensor-environment-query.d.ts +81 -16
- package/dist/optics/sensor-environment-query.js +145 -12
- package/dist/optics/sensor-environment-query.js.map +1 -1
- package/dist/optics/sensor-psf-quadrature.d.ts +12 -10
- package/dist/optics/sensor-psf-quadrature.js +18 -11
- package/dist/optics/sensor-psf-quadrature.js.map +1 -1
- package/dist/optics/sensor-psf-support.d.ts +8 -6
- package/dist/optics/sensor-psf-support.js +8 -5
- package/dist/optics/sensor-psf-support.js.map +1 -1
- package/dist/optics/stray-light.d.ts +22 -19
- package/dist/optics/stray-light.js +18 -12
- package/dist/optics/stray-light.js.map +1 -1
- package/dist/optics/thin-lens.d.ts +10 -9
- package/dist/optics/thin-lens.js +12 -8
- package/dist/optics/thin-lens.js.map +1 -1
- package/dist/optics/zernike-wavefront.d.ts +154 -0
- package/dist/optics/zernike-wavefront.js +352 -0
- package/dist/optics/zernike-wavefront.js.map +1 -0
- package/dist/output/capture-corrected-sdr.d.ts +16 -8
- package/dist/output/capture-corrected-sdr.js +16 -8
- package/dist/output/capture-corrected-sdr.js.map +1 -1
- package/dist/output/capture-geometry.d.ts +34 -36
- package/dist/output/capture-geometry.js +52 -32
- package/dist/output/capture-geometry.js.map +1 -1
- package/dist/output/capture-sdr.d.ts +7 -6
- package/dist/output/capture-sdr.js +11 -8
- package/dist/output/capture-sdr.js.map +1 -1
- package/dist/output/crop.d.ts +22 -6
- package/dist/output/crop.js +40 -6
- package/dist/output/crop.js.map +1 -1
- package/dist/output/geometric-transforms.d.ts +60 -23
- package/dist/output/geometric-transforms.js +111 -24
- package/dist/output/geometric-transforms.js.map +1 -1
- package/dist/output/lens-corrections.d.ts +27 -19
- package/dist/output/lens-corrections.js +29 -13
- package/dist/output/lens-corrections.js.map +1 -1
- package/dist/output/native-capture-sdr.d.ts +71 -16
- package/dist/output/native-capture-sdr.js +190 -33
- package/dist/output/native-capture-sdr.js.map +1 -1
- package/dist/output/png-encoder.d.ts +65 -0
- package/dist/output/png-encoder.js +461 -0
- package/dist/output/png-encoder.js.map +1 -0
- package/dist/output/print-contrast-reference.d.ts +10 -9
- package/dist/output/print-contrast-reference.js +10 -8
- package/dist/output/print-contrast-reference.js.map +1 -1
- package/dist/output/print-detail.d.ts +18 -17
- package/dist/output/print-detail.js +12 -10
- package/dist/output/print-detail.js.map +1 -1
- package/dist/output/print-jpeg.d.ts +26 -5
- package/dist/output/print-jpeg.js +117 -50
- package/dist/output/print-jpeg.js.map +1 -1
- package/dist/output/print-plan.d.ts +19 -19
- package/dist/output/print-plan.js +11 -10
- package/dist/output/print-plan.js.map +1 -1
- package/dist/output/print-region-statistics.d.ts +14 -15
- package/dist/output/print-region-statistics.js +11 -11
- package/dist/output/print-region-statistics.js.map +1 -1
- package/dist/output/sdr-rendering.d.ts +48 -10
- package/dist/output/sdr-rendering.js +114 -25
- package/dist/output/sdr-rendering.js.map +1 -1
- package/dist/output/subject-framing-crop.d.ts +6 -10
- package/dist/output/subject-framing-crop.js +23 -13
- package/dist/output/subject-framing-crop.js.map +1 -1
- package/dist/processing/demosaic.d.ts +90 -0
- package/dist/processing/demosaic.js +275 -0
- package/dist/processing/demosaic.js.map +1 -0
- package/dist/processing/denoise.d.ts +68 -0
- package/dist/processing/denoise.js +214 -0
- package/dist/processing/denoise.js.map +1 -0
- package/dist/processing/focus-stacking.d.ts +17 -0
- package/dist/processing/focus-stacking.js +80 -0
- package/dist/processing/focus-stacking.js.map +1 -0
- package/dist/processing/hdr.d.ts +54 -0
- package/dist/processing/hdr.js +172 -0
- package/dist/processing/hdr.js.map +1 -0
- package/dist/processing/image-ops.d.ts +66 -0
- package/dist/processing/image-ops.js +192 -0
- package/dist/processing/image-ops.js.map +1 -0
- package/dist/processing/panorama.d.ts +51 -0
- package/dist/processing/panorama.js +305 -0
- package/dist/processing/panorama.js.map +1 -0
- package/dist/processing/processing-task.d.ts +85 -0
- package/dist/processing/processing-task.js +164 -0
- package/dist/processing/processing-task.js.map +1 -0
- package/dist/processing/tone-mapping.d.ts +69 -0
- package/dist/processing/tone-mapping.js +310 -0
- package/dist/processing/tone-mapping.js.map +1 -0
- package/dist/schema/camera.d.ts +5 -4
- package/dist/schema/illumination-spectral.d.ts +13 -19
- package/dist/schema/illumination-spectral.js +23 -19
- package/dist/schema/illumination-spectral.js.map +1 -1
- package/dist/schema/illumination-temporal.d.ts +12 -15
- package/dist/schema/illumination-temporal.js +43 -28
- package/dist/schema/illumination-temporal.js.map +1 -1
- package/dist/schema/illumination.d.ts +5 -4
- package/dist/schema/illumination.js +55 -20
- package/dist/schema/illumination.js.map +1 -1
- package/dist/schema/scene-radiance-temporal.d.ts +9 -11
- package/dist/schema/scene-radiance-temporal.js +26 -23
- package/dist/schema/scene-radiance-temporal.js.map +1 -1
- package/dist/schema/scene-radiance.d.ts +17 -17
- package/dist/schema/scene-radiance.js +56 -34
- package/dist/schema/scene-radiance.js.map +1 -1
- package/dist/schema/scene.d.ts +14 -13
- package/dist/schema/validation.d.ts +0 -1
- package/dist/schema/validation.js +17 -15
- package/dist/schema/validation.js.map +1 -1
- package/dist/sensor/accumulated-charge.d.ts +45 -64
- package/dist/sensor/accumulated-charge.js +41 -47
- package/dist/sensor/accumulated-charge.js.map +1 -1
- package/dist/sensor/architecture.d.ts +22 -25
- package/dist/sensor/architecture.js +17 -16
- package/dist/sensor/architecture.js.map +1 -1
- package/dist/sensor/camera-saturation-capacity.d.ts +21 -28
- package/dist/sensor/camera-saturation-capacity.js +36 -34
- package/dist/sensor/camera-saturation-capacity.js.map +1 -1
- package/dist/sensor/capture-color-sampling-binding.d.ts +46 -51
- package/dist/sensor/capture-color-sampling-binding.js +39 -41
- package/dist/sensor/capture-color-sampling-binding.js.map +1 -1
- package/dist/sensor/capture-mode-timing.d.ts +8 -9
- package/dist/sensor/capture-mode-timing.js +24 -21
- package/dist/sensor/capture-mode-timing.js.map +1 -1
- package/dist/sensor/capture-mode.d.ts +28 -30
- package/dist/sensor/capture-mode.js +33 -31
- package/dist/sensor/capture-mode.js.map +1 -1
- package/dist/sensor/color-sampling.d.ts +30 -33
- package/dist/sensor/color-sampling.js +32 -37
- package/dist/sensor/color-sampling.js.map +1 -1
- package/dist/sensor/constant-rate-temporal-integration.d.ts +19 -23
- package/dist/sensor/constant-rate-temporal-integration.js +28 -26
- package/dist/sensor/constant-rate-temporal-integration.js.map +1 -1
- package/dist/sensor/dark-current.d.ts +53 -49
- package/dist/sensor/dark-current.js +87 -46
- package/dist/sensor/dark-current.js.map +1 -1
- package/dist/sensor/environment-photo-signal.d.ts +71 -30
- package/dist/sensor/environment-photo-signal.js +127 -46
- package/dist/sensor/environment-photo-signal.js.map +1 -1
- package/dist/sensor/eqe-electron-rate.d.ts +14 -13
- package/dist/sensor/eqe-electron-rate.js +34 -14
- package/dist/sensor/eqe-electron-rate.js.map +1 -1
- package/dist/sensor/eqe-local-exposure.d.ts +24 -24
- package/dist/sensor/eqe-local-exposure.js +15 -11
- package/dist/sensor/eqe-local-exposure.js.map +1 -1
- package/dist/sensor/eqe-temporal-exposure.d.ts +11 -11
- package/dist/sensor/eqe-temporal-exposure.js +15 -10
- package/dist/sensor/eqe-temporal-exposure.js.map +1 -1
- package/dist/sensor/exposure-window.d.ts +48 -34
- package/dist/sensor/exposure-window.js +77 -36
- package/dist/sensor/exposure-window.js.map +1 -1
- package/dist/sensor/fixed-pattern-noise.d.ts +108 -0
- package/dist/sensor/fixed-pattern-noise.js +166 -0
- package/dist/sensor/fixed-pattern-noise.js.map +1 -0
- package/dist/sensor/iso-gain.d.ts +44 -0
- package/dist/sensor/iso-gain.js +119 -0
- package/dist/sensor/iso-gain.js.map +1 -0
- package/dist/sensor/iso-signal-chain.d.ts +25 -48
- package/dist/sensor/iso-signal-chain.js +52 -66
- package/dist/sensor/iso-signal-chain.js.map +1 -1
- package/dist/sensor/local-exposure-binding.d.ts +21 -21
- package/dist/sensor/local-exposure-binding.js +22 -18
- package/dist/sensor/local-exposure-binding.js.map +1 -1
- package/dist/sensor/optical-stack.d.ts +36 -40
- package/dist/sensor/optical-stack.js +34 -37
- package/dist/sensor/optical-stack.js.map +1 -1
- package/dist/sensor/photon-energy.d.ts +22 -28
- package/dist/sensor/photon-energy.js +42 -34
- package/dist/sensor/photon-energy.js.map +1 -1
- package/dist/sensor/physical-charge-capacity.d.ts +20 -30
- package/dist/sensor/physical-charge-capacity.js +35 -36
- package/dist/sensor/physical-charge-capacity.js.map +1 -1
- package/dist/sensor/pixel-pitch.d.ts +2 -3
- package/dist/sensor/pixel-pitch.js +4 -2
- package/dist/sensor/pixel-pitch.js.map +1 -1
- package/dist/sensor/radiometry-readiness.d.ts +13 -15
- package/dist/sensor/radiometry-readiness.js +20 -17
- package/dist/sensor/radiometry-readiness.js.map +1 -1
- package/dist/sensor/raw-readout.d.ts +173 -83
- package/dist/sensor/raw-readout.js +425 -160
- package/dist/sensor/raw-readout.js.map +1 -1
- package/dist/sensor/raw-reconstruction.d.ts +112 -44
- package/dist/sensor/raw-reconstruction.js +200 -47
- package/dist/sensor/raw-reconstruction.js.map +1 -1
- package/dist/sensor/readout-exposure-linkage.d.ts +103 -34
- package/dist/sensor/readout-exposure-linkage.js +125 -27
- package/dist/sensor/readout-exposure-linkage.js.map +1 -1
- package/dist/sensor/readout-timing.d.ts +43 -44
- package/dist/sensor/readout-timing.js +38 -30
- package/dist/sensor/readout-timing.js.map +1 -1
- package/dist/sensor/response-application-compatibility.d.ts +21 -28
- package/dist/sensor/response-application-compatibility.js +35 -34
- package/dist/sensor/response-application-compatibility.js.map +1 -1
- package/dist/sensor/response-operating-range.d.ts +26 -35
- package/dist/sensor/response-operating-range.js +40 -39
- package/dist/sensor/response-operating-range.js.map +1 -1
- package/dist/sensor/responsivity-photocurrent.d.ts +21 -29
- package/dist/sensor/responsivity-photocurrent.js +57 -40
- package/dist/sensor/responsivity-photocurrent.js.map +1 -1
- package/dist/sensor/sampling-aperture.d.ts +21 -25
- package/dist/sensor/sampling-aperture.js +29 -28
- package/dist/sensor/sampling-aperture.js.map +1 -1
- package/dist/sensor/scene-eqe-temporal-exposure.d.ts +14 -12
- package/dist/sensor/scene-eqe-temporal-exposure.js +13 -8
- package/dist/sensor/scene-eqe-temporal-exposure.js.map +1 -1
- package/dist/sensor/sensor-geometry.d.ts +28 -32
- package/dist/sensor/sensor-geometry.js +35 -20
- package/dist/sensor/sensor-geometry.js.map +1 -1
- package/dist/sensor/signal-noise.d.ts +14 -16
- package/dist/sensor/signal-noise.js +15 -13
- package/dist/sensor/signal-noise.js.map +1 -1
- package/dist/sensor/spatial-sample-reduction.d.ts +45 -60
- package/dist/sensor/spatial-sample-reduction.js +39 -48
- package/dist/sensor/spatial-sample-reduction.js.map +1 -1
- package/dist/sensor/spatial-sampling-quadrature.d.ts +46 -54
- package/dist/sensor/spatial-sampling-quadrature.js +31 -36
- package/dist/sensor/spatial-sampling-quadrature.js.map +1 -1
- package/dist/sensor/spatio-spectral-reduction.d.ts +32 -42
- package/dist/sensor/spatio-spectral-reduction.js +24 -29
- package/dist/sensor/spatio-spectral-reduction.js.map +1 -1
- package/dist/sensor/spectral-coverage.d.ts +6 -9
- package/dist/sensor/spectral-coverage.js +9 -6
- package/dist/sensor/spectral-coverage.js.map +1 -1
- package/dist/sensor/spectral-quadrature.d.ts +46 -60
- package/dist/sensor/spectral-quadrature.js +38 -48
- package/dist/sensor/spectral-quadrature.js.map +1 -1
- package/dist/sensor/spectral-response.d.ts +53 -41
- package/dist/sensor/spectral-response.js +80 -47
- package/dist/sensor/spectral-response.js.map +1 -1
- package/dist/sensor/stochastic-seed.d.ts +50 -0
- package/dist/sensor/stochastic-seed.js +123 -0
- package/dist/sensor/stochastic-seed.js.map +1 -0
- package/dist/sensor/temporal-eqe-sum.d.ts +2 -4
- package/dist/sensor/temporal-eqe-sum.js +5 -6
- package/dist/sensor/temporal-eqe-sum.js.map +1 -1
- package/dist/sensor/temporal-photo-signal.d.ts +5 -6
- package/dist/sensor/temporal-photo-signal.js +11 -10
- package/dist/sensor/temporal-photo-signal.js.map +1 -1
- package/dist/sensor/temporal-sample-binding.d.ts +1 -2
- package/dist/sensor/temporal-sample-binding.js +3 -3
- package/dist/sensor/temporal-sample-binding.js.map +1 -1
- package/dist/simulation/poc-simulation.d.ts +16 -16
- package/dist/simulation/poc-simulation.js +20 -15
- package/dist/simulation/poc-simulation.js.map +1 -1
- package/dist/stabilization/camera-shake.d.ts +42 -18
- package/dist/stabilization/camera-shake.js +43 -20
- package/dist/stabilization/camera-shake.js.map +1 -1
- package/dist/stabilization/system.d.ts +44 -41
- package/dist/stabilization/system.js +196 -108
- package/dist/stabilization/system.js.map +1 -1
- package/docs/AGENT_GUIDE.md +183 -0
- package/docs/API_REFERENCE.md +777 -2
- package/docs/QUICK_START.md +663 -0
- package/docs/USAGE.md +1719 -714
- package/docs/api/camera-equivalent-focal-length.md +6 -7
- package/docs/api/camera-field-of-view.md +16 -8
- package/docs/api/camera-lens-projection.md +246 -0
- package/docs/api/camera-projected-object-size.md +6 -5
- package/docs/api/capture-capture-export-metadata.md +10 -10
- package/docs/api/capture-dng-import.md +134 -0
- package/docs/api/capture-environment-raw-producer.md +17 -11
- package/docs/api/capture-export-jpeg.md +16 -0
- package/docs/api/capture-focus-control.md +25 -47
- package/docs/api/capture-linear-encoding.md +21 -12
- package/docs/api/capture-lossless-jpeg.md +49 -0
- package/docs/api/capture-native-environment-optical-stage.md +75 -0
- package/docs/api/capture-native-environment-raw.md +161 -4
- package/docs/api/capture-native-raw-development.md +69 -8
- package/docs/api/capture-native-raw-dng.md +84 -0
- package/docs/api/capture-native-raw.md +21 -10
- package/docs/api/capture-packed-sensor-raw.md +156 -0
- package/docs/api/capture-photographic-export.md +69 -31
- package/docs/api/capture-raw-frame-reconstruction.md +8 -8
- package/docs/api/capture-raw-white-level.md +37 -0
- package/docs/api/capture-release-sequence.md +6 -7
- package/docs/api/capture-sensor-raw-frame.md +6 -6
- package/docs/api/capture-sensor-raw-producer.md +17 -11
- package/docs/api/capture-simulated-capture.md +15 -15
- package/docs/api/color-camera-color-matrix.md +103 -0
- package/docs/api/color-capture-color.md +22 -11
- package/docs/api/color-chromatic-adaptation.md +82 -0
- package/docs/api/color-color-difference.md +134 -0
- package/docs/api/color-color-matching-functions.md +259 -0
- package/docs/api/color-colorimetry-math.md +54 -0
- package/docs/api/color-gamut-mapping.md +72 -0
- package/docs/api/color-illuminants.md +280 -0
- package/docs/api/color-rgb-color-spaces.md +151 -0
- package/docs/api/color-sensor-color-development.md +27 -0
- package/docs/api/color-srgb-icc.md +2 -4
- package/docs/api/color-white-balance.md +95 -19
- package/docs/api/composition-image-formation-plan.md +124 -95
- package/docs/api/composition-plan-consumer.md +7 -7
- package/docs/api/core-calculation-result.md +18 -14
- package/docs/api/core-configuration-error.md +1 -1
- package/docs/api/core-image-formation.md +7 -7
- package/docs/api/core-scientific-assurance.md +12 -10
- package/docs/api/core-spectral-composition.md +14 -14
- package/docs/api/core-spectral.md +6 -6
- package/docs/api/core-validation.md +3 -3
- package/docs/api/core-version.md +7 -6
- package/docs/api/equipment-exposure-capabilities.md +11 -10
- package/docs/api/equipment-generic-tier-assets.md +7 -2
- package/docs/api/equipment-generic-tier-presets.md +6 -6
- package/docs/api/equipment-iso-capabilities.md +18 -18
- package/docs/api/equipment-metering-capabilities.md +6 -6
- package/docs/api/equipment-release-capabilities.md +4 -4
- package/docs/api/exports.json +2253 -3
- package/docs/api/exposure-exposure-duration-control.md +9 -9
- package/docs/api/exposure-exposure-mode-resolver.md +35 -31
- package/docs/api/exposure-exposure.md +10 -10
- package/docs/api/exposure-flash-ttl.md +182 -0
- package/docs/api/exposure-flash.md +183 -28
- package/docs/api/exposure-metering-scene-radiance.md +11 -10
- package/docs/api/exposure-metering-target.md +9 -8
- package/docs/api/exposure-metering-temporal.md +8 -8
- package/docs/api/exposure-metering.md +69 -9
- package/docs/api/exposure-program-line.md +6 -5
- package/docs/api/facade-chart-radiance-batch.md +96 -0
- package/docs/api/facade-chart-scenes.md +240 -0
- package/docs/api/facade-scene-radiance.md +122 -0
- package/docs/api/facade-simulate-capture.md +397 -0
- package/docs/api/gpu-image-kernel-accelerator.md +157 -0
- package/docs/api/gpu-image-kernel-execution.md +152 -0
- package/docs/api/motion-camera-rotation.md +43 -26
- package/docs/api/motion-capture-rotation-inverse-mapping.md +24 -23
- package/docs/api/motion-capture-rotation-temporal-quadrature.md +22 -22
- package/docs/api/motion-capture-rotation-trajectory.md +15 -15
- package/docs/api/motion-capture-translation-parallax-temporal-quadrature.md +15 -14
- package/docs/api/motion-extended-object-projection.md +10 -8
- package/docs/api/motion-projected-motion.md +8 -8
- package/docs/api/motion-temporal-exposure-sum.md +98 -0
- package/docs/api/motion-video-sequence.md +159 -0
- package/docs/api/optics-aperture.md +8 -8
- package/docs/api/optics-atmospheric-haze.md +104 -0
- package/docs/api/optics-brown-conrady-distortion.md +123 -0
- package/docs/api/optics-circle-of-confusion.md +5 -4
- package/docs/api/optics-complex-pupil-psf.md +57 -16
- package/docs/api/optics-depth-of-field.md +12 -6
- package/docs/api/optics-diffraction-psf-profile.md +96 -0
- package/docs/api/optics-diffraction.md +8 -7
- package/docs/api/optics-focus-breathing.md +104 -16
- package/docs/api/optics-focus-state.md +9 -10
- package/docs/api/optics-front-of-lens-filter.md +72 -14
- package/docs/api/optics-illumination-vignetting.md +10 -10
- package/docs/api/optics-irradiance-convolution.md +95 -0
- package/docs/api/optics-lateral-chromatic-aberration.md +22 -21
- package/docs/api/optics-lens-psf-kernels.md +72 -0
- package/docs/api/optics-lens-psf-profile.md +48 -26
- package/docs/api/optics-longitudinal-chromatic-aberration.md +128 -0
- package/docs/api/optics-polygon-diffraction.md +78 -13
- package/docs/api/optics-profile-contract.md +4 -4
- package/docs/api/optics-psf-foundation.md +12 -12
- package/docs/api/optics-pupil-vignetting.md +132 -0
- package/docs/api/optics-radial-distortion.md +12 -12
- package/docs/api/optics-scene-to-sensor-irradiance.md +25 -14
- package/docs/api/optics-scene-to-sensor-quadrature.md +15 -12
- package/docs/api/optics-sensor-aperture-rays.md +3 -2
- package/docs/api/optics-sensor-environment-query.md +52 -9
- package/docs/api/optics-sensor-psf-quadrature.md +13 -10
- package/docs/api/optics-stray-light.md +12 -11
- package/docs/api/optics-thin-lens.md +4 -3
- package/docs/api/optics-zernike-wavefront.md +229 -0
- package/docs/api/output-capture-corrected-sdr.md +10 -7
- package/docs/api/output-capture-geometry.md +35 -36
- package/docs/api/output-capture-sdr.md +4 -4
- package/docs/api/output-crop.md +7 -4
- package/docs/api/output-geometric-transforms.md +65 -19
- package/docs/api/output-lens-corrections.md +17 -15
- package/docs/api/output-native-capture-sdr.md +26 -13
- package/docs/api/output-png-encoder.md +105 -0
- package/docs/api/output-print-contrast-reference.md +8 -8
- package/docs/api/output-print-detail.md +14 -14
- package/docs/api/output-print-jpeg.md +22 -5
- package/docs/api/output-print-plan.md +18 -18
- package/docs/api/output-print-region-statistics.md +14 -14
- package/docs/api/output-sdr-rendering.md +52 -10
- package/docs/api/output-subject-framing-crop.md +5 -6
- package/docs/api/processing-demosaic.md +120 -0
- package/docs/api/processing-denoise.md +148 -0
- package/docs/api/processing-focus-stacking.md +41 -0
- package/docs/api/processing-hdr.md +113 -0
- package/docs/api/processing-panorama.md +82 -0
- package/docs/api/processing-processing-task.md +107 -0
- package/docs/api/processing-tone-mapping.md +142 -0
- package/docs/api/schema-camera.md +6 -4
- package/docs/api/schema-illumination-spectral.md +10 -11
- package/docs/api/schema-illumination-temporal.md +13 -15
- package/docs/api/schema-illumination.md +4 -4
- package/docs/api/schema-scene-radiance-temporal.md +10 -11
- package/docs/api/schema-scene-radiance.md +18 -17
- package/docs/api/schema-scene.md +9 -9
- package/docs/api/schema-validation.md +1 -1
- package/docs/api/sensor-accumulated-charge.md +12 -20
- package/docs/api/sensor-architecture.md +15 -16
- package/docs/api/sensor-camera-saturation-capacity.md +9 -11
- package/docs/api/sensor-capture-color-sampling-binding.md +47 -51
- package/docs/api/sensor-capture-mode-timing.md +9 -9
- package/docs/api/sensor-capture-mode.md +29 -30
- package/docs/api/sensor-color-sampling.md +31 -33
- package/docs/api/sensor-constant-rate-temporal-integration.md +10 -11
- package/docs/api/sensor-dark-current.md +30 -14
- package/docs/api/sensor-environment-photo-signal.md +13 -6
- package/docs/api/sensor-eqe-electron-rate.md +9 -8
- package/docs/api/sensor-eqe-local-exposure.md +18 -17
- package/docs/api/sensor-eqe-temporal-exposure.md +12 -11
- package/docs/api/sensor-exposure-window.md +24 -24
- package/docs/api/sensor-fixed-pattern-noise.md +104 -0
- package/docs/api/sensor-iso-gain.md +63 -0
- package/docs/api/sensor-iso-signal-chain.md +13 -22
- package/docs/api/sensor-local-exposure-binding.md +12 -13
- package/docs/api/sensor-optical-stack.md +37 -40
- package/docs/api/sensor-photon-energy.md +10 -11
- package/docs/api/sensor-physical-charge-capacity.md +8 -13
- package/docs/api/sensor-pixel-pitch.md +1 -1
- package/docs/api/sensor-radiometry-readiness.md +9 -9
- package/docs/api/sensor-raw-readout.md +118 -52
- package/docs/api/sensor-raw-reconstruction.md +97 -20
- package/docs/api/sensor-readout-exposure-linkage.md +120 -24
- package/docs/api/sensor-readout-timing.md +33 -35
- package/docs/api/sensor-response-application-compatibility.md +9 -11
- package/docs/api/sensor-response-operating-range.md +14 -18
- package/docs/api/sensor-responsivity-photocurrent.md +9 -12
- package/docs/api/sensor-sampling-aperture.md +22 -25
- package/docs/api/sensor-scene-eqe-temporal-exposure.md +9 -8
- package/docs/api/sensor-sensor-geometry.md +23 -24
- package/docs/api/sensor-signal-noise.md +10 -10
- package/docs/api/sensor-spatial-sample-reduction.md +27 -30
- package/docs/api/sensor-spatial-sampling-quadrature.md +37 -39
- package/docs/api/sensor-spatio-spectral-reduction.md +27 -29
- package/docs/api/sensor-spectral-coverage.md +5 -5
- package/docs/api/sensor-spectral-quadrature.md +33 -35
- package/docs/api/sensor-spectral-response.md +28 -16
- package/docs/api/sensor-temporal-photo-signal.md +6 -6
- package/docs/api/simulation-poc-simulation.md +17 -16
- package/docs/api/stabilization-camera-shake.md +29 -10
- package/docs/api/stabilization-system.md +25 -21
- package/docs/examples/production-request.json +3821 -2157
- package/docs/examples/simulate-capture.mjs +14 -0
- package/llms.txt +35 -0
- package/package.json +32 -11
- package/AGENTS.md +0 -674
- package/CONTRIBUTING.md +0 -76
- package/DCO +0 -33
- package/dist/camera/equivalent-focal-length.d.ts.map +0 -1
- package/dist/camera/field-of-view.d.ts.map +0 -1
- package/dist/camera/projected-object-size.d.ts.map +0 -1
- package/dist/capture/capture-export-metadata.d.ts.map +0 -1
- package/dist/capture/environment-raw-producer.d.ts.map +0 -1
- package/dist/capture/export-jpeg.d.ts.map +0 -1
- package/dist/capture/export-tiff.d.ts.map +0 -1
- package/dist/capture/focus-control.d.ts.map +0 -1
- package/dist/capture/linear-encoding.d.ts.map +0 -1
- package/dist/capture/native-environment-raw.d.ts.map +0 -1
- package/dist/capture/native-raw-development.d.ts.map +0 -1
- package/dist/capture/native-raw.d.ts.map +0 -1
- package/dist/capture/photographic-export.d.ts.map +0 -1
- package/dist/capture/raw-frame-limits.d.ts.map +0 -1
- package/dist/capture/raw-frame-reconstruction.d.ts.map +0 -1
- package/dist/capture/release-sequence.d.ts.map +0 -1
- package/dist/capture/sensor-raw-frame.d.ts.map +0 -1
- package/dist/capture/sensor-raw-producer.d.ts.map +0 -1
- package/dist/capture/simulated-capture.d.ts.map +0 -1
- package/dist/color/capture-color.d.ts.map +0 -1
- package/dist/color/sensor-color-development.d.ts.map +0 -1
- package/dist/color/srgb-icc.d.ts.map +0 -1
- package/dist/color/srgb-transfer.d.ts.map +0 -1
- package/dist/color/white-balance.d.ts.map +0 -1
- package/dist/composition/image-formation-plan.d.ts.map +0 -1
- package/dist/composition/plan-consumer.d.ts.map +0 -1
- package/dist/core/calculation-result.d.ts.map +0 -1
- package/dist/core/canonical-json.d.ts.map +0 -1
- package/dist/core/configuration-error.d.ts.map +0 -1
- package/dist/core/evidence-provenance.d.ts.map +0 -1
- package/dist/core/image-formation.d.ts.map +0 -1
- package/dist/core/owned-data.d.ts.map +0 -1
- package/dist/core/record-validation.d.ts.map +0 -1
- package/dist/core/scientific-assurance.d.ts.map +0 -1
- package/dist/core/spectral-composition.d.ts.map +0 -1
- package/dist/core/spectral.d.ts.map +0 -1
- package/dist/core/validation.d.ts.map +0 -1
- package/dist/core/version.d.ts.map +0 -1
- package/dist/equipment/exposure-capabilities.d.ts.map +0 -1
- package/dist/equipment/generic-tier-assets.d.ts.map +0 -1
- package/dist/equipment/generic-tier-presets.d.ts.map +0 -1
- package/dist/equipment/iso-capabilities.d.ts.map +0 -1
- package/dist/equipment/metering-capabilities.d.ts.map +0 -1
- package/dist/equipment/release-capabilities.d.ts.map +0 -1
- package/dist/exposure/exposure-duration-control.d.ts.map +0 -1
- package/dist/exposure/exposure-mode-resolver.d.ts.map +0 -1
- package/dist/exposure/exposure.d.ts.map +0 -1
- package/dist/exposure/flash.d.ts.map +0 -1
- package/dist/exposure/metering-scene-radiance.d.ts.map +0 -1
- package/dist/exposure/metering-target.d.ts.map +0 -1
- package/dist/exposure/metering-temporal.d.ts.map +0 -1
- package/dist/exposure/metering.d.ts.map +0 -1
- package/dist/exposure/program-line.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/motion/camera-rotation.d.ts.map +0 -1
- package/dist/motion/capture-rotation-inverse-mapping.d.ts.map +0 -1
- package/dist/motion/capture-rotation-temporal-quadrature.d.ts.map +0 -1
- package/dist/motion/capture-rotation-trajectory.d.ts.map +0 -1
- package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts.map +0 -1
- package/dist/motion/extended-object-projection.d.ts.map +0 -1
- package/dist/motion/projected-motion.d.ts.map +0 -1
- package/dist/optics/aperture.d.ts.map +0 -1
- package/dist/optics/circle-of-confusion.d.ts.map +0 -1
- package/dist/optics/complex-pupil-psf.d.ts.map +0 -1
- package/dist/optics/depth-of-field.d.ts.map +0 -1
- package/dist/optics/diffraction.d.ts.map +0 -1
- package/dist/optics/focus-breathing.d.ts.map +0 -1
- package/dist/optics/focus-state.d.ts.map +0 -1
- package/dist/optics/front-of-lens-filter.d.ts.map +0 -1
- package/dist/optics/illumination-vignetting.d.ts.map +0 -1
- package/dist/optics/lateral-chromatic-aberration.d.ts.map +0 -1
- package/dist/optics/lens-psf-profile.d.ts.map +0 -1
- package/dist/optics/polygon-diffraction.d.ts.map +0 -1
- package/dist/optics/profile-contract.d.ts.map +0 -1
- package/dist/optics/psf-foundation.d.ts.map +0 -1
- package/dist/optics/radial-distortion.d.ts.map +0 -1
- package/dist/optics/scene-to-sensor-irradiance.d.ts.map +0 -1
- package/dist/optics/scene-to-sensor-quadrature.d.ts.map +0 -1
- package/dist/optics/sensor-aperture-rays.d.ts.map +0 -1
- package/dist/optics/sensor-environment-query.d.ts.map +0 -1
- package/dist/optics/sensor-psf-quadrature.d.ts.map +0 -1
- package/dist/optics/sensor-psf-support.d.ts.map +0 -1
- package/dist/optics/stray-light.d.ts.map +0 -1
- package/dist/optics/thin-lens.d.ts.map +0 -1
- package/dist/output/capture-corrected-sdr.d.ts.map +0 -1
- package/dist/output/capture-geometry.d.ts.map +0 -1
- package/dist/output/capture-sdr.d.ts.map +0 -1
- package/dist/output/crop.d.ts.map +0 -1
- package/dist/output/geometric-transforms.d.ts.map +0 -1
- package/dist/output/lens-corrections.d.ts.map +0 -1
- package/dist/output/native-capture-sdr.d.ts.map +0 -1
- package/dist/output/print-contrast-reference.d.ts.map +0 -1
- package/dist/output/print-detail.d.ts.map +0 -1
- package/dist/output/print-jpeg.d.ts.map +0 -1
- package/dist/output/print-plan.d.ts.map +0 -1
- package/dist/output/print-region-statistics.d.ts.map +0 -1
- package/dist/output/sdr-rendering.d.ts.map +0 -1
- package/dist/output/subject-framing-crop.d.ts.map +0 -1
- package/dist/schema/camera.d.ts.map +0 -1
- package/dist/schema/camera.js +0 -3
- package/dist/schema/camera.js.map +0 -1
- package/dist/schema/illumination-spectral.d.ts.map +0 -1
- package/dist/schema/illumination-temporal.d.ts.map +0 -1
- package/dist/schema/illumination.d.ts.map +0 -1
- package/dist/schema/scene-radiance-temporal.d.ts.map +0 -1
- package/dist/schema/scene-radiance.d.ts.map +0 -1
- package/dist/schema/scene.d.ts.map +0 -1
- package/dist/schema/scene.js +0 -3
- package/dist/schema/scene.js.map +0 -1
- package/dist/schema/validation.d.ts.map +0 -1
- package/dist/sensor/accumulated-charge.d.ts.map +0 -1
- package/dist/sensor/architecture.d.ts.map +0 -1
- package/dist/sensor/camera-saturation-capacity.d.ts.map +0 -1
- package/dist/sensor/capture-color-sampling-binding.d.ts.map +0 -1
- package/dist/sensor/capture-mode-timing.d.ts.map +0 -1
- package/dist/sensor/capture-mode.d.ts.map +0 -1
- package/dist/sensor/color-sampling.d.ts.map +0 -1
- package/dist/sensor/constant-rate-temporal-integration.d.ts.map +0 -1
- package/dist/sensor/dark-current.d.ts.map +0 -1
- package/dist/sensor/environment-photo-signal.d.ts.map +0 -1
- package/dist/sensor/eqe-electron-rate.d.ts.map +0 -1
- package/dist/sensor/eqe-local-exposure.d.ts.map +0 -1
- package/dist/sensor/eqe-temporal-exposure.d.ts.map +0 -1
- package/dist/sensor/exposure-window.d.ts.map +0 -1
- package/dist/sensor/iso-signal-chain.d.ts.map +0 -1
- package/dist/sensor/local-exposure-binding.d.ts.map +0 -1
- package/dist/sensor/optical-stack.d.ts.map +0 -1
- package/dist/sensor/photon-energy.d.ts.map +0 -1
- package/dist/sensor/physical-charge-capacity.d.ts.map +0 -1
- package/dist/sensor/pixel-pitch.d.ts.map +0 -1
- package/dist/sensor/radiometry-readiness.d.ts.map +0 -1
- package/dist/sensor/raw-readout.d.ts.map +0 -1
- package/dist/sensor/raw-reconstruction.d.ts.map +0 -1
- package/dist/sensor/readout-exposure-linkage.d.ts.map +0 -1
- package/dist/sensor/readout-timing.d.ts.map +0 -1
- package/dist/sensor/response-application-compatibility.d.ts.map +0 -1
- package/dist/sensor/response-operating-range.d.ts.map +0 -1
- package/dist/sensor/responsivity-photocurrent.d.ts.map +0 -1
- package/dist/sensor/sampling-aperture.d.ts.map +0 -1
- package/dist/sensor/scene-eqe-temporal-exposure.d.ts.map +0 -1
- package/dist/sensor/sensor-geometry.d.ts.map +0 -1
- package/dist/sensor/signal-noise.d.ts.map +0 -1
- package/dist/sensor/spatial-sample-reduction.d.ts.map +0 -1
- package/dist/sensor/spatial-sampling-quadrature.d.ts.map +0 -1
- package/dist/sensor/spatio-spectral-reduction.d.ts.map +0 -1
- package/dist/sensor/spectral-coverage.d.ts.map +0 -1
- package/dist/sensor/spectral-quadrature.d.ts.map +0 -1
- package/dist/sensor/spectral-response.d.ts.map +0 -1
- package/dist/sensor/temporal-eqe-sum.d.ts.map +0 -1
- package/dist/sensor/temporal-photo-signal.d.ts.map +0 -1
- package/dist/sensor/temporal-sample-binding.d.ts.map +0 -1
- package/dist/simulation/poc-simulation.d.ts.map +0 -1
- package/dist/stabilization/camera-shake.d.ts.map +0 -1
- package/dist/stabilization/system.d.ts.map +0 -1
- package/docs/API_STYLE.md +0 -235
- package/docs/ARCHITECTURE.md +0 -356
- package/docs/AUTOMATION_COORDINATION.md +0 -190
- package/docs/CAPTURE_COLOR.md +0 -25
- package/docs/CAPTURE_CORRECTED_SDR.md +0 -25
- package/docs/CAPTURE_EXPORT_METADATA.md +0 -27
- package/docs/CAPTURE_SDR.md +0 -22
- package/docs/DENSE_PUPIL_QUALIFICATION.md +0 -121
- package/docs/DEVELOPERS.md +0 -68
- package/docs/DIGITAL_OPTICS_FOUNDATION.md +0 -69
- package/docs/ENVIRONMENT_RAW_CAPTURE.md +0 -208
- package/docs/EXPORT_ACCEPTANCE.md +0 -133
- package/docs/GENERIC_TIER_PRESETS.md +0 -269
- package/docs/GEOMETRIC_PREPARATION_REUSE.md +0 -141
- package/docs/IMAGE_FORMATION.md +0 -247
- package/docs/LINEAR_CAPTURE_ENCODING.md +0 -25
- package/docs/MOTION_AND_SIGNAL.md +0 -250
- package/docs/NATIVE_CAPTURE_SDR.md +0 -70
- package/docs/NATIVE_CAPTURE_SDR_REVIEW.md +0 -37
- package/docs/NATIVE_CAPTURE_SDR_VALIDATION.md +0 -34
- package/docs/NATIVE_RAW_AND_PRINT.md +0 -54
- package/docs/NUMERICAL_CORRECTNESS.md +0 -191
- package/docs/PERFORMANCE_BASELINE.md +0 -56
- package/docs/PHOTOGRAPHIC_EXPORT.md +0 -206
- package/docs/PHYSICS_FOUNDATION.md +0 -426
- package/docs/POC_API.md +0 -278
- package/docs/POC_PROJECTION_PLATFORM_REFERENCE.md +0 -12
- package/docs/POC_PROJECTION_REUSE.md +0 -124
- package/docs/PRINT_195_196_REVIEW.md +0 -93
- package/docs/PRINT_196_ENGINE_ACCEPTANCE.md +0 -45
- package/docs/PRINT_CONTRAST_REFERENCE.md +0 -43
- package/docs/PRINT_DETAIL_ASSESSMENT.md +0 -81
- package/docs/PRINT_DETAIL_JPEG_EVIDENCE.md +0 -36
- package/docs/PRINT_DETAIL_SDR_EVIDENCE.md +0 -29
- package/docs/PRINT_DETAIL_VALIDATION.md +0 -36
- package/docs/PRINT_PLANNING.md +0 -75
- package/docs/PRINT_REGION_STATISTICS.md +0 -38
- package/docs/PROCESSED_OUTPUT.md +0 -157
- package/docs/PRODUCTION_COMPOSITION.md +0 -373
- package/docs/PRODUCTION_ENVIRONMENT_CAPTURE.md +0 -131
- package/docs/PROVENANCE.md +0 -115
- package/docs/PSF_FOUNDATION.md +0 -165
- package/docs/RAW_FRAME_ENVELOPE.md +0 -56
- package/docs/RAW_FRAME_RECONSTRUCTION.md +0 -30
- package/docs/RELEASE_1_0.md +0 -66
- package/docs/RELEASE_1_0_1.md +0 -61
- package/docs/RELEASE_1_1_0.md +0 -25
- package/docs/RELEASE_1_2_0.md +0 -51
- package/docs/RELEASE_1_3_0.md +0 -15
- package/docs/RELEASE_1_4_0.md +0 -23
- package/docs/RELEASE_1_5_0.md +0 -105
- package/docs/RELEASE_AUDIT.md +0 -39
- package/docs/SCENE_RADIANCE_AND_ILLUMINATION.md +0 -298
- package/docs/SCENE_SENSOR_QUADRATURE.md +0 -98
- package/docs/SCENE_SENSOR_TEMPORAL_EXPOSURE.md +0 -86
- package/docs/SCIENTIFIC_ASSURANCE.md +0 -280
- package/docs/SCIENTIFIC_CONFORMANCE.md +0 -83
- package/docs/SDR_RENDERING.md +0 -33
- package/docs/SENSOR_APERTURE_RAYS.md +0 -23
- package/docs/SENSOR_ENVIRONMENT_QUERY.md +0 -86
- package/docs/SENSOR_EQE_LOCAL_EXPOSURE.md +0 -104
- package/docs/SENSOR_EQE_TEMPORAL_EXPOSURE.md +0 -74
- package/docs/SENSOR_PSF_QUADRATURE.md +0 -90
- package/docs/SENSOR_RAW_FRAME.md +0 -20
- package/docs/SENSOR_RAW_PRODUCER.md +0 -77
- package/docs/SEPARABLE_EMISSION_DRAFT.md +0 -103
- package/docs/SIGNAL_CONFORMANCE.md +0 -23
- package/docs/SIMULATED_CAPTURE.md +0 -65
- package/docs/STABILIZATION.md +0 -234
- package/docs/TEMPORAL_PHOTO_RAW.md +0 -83
- package/docs/TIER_ACCEPTANCE.md +0 -129
- package/docs/TIER_PRESET_ACCEPTANCE.md +0 -59
- package/docs/V1_COMPOSITION_MAP.md +0 -123
- package/docs/V1_HELPER_REUSE_REVIEW.md +0 -60
- package/docs/V1_PERFORMANCE_DISPOSITION.md +0 -88
- package/docs/benchmarks/2026-10-01-main-baseline.json +0 -694
- package/docs/benchmarks/2026-10-02-geometric-preparation-reuse.json +0 -2190
- package/docs/benchmarks/2026-10-02-poc-projection-reuse.json +0 -2423
- package/docs/benchmarks/2026-10-02-v1-environment-gc-profile.json +0 -210
- package/docs/benchmarks/2026-10-02-v1-environment-ordinary.json +0 -187
- package/docs/benchmarks/2026-10-02-v1-geometry-gc-profile.json +0 -756
- package/docs/benchmarks/2026-10-02-v1-geometry-ordinary-1.json +0 -711
- package/docs/benchmarks/2026-10-02-v1-geometry-ordinary-2.json +0 -711
- package/docs/benchmarks/2026-10-02-v1-poc-gc-profile.json +0 -885
- package/docs/benchmarks/2026-10-02-v1-poc-ordinary-1.json +0 -868
- package/docs/benchmarks/2026-10-02-v1-poc-ordinary-2.json +0 -868
- package/docs/licenses/castleCSF-MIT.txt +0 -21
- package/docs/validation/dense-pupil-2026-10-06/pilot.jsonl +0 -6
- package/docs/validation/documentation-fragments.json +0 -212
- package/docs/validation/native-capture-sdr-darwin-arm64-node26-review.jsonl +0 -4
- package/docs/validation/native-capture-sdr-darwin-arm64.jsonl +0 -3
- package/docs/validation/native-raw-print-2026-10-04/fractional-asymmetric-crop.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/gray-ramp.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/linear-area-checker.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/manifest.json +0 -218
- package/docs/validation/native-raw-print-2026-10-04/megapixel-native.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/native-color.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel-validation.json +0 -9
- package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json +0 -29
- package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.codes.u16le.gz +0 -0
- package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.rgb.gz +0 -0
- package/docs/validation/native-raw-print-2026-10-04/srgb.icc +0 -0
- package/docs/validation/native-raw-print-2026-10-04/validation.json +0 -41
- package/docs/validation/print-196-candidate-capabilities.json +0 -28
- package/docs/validation/print-196-candidate-evidence.json +0 -356
- package/docs/validation/print-196-engine-acceptance.json +0 -81
- package/docs/validation/print-detail-capabilities.json +0 -103
- package/docs/validation/print-detail-jpeg-evidence.json +0 -116
- package/docs/validation/print-detail-sdr-evidence.json +0 -81
- package/docs/validation/release-audit-inventory.json +0 -1306
- package/docs/validation/tier-acceptance-report-v1.json +0 -2538
|
@@ -1,25 +1,34 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
3
|
+
* Sampled lens PSF (point-spread function) profiles, and MTF-only diagnostic profiles.
|
|
4
|
+
*
|
|
5
|
+
* The parsers validate untrusted input and return the normalized typed contract. Unknown enum
|
|
6
|
+
* values, missing required fields and incompatible scientific data are rejected.
|
|
7
|
+
*
|
|
8
|
+
* The resolver finds the sampled PSF for a declared optical state and query point. It never
|
|
9
|
+
* extrapolates and never invents missing dimensions.
|
|
10
|
+
*
|
|
11
|
+
* A sampled lens PSF is tied to an exact generic optical state and to declared ranges of field
|
|
12
|
+
* position, wavelength and signed defocus. Interpolation stays inside those declared ranges. It keeps
|
|
13
|
+
* the normalized shape separate from the throughput. MTF (modulation transfer function) data alone
|
|
14
|
+
* has no phase or spatial information, so it cannot justify rendering one unique PSF.
|
|
15
|
+
* @see docs/PSF_FOUNDATION.md for the equations, units, coordinate conventions, known blockers and
|
|
16
|
+
* support limits.
|
|
15
17
|
*/
|
|
16
18
|
import { approximationResult } from "../core/calculation-result.js";
|
|
17
19
|
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
20
|
+
import { freezeOwnedData } from "../core/owned-data.js";
|
|
18
21
|
import { parseEvidenceList } from "../core/evidence-provenance.js";
|
|
19
22
|
import { InvalidScientificInputError } from "../core/validation.js";
|
|
20
23
|
import { parseFocusPlane } from "./focus-state.js";
|
|
24
|
+
import { requireInputKeys, rejectUnknownFields, rejectUnknownVariantFields, UNCERTAINTY_VARIANT_FIELDS } from "../core/record-validation.js";
|
|
21
25
|
export const LENS_SAMPLED_PSF_PROFILE_SCHEMA_VERSION = "0.1.0";
|
|
22
26
|
export const LENS_MTF_DIAGNOSTIC_PROFILE_SCHEMA_VERSION = "0.1.0";
|
|
27
|
+
const LENS_SAMPLED_PSF_INTERPOLATIONS = [
|
|
28
|
+
"bounded-regular-grid-multilinear",
|
|
29
|
+
"bounded-regular-grid-centroid-aligned",
|
|
30
|
+
"rotationally-symmetric-radial-field-centroid-aligned"
|
|
31
|
+
];
|
|
23
32
|
const AXIS_KEYS = [
|
|
24
33
|
"focalLengthMm",
|
|
25
34
|
"focusDiopters",
|
|
@@ -29,12 +38,14 @@ const AXIS_KEYS = [
|
|
|
29
38
|
"wavelengthNm",
|
|
30
39
|
"signedDefocusImagePlaneMicrometers"
|
|
31
40
|
];
|
|
32
|
-
function requireRecord(value, path) {
|
|
41
|
+
function requireRecord(value, path, allowedKeys) {
|
|
33
42
|
if (typeof value !== "object" ||
|
|
34
43
|
value === null ||
|
|
35
44
|
Array.isArray(value)) {
|
|
36
45
|
throw new InvalidConfigurationError(path + " must be an object.");
|
|
37
46
|
}
|
|
47
|
+
if (allowedKeys !== null)
|
|
48
|
+
rejectUnknownFields(value, allowedKeys, path);
|
|
38
49
|
return value;
|
|
39
50
|
}
|
|
40
51
|
function requireNonEmptyString(value, path) {
|
|
@@ -103,7 +114,8 @@ function parseStatus(value, path) {
|
|
|
103
114
|
return value;
|
|
104
115
|
}
|
|
105
116
|
function parseUncertainty(value, path) {
|
|
106
|
-
const record = requireRecord(value, path);
|
|
117
|
+
const record = requireRecord(value, path, null);
|
|
118
|
+
rejectUnknownVariantFields(record, "kind", UNCERTAINTY_VARIANT_FIELDS, path);
|
|
107
119
|
if (record.kind === "relative") {
|
|
108
120
|
return {
|
|
109
121
|
kind: "relative",
|
|
@@ -165,7 +177,7 @@ function parseAxis(value, path, options = {}) {
|
|
|
165
177
|
return parsed;
|
|
166
178
|
}
|
|
167
179
|
function parseKernel(value, path) {
|
|
168
|
-
const record = requireRecord(value, path);
|
|
180
|
+
const record = requireRecord(value, path, ["widthSamples", "heightSamples", "centerSampleX", "centerSampleY", "normalizedIntensity", "samplePitchMicrometersX", "samplePitchMicrometersY"]);
|
|
169
181
|
const widthSamples = requirePositiveSafeInteger(record.widthSamples, path + ".widthSamples");
|
|
170
182
|
const heightSamples = requirePositiveSafeInteger(record.heightSamples, path + ".heightSamples");
|
|
171
183
|
const total = widthSamples *
|
|
@@ -218,7 +230,7 @@ function parseKernel(value, path) {
|
|
|
218
230
|
};
|
|
219
231
|
}
|
|
220
232
|
function parseAxes(value) {
|
|
221
|
-
const record = requireRecord(value, "lensPsfProfile.axes");
|
|
233
|
+
const record = requireRecord(value, "lensPsfProfile.axes", ["focalLengthMm", "focusDiopters", "apertureFNumber", "fieldXmm", "fieldYmm", "wavelengthNm", "signedDefocusImagePlaneMicrometers"]);
|
|
222
234
|
return {
|
|
223
235
|
focalLengthMm: parseAxis(record.focalLengthMm, "lensPsfProfile.axes.focalLengthMm", {
|
|
224
236
|
positive: true
|
|
@@ -239,7 +251,7 @@ function parseAxes(value) {
|
|
|
239
251
|
};
|
|
240
252
|
}
|
|
241
253
|
function parseCoordinate(value, path) {
|
|
242
|
-
const record = requireRecord(value, path);
|
|
254
|
+
const record = requireRecord(value, path, ["focalLengthMm", "focusDiopters", "apertureFNumber", "fieldXmm", "fieldYmm", "wavelengthNm", "signedDefocusImagePlaneMicrometers"]);
|
|
243
255
|
return {
|
|
244
256
|
focalLengthMm: requirePositiveFinite(record.focalLengthMm, path + ".focalLengthMm"),
|
|
245
257
|
focusDiopters: requireNonNegativeFinite(record.focusDiopters, path + ".focusDiopters"),
|
|
@@ -274,7 +286,7 @@ function parseNode(value, index, axes, status) {
|
|
|
274
286
|
const path = "lensPsfProfile.nodes[" +
|
|
275
287
|
index +
|
|
276
288
|
"]";
|
|
277
|
-
const record = requireRecord(value, path);
|
|
289
|
+
const record = requireRecord(value, path, ["coordinate", "uncertainty", "nodeId", "kernel", "bestFocusImagePlaneOffsetMicrometers", "relativePupilThroughputFactor", "evidence"]);
|
|
278
290
|
const coordinate = parseCoordinate(record.coordinate, path + ".coordinate");
|
|
279
291
|
validateNodeCoordinate(axes, coordinate, path + ".coordinate");
|
|
280
292
|
const uncertainty = parseUncertainty(record.uncertainty, path + ".uncertainty");
|
|
@@ -327,21 +339,61 @@ function sameKernelGeometry(first, second) {
|
|
|
327
339
|
first.centerSampleY ===
|
|
328
340
|
second.centerSampleY);
|
|
329
341
|
}
|
|
342
|
+
/** Private profile declarations owned by the engine, registered by markEngineOwnedLensSampledPsfProfile. */
|
|
343
|
+
const ENGINE_OWNED_PROFILES = new WeakSet();
|
|
344
|
+
/** Deep-frozen parse of a deep-frozen engine-owned declaration. */
|
|
345
|
+
const PARSED_OWNED_PROFILES = new WeakMap();
|
|
346
|
+
/** Grid node index of a cached, deep-frozen parse. */
|
|
347
|
+
const TRUSTED_NODE_INDEX = new WeakMap();
|
|
330
348
|
/**
|
|
331
|
-
*
|
|
332
|
-
*
|
|
349
|
+
* Internal: registers a private profile declaration owned by the engine, so that repeated
|
|
350
|
+
* resolveLensSampledPsf calls reuse one parse. The declaration is a structured clone that caller code
|
|
351
|
+
* never sees.
|
|
333
352
|
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
353
|
+
* The first resolve parses it exactly like untrusted input. It then deep-freezes the declaration and
|
|
354
|
+
* caches the frozen parse with its node index. A frozen declaration cannot change, so the cached
|
|
355
|
+
* parse stays exact. Caller objects that were never registered are always parsed again.
|
|
356
|
+
*/
|
|
357
|
+
export function markEngineOwnedLensSampledPsfProfile(value) {
|
|
358
|
+
if (typeof value === "object" && value !== null)
|
|
359
|
+
ENGINE_OWNED_PROFILES.add(value);
|
|
360
|
+
}
|
|
361
|
+
function parseOwnedOrUntrustedProfile(value) {
|
|
362
|
+
if (typeof value !== "object" || value === null || !ENGINE_OWNED_PROFILES.has(value)) {
|
|
363
|
+
return parseLensSampledPsfProfile(value);
|
|
364
|
+
}
|
|
365
|
+
const cached = PARSED_OWNED_PROFILES.get(value);
|
|
366
|
+
if (cached !== undefined)
|
|
367
|
+
return cached;
|
|
368
|
+
const parsed = parseLensSampledPsfProfile(value);
|
|
369
|
+
try {
|
|
370
|
+
freezeOwnedData(value);
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
// Not plain data that freezeOwnedData accepts (for example typed-array storage), so do not cache.
|
|
374
|
+
ENGINE_OWNED_PROFILES.delete(value);
|
|
375
|
+
return parsed;
|
|
376
|
+
}
|
|
377
|
+
freezeOwnedData(parsed);
|
|
378
|
+
TRUSTED_NODE_INDEX.set(parsed, buildGridNodeIndex(parsed));
|
|
379
|
+
PARSED_OWNED_PROFILES.set(value, parsed);
|
|
380
|
+
return parsed;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Validates an untrusted declaration and returns the normalized typed contract. Unknown enum values,
|
|
384
|
+
* missing required fields and incompatible scientific data are rejected here.
|
|
385
|
+
*
|
|
386
|
+
* A sampled lens PSF is tied to an exact generic optical state and to declared ranges of field
|
|
387
|
+
* position, wavelength and signed defocus. Interpolation stays inside those declared ranges. It keeps
|
|
388
|
+
* the normalized shape separate from the throughput. MTF (modulation transfer function) data alone
|
|
389
|
+
* has no phase or spatial information, so it cannot justify rendering one unique PSF.
|
|
390
|
+
* @param value - unknown. Untrusted input; TypeScript types alone are not validation.
|
|
391
|
+
* @returns LensSampledPsfProfile. The result states its shape and scientific status; a successful call does not imply calibration.
|
|
340
392
|
*
|
|
341
393
|
* @see docs/API_REFERENCE.md for the root export and exact type graph.
|
|
342
394
|
*/
|
|
343
395
|
export function parseLensSampledPsfProfile(value) {
|
|
344
|
-
const record = requireRecord(value, "lensPsfProfile");
|
|
396
|
+
const record = requireRecord(value, "lensPsfProfile", ["schemaVersion", "opticalDomain", "coordinateSystem", "fieldAxes", "kernelEnergyNormalization", "interpolation", "throughputOwnership", "sensorOpticalStackIncluded", "sensorSamplingIncluded", "reconstructionIncluded", "strayLightIncluded", "scientificStatus", "responseIncludes", "axes", "nodes", "profileId", "profileVersion", "evidence", "limitations"]);
|
|
345
397
|
if (record.schemaVersion !==
|
|
346
398
|
LENS_SAMPLED_PSF_PROFILE_SCHEMA_VERSION) {
|
|
347
399
|
throw new InvalidConfigurationError('lensPsfProfile.schemaVersion must be "' +
|
|
@@ -360,8 +412,7 @@ export function parseLensSampledPsfProfile(value) {
|
|
|
360
412
|
}
|
|
361
413
|
if (record.kernelEnergyNormalization !==
|
|
362
414
|
"unit-energy-shape" ||
|
|
363
|
-
record.interpolation
|
|
364
|
-
"bounded-regular-grid-multilinear" ||
|
|
415
|
+
!LENS_SAMPLED_PSF_INTERPOLATIONS.includes(record.interpolation) ||
|
|
365
416
|
record.throughputOwnership !==
|
|
366
417
|
"separate-relative-pupil-throughput-factor") {
|
|
367
418
|
throw new InvalidConfigurationError("lensPsfProfile normalization/interpolation/throughput ownership is invalid.");
|
|
@@ -377,7 +428,7 @@ export function parseLensSampledPsfProfile(value) {
|
|
|
377
428
|
throw new InvalidConfigurationError("V1 lens PSF profiles must remain lens-primary-optical-path-only and exclude sensor/reconstruction/stray-light effects.");
|
|
378
429
|
}
|
|
379
430
|
const status = parseStatus(record.scientificStatus, "lensPsfProfile.scientificStatus");
|
|
380
|
-
const response = requireRecord(record.responseIncludes, "lensPsfProfile.responseIncludes");
|
|
431
|
+
const response = requireRecord(record.responseIncludes, "lensPsfProfile.responseIncludes", ["diffraction", "aberration", "defocus", "pupilClippingShape"]);
|
|
381
432
|
for (const key of [
|
|
382
433
|
"diffraction",
|
|
383
434
|
"aberration",
|
|
@@ -419,6 +470,18 @@ export function parseLensSampledPsfProfile(value) {
|
|
|
419
470
|
throw new InvalidConfigurationError("Every lensPsfProfile node must use identical PSF kernel grid geometry for multilinear interpolation.");
|
|
420
471
|
}
|
|
421
472
|
}
|
|
473
|
+
if (record.interpolation ===
|
|
474
|
+
"rotationally-symmetric-radial-field-centroid-aligned") {
|
|
475
|
+
if (axes.fieldYmm.length !== 1 ||
|
|
476
|
+
axes.fieldYmm[0] !== 0 ||
|
|
477
|
+
axes.fieldXmm.some((value) => value < 0)) {
|
|
478
|
+
throw new InvalidConfigurationError("Rotationally symmetric PSF profiles must declare fieldYmm = [0] and non-negative fieldXmm radii.");
|
|
479
|
+
}
|
|
480
|
+
if (firstKernel.samplePitchMicrometersX !==
|
|
481
|
+
firstKernel.samplePitchMicrometersY) {
|
|
482
|
+
throw new InvalidConfigurationError("Rotationally symmetric PSF profiles require square kernel sample pitch for rotation.");
|
|
483
|
+
}
|
|
484
|
+
}
|
|
422
485
|
return {
|
|
423
486
|
schemaVersion: LENS_SAMPLED_PSF_PROFILE_SCHEMA_VERSION,
|
|
424
487
|
profileId: requireNonEmptyString(record.profileId, "lensPsfProfile.profileId"),
|
|
@@ -428,7 +491,7 @@ export function parseLensSampledPsfProfile(value) {
|
|
|
428
491
|
coordinateSystem: "image-plane-metric",
|
|
429
492
|
fieldAxes: "+X right, +Y up",
|
|
430
493
|
kernelEnergyNormalization: "unit-energy-shape",
|
|
431
|
-
interpolation:
|
|
494
|
+
interpolation: record.interpolation,
|
|
432
495
|
throughputOwnership: "separate-relative-pupil-throughput-factor",
|
|
433
496
|
responseIncludes: {
|
|
434
497
|
diffraction: response.diffraction,
|
|
@@ -484,11 +547,14 @@ function bracketAxis(values, target, path) {
|
|
|
484
547
|
throw new InvalidScientificInputError(path +
|
|
485
548
|
" lies outside the declared PSF profile grid; extrapolation is not permitted.");
|
|
486
549
|
}
|
|
487
|
-
for (
|
|
550
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
551
|
+
const value = values[index];
|
|
488
552
|
if (Math.abs(target - value) <= tolerance) {
|
|
489
553
|
return {
|
|
490
554
|
lower: value,
|
|
491
555
|
upper: value,
|
|
556
|
+
lowerIndex: index,
|
|
557
|
+
upperIndex: index,
|
|
492
558
|
fraction: 0,
|
|
493
559
|
exact: true
|
|
494
560
|
};
|
|
@@ -503,6 +569,8 @@ function bracketAxis(values, target, path) {
|
|
|
503
569
|
return {
|
|
504
570
|
lower,
|
|
505
571
|
upper,
|
|
572
|
+
lowerIndex: index,
|
|
573
|
+
upperIndex: index + 1,
|
|
506
574
|
fraction: (target - lower) /
|
|
507
575
|
(upper - lower),
|
|
508
576
|
exact: false
|
|
@@ -541,66 +609,68 @@ function bracketCoordinate(axes, coordinate) {
|
|
|
541
609
|
.signedDefocusImagePlaneMicrometers, "signedDefocusImagePlaneMicrometers")
|
|
542
610
|
};
|
|
543
611
|
}
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
];
|
|
567
|
-
const next = [];
|
|
568
|
-
for (const corner of corners) {
|
|
569
|
-
for (const option of values) {
|
|
570
|
-
if (option.weight === 0) {
|
|
571
|
-
continue;
|
|
572
|
-
}
|
|
573
|
-
next.push({
|
|
574
|
-
partial: {
|
|
575
|
-
...corner.partial,
|
|
576
|
-
[key]: option.value
|
|
577
|
-
},
|
|
578
|
-
weight: corner.weight *
|
|
579
|
-
option.weight
|
|
580
|
-
});
|
|
581
|
-
}
|
|
612
|
+
/** Flat-index strides of the regular grid over AXIS_KEYS (the last axis varies fastest). */
|
|
613
|
+
function gridStrides(axes) {
|
|
614
|
+
const strides = new Array(AXIS_KEYS.length);
|
|
615
|
+
let stride = 1;
|
|
616
|
+
for (let a = AXIS_KEYS.length - 1; a >= 0; a -= 1) {
|
|
617
|
+
strides[a] = stride;
|
|
618
|
+
stride *= axes[AXIS_KEYS[a]].length;
|
|
619
|
+
}
|
|
620
|
+
return strides;
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Nodes indexed by grid position. Node coordinates match declared axis values exactly (checked by the
|
|
624
|
+
* parser, with `===`, so −0 and 0 are one position) and are unique, so each position holds at most one node.
|
|
625
|
+
*/
|
|
626
|
+
function buildGridNodeIndex(profile) {
|
|
627
|
+
const strides = gridStrides(profile.axes);
|
|
628
|
+
const nodes = new Array(AXIS_KEYS.reduce((n, key) => n * profile.axes[key].length, 1));
|
|
629
|
+
for (const node of profile.nodes) {
|
|
630
|
+
let flat = 0;
|
|
631
|
+
for (let a = 0; a < AXIS_KEYS.length; a += 1) {
|
|
632
|
+
const key = AXIS_KEYS[a];
|
|
633
|
+
flat += profile.axes[key].indexOf(node.coordinate[key]) * strides[a];
|
|
582
634
|
}
|
|
583
|
-
|
|
635
|
+
nodes[flat] = node;
|
|
584
636
|
}
|
|
585
|
-
return
|
|
586
|
-
coordinate: corner.partial,
|
|
587
|
-
weight: corner.weight
|
|
588
|
-
}));
|
|
637
|
+
return { strides, nodes };
|
|
589
638
|
}
|
|
639
|
+
/**
|
|
640
|
+
* The multilinear corners of a bracketed query and their weights, in a fixed order: axes in AXIS_KEYS order,
|
|
641
|
+
* lower before upper, zero-weight options skipped. Each weight is the product of its per-axis weights in that order.
|
|
642
|
+
*/
|
|
590
643
|
function resolveWeightedNodes(profile, brackets) {
|
|
591
|
-
const
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
644
|
+
const index = TRUSTED_NODE_INDEX.get(profile) ?? buildGridNodeIndex(profile);
|
|
645
|
+
let flats = [0], weights = [1];
|
|
646
|
+
for (let a = 0; a < AXIS_KEYS.length; a += 1) {
|
|
647
|
+
const bracket = brackets[AXIS_KEYS[a]], stride = index.strides[a];
|
|
648
|
+
const nextFlats = [], nextWeights = [];
|
|
649
|
+
for (let c = 0; c < flats.length; c += 1) {
|
|
650
|
+
if (bracket.exact) {
|
|
651
|
+
nextFlats.push(flats[c] + bracket.lowerIndex * stride);
|
|
652
|
+
nextWeights.push(weights[c] * 1);
|
|
653
|
+
continue;
|
|
654
|
+
}
|
|
655
|
+
const lowerWeight = 1 - bracket.fraction, upperWeight = bracket.fraction;
|
|
656
|
+
if (lowerWeight !== 0) {
|
|
657
|
+
nextFlats.push(flats[c] + bracket.lowerIndex * stride);
|
|
658
|
+
nextWeights.push(weights[c] * lowerWeight);
|
|
659
|
+
}
|
|
660
|
+
if (upperWeight !== 0) {
|
|
661
|
+
nextFlats.push(flats[c] + bracket.upperIndex * stride);
|
|
662
|
+
nextWeights.push(weights[c] * upperWeight);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
flats = nextFlats;
|
|
666
|
+
weights = nextWeights;
|
|
667
|
+
}
|
|
668
|
+
return flats.map((flat, c) => {
|
|
669
|
+
const node = index.nodes[flat];
|
|
597
670
|
if (node === undefined) {
|
|
598
671
|
throw new InvalidScientificInputError("PSF profile grid is missing a required interpolation corner.");
|
|
599
672
|
}
|
|
600
|
-
return {
|
|
601
|
-
node,
|
|
602
|
-
weight: corner.weight
|
|
603
|
-
};
|
|
673
|
+
return { node, weight: weights[c] };
|
|
604
674
|
});
|
|
605
675
|
}
|
|
606
676
|
function interpolateKernel(weighted) {
|
|
@@ -637,41 +707,170 @@ function interpolateKernel(weighted) {
|
|
|
637
707
|
normalizedIntensity: normalized
|
|
638
708
|
};
|
|
639
709
|
}
|
|
710
|
+
function kernelCentroid(kernel) {
|
|
711
|
+
let sum = 0;
|
|
712
|
+
let x = 0;
|
|
713
|
+
let y = 0;
|
|
714
|
+
for (let row = 0; row < kernel.heightSamples; row += 1) {
|
|
715
|
+
for (let column = 0; column < kernel.widthSamples; column += 1) {
|
|
716
|
+
const value = kernel.normalizedIntensity[row * kernel.widthSamples + column];
|
|
717
|
+
sum += value;
|
|
718
|
+
x += value * (column - kernel.centerSampleX);
|
|
719
|
+
y += value * (row - kernel.centerSampleY);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
return { x: x / sum, y: y / sum };
|
|
723
|
+
}
|
|
724
|
+
/** Bilinear sample at fractional array coordinates; zero outside the kernel. */
|
|
725
|
+
function bilinearSample(kernel, column, row) {
|
|
726
|
+
const x0 = Math.floor(column);
|
|
727
|
+
const y0 = Math.floor(row);
|
|
728
|
+
const fx = column - x0;
|
|
729
|
+
const fy = row - y0;
|
|
730
|
+
const at = (x, y) => x < 0 || y < 0 || x >= kernel.widthSamples || y >= kernel.heightSamples
|
|
731
|
+
? 0
|
|
732
|
+
: kernel.normalizedIntensity[y * kernel.widthSamples + x];
|
|
733
|
+
const top = fx === 0 ? at(x0, y0) : (1 - fx) * at(x0, y0) + fx * at(x0 + 1, y0);
|
|
734
|
+
if (fy === 0) {
|
|
735
|
+
return top;
|
|
736
|
+
}
|
|
737
|
+
const bottom = fx === 0 ? at(x0, y0 + 1) : (1 - fx) * at(x0, y0 + 1) + fx * at(x0 + 1, y0 + 1);
|
|
738
|
+
return (1 - fy) * top + fy * bottom;
|
|
739
|
+
}
|
|
740
|
+
function normalizedKernel(template, values) {
|
|
741
|
+
const sum = values.reduce((acc, value) => acc + value, 0);
|
|
742
|
+
if (!Number.isFinite(sum) || sum <= 0) {
|
|
743
|
+
throw new InvalidScientificInputError("Interpolated PSF energy must remain finite and positive.");
|
|
744
|
+
}
|
|
745
|
+
return {
|
|
746
|
+
widthSamples: template.widthSamples,
|
|
747
|
+
heightSamples: template.heightSamples,
|
|
748
|
+
samplePitchMicrometersX: template.samplePitchMicrometersX,
|
|
749
|
+
samplePitchMicrometersY: template.samplePitchMicrometersY,
|
|
750
|
+
centerSampleX: template.centerSampleX,
|
|
751
|
+
centerSampleY: template.centerSampleY,
|
|
752
|
+
normalizedIntensity: values.map((value) => value / sum)
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Centroid-aligned interpolation. Each node kernel is shifted so its intensity centroid lands on the
|
|
757
|
+
* weighted centroid. Then the multilinear weights are applied. A single exact node is returned
|
|
758
|
+
* unchanged.
|
|
759
|
+
*/
|
|
760
|
+
function interpolateKernelCentroidAligned(weighted) {
|
|
761
|
+
const first = weighted[0]?.node.kernel;
|
|
762
|
+
if (first === undefined) {
|
|
763
|
+
throw new InvalidScientificInputError("PSF interpolation requires at least one source node.");
|
|
764
|
+
}
|
|
765
|
+
if (weighted.length === 1) {
|
|
766
|
+
// An exact grid node is already a validated unit-energy kernel; return it bit-for-bit.
|
|
767
|
+
return { ...first, normalizedIntensity: [...first.normalizedIntensity] };
|
|
768
|
+
}
|
|
769
|
+
const centroids = weighted.map((entry) => kernelCentroid(entry.node.kernel));
|
|
770
|
+
const target = centroids.reduce((acc, centroid, index) => ({
|
|
771
|
+
x: acc.x + weighted[index].weight * centroid.x,
|
|
772
|
+
y: acc.y + weighted[index].weight * centroid.y
|
|
773
|
+
}), { x: 0, y: 0 });
|
|
774
|
+
const values = new Array(first.normalizedIntensity.length).fill(0);
|
|
775
|
+
weighted.forEach((entry, index) => {
|
|
776
|
+
const dx = centroids[index].x - target.x;
|
|
777
|
+
const dy = centroids[index].y - target.y;
|
|
778
|
+
for (let row = 0; row < first.heightSamples; row += 1) {
|
|
779
|
+
for (let column = 0; column < first.widthSamples; column += 1) {
|
|
780
|
+
values[row * first.widthSamples + column] +=
|
|
781
|
+
entry.weight * bilinearSample(entry.node.kernel, column + dx, row + dy);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
});
|
|
785
|
+
return normalizedKernel(first, values);
|
|
786
|
+
}
|
|
787
|
+
/** Rotates a kernel by angleRadians (counter-clockwise, +Y up) about its centre sample. */
|
|
788
|
+
function rotateKernel(kernel, angleRadians) {
|
|
789
|
+
const cos = Math.cos(angleRadians);
|
|
790
|
+
const sin = Math.sin(angleRadians);
|
|
791
|
+
const values = [];
|
|
792
|
+
for (let row = 0; row < kernel.heightSamples; row += 1) {
|
|
793
|
+
// Array rows increase downward; image +Y is up.
|
|
794
|
+
const y = kernel.centerSampleY - row;
|
|
795
|
+
for (let column = 0; column < kernel.widthSamples; column += 1) {
|
|
796
|
+
const x = column - kernel.centerSampleX;
|
|
797
|
+
// Inverse rotation: destination (x, y) samples source R(-angle) (x, y).
|
|
798
|
+
const sourceX = cos * x + sin * y;
|
|
799
|
+
const sourceY = -sin * x + cos * y;
|
|
800
|
+
values.push(bilinearSample(kernel, kernel.centerSampleX + sourceX, kernel.centerSampleY - sourceY));
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
return normalizedKernel(kernel, values);
|
|
804
|
+
}
|
|
640
805
|
function weightedScalar(weighted, select) {
|
|
641
806
|
return weighted.reduce((sum, entry) => sum +
|
|
642
807
|
entry.weight *
|
|
643
808
|
select(entry.node), 0);
|
|
644
809
|
}
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
*
|
|
649
|
-
* Sampled lens PSF shapes bind exact generic optical state, field, wavelength and signed defocus
|
|
650
|
-
* support. Interpolation stays within declared applicability and preserves normalized shape separately
|
|
651
|
-
* from throughput. MTF-only data lacks phase/spatial information and does not authorize rendering a
|
|
652
|
-
* unique PSF.
|
|
653
|
-
* @param input - ResolveLensSampledPsfInput. See the linked contract for coordinate, unit and profile binding semantics.
|
|
654
|
-
* @returns CalculationResult<ResolvedLensSampledPsf>. Return shape and scientific status are explicit; no calibration is inferred from successful execution.
|
|
655
|
-
*
|
|
656
|
-
* @see docs/API_REFERENCE.md for the root export and exact type graph.
|
|
657
|
-
*/
|
|
658
|
-
export function resolveLensSampledPsf(input) {
|
|
659
|
-
const profile = parseLensSampledPsfProfile(input.profile);
|
|
810
|
+
function resolveLensSampledPsfCore(input) {
|
|
811
|
+
requireInputKeys(input, "resolveLensSampledPsf", ["profile", "focalLengthMm", "focus", "apertureFNumber", "fieldPointMm", "wavelengthNm", "signedDefocusImagePlaneMicrometers"]);
|
|
812
|
+
const profile = parseOwnedOrUntrustedProfile(input.profile);
|
|
660
813
|
const query = queryCoordinate(input);
|
|
661
|
-
const
|
|
814
|
+
const rotational = profile.interpolation ===
|
|
815
|
+
"rotationally-symmetric-radial-field-centroid-aligned";
|
|
816
|
+
const fieldRadiusMm = Math.hypot(query.coordinate.fieldXmm, query.coordinate.fieldYmm);
|
|
817
|
+
const fieldAngleRadians = rotational
|
|
818
|
+
? Math.atan2(query.coordinate.fieldYmm, query.coordinate.fieldXmm)
|
|
819
|
+
: 0;
|
|
820
|
+
const brackets = bracketCoordinate(profile.axes, rotational
|
|
821
|
+
? { ...query.coordinate, fieldXmm: fieldRadiusMm, fieldYmm: 0 }
|
|
822
|
+
: query.coordinate);
|
|
662
823
|
const weighted = resolveWeightedNodes(profile, brackets);
|
|
663
|
-
const exact = AXIS_KEYS.every((key) => brackets[key].exact);
|
|
664
|
-
const kernel =
|
|
824
|
+
const exact = AXIS_KEYS.every((key) => brackets[key].exact) && fieldAngleRadians === 0;
|
|
825
|
+
const kernel = profile.interpolation === "bounded-regular-grid-multilinear"
|
|
826
|
+
? interpolateKernel(weighted)
|
|
827
|
+
: fieldAngleRadians === 0
|
|
828
|
+
? interpolateKernelCentroidAligned(weighted)
|
|
829
|
+
: rotateKernel(interpolateKernelCentroidAligned(weighted), fieldAngleRadians);
|
|
665
830
|
const bestFocus = weightedScalar(weighted, (node) => node
|
|
666
831
|
.bestFocusImagePlaneOffsetMicrometers);
|
|
667
|
-
|
|
832
|
+
// A multilinear blend is a convex combination, so it cannot exceed its largest node value. But its
|
|
833
|
+
// floating-point weights can sum to a few ulps above 1. A result above 1 that lies within
|
|
834
|
+
// 8·ε·(node count)·max of the largest node is that rounding error. It is clamped to the largest node
|
|
835
|
+
// value (≤ 1, so the result is again a declared value). Results already within [0, 1] are unchanged.
|
|
836
|
+
const blended = weightedScalar(weighted, (node) => node
|
|
668
837
|
.relativePupilThroughputFactor);
|
|
838
|
+
const largestThroughput = Math.max(...weighted.map((entry) => entry.node.relativePupilThroughputFactor));
|
|
839
|
+
const throughput = blended > 1 && largestThroughput <= 1 &&
|
|
840
|
+
blended - largestThroughput <= 8 * Number.EPSILON * weighted.length * Math.max(1, largestThroughput)
|
|
841
|
+
? largestThroughput
|
|
842
|
+
: blended;
|
|
669
843
|
if (!Number.isFinite(bestFocus) ||
|
|
670
844
|
!Number.isFinite(throughput) ||
|
|
671
845
|
throughput < 0 ||
|
|
672
846
|
throughput > 1) {
|
|
673
847
|
throw new InvalidScientificInputError("Interpolated PSF metadata must remain finite and physically bounded.");
|
|
674
848
|
}
|
|
849
|
+
return { profile, query, rotational, exact, weighted, kernel, bestFocus, throughput };
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
852
|
+
* Internal (2.0 performance): the kernel resolveLensSampledPsf returns for the same input, computed by
|
|
853
|
+
* the same code without building the result envelope. Throws whenever resolveLensSampledPsf would throw
|
|
854
|
+
* before its envelope. Not exported from the package.
|
|
855
|
+
*/
|
|
856
|
+
export function resolveLensSampledPsfKernel(input) {
|
|
857
|
+
return resolveLensSampledPsfCore(input).kernel;
|
|
858
|
+
}
|
|
859
|
+
/**
|
|
860
|
+
* Resolves the sampled PSF for a declared optical state and query point. It never extrapolates and
|
|
861
|
+
* never invents missing dimensions.
|
|
862
|
+
*
|
|
863
|
+
* A sampled lens PSF is tied to an exact generic optical state and to declared ranges of field
|
|
864
|
+
* position, wavelength and signed defocus. Interpolation stays inside those declared ranges. It keeps
|
|
865
|
+
* the normalized shape separate from the throughput. MTF (modulation transfer function) data alone
|
|
866
|
+
* has no phase or spatial information, so it cannot justify rendering one unique PSF.
|
|
867
|
+
* @param input - ResolveLensSampledPsfInput. See that type for coordinates, units and profile binding.
|
|
868
|
+
* @returns CalculationResult<ResolvedLensSampledPsf>. The result states its shape and scientific status; a successful call does not imply calibration.
|
|
869
|
+
*
|
|
870
|
+
* @see docs/API_REFERENCE.md for the root export and exact type graph.
|
|
871
|
+
*/
|
|
872
|
+
export function resolveLensSampledPsf(input) {
|
|
873
|
+
const { profile, query, rotational, exact, weighted, kernel, bestFocus, throughput } = resolveLensSampledPsfCore(input);
|
|
675
874
|
return approximationResult({
|
|
676
875
|
profileId: profile.profileId,
|
|
677
876
|
profileVersion: profile.profileVersion,
|
|
@@ -705,7 +904,19 @@ export function resolveLensSampledPsf(input) {
|
|
|
705
904
|
reconstructionIncluded: false,
|
|
706
905
|
strayLightIncluded: false,
|
|
707
906
|
scalarSharpnessScoreProduced: false
|
|
708
|
-
}, "
|
|
907
|
+
}, profile.interpolation === "bounded-regular-grid-multilinear"
|
|
908
|
+
? "lens-sampled-psf-bounded-interpolation"
|
|
909
|
+
: rotational
|
|
910
|
+
? "lens-sampled-psf-rotational-centroid-aligned-interpolation"
|
|
911
|
+
: "lens-sampled-psf-centroid-aligned-interpolation", "1.0.0", [
|
|
912
|
+
...(profile.interpolation === "bounded-regular-grid-multilinear"
|
|
913
|
+
? []
|
|
914
|
+
: [
|
|
915
|
+
"Node kernels are translated to the weighted intensity centroid before blending (bilinear resampling, outside samples zero, renormalised), so shifted PSFs blend into one peak.",
|
|
916
|
+
...(rotational
|
|
917
|
+
? ["Rotationally symmetric lens: nodes along +X are interpolated at the field radius and the kernel is rotated by the field azimuth."]
|
|
918
|
+
: [])
|
|
919
|
+
]),
|
|
709
920
|
"PSF intensity is a unit-energy shape; relative pupil throughput remains a separate factor for the optical-throughput path.",
|
|
710
921
|
"Regular-grid interpolation is bounded and never extrapolates beyond declared focal-length, focus, aperture, field, wavelength or signed-defocus axes.",
|
|
711
922
|
"Full 2D image-plane kernel orientation is preserved in +X right, +Y up coordinates; no radial or sagittal/tangential averaging is forced.",
|
|
@@ -715,20 +926,20 @@ export function resolveLensSampledPsf(input) {
|
|
|
715
926
|
]);
|
|
716
927
|
}
|
|
717
928
|
/**
|
|
718
|
-
*
|
|
719
|
-
* missing required fields and incompatible scientific data
|
|
929
|
+
* Validates an untrusted declaration and returns the normalized typed contract. Unknown enum values,
|
|
930
|
+
* missing required fields and incompatible scientific data are rejected here.
|
|
720
931
|
*
|
|
721
|
-
*
|
|
722
|
-
*
|
|
723
|
-
*
|
|
724
|
-
* unique PSF.
|
|
725
|
-
* @param value - unknown.
|
|
726
|
-
* @returns LensMtfDiagnosticProfile.
|
|
932
|
+
* A sampled lens PSF is tied to an exact generic optical state and to declared ranges of field
|
|
933
|
+
* position, wavelength and signed defocus. Interpolation stays inside those declared ranges. It keeps
|
|
934
|
+
* the normalized shape separate from the throughput. MTF (modulation transfer function) data alone
|
|
935
|
+
* has no phase or spatial information, so it cannot justify rendering one unique PSF.
|
|
936
|
+
* @param value - unknown. Untrusted input; TypeScript types alone are not validation.
|
|
937
|
+
* @returns LensMtfDiagnosticProfile. The result states its shape and scientific status; a successful call does not imply calibration.
|
|
727
938
|
*
|
|
728
939
|
* @see docs/API_REFERENCE.md for the root export and exact type graph.
|
|
729
940
|
*/
|
|
730
941
|
export function parseLensMtfDiagnosticProfile(value) {
|
|
731
|
-
const record = requireRecord(value, "lensMtfProfile");
|
|
942
|
+
const record = requireRecord(value, "lensMtfProfile", ["schemaVersion", "opticalDomain", "phaseInformationAvailable", "magnitudeMeaning", "samples", "fieldPointMm", "wavelengthNm", "profileId", "profileVersion", "focalLengthMm", "focus", "apertureFNumber", "evidence", "limitations"]);
|
|
732
943
|
if (record.schemaVersion !==
|
|
733
944
|
LENS_MTF_DIAGNOSTIC_PROFILE_SCHEMA_VERSION) {
|
|
734
945
|
throw new InvalidConfigurationError('lensMtfProfile.schemaVersion must be "' +
|
|
@@ -753,7 +964,7 @@ export function parseLensMtfDiagnosticProfile(value) {
|
|
|
753
964
|
const path = "lensMtfProfile.samples[" +
|
|
754
965
|
index +
|
|
755
966
|
"]";
|
|
756
|
-
const sample = requireRecord(entry, path);
|
|
967
|
+
const sample = requireRecord(entry, path, ["spatialFrequencyCyclesPerMm", "sagittalMagnitude", "tangentialMagnitude"]);
|
|
757
968
|
const frequency = requireNonNegativeFinite(sample
|
|
758
969
|
.spatialFrequencyCyclesPerMm, path +
|
|
759
970
|
".spatialFrequencyCyclesPerMm");
|
|
@@ -773,7 +984,7 @@ export function parseLensMtfDiagnosticProfile(value) {
|
|
|
773
984
|
".tangentialMagnitude")
|
|
774
985
|
};
|
|
775
986
|
});
|
|
776
|
-
const field = requireRecord(record.fieldPointMm, "lensMtfProfile.fieldPointMm");
|
|
987
|
+
const field = requireRecord(record.fieldPointMm, "lensMtfProfile.fieldPointMm", ["x", "y"]);
|
|
777
988
|
const wavelength = record.wavelengthNm ===
|
|
778
989
|
null
|
|
779
990
|
? null
|
|
@@ -799,15 +1010,15 @@ export function parseLensMtfDiagnosticProfile(value) {
|
|
|
799
1010
|
};
|
|
800
1011
|
}
|
|
801
1012
|
/**
|
|
802
|
-
*
|
|
803
|
-
*
|
|
1013
|
+
* Explains why MTF-only evidence cannot determine one unique renderable PSF. Returns blockers instead
|
|
1014
|
+
* of making up phase information.
|
|
804
1015
|
*
|
|
805
|
-
*
|
|
806
|
-
*
|
|
807
|
-
*
|
|
808
|
-
* unique PSF.
|
|
809
|
-
* @param profile - LensMtfDiagnosticProfile. See
|
|
810
|
-
* @returns MtfOnlyPsfRenderabilityAssessment. Read structured blockers before
|
|
1016
|
+
* A sampled lens PSF is tied to an exact generic optical state and to declared ranges of field
|
|
1017
|
+
* position, wavelength and signed defocus. Interpolation stays inside those declared ranges. It keeps
|
|
1018
|
+
* the normalized shape separate from the throughput. MTF (modulation transfer function) data alone
|
|
1019
|
+
* has no phase or spatial information, so it cannot justify rendering one unique PSF.
|
|
1020
|
+
* @param profile - LensMtfDiagnosticProfile. See that type for coordinates, units and profile binding.
|
|
1021
|
+
* @returns MtfOnlyPsfRenderabilityAssessment. Read the structured blockers before relying on any authorization.
|
|
811
1022
|
*
|
|
812
1023
|
* @see docs/API_REFERENCE.md for the root export and exact type graph.
|
|
813
1024
|
*/
|