@photivra/engine 1.4.0 → 2.0.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 +401 -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 +118 -5
- package/dist/capture/native-raw-development.js +224 -59
- 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 +67 -10
- package/dist/capture/native-raw.js +90 -24
- 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/host-yield.d.ts +7 -0
- package/dist/facade/host-yield.js +23 -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 +284 -0
- package/dist/facade/simulate-capture.js +1026 -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 +89 -25
- package/dist/index.js +59 -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.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 +761 -2
- package/docs/QUICK_START.md +495 -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 -4
- package/docs/api/capture-native-raw-dng.md +84 -0
- package/docs/api/capture-native-raw.md +23 -8
- 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 +2213 -8
- 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 +324 -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.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 -12
- 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/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 -47
- 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_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/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/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
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* Generic Brown-Conrady lens distortion: radial (k1, k2, k3) plus tangential/decentering (p1, p2)
|
|
4
|
+
* terms on normalized image-plane coordinates (x, y) = point / normalizationRadiusMm, r^2 = x^2 + y^2:
|
|
5
|
+
* x_d = x (1 + k1 r^2 + k2 r^4 + k3 r^6) + 2 p1 x y + p2 (r^2 + 2 x^2)
|
|
6
|
+
* y_d = y (1 + k1 r^2 + k2 r^4 + k3 r^6) + p1 (r^2 + 2 y^2) + 2 p2 x y
|
|
7
|
+
* In vector form the tangential term is r^2 P + 2 (P . u) u with P = (p2, p1), so (p1, p2) rotate as
|
|
8
|
+
* a vector with the image.
|
|
9
|
+
*
|
|
10
|
+
* Sources: Conrady 1919 (MNRAS 79:384, decentred lens systems); Brown 1966
|
|
11
|
+
* (Photogrammetric Engineering 32:444, "Decentering distortion of lenses"); Brown 1971 (Photogramm.
|
|
12
|
+
* Eng. 37:855, close-range camera calibration). The coefficient layout follows the widely used
|
|
13
|
+
* Brown-Conrady convention (for example Heikkila & Silven 1997, CVPR). The coefficient names match
|
|
14
|
+
* that convention, but the values only mean something together with the declared normalization
|
|
15
|
+
* radius.
|
|
16
|
+
*
|
|
17
|
+
* Validity checks (matching the radial-distortion validator):
|
|
18
|
+
* - The radial part must be strictly monotonic over the envelope (the valid radius range).
|
|
19
|
+
* - The Jacobian determinant must stay positive at a dense, fixed polar grid of samples over the
|
|
20
|
+
* envelope disk.
|
|
21
|
+
* - The mapped envelope boundary must have strictly increasing polar angle, so it is a simple
|
|
22
|
+
* star-shaped curve.
|
|
23
|
+
* A smooth, locally invertible map of a closed disk that is one-to-one on its boundary is one-to-one
|
|
24
|
+
* everywhere. So these conditions make the inverse single-valued. Note that the Jacobian and boundary
|
|
25
|
+
* conditions are checked at samples, not proven between them.
|
|
26
|
+
*
|
|
27
|
+
* The inverse uses damped Newton iteration, starting from the radial-only inverse.
|
|
28
|
+
* @see docs/PHYSICS_FOUNDATION.md for the equations, units, coordinate conventions, known blockers
|
|
29
|
+
* and support limits.
|
|
30
|
+
*/
|
|
31
|
+
import { approximationResult } from "../core/calculation-result.js";
|
|
32
|
+
import { InvalidScientificInputError } from "../core/validation.js";
|
|
33
|
+
import { calculateInverseRadialSourcePointValue, validateRadialDistortionProfile } from "./radial-distortion.js";
|
|
34
|
+
import { requireInputKeys } from "../core/record-validation.js";
|
|
35
|
+
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
36
|
+
const VALIDATION_RINGS = 64;
|
|
37
|
+
const VALIDATION_AZIMUTHS = 256;
|
|
38
|
+
const MAXIMUM_NEWTON_ITERATIONS = 100;
|
|
39
|
+
function requireFinite(name, value) {
|
|
40
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
41
|
+
throw new InvalidScientificInputError(`${name} must be finite.`);
|
|
42
|
+
}
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
function requirePoint(name, point) {
|
|
46
|
+
if (typeof point !== "object" || point === null) {
|
|
47
|
+
throw new InvalidConfigurationError(`${name} must be an object with finite numeric x and y coordinates.`);
|
|
48
|
+
}
|
|
49
|
+
const record = point;
|
|
50
|
+
return {
|
|
51
|
+
x: requireFinite(`${name}.x`, record.x),
|
|
52
|
+
y: requireFinite(`${name}.y`, record.y)
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/** Forward map on normalized coordinates. */
|
|
56
|
+
function forwardNormalized(x, y, c) {
|
|
57
|
+
const r2 = x * x + y * y;
|
|
58
|
+
const radial = 1 + r2 * (c.k1 + r2 * (c.k2 + r2 * c.k3));
|
|
59
|
+
return {
|
|
60
|
+
x: x * radial + 2 * c.p1 * x * y + c.p2 * (r2 + 2 * x * x),
|
|
61
|
+
y: y * radial + c.p1 * (r2 + 2 * y * y) + 2 * c.p2 * x * y
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** Jacobian [[a, b], [c, d]] of the normalized forward map. */
|
|
65
|
+
function jacobianNormalized(x, y, c) {
|
|
66
|
+
const r2 = x * x + y * y;
|
|
67
|
+
const s = 1 + r2 * (c.k1 + r2 * (c.k2 + r2 * c.k3));
|
|
68
|
+
const ds = c.k1 + r2 * (2 * c.k2 + 3 * c.k3 * r2);
|
|
69
|
+
const off = 2 * x * y * ds + 2 * c.p1 * x + 2 * c.p2 * y;
|
|
70
|
+
return {
|
|
71
|
+
a: s + 2 * x * x * ds + 2 * c.p1 * y + 6 * c.p2 * x,
|
|
72
|
+
b: off,
|
|
73
|
+
c: off,
|
|
74
|
+
d: s + 2 * y * y * ds + 6 * c.p1 * y + 2 * c.p2 * x
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function determinant(j) {
|
|
78
|
+
return j.a * j.d - j.b * j.c;
|
|
79
|
+
}
|
|
80
|
+
function validateProfile(profile) {
|
|
81
|
+
if (typeof profile !== "object" || profile === null) {
|
|
82
|
+
throw new InvalidConfigurationError("profile must be an object.");
|
|
83
|
+
}
|
|
84
|
+
if (typeof profile.coefficients !== "object" || profile.coefficients === null) {
|
|
85
|
+
throw new InvalidConfigurationError("profile.coefficients must be an object.");
|
|
86
|
+
}
|
|
87
|
+
const coefficients = {
|
|
88
|
+
k1: requireFinite("profile.coefficients.k1", profile.coefficients.k1),
|
|
89
|
+
k2: requireFinite("profile.coefficients.k2", profile.coefficients.k2),
|
|
90
|
+
k3: requireFinite("profile.coefficients.k3", profile.coefficients.k3),
|
|
91
|
+
p1: requireFinite("profile.coefficients.p1", profile.coefficients.p1),
|
|
92
|
+
p2: requireFinite("profile.coefficients.p2", profile.coefficients.p2)
|
|
93
|
+
};
|
|
94
|
+
const radial = validateRadialDistortionProfile({
|
|
95
|
+
normalizationRadiusMm: profile.normalizationRadiusMm,
|
|
96
|
+
maximumNormalizedRadius: profile.maximumNormalizedRadius,
|
|
97
|
+
coefficients: {
|
|
98
|
+
k1: coefficients.k1,
|
|
99
|
+
k2: coefficients.k2,
|
|
100
|
+
k3: coefficients.k3
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
const maximum = radial.maximumNormalizedRadius;
|
|
104
|
+
let minimumJacobianDeterminant = Number.POSITIVE_INFINITY;
|
|
105
|
+
for (let ring = 0; ring <= VALIDATION_RINGS; ring += 1) {
|
|
106
|
+
const rho = (maximum * ring) / VALIDATION_RINGS;
|
|
107
|
+
const azimuths = ring === 0 ? 1 : VALIDATION_AZIMUTHS;
|
|
108
|
+
for (let index = 0; index < azimuths; index += 1) {
|
|
109
|
+
const phi = (2 * Math.PI * index) / VALIDATION_AZIMUTHS;
|
|
110
|
+
const det = determinant(jacobianNormalized(rho * Math.cos(phi), rho * Math.sin(phi), coefficients));
|
|
111
|
+
minimumJacobianDeterminant = Math.min(minimumJacobianDeterminant, det);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (!Number.isFinite(minimumJacobianDeterminant) || minimumJacobianDeterminant <= 0) {
|
|
115
|
+
throw new InvalidScientificInputError("Brown-Conrady profile must keep a positive Jacobian determinant over maximumNormalizedRadius so the mapping stays locally invertible.");
|
|
116
|
+
}
|
|
117
|
+
// The mapped boundary must be star-shaped about the mapped centre (the origin): its polar angle
|
|
118
|
+
// must increase strictly around the circle, so the boundary curve is simple.
|
|
119
|
+
let previous;
|
|
120
|
+
let accumulated = 0;
|
|
121
|
+
for (let index = 0; index <= VALIDATION_AZIMUTHS; index += 1) {
|
|
122
|
+
const phi = (2 * Math.PI * index) / VALIDATION_AZIMUTHS;
|
|
123
|
+
const mapped = forwardNormalized(maximum * Math.cos(phi), maximum * Math.sin(phi), coefficients);
|
|
124
|
+
const angle = Math.atan2(mapped.y, mapped.x);
|
|
125
|
+
if (previous !== undefined) {
|
|
126
|
+
let step = angle - previous;
|
|
127
|
+
if (step <= -Math.PI)
|
|
128
|
+
step += 2 * Math.PI;
|
|
129
|
+
if (step > Math.PI)
|
|
130
|
+
step -= 2 * Math.PI;
|
|
131
|
+
if (!(step > 0)) {
|
|
132
|
+
throw new InvalidScientificInputError("Brown-Conrady profile maps the envelope boundary to a curve that is not star-shaped about the optical axis; the inverse would not be single-valued.");
|
|
133
|
+
}
|
|
134
|
+
accumulated += step;
|
|
135
|
+
}
|
|
136
|
+
previous = angle;
|
|
137
|
+
}
|
|
138
|
+
if (Math.abs(accumulated - 2 * Math.PI) > 1e-9) {
|
|
139
|
+
throw new InvalidScientificInputError("Brown-Conrady profile boundary must wind exactly once around the optical axis.");
|
|
140
|
+
}
|
|
141
|
+
return { radial, coefficients, minimumJacobianDeterminant };
|
|
142
|
+
}
|
|
143
|
+
function assumptions() {
|
|
144
|
+
return [
|
|
145
|
+
"Generic Brown-Conrady radial (k1, k2, k3) plus tangential/decentering (p1, p2) polynomial field mapping",
|
|
146
|
+
"Coordinates are normalized by the caller-declared normalizationRadiusMm; the optical axis maps to itself",
|
|
147
|
+
"Validity: monotonic radial part, positive Jacobian at a 64-ring x 256-azimuth polar sample and a strictly star-shaped mapped boundary; checked at samples, not proven between them",
|
|
148
|
+
"Coefficients are generic caller inputs and do not represent a named lens unless separately calibrated with defensible provenance",
|
|
149
|
+
"Thin-prism, anamorphic and higher-order decentering terms are not modeled"
|
|
150
|
+
];
|
|
151
|
+
}
|
|
152
|
+
/** @internal Validates one profile for repeated evaluation (geometric mapping, ray queries). */
|
|
153
|
+
export function validateBrownConradyDistortionProfile(profile) {
|
|
154
|
+
return validateProfile(profile);
|
|
155
|
+
}
|
|
156
|
+
/** @internal Forward map in mm with its Jacobian d(distorted)/d(ideal), row-major. */
|
|
157
|
+
export function brownConradyForwardValue(profile, point) {
|
|
158
|
+
const scale = profile.radial.normalizationRadiusMm;
|
|
159
|
+
const x = point.x / scale;
|
|
160
|
+
const y = point.y / scale;
|
|
161
|
+
if (Math.hypot(x, y) > profile.radial.maximumNormalizedRadius) {
|
|
162
|
+
throw new InvalidScientificInputError("Point lies outside the Brown-Conrady profile maximumNormalizedRadius.");
|
|
163
|
+
}
|
|
164
|
+
const mapped = forwardNormalized(x, y, profile.coefficients);
|
|
165
|
+
const j = jacobianNormalized(x, y, profile.coefficients);
|
|
166
|
+
return {
|
|
167
|
+
mappedImagePointMm: { x: mapped.x * scale, y: mapped.y * scale },
|
|
168
|
+
jacobian: [j.a, j.b, j.c, j.d]
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/** @internal Inverse map in mm (distorted to ideal). */
|
|
172
|
+
export function brownConradyInverseValue(profile, point) {
|
|
173
|
+
const solved = solveInverseBrownConrady(profile, point);
|
|
174
|
+
const scale = profile.radial.normalizationRadiusMm;
|
|
175
|
+
return { x: solved.x * scale, y: solved.y * scale };
|
|
176
|
+
}
|
|
177
|
+
function solveInverseBrownConrady(profile, point) {
|
|
178
|
+
const scale = profile.radial.normalizationRadiusMm;
|
|
179
|
+
const maximum = profile.radial.maximumNormalizedRadius;
|
|
180
|
+
const tx = point.x / scale;
|
|
181
|
+
const ty = point.y / scale;
|
|
182
|
+
const tolerance = 1e-12 * Math.max(1, Math.hypot(tx, ty));
|
|
183
|
+
// Starting point: the radial-only inverse if inside its mapped envelope, otherwise the target itself.
|
|
184
|
+
let x = tx;
|
|
185
|
+
let y = ty;
|
|
186
|
+
if (Math.hypot(tx, ty) <= profile.radial.maximumMappedNormalizedRadius) {
|
|
187
|
+
const seed = calculateInverseRadialSourcePointValue(point, profile.radial, "distortedImagePointMm").sourceImagePointMm;
|
|
188
|
+
x = seed.x / scale;
|
|
189
|
+
y = seed.y / scale;
|
|
190
|
+
}
|
|
191
|
+
let iterations = 0;
|
|
192
|
+
let residual = Number.POSITIVE_INFINITY;
|
|
193
|
+
for (; iterations < MAXIMUM_NEWTON_ITERATIONS; iterations += 1) {
|
|
194
|
+
const f = forwardNormalized(x, y, profile.coefficients);
|
|
195
|
+
const rx = f.x - tx;
|
|
196
|
+
const ry = f.y - ty;
|
|
197
|
+
residual = Math.hypot(rx, ry);
|
|
198
|
+
if (residual <= tolerance) {
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
const j = jacobianNormalized(x, y, profile.coefficients);
|
|
202
|
+
const det = determinant(j);
|
|
203
|
+
if (!(Math.abs(det) > 0) || !Number.isFinite(det)) {
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
const stepX = (j.d * rx - j.b * ry) / det;
|
|
207
|
+
const stepY = (-j.c * rx + j.a * ry) / det;
|
|
208
|
+
// Damping: halve the step until the residual decreases (at most 30 halvings).
|
|
209
|
+
let lambda = 1;
|
|
210
|
+
let accepted = false;
|
|
211
|
+
for (let halving = 0; halving < 30; halving += 1) {
|
|
212
|
+
const nx = x - lambda * stepX;
|
|
213
|
+
const ny = y - lambda * stepY;
|
|
214
|
+
const g = forwardNormalized(nx, ny, profile.coefficients);
|
|
215
|
+
if (Math.hypot(g.x - tx, g.y - ty) < residual) {
|
|
216
|
+
x = nx;
|
|
217
|
+
y = ny;
|
|
218
|
+
accepted = true;
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
lambda /= 2;
|
|
222
|
+
}
|
|
223
|
+
if (!accepted) {
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
const sourceNormalizedRadius = Math.hypot(x, y);
|
|
228
|
+
if (!(residual <= tolerance) ||
|
|
229
|
+
sourceNormalizedRadius > maximum * (1 + 1e-12)) {
|
|
230
|
+
throw new InvalidScientificInputError("distortedImagePointMm lies outside the mapped Brown-Conrady profile operating envelope.");
|
|
231
|
+
}
|
|
232
|
+
return { x, y, iterations, residual, sourceNormalizedRadius };
|
|
233
|
+
}
|
|
234
|
+
/** Applies the Brown-Conrady forward mapping to one ideal image-plane point. */
|
|
235
|
+
export function calculateBrownConradyDistortionMapping(input) {
|
|
236
|
+
requireInputKeys(input, "calculateBrownConradyDistortionMapping", ["imagePointMm", "profile"]);
|
|
237
|
+
const point = requirePoint("imagePointMm", input.imagePointMm);
|
|
238
|
+
const profile = validateProfile(input.profile);
|
|
239
|
+
const scale = profile.radial.normalizationRadiusMm;
|
|
240
|
+
const x = point.x / scale;
|
|
241
|
+
const y = point.y / scale;
|
|
242
|
+
const sourceNormalizedRadius = Math.hypot(x, y);
|
|
243
|
+
if (sourceNormalizedRadius > profile.radial.maximumNormalizedRadius) {
|
|
244
|
+
throw new InvalidScientificInputError("imagePointMm lies outside the Brown-Conrady profile maximumNormalizedRadius.");
|
|
245
|
+
}
|
|
246
|
+
const mapped = forwardNormalized(x, y, profile.coefficients);
|
|
247
|
+
const mappedImagePointMm = { x: mapped.x * scale, y: mapped.y * scale };
|
|
248
|
+
const dx = mappedImagePointMm.x - point.x;
|
|
249
|
+
const dy = mappedImagePointMm.y - point.y;
|
|
250
|
+
return approximationResult({
|
|
251
|
+
direction: "undistorted-to-distorted",
|
|
252
|
+
sourceImagePointMm: point,
|
|
253
|
+
mappedImagePointMm,
|
|
254
|
+
sourceNormalizedRadius,
|
|
255
|
+
jacobianDeterminant: determinant(jacobianNormalized(x, y, profile.coefficients)),
|
|
256
|
+
deltaMm: { x: dx, y: dy, distance: Math.hypot(dx, dy) },
|
|
257
|
+
profileMinimumJacobianDeterminant: profile.minimumJacobianDeterminant
|
|
258
|
+
}, "generic-brown-conrady-lens-distortion", "1.0.0", assumptions());
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Inverse-maps one distorted image-plane point to its ideal source point, for destination-to-source
|
|
262
|
+
* resampling. Damped Newton iteration starts from the radial-only inverse. The solution must lie
|
|
263
|
+
* inside the declared envelope and must reproduce the distorted point within a relative tolerance of
|
|
264
|
+
* 1e-12.
|
|
265
|
+
*/
|
|
266
|
+
export function calculateInverseBrownConradyDistortionMapping(input) {
|
|
267
|
+
requireInputKeys(input, "calculateInverseBrownConradyDistortionMapping", ["distortedImagePointMm", "profile"]);
|
|
268
|
+
const point = requirePoint("distortedImagePointMm", input.distortedImagePointMm);
|
|
269
|
+
const profile = validateProfile(input.profile);
|
|
270
|
+
const solved = solveInverseBrownConrady(profile, point);
|
|
271
|
+
const scale = profile.radial.normalizationRadiusMm;
|
|
272
|
+
const { x, y, iterations, residual, sourceNormalizedRadius } = solved;
|
|
273
|
+
const sourceImagePointMm = { x: x * scale, y: y * scale };
|
|
274
|
+
const dx = sourceImagePointMm.x - point.x;
|
|
275
|
+
const dy = sourceImagePointMm.y - point.y;
|
|
276
|
+
return approximationResult({
|
|
277
|
+
direction: "distorted-to-undistorted",
|
|
278
|
+
distortedImagePointMm: point,
|
|
279
|
+
sourceImagePointMm,
|
|
280
|
+
sourceNormalizedRadius,
|
|
281
|
+
jacobianDeterminantAtSource: determinant(jacobianNormalized(x, y, profile.coefficients)),
|
|
282
|
+
newtonIterations: iterations,
|
|
283
|
+
residualMm: residual * scale,
|
|
284
|
+
deltaMm: { x: dx, y: dy, distance: Math.hypot(dx, dy) },
|
|
285
|
+
profileMinimumJacobianDeterminant: profile.minimumJacobianDeterminant
|
|
286
|
+
}, "generic-inverse-brown-conrady-lens-distortion", "1.0.0", [
|
|
287
|
+
...assumptions(),
|
|
288
|
+
`Inverse uses damped Newton iteration (at most ${MAXIMUM_NEWTON_ITERATIONS} steps) seeded by the radial-only inverse, accepted at a normalized residual of 1e-12`
|
|
289
|
+
]);
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=brown-conrady-distortion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brown-conrady-distortion.js","sourceRoot":"","sources":["../../src/optics/brown-conrady-distortion.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Generic Brown-Conrady lens distortion: radial (k1, k2, k3) plus tangential/decentering (p1, p2)\n * terms on normalized image-plane coordinates (x, y) = point / normalizationRadiusMm, r^2 = x^2 + y^2:\n * x_d = x (1 + k1 r^2 + k2 r^4 + k3 r^6) + 2 p1 x y + p2 (r^2 + 2 x^2)\n * y_d = y (1 + k1 r^2 + k2 r^4 + k3 r^6) + p1 (r^2 + 2 y^2) + 2 p2 x y\n * In vector form the tangential term is r^2 P + 2 (P . u) u with P = (p2, p1), so (p1, p2) rotate as\n * a vector with the image.\n *\n * Sources: Conrady 1919 (MNRAS 79:384, decentred lens systems); Brown 1966\n * (Photogrammetric Engineering 32:444, \"Decentering distortion of lenses\"); Brown 1971 (Photogramm.\n * Eng. 37:855, close-range camera calibration). The coefficient layout follows the widely used\n * Brown-Conrady convention (for example Heikkila & Silven 1997, CVPR). The coefficient names match\n * that convention, but the values only mean something together with the declared normalization\n * radius.\n *\n * Validity checks (matching the radial-distortion validator):\n * - The radial part must be strictly monotonic over the envelope (the valid radius range).\n * - The Jacobian determinant must stay positive at a dense, fixed polar grid of samples over the\n * envelope disk.\n * - The mapped envelope boundary must have strictly increasing polar angle, so it is a simple\n * star-shaped curve.\n * A smooth, locally invertible map of a closed disk that is one-to-one on its boundary is one-to-one\n * everywhere. So these conditions make the inverse single-valued. Note that the Jacobian and boundary\n * conditions are checked at samples, not proven between them.\n *\n * The inverse uses damped Newton iteration, starting from the radial-only inverse.\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 calculateInverseRadialSourcePointValue,\n validateRadialDistortionProfile,\n type LensFieldPointMm,\n type ValidatedRadialProfile\n} from \"./radial-distortion.js\";\nimport { requireInputKeys } from \"../core/record-validation.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\n\nexport interface BrownConradyDistortionCoefficients {\n /** Radial r^2 coefficient. */\n k1: number;\n /** Radial r^4 coefficient. */\n k2: number;\n /** Radial r^6 coefficient. */\n k3: number;\n /** Tangential (decentering) coefficient p1 (couples to y; see module equation). */\n p1: number;\n /** Tangential (decentering) coefficient p2 (couples to x; see module equation). */\n p2: number;\n}\n\nexport interface BrownConradyDistortionProfile {\n /** Physical image-plane radius used to normalize field position, in mm. */\n normalizationRadiusMm: number;\n /** Maximum undistorted normalized radius of the operating envelope. */\n maximumNormalizedRadius: number;\n coefficients: BrownConradyDistortionCoefficients;\n}\n\nexport interface CalculateBrownConradyDistortionMappingInput {\n /** Ideal/undistorted image-plane point, in mm. */\n imagePointMm: LensFieldPointMm;\n profile: BrownConradyDistortionProfile;\n}\n\nexport interface CalculateInverseBrownConradyDistortionMappingInput {\n /** Distorted image-plane point to map back to ideal coordinates, in mm. */\n distortedImagePointMm: LensFieldPointMm;\n profile: BrownConradyDistortionProfile;\n}\n\nexport interface BrownConradyDistortionMapping {\n direction: \"undistorted-to-distorted\";\n sourceImagePointMm: LensFieldPointMm;\n mappedImagePointMm: LensFieldPointMm;\n sourceNormalizedRadius: number;\n /** Determinant of d(mapped)/d(source) at the source point (dimensionless area scale). */\n jacobianDeterminant: number;\n deltaMm: { x: number; y: number; distance: number };\n profileMinimumJacobianDeterminant: number;\n}\n\nexport interface InverseBrownConradyDistortionMapping {\n direction: \"distorted-to-undistorted\";\n distortedImagePointMm: LensFieldPointMm;\n sourceImagePointMm: LensFieldPointMm;\n sourceNormalizedRadius: number;\n jacobianDeterminantAtSource: number;\n newtonIterations: number;\n /** Forward-mapping residual of the solved source point, in mm. */\n residualMm: number;\n deltaMm: { x: number; y: number; distance: number };\n profileMinimumJacobianDeterminant: number;\n}\n\ninterface ValidatedBrownConradyProfile {\n radial: ValidatedRadialProfile;\n coefficients: BrownConradyDistortionCoefficients;\n minimumJacobianDeterminant: number;\n}\n\nconst VALIDATION_RINGS = 64;\nconst VALIDATION_AZIMUTHS = 256;\nconst MAXIMUM_NEWTON_ITERATIONS = 100;\n\nfunction requireFinite(name: string, value: unknown): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new InvalidScientificInputError(`${name} must be finite.`);\n }\n return value;\n}\n\nfunction requirePoint(name: string, point: unknown): LensFieldPointMm {\n if (typeof point !== \"object\" || point === null) {\n throw new InvalidConfigurationError(\n `${name} must be an object with finite numeric x and y coordinates.`\n );\n }\n const record = point as Record<string, unknown>;\n return {\n x: requireFinite(`${name}.x`, record.x),\n y: requireFinite(`${name}.y`, record.y)\n };\n}\n\n/** Forward map on normalized coordinates. */\nfunction forwardNormalized(\n x: number,\n y: number,\n c: BrownConradyDistortionCoefficients\n): { x: number; y: number } {\n const r2 = x * x + y * y;\n const radial = 1 + r2 * (c.k1 + r2 * (c.k2 + r2 * c.k3));\n return {\n x: x * radial + 2 * c.p1 * x * y + c.p2 * (r2 + 2 * x * x),\n y: y * radial + c.p1 * (r2 + 2 * y * y) + 2 * c.p2 * x * y\n };\n}\n\n/** Jacobian [[a, b], [c, d]] of the normalized forward map. */\nfunction jacobianNormalized(\n x: number,\n y: number,\n c: BrownConradyDistortionCoefficients\n): { a: number; b: number; c: number; d: number } {\n const r2 = x * x + y * y;\n const s = 1 + r2 * (c.k1 + r2 * (c.k2 + r2 * c.k3));\n const ds = c.k1 + r2 * (2 * c.k2 + 3 * c.k3 * r2);\n const off = 2 * x * y * ds + 2 * c.p1 * x + 2 * c.p2 * y;\n return {\n a: s + 2 * x * x * ds + 2 * c.p1 * y + 6 * c.p2 * x,\n b: off,\n c: off,\n d: s + 2 * y * y * ds + 6 * c.p1 * y + 2 * c.p2 * x\n };\n}\n\nfunction determinant(j: { a: number; b: number; c: number; d: number }): number {\n return j.a * j.d - j.b * j.c;\n}\n\nfunction validateProfile(\n profile: BrownConradyDistortionProfile\n): ValidatedBrownConradyProfile {\n if (typeof profile !== \"object\" || profile === null) {\n throw new InvalidConfigurationError(\"profile must be an object.\");\n }\n if (typeof profile.coefficients !== \"object\" || profile.coefficients === null) {\n throw new InvalidConfigurationError(\"profile.coefficients must be an object.\");\n }\n const coefficients: BrownConradyDistortionCoefficients = {\n k1: requireFinite(\"profile.coefficients.k1\", profile.coefficients.k1),\n k2: requireFinite(\"profile.coefficients.k2\", profile.coefficients.k2),\n k3: requireFinite(\"profile.coefficients.k3\", profile.coefficients.k3),\n p1: requireFinite(\"profile.coefficients.p1\", profile.coefficients.p1),\n p2: requireFinite(\"profile.coefficients.p2\", profile.coefficients.p2)\n };\n const radial = validateRadialDistortionProfile({\n normalizationRadiusMm: profile.normalizationRadiusMm,\n maximumNormalizedRadius: profile.maximumNormalizedRadius,\n coefficients: {\n k1: coefficients.k1,\n k2: coefficients.k2,\n k3: coefficients.k3\n }\n });\n\n const maximum = radial.maximumNormalizedRadius;\n let minimumJacobianDeterminant = Number.POSITIVE_INFINITY;\n for (let ring = 0; ring <= VALIDATION_RINGS; ring += 1) {\n const rho = (maximum * ring) / VALIDATION_RINGS;\n const azimuths = ring === 0 ? 1 : VALIDATION_AZIMUTHS;\n for (let index = 0; index < azimuths; index += 1) {\n const phi = (2 * Math.PI * index) / VALIDATION_AZIMUTHS;\n const det = determinant(\n jacobianNormalized(rho * Math.cos(phi), rho * Math.sin(phi), coefficients)\n );\n minimumJacobianDeterminant = Math.min(minimumJacobianDeterminant, det);\n }\n }\n if (!Number.isFinite(minimumJacobianDeterminant) || minimumJacobianDeterminant <= 0) {\n throw new InvalidScientificInputError(\n \"Brown-Conrady profile must keep a positive Jacobian determinant over maximumNormalizedRadius so the mapping stays locally invertible.\"\n );\n }\n\n // The mapped boundary must be star-shaped about the mapped centre (the origin): its polar angle\n // must increase strictly around the circle, so the boundary curve is simple.\n let previous: number | undefined;\n let accumulated = 0;\n for (let index = 0; index <= VALIDATION_AZIMUTHS; index += 1) {\n const phi = (2 * Math.PI * index) / VALIDATION_AZIMUTHS;\n const mapped = forwardNormalized(\n maximum * Math.cos(phi),\n maximum * Math.sin(phi),\n coefficients\n );\n const angle = Math.atan2(mapped.y, mapped.x);\n if (previous !== undefined) {\n let step = angle - previous;\n if (step <= -Math.PI) step += 2 * Math.PI;\n if (step > Math.PI) step -= 2 * Math.PI;\n if (!(step > 0)) {\n throw new InvalidScientificInputError(\n \"Brown-Conrady profile maps the envelope boundary to a curve that is not star-shaped about the optical axis; the inverse would not be single-valued.\"\n );\n }\n accumulated += step;\n }\n previous = angle;\n }\n if (Math.abs(accumulated - 2 * Math.PI) > 1e-9) {\n throw new InvalidScientificInputError(\n \"Brown-Conrady profile boundary must wind exactly once around the optical axis.\"\n );\n }\n\n return { radial, coefficients, minimumJacobianDeterminant };\n}\n\nfunction assumptions(): readonly string[] {\n return [\n \"Generic Brown-Conrady radial (k1, k2, k3) plus tangential/decentering (p1, p2) polynomial field mapping\",\n \"Coordinates are normalized by the caller-declared normalizationRadiusMm; the optical axis maps to itself\",\n \"Validity: monotonic radial part, positive Jacobian at a 64-ring x 256-azimuth polar sample and a strictly star-shaped mapped boundary; checked at samples, not proven between them\",\n \"Coefficients are generic caller inputs and do not represent a named lens unless separately calibrated with defensible provenance\",\n \"Thin-prism, anamorphic and higher-order decentering terms are not modeled\"\n ];\n}\n\n/** @internal Opaque validated profile for repeated in-package evaluation. */\nexport type ValidatedBrownConradyDistortionProfile = ValidatedBrownConradyProfile;\n\n/** @internal Validates one profile for repeated evaluation (geometric mapping, ray queries). */\nexport function validateBrownConradyDistortionProfile(\n profile: BrownConradyDistortionProfile\n): ValidatedBrownConradyDistortionProfile {\n return validateProfile(profile);\n}\n\n/** @internal Forward map in mm with its Jacobian d(distorted)/d(ideal), row-major. */\nexport function brownConradyForwardValue(\n profile: ValidatedBrownConradyDistortionProfile,\n point: LensFieldPointMm\n): { mappedImagePointMm: LensFieldPointMm; jacobian: readonly [number, number, number, number] } {\n const scale = profile.radial.normalizationRadiusMm;\n const x = point.x / scale;\n const y = point.y / scale;\n if (Math.hypot(x, y) > profile.radial.maximumNormalizedRadius) {\n throw new InvalidScientificInputError(\n \"Point lies outside the Brown-Conrady profile maximumNormalizedRadius.\"\n );\n }\n const mapped = forwardNormalized(x, y, profile.coefficients);\n const j = jacobianNormalized(x, y, profile.coefficients);\n return {\n mappedImagePointMm: { x: mapped.x * scale, y: mapped.y * scale },\n jacobian: [j.a, j.b, j.c, j.d]\n };\n}\n\n/** @internal Inverse map in mm (distorted to ideal). */\nexport function brownConradyInverseValue(\n profile: ValidatedBrownConradyDistortionProfile,\n point: LensFieldPointMm\n): LensFieldPointMm {\n const solved = solveInverseBrownConrady(profile, point);\n const scale = profile.radial.normalizationRadiusMm;\n return { x: solved.x * scale, y: solved.y * scale };\n}\n\nfunction solveInverseBrownConrady(\n profile: ValidatedBrownConradyProfile,\n point: LensFieldPointMm\n): { x: number; y: number; iterations: number; residual: number; sourceNormalizedRadius: number } {\n const scale = profile.radial.normalizationRadiusMm;\n const maximum = profile.radial.maximumNormalizedRadius;\n const tx = point.x / scale;\n const ty = point.y / scale;\n const tolerance = 1e-12 * Math.max(1, Math.hypot(tx, ty));\n\n // Starting point: the radial-only inverse if inside its mapped envelope, otherwise the target itself.\n let x = tx;\n let y = ty;\n if (Math.hypot(tx, ty) <= profile.radial.maximumMappedNormalizedRadius) {\n const seed = calculateInverseRadialSourcePointValue(\n point,\n profile.radial,\n \"distortedImagePointMm\"\n ).sourceImagePointMm;\n x = seed.x / scale;\n y = seed.y / scale;\n }\n\n let iterations = 0;\n let residual = Number.POSITIVE_INFINITY;\n for (; iterations < MAXIMUM_NEWTON_ITERATIONS; iterations += 1) {\n const f = forwardNormalized(x, y, profile.coefficients);\n const rx = f.x - tx;\n const ry = f.y - ty;\n residual = Math.hypot(rx, ry);\n if (residual <= tolerance) {\n break;\n }\n const j = jacobianNormalized(x, y, profile.coefficients);\n const det = determinant(j);\n if (!(Math.abs(det) > 0) || !Number.isFinite(det)) {\n break;\n }\n const stepX = (j.d * rx - j.b * ry) / det;\n const stepY = (-j.c * rx + j.a * ry) / det;\n // Damping: halve the step until the residual decreases (at most 30 halvings).\n let lambda = 1;\n let accepted = false;\n for (let halving = 0; halving < 30; halving += 1) {\n const nx = x - lambda * stepX;\n const ny = y - lambda * stepY;\n const g = forwardNormalized(nx, ny, profile.coefficients);\n if (Math.hypot(g.x - tx, g.y - ty) < residual) {\n x = nx;\n y = ny;\n accepted = true;\n break;\n }\n lambda /= 2;\n }\n if (!accepted) {\n break;\n }\n }\n\n const sourceNormalizedRadius = Math.hypot(x, y);\n if (\n !(residual <= tolerance) ||\n sourceNormalizedRadius > maximum * (1 + 1e-12)\n ) {\n throw new InvalidScientificInputError(\n \"distortedImagePointMm lies outside the mapped Brown-Conrady profile operating envelope.\"\n );\n }\n\n return { x, y, iterations, residual, sourceNormalizedRadius };\n}\n\n/** Applies the Brown-Conrady forward mapping to one ideal image-plane point. */\nexport function calculateBrownConradyDistortionMapping(\n input: CalculateBrownConradyDistortionMappingInput\n): CalculationResult<BrownConradyDistortionMapping> {\n requireInputKeys(input, \"calculateBrownConradyDistortionMapping\", [\"imagePointMm\", \"profile\"]);\n const point = requirePoint(\"imagePointMm\", input.imagePointMm);\n const profile = validateProfile(input.profile);\n const scale = profile.radial.normalizationRadiusMm;\n const x = point.x / scale;\n const y = point.y / scale;\n const sourceNormalizedRadius = Math.hypot(x, y);\n if (sourceNormalizedRadius > profile.radial.maximumNormalizedRadius) {\n throw new InvalidScientificInputError(\n \"imagePointMm lies outside the Brown-Conrady profile maximumNormalizedRadius.\"\n );\n }\n const mapped = forwardNormalized(x, y, profile.coefficients);\n const mappedImagePointMm = { x: mapped.x * scale, y: mapped.y * scale };\n const dx = mappedImagePointMm.x - point.x;\n const dy = mappedImagePointMm.y - point.y;\n return approximationResult(\n {\n direction: \"undistorted-to-distorted\",\n sourceImagePointMm: point,\n mappedImagePointMm,\n sourceNormalizedRadius,\n jacobianDeterminant: determinant(jacobianNormalized(x, y, profile.coefficients)),\n deltaMm: { x: dx, y: dy, distance: Math.hypot(dx, dy) },\n profileMinimumJacobianDeterminant: profile.minimumJacobianDeterminant\n },\n \"generic-brown-conrady-lens-distortion\",\n \"1.0.0\",\n assumptions()\n );\n}\n\n/**\n * Inverse-maps one distorted image-plane point to its ideal source point, for destination-to-source\n * resampling. Damped Newton iteration starts from the radial-only inverse. The solution must lie\n * inside the declared envelope and must reproduce the distorted point within a relative tolerance of\n * 1e-12.\n */\nexport function calculateInverseBrownConradyDistortionMapping(\n input: CalculateInverseBrownConradyDistortionMappingInput\n): CalculationResult<InverseBrownConradyDistortionMapping> {\n requireInputKeys(input, \"calculateInverseBrownConradyDistortionMapping\", [\"distortedImagePointMm\", \"profile\"]);\n const point = requirePoint(\"distortedImagePointMm\", input.distortedImagePointMm);\n const profile = validateProfile(input.profile);\n const solved = solveInverseBrownConrady(profile, point);\n const scale = profile.radial.normalizationRadiusMm;\n const { x, y, iterations, residual, sourceNormalizedRadius } = solved;\n const sourceImagePointMm = { x: x * scale, y: y * scale };\n const dx = sourceImagePointMm.x - point.x;\n const dy = sourceImagePointMm.y - point.y;\n return approximationResult(\n {\n direction: \"distorted-to-undistorted\",\n distortedImagePointMm: point,\n sourceImagePointMm,\n sourceNormalizedRadius,\n jacobianDeterminantAtSource: determinant(\n jacobianNormalized(x, y, profile.coefficients)\n ),\n newtonIterations: iterations,\n residualMm: residual * scale,\n deltaMm: { x: dx, y: dy, distance: Math.hypot(dx, dy) },\n profileMinimumJacobianDeterminant: profile.minimumJacobianDeterminant\n },\n \"generic-inverse-brown-conrady-lens-distortion\",\n \"1.0.0\",\n [\n ...assumptions(),\n `Inverse uses damped Newton iteration (at most ${MAXIMUM_NEWTON_ITERATIONS} steps) seeded by the radial-only inverse, accepted at a normalized residual of 1e-12`\n ]\n );\n}\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* not a physical blur threshold.
|
|
6
|
-
* @see docs/PHYSICS_FOUNDATION.md for equations, coordinate
|
|
7
|
-
* limits.
|
|
2
|
+
* Estimates a circle-of-confusion (CoC) criterion for equivalent final viewing. It scales a
|
|
3
|
+
* caller-supplied reference criterion in proportion to the sensor diagonal.
|
|
4
|
+
*
|
|
5
|
+
* This is a viewing (acceptable-sharpness) convention, not a physical blur threshold.
|
|
6
|
+
* @see docs/PHYSICS_FOUNDATION.md for the equations, units, coordinate conventions, known blockers
|
|
7
|
+
* and support limits.
|
|
8
8
|
*/
|
|
9
9
|
import { type CalculationResult } from "../core/calculation-result.js";
|
|
10
10
|
export interface EstimateEquivalentViewingCircleOfConfusionInput {
|
|
@@ -21,11 +21,11 @@ export interface EquivalentViewingCircleOfConfusion {
|
|
|
21
21
|
scaleFactor: number;
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
-
* Estimates a circle-of-confusion criterion for equivalent final viewing
|
|
25
|
-
*
|
|
24
|
+
* Estimates a circle-of-confusion criterion for equivalent final viewing. It
|
|
25
|
+
* scales a caller-supplied reference criterion in proportion to the sensor
|
|
26
26
|
* diagonal.
|
|
27
27
|
*
|
|
28
|
-
* This is a viewing
|
|
28
|
+
* This is a viewing (acceptable-sharpness) convention, not a physical blur
|
|
29
|
+
* threshold.
|
|
29
30
|
*/
|
|
30
31
|
export declare function estimateEquivalentViewingCircleOfConfusion(input: EstimateEquivalentViewingCircleOfConfusionInput): CalculationResult<EquivalentViewingCircleOfConfusion>;
|
|
31
|
-
//# sourceMappingURL=circle-of-confusion.d.ts.map
|
|
@@ -1,29 +1,33 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* not a physical blur threshold.
|
|
7
|
-
* @see docs/PHYSICS_FOUNDATION.md for equations, coordinate
|
|
8
|
-
* limits.
|
|
3
|
+
* Estimates a circle-of-confusion (CoC) criterion for equivalent final viewing. It scales a
|
|
4
|
+
* caller-supplied reference criterion in proportion to the sensor diagonal.
|
|
5
|
+
*
|
|
6
|
+
* This is a viewing (acceptable-sharpness) convention, not a physical blur threshold.
|
|
7
|
+
* @see docs/PHYSICS_FOUNDATION.md for the equations, units, coordinate conventions, known blockers
|
|
8
|
+
* and support limits.
|
|
9
9
|
*/
|
|
10
10
|
import { approximationResult } from "../core/calculation-result.js";
|
|
11
11
|
import { requirePositiveFinite } from "../core/validation.js";
|
|
12
|
+
import { portableHypot } from "../core/portable-math.js";
|
|
13
|
+
import { requireInputKeys } from "../core/record-validation.js";
|
|
12
14
|
/**
|
|
13
|
-
* Estimates a circle-of-confusion criterion for equivalent final viewing
|
|
14
|
-
*
|
|
15
|
+
* Estimates a circle-of-confusion criterion for equivalent final viewing. It
|
|
16
|
+
* scales a caller-supplied reference criterion in proportion to the sensor
|
|
15
17
|
* diagonal.
|
|
16
18
|
*
|
|
17
|
-
* This is a viewing
|
|
19
|
+
* This is a viewing (acceptable-sharpness) convention, not a physical blur
|
|
20
|
+
* threshold.
|
|
18
21
|
*/
|
|
19
22
|
export function estimateEquivalentViewingCircleOfConfusion(input) {
|
|
23
|
+
requireInputKeys(input, "estimateEquivalentViewingCircleOfConfusion", ["sensorWidthMm", "sensorHeightMm", "referenceSensorWidthMm", "referenceSensorHeightMm", "referenceCircleOfConfusionMm"]);
|
|
20
24
|
requirePositiveFinite("sensorWidthMm", input.sensorWidthMm);
|
|
21
25
|
requirePositiveFinite("sensorHeightMm", input.sensorHeightMm);
|
|
22
26
|
requirePositiveFinite("referenceSensorWidthMm", input.referenceSensorWidthMm);
|
|
23
27
|
requirePositiveFinite("referenceSensorHeightMm", input.referenceSensorHeightMm);
|
|
24
28
|
requirePositiveFinite("referenceCircleOfConfusionMm", input.referenceCircleOfConfusionMm);
|
|
25
|
-
const sensorDiagonalMm =
|
|
26
|
-
const referenceSensorDiagonalMm =
|
|
29
|
+
const sensorDiagonalMm = portableHypot(input.sensorWidthMm, input.sensorHeightMm);
|
|
30
|
+
const referenceSensorDiagonalMm = portableHypot(input.referenceSensorWidthMm, input.referenceSensorHeightMm);
|
|
27
31
|
const scaleFactor = sensorDiagonalMm / referenceSensorDiagonalMm;
|
|
28
32
|
return approximationResult({
|
|
29
33
|
circleOfConfusionMm: input.referenceCircleOfConfusionMm * scaleFactor,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"circle-of-confusion.js","sourceRoot":"","sources":["../../src/optics/circle-of-confusion.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;;GAOG;AAEH,OAAO,EACL,mBAAmB,EAEpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"circle-of-confusion.js","sourceRoot":"","sources":["../../src/optics/circle-of-confusion.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;;GAOG;AAEH,OAAO,EACL,mBAAmB,EAEpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAiBhE;;;;;;;GAOG;AACH,MAAM,UAAU,0CAA0C,CACxD,KAAsD;IAEtD,gBAAgB,CAAC,KAAK,EAAE,4CAA4C,EAAE,CAAC,eAAe,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,8BAA8B,CAAC,CAAC,CAAC;IAChM,qBAAqB,CAAC,eAAe,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IAC5D,qBAAqB,CAAC,gBAAgB,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IAC9D,qBAAqB,CACnB,wBAAwB,EACxB,KAAK,CAAC,sBAAsB,CAC7B,CAAC;IACF,qBAAqB,CACnB,yBAAyB,EACzB,KAAK,CAAC,uBAAuB,CAC9B,CAAC;IACF,qBAAqB,CACnB,8BAA8B,EAC9B,KAAK,CAAC,4BAA4B,CACnC,CAAC;IAEF,MAAM,gBAAgB,GAAG,aAAa,CACpC,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,CACrB,CAAC;IACF,MAAM,yBAAyB,GAAG,aAAa,CAC7C,KAAK,CAAC,sBAAsB,EAC5B,KAAK,CAAC,uBAAuB,CAC9B,CAAC;IACF,MAAM,WAAW,GAAG,gBAAgB,GAAG,yBAAyB,CAAC;IAEjE,OAAO,mBAAmB,CACxB;QACE,mBAAmB,EACjB,KAAK,CAAC,4BAA4B,GAAG,WAAW;QAClD,gBAAgB;QAChB,yBAAyB;QACzB,WAAW;KACZ,EACD,wCAAwC,EACxC,OAAO,EACP;QACE,iFAAiF;QACjF,wEAAwE;QACxE,qEAAqE;QACrE,yEAAyE;KAC1E,CACF,CAAC;AACJ,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Estimates a circle-of-confusion (CoC) criterion for equivalent final viewing. It scales a\n * caller-supplied reference criterion in proportion to the sensor diagonal.\n *\n * This is a viewing (acceptable-sharpness) convention, not a physical blur threshold.\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 { requirePositiveFinite } from \"../core/validation.js\";\nimport { portableHypot } from \"../core/portable-math.js\";\nimport { requireInputKeys } from \"../core/record-validation.js\";\n\nexport interface EstimateEquivalentViewingCircleOfConfusionInput {\n sensorWidthMm: number;\n sensorHeightMm: number;\n referenceSensorWidthMm: number;\n referenceSensorHeightMm: number;\n referenceCircleOfConfusionMm: number;\n}\n\nexport interface EquivalentViewingCircleOfConfusion {\n circleOfConfusionMm: number;\n sensorDiagonalMm: number;\n referenceSensorDiagonalMm: number;\n scaleFactor: number;\n}\n\n/**\n * Estimates a circle-of-confusion criterion for equivalent final viewing. It\n * scales a caller-supplied reference criterion in proportion to the sensor\n * diagonal.\n *\n * This is a viewing (acceptable-sharpness) convention, not a physical blur\n * threshold.\n */\nexport function estimateEquivalentViewingCircleOfConfusion(\n input: EstimateEquivalentViewingCircleOfConfusionInput\n): CalculationResult<EquivalentViewingCircleOfConfusion> {\n requireInputKeys(input, \"estimateEquivalentViewingCircleOfConfusion\", [\"sensorWidthMm\", \"sensorHeightMm\", \"referenceSensorWidthMm\", \"referenceSensorHeightMm\", \"referenceCircleOfConfusionMm\"]);\n requirePositiveFinite(\"sensorWidthMm\", input.sensorWidthMm);\n requirePositiveFinite(\"sensorHeightMm\", input.sensorHeightMm);\n requirePositiveFinite(\n \"referenceSensorWidthMm\",\n input.referenceSensorWidthMm\n );\n requirePositiveFinite(\n \"referenceSensorHeightMm\",\n input.referenceSensorHeightMm\n );\n requirePositiveFinite(\n \"referenceCircleOfConfusionMm\",\n input.referenceCircleOfConfusionMm\n );\n\n const sensorDiagonalMm = portableHypot(\n input.sensorWidthMm,\n input.sensorHeightMm\n );\n const referenceSensorDiagonalMm = portableHypot(\n input.referenceSensorWidthMm,\n input.referenceSensorHeightMm\n );\n const scaleFactor = sensorDiagonalMm / referenceSensorDiagonalMm;\n\n return approximationResult(\n {\n circleOfConfusionMm:\n input.referenceCircleOfConfusionMm * scaleFactor,\n sensorDiagonalMm,\n referenceSensorDiagonalMm,\n scaleFactor\n },\n \"equivalent-viewing-circle-of-confusion\",\n \"1.0.0\",\n [\n \"Reference and target images are compared at equivalent final display/print size\",\n \"Viewing distance and visual-acuity criterion are treated as equivalent\",\n \"Acceptable circle of confusion scales linearly with sensor diagonal\",\n \"This is a viewing convention, not a physical lens/sensor blur threshold\"\n ]\n );\n}\n"]}
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* scalar blur radius. Numeric profiles require owned or reusable-data provenance.
|
|
14
|
-
* @see docs/PSF_FOUNDATION.md for equations, coordinate/unit conventions, blockers and support limits.
|
|
2
|
+
* PSF (point-spread function) from a declared complex pupil: amplitude and phase sampled on a grid.
|
|
3
|
+
*
|
|
4
|
+
* The profile parser validates untrusted input and returns the normalized typed contract. Unknown
|
|
5
|
+
* enum values, missing required fields and incompatible scientific data are rejected.
|
|
6
|
+
*
|
|
7
|
+
* The complex pupil is evaluated by summing the declared amplitude and phase over a bounded, regular
|
|
8
|
+
* pupil grid. The PSF shape is normalized separately from the pupil throughput. A single blur radius
|
|
9
|
+
* cannot stand in for coherent phase, pupil energy, or the wavelength and field range where the
|
|
10
|
+
* profile applies. Numeric profiles need provenance showing the data is owned or reusable.
|
|
11
|
+
* @see docs/PSF_FOUNDATION.md for the equations, units, coordinate conventions, known blockers and
|
|
12
|
+
* support limits.
|
|
15
13
|
*/
|
|
16
14
|
import { type CalculationResult } from "../core/calculation-result.js";
|
|
17
15
|
import { type EvidenceProvenance } from "../core/evidence-provenance.js";
|
|
@@ -71,9 +69,9 @@ export interface LensComplexPupilProfile {
|
|
|
71
69
|
}
|
|
72
70
|
export interface CalculateLensComplexPupilPsfInput {
|
|
73
71
|
profile: LensComplexPupilProfile;
|
|
74
|
-
/** Physical pupil
|
|
75
|
-
* nominal focal-plane reference.
|
|
76
|
-
* the supported principal-plane geometry; profile metadata does not
|
|
72
|
+
/** Physical propagation distance from pupil to image, in mm. If omitted, the
|
|
73
|
+
* nominal focal-plane reference is used. At finite focus the caller must
|
|
74
|
+
* resolve the supported principal-plane geometry; profile metadata does not. */
|
|
77
75
|
propagationDistanceMm?: number;
|
|
78
76
|
}
|
|
79
77
|
export interface LensComplexPupilPsf {
|
|
@@ -84,6 +82,8 @@ export interface LensComplexPupilPsf {
|
|
|
84
82
|
scientificStatus: LensPsfScientificStatus;
|
|
85
83
|
context: LensComplexPupilProfile["context"];
|
|
86
84
|
kernel: LensPsfKernel;
|
|
85
|
+
/** Nyquist sampling diagnostics and the applied zero padding. */
|
|
86
|
+
sampling: LensComplexPupilPsfSampling;
|
|
87
87
|
relativePupilThroughputFactor: number;
|
|
88
88
|
throughputOwnership: "separate-relative-pupil-throughput-factor";
|
|
89
89
|
diffractionAndAberrationJointlyEvaluated: true;
|
|
@@ -104,31 +104,62 @@ export interface LensComplexPupilPsf {
|
|
|
104
104
|
uncertainty: LensPsfUncertainty;
|
|
105
105
|
}
|
|
106
106
|
/**
|
|
107
|
-
*
|
|
108
|
-
* missing required fields and incompatible scientific data
|
|
107
|
+
* Validates an untrusted declaration and returns the normalized typed contract. Unknown enum values,
|
|
108
|
+
* missing required fields and incompatible scientific data are rejected here.
|
|
109
109
|
*
|
|
110
|
-
*
|
|
111
|
-
* shape is normalized separately from pupil throughput
|
|
112
|
-
*
|
|
113
|
-
* owned or reusable
|
|
114
|
-
* @param value - unknown.
|
|
115
|
-
* @returns LensComplexPupilProfile.
|
|
110
|
+
* The complex pupil is evaluated by summing the declared amplitude and phase over a bounded, regular
|
|
111
|
+
* pupil grid. The PSF shape is normalized separately from the pupil throughput. A single blur radius
|
|
112
|
+
* cannot stand in for coherent phase, pupil energy, or the wavelength and field range where the
|
|
113
|
+
* profile applies. Numeric profiles need provenance showing the data is owned or reusable.
|
|
114
|
+
* @param value - unknown. Untrusted input; TypeScript types alone are not validation.
|
|
115
|
+
* @returns LensComplexPupilProfile. The result states its shape and scientific status; a successful call does not imply calibration.
|
|
116
116
|
*
|
|
117
117
|
* @see docs/API_REFERENCE.md for the root export and exact type graph.
|
|
118
118
|
*/
|
|
119
119
|
export declare function parseLensComplexPupilProfile(value: unknown): LensComplexPupilProfile;
|
|
120
|
+
export interface LensComplexPupilPsfSampling {
|
|
121
|
+
criterion: "discrete-intensity-alias-free-goodman-q-above-2";
|
|
122
|
+
/** Number of pupil samples spanned by non-zero amplitude, per axis. */
|
|
123
|
+
pupilSupportSamplesX: number;
|
|
124
|
+
pupilSupportSamplesY: number;
|
|
125
|
+
/**
|
|
126
|
+
* Sampled pupil diameter D = (support samples - 1) x pupil pitch: the
|
|
127
|
+
* centre-to-centre span of the outermost non-zero samples, in millimetres.
|
|
128
|
+
*/
|
|
129
|
+
pupilSupportDiameterMmX: number;
|
|
130
|
+
pupilSupportDiameterMmY: number;
|
|
131
|
+
/**
|
|
132
|
+
* Widest support allowed by the declared f-number at the resolved propagation distance:
|
|
133
|
+
* propagationDistanceMm / apertureFNumber, in millimetres. For the nominal focal-plane reference
|
|
134
|
+
* this is focalLengthMm / apertureFNumber.
|
|
135
|
+
*/
|
|
136
|
+
declaredPupilDiameterMm: number;
|
|
137
|
+
/** Declared pupil grid size before zero padding. */
|
|
138
|
+
pupilGridWidthSamples: number;
|
|
139
|
+
pupilGridHeightSamples: number;
|
|
140
|
+
/** DFT size after zero padding; equals the output kernel size. */
|
|
141
|
+
transformWidthSamples: number;
|
|
142
|
+
transformHeightSamples: number;
|
|
143
|
+
zeroPaddingApplied: boolean;
|
|
144
|
+
/**
|
|
145
|
+
* Achieved Goodman sampling factor Q = lambda*(z/D)/imagePitch =
|
|
146
|
+
* transform samples / (support samples - 1). Always greater than 2. Null
|
|
147
|
+
* when the support is a single sample on that axis (no finite diameter).
|
|
148
|
+
*/
|
|
149
|
+
samplingFactorQX: number | null;
|
|
150
|
+
samplingFactorQY: number | null;
|
|
151
|
+
}
|
|
120
152
|
/**
|
|
121
|
-
*
|
|
122
|
-
* shape and
|
|
153
|
+
* Evaluates a declared complex pupil with explicit amplitude, phase and sampling support. Returns the
|
|
154
|
+
* normalized PSF shape, and the pupil throughput as a separate quantity.
|
|
123
155
|
*
|
|
124
|
-
*
|
|
125
|
-
* shape is normalized separately from pupil throughput
|
|
126
|
-
*
|
|
127
|
-
* owned or reusable
|
|
128
|
-
* @param input - CalculateLensComplexPupilPsfInput. See
|
|
129
|
-
* @returns CalculationResult<LensComplexPupilPsf>.
|
|
156
|
+
* The complex pupil is evaluated by summing the declared amplitude and phase over a bounded, regular
|
|
157
|
+
* pupil grid. The PSF shape is normalized separately from the pupil throughput. A single blur radius
|
|
158
|
+
* cannot stand in for coherent phase, pupil energy, or the wavelength and field range where the
|
|
159
|
+
* profile applies. Numeric profiles need provenance showing the data is owned or reusable.
|
|
160
|
+
* @param input - CalculateLensComplexPupilPsfInput. See that type for coordinates, units and profile binding.
|
|
161
|
+
* @returns CalculationResult<LensComplexPupilPsf>. The result states its shape and scientific status; a successful call does not imply calibration.
|
|
130
162
|
*
|
|
131
163
|
* @see docs/API_REFERENCE.md for the root export and exact type graph.
|
|
132
164
|
*/
|
|
133
165
|
export declare function calculateLensComplexPupilPsf(input: CalculateLensComplexPupilPsfInput): CalculationResult<LensComplexPupilPsf>;
|
|
134
|
-
//# sourceMappingURL=complex-pupil-psf.d.ts.map
|