@photivra/engine 1.5.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 +393 -6
- package/CITATION.cff +1 -1
- package/NODE_SUPPORT.md +64 -12
- package/README.md +301 -182
- package/SECURITY.md +37 -28
- package/THIRD_PARTY.md +148 -4
- package/dist/camera/equivalent-focal-length.d.ts +13 -14
- package/dist/camera/equivalent-focal-length.js +15 -13
- package/dist/camera/equivalent-focal-length.js.map +1 -1
- package/dist/camera/field-of-view.d.ts +30 -19
- package/dist/camera/field-of-view.js +67 -18
- package/dist/camera/field-of-view.js.map +1 -1
- package/dist/camera/lens-projection.d.ts +170 -0
- package/dist/camera/lens-projection.js +444 -0
- package/dist/camera/lens-projection.js.map +1 -0
- package/dist/camera/projected-object-size.d.ts +10 -11
- package/dist/camera/projected-object-size.js +12 -10
- package/dist/camera/projected-object-size.js.map +1 -1
- package/dist/capture/capture-export-metadata.d.ts +9 -10
- package/dist/capture/capture-export-metadata.js +8 -5
- package/dist/capture/capture-export-metadata.js.map +1 -1
- package/dist/capture/dng-import.d.ts +91 -0
- package/dist/capture/dng-import.js +343 -0
- package/dist/capture/dng-import.js.map +1 -0
- package/dist/capture/environment-raw-producer.d.ts +37 -17
- package/dist/capture/environment-raw-producer.js +43 -19
- package/dist/capture/environment-raw-producer.js.map +1 -1
- package/dist/capture/export-jpeg.d.ts +35 -4
- package/dist/capture/export-jpeg.js +133 -47
- package/dist/capture/export-jpeg.js.map +1 -1
- package/dist/capture/export-tiff.d.ts +48 -24
- package/dist/capture/export-tiff.js +91 -31
- package/dist/capture/export-tiff.js.map +1 -1
- package/dist/capture/focus-control.d.ts +42 -65
- package/dist/capture/focus-control.js +56 -75
- package/dist/capture/focus-control.js.map +1 -1
- package/dist/capture/host-yield-cadence.d.ts +25 -0
- package/dist/capture/host-yield-cadence.js +25 -0
- package/dist/capture/host-yield-cadence.js.map +1 -0
- package/dist/capture/linear-encoding.d.ts +14 -12
- package/dist/capture/linear-encoding.js +14 -13
- package/dist/capture/linear-encoding.js.map +1 -1
- package/dist/capture/lossless-jpeg.d.ts +27 -0
- package/dist/capture/lossless-jpeg.js +237 -0
- package/dist/capture/lossless-jpeg.js.map +1 -0
- package/dist/capture/native-environment-lean.d.ts +227 -0
- package/dist/capture/native-environment-lean.js +974 -0
- package/dist/capture/native-environment-lean.js.map +1 -0
- package/dist/capture/native-environment-optical-stage.d.ts +97 -0
- package/dist/capture/native-environment-optical-stage.js +340 -0
- package/dist/capture/native-environment-optical-stage.js.map +1 -0
- package/dist/capture/native-environment-raw.d.ts +140 -6
- package/dist/capture/native-environment-raw.js +435 -34
- package/dist/capture/native-environment-raw.js.map +1 -1
- package/dist/capture/native-raw-development.d.ts +116 -9
- package/dist/capture/native-raw-development.js +221 -62
- package/dist/capture/native-raw-development.js.map +1 -1
- package/dist/capture/native-raw-dng.d.ts +60 -0
- package/dist/capture/native-raw-dng.js +167 -0
- package/dist/capture/native-raw-dng.js.map +1 -0
- package/dist/capture/native-raw.d.ts +65 -12
- package/dist/capture/native-raw.js +81 -19
- package/dist/capture/native-raw.js.map +1 -1
- package/dist/capture/packed-sensor-raw.d.ts +160 -0
- package/dist/capture/packed-sensor-raw.js +221 -0
- package/dist/capture/packed-sensor-raw.js.map +1 -0
- package/dist/capture/photographic-export.d.ts +58 -35
- package/dist/capture/photographic-export.js +177 -70
- package/dist/capture/photographic-export.js.map +1 -1
- package/dist/capture/raw-development-kernel.d.ts +52 -0
- package/dist/capture/raw-development-kernel.js +88 -0
- package/dist/capture/raw-development-kernel.js.map +1 -0
- package/dist/capture/raw-frame-limits.d.ts +7 -7
- package/dist/capture/raw-frame-limits.js +7 -6
- package/dist/capture/raw-frame-limits.js.map +1 -1
- package/dist/capture/raw-frame-reconstruction.d.ts +8 -9
- package/dist/capture/raw-frame-reconstruction.js +9 -8
- package/dist/capture/raw-frame-reconstruction.js.map +1 -1
- package/dist/capture/raw-white-level.d.ts +55 -0
- package/dist/capture/raw-white-level.js +165 -0
- package/dist/capture/raw-white-level.js.map +1 -0
- package/dist/capture/release-sequence.d.ts +5 -7
- package/dist/capture/release-sequence.js +15 -13
- package/dist/capture/release-sequence.js.map +1 -1
- package/dist/capture/sensor-raw-frame.d.ts +5 -6
- package/dist/capture/sensor-raw-frame.js +26 -9
- package/dist/capture/sensor-raw-frame.js.map +1 -1
- package/dist/capture/sensor-raw-producer.d.ts +21 -13
- package/dist/capture/sensor-raw-producer.js +86 -25
- package/dist/capture/sensor-raw-producer.js.map +1 -1
- package/dist/capture/simulated-capture.d.ts +15 -16
- package/dist/capture/simulated-capture.js +22 -12
- package/dist/capture/simulated-capture.js.map +1 -1
- package/dist/color/camera-color-matrix.d.ts +69 -0
- package/dist/color/camera-color-matrix.js +132 -0
- package/dist/color/camera-color-matrix.js.map +1 -0
- package/dist/color/capture-color.d.ts +17 -10
- package/dist/color/capture-color.js +50 -17
- package/dist/color/capture-color.js.map +1 -1
- package/dist/color/chromatic-adaptation.d.ts +63 -0
- package/dist/color/chromatic-adaptation.js +91 -0
- package/dist/color/chromatic-adaptation.js.map +1 -0
- package/dist/color/color-difference.d.ts +104 -0
- package/dist/color/color-difference.js +205 -0
- package/dist/color/color-difference.js.map +1 -0
- package/dist/color/color-matching-functions.d.ts +168 -0
- package/dist/color/color-matching-functions.js +309 -0
- package/dist/color/color-matching-functions.js.map +1 -0
- package/dist/color/colorimetry-math.d.ts +52 -0
- package/dist/color/colorimetry-math.js +144 -0
- package/dist/color/colorimetry-math.js.map +1 -0
- package/dist/color/gamut-mapping.d.ts +54 -0
- package/dist/color/gamut-mapping.js +107 -0
- package/dist/color/gamut-mapping.js.map +1 -0
- package/dist/color/illuminants.d.ts +182 -0
- package/dist/color/illuminants.js +434 -0
- package/dist/color/illuminants.js.map +1 -0
- package/dist/color/rgb-color-spaces.d.ts +79 -0
- package/dist/color/rgb-color-spaces.js +115 -0
- package/dist/color/rgb-color-spaces.js.map +1 -0
- package/dist/color/sensor-color-development.d.ts +33 -11
- package/dist/color/sensor-color-development.js +104 -30
- package/dist/color/sensor-color-development.js.map +1 -1
- package/dist/color/srgb-icc.d.ts +9 -2
- package/dist/color/srgb-icc.js +16 -5
- package/dist/color/srgb-icc.js.map +1 -1
- package/dist/color/srgb-transfer.d.ts +1 -2
- package/dist/color/srgb-transfer.js +1 -1
- package/dist/color/srgb-transfer.js.map +1 -1
- package/dist/color/white-balance.d.ts +68 -19
- package/dist/color/white-balance.js +168 -35
- package/dist/color/white-balance.js.map +1 -1
- package/dist/composition/image-formation-plan.d.ts +152 -128
- package/dist/composition/image-formation-plan.js +292 -138
- package/dist/composition/image-formation-plan.js.map +1 -1
- package/dist/composition/plan-consumer.d.ts +6 -7
- package/dist/composition/plan-consumer.js +14 -11
- package/dist/composition/plan-consumer.js.map +1 -1
- package/dist/core/calculation-result.d.ts +21 -14
- package/dist/core/calculation-result.js +209 -11
- package/dist/core/calculation-result.js.map +1 -1
- package/dist/core/canonical-json.d.ts +13 -8
- package/dist/core/canonical-json.js +34 -15
- package/dist/core/canonical-json.js.map +1 -1
- package/dist/core/configuration-error.d.ts +5 -4
- package/dist/core/configuration-error.js +5 -3
- package/dist/core/configuration-error.js.map +1 -1
- package/dist/core/evidence-provenance.d.ts +12 -12
- package/dist/core/evidence-provenance.js +10 -9
- package/dist/core/evidence-provenance.js.map +1 -1
- package/dist/core/image-formation.d.ts +11 -10
- package/dist/core/image-formation.js +11 -9
- package/dist/core/image-formation.js.map +1 -1
- package/dist/core/owned-data.d.ts +9 -17
- package/dist/core/owned-data.js +9 -16
- package/dist/core/owned-data.js.map +1 -1
- package/dist/core/portable-math.d.ts +15 -0
- package/dist/core/portable-math.js +56 -0
- package/dist/core/portable-math.js.map +1 -0
- package/dist/core/record-validation.d.ts +48 -9
- package/dist/core/record-validation.js +93 -19
- package/dist/core/record-validation.js.map +1 -1
- package/dist/core/scientific-assurance.d.ts +16 -14
- package/dist/core/scientific-assurance.js +22 -18
- package/dist/core/scientific-assurance.js.map +1 -1
- package/dist/core/spectral-composition.d.ts +13 -14
- package/dist/core/spectral-composition.js +30 -27
- package/dist/core/spectral-composition.js.map +1 -1
- package/dist/core/spectral.d.ts +5 -6
- package/dist/core/spectral.js +9 -7
- package/dist/core/spectral.js.map +1 -1
- package/dist/core/validation.d.ts +3 -6
- package/dist/core/validation.js +3 -5
- package/dist/core/validation.js.map +1 -1
- package/dist/core/version.d.ts +6 -6
- package/dist/core/version.js +6 -5
- package/dist/core/version.js.map +1 -1
- package/dist/equipment/exposure-capabilities.d.ts +10 -10
- package/dist/equipment/exposure-capabilities.js +40 -30
- package/dist/equipment/exposure-capabilities.js.map +1 -1
- package/dist/equipment/generic-tier-assets.d.ts +13 -6
- package/dist/equipment/generic-tier-assets.js +34 -15
- package/dist/equipment/generic-tier-assets.js.map +1 -1
- package/dist/equipment/generic-tier-presets.d.ts +5 -6
- package/dist/equipment/generic-tier-presets.js +15 -13
- package/dist/equipment/generic-tier-presets.js.map +1 -1
- package/dist/equipment/iso-capabilities.d.ts +21 -22
- package/dist/equipment/iso-capabilities.js +49 -44
- package/dist/equipment/iso-capabilities.js.map +1 -1
- package/dist/equipment/metering-capabilities.d.ts +5 -6
- package/dist/equipment/metering-capabilities.js +22 -19
- package/dist/equipment/metering-capabilities.js.map +1 -1
- package/dist/equipment/release-capabilities.d.ts +3 -4
- package/dist/equipment/release-capabilities.js +18 -14
- package/dist/equipment/release-capabilities.js.map +1 -1
- package/dist/exposure/exposure-duration-control.d.ts +19 -17
- package/dist/exposure/exposure-duration-control.js +27 -23
- package/dist/exposure/exposure-duration-control.js.map +1 -1
- package/dist/exposure/exposure-mode-resolver.d.ts +42 -39
- package/dist/exposure/exposure-mode-resolver.js +127 -82
- package/dist/exposure/exposure-mode-resolver.js.map +1 -1
- package/dist/exposure/exposure.d.ts +17 -16
- package/dist/exposure/exposure.js +22 -15
- package/dist/exposure/exposure.js.map +1 -1
- package/dist/exposure/flash-ttl.d.ts +135 -0
- package/dist/exposure/flash-ttl.js +193 -0
- package/dist/exposure/flash-ttl.js.map +1 -0
- package/dist/exposure/flash.d.ts +144 -36
- package/dist/exposure/flash.js +259 -59
- package/dist/exposure/flash.js.map +1 -1
- package/dist/exposure/metering-scene-radiance.d.ts +10 -10
- package/dist/exposure/metering-scene-radiance.js +42 -23
- package/dist/exposure/metering-scene-radiance.js.map +1 -1
- package/dist/exposure/metering-target.d.ts +8 -8
- package/dist/exposure/metering-target.js +30 -20
- package/dist/exposure/metering-target.js.map +1 -1
- package/dist/exposure/metering-temporal.d.ts +16 -15
- package/dist/exposure/metering-temporal.js +41 -19
- package/dist/exposure/metering-temporal.js.map +1 -1
- package/dist/exposure/metering.d.ts +64 -17
- package/dist/exposure/metering.js +159 -30
- package/dist/exposure/metering.js.map +1 -1
- package/dist/exposure/program-line.d.ts +5 -5
- package/dist/exposure/program-line.js +20 -13
- package/dist/exposure/program-line.js.map +1 -1
- package/dist/facade/camera-preset.d.ts +8 -0
- package/dist/facade/camera-preset.js +102 -0
- package/dist/facade/camera-preset.js.map +1 -0
- package/dist/facade/chart-radiance-batch.d.ts +57 -0
- package/dist/facade/chart-radiance-batch.js +121 -0
- package/dist/facade/chart-radiance-batch.js.map +1 -0
- package/dist/facade/chart-scenes.d.ts +177 -0
- package/dist/facade/chart-scenes.js +232 -0
- package/dist/facade/chart-scenes.js.map +1 -0
- package/dist/facade/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 -8
- package/docs/api/capture-native-raw-dng.md +84 -0
- package/docs/api/capture-native-raw.md +21 -10
- package/docs/api/capture-packed-sensor-raw.md +156 -0
- package/docs/api/capture-photographic-export.md +69 -31
- package/docs/api/capture-raw-frame-reconstruction.md +8 -8
- package/docs/api/capture-raw-white-level.md +37 -0
- package/docs/api/capture-release-sequence.md +6 -7
- package/docs/api/capture-sensor-raw-frame.md +6 -6
- package/docs/api/capture-sensor-raw-producer.md +17 -11
- package/docs/api/capture-simulated-capture.md +15 -15
- package/docs/api/color-camera-color-matrix.md +103 -0
- package/docs/api/color-capture-color.md +22 -11
- package/docs/api/color-chromatic-adaptation.md +82 -0
- package/docs/api/color-color-difference.md +134 -0
- package/docs/api/color-color-matching-functions.md +259 -0
- package/docs/api/color-colorimetry-math.md +54 -0
- package/docs/api/color-gamut-mapping.md +72 -0
- package/docs/api/color-illuminants.md +280 -0
- package/docs/api/color-rgb-color-spaces.md +151 -0
- package/docs/api/color-sensor-color-development.md +27 -0
- package/docs/api/color-srgb-icc.md +2 -4
- package/docs/api/color-white-balance.md +95 -19
- package/docs/api/composition-image-formation-plan.md +124 -95
- package/docs/api/composition-plan-consumer.md +7 -7
- package/docs/api/core-calculation-result.md +18 -14
- package/docs/api/core-configuration-error.md +1 -1
- package/docs/api/core-image-formation.md +7 -7
- package/docs/api/core-scientific-assurance.md +12 -10
- package/docs/api/core-spectral-composition.md +14 -14
- package/docs/api/core-spectral.md +6 -6
- package/docs/api/core-validation.md +3 -3
- package/docs/api/core-version.md +7 -6
- package/docs/api/equipment-exposure-capabilities.md +11 -10
- package/docs/api/equipment-generic-tier-assets.md +7 -2
- package/docs/api/equipment-generic-tier-presets.md +6 -6
- package/docs/api/equipment-iso-capabilities.md +18 -18
- package/docs/api/equipment-metering-capabilities.md +6 -6
- package/docs/api/equipment-release-capabilities.md +4 -4
- package/docs/api/exports.json +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/DENSE_PUPIL_QUALIFICATION.md +0 -121
- package/docs/DEVELOPERS.md +0 -68
- package/docs/DIGITAL_OPTICS_FOUNDATION.md +0 -69
- package/docs/ENVIRONMENT_RAW_CAPTURE.md +0 -208
- package/docs/EXPORT_ACCEPTANCE.md +0 -133
- package/docs/GENERIC_TIER_PRESETS.md +0 -269
- package/docs/GEOMETRIC_PREPARATION_REUSE.md +0 -141
- package/docs/IMAGE_FORMATION.md +0 -247
- package/docs/LINEAR_CAPTURE_ENCODING.md +0 -25
- package/docs/MOTION_AND_SIGNAL.md +0 -250
- package/docs/NATIVE_CAPTURE_SDR.md +0 -70
- package/docs/NATIVE_CAPTURE_SDR_REVIEW.md +0 -37
- package/docs/NATIVE_CAPTURE_SDR_VALIDATION.md +0 -34
- package/docs/NATIVE_RAW_AND_PRINT.md +0 -54
- package/docs/NUMERICAL_CORRECTNESS.md +0 -191
- package/docs/PERFORMANCE_BASELINE.md +0 -56
- package/docs/PHOTOGRAPHIC_EXPORT.md +0 -206
- package/docs/PHYSICS_FOUNDATION.md +0 -426
- package/docs/POC_API.md +0 -278
- package/docs/POC_PROJECTION_PLATFORM_REFERENCE.md +0 -12
- package/docs/POC_PROJECTION_REUSE.md +0 -124
- package/docs/PRINT_195_196_REVIEW.md +0 -93
- package/docs/PRINT_196_ENGINE_ACCEPTANCE.md +0 -45
- package/docs/PRINT_CONTRAST_REFERENCE.md +0 -43
- package/docs/PRINT_DETAIL_ASSESSMENT.md +0 -81
- package/docs/PRINT_DETAIL_JPEG_EVIDENCE.md +0 -36
- package/docs/PRINT_DETAIL_SDR_EVIDENCE.md +0 -29
- package/docs/PRINT_DETAIL_VALIDATION.md +0 -36
- package/docs/PRINT_PLANNING.md +0 -75
- package/docs/PRINT_REGION_STATISTICS.md +0 -38
- package/docs/PROCESSED_OUTPUT.md +0 -157
- package/docs/PRODUCTION_COMPOSITION.md +0 -373
- package/docs/PRODUCTION_ENVIRONMENT_CAPTURE.md +0 -131
- package/docs/PROVENANCE.md +0 -115
- package/docs/PSF_FOUNDATION.md +0 -165
- package/docs/RAW_FRAME_ENVELOPE.md +0 -56
- package/docs/RAW_FRAME_RECONSTRUCTION.md +0 -30
- package/docs/RELEASE_1_0.md +0 -66
- package/docs/RELEASE_1_0_1.md +0 -61
- package/docs/RELEASE_1_1_0.md +0 -25
- package/docs/RELEASE_1_2_0.md +0 -51
- package/docs/RELEASE_1_3_0.md +0 -15
- package/docs/RELEASE_1_4_0.md +0 -23
- package/docs/RELEASE_1_5_0.md +0 -105
- package/docs/RELEASE_AUDIT.md +0 -39
- package/docs/SCENE_RADIANCE_AND_ILLUMINATION.md +0 -298
- package/docs/SCENE_SENSOR_QUADRATURE.md +0 -98
- package/docs/SCENE_SENSOR_TEMPORAL_EXPOSURE.md +0 -86
- package/docs/SCIENTIFIC_ASSURANCE.md +0 -280
- package/docs/SCIENTIFIC_CONFORMANCE.md +0 -83
- package/docs/SDR_RENDERING.md +0 -33
- package/docs/SENSOR_APERTURE_RAYS.md +0 -23
- package/docs/SENSOR_ENVIRONMENT_QUERY.md +0 -86
- package/docs/SENSOR_EQE_LOCAL_EXPOSURE.md +0 -104
- package/docs/SENSOR_EQE_TEMPORAL_EXPOSURE.md +0 -74
- package/docs/SENSOR_PSF_QUADRATURE.md +0 -90
- package/docs/SENSOR_RAW_FRAME.md +0 -20
- package/docs/SENSOR_RAW_PRODUCER.md +0 -77
- package/docs/SEPARABLE_EMISSION_DRAFT.md +0 -103
- package/docs/SIGNAL_CONFORMANCE.md +0 -23
- package/docs/SIMULATED_CAPTURE.md +0 -65
- package/docs/STABILIZATION.md +0 -234
- package/docs/TEMPORAL_PHOTO_RAW.md +0 -83
- package/docs/TIER_ACCEPTANCE.md +0 -129
- package/docs/TIER_PRESET_ACCEPTANCE.md +0 -59
- package/docs/V1_COMPOSITION_MAP.md +0 -123
- package/docs/V1_HELPER_REUSE_REVIEW.md +0 -60
- package/docs/V1_PERFORMANCE_DISPOSITION.md +0 -88
- package/docs/benchmarks/2026-10-01-main-baseline.json +0 -694
- package/docs/benchmarks/2026-10-02-geometric-preparation-reuse.json +0 -2190
- package/docs/benchmarks/2026-10-02-poc-projection-reuse.json +0 -2423
- package/docs/benchmarks/2026-10-02-v1-environment-gc-profile.json +0 -210
- package/docs/benchmarks/2026-10-02-v1-environment-ordinary.json +0 -187
- package/docs/benchmarks/2026-10-02-v1-geometry-gc-profile.json +0 -756
- package/docs/benchmarks/2026-10-02-v1-geometry-ordinary-1.json +0 -711
- package/docs/benchmarks/2026-10-02-v1-geometry-ordinary-2.json +0 -711
- package/docs/benchmarks/2026-10-02-v1-poc-gc-profile.json +0 -885
- package/docs/benchmarks/2026-10-02-v1-poc-ordinary-1.json +0 -868
- package/docs/benchmarks/2026-10-02-v1-poc-ordinary-2.json +0 -868
- package/docs/licenses/castleCSF-MIT.txt +0 -21
- package/docs/validation/dense-pupil-2026-10-06/pilot.jsonl +0 -6
- package/docs/validation/documentation-fragments.json +0 -212
- package/docs/validation/native-capture-sdr-darwin-arm64-node26-review.jsonl +0 -4
- package/docs/validation/native-capture-sdr-darwin-arm64.jsonl +0 -3
- package/docs/validation/native-raw-print-2026-10-04/fractional-asymmetric-crop.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/gray-ramp.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/linear-area-checker.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/manifest.json +0 -218
- package/docs/validation/native-raw-print-2026-10-04/megapixel-native.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/native-color.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel-validation.json +0 -9
- package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json +0 -29
- package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.codes.u16le.gz +0 -0
- package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.rgb.gz +0 -0
- package/docs/validation/native-raw-print-2026-10-04/srgb.icc +0 -0
- package/docs/validation/native-raw-print-2026-10-04/validation.json +0 -41
- package/docs/validation/print-196-candidate-capabilities.json +0 -28
- package/docs/validation/print-196-candidate-evidence.json +0 -356
- package/docs/validation/print-196-engine-acceptance.json +0 -81
- package/docs/validation/print-detail-capabilities.json +0 -103
- package/docs/validation/print-detail-jpeg-evidence.json +0 -116
- package/docs/validation/print-detail-sdr-evidence.json +0 -81
- package/docs/validation/release-audit-inventory.json +0 -1306
- package/docs/validation/tier-acceptance-report-v1.json +0 -2538
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
3
|
+
* RAW readout: turns the expected charge in a sensor site into a RAW code, with shot noise, read
|
|
4
|
+
* noise and the ADC (analogue-to-digital converter).
|
|
5
|
+
*
|
|
6
|
+
* The steps, in order:
|
|
7
|
+
* 1. expected charge;
|
|
8
|
+
* 2. separately seeded random photo and dark draws (Poisson shot noise);
|
|
9
|
+
* 3. signed electronic read noise;
|
|
10
|
+
* 4. the upper pre-ADC clipping threshold;
|
|
11
|
+
* 5. the black pedestal (offset);
|
|
12
|
+
* 6. ADC quantization, rounding to nearest with ties up;
|
|
13
|
+
* 7. limits on the unsigned code.
|
|
14
|
+
*
|
|
15
|
+
* Values below black stay signed until the final code clamp. Physical storage saturation, pre-ADC
|
|
16
|
+
* clipping and digital clipping are reported separately. The ISO setting never invents a conversion
|
|
17
|
+
* regime; regimes are declared.
|
|
16
18
|
* @see docs/SENSOR_RAW_PRODUCER.md for equations, coordinate/unit conventions, blockers and support
|
|
17
19
|
* limits.
|
|
18
20
|
*/
|
|
@@ -20,14 +22,19 @@ import { approximationResult } from "../core/calculation-result.js";
|
|
|
20
22
|
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
21
23
|
import { parseEvidenceList } from "../core/evidence-provenance.js";
|
|
22
24
|
import { InvalidScientificInputError } from "../core/validation.js";
|
|
25
|
+
import { createDeterministicUniformStream, sampleDeterministicStandardNormal } from "./stochastic-seed.js";
|
|
26
|
+
import { requireInputKeys, rejectUnknownFields } from "../core/record-validation.js";
|
|
27
|
+
import { evaluateParsedFixedPatternSite, parseSensorFixedPatternNoiseProfile } from "./fixed-pattern-noise.js";
|
|
23
28
|
export const SENSOR_CHARGE_SAMPLING_PROFILE_SCHEMA_VERSION = "0.1.0";
|
|
24
29
|
export const SENSOR_READOUT_CONVERSION_PROFILE_SCHEMA_VERSION = "0.1.0";
|
|
25
|
-
function requireRecord(value, path) {
|
|
30
|
+
function requireRecord(value, path, allowedKeys) {
|
|
26
31
|
if (typeof value !== "object" ||
|
|
27
32
|
value === null ||
|
|
28
33
|
Array.isArray(value)) {
|
|
29
34
|
throw new InvalidConfigurationError(path + " must be an object.");
|
|
30
35
|
}
|
|
36
|
+
if (allowedKeys !== null)
|
|
37
|
+
rejectUnknownFields(value, allowedKeys, path);
|
|
31
38
|
return value;
|
|
32
39
|
}
|
|
33
40
|
function requireNonEmptyString(value, path) {
|
|
@@ -93,35 +100,31 @@ function parseLimitations(value, path) {
|
|
|
93
100
|
return parsed;
|
|
94
101
|
}
|
|
95
102
|
function parsePositiveFact(value, path) {
|
|
96
|
-
const record = requireRecord(value, path);
|
|
103
|
+
const record = requireRecord(value, path, ["value", "evidence"]);
|
|
97
104
|
return {
|
|
98
105
|
value: requirePositiveFinite(record.value, path + ".value"),
|
|
99
106
|
evidence: parseEvidenceList(record.evidence, path + ".evidence")
|
|
100
107
|
};
|
|
101
108
|
}
|
|
102
109
|
function parseNonNegativeFact(value, path) {
|
|
103
|
-
const record = requireRecord(value, path);
|
|
110
|
+
const record = requireRecord(value, path, ["value", "evidence"]);
|
|
104
111
|
return {
|
|
105
112
|
value: requireNonNegativeFinite(record.value, path + ".value"),
|
|
106
113
|
evidence: parseEvidenceList(record.evidence, path + ".evidence")
|
|
107
114
|
};
|
|
108
115
|
}
|
|
109
116
|
/**
|
|
110
|
-
*
|
|
111
|
-
* missing required fields and
|
|
117
|
+
* Validates untrusted input and returns it as a normalized, typed value. Unknown enum values,
|
|
118
|
+
* missing required fields and inconsistent scientific data are rejected.
|
|
112
119
|
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
* pre-ADC clipping and digital clipping have distinct diagnostics; ISO never invents a conversion
|
|
117
|
-
* regime.
|
|
118
|
-
* @param value - unknown. Treated as untrusted data; static typing alone is not validation.
|
|
119
|
-
* @returns SensorChargeSamplingProfile. Return shape and scientific status are explicit; no calibration is inferred from successful execution.
|
|
120
|
+
* The profile sets how expected charge is sampled into random photo and dark counts.
|
|
121
|
+
* @param value - Untrusted data. TypeScript types alone are not validation.
|
|
122
|
+
* @returns The result. Success does not imply calibration.
|
|
120
123
|
*
|
|
121
|
-
* @see docs/API_REFERENCE.md for the
|
|
124
|
+
* @see docs/API_REFERENCE.md for the package export and its full type definitions.
|
|
122
125
|
*/
|
|
123
126
|
export function parseSensorChargeSamplingProfile(value) {
|
|
124
|
-
const record = requireRecord(value, "sensorChargeSamplingProfile");
|
|
127
|
+
const record = requireRecord(value, "sensorChargeSamplingProfile", ["schemaVersion", "scientificStatus", "photoShotNoiseModel", "darkShotNoiseModel", "additionalComponentPolicies", "profileId", "completenessProfileId", "evidence", "limitations"]);
|
|
125
128
|
if (record.schemaVersion !==
|
|
126
129
|
SENSOR_CHARGE_SAMPLING_PROFILE_SCHEMA_VERSION) {
|
|
127
130
|
throw new InvalidConfigurationError('sensorChargeSamplingProfile.schemaVersion must be "' +
|
|
@@ -145,7 +148,7 @@ export function parseSensorChargeSamplingProfile(value) {
|
|
|
145
148
|
const path = "sensorChargeSamplingProfile.additionalComponentPolicies[" +
|
|
146
149
|
index +
|
|
147
150
|
"]";
|
|
148
|
-
const policy = requireRecord(entry, path);
|
|
151
|
+
const policy = requireRecord(entry, path, ["model", "componentId"]);
|
|
149
152
|
if (policy.model !==
|
|
150
153
|
"poisson" &&
|
|
151
154
|
policy.model !==
|
|
@@ -184,16 +187,85 @@ function parseStatus(value, path) {
|
|
|
184
187
|
return value;
|
|
185
188
|
}
|
|
186
189
|
function parseReadNoiseComponent(value, path) {
|
|
187
|
-
const record = requireRecord(value, path);
|
|
190
|
+
const record = requireRecord(value, path, ["componentId", "rmsElectrons", "evidence"]);
|
|
188
191
|
return {
|
|
189
192
|
componentId: requireNonEmptyString(record.componentId, path + ".componentId"),
|
|
190
193
|
rmsElectrons: parseNonNegativeFact(record.rmsElectrons, path + ".rmsElectrons"),
|
|
191
194
|
evidence: parseEvidenceList(record.evidence, path + ".evidence")
|
|
192
195
|
};
|
|
193
196
|
}
|
|
197
|
+
function parseIntegralNonLinearity(value, path, adcMaximumCode) {
|
|
198
|
+
const record = requireRecord(value, path, ["kind", "knots", "evidence"]);
|
|
199
|
+
if (record.kind !==
|
|
200
|
+
"piecewise-linear-code-offset") {
|
|
201
|
+
throw new InvalidConfigurationError(path +
|
|
202
|
+
'.kind must be "piecewise-linear-code-offset".');
|
|
203
|
+
}
|
|
204
|
+
if (!Array.isArray(record.knots) ||
|
|
205
|
+
record.knots.length < 2 ||
|
|
206
|
+
record.knots.length > 4096) {
|
|
207
|
+
throw new InvalidConfigurationError(path +
|
|
208
|
+
".knots must contain 2 through 4096 knots.");
|
|
209
|
+
}
|
|
210
|
+
const knots = record.knots.map((entry, index) => {
|
|
211
|
+
const knot = requireRecord(entry, path + ".knots[" + index + "]", ["code", "offsetCodes"]);
|
|
212
|
+
return {
|
|
213
|
+
code: requireFinite(knot.code, path + ".knots[" + index + "].code"),
|
|
214
|
+
offsetCodes: requireFinite(knot.offsetCodes, path + ".knots[" + index + "].offsetCodes")
|
|
215
|
+
};
|
|
216
|
+
});
|
|
217
|
+
if (knots[0].code !== 0 ||
|
|
218
|
+
knots[knots.length - 1].code !==
|
|
219
|
+
adcMaximumCode ||
|
|
220
|
+
knots.some((knot, index) => index > 0 &&
|
|
221
|
+
knot.code <=
|
|
222
|
+
knots[index - 1].code) ||
|
|
223
|
+
knots.some((knot) => Math.abs(knot.offsetCodes) >
|
|
224
|
+
adcMaximumCode)) {
|
|
225
|
+
throw new InvalidConfigurationError(path +
|
|
226
|
+
".knots must strictly increase from code 0 to the ADC maximum code with bounded offsets.");
|
|
227
|
+
}
|
|
228
|
+
return {
|
|
229
|
+
kind: "piecewise-linear-code-offset",
|
|
230
|
+
knots,
|
|
231
|
+
evidence: parseEvidenceList(record.evidence, path + ".evidence")
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
function parseExposureIndexGain(value, path, adcDigitalGain) {
|
|
235
|
+
const record = requireRecord(value, path, ["exposureIndex", "baseExposureIndex", "analogGain", "digitalGain", "conversionGainMode", "evidence"]);
|
|
236
|
+
const exposureIndex = requirePositiveFinite(record.exposureIndex, path + ".exposureIndex");
|
|
237
|
+
const baseExposureIndex = requirePositiveFinite(record.baseExposureIndex, path + ".baseExposureIndex");
|
|
238
|
+
const analogGain = requirePositiveFinite(record.analogGain, path + ".analogGain");
|
|
239
|
+
const digitalGain = requirePositiveFinite(record.digitalGain, path + ".digitalGain");
|
|
240
|
+
const mode = record.conversionGainMode;
|
|
241
|
+
if (mode !== "single-conversion-gain" &&
|
|
242
|
+
mode !== "low-conversion-gain" &&
|
|
243
|
+
mode !== "high-conversion-gain") {
|
|
244
|
+
throw new InvalidConfigurationError(path +
|
|
245
|
+
".conversionGainMode is invalid.");
|
|
246
|
+
}
|
|
247
|
+
const ratio = exposureIndex /
|
|
248
|
+
baseExposureIndex;
|
|
249
|
+
if (digitalGain !==
|
|
250
|
+
adcDigitalGain ||
|
|
251
|
+
Math.abs(analogGain * digitalGain -
|
|
252
|
+
ratio) >
|
|
253
|
+
1e-12 * ratio) {
|
|
254
|
+
throw new InvalidConfigurationError(path +
|
|
255
|
+
" must satisfy analogGain x digitalGain = exposureIndex / baseExposureIndex and digitalGain = adc.digitalGain.");
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
exposureIndex,
|
|
259
|
+
baseExposureIndex,
|
|
260
|
+
analogGain,
|
|
261
|
+
digitalGain,
|
|
262
|
+
conversionGainMode: mode,
|
|
263
|
+
evidence: parseEvidenceList(record.evidence, path + ".evidence")
|
|
264
|
+
};
|
|
265
|
+
}
|
|
194
266
|
function parseRegime(value, path) {
|
|
195
|
-
const record = requireRecord(value, path);
|
|
196
|
-
const adc = requireRecord(record.adc, path + ".adc");
|
|
267
|
+
const record = requireRecord(value, path, ["adc", "readNoiseComponents", "systemConversionGainElectronsPerCode", "exposureIndexGain", "regimeId", "scientificStatus", "preAdcSaturationElectronEquivalent", "evidence", "limitations"]);
|
|
268
|
+
const adc = requireRecord(record.adc, path + ".adc", ["bitDepth", "blackLevelCode", "digitalSaturationCode", "transfer", "digitalGain", "integralNonLinearity"]);
|
|
197
269
|
const bitDepth = requireSafeInteger(adc.bitDepth, path + ".adc.bitDepth");
|
|
198
270
|
if (bitDepth < 1 ||
|
|
199
271
|
bitDepth > 30) {
|
|
@@ -236,13 +308,29 @@ function parseRegime(value, path) {
|
|
|
236
308
|
throw new InvalidConfigurationError(path +
|
|
237
309
|
".readNoiseComponents must not contain duplicate componentId values.");
|
|
238
310
|
}
|
|
311
|
+
const digitalGain = adc.digitalGain === undefined
|
|
312
|
+
? undefined
|
|
313
|
+
: requireFinite(adc.digitalGain, path + ".adc.digitalGain");
|
|
314
|
+
if (digitalGain !== undefined &&
|
|
315
|
+
(digitalGain < 1 ||
|
|
316
|
+
digitalGain > 65536)) {
|
|
317
|
+
throw new InvalidConfigurationError(path +
|
|
318
|
+
".adc.digitalGain must be from 1 through 65536.");
|
|
319
|
+
}
|
|
320
|
+
const integralNonLinearity = adc.integralNonLinearity === undefined
|
|
321
|
+
? undefined
|
|
322
|
+
: parseIntegralNonLinearity(adc.integralNonLinearity, path + ".adc.integralNonLinearity", adcMaximumCode);
|
|
323
|
+
const systemConversionGainElectronsPerCode = parsePositiveFact(record
|
|
324
|
+
.systemConversionGainElectronsPerCode, path +
|
|
325
|
+
".systemConversionGainElectronsPerCode");
|
|
326
|
+
const exposureIndexGain = record.exposureIndexGain === undefined
|
|
327
|
+
? undefined
|
|
328
|
+
: parseExposureIndexGain(record.exposureIndexGain, path + ".exposureIndexGain", digitalGain ?? 1);
|
|
239
329
|
return {
|
|
240
330
|
regimeId: requireNonEmptyString(record.regimeId, path + ".regimeId"),
|
|
241
331
|
scientificStatus: parseStatus(record.scientificStatus, path +
|
|
242
332
|
".scientificStatus"),
|
|
243
|
-
systemConversionGainElectronsPerCode
|
|
244
|
-
.systemConversionGainElectronsPerCode, path +
|
|
245
|
-
".systemConversionGainElectronsPerCode"),
|
|
333
|
+
systemConversionGainElectronsPerCode,
|
|
246
334
|
preAdcSaturationElectronEquivalent: parsePositiveFact(record
|
|
247
335
|
.preAdcSaturationElectronEquivalent, path +
|
|
248
336
|
".preAdcSaturationElectronEquivalent"),
|
|
@@ -251,28 +339,33 @@ function parseRegime(value, path) {
|
|
|
251
339
|
bitDepth,
|
|
252
340
|
blackLevelCode,
|
|
253
341
|
digitalSaturationCode,
|
|
254
|
-
transfer: "uniform-round-half-up"
|
|
342
|
+
transfer: "uniform-round-half-up",
|
|
343
|
+
...(digitalGain === undefined
|
|
344
|
+
? {}
|
|
345
|
+
: { digitalGain }),
|
|
346
|
+
...(integralNonLinearity === undefined
|
|
347
|
+
? {}
|
|
348
|
+
: { integralNonLinearity })
|
|
255
349
|
},
|
|
350
|
+
...(exposureIndexGain === undefined
|
|
351
|
+
? {}
|
|
352
|
+
: { exposureIndexGain }),
|
|
256
353
|
evidence: parseEvidenceList(record.evidence, path + ".evidence"),
|
|
257
354
|
limitations: parseLimitations(record.limitations, path + ".limitations")
|
|
258
355
|
};
|
|
259
356
|
}
|
|
260
357
|
/**
|
|
261
|
-
*
|
|
262
|
-
* missing required fields and
|
|
358
|
+
* Validates untrusted input and returns it as a normalized, typed value. Unknown enum values,
|
|
359
|
+
* missing required fields and inconsistent scientific data are rejected.
|
|
263
360
|
*
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
* pre-ADC clipping and digital clipping have distinct diagnostics; ISO never invents a conversion
|
|
268
|
-
* regime.
|
|
269
|
-
* @param value - unknown. Treated as untrusted data; static typing alone is not validation.
|
|
270
|
-
* @returns SensorReadoutConversionProfile. Return shape and scientific status are explicit; no calibration is inferred from successful execution.
|
|
361
|
+
* The profile lists the declared conversion regimes. ISO never invents a regime.
|
|
362
|
+
* @param value - Untrusted data. TypeScript types alone are not validation.
|
|
363
|
+
* @returns The result. Success does not imply calibration.
|
|
271
364
|
*
|
|
272
|
-
* @see docs/API_REFERENCE.md for the
|
|
365
|
+
* @see docs/API_REFERENCE.md for the package export and its full type definitions.
|
|
273
366
|
*/
|
|
274
367
|
export function parseSensorReadoutConversionProfile(value) {
|
|
275
|
-
const record = requireRecord(value, "sensorReadoutConversionProfile");
|
|
368
|
+
const record = requireRecord(value, "sensorReadoutConversionProfile", ["schemaVersion", "regimeSelectionOwnedBy", "regimes", "profileId", "colorSamplingProfileId", "channelId", "evidence"]);
|
|
276
369
|
if (record.schemaVersion !==
|
|
277
370
|
SENSOR_READOUT_CONVERSION_PROFILE_SCHEMA_VERSION) {
|
|
278
371
|
throw new InvalidConfigurationError('sensorReadoutConversionProfile.schemaVersion must be "' +
|
|
@@ -306,26 +399,21 @@ export function parseSensorReadoutConversionProfile(value) {
|
|
|
306
399
|
};
|
|
307
400
|
}
|
|
308
401
|
/**
|
|
309
|
-
*
|
|
310
|
-
*
|
|
402
|
+
* Selects a declared readout regime and checks it against the exact channel and profile identity.
|
|
403
|
+
* The regime is never inferred from ISO.
|
|
404
|
+
* @param input - The input; see `ResolveSensorReadoutRegimeInput` for its fields, units and coordinates.
|
|
405
|
+
* @returns The result. Success does not imply calibration.
|
|
311
406
|
*
|
|
312
|
-
*
|
|
313
|
-
* noise → upper pre-ADC threshold → black pedestal → nearest-half-up ADC quantization → unsigned code
|
|
314
|
-
* limits. Signed below-black values survive until the final code clamp. Physical storage saturation,
|
|
315
|
-
* pre-ADC clipping and digital clipping have distinct diagnostics; ISO never invents a conversion
|
|
316
|
-
* regime.
|
|
317
|
-
* @param input - ResolveSensorReadoutRegimeInput. See the linked contract for coordinate, unit and profile binding semantics.
|
|
318
|
-
* @returns ResolvedSensorReadoutRegime. Return shape and scientific status are explicit; no calibration is inferred from successful execution.
|
|
319
|
-
*
|
|
320
|
-
* @see docs/API_REFERENCE.md for the root export and exact type graph.
|
|
407
|
+
* @see docs/API_REFERENCE.md for the package export and its full type definitions.
|
|
321
408
|
*/
|
|
322
409
|
export function resolveSensorReadoutRegime(input) {
|
|
410
|
+
requireInputKeys(input, "resolveSensorReadoutRegime", ["profile", "regimeId"]);
|
|
323
411
|
const profile = parseSensorReadoutConversionProfile(input.profile);
|
|
324
412
|
if (typeof input.regimeId !==
|
|
325
413
|
"string" ||
|
|
326
414
|
input.regimeId.trim().length ===
|
|
327
415
|
0) {
|
|
328
|
-
throw new
|
|
416
|
+
throw new InvalidConfigurationError("regimeId must be a non-empty string.");
|
|
329
417
|
}
|
|
330
418
|
const regimeId = input.regimeId.trim();
|
|
331
419
|
const regime = profile.regimes.find((entry) => entry.regimeId === regimeId);
|
|
@@ -367,6 +455,14 @@ function validateChargeIdentity(charge, capacity, readout) {
|
|
|
367
455
|
capacity.bindingId) {
|
|
368
456
|
throw new InvalidScientificInputError("Physical capacity assessment identity must match the accumulated charge.");
|
|
369
457
|
}
|
|
458
|
+
// The assessment copies the complete expected stored-electron total exactly from the charge it
|
|
459
|
+
// assessed. So the match must be exact: an assessment made for any other charge is out of date.
|
|
460
|
+
if (charge
|
|
461
|
+
.totalExpectedStoredElectronCount !==
|
|
462
|
+
capacity
|
|
463
|
+
.totalExpectedStoredElectronCount) {
|
|
464
|
+
throw new InvalidScientificInputError("Physical capacity assessment must be computed for the supplied accumulated charge; its total expected stored electrons differ.");
|
|
465
|
+
}
|
|
370
466
|
if (readout
|
|
371
467
|
.colorSamplingProfileId !==
|
|
372
468
|
charge.colorSamplingProfileId ||
|
|
@@ -374,9 +470,14 @@ function validateChargeIdentity(charge, capacity, readout) {
|
|
|
374
470
|
charge.channelId) {
|
|
375
471
|
throw new InvalidScientificInputError("Sensor readout profile color/channel identity must match the accumulated charge.");
|
|
376
472
|
}
|
|
473
|
+
const belowOrAtCapacity = capacity
|
|
474
|
+
.totalExpectedStoredElectronCount <=
|
|
475
|
+
capacity
|
|
476
|
+
.physicalChargeCapacityElectrons;
|
|
377
477
|
if (capacity
|
|
378
478
|
.expectedChargeCapacityStatus ===
|
|
379
|
-
"above-capacity"
|
|
479
|
+
"above-capacity" ||
|
|
480
|
+
!belowOrAtCapacity) {
|
|
380
481
|
throw new InvalidScientificInputError("Expected stored charge above physical capacity cannot enter linear expected readout; the actual post-saturation stored charge is not defined by the upstream assessment.");
|
|
381
482
|
}
|
|
382
483
|
if (charge.saturationAssessed !==
|
|
@@ -387,6 +488,7 @@ function validateChargeIdentity(charge, capacity, readout) {
|
|
|
387
488
|
false) {
|
|
388
489
|
throw new InvalidScientificInputError("Sensor readout requires the unmodified accumulated-charge result.");
|
|
389
490
|
}
|
|
491
|
+
return belowOrAtCapacity;
|
|
390
492
|
}
|
|
391
493
|
function additionalPolicyMap(profile, charge) {
|
|
392
494
|
if (profile.completenessProfileId !==
|
|
@@ -408,37 +510,14 @@ function additionalPolicyMap(profile, charge) {
|
|
|
408
510
|
policy
|
|
409
511
|
]));
|
|
410
512
|
}
|
|
411
|
-
/**
|
|
412
|
-
* Create the deterministic non-cryptographic xorshift32 stream for one charge or
|
|
413
|
-
* read-noise identity. The XOR mix and nonzero fallback avoid the absorbing zero
|
|
414
|
-
* state. Adding 0.5 before division produces values strictly inside (0,1), so
|
|
415
|
-
* logarithmic Poisson/normal transforms never receive a zero or one endpoint.
|
|
416
|
-
* Changing these mechanics changes realized RAW and requires model/replay review.
|
|
417
|
-
*/
|
|
418
513
|
function createRandom(seedUint32) {
|
|
419
|
-
|
|
420
|
-
0x9e3779b9) >>>
|
|
421
|
-
0;
|
|
422
|
-
if (state === 0) {
|
|
423
|
-
state =
|
|
424
|
-
0x6d2b79f5;
|
|
425
|
-
}
|
|
426
|
-
return {
|
|
427
|
-
next() {
|
|
428
|
-
state ^= state << 13;
|
|
429
|
-
state ^= state >>> 17;
|
|
430
|
-
state ^= state << 5;
|
|
431
|
-
state >>>= 0;
|
|
432
|
-
return ((state + 0.5) /
|
|
433
|
-
0x1_0000_0000);
|
|
434
|
-
}
|
|
435
|
-
};
|
|
514
|
+
return createDeterministicUniformStream(seedUint32);
|
|
436
515
|
}
|
|
437
516
|
/**
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
* terms 1/(12n) - 1/(360n³). This is internal to the Poisson rejection
|
|
441
|
-
* not
|
|
517
|
+
* Computes log(n!) without forming the factorial, which would overflow. Small counts
|
|
518
|
+
* sum the logarithms directly. Larger counts use Stirling's formula with the
|
|
519
|
+
* correction terms 1/(12n) - 1/(360n³). This is internal to the Poisson rejection
|
|
520
|
+
* sampler; it is not a claim about physical accuracy or uncertainty.
|
|
442
521
|
*/
|
|
443
522
|
function logFactorial(n) {
|
|
444
523
|
if (n < 2) {
|
|
@@ -460,14 +539,23 @@ function logFactorial(n) {
|
|
|
460
539
|
inverse / 12 -
|
|
461
540
|
inverseCubed / 360);
|
|
462
541
|
}
|
|
542
|
+
/** Means at or above this use the continuity-corrected normal approximation. */
|
|
543
|
+
const POISSON_NORMAL_APPROXIMATION_MINIMUM_MEAN = 1e9;
|
|
463
544
|
/**
|
|
464
|
-
*
|
|
465
|
-
*
|
|
466
|
-
*
|
|
467
|
-
*
|
|
468
|
-
*
|
|
545
|
+
* Draws a nonnegative integer from a Poisson distribution with the given mean.
|
|
546
|
+
*
|
|
547
|
+
* - Mean 0 returns exactly 0.
|
|
548
|
+
* - Mean below 30: multiply uniform random numbers until the product drops below e^(−mean).
|
|
549
|
+
* - Mean from 30 to below 1e9: Hörmann's (1993) PTRS transformed rejection, comparing log
|
|
550
|
+
* probabilities to avoid overflow.
|
|
551
|
+
* - Mean of 1e9 and above: a continuity-corrected normal approximation, because the log terms lose
|
|
552
|
+
* precision there.
|
|
553
|
+
*
|
|
554
|
+
* The same mean and random stream reproduce the same draw. Increasing the mean does not guarantee
|
|
555
|
+
* that each individual draw increases. Exported internally for the lean native executor, which must
|
|
556
|
+
* draw exactly as simulateSensorChargeRealization does; not exported from the package.
|
|
469
557
|
*/
|
|
470
|
-
function samplePoisson(mean, random) {
|
|
558
|
+
export function samplePoisson(mean, random) {
|
|
471
559
|
if (!Number.isFinite(mean) ||
|
|
472
560
|
mean < 0) {
|
|
473
561
|
throw new InvalidScientificInputError("Poisson mean must be finite and nonnegative.");
|
|
@@ -475,6 +563,19 @@ function samplePoisson(mean, random) {
|
|
|
475
563
|
if (mean === 0) {
|
|
476
564
|
return 0;
|
|
477
565
|
}
|
|
566
|
+
if (mean >=
|
|
567
|
+
POISSON_NORMAL_APPROXIMATION_MINIMUM_MEAN) {
|
|
568
|
+
// Above 1e9 the log-probability terms of the rejection test reach about 1e10 and cancel badly
|
|
569
|
+
// (variance/mean is 1.012 at 1e14). Here the continuity-corrected normal approximation has a
|
|
570
|
+
// relative skewness error of 1/sqrt(mean) <= 3.2e-5 (Poisson skewness 1/sqrt(mean): NIST/SEMATECH
|
|
571
|
+
// e-Handbook of Statistical Methods, sec. 1.3.6.6.19, free; normal approximation with continuity
|
|
572
|
+
// correction: SOCR, University of Michigan, free. Also see: Johnson, Kemp & Kotz, Univariate
|
|
573
|
+
// Discrete Distributions, 3rd ed., section 4.4).
|
|
574
|
+
return Math.max(0, Math.floor(mean +
|
|
575
|
+
Math.sqrt(mean) *
|
|
576
|
+
sampleStandardNormal(random) +
|
|
577
|
+
0.5));
|
|
578
|
+
}
|
|
478
579
|
if (mean < 30) {
|
|
479
580
|
const threshold = Math.exp(-mean);
|
|
480
581
|
let product = 1;
|
|
@@ -532,31 +633,37 @@ function samplePoisson(mean, random) {
|
|
|
532
633
|
}
|
|
533
634
|
}
|
|
534
635
|
/**
|
|
535
|
-
*
|
|
536
|
-
*
|
|
537
|
-
|
|
636
|
+
* Internal (not exported from the package): draws `count` Poisson samples of one mean from one seeded
|
|
637
|
+
* stream, exactly as the charge realization does. Used by the sampler's distribution tests.
|
|
638
|
+
*/
|
|
639
|
+
export function samplePoissonStreamForValidation(mean, seedUint32, count) {
|
|
640
|
+
const random = createRandom(seedUint32);
|
|
641
|
+
return Array.from({ length: count }, () => samplePoisson(mean, random));
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Internal (not exported from the package): draws `count` standard normal values from one seeded
|
|
645
|
+
* stream, exactly as the read-noise path does. Used by the sampler's distribution tests.
|
|
538
646
|
*/
|
|
647
|
+
export function sampleStandardNormalStreamForValidation(seedUint32, count) {
|
|
648
|
+
const random = createRandom(seedUint32);
|
|
649
|
+
return Array.from({ length: count }, () => sampleStandardNormal(random));
|
|
650
|
+
}
|
|
539
651
|
function sampleStandardNormal(random) {
|
|
540
|
-
|
|
541
|
-
const u2 = random.next();
|
|
542
|
-
return (Math.sqrt(-2 * Math.log(u1)) *
|
|
543
|
-
Math.cos(2 * Math.PI * u2));
|
|
652
|
+
return sampleDeterministicStandardNormal(random);
|
|
544
653
|
}
|
|
545
654
|
/**
|
|
546
|
-
*
|
|
547
|
-
* policies from expected accumulated charge.
|
|
655
|
+
* Draws deterministic, separately seeded Poisson counts for photo and dark charge, and applies the
|
|
656
|
+
* declared policies for additional components, starting from the expected accumulated charge.
|
|
548
657
|
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
*
|
|
553
|
-
* regime.
|
|
554
|
-
* @param input - SimulateSensorChargeRealizationInput. See the linked contract for coordinate, unit and profile binding semantics.
|
|
555
|
-
* @returns CalculationResult<SensorChargeRealization>. Return shape and scientific status are explicit; no calibration is inferred from successful execution.
|
|
658
|
+
* This is steps 1–2 of the readout order (see the module notes). Physical storage saturation is
|
|
659
|
+
* reported separately from later clipping.
|
|
660
|
+
* @param input - The input; see `SimulateSensorChargeRealizationInput` for its fields, units and coordinates.
|
|
661
|
+
* @returns The result. Success does not imply calibration.
|
|
556
662
|
*
|
|
557
|
-
* @see docs/API_REFERENCE.md for the
|
|
663
|
+
* @see docs/API_REFERENCE.md for the package export and its full type definitions.
|
|
558
664
|
*/
|
|
559
665
|
export function simulateSensorChargeRealization(input) {
|
|
666
|
+
requireInputKeys(input, "simulateSensorChargeRealization", ["accumulatedCharge", "samplingProfile", "seedUint32", "fixedPatternNoise"]);
|
|
560
667
|
const profile = parseSensorChargeSamplingProfile(input.samplingProfile);
|
|
561
668
|
const seed = requireUint32(input.seedUint32, "seedUint32");
|
|
562
669
|
const charge = input.accumulatedCharge;
|
|
@@ -571,11 +678,32 @@ export function simulateSensorChargeRealization(input) {
|
|
|
571
678
|
throw new InvalidScientificInputError("Charge realization requires a complete unsaturated pre-readout accumulated-charge result.");
|
|
572
679
|
}
|
|
573
680
|
const policies = additionalPolicyMap(profile, charge);
|
|
681
|
+
const pattern = input.fixedPatternNoise === undefined
|
|
682
|
+
? null
|
|
683
|
+
: fixedPatternAtSite(parseSensorFixedPatternNoiseProfile(input.fixedPatternNoise), charge
|
|
684
|
+
.colorSamplingProfileId, charge.site);
|
|
685
|
+
const photoGain = pattern === null
|
|
686
|
+
? 1
|
|
687
|
+
: pattern
|
|
688
|
+
.photoResponseGainFactor;
|
|
689
|
+
const darkFactor = pattern === null
|
|
690
|
+
? 1
|
|
691
|
+
: pattern.darkCurrentFactor;
|
|
692
|
+
const photoMean = pattern === null
|
|
693
|
+
? charge
|
|
694
|
+
.photoExpectedElectronCount
|
|
695
|
+
: charge
|
|
696
|
+
.photoExpectedElectronCount *
|
|
697
|
+
photoGain;
|
|
698
|
+
const darkMean = pattern === null
|
|
699
|
+
? charge
|
|
700
|
+
.darkExpectedElectronCount
|
|
701
|
+
: charge
|
|
702
|
+
.darkExpectedElectronCount *
|
|
703
|
+
darkFactor;
|
|
574
704
|
const random = createRandom(seed);
|
|
575
|
-
const photoRealized = samplePoisson(
|
|
576
|
-
|
|
577
|
-
const darkRealized = samplePoisson(charge
|
|
578
|
-
.darkExpectedElectronCount, random);
|
|
705
|
+
const photoRealized = samplePoisson(photoMean, random);
|
|
706
|
+
const darkRealized = samplePoisson(darkMean, random);
|
|
579
707
|
const additionalComponents = charge.additionalComponents.map((component) => {
|
|
580
708
|
const policy = policies.get(component.componentId);
|
|
581
709
|
const realized = policy.model ===
|
|
@@ -620,6 +748,14 @@ export function simulateSensorChargeRealization(input) {
|
|
|
620
748
|
darkExpectedElectronCount: charge
|
|
621
749
|
.darkExpectedElectronCount,
|
|
622
750
|
darkRealizedElectronCount: darkRealized,
|
|
751
|
+
fixedPatternNoiseProfileId: pattern === null
|
|
752
|
+
? null
|
|
753
|
+
: pattern.profileId,
|
|
754
|
+
photoResponseGainFactor: photoGain,
|
|
755
|
+
darkCurrentFactor: darkFactor,
|
|
756
|
+
hotPixel: pattern?.hotPixel ?? false,
|
|
757
|
+
photoSampledMeanElectronCount: photoMean,
|
|
758
|
+
darkSampledMeanElectronCount: darkMean,
|
|
623
759
|
additionalComponents,
|
|
624
760
|
totalExpectedStoredElectronCount: charge
|
|
625
761
|
.totalExpectedStoredElectronCount,
|
|
@@ -634,13 +770,39 @@ export function simulateSensorChargeRealization(input) {
|
|
|
634
770
|
rawCodeValueProduced: false,
|
|
635
771
|
stochasticModel: "independent-poisson-photo-dark-explicit-additional-policy",
|
|
636
772
|
deterministicSeededRealization: true
|
|
637
|
-
}, "sensor-charge-stochastic-realization", "
|
|
773
|
+
}, "sensor-charge-stochastic-realization", "3.0.0", [
|
|
774
|
+
"An optional explicit fixed-pattern profile multiplies the photo Poisson mean by the site's PRNU gain and the dark Poisson mean by its DSNU/hot-pixel factor; without one the uniform population expectation is sampled. Fixed-pattern values are deterministic per sensor instance and colour-sampling site.",
|
|
775
|
+
"Poisson means of 1e9 electrons and above use a continuity-corrected normal approximation.",
|
|
638
776
|
"Photo-generated and dark-generated electron counts are sampled independently from Poisson distributions using an explicit deterministic seed.",
|
|
639
777
|
"Each additional stored-charge component uses its explicitly declared Poisson or deterministic electron-equivalent policy; Photivra does not infer defect/leakage statistics from the component name.",
|
|
640
778
|
"This is a pre-saturation, pre-electronic-read-noise charge realization and remains separate from expectation-value calculations.",
|
|
641
|
-
"The seeded PRNG is a deterministic simulation mechanism and is not cryptographically secure."
|
|
779
|
+
"The seeded PRNG is a deterministic simulation mechanism and is not cryptographically secure; its seed is scrambled by the MurmurHash3 fmix32 finalizer so nearby seeds give unrelated streams."
|
|
642
780
|
]);
|
|
643
781
|
}
|
|
782
|
+
function fixedPatternAtSite(profile, colorSamplingProfileId, site) {
|
|
783
|
+
if (profile.colorSamplingProfileId !==
|
|
784
|
+
colorSamplingProfileId) {
|
|
785
|
+
throw new InvalidScientificInputError("Fixed-pattern noise profile colour-sampling identity must match the charge.");
|
|
786
|
+
}
|
|
787
|
+
return evaluateParsedFixedPatternSite(profile, site);
|
|
788
|
+
}
|
|
789
|
+
function fixedPatternForRealization(value, charge) {
|
|
790
|
+
if (value === undefined) {
|
|
791
|
+
if (charge.fixedPatternNoiseProfileId !==
|
|
792
|
+
null &&
|
|
793
|
+
charge.fixedPatternNoiseProfileId !==
|
|
794
|
+
undefined) {
|
|
795
|
+
throw new InvalidScientificInputError("A charge realization with a fixed pattern requires the same fixed-pattern profile at readout.");
|
|
796
|
+
}
|
|
797
|
+
return null;
|
|
798
|
+
}
|
|
799
|
+
const profile = parseSensorFixedPatternNoiseProfile(value);
|
|
800
|
+
if (charge.fixedPatternNoiseProfileId !==
|
|
801
|
+
profile.profileId) {
|
|
802
|
+
throw new InvalidScientificInputError("Readout fixed-pattern profile must be the profile used for the charge realization.");
|
|
803
|
+
}
|
|
804
|
+
return fixedPatternAtSite(profile, charge.colorSamplingProfileId, charge.site);
|
|
805
|
+
}
|
|
644
806
|
function validateCapacityAgainstRealization(charge, capacity, readout) {
|
|
645
807
|
if (charge.completenessProfileId !==
|
|
646
808
|
capacity
|
|
@@ -658,6 +820,12 @@ function validateCapacityAgainstRealization(charge, capacity, readout) {
|
|
|
658
820
|
capacity.bindingId) {
|
|
659
821
|
throw new InvalidScientificInputError("Physical capacity assessment identity must match the charge realization.");
|
|
660
822
|
}
|
|
823
|
+
if (charge
|
|
824
|
+
.totalExpectedStoredElectronCount !==
|
|
825
|
+
capacity
|
|
826
|
+
.totalExpectedStoredElectronCount) {
|
|
827
|
+
throw new InvalidScientificInputError("Physical capacity assessment must be computed for the charge behind the realization; its total expected stored electrons differ.");
|
|
828
|
+
}
|
|
661
829
|
if (readout
|
|
662
830
|
.colorSamplingProfileId !==
|
|
663
831
|
charge.colorSamplingProfileId ||
|
|
@@ -667,25 +835,20 @@ function validateCapacityAgainstRealization(charge, capacity, readout) {
|
|
|
667
835
|
}
|
|
668
836
|
}
|
|
669
837
|
/**
|
|
670
|
-
*
|
|
671
|
-
*
|
|
672
|
-
*
|
|
673
|
-
*
|
|
674
|
-
* noise → upper pre-ADC threshold → black pedestal → nearest-half-up ADC quantization → unsigned code
|
|
675
|
-
* limits. Signed below-black values survive until the final code clamp. Physical storage saturation,
|
|
676
|
-
* pre-ADC clipping and digital clipping have distinct diagnostics; ISO never invents a conversion
|
|
677
|
-
* regime.
|
|
678
|
-
* @param input - CalculateExpectedSensorReadoutInput. See the linked contract for coordinate, unit and profile binding semantics.
|
|
679
|
-
* @returns CalculationResult<SensorExpectedReadoutSignal>. Return shape and scientific status are explicit; no calibration is inferred from successful execution.
|
|
838
|
+
* Maps the expected charge through the declared gain, offset and readout limits, with no random
|
|
839
|
+
* sampling. Each kind of clipping (physical storage, pre-ADC, digital) is reported separately.
|
|
840
|
+
* @param input - The input; see `CalculateExpectedSensorReadoutInput` for its fields, units and coordinates.
|
|
841
|
+
* @returns The result. Success does not imply calibration.
|
|
680
842
|
*
|
|
681
|
-
* @see docs/API_REFERENCE.md for the
|
|
843
|
+
* @see docs/API_REFERENCE.md for the package export and its full type definitions.
|
|
682
844
|
*/
|
|
683
845
|
export function calculateExpectedSensorReadout(input) {
|
|
846
|
+
requireInputKeys(input, "calculateExpectedSensorReadout", ["accumulatedCharge", "physicalCapacityAssessment", "readoutProfile", "regimeId"]);
|
|
684
847
|
const readout = resolveSensorReadoutRegime({
|
|
685
848
|
profile: input.readoutProfile,
|
|
686
849
|
regimeId: input.regimeId
|
|
687
850
|
});
|
|
688
|
-
validateChargeIdentity(input.accumulatedCharge, input
|
|
851
|
+
const expectedStoredChargeBelowOrAtPhysicalCapacity = validateChargeIdentity(input.accumulatedCharge, input
|
|
689
852
|
.physicalCapacityAssessment, readout);
|
|
690
853
|
const expected = input.accumulatedCharge
|
|
691
854
|
.totalExpectedStoredElectronCount;
|
|
@@ -697,9 +860,25 @@ export function calculateExpectedSensorReadout(input) {
|
|
|
697
860
|
readout.regime
|
|
698
861
|
.systemConversionGainElectronsPerCode
|
|
699
862
|
.value;
|
|
863
|
+
const inlOffset = integralNonLinearityOffset(readout.regime.adc
|
|
864
|
+
.integralNonLinearity, codeSignal +
|
|
865
|
+
readout.regime
|
|
866
|
+
.adc.blackLevelCode);
|
|
700
867
|
const codeBeforeQuantization = codeSignal +
|
|
701
868
|
readout.regime
|
|
702
|
-
.adc.blackLevelCode
|
|
869
|
+
.adc.blackLevelCode +
|
|
870
|
+
inlOffset;
|
|
871
|
+
const digitalGain = readout.regime.adc
|
|
872
|
+
.digitalGain ?? 1;
|
|
873
|
+
const codeAfterDigitalGain = readout.regime.adc
|
|
874
|
+
.digitalGain === undefined
|
|
875
|
+
? codeBeforeQuantization
|
|
876
|
+
: (Math.min(codeBeforeQuantization, readout.adcMaximumCode) -
|
|
877
|
+
readout.regime.adc
|
|
878
|
+
.blackLevelCode) *
|
|
879
|
+
digitalGain +
|
|
880
|
+
readout.regime.adc
|
|
881
|
+
.blackLevelCode;
|
|
703
882
|
return approximationResult({
|
|
704
883
|
readoutProfileId: readout.profileId,
|
|
705
884
|
regimeId: readout.regime
|
|
@@ -721,7 +900,7 @@ export function calculateExpectedSensorReadout(input) {
|
|
|
721
900
|
bindingId: input.accumulatedCharge
|
|
722
901
|
.bindingId,
|
|
723
902
|
expectedStoredElectronCount: expected,
|
|
724
|
-
expectedStoredChargeBelowOrAtPhysicalCapacity
|
|
903
|
+
expectedStoredChargeBelowOrAtPhysicalCapacity,
|
|
725
904
|
expectedElectronEquivalentAfterPreAdcSaturation: afterPreAdc,
|
|
726
905
|
preAdcSaturationAppliedToExpectation: afterPreAdc < expected,
|
|
727
906
|
systemConversionGainElectronsPerCode: readout.regime
|
|
@@ -731,13 +910,16 @@ export function calculateExpectedSensorReadout(input) {
|
|
|
731
910
|
blackLevelCode: readout.regime
|
|
732
911
|
.adc.blackLevelCode,
|
|
733
912
|
expectedCodeBeforeQuantization: codeBeforeQuantization,
|
|
913
|
+
adcIntegralNonLinearityOffsetCodes: inlOffset,
|
|
914
|
+
digitalGain,
|
|
915
|
+
expectedCodeAfterDigitalGain: codeAfterDigitalGain,
|
|
734
916
|
adcBitDepth: readout.regime
|
|
735
917
|
.adc.bitDepth,
|
|
736
918
|
adcMaximumCode: readout.adcMaximumCode,
|
|
737
919
|
digitalSaturationCode: readout.regime
|
|
738
920
|
.adc
|
|
739
921
|
.digitalSaturationCode,
|
|
740
|
-
expectedDigitalSaturation:
|
|
922
|
+
expectedDigitalSaturation: codeAfterDigitalGain >=
|
|
741
923
|
readout.regime
|
|
742
924
|
.adc
|
|
743
925
|
.digitalSaturationCode,
|
|
@@ -748,32 +930,106 @@ export function calculateExpectedSensorReadout(input) {
|
|
|
748
930
|
adcQuantizationApplied: false,
|
|
749
931
|
rawCodeValueProduced: false,
|
|
750
932
|
isoUsedToInferRegime: false
|
|
751
|
-
}, "sensor-expected-electronic-readout", "
|
|
933
|
+
}, "sensor-expected-electronic-readout", "2.0.0", [
|
|
752
934
|
"Expected readout uses complete expected stored charge only after the upstream physical-capacity assessment confirms the expectation is not above physical capacity.",
|
|
753
935
|
"Electronic read-noise mean is zero and is not sampled in this expectation result.",
|
|
754
|
-
"The explicitly selected conversion regime is not inferred from ISO, sensor technology family or marketing mode names.",
|
|
936
|
+
"The explicitly selected conversion regime is not inferred from ISO, sensor technology family or marketing mode names; an ISO signal chain may bind an exposure index to a declared regime.",
|
|
937
|
+
"Declared ADC integral non-linearity and post-ADC digital gain are applied to the continuous expectation without quantization.",
|
|
755
938
|
"Pre-ADC electron-equivalent saturation, black offset and ADC/digital saturation remain separate domains.",
|
|
756
939
|
"ADC quantization is not applied to the expectation value."
|
|
757
940
|
]);
|
|
758
941
|
}
|
|
942
|
+
/**
|
|
943
|
+
* Nearest integer, with ties going towards +infinity. Math.round is exact for every double. (In
|
|
944
|
+
* contrast, floor(x + 0.5) returns 1 for 0.49999999999999994, because the addition rounds up.)
|
|
945
|
+
* Adding 0 turns -0 into +0.
|
|
946
|
+
*/
|
|
759
947
|
function roundHalfUp(value) {
|
|
760
|
-
return Math.
|
|
948
|
+
return Math.round(value) + 0;
|
|
949
|
+
}
|
|
950
|
+
function integralNonLinearityOffset(inl, code) {
|
|
951
|
+
if (inl === undefined) {
|
|
952
|
+
return 0;
|
|
953
|
+
}
|
|
954
|
+
const knots = inl.knots;
|
|
955
|
+
const first = knots[0];
|
|
956
|
+
const last = knots[knots.length - 1];
|
|
957
|
+
if (code <= first.code) {
|
|
958
|
+
return first.offsetCodes;
|
|
959
|
+
}
|
|
960
|
+
if (code >= last.code) {
|
|
961
|
+
return last.offsetCodes;
|
|
962
|
+
}
|
|
963
|
+
let low = 0;
|
|
964
|
+
let high = knots.length - 1;
|
|
965
|
+
while (high - low > 1) {
|
|
966
|
+
const middle = (low + high) >> 1;
|
|
967
|
+
if (knots[middle].code <= code) {
|
|
968
|
+
low = middle;
|
|
969
|
+
}
|
|
970
|
+
else {
|
|
971
|
+
high = middle;
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
const a = knots[low];
|
|
975
|
+
const b = knots[high];
|
|
976
|
+
return (a.offsetCodes +
|
|
977
|
+
((code - a.code) /
|
|
978
|
+
(b.code - a.code)) *
|
|
979
|
+
(b.offsetCodes - a.offsetCodes));
|
|
761
980
|
}
|
|
762
981
|
/**
|
|
763
|
-
*
|
|
764
|
-
*
|
|
765
|
-
*
|
|
766
|
-
*
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
982
|
+
* Shared ADC transfer function: continuous input code (signal/gain + black + INL), rounded half up
|
|
983
|
+
* and limited to the ADC code range, then optional post-ADC digital gain about black, rounded again.
|
|
984
|
+
* The caller applies the final clamp to [0, digitalSaturationCode]. Exported internally for the lean
|
|
985
|
+
* native executor; not exported from the package.
|
|
986
|
+
*/
|
|
987
|
+
export function adcTransfer(regime, adcMaximumCode, electronEquivalent) {
|
|
988
|
+
const ideal = electronEquivalent /
|
|
989
|
+
regime
|
|
990
|
+
.systemConversionGainElectronsPerCode
|
|
991
|
+
.value +
|
|
992
|
+
regime.adc.blackLevelCode;
|
|
993
|
+
const inlOffset = integralNonLinearityOffset(regime.adc.integralNonLinearity, ideal);
|
|
994
|
+
const codeBeforeQuantization = ideal + inlOffset;
|
|
995
|
+
const quantizedAdc = roundHalfUp(codeBeforeQuantization);
|
|
996
|
+
const digitalGain = regime.adc.digitalGain ?? 1;
|
|
997
|
+
if (regime.adc.digitalGain ===
|
|
998
|
+
undefined) {
|
|
999
|
+
return {
|
|
1000
|
+
codeBeforeQuantization,
|
|
1001
|
+
inlOffset,
|
|
1002
|
+
adcCode: quantizedAdc,
|
|
1003
|
+
digitalGain,
|
|
1004
|
+
quantized: quantizedAdc
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
const adcCode = Math.max(0, Math.min(quantizedAdc, adcMaximumCode));
|
|
1008
|
+
return {
|
|
1009
|
+
codeBeforeQuantization,
|
|
1010
|
+
inlOffset,
|
|
1011
|
+
adcCode,
|
|
1012
|
+
digitalGain,
|
|
1013
|
+
quantized: roundHalfUp((adcCode -
|
|
1014
|
+
regime.adc
|
|
1015
|
+
.blackLevelCode) *
|
|
1016
|
+
digitalGain +
|
|
1017
|
+
regime.adc
|
|
1018
|
+
.blackLevelCode)
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
/**
|
|
1022
|
+
* Simulates one RAW code from a charge realization with the declared seed and regime: steps 3–7 of
|
|
1023
|
+
* the readout order (see the module notes). Signed read noise is kept through the black pedestal and
|
|
1024
|
+
* quantization, and only the final code is clamped. Returns the bounded native ADC code and per-step
|
|
1025
|
+
* diagnostics.
|
|
1026
|
+
* @param input - The input; see `SimulateSensorRawCodeInput` for its fields, units and coordinates.
|
|
1027
|
+
* @returns The result. Success does not imply calibration.
|
|
773
1028
|
*
|
|
774
|
-
* @see docs/API_REFERENCE.md for the
|
|
1029
|
+
* @see docs/API_REFERENCE.md for the package export and its full type definitions.
|
|
775
1030
|
*/
|
|
776
1031
|
export function simulateSensorRawCode(input) {
|
|
1032
|
+
requireInputKeys(input, "simulateSensorRawCode", ["chargeRealization", "physicalCapacityAssessment", "readoutProfile", "regimeId", "readNoiseSeedUint32", "fixedPatternNoise"]);
|
|
777
1033
|
const readout = resolveSensorReadoutRegime({
|
|
778
1034
|
profile: input.readoutProfile,
|
|
779
1035
|
regimeId: input.regimeId
|
|
@@ -816,23 +1072,25 @@ export function simulateSensorRawCode(input) {
|
|
|
816
1072
|
const totalReadNoise = readNoiseComponents.reduce((sum, component) => sum +
|
|
817
1073
|
component
|
|
818
1074
|
.sampledElectrons, 0);
|
|
1075
|
+
const pattern = fixedPatternForRealization(input.fixedPatternNoise, input.chargeRealization);
|
|
1076
|
+
const fixedPatternOffset = pattern === null
|
|
1077
|
+
? 0
|
|
1078
|
+
: pattern
|
|
1079
|
+
.readoutOffsetElectrons;
|
|
819
1080
|
const afterReadNoise = afterPhysical +
|
|
820
|
-
totalReadNoise
|
|
1081
|
+
totalReadNoise +
|
|
1082
|
+
fixedPatternOffset;
|
|
821
1083
|
const preAdcThreshold = readout.regime
|
|
822
1084
|
.preAdcSaturationElectronEquivalent
|
|
823
1085
|
.value;
|
|
824
|
-
// Stored charge is nonnegative
|
|
825
|
-
//
|
|
1086
|
+
// Stored charge is nonnegative, but the electronic signal after it is signed.
|
|
1087
|
+
// Keep negative read noise until the black pedestal and the unsigned ADC limit.
|
|
826
1088
|
const afterPreAdc = Math.min(afterReadNoise, preAdcThreshold);
|
|
827
1089
|
const preAdcSaturation = afterReadNoise >
|
|
828
1090
|
preAdcThreshold;
|
|
829
|
-
const
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
.value +
|
|
833
|
-
readout.regime
|
|
834
|
-
.adc.blackLevelCode;
|
|
835
|
-
const quantized = roundHalfUp(codeBeforeQuantization);
|
|
1091
|
+
const transfer = adcTransfer(readout.regime, readout.adcMaximumCode, afterPreAdc);
|
|
1092
|
+
const codeBeforeQuantization = transfer.codeBeforeQuantization;
|
|
1093
|
+
const quantized = transfer.quantized;
|
|
836
1094
|
const rawCode = Math.max(0, Math.min(quantized, readout.regime
|
|
837
1095
|
.adc
|
|
838
1096
|
.digitalSaturationCode));
|
|
@@ -868,6 +1126,10 @@ export function simulateSensorRawCode(input) {
|
|
|
868
1126
|
bloomingModeled: false,
|
|
869
1127
|
electronicReadNoiseComponents: readNoiseComponents,
|
|
870
1128
|
totalElectronicReadNoiseElectrons: totalReadNoise,
|
|
1129
|
+
fixedPatternNoiseProfileId: pattern === null
|
|
1130
|
+
? null
|
|
1131
|
+
: pattern.profileId,
|
|
1132
|
+
fixedPatternReadoutOffsetElectrons: fixedPatternOffset,
|
|
871
1133
|
electronEquivalentAfterReadNoise: afterReadNoise,
|
|
872
1134
|
preAdcSaturationElectronEquivalent: preAdcThreshold,
|
|
873
1135
|
electronEquivalentAfterPreAdcSaturation: afterPreAdc,
|
|
@@ -878,6 +1140,9 @@ export function simulateSensorRawCode(input) {
|
|
|
878
1140
|
blackLevelCode: readout.regime
|
|
879
1141
|
.adc.blackLevelCode,
|
|
880
1142
|
codeBeforeQuantization,
|
|
1143
|
+
adcIntegralNonLinearityOffsetCodes: transfer.inlOffset,
|
|
1144
|
+
adcCodeBeforeDigitalGain: transfer.adcCode,
|
|
1145
|
+
digitalGain: transfer.digitalGain,
|
|
881
1146
|
quantizedCodeBeforeDigitalClamp: quantized,
|
|
882
1147
|
adcBitDepth: readout.regime
|
|
883
1148
|
.adc.bitDepth,
|
|
@@ -886,7 +1151,7 @@ export function simulateSensorRawCode(input) {
|
|
|
886
1151
|
.adc
|
|
887
1152
|
.digitalSaturationCode,
|
|
888
1153
|
rawCode,
|
|
889
|
-
digitalSaturationApplied: quantized
|
|
1154
|
+
digitalSaturationApplied: quantized >=
|
|
890
1155
|
readout.regime
|
|
891
1156
|
.adc
|
|
892
1157
|
.digitalSaturationCode,
|
|
@@ -902,11 +1167,11 @@ export function simulateSensorRawCode(input) {
|
|
|
902
1167
|
rawCodeValueProduced: true,
|
|
903
1168
|
isoUsedToInferRegime: false,
|
|
904
1169
|
deterministicSeededRealization: true
|
|
905
|
-
}, "sensor-raw-code-stochastic-readout", "
|
|
1170
|
+
}, "sensor-raw-code-stochastic-readout", "4.0.0", [
|
|
906
1171
|
"A stochastic stored-charge realization is scalar-clamped at the explicit physical storage capacity; this is a bounded saturation approximation and does not model blooming, neighbor transport or anti-blooming behavior.",
|
|
907
|
-
"Independent input-referred Gaussian electronic read-noise components are
|
|
908
|
-
"System conversion gain is expressed in electrons per digital-number code unit for the explicitly selected regime
|
|
909
|
-
"Signed electronic read noise survives the upper-only pre-ADC saturation threshold. Black level
|
|
1172
|
+
"Independent input-referred Gaussian electronic read-noise components, plus any declared static fixed-pattern row/column offsets, are added after physical charge saturation and before the explicit pre-ADC electron-equivalent saturation threshold.",
|
|
1173
|
+
"System conversion gain is expressed in electrons per digital-number code unit for the explicitly selected regime; an ISO-dependent gain exists only where an explicit ISO signal chain binds the setting to a declared regime.",
|
|
1174
|
+
"Signed electronic read noise survives the upper-only pre-ADC saturation threshold. Black level and any declared ADC integral non-linearity are added before uniform round-half-up quantization (exact ties toward +infinity); an optional post-ADC digital gain about black is re-quantized; codes are then clamped to zero/digital saturation and valid below-black codes are retained.",
|
|
910
1175
|
"Physical storage capacity, pre-ADC saturation and digital/ADC saturation remain separate thresholds.",
|
|
911
1176
|
"The charge seed and read-noise seed are separate deterministic simulation identities; neither is cryptographically secure."
|
|
912
1177
|
]);
|