@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,13 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
2
|
+
* Generic lateral chromatic aberration (CA): red, green and blue land at slightly different image
|
|
3
|
+
* positions.
|
|
4
|
+
*
|
|
5
|
+
* The forward mapping sends one ideal image-plane point through a base distortion shared by all
|
|
6
|
+
* channels (green is the reference), plus extra radial coefficients for red and blue. It moves each
|
|
7
|
+
* channel; it is not a blur kernel.
|
|
8
|
+
*
|
|
9
|
+
* The inverse mapping takes one distorted output point and finds the ideal source point separately
|
|
10
|
+
* for red, green and blue. Renderers can sample those per-channel source points directly, without
|
|
11
|
+
* writing their own CA equations.
|
|
12
|
+
* @see docs/PHYSICS_FOUNDATION.md for the equations, units, coordinate conventions, known blockers
|
|
13
|
+
* and support limits.
|
|
11
14
|
*/
|
|
12
15
|
import { type CalculationResult } from "../core/calculation-result.js";
|
|
13
16
|
import { type LensFieldPointMm, type RadialDistortionCoefficients } from "./radial-distortion.js";
|
|
@@ -20,8 +23,8 @@ export interface LateralChromaticAberrationProfile {
|
|
|
20
23
|
/**
|
|
21
24
|
* Green-reference base geometric distortion.
|
|
22
25
|
*
|
|
23
|
-
*
|
|
24
|
-
* added
|
|
26
|
+
* Every channel includes this shared mapping. The red and blue CA terms are
|
|
27
|
+
* added on top of it, so do not apply a second distortion pass.
|
|
25
28
|
*/
|
|
26
29
|
baseDistortionCoefficients: RadialDistortionCoefficients;
|
|
27
30
|
/** Additional red-channel radial coefficients relative to green. */
|
|
@@ -36,17 +39,17 @@ export interface CalculateLateralChromaticAberrationMappingInput {
|
|
|
36
39
|
}
|
|
37
40
|
export interface CalculateInverseLateralChromaticAberrationMappingInput {
|
|
38
41
|
/**
|
|
39
|
-
* Distorted output image-plane
|
|
40
|
-
*
|
|
42
|
+
* Distorted output image-plane point. Each channel is inverse-mapped on its
|
|
43
|
+
* own to its ideal source point.
|
|
41
44
|
*/
|
|
42
45
|
distortedImagePointMm: LensFieldPointMm;
|
|
43
46
|
profile: LateralChromaticAberrationProfile;
|
|
44
47
|
}
|
|
45
48
|
export interface CalculateInverseLateralChromaticAberrationMappingsInput {
|
|
46
49
|
/**
|
|
47
|
-
* Distorted output image-plane
|
|
48
|
-
* mapped
|
|
49
|
-
*
|
|
50
|
+
* Distorted output image-plane points. The profile is resolved once for the
|
|
51
|
+
* batch. Then each point is inverse-mapped separately for red, green and
|
|
52
|
+
* blue.
|
|
50
53
|
*/
|
|
51
54
|
distortedImagePointsMm: readonly LensFieldPointMm[];
|
|
52
55
|
profile: LateralChromaticAberrationProfile;
|
|
@@ -101,28 +104,28 @@ export interface InverseLateralChromaticAberrationMappings {
|
|
|
101
104
|
pointCount: number;
|
|
102
105
|
}
|
|
103
106
|
/**
|
|
104
|
-
* Calculates
|
|
105
|
-
* one ideal image-plane point through a shared
|
|
106
|
-
*
|
|
107
|
+
* Calculates how far lateral chromatic aberration (CA) separates the colour
|
|
108
|
+
* channels at one ideal image-plane point. The point goes through a shared
|
|
109
|
+
* base distortion (green is the reference) plus extra radial coefficients for
|
|
110
|
+
* red and blue.
|
|
107
111
|
*
|
|
108
|
-
* This
|
|
112
|
+
* This moves each channel; it is not a blur kernel.
|
|
109
113
|
*/
|
|
110
114
|
export declare function calculateLateralChromaticAberrationMapping(input: CalculateLateralChromaticAberrationMappingInput): CalculationResult<LateralChromaticAberrationMapping>;
|
|
111
115
|
/**
|
|
112
|
-
* Inverse-maps one distorted output
|
|
113
|
-
*
|
|
116
|
+
* Inverse-maps one distorted output point separately for the representative
|
|
117
|
+
* red, green and blue channels.
|
|
114
118
|
*
|
|
115
|
-
* Renderers can
|
|
116
|
-
*
|
|
119
|
+
* Renderers can sample the returned per-channel ideal source points directly,
|
|
120
|
+
* without writing their own chromatic-aberration equations.
|
|
117
121
|
*/
|
|
118
122
|
export declare function calculateInverseLateralChromaticAberrationMapping(input: CalculateInverseLateralChromaticAberrationMappingInput): CalculationResult<InverseLateralChromaticAberrationMapping>;
|
|
119
123
|
/**
|
|
120
|
-
* Inverse-maps
|
|
121
|
-
*
|
|
122
|
-
*
|
|
124
|
+
* Inverse-maps many distorted points at once. The shared CA profile is
|
|
125
|
+
* resolved once, and each combined channel profile is validated once, for
|
|
126
|
+
* the whole batch.
|
|
123
127
|
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
128
|
+
* Each point's values match calculateInverseLateralChromaticAberrationMapping().
|
|
129
|
+
* Provenance is reported once for the batch.
|
|
126
130
|
*/
|
|
127
131
|
export declare function calculateInverseLateralChromaticAberrationMappings(input: CalculateInverseLateralChromaticAberrationMappingsInput): CalculationResult<InverseLateralChromaticAberrationMappings>;
|
|
128
|
-
//# sourceMappingURL=lateral-chromatic-aberration.d.ts.map
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
3
|
+
* Generic lateral chromatic aberration (CA): red, green and blue land at slightly different image
|
|
4
|
+
* positions.
|
|
5
|
+
*
|
|
6
|
+
* The forward mapping sends one ideal image-plane point through a base distortion shared by all
|
|
7
|
+
* channels (green is the reference), plus extra radial coefficients for red and blue. It moves each
|
|
8
|
+
* channel; it is not a blur kernel.
|
|
9
|
+
*
|
|
10
|
+
* The inverse mapping takes one distorted output point and finds the ideal source point separately
|
|
11
|
+
* for red, green and blue. Renderers can sample those per-channel source points directly, without
|
|
12
|
+
* writing their own CA equations.
|
|
13
|
+
* @see docs/PHYSICS_FOUNDATION.md for the equations, units, coordinate conventions, known blockers
|
|
14
|
+
* and support limits.
|
|
12
15
|
*/
|
|
13
16
|
import { approximationResult } from "../core/calculation-result.js";
|
|
14
17
|
import { InvalidScientificInputError } from "../core/validation.js";
|
|
15
18
|
import { calculateInverseRadialDistortionMapping, calculateInverseRadialSourcePointValue, calculateRadialDistortionMapping, validateRadialDistortionProfile } from "./radial-distortion.js";
|
|
19
|
+
import { requireInputObject, requireInputKeys } from "../core/record-validation.js";
|
|
20
|
+
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
16
21
|
function requireFiniteCoefficients(path, coefficients) {
|
|
17
22
|
for (const key of ["k1", "k2", "k3"]) {
|
|
18
23
|
if (!Number.isFinite(coefficients[key])) {
|
|
@@ -28,6 +33,7 @@ function addCoefficients(base, offset) {
|
|
|
28
33
|
};
|
|
29
34
|
}
|
|
30
35
|
function resolveProfiles(profile) {
|
|
36
|
+
requireInputObject(profile, "profile input");
|
|
31
37
|
requireFiniteCoefficients("profile.baseDistortionCoefficients", profile.baseDistortionCoefficients);
|
|
32
38
|
requireFiniteCoefficients("profile.redCoefficientOffset", profile.redCoefficientOffset);
|
|
33
39
|
requireFiniteCoefficients("profile.blueCoefficientOffset", profile.blueCoefficientOffset);
|
|
@@ -93,13 +99,15 @@ function assumptions() {
|
|
|
93
99
|
];
|
|
94
100
|
}
|
|
95
101
|
/**
|
|
96
|
-
* Calculates
|
|
97
|
-
* one ideal image-plane point through a shared
|
|
98
|
-
*
|
|
102
|
+
* Calculates how far lateral chromatic aberration (CA) separates the colour
|
|
103
|
+
* channels at one ideal image-plane point. The point goes through a shared
|
|
104
|
+
* base distortion (green is the reference) plus extra radial coefficients for
|
|
105
|
+
* red and blue.
|
|
99
106
|
*
|
|
100
|
-
* This
|
|
107
|
+
* This moves each channel; it is not a blur kernel.
|
|
101
108
|
*/
|
|
102
109
|
export function calculateLateralChromaticAberrationMapping(input) {
|
|
110
|
+
requireInputKeys(input, "calculateLateralChromaticAberrationMapping", ["imagePointMm", "profile"]);
|
|
103
111
|
const profiles = resolveProfiles(input.profile);
|
|
104
112
|
const red = withChannelContext("red", () => calculateRadialDistortionMapping({
|
|
105
113
|
imagePointMm: input.imagePointMm,
|
|
@@ -138,13 +146,14 @@ export function calculateLateralChromaticAberrationMapping(input) {
|
|
|
138
146
|
}, "generic-green-reference-lateral-chromatic-aberration", "1.0.0", assumptions());
|
|
139
147
|
}
|
|
140
148
|
/**
|
|
141
|
-
* Inverse-maps one distorted output
|
|
142
|
-
*
|
|
149
|
+
* Inverse-maps one distorted output point separately for the representative
|
|
150
|
+
* red, green and blue channels.
|
|
143
151
|
*
|
|
144
|
-
* Renderers can
|
|
145
|
-
*
|
|
152
|
+
* Renderers can sample the returned per-channel ideal source points directly,
|
|
153
|
+
* without writing their own chromatic-aberration equations.
|
|
146
154
|
*/
|
|
147
155
|
export function calculateInverseLateralChromaticAberrationMapping(input) {
|
|
156
|
+
requireInputKeys(input, "calculateInverseLateralChromaticAberrationMapping", ["distortedImagePointMm", "profile"]);
|
|
148
157
|
const profiles = resolveProfiles(input.profile);
|
|
149
158
|
const red = withChannelContext("red", () => calculateInverseRadialDistortionMapping({
|
|
150
159
|
distortedImagePointMm: input.distortedImagePointMm,
|
|
@@ -183,14 +192,15 @@ export function calculateInverseLateralChromaticAberrationMapping(input) {
|
|
|
183
192
|
}, "generic-inverse-green-reference-lateral-chromatic-aberration", "1.0.0", assumptions());
|
|
184
193
|
}
|
|
185
194
|
/**
|
|
186
|
-
* Inverse-maps
|
|
187
|
-
*
|
|
188
|
-
*
|
|
195
|
+
* Inverse-maps many distorted points at once. The shared CA profile is
|
|
196
|
+
* resolved once, and each combined channel profile is validated once, for
|
|
197
|
+
* the whole batch.
|
|
189
198
|
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
199
|
+
* Each point's values match calculateInverseLateralChromaticAberrationMapping().
|
|
200
|
+
* Provenance is reported once for the batch.
|
|
192
201
|
*/
|
|
193
202
|
export function calculateInverseLateralChromaticAberrationMappings(input) {
|
|
203
|
+
requireInputKeys(input, "calculateInverseLateralChromaticAberrationMappings", ["distortedImagePointsMm", "profile"]);
|
|
194
204
|
const profiles = resolveProfiles(input.profile);
|
|
195
205
|
const validatedProfiles = {
|
|
196
206
|
red: withChannelContext("red", () => validateRadialDistortionProfile(profiles.red)),
|
|
@@ -198,7 +208,7 @@ export function calculateInverseLateralChromaticAberrationMappings(input) {
|
|
|
198
208
|
blue: withChannelContext("blue", () => validateRadialDistortionProfile(profiles.blue))
|
|
199
209
|
};
|
|
200
210
|
if (!Array.isArray(input.distortedImagePointsMm)) {
|
|
201
|
-
throw new
|
|
211
|
+
throw new InvalidConfigurationError("distortedImagePointsMm must be an array of image-plane points.");
|
|
202
212
|
}
|
|
203
213
|
const mappings = [];
|
|
204
214
|
for (let index = 0; index < input.distortedImagePointsMm.length; index += 1) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lateral-chromatic-aberration.js","sourceRoot":"","sources":["../../src/optics/lateral-chromatic-aberration.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lateral-chromatic-aberration.js","sourceRoot":"","sources":["../../src/optics/lateral-chromatic-aberration.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Generic lateral chromatic aberration (CA): red, green and blue land at slightly different image\n * positions.\n *\n * The forward mapping sends one ideal image-plane point through a base distortion shared by all\n * channels (green is the reference), plus extra radial coefficients for red and blue. It moves each\n * channel; it is not a blur kernel.\n *\n * The inverse mapping takes one distorted output point and finds the ideal source point separately\n * for red, green and blue. Renderers can sample those per-channel source points directly, without\n * writing their own CA equations.\n * @see docs/PHYSICS_FOUNDATION.md for the equations, units, coordinate conventions, known blockers\n * and support limits.\n */\n\nimport {\n approximationResult,\n type CalculationResult\n} from \"../core/calculation-result.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport {\n calculateInverseRadialDistortionMapping,\n calculateInverseRadialSourcePointValue,\n calculateRadialDistortionMapping,\n validateRadialDistortionProfile,\n type LensFieldPointMm,\n type RadialDistortionCoefficients,\n type RadialDistortionProfile\n} from \"./radial-distortion.js\";\nimport { requireInputObject, requireInputKeys } from \"../core/record-validation.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\n\nexport type LateralChromaticAberrationChannel = \"red\" | \"green\" | \"blue\";\n\nexport interface LateralChromaticAberrationProfile {\n /** Shared physical image-plane normalization radius in millimetres. */\n normalizationRadiusMm: number;\n /** Shared undistorted normalized-radius operating envelope. */\n maximumNormalizedRadius: number;\n /**\n * Green-reference base geometric distortion.\n *\n * Every channel includes this shared mapping. The red and blue CA terms are\n * added on top of it, so do not apply a second distortion pass.\n */\n baseDistortionCoefficients: RadialDistortionCoefficients;\n /** Additional red-channel radial coefficients relative to green. */\n redCoefficientOffset: RadialDistortionCoefficients;\n /** Additional blue-channel radial coefficients relative to green. */\n blueCoefficientOffset: RadialDistortionCoefficients;\n}\n\nexport interface CalculateLateralChromaticAberrationMappingInput {\n /** Ideal/undistorted image-plane point shared by all channels. */\n imagePointMm: LensFieldPointMm;\n profile: LateralChromaticAberrationProfile;\n}\n\nexport interface CalculateInverseLateralChromaticAberrationMappingInput {\n /**\n * Distorted output image-plane point. Each channel is inverse-mapped on its\n * own to its ideal source point.\n */\n distortedImagePointMm: LensFieldPointMm;\n profile: LateralChromaticAberrationProfile;\n}\n\nexport interface CalculateInverseLateralChromaticAberrationMappingsInput {\n /**\n * Distorted output image-plane points. The profile is resolved once for the\n * batch. Then each point is inverse-mapped separately for red, green and\n * blue.\n */\n distortedImagePointsMm: readonly LensFieldPointMm[];\n profile: LateralChromaticAberrationProfile;\n}\n\nexport interface LateralChromaticAberrationChannelMapping {\n mappedImagePointMm: LensFieldPointMm;\n radialScale: number;\n combinedCoefficients: RadialDistortionCoefficients;\n}\n\nexport interface InverseLateralChromaticAberrationChannelMapping {\n sourceImagePointMm: LensFieldPointMm;\n radialScaleAtSource: number;\n combinedCoefficients: RadialDistortionCoefficients;\n}\n\nexport interface ChannelSeparationVectorMm {\n x: number;\n y: number;\n distance: number;\n}\n\nexport interface LateralChromaticAberrationSeparation {\n redGreen: ChannelSeparationVectorMm;\n blueGreen: ChannelSeparationVectorMm;\n redBlue: ChannelSeparationVectorMm;\n maximumPairDistanceMm: number;\n}\n\nexport interface LateralChromaticAberrationMapping {\n direction: \"undistorted-to-channel-distorted\";\n referenceChannel: \"green\";\n sourceImagePointMm: LensFieldPointMm;\n channels: {\n red: LateralChromaticAberrationChannelMapping;\n green: LateralChromaticAberrationChannelMapping;\n blue: LateralChromaticAberrationChannelMapping;\n };\n separation: LateralChromaticAberrationSeparation;\n}\n\nexport interface InverseLateralChromaticAberrationMapping {\n direction: \"distorted-output-to-channel-sources\";\n referenceChannel: \"green\";\n distortedImagePointMm: LensFieldPointMm;\n channels: {\n red: InverseLateralChromaticAberrationChannelMapping;\n green: InverseLateralChromaticAberrationChannelMapping;\n blue: InverseLateralChromaticAberrationChannelMapping;\n };\n sourceSeparation: LateralChromaticAberrationSeparation;\n}\n\nexport interface InverseLateralChromaticAberrationMappings {\n direction: \"distorted-output-to-channel-sources-batch\";\n referenceChannel: \"green\";\n mappings: readonly InverseLateralChromaticAberrationMapping[];\n pointCount: number;\n}\n\ninterface ChannelProfiles {\n red: RadialDistortionProfile;\n green: RadialDistortionProfile;\n blue: RadialDistortionProfile;\n}\n\nfunction requireFiniteCoefficients(\n path: string,\n coefficients: RadialDistortionCoefficients\n): void {\n for (const key of [\"k1\", \"k2\", \"k3\"] as const) {\n if (!Number.isFinite(coefficients[key])) {\n throw new InvalidScientificInputError(\n `${path}.${key} must be finite.`\n );\n }\n }\n}\n\nfunction addCoefficients(\n base: RadialDistortionCoefficients,\n offset: RadialDistortionCoefficients\n): RadialDistortionCoefficients {\n return {\n k1: base.k1 + offset.k1,\n k2: base.k2 + offset.k2,\n k3: base.k3 + offset.k3\n };\n}\n\nfunction resolveProfiles(\n profile: LateralChromaticAberrationProfile\n): ChannelProfiles {\n requireInputObject(profile, \"profile input\");\n requireFiniteCoefficients(\n \"profile.baseDistortionCoefficients\",\n profile.baseDistortionCoefficients\n );\n requireFiniteCoefficients(\n \"profile.redCoefficientOffset\",\n profile.redCoefficientOffset\n );\n requireFiniteCoefficients(\n \"profile.blueCoefficientOffset\",\n profile.blueCoefficientOffset\n );\n\n const shared = {\n normalizationRadiusMm: profile.normalizationRadiusMm,\n maximumNormalizedRadius: profile.maximumNormalizedRadius\n };\n\n return {\n red: {\n ...shared,\n coefficients: addCoefficients(\n profile.baseDistortionCoefficients,\n profile.redCoefficientOffset\n )\n },\n green: {\n ...shared,\n coefficients: { ...profile.baseDistortionCoefficients }\n },\n blue: {\n ...shared,\n coefficients: addCoefficients(\n profile.baseDistortionCoefficients,\n profile.blueCoefficientOffset\n )\n }\n };\n}\n\nfunction withChannelContext<T>(\n channel: LateralChromaticAberrationChannel,\n calculate: () => T\n): T {\n try {\n return calculate();\n } catch (error: unknown) {\n if (error instanceof InvalidScientificInputError) {\n throw new InvalidScientificInputError(\n `Lateral chromatic aberration ${channel} channel: ${error.message}`\n );\n }\n throw error;\n }\n}\n\nfunction separationVector(\n first: LensFieldPointMm,\n second: LensFieldPointMm\n): ChannelSeparationVectorMm {\n const x = first.x - second.x;\n const y = first.y - second.y;\n return {\n x,\n y,\n distance: Math.hypot(x, y)\n };\n}\n\nfunction separations(\n red: LensFieldPointMm,\n green: LensFieldPointMm,\n blue: LensFieldPointMm\n): LateralChromaticAberrationSeparation {\n const redGreen = separationVector(red, green);\n const blueGreen = separationVector(blue, green);\n const redBlue = separationVector(red, blue);\n\n return {\n redGreen,\n blueGreen,\n redBlue,\n maximumPairDistanceMm: Math.max(\n redGreen.distance,\n blueGreen.distance,\n redBlue.distance\n )\n };\n}\n\nfunction assumptions(): readonly string[] {\n return [\n \"Generic lateral chromatic aberration is represented as independent radial field mapping for abstract red, green, and blue renderer channels\",\n \"Green is the reference field mapping; red and blue coefficient offsets are added to the green-reference base distortion rather than applied as a second warp\",\n \"All channel mappings share one physical normalization radius and declared operating envelope\",\n \"Each combined channel radial profile must remain one-to-one over the declared operating envelope\",\n \"The RGB channel labels are representative rendering channels, not calibrated wavelengths, sensor spectral responses, or CFA primaries\",\n \"This model changes channel field coordinates only; it does not blur, change PSF shape, modify channel intensity, or model longitudinal chromatic aberration\",\n \"Profiles are generic caller inputs and do not represent a named lens unless separately calibrated with defensible provenance\"\n ];\n}\n\n/**\n * Calculates how far lateral chromatic aberration (CA) separates the colour\n * channels at one ideal image-plane point. The point goes through a shared\n * base distortion (green is the reference) plus extra radial coefficients for\n * red and blue.\n *\n * This moves each channel; it is not a blur kernel.\n */\nexport function calculateLateralChromaticAberrationMapping(\n input: CalculateLateralChromaticAberrationMappingInput\n): CalculationResult<LateralChromaticAberrationMapping> {\n requireInputKeys(input, \"calculateLateralChromaticAberrationMapping\", [\"imagePointMm\", \"profile\"]);\n const profiles = resolveProfiles(input.profile);\n\n const red = withChannelContext(\"red\", () =>\n calculateRadialDistortionMapping({\n imagePointMm: input.imagePointMm,\n profile: profiles.red\n })\n ).value;\n const green = withChannelContext(\"green\", () =>\n calculateRadialDistortionMapping({\n imagePointMm: input.imagePointMm,\n profile: profiles.green\n })\n ).value;\n const blue = withChannelContext(\"blue\", () =>\n calculateRadialDistortionMapping({\n imagePointMm: input.imagePointMm,\n profile: profiles.blue\n })\n ).value;\n\n return approximationResult(\n {\n direction: \"undistorted-to-channel-distorted\",\n referenceChannel: \"green\",\n sourceImagePointMm: { ...input.imagePointMm },\n channels: {\n red: {\n mappedImagePointMm: { ...red.mappedImagePointMm },\n radialScale: red.radialScale,\n combinedCoefficients: { ...profiles.red.coefficients }\n },\n green: {\n mappedImagePointMm: { ...green.mappedImagePointMm },\n radialScale: green.radialScale,\n combinedCoefficients: { ...profiles.green.coefficients }\n },\n blue: {\n mappedImagePointMm: { ...blue.mappedImagePointMm },\n radialScale: blue.radialScale,\n combinedCoefficients: { ...profiles.blue.coefficients }\n }\n },\n separation: separations(\n red.mappedImagePointMm,\n green.mappedImagePointMm,\n blue.mappedImagePointMm\n )\n },\n \"generic-green-reference-lateral-chromatic-aberration\",\n \"1.0.0\",\n assumptions()\n );\n}\n\n/**\n * Inverse-maps one distorted output point separately for the representative\n * red, green and blue channels.\n *\n * Renderers can sample the returned per-channel ideal source points directly,\n * without writing their own chromatic-aberration equations.\n */\nexport function calculateInverseLateralChromaticAberrationMapping(\n input: CalculateInverseLateralChromaticAberrationMappingInput\n): CalculationResult<InverseLateralChromaticAberrationMapping> {\n requireInputKeys(input, \"calculateInverseLateralChromaticAberrationMapping\", [\"distortedImagePointMm\", \"profile\"]);\n const profiles = resolveProfiles(input.profile);\n\n const red = withChannelContext(\"red\", () =>\n calculateInverseRadialDistortionMapping({\n distortedImagePointMm: input.distortedImagePointMm,\n profile: profiles.red\n })\n ).value;\n const green = withChannelContext(\"green\", () =>\n calculateInverseRadialDistortionMapping({\n distortedImagePointMm: input.distortedImagePointMm,\n profile: profiles.green\n })\n ).value;\n const blue = withChannelContext(\"blue\", () =>\n calculateInverseRadialDistortionMapping({\n distortedImagePointMm: input.distortedImagePointMm,\n profile: profiles.blue\n })\n ).value;\n\n return approximationResult(\n {\n direction: \"distorted-output-to-channel-sources\",\n referenceChannel: \"green\",\n distortedImagePointMm: { ...input.distortedImagePointMm },\n channels: {\n red: {\n sourceImagePointMm: { ...red.sourceImagePointMm },\n radialScaleAtSource: red.radialScaleAtSource,\n combinedCoefficients: { ...profiles.red.coefficients }\n },\n green: {\n sourceImagePointMm: { ...green.sourceImagePointMm },\n radialScaleAtSource: green.radialScaleAtSource,\n combinedCoefficients: { ...profiles.green.coefficients }\n },\n blue: {\n sourceImagePointMm: { ...blue.sourceImagePointMm },\n radialScaleAtSource: blue.radialScaleAtSource,\n combinedCoefficients: { ...profiles.blue.coefficients }\n }\n },\n sourceSeparation: separations(\n red.sourceImagePointMm,\n green.sourceImagePointMm,\n blue.sourceImagePointMm\n )\n },\n \"generic-inverse-green-reference-lateral-chromatic-aberration\",\n \"1.0.0\",\n assumptions()\n );\n}\n\n/**\n * Inverse-maps many distorted points at once. The shared CA profile is\n * resolved once, and each combined channel profile is validated once, for\n * the whole batch.\n *\n * Each point's values match calculateInverseLateralChromaticAberrationMapping().\n * Provenance is reported once for the batch.\n */\nexport function calculateInverseLateralChromaticAberrationMappings(\n input: CalculateInverseLateralChromaticAberrationMappingsInput\n): CalculationResult<InverseLateralChromaticAberrationMappings> {\n requireInputKeys(input, \"calculateInverseLateralChromaticAberrationMappings\", [\"distortedImagePointsMm\", \"profile\"]);\n const profiles = resolveProfiles(input.profile);\n const validatedProfiles = {\n red: withChannelContext(\"red\", () =>\n validateRadialDistortionProfile(profiles.red)\n ),\n green: withChannelContext(\"green\", () =>\n validateRadialDistortionProfile(profiles.green)\n ),\n blue: withChannelContext(\"blue\", () =>\n validateRadialDistortionProfile(profiles.blue)\n )\n };\n if (!Array.isArray(input.distortedImagePointsMm)) {\n throw new InvalidConfigurationError(\n \"distortedImagePointsMm must be an array of image-plane points.\"\n );\n }\n\n const mappings: InverseLateralChromaticAberrationMapping[] = [];\n for (\n let index = 0;\n index < input.distortedImagePointsMm.length;\n index += 1\n ) {\n const point = input.distortedImagePointsMm[index];\n if (point === undefined) {\n throw new InvalidScientificInputError(\n `distortedImagePointsMm[${index}] must be an image-plane point.`\n );\n }\n\n const red = withChannelContext(\"red\", () =>\n calculateInverseRadialSourcePointValue(\n point,\n validatedProfiles.red,\n `distortedImagePointsMm[${index}]`\n )\n );\n const green = withChannelContext(\"green\", () =>\n calculateInverseRadialSourcePointValue(\n point,\n validatedProfiles.green,\n `distortedImagePointsMm[${index}]`\n )\n );\n const blue = withChannelContext(\"blue\", () =>\n calculateInverseRadialSourcePointValue(\n point,\n validatedProfiles.blue,\n `distortedImagePointsMm[${index}]`\n )\n );\n\n mappings.push({\n direction: \"distorted-output-to-channel-sources\" as const,\n referenceChannel: \"green\" as const,\n distortedImagePointMm: { ...point },\n channels: {\n red: {\n sourceImagePointMm: { ...red.sourceImagePointMm },\n radialScaleAtSource: red.radialScaleAtSource,\n combinedCoefficients: { ...profiles.red.coefficients }\n },\n green: {\n sourceImagePointMm: { ...green.sourceImagePointMm },\n radialScaleAtSource: green.radialScaleAtSource,\n combinedCoefficients: { ...profiles.green.coefficients }\n },\n blue: {\n sourceImagePointMm: { ...blue.sourceImagePointMm },\n radialScaleAtSource: blue.radialScaleAtSource,\n combinedCoefficients: { ...profiles.blue.coefficients }\n }\n },\n sourceSeparation: separations(\n red.sourceImagePointMm,\n green.sourceImagePointMm,\n blue.sourceImagePointMm\n )\n });\n }\n\n return approximationResult(\n {\n direction: \"distorted-output-to-channel-sources-batch\",\n referenceChannel: \"green\",\n mappings,\n pointCount: mappings.length\n },\n \"generic-inverse-green-reference-lateral-chromatic-aberration-batch\",\n \"1.0.0\",\n [\n ...assumptions(),\n \"Combined red/green/blue radial profiles are resolved once for the batch\",\n \"Each channel profile is validated once before batch point sampling\"\n ]\n );\n}\n"]}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Samples the engine's lens PSFs (`LensSampledPsfProfile`, resolved with `resolveLensSampledPsf`) into
|
|
3
|
+
* the per-patch kernels of the isoplanatic convolution (`calculateIrradianceConvolution`, #277).
|
|
4
|
+
*
|
|
5
|
+
* For each patch, the PSF is resolved at the patch centre's field point, in the per-site engine's own
|
|
6
|
+
* coordinates: native sensor millimetres from the optical axis (+Y down), field point (x, −y). Every
|
|
7
|
+
* PSF tap then maps to a site displacement with the per-site quadrature's inverse support
|
|
8
|
+
* (`sensorPsfSourcePoint`): tap (kx, ky) is the source at native offset (−(kx − cx)·pₓ, +(ky − cy)·p_y)
|
|
9
|
+
* from the destination, so its weight lands at displacement u = (kx − cx)·pₓ/sₓ, v = −(ky − cy)·p_y/s_y
|
|
10
|
+
* sites (p: PSF sample pitch, s: site pitch).
|
|
11
|
+
*
|
|
12
|
+
* - **Exact site sampling.** When every displacement is an integer (equal pitches, integer centre), each
|
|
13
|
+
* tap's weight goes to one kernel cell. For a destination whose PSF equals its patch's, the
|
|
14
|
+
* convolution then equals the per-site PSF quadrature at site-centre sources term by term.
|
|
15
|
+
* - **Otherwise (labelled approximation): bilinear splatting.** Each weight is split over the four
|
|
16
|
+
* surrounding integer displacements with bilinear weights. This is the exact adjoint of bilinear
|
|
17
|
+
* interpolation, so the convolution equals the per-site quadrature applied to the bilinear interpolant of
|
|
18
|
+
* the site-centre samples (tested). Weights are conserved.
|
|
19
|
+
*
|
|
20
|
+
* With several wavelengths the kernel is the weight-normalized sum of the per-wavelength kernels. For a
|
|
21
|
+
* spectrally neutral scene that is exactly the per-site engine's spectral sum when the weights are its
|
|
22
|
+
* spectral quadrature weights times the scene spectrum (see docs/WEBGPU.md).
|
|
23
|
+
*
|
|
24
|
+
* The patch approximation (one PSF per patch, indexed by source site) is the caller's choice of patch
|
|
25
|
+
* size; its method error is measured, not bounded (docs/WEBGPU.md, "Per-fixture rollout"). Relative
|
|
26
|
+
* pupil throughput stays a separate factor and is reported, never folded into the unit-energy kernels.
|
|
27
|
+
*/
|
|
28
|
+
import { type CalculationResult } from "../core/calculation-result.js";
|
|
29
|
+
import { type ResolveLensSampledPsfInput } from "./lens-psf-profile.js";
|
|
30
|
+
export declare const LENS_PSF_CONVOLUTION_KERNELS_SCHEMA_VERSION: "0.1.0";
|
|
31
|
+
/** At most this many wavelengths per call. */
|
|
32
|
+
export declare const LENS_PSF_CONVOLUTION_KERNELS_MAXIMUM_WAVELENGTHS = 64;
|
|
33
|
+
export interface LensPsfConvolutionKernelsInput {
|
|
34
|
+
schemaVersion: typeof LENS_PSF_CONVOLUTION_KERNELS_SCHEMA_VERSION;
|
|
35
|
+
/** The optical state, as for `resolveLensSampledPsf`, without the field point and wavelength. */
|
|
36
|
+
psf: Omit<ResolveLensSampledPsfInput, "fieldPointMm" | "wavelengthNm">;
|
|
37
|
+
/** One or more wavelengths with non-negative weights (at least one positive). */
|
|
38
|
+
spectralWeights: readonly {
|
|
39
|
+
wavelengthNm: number;
|
|
40
|
+
weight: number;
|
|
41
|
+
}[];
|
|
42
|
+
/** The convolution grid: sites, their pitch, and the optical axis in site units (site centres at i + 0.5). */
|
|
43
|
+
grid: {
|
|
44
|
+
width: number;
|
|
45
|
+
height: number;
|
|
46
|
+
sitePitchMicrometers: {
|
|
47
|
+
x: number;
|
|
48
|
+
y: number;
|
|
49
|
+
};
|
|
50
|
+
opticalAxisSite: {
|
|
51
|
+
x: number;
|
|
52
|
+
y: number;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
/** Patch size in sites; the last row and column of patches may be partial. */
|
|
56
|
+
patchWidth: number;
|
|
57
|
+
patchHeight: number;
|
|
58
|
+
/** Kernel radius to use; omitted, the smallest radius that holds every tap. A radius too small to hold the PSF is rejected. */
|
|
59
|
+
kernelRadius?: number;
|
|
60
|
+
}
|
|
61
|
+
export interface LensPsfConvolutionKernels {
|
|
62
|
+
schemaVersion: typeof LENS_PSF_CONVOLUTION_KERNELS_SCHEMA_VERSION;
|
|
63
|
+
kernelRadius: number;
|
|
64
|
+
patchWidth: number;
|
|
65
|
+
patchHeight: number;
|
|
66
|
+
patchColumns: number;
|
|
67
|
+
patchRows: number;
|
|
68
|
+
/** `[patchRow][patchColumn][v + r][u + r]`, ready for `IrradianceConvolutionInput.kernels`. */
|
|
69
|
+
kernels: Float64Array;
|
|
70
|
+
/** True when every tap landed on one integer displacement (no bilinear splatting). */
|
|
71
|
+
exactSiteSampling: boolean;
|
|
72
|
+
maximumKernelSum: number;
|
|
73
|
+
/** Per patch, row-major: the field point used and the weight-averaged relative pupil throughput (not applied). */
|
|
74
|
+
patches: readonly {
|
|
75
|
+
fieldPointMm: {
|
|
76
|
+
x: number;
|
|
77
|
+
y: number;
|
|
78
|
+
};
|
|
79
|
+
relativePupilThroughputFactor: number;
|
|
80
|
+
interpolated: boolean;
|
|
81
|
+
}[];
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Builds the per-patch convolution kernels from a sampled lens PSF profile.
|
|
85
|
+
* @param input - See `LensPsfConvolutionKernelsInput`.
|
|
86
|
+
* @returns The kernels and per-patch field points. Success does not imply calibration.
|
|
87
|
+
* @see docs/WEBGPU.md, "Kernels from a lens PSF profile".
|
|
88
|
+
*/
|
|
89
|
+
export declare function resolveLensPsfConvolutionKernels(input: LensPsfConvolutionKernelsInput): CalculationResult<LensPsfConvolutionKernels>;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* Samples the engine's lens PSFs (`LensSampledPsfProfile`, resolved with `resolveLensSampledPsf`) into
|
|
4
|
+
* the per-patch kernels of the isoplanatic convolution (`calculateIrradianceConvolution`, #277).
|
|
5
|
+
*
|
|
6
|
+
* For each patch, the PSF is resolved at the patch centre's field point, in the per-site engine's own
|
|
7
|
+
* coordinates: native sensor millimetres from the optical axis (+Y down), field point (x, −y). Every
|
|
8
|
+
* PSF tap then maps to a site displacement with the per-site quadrature's inverse support
|
|
9
|
+
* (`sensorPsfSourcePoint`): tap (kx, ky) is the source at native offset (−(kx − cx)·pₓ, +(ky − cy)·p_y)
|
|
10
|
+
* from the destination, so its weight lands at displacement u = (kx − cx)·pₓ/sₓ, v = −(ky − cy)·p_y/s_y
|
|
11
|
+
* sites (p: PSF sample pitch, s: site pitch).
|
|
12
|
+
*
|
|
13
|
+
* - **Exact site sampling.** When every displacement is an integer (equal pitches, integer centre), each
|
|
14
|
+
* tap's weight goes to one kernel cell. For a destination whose PSF equals its patch's, the
|
|
15
|
+
* convolution then equals the per-site PSF quadrature at site-centre sources term by term.
|
|
16
|
+
* - **Otherwise (labelled approximation): bilinear splatting.** Each weight is split over the four
|
|
17
|
+
* surrounding integer displacements with bilinear weights. This is the exact adjoint of bilinear
|
|
18
|
+
* interpolation, so the convolution equals the per-site quadrature applied to the bilinear interpolant of
|
|
19
|
+
* the site-centre samples (tested). Weights are conserved.
|
|
20
|
+
*
|
|
21
|
+
* With several wavelengths the kernel is the weight-normalized sum of the per-wavelength kernels. For a
|
|
22
|
+
* spectrally neutral scene that is exactly the per-site engine's spectral sum when the weights are its
|
|
23
|
+
* spectral quadrature weights times the scene spectrum (see docs/WEBGPU.md).
|
|
24
|
+
*
|
|
25
|
+
* The patch approximation (one PSF per patch, indexed by source site) is the caller's choice of patch
|
|
26
|
+
* size; its method error is measured, not bounded (docs/WEBGPU.md, "Per-fixture rollout"). Relative
|
|
27
|
+
* pupil throughput stays a separate factor and is reported, never folded into the unit-energy kernels.
|
|
28
|
+
*/
|
|
29
|
+
import { approximationResult } from "../core/calculation-result.js";
|
|
30
|
+
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
31
|
+
import { requireAllowlistedRecord } from "../core/record-validation.js";
|
|
32
|
+
import { IRRADIANCE_CONVOLUTION_LIMITS } from "./irradiance-convolution.js";
|
|
33
|
+
import { markEngineOwnedLensSampledPsfProfile, resolveLensSampledPsf } from "./lens-psf-profile.js";
|
|
34
|
+
export const LENS_PSF_CONVOLUTION_KERNELS_SCHEMA_VERSION = "0.1.0";
|
|
35
|
+
/** At most this many wavelengths per call. */
|
|
36
|
+
export const LENS_PSF_CONVOLUTION_KERNELS_MAXIMUM_WAVELENGTHS = 64;
|
|
37
|
+
function positive(value, message) {
|
|
38
|
+
if (typeof value !== "number" || !(value > 0 && value <= Number.MAX_VALUE))
|
|
39
|
+
throw new InvalidConfigurationError(message);
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
function integer(value, minimum, maximum, message) {
|
|
43
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < minimum || value > maximum)
|
|
44
|
+
throw new InvalidConfigurationError(message);
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Builds the per-patch convolution kernels from a sampled lens PSF profile.
|
|
49
|
+
* @param input - See `LensPsfConvolutionKernelsInput`.
|
|
50
|
+
* @returns The kernels and per-patch field points. Success does not imply calibration.
|
|
51
|
+
* @see docs/WEBGPU.md, "Kernels from a lens PSF profile".
|
|
52
|
+
*/
|
|
53
|
+
export function resolveLensPsfConvolutionKernels(input) {
|
|
54
|
+
const r = requireAllowlistedRecord(input, ["schemaVersion", "psf", "spectralWeights", "grid", "patchWidth", "patchHeight", "kernelRadius"], "Invalid lens PSF convolution kernel input.");
|
|
55
|
+
if (r.schemaVersion !== LENS_PSF_CONVOLUTION_KERNELS_SCHEMA_VERSION)
|
|
56
|
+
throw new InvalidConfigurationError("Unsupported lens PSF convolution kernel schema.");
|
|
57
|
+
const L = IRRADIANCE_CONVOLUTION_LIMITS;
|
|
58
|
+
const g = requireAllowlistedRecord(r.grid, ["width", "height", "sitePitchMicrometers", "opticalAxisSite"], "Invalid convolution grid.");
|
|
59
|
+
const width = integer(g.width, 1, L.maximumDimension, "Invalid convolution grid size."), height = integer(g.height, 1, L.maximumDimension, "Invalid convolution grid size.");
|
|
60
|
+
const pitch = requireAllowlistedRecord(g.sitePitchMicrometers, ["x", "y"], "Invalid site pitch.");
|
|
61
|
+
const sx = positive(pitch.x, "Site pitch must be positive."), sy = positive(pitch.y, "Site pitch must be positive.");
|
|
62
|
+
const axis = requireAllowlistedRecord(g.opticalAxisSite, ["x", "y"], "Invalid optical axis.");
|
|
63
|
+
if (typeof axis.x !== "number" || typeof axis.y !== "number" || !Number.isFinite(axis.x) || !Number.isFinite(axis.y)) {
|
|
64
|
+
throw new InvalidConfigurationError("The optical axis must be finite site coordinates.");
|
|
65
|
+
}
|
|
66
|
+
const patchWidth = integer(r.patchWidth, 1, width, "Invalid patch size."), patchHeight = integer(r.patchHeight, 1, height, "Invalid patch size.");
|
|
67
|
+
const columns = Math.ceil(width / patchWidth), rows = Math.ceil(height / patchHeight);
|
|
68
|
+
if (columns * rows > L.maximumPatchCount)
|
|
69
|
+
throw new InvalidConfigurationError("Too many patches.");
|
|
70
|
+
const list = r.spectralWeights;
|
|
71
|
+
if (!Array.isArray(list) || list.length < 1 || list.length > LENS_PSF_CONVOLUTION_KERNELS_MAXIMUM_WAVELENGTHS) {
|
|
72
|
+
throw new InvalidConfigurationError("spectralWeights must list 1 to 64 wavelengths.");
|
|
73
|
+
}
|
|
74
|
+
const spectral = list.map((entry) => {
|
|
75
|
+
const e = requireAllowlistedRecord(entry, ["wavelengthNm", "weight"], "Invalid spectral weight.");
|
|
76
|
+
if (typeof e.weight !== "number" || !(e.weight >= 0 && e.weight <= Number.MAX_VALUE))
|
|
77
|
+
throw new InvalidConfigurationError("Spectral weights must be finite and non-negative.");
|
|
78
|
+
return { wavelengthNm: positive(e.wavelengthNm, "Wavelengths must be positive."), weight: e.weight };
|
|
79
|
+
});
|
|
80
|
+
const totalWeight = spectral.reduce((s, e) => s + e.weight, 0);
|
|
81
|
+
if (!(totalWeight > 0 && totalWeight <= Number.MAX_VALUE))
|
|
82
|
+
throw new InvalidConfigurationError("At least one spectral weight must be positive.");
|
|
83
|
+
const psf = requireAllowlistedRecord(r.psf, ["profile", "focalLengthMm", "focus", "apertureFNumber", "signedDefocusImagePlaneMicrometers"], "Invalid PSF state.");
|
|
84
|
+
// One private parse of the profile for every patch and wavelength.
|
|
85
|
+
const profile = structuredClone(psf.profile);
|
|
86
|
+
markEngineOwnedLensSampledPsfProfile(profile);
|
|
87
|
+
const state = { ...psf, profile };
|
|
88
|
+
// Resolve every patch and wavelength, splatting straight into one scratch displacement map sized for the largest
|
|
89
|
+
// allowed radius; each patch keeps a copy cropped to its own reach. The common radius is known only at the end.
|
|
90
|
+
// Every cell receives its weights in the same order as a direct sum (taps in kernel order, then the four
|
|
91
|
+
// bilinear corners), so the kernels do not depend on the scratch layout.
|
|
92
|
+
const M = L.maximumKernelRadius, scratchSize = 2 * M + 1, scratch = new Float64Array(scratchSize * scratchSize);
|
|
93
|
+
const cropped = [], patches = [];
|
|
94
|
+
let reach = 0, exact = true, overflow = false;
|
|
95
|
+
for (let pr = 0; pr < rows; pr++)
|
|
96
|
+
for (let pc = 0; pc < columns; pc++) {
|
|
97
|
+
const x0 = pc * patchWidth, y0 = pr * patchHeight, x1 = Math.min(width, x0 + patchWidth), y1 = Math.min(height, y0 + patchHeight);
|
|
98
|
+
const nativeX = ((x0 + x1) / 2 - axis.x) * sx / 1000, nativeY = ((y0 + y1) / 2 - axis.y) * sy / 1000;
|
|
99
|
+
const fieldPointMm = { x: nativeX, y: -nativeY };
|
|
100
|
+
let throughput = 0, interpolated = false, patchReach = 0;
|
|
101
|
+
for (const { wavelengthNm, weight } of spectral) {
|
|
102
|
+
if (weight === 0)
|
|
103
|
+
continue;
|
|
104
|
+
const resolved = resolveLensSampledPsf({ ...state, fieldPointMm, wavelengthNm }).value, k = resolved.kernel, share = weight / totalWeight;
|
|
105
|
+
throughput += share * resolved.relativePupilThroughputFactor;
|
|
106
|
+
if (resolved.resolutionStatus !== "exact-grid-sample")
|
|
107
|
+
interpolated = true;
|
|
108
|
+
for (let ky = 0; ky < k.heightSamples; ky++)
|
|
109
|
+
for (let kx = 0; kx < k.widthSamples; kx++) {
|
|
110
|
+
const intensity = k.normalizedIntensity[ky * k.widthSamples + kx];
|
|
111
|
+
if (intensity === 0)
|
|
112
|
+
continue;
|
|
113
|
+
const u = (kx - k.centerSampleX) * k.samplePitchMicrometersX / sx, v = -(ky - k.centerSampleY) * k.samplePitchMicrometersY / sy;
|
|
114
|
+
const u0 = Math.floor(u), v0 = Math.floor(v), fu = u - u0, fv = v - v0, w = share * intensity;
|
|
115
|
+
if (fu !== 0 || fv !== 0)
|
|
116
|
+
exact = false;
|
|
117
|
+
for (let corner = 0; corner < 4; corner++) {
|
|
118
|
+
const du = corner & 1, dv = corner >> 1;
|
|
119
|
+
const b = du === 0 ? (dv === 0 ? (1 - fu) * (1 - fv) : (1 - fu) * fv) : (dv === 0 ? fu * (1 - fv) : fu * fv);
|
|
120
|
+
if (b === 0)
|
|
121
|
+
continue;
|
|
122
|
+
const cu = u0 + du, cv = v0 + dv;
|
|
123
|
+
patchReach = Math.max(patchReach, Math.abs(cu), Math.abs(cv));
|
|
124
|
+
// Past the largest radius the call is rejected below; resolving continues so errors keep their order.
|
|
125
|
+
if (patchReach > M) {
|
|
126
|
+
overflow = true;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (!overflow)
|
|
130
|
+
scratch[(cv + M) * scratchSize + cu + M] += w * b;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
reach = Math.max(reach, patchReach);
|
|
135
|
+
if (!overflow) {
|
|
136
|
+
const n = 2 * patchReach + 1, values = new Float64Array(n * n);
|
|
137
|
+
for (let v = -patchReach; v <= patchReach; v++) {
|
|
138
|
+
const row = (v + M) * scratchSize + M;
|
|
139
|
+
values.set(scratch.subarray(row - patchReach, row + patchReach + 1), (v + patchReach) * n);
|
|
140
|
+
scratch.fill(0, row - patchReach, row + patchReach + 1);
|
|
141
|
+
}
|
|
142
|
+
cropped.push({ reach: patchReach, values });
|
|
143
|
+
}
|
|
144
|
+
patches.push(Object.freeze({ fieldPointMm: Object.freeze(fieldPointMm), relativePupilThroughputFactor: throughput, interpolated }));
|
|
145
|
+
}
|
|
146
|
+
const radius = r.kernelRadius === undefined ? reach : integer(r.kernelRadius, 0, L.maximumKernelRadius, "Invalid kernel radius.");
|
|
147
|
+
if (reach > radius)
|
|
148
|
+
throw new InvalidConfigurationError("The kernel radius is too small for the PSF support; no tap is dropped.");
|
|
149
|
+
if (radius > L.maximumKernelRadius)
|
|
150
|
+
throw new InvalidConfigurationError("The PSF support needs a kernel radius above 32 sites.");
|
|
151
|
+
const size = 2 * radius + 1, taps = size * size;
|
|
152
|
+
if (columns * rows * taps > L.maximumKernelWeights)
|
|
153
|
+
throw new InvalidConfigurationError("Too many kernel weights.");
|
|
154
|
+
const kernels = new Float64Array(columns * rows * taps);
|
|
155
|
+
let maximumKernelSum = 0;
|
|
156
|
+
cropped.forEach(({ reach: q, values }, p) => {
|
|
157
|
+
const n = 2 * q + 1;
|
|
158
|
+
let sum = 0;
|
|
159
|
+
for (let v = 0; v < n; v++)
|
|
160
|
+
kernels.set(values.subarray(v * n, (v + 1) * n), p * taps + (v - q + radius) * size + radius - q);
|
|
161
|
+
for (let t = 0; t < taps; t++)
|
|
162
|
+
sum += kernels[p * taps + t];
|
|
163
|
+
maximumKernelSum = Math.max(maximumKernelSum, sum);
|
|
164
|
+
});
|
|
165
|
+
if (maximumKernelSum > L.maximumKernelSum)
|
|
166
|
+
throw new InvalidConfigurationError("Sampled kernels exceed unit energy.");
|
|
167
|
+
return approximationResult({ schemaVersion: LENS_PSF_CONVOLUTION_KERNELS_SCHEMA_VERSION, kernelRadius: radius, patchWidth, patchHeight,
|
|
168
|
+
patchColumns: columns, patchRows: rows, kernels, exactSiteSampling: exact, maximumKernelSum, patches: Object.freeze(patches) }, "lens-psf-convolution-kernels", LENS_PSF_CONVOLUTION_KERNELS_SCHEMA_VERSION, [
|
|
169
|
+
"One PSF per patch, resolved at the patch centre with resolveLensSampledPsf; indexed by source site in the convolution (isoplanatic patches).",
|
|
170
|
+
exact ? "Every PSF tap maps to one integer site displacement (exact site sampling)." :
|
|
171
|
+
"PSF taps between sites are split bilinearly (the adjoint of bilinear interpolation of site-centre samples); a labelled approximation.",
|
|
172
|
+
"Relative pupil throughput is reported per patch and not applied to the unit-energy kernels."
|
|
173
|
+
]);
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=lens-psf-kernels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lens-psf-kernels.js","sourceRoot":"","sources":["../../src/optics/lens-psf-kernels.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Samples the engine's lens PSFs (`LensSampledPsfProfile`, resolved with `resolveLensSampledPsf`) into\n * the per-patch kernels of the isoplanatic convolution (`calculateIrradianceConvolution`, #277).\n *\n * For each patch, the PSF is resolved at the patch centre's field point, in the per-site engine's own\n * coordinates: native sensor millimetres from the optical axis (+Y down), field point (x, −y). Every\n * PSF tap then maps to a site displacement with the per-site quadrature's inverse support\n * (`sensorPsfSourcePoint`): tap (kx, ky) is the source at native offset (−(kx − cx)·pₓ, +(ky − cy)·p_y)\n * from the destination, so its weight lands at displacement u = (kx − cx)·pₓ/sₓ, v = −(ky − cy)·p_y/s_y\n * sites (p: PSF sample pitch, s: site pitch).\n *\n * - **Exact site sampling.** When every displacement is an integer (equal pitches, integer centre), each\n * tap's weight goes to one kernel cell. For a destination whose PSF equals its patch's, the\n * convolution then equals the per-site PSF quadrature at site-centre sources term by term.\n * - **Otherwise (labelled approximation): bilinear splatting.** Each weight is split over the four\n * surrounding integer displacements with bilinear weights. This is the exact adjoint of bilinear\n * interpolation, so the convolution equals the per-site quadrature applied to the bilinear interpolant of\n * the site-centre samples (tested). Weights are conserved.\n *\n * With several wavelengths the kernel is the weight-normalized sum of the per-wavelength kernels. For a\n * spectrally neutral scene that is exactly the per-site engine's spectral sum when the weights are its\n * spectral quadrature weights times the scene spectrum (see docs/WEBGPU.md).\n *\n * The patch approximation (one PSF per patch, indexed by source site) is the caller's choice of patch\n * size; its method error is measured, not bounded (docs/WEBGPU.md, \"Per-fixture rollout\"). Relative\n * pupil throughput stays a separate factor and is reported, never folded into the unit-energy kernels.\n */\n\nimport { approximationResult, type CalculationResult } from \"../core/calculation-result.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { requireAllowlistedRecord } from \"../core/record-validation.js\";\nimport { IRRADIANCE_CONVOLUTION_LIMITS } from \"./irradiance-convolution.js\";\nimport { markEngineOwnedLensSampledPsfProfile, resolveLensSampledPsf, type ResolveLensSampledPsfInput } from \"./lens-psf-profile.js\";\n\nexport const LENS_PSF_CONVOLUTION_KERNELS_SCHEMA_VERSION = \"0.1.0\" as const;\n/** At most this many wavelengths per call. */\nexport const LENS_PSF_CONVOLUTION_KERNELS_MAXIMUM_WAVELENGTHS = 64;\n\nexport interface LensPsfConvolutionKernelsInput {\n schemaVersion: typeof LENS_PSF_CONVOLUTION_KERNELS_SCHEMA_VERSION;\n /** The optical state, as for `resolveLensSampledPsf`, without the field point and wavelength. */\n psf: Omit<ResolveLensSampledPsfInput, \"fieldPointMm\" | \"wavelengthNm\">;\n /** One or more wavelengths with non-negative weights (at least one positive). */\n spectralWeights: readonly { wavelengthNm: number; weight: number }[];\n /** The convolution grid: sites, their pitch, and the optical axis in site units (site centres at i + 0.5). */\n grid: { width: number; height: number; sitePitchMicrometers: { x: number; y: number }; opticalAxisSite: { x: number; y: number } };\n /** Patch size in sites; the last row and column of patches may be partial. */\n patchWidth: number;\n patchHeight: number;\n /** Kernel radius to use; omitted, the smallest radius that holds every tap. A radius too small to hold the PSF is rejected. */\n kernelRadius?: number;\n}\n\nexport interface LensPsfConvolutionKernels {\n schemaVersion: typeof LENS_PSF_CONVOLUTION_KERNELS_SCHEMA_VERSION;\n kernelRadius: number;\n patchWidth: number;\n patchHeight: number;\n patchColumns: number;\n patchRows: number;\n /** `[patchRow][patchColumn][v + r][u + r]`, ready for `IrradianceConvolutionInput.kernels`. */\n kernels: Float64Array;\n /** True when every tap landed on one integer displacement (no bilinear splatting). */\n exactSiteSampling: boolean;\n maximumKernelSum: number;\n /** Per patch, row-major: the field point used and the weight-averaged relative pupil throughput (not applied). */\n patches: readonly { fieldPointMm: { x: number; y: number }; relativePupilThroughputFactor: number; interpolated: boolean }[];\n}\n\nfunction positive(value: unknown, message: string): number {\n if (typeof value !== \"number\" || !(value > 0 && value <= Number.MAX_VALUE)) throw new InvalidConfigurationError(message);\n return value;\n}\nfunction integer(value: unknown, minimum: number, maximum: number, message: string): number {\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < minimum || value > maximum) throw new InvalidConfigurationError(message);\n return value;\n}\n\n/**\n * Builds the per-patch convolution kernels from a sampled lens PSF profile.\n * @param input - See `LensPsfConvolutionKernelsInput`.\n * @returns The kernels and per-patch field points. Success does not imply calibration.\n * @see docs/WEBGPU.md, \"Kernels from a lens PSF profile\".\n */\nexport function resolveLensPsfConvolutionKernels(input: LensPsfConvolutionKernelsInput): CalculationResult<LensPsfConvolutionKernels> {\n const r = requireAllowlistedRecord(input, [\"schemaVersion\", \"psf\", \"spectralWeights\", \"grid\", \"patchWidth\", \"patchHeight\", \"kernelRadius\"],\n \"Invalid lens PSF convolution kernel input.\");\n if (r.schemaVersion !== LENS_PSF_CONVOLUTION_KERNELS_SCHEMA_VERSION) throw new InvalidConfigurationError(\"Unsupported lens PSF convolution kernel schema.\");\n const L = IRRADIANCE_CONVOLUTION_LIMITS;\n const g = requireAllowlistedRecord(r.grid, [\"width\", \"height\", \"sitePitchMicrometers\", \"opticalAxisSite\"], \"Invalid convolution grid.\");\n const width = integer(g.width, 1, L.maximumDimension, \"Invalid convolution grid size.\"), height = integer(g.height, 1, L.maximumDimension, \"Invalid convolution grid size.\");\n const pitch = requireAllowlistedRecord(g.sitePitchMicrometers, [\"x\", \"y\"], \"Invalid site pitch.\");\n const sx = positive(pitch.x, \"Site pitch must be positive.\"), sy = positive(pitch.y, \"Site pitch must be positive.\");\n const axis = requireAllowlistedRecord(g.opticalAxisSite, [\"x\", \"y\"], \"Invalid optical axis.\");\n if (typeof axis.x !== \"number\" || typeof axis.y !== \"number\" || !Number.isFinite(axis.x) || !Number.isFinite(axis.y)) {\n throw new InvalidConfigurationError(\"The optical axis must be finite site coordinates.\");\n }\n const patchWidth = integer(r.patchWidth, 1, width, \"Invalid patch size.\"), patchHeight = integer(r.patchHeight, 1, height, \"Invalid patch size.\");\n const columns = Math.ceil(width / patchWidth), rows = Math.ceil(height / patchHeight);\n if (columns * rows > L.maximumPatchCount) throw new InvalidConfigurationError(\"Too many patches.\");\n const list = r.spectralWeights;\n if (!Array.isArray(list) || list.length < 1 || list.length > LENS_PSF_CONVOLUTION_KERNELS_MAXIMUM_WAVELENGTHS) {\n throw new InvalidConfigurationError(\"spectralWeights must list 1 to 64 wavelengths.\");\n }\n const spectral = list.map((entry: unknown) => {\n const e = requireAllowlistedRecord(entry, [\"wavelengthNm\", \"weight\"], \"Invalid spectral weight.\");\n if (typeof e.weight !== \"number\" || !(e.weight >= 0 && e.weight <= Number.MAX_VALUE)) throw new InvalidConfigurationError(\"Spectral weights must be finite and non-negative.\");\n return { wavelengthNm: positive(e.wavelengthNm, \"Wavelengths must be positive.\"), weight: e.weight };\n });\n const totalWeight = spectral.reduce((s, e) => s + e.weight, 0);\n if (!(totalWeight > 0 && totalWeight <= Number.MAX_VALUE)) throw new InvalidConfigurationError(\"At least one spectral weight must be positive.\");\n const psf = requireAllowlistedRecord(r.psf, [\"profile\", \"focalLengthMm\", \"focus\", \"apertureFNumber\", \"signedDefocusImagePlaneMicrometers\"], \"Invalid PSF state.\");\n // One private parse of the profile for every patch and wavelength.\n const profile = structuredClone(psf.profile);\n markEngineOwnedLensSampledPsfProfile(profile);\n const state = { ...(psf as unknown as Omit<ResolveLensSampledPsfInput, \"fieldPointMm\" | \"wavelengthNm\">), profile } as Omit<ResolveLensSampledPsfInput, \"fieldPointMm\" | \"wavelengthNm\">;\n\n // Resolve every patch and wavelength, splatting straight into one scratch displacement map sized for the largest\n // allowed radius; each patch keeps a copy cropped to its own reach. The common radius is known only at the end.\n // Every cell receives its weights in the same order as a direct sum (taps in kernel order, then the four\n // bilinear corners), so the kernels do not depend on the scratch layout.\n const M = L.maximumKernelRadius, scratchSize = 2 * M + 1, scratch = new Float64Array(scratchSize * scratchSize);\n const cropped: { reach: number; values: Float64Array }[] = [], patches: LensPsfConvolutionKernels[\"patches\"][number][] = [];\n let reach = 0, exact = true, overflow = false;\n for (let pr = 0; pr < rows; pr++) for (let pc = 0; pc < columns; pc++) {\n const x0 = pc * patchWidth, y0 = pr * patchHeight, x1 = Math.min(width, x0 + patchWidth), y1 = Math.min(height, y0 + patchHeight);\n const nativeX = ((x0 + x1) / 2 - axis.x) * sx / 1000, nativeY = ((y0 + y1) / 2 - axis.y) * sy / 1000;\n const fieldPointMm = { x: nativeX, y: -nativeY };\n let throughput = 0, interpolated = false, patchReach = 0;\n for (const { wavelengthNm, weight } of spectral) {\n if (weight === 0) continue;\n const resolved = resolveLensSampledPsf({ ...state, fieldPointMm, wavelengthNm }).value, k = resolved.kernel, share = weight / totalWeight;\n throughput += share * resolved.relativePupilThroughputFactor;\n if (resolved.resolutionStatus !== \"exact-grid-sample\") interpolated = true;\n for (let ky = 0; ky < k.heightSamples; ky++) for (let kx = 0; kx < k.widthSamples; kx++) {\n const intensity = k.normalizedIntensity[ky * k.widthSamples + kx]!;\n if (intensity === 0) continue;\n const u = (kx - k.centerSampleX) * k.samplePitchMicrometersX / sx, v = -(ky - k.centerSampleY) * k.samplePitchMicrometersY / sy;\n const u0 = Math.floor(u), v0 = Math.floor(v), fu = u - u0, fv = v - v0, w = share * intensity;\n if (fu !== 0 || fv !== 0) exact = false;\n for (let corner = 0; corner < 4; corner++) {\n const du = corner & 1, dv = corner >> 1;\n const b = du === 0 ? (dv === 0 ? (1 - fu) * (1 - fv) : (1 - fu) * fv) : (dv === 0 ? fu * (1 - fv) : fu * fv);\n if (b === 0) continue;\n const cu = u0 + du, cv = v0 + dv;\n patchReach = Math.max(patchReach, Math.abs(cu), Math.abs(cv));\n // Past the largest radius the call is rejected below; resolving continues so errors keep their order.\n if (patchReach > M) { overflow = true; continue; }\n if (!overflow) scratch[(cv + M) * scratchSize + cu + M]! += w * b;\n }\n }\n }\n reach = Math.max(reach, patchReach);\n if (!overflow) {\n const n = 2 * patchReach + 1, values = new Float64Array(n * n);\n for (let v = -patchReach; v <= patchReach; v++) {\n const row = (v + M) * scratchSize + M;\n values.set(scratch.subarray(row - patchReach, row + patchReach + 1), (v + patchReach) * n);\n scratch.fill(0, row - patchReach, row + patchReach + 1);\n }\n cropped.push({ reach: patchReach, values });\n }\n patches.push(Object.freeze({ fieldPointMm: Object.freeze(fieldPointMm), relativePupilThroughputFactor: throughput, interpolated }));\n }\n const radius = r.kernelRadius === undefined ? reach : integer(r.kernelRadius, 0, L.maximumKernelRadius, \"Invalid kernel radius.\");\n if (reach > radius) throw new InvalidConfigurationError(\"The kernel radius is too small for the PSF support; no tap is dropped.\");\n if (radius > L.maximumKernelRadius) throw new InvalidConfigurationError(\"The PSF support needs a kernel radius above 32 sites.\");\n const size = 2 * radius + 1, taps = size * size;\n if (columns * rows * taps > L.maximumKernelWeights) throw new InvalidConfigurationError(\"Too many kernel weights.\");\n const kernels = new Float64Array(columns * rows * taps);\n let maximumKernelSum = 0;\n cropped.forEach(({ reach: q, values }, p) => {\n const n = 2 * q + 1;\n let sum = 0;\n for (let v = 0; v < n; v++) kernels.set(values.subarray(v * n, (v + 1) * n), p * taps + (v - q + radius) * size + radius - q);\n for (let t = 0; t < taps; t++) sum += kernels[p * taps + t]!;\n maximumKernelSum = Math.max(maximumKernelSum, sum);\n });\n if (maximumKernelSum > L.maximumKernelSum) throw new InvalidConfigurationError(\"Sampled kernels exceed unit energy.\");\n return approximationResult({ schemaVersion: LENS_PSF_CONVOLUTION_KERNELS_SCHEMA_VERSION, kernelRadius: radius, patchWidth, patchHeight,\n patchColumns: columns, patchRows: rows, kernels, exactSiteSampling: exact, maximumKernelSum, patches: Object.freeze(patches) },\n \"lens-psf-convolution-kernels\", LENS_PSF_CONVOLUTION_KERNELS_SCHEMA_VERSION, [\n \"One PSF per patch, resolved at the patch centre with resolveLensSampledPsf; indexed by source site in the convolution (isoplanatic patches).\",\n exact ? \"Every PSF tap maps to one integer site displacement (exact site sampling).\" :\n \"PSF taps between sites are split bilinearly (the adjoint of bilinear interpolation of site-centre samples); a labelled approximation.\",\n \"Relative pupil throughput is reported per patch and not applied to the unit-energy kernels.\"\n ]);\n}\n"]}
|