@photivra/engine 0.6.0 → 1.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/AGENTS.md +674 -0
- package/CHANGELOG.md +186 -0
- package/CITATION.cff +1 -1
- package/CONTRIBUTING.md +76 -0
- package/DCO +33 -0
- package/NODE_SUPPORT.md +37 -0
- package/NOTICE +2 -0
- package/README.md +138 -71
- package/SECURITY.md +55 -0
- package/THIRD_PARTY.md +63 -0
- package/dist/camera/equivalent-focal-length.d.ts +9 -0
- package/dist/camera/equivalent-focal-length.d.ts.map +1 -1
- package/dist/camera/equivalent-focal-length.js +9 -0
- package/dist/camera/equivalent-focal-length.js.map +1 -1
- package/dist/camera/field-of-view.d.ts +13 -0
- package/dist/camera/field-of-view.d.ts.map +1 -1
- package/dist/camera/field-of-view.js +13 -0
- package/dist/camera/field-of-view.js.map +1 -1
- package/dist/camera/projected-object-size.d.ts +8 -0
- package/dist/camera/projected-object-size.d.ts.map +1 -1
- package/dist/camera/projected-object-size.js +8 -0
- package/dist/camera/projected-object-size.js.map +1 -1
- package/dist/capture/capture-export-metadata.d.ts +60 -0
- package/dist/capture/capture-export-metadata.d.ts.map +1 -0
- package/dist/capture/capture-export-metadata.js +62 -0
- package/dist/capture/capture-export-metadata.js.map +1 -0
- package/dist/capture/environment-raw-producer.d.ts +55 -0
- package/dist/capture/environment-raw-producer.d.ts.map +1 -0
- package/dist/capture/environment-raw-producer.js +88 -0
- package/dist/capture/environment-raw-producer.js.map +1 -0
- package/dist/capture/export-jpeg.d.ts +12 -0
- package/dist/capture/export-jpeg.d.ts.map +1 -0
- package/dist/capture/export-jpeg.js +126 -0
- package/dist/capture/export-jpeg.js.map +1 -0
- package/dist/capture/export-tiff.d.ts +45 -0
- package/dist/capture/export-tiff.d.ts.map +1 -0
- package/dist/capture/export-tiff.js +129 -0
- package/dist/capture/export-tiff.js.map +1 -0
- package/dist/capture/focus-control.d.ts +210 -0
- package/dist/capture/focus-control.d.ts.map +1 -0
- package/dist/capture/focus-control.js +664 -0
- package/dist/capture/focus-control.js.map +1 -0
- package/dist/capture/linear-encoding.d.ts +59 -0
- package/dist/capture/linear-encoding.d.ts.map +1 -0
- package/dist/capture/linear-encoding.js +98 -0
- package/dist/capture/linear-encoding.js.map +1 -0
- package/dist/capture/photographic-export.d.ts +135 -0
- package/dist/capture/photographic-export.d.ts.map +1 -0
- package/dist/capture/photographic-export.js +273 -0
- package/dist/capture/photographic-export.js.map +1 -0
- package/dist/capture/raw-frame-limits.d.ts +12 -0
- package/dist/capture/raw-frame-limits.d.ts.map +1 -0
- package/dist/capture/raw-frame-limits.js +13 -0
- package/dist/capture/raw-frame-limits.js.map +1 -0
- package/dist/capture/raw-frame-reconstruction.d.ts +48 -0
- package/dist/capture/raw-frame-reconstruction.d.ts.map +1 -0
- package/dist/capture/raw-frame-reconstruction.js +146 -0
- package/dist/capture/raw-frame-reconstruction.js.map +1 -0
- package/dist/capture/release-sequence.d.ts +120 -0
- package/dist/capture/release-sequence.d.ts.map +1 -0
- package/dist/capture/release-sequence.js +446 -0
- package/dist/capture/release-sequence.js.map +1 -0
- package/dist/capture/sensor-raw-frame.d.ts +34 -0
- package/dist/capture/sensor-raw-frame.d.ts.map +1 -0
- package/dist/capture/sensor-raw-frame.js +106 -0
- package/dist/capture/sensor-raw-frame.js.map +1 -0
- package/dist/capture/sensor-raw-producer.d.ts +51 -0
- package/dist/capture/sensor-raw-producer.d.ts.map +1 -0
- package/dist/capture/sensor-raw-producer.js +235 -0
- package/dist/capture/sensor-raw-producer.js.map +1 -0
- package/dist/capture/simulated-capture.d.ts +125 -0
- package/dist/capture/simulated-capture.d.ts.map +1 -0
- package/dist/capture/simulated-capture.js +248 -0
- package/dist/capture/simulated-capture.js.map +1 -0
- package/dist/color/capture-color.d.ts +73 -0
- package/dist/color/capture-color.d.ts.map +1 -0
- package/dist/color/capture-color.js +145 -0
- package/dist/color/capture-color.js.map +1 -0
- package/dist/color/sensor-color-development.d.ts +23 -0
- package/dist/color/sensor-color-development.d.ts.map +1 -0
- package/dist/color/sensor-color-development.js +56 -0
- package/dist/color/sensor-color-development.js.map +1 -0
- package/dist/color/white-balance.d.ts +175 -0
- package/dist/color/white-balance.d.ts.map +1 -0
- package/dist/color/white-balance.js +606 -0
- package/dist/color/white-balance.js.map +1 -0
- package/dist/composition/image-formation-plan.d.ts +481 -0
- package/dist/composition/image-formation-plan.d.ts.map +1 -0
- package/dist/composition/image-formation-plan.js +2499 -0
- package/dist/composition/image-formation-plan.js.map +1 -0
- package/dist/composition/plan-consumer.d.ts +53 -0
- package/dist/composition/plan-consumer.d.ts.map +1 -0
- package/dist/composition/plan-consumer.js +119 -0
- package/dist/composition/plan-consumer.js.map +1 -0
- package/dist/core/calculation-result.d.ts.map +1 -1
- package/dist/core/calculation-result.js +6 -0
- package/dist/core/calculation-result.js.map +1 -1
- package/dist/core/canonical-json.d.ts +18 -0
- package/dist/core/canonical-json.d.ts.map +1 -0
- package/dist/core/canonical-json.js +44 -0
- package/dist/core/canonical-json.js.map +1 -0
- package/dist/core/configuration-error.d.ts +6 -0
- package/dist/core/configuration-error.d.ts.map +1 -1
- package/dist/core/configuration-error.js +6 -0
- package/dist/core/configuration-error.js.map +1 -1
- package/dist/core/evidence-provenance.d.ts +6 -0
- package/dist/core/evidence-provenance.d.ts.map +1 -1
- package/dist/core/evidence-provenance.js +7 -0
- package/dist/core/evidence-provenance.js.map +1 -1
- package/dist/core/image-formation.d.ts +9 -3
- package/dist/core/image-formation.d.ts.map +1 -1
- package/dist/core/image-formation.js +29 -5
- package/dist/core/image-formation.js.map +1 -1
- package/dist/core/owned-data.d.ts +25 -0
- package/dist/core/owned-data.d.ts.map +1 -0
- package/dist/core/owned-data.js +34 -0
- package/dist/core/owned-data.js.map +1 -0
- package/dist/core/record-validation.d.ts +17 -0
- package/dist/core/record-validation.d.ts.map +1 -0
- package/dist/core/record-validation.js +44 -0
- package/dist/core/record-validation.js.map +1 -0
- package/dist/core/scientific-assurance.d.ts +101 -0
- package/dist/core/scientific-assurance.d.ts.map +1 -0
- package/dist/core/scientific-assurance.js +301 -0
- package/dist/core/scientific-assurance.js.map +1 -0
- package/dist/core/spectral-composition.d.ts +106 -0
- package/dist/core/spectral-composition.d.ts.map +1 -0
- package/dist/core/spectral-composition.js +334 -0
- package/dist/core/spectral-composition.js.map +1 -0
- package/dist/core/spectral.d.ts +34 -0
- package/dist/core/spectral.d.ts.map +1 -0
- package/dist/core/spectral.js +57 -0
- package/dist/core/spectral.js.map +1 -0
- package/dist/core/validation.d.ts +6 -0
- package/dist/core/validation.d.ts.map +1 -1
- package/dist/core/validation.js +6 -0
- package/dist/core/validation.js.map +1 -1
- package/dist/core/version.d.ts +14 -0
- package/dist/core/version.d.ts.map +1 -0
- package/dist/core/version.js +15 -0
- package/dist/core/version.js.map +1 -0
- package/dist/equipment/exposure-capabilities.d.ts +125 -0
- package/dist/equipment/exposure-capabilities.d.ts.map +1 -0
- package/dist/equipment/exposure-capabilities.js +391 -0
- package/dist/equipment/exposure-capabilities.js.map +1 -0
- package/dist/equipment/generic-tier-assets.d.ts +82 -0
- package/dist/equipment/generic-tier-assets.d.ts.map +1 -0
- package/dist/equipment/generic-tier-assets.js +119 -0
- package/dist/equipment/generic-tier-assets.js.map +1 -0
- package/dist/equipment/generic-tier-presets.d.ts +57 -0
- package/dist/equipment/generic-tier-presets.d.ts.map +1 -0
- package/dist/equipment/generic-tier-presets.js +122 -0
- package/dist/equipment/generic-tier-presets.js.map +1 -0
- package/dist/equipment/iso-capabilities.d.ts +143 -0
- package/dist/equipment/iso-capabilities.d.ts.map +1 -0
- package/dist/equipment/iso-capabilities.js +578 -0
- package/dist/equipment/iso-capabilities.js.map +1 -0
- package/dist/equipment/metering-capabilities.d.ts +58 -0
- package/dist/equipment/metering-capabilities.d.ts.map +1 -0
- package/dist/equipment/metering-capabilities.js +151 -0
- package/dist/equipment/metering-capabilities.js.map +1 -0
- package/dist/equipment/release-capabilities.d.ts +33 -0
- package/dist/equipment/release-capabilities.d.ts.map +1 -0
- package/dist/equipment/release-capabilities.js +176 -0
- package/dist/equipment/release-capabilities.js.map +1 -0
- package/dist/exposure/exposure-duration-control.d.ts +72 -0
- package/dist/exposure/exposure-duration-control.d.ts.map +1 -0
- package/dist/exposure/exposure-duration-control.js +161 -0
- package/dist/exposure/exposure-duration-control.js.map +1 -0
- package/dist/exposure/exposure-mode-resolver.d.ts +637 -0
- package/dist/exposure/exposure-mode-resolver.d.ts.map +1 -0
- package/dist/exposure/exposure-mode-resolver.js +1905 -0
- package/dist/exposure/exposure-mode-resolver.js.map +1 -0
- package/dist/exposure/exposure.d.ts +8 -0
- package/dist/exposure/exposure.d.ts.map +1 -1
- package/dist/exposure/exposure.js +8 -0
- package/dist/exposure/exposure.js.map +1 -1
- package/dist/exposure/flash.d.ts +179 -0
- package/dist/exposure/flash.d.ts.map +1 -0
- package/dist/exposure/flash.js +644 -0
- package/dist/exposure/flash.js.map +1 -0
- package/dist/exposure/metering-scene-radiance.d.ts +72 -0
- package/dist/exposure/metering-scene-radiance.d.ts.map +1 -0
- package/dist/exposure/metering-scene-radiance.js +222 -0
- package/dist/exposure/metering-scene-radiance.js.map +1 -0
- package/dist/exposure/metering-target.d.ts +67 -0
- package/dist/exposure/metering-target.d.ts.map +1 -0
- package/dist/exposure/metering-target.js +265 -0
- package/dist/exposure/metering-target.js.map +1 -0
- package/dist/exposure/metering-temporal.d.ts +76 -0
- package/dist/exposure/metering-temporal.d.ts.map +1 -0
- package/dist/exposure/metering-temporal.js +210 -0
- package/dist/exposure/metering-temporal.js.map +1 -0
- package/dist/exposure/metering.d.ts +124 -0
- package/dist/exposure/metering.d.ts.map +1 -0
- package/dist/exposure/metering.js +422 -0
- package/dist/exposure/metering.js.map +1 -0
- package/dist/exposure/program-line.d.ts +29 -0
- package/dist/exposure/program-line.d.ts.map +1 -0
- package/dist/exposure/program-line.js +126 -0
- package/dist/exposure/program-line.js.map +1 -0
- package/dist/index.d.ts +87 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +85 -6
- package/dist/index.js.map +1 -1
- package/dist/motion/camera-rotation.d.ts +16 -0
- package/dist/motion/camera-rotation.d.ts.map +1 -1
- package/dist/motion/camera-rotation.js +16 -0
- package/dist/motion/camera-rotation.js.map +1 -1
- package/dist/motion/capture-rotation-inverse-mapping.d.ts +13 -0
- package/dist/motion/capture-rotation-inverse-mapping.d.ts.map +1 -1
- package/dist/motion/capture-rotation-inverse-mapping.js +13 -0
- package/dist/motion/capture-rotation-inverse-mapping.js.map +1 -1
- package/dist/motion/capture-rotation-temporal-quadrature.d.ts +15 -0
- package/dist/motion/capture-rotation-temporal-quadrature.d.ts.map +1 -1
- package/dist/motion/capture-rotation-temporal-quadrature.js +15 -0
- package/dist/motion/capture-rotation-temporal-quadrature.js.map +1 -1
- package/dist/motion/capture-rotation-trajectory.d.ts +15 -0
- package/dist/motion/capture-rotation-trajectory.d.ts.map +1 -1
- package/dist/motion/capture-rotation-trajectory.js +15 -0
- package/dist/motion/capture-rotation-trajectory.js.map +1 -1
- package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts +119 -0
- package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts.map +1 -0
- package/dist/motion/capture-translation-parallax-temporal-quadrature.js +263 -0
- package/dist/motion/capture-translation-parallax-temporal-quadrature.js.map +1 -0
- package/dist/motion/extended-object-projection.d.ts +175 -0
- package/dist/motion/extended-object-projection.d.ts.map +1 -0
- package/dist/motion/extended-object-projection.js +402 -0
- package/dist/motion/extended-object-projection.js.map +1 -0
- package/dist/motion/projected-motion.d.ts +11 -0
- package/dist/motion/projected-motion.d.ts.map +1 -1
- package/dist/motion/projected-motion.js +11 -0
- package/dist/motion/projected-motion.js.map +1 -1
- package/dist/optics/aperture.d.ts +9 -0
- package/dist/optics/aperture.d.ts.map +1 -1
- package/dist/optics/aperture.js +9 -0
- package/dist/optics/aperture.js.map +1 -1
- package/dist/optics/circle-of-confusion.d.ts +8 -0
- package/dist/optics/circle-of-confusion.d.ts.map +1 -1
- package/dist/optics/circle-of-confusion.js +8 -0
- package/dist/optics/circle-of-confusion.js.map +1 -1
- package/dist/optics/complex-pupil-psf.d.ts +128 -0
- package/dist/optics/complex-pupil-psf.d.ts.map +1 -0
- package/dist/optics/complex-pupil-psf.js +462 -0
- package/dist/optics/complex-pupil-psf.js.map +1 -0
- package/dist/optics/depth-of-field.d.ts +18 -0
- package/dist/optics/depth-of-field.d.ts.map +1 -1
- package/dist/optics/depth-of-field.js +29 -4
- package/dist/optics/depth-of-field.js.map +1 -1
- package/dist/optics/diffraction.d.ts +8 -0
- package/dist/optics/diffraction.d.ts.map +1 -1
- package/dist/optics/diffraction.js +8 -0
- package/dist/optics/diffraction.js.map +1 -1
- package/dist/optics/focus-breathing.d.ts +13 -0
- package/dist/optics/focus-breathing.d.ts.map +1 -1
- package/dist/optics/focus-breathing.js +13 -0
- package/dist/optics/focus-breathing.js.map +1 -1
- package/dist/optics/focus-state.d.ts +47 -0
- package/dist/optics/focus-state.d.ts.map +1 -0
- package/dist/optics/focus-state.js +78 -0
- package/dist/optics/focus-state.js.map +1 -0
- package/dist/optics/front-of-lens-filter.d.ts +114 -0
- package/dist/optics/front-of-lens-filter.d.ts.map +1 -0
- package/dist/optics/front-of-lens-filter.js +468 -0
- package/dist/optics/front-of-lens-filter.js.map +1 -0
- package/dist/optics/illumination-vignetting.d.ts +9 -0
- package/dist/optics/illumination-vignetting.d.ts.map +1 -1
- package/dist/optics/illumination-vignetting.js +9 -0
- package/dist/optics/illumination-vignetting.js.map +1 -1
- package/dist/optics/lateral-chromatic-aberration.d.ts +11 -0
- package/dist/optics/lateral-chromatic-aberration.d.ts.map +1 -1
- package/dist/optics/lateral-chromatic-aberration.js +11 -0
- package/dist/optics/lateral-chromatic-aberration.js.map +1 -1
- package/dist/optics/lens-psf-profile.d.ts +217 -0
- package/dist/optics/lens-psf-profile.d.ts.map +1 -0
- package/dist/optics/lens-psf-profile.js +823 -0
- package/dist/optics/lens-psf-profile.js.map +1 -0
- package/dist/optics/polygon-diffraction.d.ts +67 -0
- package/dist/optics/polygon-diffraction.d.ts.map +1 -0
- package/dist/optics/polygon-diffraction.js +145 -0
- package/dist/optics/polygon-diffraction.js.map +1 -0
- package/dist/optics/profile-contract.d.ts +42 -0
- package/dist/optics/profile-contract.d.ts.map +1 -0
- package/dist/optics/profile-contract.js +92 -0
- package/dist/optics/profile-contract.js.map +1 -0
- package/dist/optics/psf-foundation.d.ts +16 -3
- package/dist/optics/psf-foundation.d.ts.map +1 -1
- package/dist/optics/psf-foundation.js +28 -15
- package/dist/optics/psf-foundation.js.map +1 -1
- package/dist/optics/radial-distortion.d.ts +18 -0
- package/dist/optics/radial-distortion.d.ts.map +1 -1
- package/dist/optics/radial-distortion.js +18 -0
- package/dist/optics/radial-distortion.js.map +1 -1
- package/dist/optics/scene-to-sensor-irradiance.d.ts +213 -0
- package/dist/optics/scene-to-sensor-irradiance.d.ts.map +1 -0
- package/dist/optics/scene-to-sensor-irradiance.js +662 -0
- package/dist/optics/scene-to-sensor-irradiance.js.map +1 -0
- package/dist/optics/scene-to-sensor-quadrature.d.ts +63 -0
- package/dist/optics/scene-to-sensor-quadrature.d.ts.map +1 -0
- package/dist/optics/scene-to-sensor-quadrature.js +82 -0
- package/dist/optics/scene-to-sensor-quadrature.js.map +1 -0
- package/dist/optics/sensor-environment-query.d.ts +60 -0
- package/dist/optics/sensor-environment-query.d.ts.map +1 -0
- package/dist/optics/sensor-environment-query.js +50 -0
- package/dist/optics/sensor-environment-query.js.map +1 -0
- package/dist/optics/sensor-psf-quadrature.d.ts +70 -0
- package/dist/optics/sensor-psf-quadrature.d.ts.map +1 -0
- package/dist/optics/sensor-psf-quadrature.js +101 -0
- package/dist/optics/sensor-psf-quadrature.js.map +1 -0
- package/dist/optics/sensor-psf-support.d.ts +20 -0
- package/dist/optics/sensor-psf-support.d.ts.map +1 -0
- package/dist/optics/sensor-psf-support.js +13 -0
- package/dist/optics/sensor-psf-support.js.map +1 -0
- package/dist/optics/stray-light.d.ts +91 -0
- package/dist/optics/stray-light.d.ts.map +1 -0
- package/dist/optics/stray-light.js +110 -0
- package/dist/optics/stray-light.js.map +1 -0
- package/dist/optics/thin-lens.d.ts +8 -0
- package/dist/optics/thin-lens.d.ts.map +1 -1
- package/dist/optics/thin-lens.js +8 -0
- package/dist/optics/thin-lens.js.map +1 -1
- package/dist/output/capture-corrected-sdr.d.ts +49 -0
- package/dist/output/capture-corrected-sdr.d.ts.map +1 -0
- package/dist/output/capture-corrected-sdr.js +149 -0
- package/dist/output/capture-corrected-sdr.js.map +1 -0
- package/dist/output/capture-geometry.d.ts.map +1 -1
- package/dist/output/capture-geometry.js +8 -0
- package/dist/output/capture-geometry.js.map +1 -1
- package/dist/output/capture-sdr.d.ts +49 -0
- package/dist/output/capture-sdr.d.ts.map +1 -0
- package/dist/output/capture-sdr.js +90 -0
- package/dist/output/capture-sdr.js.map +1 -0
- package/dist/output/crop.d.ts +6 -0
- package/dist/output/crop.d.ts.map +1 -1
- package/dist/output/crop.js +6 -0
- package/dist/output/crop.js.map +1 -1
- package/dist/output/geometric-transforms.d.ts +137 -0
- package/dist/output/geometric-transforms.d.ts.map +1 -0
- package/dist/output/geometric-transforms.js +225 -0
- package/dist/output/geometric-transforms.js.map +1 -0
- package/dist/output/lens-corrections.d.ts +121 -0
- package/dist/output/lens-corrections.d.ts.map +1 -0
- package/dist/output/lens-corrections.js +210 -0
- package/dist/output/lens-corrections.js.map +1 -0
- package/dist/output/sdr-rendering.d.ts +81 -0
- package/dist/output/sdr-rendering.d.ts.map +1 -0
- package/dist/output/sdr-rendering.js +106 -0
- package/dist/output/sdr-rendering.js.map +1 -0
- package/dist/output/subject-framing-crop.d.ts +8 -0
- package/dist/output/subject-framing-crop.d.ts.map +1 -1
- package/dist/output/subject-framing-crop.js +8 -0
- package/dist/output/subject-framing-crop.js.map +1 -1
- package/dist/schema/camera.d.ts +6 -0
- package/dist/schema/camera.d.ts.map +1 -1
- package/dist/schema/illumination-spectral.d.ts +51 -0
- package/dist/schema/illumination-spectral.d.ts.map +1 -0
- package/dist/schema/illumination-spectral.js +132 -0
- package/dist/schema/illumination-spectral.js.map +1 -0
- package/dist/schema/illumination-temporal.d.ts +156 -0
- package/dist/schema/illumination-temporal.d.ts.map +1 -0
- package/dist/schema/illumination-temporal.js +554 -0
- package/dist/schema/illumination-temporal.js.map +1 -0
- package/dist/schema/illumination.d.ts +138 -0
- package/dist/schema/illumination.d.ts.map +1 -0
- package/dist/schema/illumination.js +483 -0
- package/dist/schema/illumination.js.map +1 -0
- package/dist/schema/scene-radiance-temporal.d.ts +107 -0
- package/dist/schema/scene-radiance-temporal.d.ts.map +1 -0
- package/dist/schema/scene-radiance-temporal.js +259 -0
- package/dist/schema/scene-radiance-temporal.js.map +1 -0
- package/dist/schema/scene-radiance.d.ts +185 -0
- package/dist/schema/scene-radiance.d.ts.map +1 -0
- package/dist/schema/scene-radiance.js +535 -0
- package/dist/schema/scene-radiance.js.map +1 -0
- package/dist/schema/scene.d.ts +7 -0
- package/dist/schema/scene.d.ts.map +1 -1
- package/dist/schema/validation.d.ts.map +1 -1
- package/dist/schema/validation.js +7 -0
- package/dist/schema/validation.js.map +1 -1
- package/dist/sensor/accumulated-charge.d.ts +199 -0
- package/dist/sensor/accumulated-charge.d.ts.map +1 -0
- package/dist/sensor/accumulated-charge.js +450 -0
- package/dist/sensor/accumulated-charge.js.map +1 -0
- package/dist/sensor/architecture.d.ts +48 -13
- package/dist/sensor/architecture.d.ts.map +1 -1
- package/dist/sensor/architecture.js +58 -16
- package/dist/sensor/architecture.js.map +1 -1
- package/dist/sensor/camera-saturation-capacity.d.ts +138 -0
- package/dist/sensor/camera-saturation-capacity.d.ts.map +1 -0
- package/dist/sensor/camera-saturation-capacity.js +356 -0
- package/dist/sensor/camera-saturation-capacity.js.map +1 -0
- package/dist/sensor/capture-color-sampling-binding.d.ts +1 -0
- package/dist/sensor/capture-color-sampling-binding.d.ts.map +1 -1
- package/dist/sensor/capture-color-sampling-binding.js +14 -0
- package/dist/sensor/capture-color-sampling-binding.js.map +1 -1
- package/dist/sensor/capture-mode-timing.d.ts +63 -0
- package/dist/sensor/capture-mode-timing.d.ts.map +1 -0
- package/dist/sensor/capture-mode-timing.js +270 -0
- package/dist/sensor/capture-mode-timing.js.map +1 -0
- package/dist/sensor/capture-mode.d.ts.map +1 -1
- package/dist/sensor/capture-mode.js +13 -0
- package/dist/sensor/capture-mode.js.map +1 -1
- package/dist/sensor/color-sampling.d.ts.map +1 -1
- package/dist/sensor/color-sampling.js +19 -0
- package/dist/sensor/color-sampling.js.map +1 -1
- package/dist/sensor/constant-rate-temporal-integration.d.ts +126 -0
- package/dist/sensor/constant-rate-temporal-integration.d.ts.map +1 -0
- package/dist/sensor/constant-rate-temporal-integration.js +382 -0
- package/dist/sensor/constant-rate-temporal-integration.js.map +1 -0
- package/dist/sensor/dark-current.d.ts +169 -0
- package/dist/sensor/dark-current.d.ts.map +1 -0
- package/dist/sensor/dark-current.js +427 -0
- package/dist/sensor/dark-current.js.map +1 -0
- package/dist/sensor/environment-photo-signal.d.ts +123 -0
- package/dist/sensor/environment-photo-signal.d.ts.map +1 -0
- package/dist/sensor/environment-photo-signal.js +186 -0
- package/dist/sensor/environment-photo-signal.js.map +1 -0
- package/dist/sensor/eqe-electron-rate.d.ts +107 -0
- package/dist/sensor/eqe-electron-rate.d.ts.map +1 -0
- package/dist/sensor/eqe-electron-rate.js +561 -0
- package/dist/sensor/eqe-electron-rate.js.map +1 -0
- package/dist/sensor/eqe-local-exposure.d.ts +65 -0
- package/dist/sensor/eqe-local-exposure.d.ts.map +1 -0
- package/dist/sensor/eqe-local-exposure.js +84 -0
- package/dist/sensor/eqe-local-exposure.js.map +1 -0
- package/dist/sensor/eqe-temporal-exposure.d.ts +55 -0
- package/dist/sensor/eqe-temporal-exposure.d.ts.map +1 -0
- package/dist/sensor/eqe-temporal-exposure.js +62 -0
- package/dist/sensor/eqe-temporal-exposure.js.map +1 -0
- package/dist/sensor/exposure-window.d.ts +14 -0
- package/dist/sensor/exposure-window.d.ts.map +1 -1
- package/dist/sensor/exposure-window.js +14 -0
- package/dist/sensor/exposure-window.js.map +1 -1
- package/dist/sensor/iso-signal-chain.d.ts +148 -0
- package/dist/sensor/iso-signal-chain.d.ts.map +1 -0
- package/dist/sensor/iso-signal-chain.js +411 -0
- package/dist/sensor/iso-signal-chain.js.map +1 -0
- package/dist/sensor/local-exposure-binding.d.ts +87 -0
- package/dist/sensor/local-exposure-binding.d.ts.map +1 -0
- package/dist/sensor/local-exposure-binding.js +214 -0
- package/dist/sensor/local-exposure-binding.js.map +1 -0
- package/dist/sensor/optical-stack.d.ts.map +1 -1
- package/dist/sensor/optical-stack.js +17 -0
- package/dist/sensor/optical-stack.js.map +1 -1
- package/dist/sensor/photon-energy.d.ts +97 -0
- package/dist/sensor/photon-energy.d.ts.map +1 -0
- package/dist/sensor/photon-energy.js +390 -0
- package/dist/sensor/photon-energy.js.map +1 -0
- package/dist/sensor/physical-charge-capacity.d.ts +130 -0
- package/dist/sensor/physical-charge-capacity.d.ts.map +1 -0
- package/dist/sensor/physical-charge-capacity.js +345 -0
- package/dist/sensor/physical-charge-capacity.js.map +1 -0
- package/dist/sensor/pixel-pitch.d.ts +6 -0
- package/dist/sensor/pixel-pitch.d.ts.map +1 -1
- package/dist/sensor/pixel-pitch.js +6 -0
- package/dist/sensor/pixel-pitch.js.map +1 -1
- package/dist/sensor/radiometry-readiness.d.ts +10 -0
- package/dist/sensor/radiometry-readiness.d.ts.map +1 -1
- package/dist/sensor/radiometry-readiness.js +10 -0
- package/dist/sensor/radiometry-readiness.js.map +1 -1
- package/dist/sensor/raw-readout.d.ts +314 -0
- package/dist/sensor/raw-readout.d.ts.map +1 -0
- package/dist/sensor/raw-readout.js +914 -0
- package/dist/sensor/raw-readout.js.map +1 -0
- package/dist/sensor/raw-reconstruction.d.ts +170 -0
- package/dist/sensor/raw-reconstruction.d.ts.map +1 -0
- package/dist/sensor/raw-reconstruction.js +424 -0
- package/dist/sensor/raw-reconstruction.js.map +1 -0
- package/dist/sensor/readout-exposure-linkage.d.ts +12 -0
- package/dist/sensor/readout-exposure-linkage.d.ts.map +1 -1
- package/dist/sensor/readout-exposure-linkage.js +12 -0
- package/dist/sensor/readout-exposure-linkage.js.map +1 -1
- package/dist/sensor/readout-timing.d.ts +13 -0
- package/dist/sensor/readout-timing.d.ts.map +1 -1
- package/dist/sensor/readout-timing.js +13 -0
- package/dist/sensor/readout-timing.js.map +1 -1
- package/dist/sensor/response-application-compatibility.d.ts +136 -0
- package/dist/sensor/response-application-compatibility.d.ts.map +1 -0
- package/dist/sensor/response-application-compatibility.js +408 -0
- package/dist/sensor/response-application-compatibility.js.map +1 -0
- package/dist/sensor/response-operating-range.d.ts +173 -0
- package/dist/sensor/response-operating-range.d.ts.map +1 -0
- package/dist/sensor/response-operating-range.js +672 -0
- package/dist/sensor/response-operating-range.js.map +1 -0
- package/dist/sensor/responsivity-photocurrent.d.ts +158 -0
- package/dist/sensor/responsivity-photocurrent.d.ts.map +1 -0
- package/dist/sensor/responsivity-photocurrent.js +644 -0
- package/dist/sensor/responsivity-photocurrent.js.map +1 -0
- package/dist/sensor/sampling-aperture.d.ts.map +1 -1
- package/dist/sensor/sampling-aperture.js +14 -0
- package/dist/sensor/sampling-aperture.js.map +1 -1
- package/dist/sensor/scene-eqe-temporal-exposure.d.ts +45 -0
- package/dist/sensor/scene-eqe-temporal-exposure.d.ts.map +1 -0
- package/dist/sensor/scene-eqe-temporal-exposure.js +64 -0
- package/dist/sensor/scene-eqe-temporal-exposure.js.map +1 -0
- package/dist/sensor/sensor-geometry.d.ts +12 -0
- package/dist/sensor/sensor-geometry.d.ts.map +1 -1
- package/dist/sensor/sensor-geometry.js +12 -0
- package/dist/sensor/sensor-geometry.js.map +1 -1
- package/dist/sensor/signal-noise.d.ts +10 -0
- package/dist/sensor/signal-noise.d.ts.map +1 -1
- package/dist/sensor/signal-noise.js +10 -0
- package/dist/sensor/signal-noise.js.map +1 -1
- package/dist/sensor/spatial-sample-reduction.d.ts +44 -1
- package/dist/sensor/spatial-sample-reduction.d.ts.map +1 -1
- package/dist/sensor/spatial-sample-reduction.js +51 -5
- package/dist/sensor/spatial-sample-reduction.js.map +1 -1
- package/dist/sensor/spatial-sampling-quadrature.d.ts +24 -0
- package/dist/sensor/spatial-sampling-quadrature.d.ts.map +1 -1
- package/dist/sensor/spatial-sampling-quadrature.js +27 -0
- package/dist/sensor/spatial-sampling-quadrature.js.map +1 -1
- package/dist/sensor/spatio-spectral-reduction.d.ts +187 -0
- package/dist/sensor/spatio-spectral-reduction.d.ts.map +1 -0
- package/dist/sensor/spatio-spectral-reduction.js +373 -0
- package/dist/sensor/spatio-spectral-reduction.js.map +1 -0
- package/dist/sensor/spectral-coverage.d.ts +24 -0
- package/dist/sensor/spectral-coverage.d.ts.map +1 -0
- package/dist/sensor/spectral-coverage.js +86 -0
- package/dist/sensor/spectral-coverage.js.map +1 -0
- package/dist/sensor/spectral-quadrature.d.ts +169 -0
- package/dist/sensor/spectral-quadrature.d.ts.map +1 -0
- package/dist/sensor/spectral-quadrature.js +542 -0
- package/dist/sensor/spectral-quadrature.js.map +1 -0
- package/dist/sensor/spectral-response.d.ts +192 -0
- package/dist/sensor/spectral-response.d.ts.map +1 -0
- package/dist/sensor/spectral-response.js +664 -0
- package/dist/sensor/spectral-response.js.map +1 -0
- package/dist/sensor/temporal-eqe-sum.d.ts +15 -0
- package/dist/sensor/temporal-eqe-sum.d.ts.map +1 -0
- package/dist/sensor/temporal-eqe-sum.js +30 -0
- package/dist/sensor/temporal-eqe-sum.js.map +1 -0
- package/dist/sensor/temporal-photo-signal.d.ts +38 -0
- package/dist/sensor/temporal-photo-signal.d.ts.map +1 -0
- package/dist/sensor/temporal-photo-signal.js +110 -0
- package/dist/sensor/temporal-photo-signal.js.map +1 -0
- package/dist/sensor/temporal-sample-binding.d.ts +6 -0
- package/dist/sensor/temporal-sample-binding.d.ts.map +1 -0
- package/dist/sensor/temporal-sample-binding.js +32 -0
- package/dist/sensor/temporal-sample-binding.js.map +1 -0
- package/dist/simulation/poc-simulation.d.ts.map +1 -1
- package/dist/simulation/poc-simulation.js +34 -11
- package/dist/simulation/poc-simulation.js.map +1 -1
- package/dist/stabilization/camera-shake.d.ts +11 -0
- package/dist/stabilization/camera-shake.d.ts.map +1 -1
- package/dist/stabilization/camera-shake.js +11 -0
- package/dist/stabilization/camera-shake.js.map +1 -1
- package/dist/stabilization/system.d.ts +218 -0
- package/dist/stabilization/system.d.ts.map +1 -0
- package/dist/stabilization/system.js +695 -0
- package/dist/stabilization/system.js.map +1 -0
- package/docs/API_REFERENCE.md +2017 -0
- package/docs/API_STYLE.md +132 -0
- package/docs/ARCHITECTURE.md +134 -24
- package/docs/AUTOMATION_COORDINATION.md +2 -0
- package/docs/CAPTURE_COLOR.md +25 -0
- package/docs/CAPTURE_CORRECTED_SDR.md +25 -0
- package/docs/CAPTURE_EXPORT_METADATA.md +27 -0
- package/docs/CAPTURE_SDR.md +20 -0
- package/docs/DEVELOPERS.md +60 -0
- package/docs/DIGITAL_OPTICS_FOUNDATION.md +69 -0
- package/docs/ENVIRONMENT_RAW_CAPTURE.md +187 -0
- package/docs/EXPORT_ACCEPTANCE.md +133 -0
- package/docs/GENERIC_TIER_PRESETS.md +269 -0
- package/docs/GEOMETRIC_PREPARATION_REUSE.md +141 -0
- package/docs/IMAGE_FORMATION.md +80 -10
- package/docs/LINEAR_CAPTURE_ENCODING.md +25 -0
- package/docs/MOTION_AND_SIGNAL.md +5 -3
- package/docs/NUMERICAL_CORRECTNESS.md +191 -0
- package/docs/PERFORMANCE_BASELINE.md +56 -0
- package/docs/PHOTOGRAPHIC_EXPORT.md +206 -0
- package/docs/PHYSICS_FOUNDATION.md +152 -5
- package/docs/POC_API.md +2 -0
- package/docs/POC_PROJECTION_REUSE.md +124 -0
- package/docs/PROCESSED_OUTPUT.md +157 -0
- package/docs/PRODUCTION_COMPOSITION.md +373 -0
- package/docs/PRODUCTION_ENVIRONMENT_CAPTURE.md +131 -0
- package/docs/PROVENANCE.md +4 -0
- package/docs/PSF_FOUNDATION.md +110 -88
- package/docs/RAW_FRAME_ENVELOPE.md +56 -0
- package/docs/RAW_FRAME_RECONSTRUCTION.md +30 -0
- package/docs/RELEASE_1_0.md +65 -0
- package/docs/RELEASE_AUDIT.md +38 -0
- package/docs/SCENE_RADIANCE_AND_ILLUMINATION.md +298 -0
- package/docs/SCENE_SENSOR_QUADRATURE.md +98 -0
- package/docs/SCENE_SENSOR_TEMPORAL_EXPOSURE.md +86 -0
- package/docs/SCIENTIFIC_ASSURANCE.md +280 -0
- package/docs/SCIENTIFIC_CONFORMANCE.md +83 -0
- package/docs/SDR_RENDERING.md +33 -0
- package/docs/SENSOR_ENVIRONMENT_QUERY.md +86 -0
- package/docs/SENSOR_EQE_LOCAL_EXPOSURE.md +104 -0
- package/docs/SENSOR_EQE_TEMPORAL_EXPOSURE.md +74 -0
- package/docs/SENSOR_PSF_QUADRATURE.md +90 -0
- package/docs/SENSOR_RAW_FRAME.md +20 -0
- package/docs/SENSOR_RAW_PRODUCER.md +77 -0
- package/docs/SIGNAL_CONFORMANCE.md +23 -0
- package/docs/SIMULATED_CAPTURE.md +65 -0
- package/docs/STABILIZATION.md +160 -17
- package/docs/TEMPORAL_PHOTO_RAW.md +83 -0
- package/docs/TIER_ACCEPTANCE.md +129 -0
- package/docs/TIER_PRESET_ACCEPTANCE.md +59 -0
- package/docs/USAGE.md +5050 -1047
- package/docs/V1_COMPOSITION_MAP.md +123 -0
- package/docs/V1_HELPER_REUSE_REVIEW.md +60 -0
- package/docs/V1_PERFORMANCE_DISPOSITION.md +88 -0
- package/docs/api/camera-equivalent-focal-length.md +53 -0
- package/docs/api/camera-field-of-view.md +119 -0
- package/docs/api/camera-projected-object-size.md +54 -0
- package/docs/api/capture-capture-export-metadata.md +107 -0
- package/docs/api/capture-environment-raw-producer.md +56 -0
- package/docs/api/capture-focus-control.md +419 -0
- package/docs/api/capture-linear-encoding.md +99 -0
- package/docs/api/capture-photographic-export.md +172 -0
- package/docs/api/capture-raw-frame-reconstruction.md +87 -0
- package/docs/api/capture-release-sequence.md +252 -0
- package/docs/api/capture-sensor-raw-frame.md +66 -0
- package/docs/api/capture-sensor-raw-producer.md +98 -0
- package/docs/api/capture-simulated-capture.md +179 -0
- package/docs/api/color-capture-color.md +122 -0
- package/docs/api/color-white-balance.md +386 -0
- package/docs/api/composition-image-formation-plan.md +825 -0
- package/docs/api/composition-plan-consumer.md +98 -0
- package/docs/api/core-calculation-result.md +220 -0
- package/docs/api/core-configuration-error.md +19 -0
- package/docs/api/core-image-formation.md +204 -0
- package/docs/api/core-scientific-assurance.md +214 -0
- package/docs/api/core-spectral-composition.md +268 -0
- package/docs/api/core-spectral.md +78 -0
- package/docs/api/core-validation.md +34 -0
- package/docs/api/core-version.md +14 -0
- package/docs/api/equipment-exposure-capabilities.md +270 -0
- package/docs/api/equipment-generic-tier-assets.md +82 -0
- package/docs/api/equipment-generic-tier-presets.md +103 -0
- package/docs/api/equipment-iso-capabilities.md +295 -0
- package/docs/api/equipment-metering-capabilities.md +126 -0
- package/docs/api/equipment-release-capabilities.md +91 -0
- package/docs/api/exports.json +5656 -0
- package/docs/api/exposure-exposure-duration-control.md +115 -0
- package/docs/api/exposure-exposure-mode-resolver.md +966 -0
- package/docs/api/exposure-exposure.md +150 -0
- package/docs/api/exposure-flash.md +327 -0
- package/docs/api/exposure-metering-scene-radiance.md +154 -0
- package/docs/api/exposure-metering-target.md +134 -0
- package/docs/api/exposure-metering-temporal.md +77 -0
- package/docs/api/exposure-metering.md +172 -0
- package/docs/api/exposure-program-line.md +64 -0
- package/docs/api/motion-camera-rotation.md +215 -0
- package/docs/api/motion-capture-rotation-inverse-mapping.md +128 -0
- package/docs/api/motion-capture-rotation-temporal-quadrature.md +127 -0
- package/docs/api/motion-capture-rotation-trajectory.md +132 -0
- package/docs/api/motion-capture-translation-parallax-temporal-quadrature.md +171 -0
- package/docs/api/motion-extended-object-projection.md +312 -0
- package/docs/api/motion-projected-motion.md +60 -0
- package/docs/api/optics-aperture.md +69 -0
- package/docs/api/optics-circle-of-confusion.md +46 -0
- package/docs/api/optics-complex-pupil-psf.md +193 -0
- package/docs/api/optics-depth-of-field.md +92 -0
- package/docs/api/optics-diffraction.md +46 -0
- package/docs/api/optics-focus-breathing.md +119 -0
- package/docs/api/optics-focus-state.md +64 -0
- package/docs/api/optics-front-of-lens-filter.md +263 -0
- package/docs/api/optics-illumination-vignetting.md +95 -0
- package/docs/api/optics-lateral-chromatic-aberration.md +225 -0
- package/docs/api/optics-lens-psf-profile.md +380 -0
- package/docs/api/optics-polygon-diffraction.md +68 -0
- package/docs/api/optics-profile-contract.md +47 -0
- package/docs/api/optics-psf-foundation.md +181 -0
- package/docs/api/optics-radial-distortion.md +194 -0
- package/docs/api/optics-scene-to-sensor-irradiance.md +371 -0
- package/docs/api/optics-scene-to-sensor-quadrature.md +78 -0
- package/docs/api/optics-sensor-environment-query.md +58 -0
- package/docs/api/optics-sensor-psf-quadrature.md +81 -0
- package/docs/api/optics-stray-light.md +109 -0
- package/docs/api/optics-thin-lens.md +53 -0
- package/docs/api/output-capture-corrected-sdr.md +71 -0
- package/docs/api/output-capture-geometry.md +500 -0
- package/docs/api/output-capture-sdr.md +69 -0
- package/docs/api/output-crop.md +47 -0
- package/docs/api/output-geometric-transforms.md +199 -0
- package/docs/api/output-lens-corrections.md +162 -0
- package/docs/api/output-sdr-rendering.md +122 -0
- package/docs/api/output-subject-framing-crop.md +59 -0
- package/docs/api/schema-camera.md +84 -0
- package/docs/api/schema-illumination-spectral.md +77 -0
- package/docs/api/schema-illumination-temporal.md +289 -0
- package/docs/api/schema-illumination.md +246 -0
- package/docs/api/schema-scene-radiance-temporal.md +215 -0
- package/docs/api/schema-scene-radiance.md +415 -0
- package/docs/api/schema-scene.md +105 -0
- package/docs/api/schema-validation.md +25 -0
- package/docs/api/sensor-accumulated-charge.md +273 -0
- package/docs/api/sensor-architecture.md +155 -0
- package/docs/api/sensor-camera-saturation-capacity.md +215 -0
- package/docs/api/sensor-capture-color-sampling-binding.md +323 -0
- package/docs/api/sensor-capture-mode-timing.md +123 -0
- package/docs/api/sensor-capture-mode.md +321 -0
- package/docs/api/sensor-color-sampling.md +228 -0
- package/docs/api/sensor-constant-rate-temporal-integration.md +152 -0
- package/docs/api/sensor-dark-current.md +227 -0
- package/docs/api/sensor-environment-photo-signal.md +77 -0
- package/docs/api/sensor-eqe-electron-rate.md +166 -0
- package/docs/api/sensor-eqe-local-exposure.md +68 -0
- package/docs/api/sensor-eqe-temporal-exposure.md +73 -0
- package/docs/api/sensor-exposure-window.md +183 -0
- package/docs/api/sensor-iso-signal-chain.md +264 -0
- package/docs/api/sensor-local-exposure-binding.md +126 -0
- package/docs/api/sensor-optical-stack.md +211 -0
- package/docs/api/sensor-photon-energy.md +149 -0
- package/docs/api/sensor-physical-charge-capacity.md +196 -0
- package/docs/api/sensor-pixel-pitch.md +41 -0
- package/docs/api/sensor-radiometry-readiness.md +240 -0
- package/docs/api/sensor-raw-readout.md +499 -0
- package/docs/api/sensor-raw-reconstruction.md +260 -0
- package/docs/api/sensor-readout-exposure-linkage.md +172 -0
- package/docs/api/sensor-readout-timing.md +209 -0
- package/docs/api/sensor-response-application-compatibility.md +256 -0
- package/docs/api/sensor-response-operating-range.md +293 -0
- package/docs/api/sensor-responsivity-photocurrent.md +245 -0
- package/docs/api/sensor-sampling-aperture.md +221 -0
- package/docs/api/sensor-scene-eqe-temporal-exposure.md +56 -0
- package/docs/api/sensor-sensor-geometry.md +143 -0
- package/docs/api/sensor-signal-noise.md +75 -0
- package/docs/api/sensor-spatial-sample-reduction.md +186 -0
- package/docs/api/sensor-spatial-sampling-quadrature.md +188 -0
- package/docs/api/sensor-spatio-spectral-reduction.md +217 -0
- package/docs/api/sensor-spectral-coverage.md +33 -0
- package/docs/api/sensor-spectral-quadrature.md +183 -0
- package/docs/api/sensor-spectral-response.md +291 -0
- package/docs/api/sensor-temporal-photo-signal.md +62 -0
- package/docs/api/simulation-poc-simulation.md +364 -0
- package/docs/api/stabilization-camera-shake.md +71 -0
- package/docs/api/stabilization-system.md +442 -0
- package/docs/benchmarks/2026-10-01-main-baseline.json +694 -0
- package/docs/benchmarks/2026-10-02-geometric-preparation-reuse.json +2190 -0
- package/docs/benchmarks/2026-10-02-poc-projection-reuse.json +2423 -0
- package/docs/benchmarks/2026-10-02-v1-environment-gc-profile.json +210 -0
- package/docs/benchmarks/2026-10-02-v1-environment-ordinary.json +187 -0
- package/docs/benchmarks/2026-10-02-v1-geometry-gc-profile.json +756 -0
- package/docs/benchmarks/2026-10-02-v1-geometry-ordinary-1.json +711 -0
- package/docs/benchmarks/2026-10-02-v1-geometry-ordinary-2.json +711 -0
- package/docs/benchmarks/2026-10-02-v1-poc-gc-profile.json +885 -0
- package/docs/benchmarks/2026-10-02-v1-poc-ordinary-1.json +868 -0
- package/docs/benchmarks/2026-10-02-v1-poc-ordinary-2.json +868 -0
- package/docs/examples/production-capture.mjs +34 -0
- package/docs/examples/production-request.json +4613 -0
- package/docs/examples/quick-start.mjs +12 -0
- package/docs/validation/documentation-fragments.json +212 -0
- package/docs/validation/release-audit-inventory.json +1306 -0
- package/docs/validation/tier-acceptance-report-v1.json +2538 -0
- package/package.json +15 -3
|
@@ -0,0 +1,662 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* Module boundary and integration notes.
|
|
4
|
+
* Validate an untrusted declaration and return the normalized typed contract. Unknown enum values,
|
|
5
|
+
* missing required fields and incompatible scientific data fail at this boundary. The optical bridge
|
|
6
|
+
* maps outgoing W/m²/sr/nm radiance to pre-sensor-stack W/m²/nm irradiance. Circular paraxial
|
|
7
|
+
* acceptance is pi/(4*Nworking²); finite-focus unity-pupil geometry uses N*(1+m). Spectral
|
|
8
|
+
* transmission and effective working T-stop are alternative paths, and field throughput is applied
|
|
9
|
+
* exactly once. Sensor response and PSF redistribution are downstream.
|
|
10
|
+
* Apply declared pupil acceptance and exactly one transmission/field-throughput path to spectral scene
|
|
11
|
+
* radiance, returning pre-stack irradiance with conservative evidence. The optical bridge maps
|
|
12
|
+
* outgoing W/m²/sr/nm radiance to pre-sensor-stack W/m²/nm irradiance. Circular paraxial acceptance is
|
|
13
|
+
* pi/(4*Nworking²); finite-focus unity-pupil geometry uses N*(1+m). Spectral transmission and
|
|
14
|
+
* effective working T-stop are alternative paths, and field throughput is applied exactly once. Sensor
|
|
15
|
+
* response and PSF redistribution are downstream.
|
|
16
|
+
* @see docs/SCENE_SENSOR_QUADRATURE.md for equations, coordinate/unit conventions, blockers and
|
|
17
|
+
* support limits.
|
|
18
|
+
*/
|
|
19
|
+
import { approximationResult } from "../core/calculation-result.js";
|
|
20
|
+
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
21
|
+
import { parseEvidenceList } from "../core/evidence-provenance.js";
|
|
22
|
+
import { parseSpectralWavelengthBasis } from "../core/spectral.js";
|
|
23
|
+
import { InvalidScientificInputError } from "../core/validation.js";
|
|
24
|
+
import { composeFrontOfLensFilterTransmission } from "./front-of-lens-filter.js";
|
|
25
|
+
import { calculateThinLensImageDistance } from "./thin-lens.js";
|
|
26
|
+
import { parseSceneRadianceEvaluationRequest, parseSceneRadianceEvaluationResult } from "../schema/scene-radiance.js";
|
|
27
|
+
export const SCENE_TO_SENSOR_IRRADIANCE_PROFILE_SCHEMA_VERSION = "0.1.0";
|
|
28
|
+
function requireRecord(value, path) {
|
|
29
|
+
if (typeof value !== "object" ||
|
|
30
|
+
value === null ||
|
|
31
|
+
Array.isArray(value)) {
|
|
32
|
+
throw new InvalidConfigurationError(path + " must be an object.");
|
|
33
|
+
}
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
function requireNonEmptyString(value, path) {
|
|
37
|
+
if (typeof value !== "string" ||
|
|
38
|
+
value.trim().length === 0) {
|
|
39
|
+
throw new InvalidConfigurationError(path + " must be a non-empty string.");
|
|
40
|
+
}
|
|
41
|
+
return value.trim();
|
|
42
|
+
}
|
|
43
|
+
function requireFinite(value, path) {
|
|
44
|
+
if (typeof value !== "number" ||
|
|
45
|
+
!Number.isFinite(value)) {
|
|
46
|
+
throw new InvalidConfigurationError(path + " must be finite.");
|
|
47
|
+
}
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
function requirePositiveFinite(value, path) {
|
|
51
|
+
const parsed = requireFinite(value, path);
|
|
52
|
+
if (parsed <= 0) {
|
|
53
|
+
throw new InvalidConfigurationError(path +
|
|
54
|
+
" must be greater than zero.");
|
|
55
|
+
}
|
|
56
|
+
return parsed;
|
|
57
|
+
}
|
|
58
|
+
function requireFraction(value, path) {
|
|
59
|
+
const parsed = requireFinite(value, path);
|
|
60
|
+
if (parsed < 0 ||
|
|
61
|
+
parsed > 1) {
|
|
62
|
+
throw new InvalidConfigurationError(path +
|
|
63
|
+
" must be from zero through one.");
|
|
64
|
+
}
|
|
65
|
+
return parsed;
|
|
66
|
+
}
|
|
67
|
+
function parseRange(value, path) {
|
|
68
|
+
const record = requireRecord(value, path);
|
|
69
|
+
const minimum = requirePositiveFinite(record.minimum, path + ".minimum");
|
|
70
|
+
const maximum = requirePositiveFinite(record.maximum, path + ".maximum");
|
|
71
|
+
if (minimum > maximum) {
|
|
72
|
+
throw new InvalidConfigurationError(path +
|
|
73
|
+
".minimum must be less than or equal to maximum.");
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
minimum,
|
|
77
|
+
maximum
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function parseScientificStatus(value, path) {
|
|
81
|
+
if (value !== "calibrated" &&
|
|
82
|
+
value !== "approximation") {
|
|
83
|
+
throw new InvalidConfigurationError(path + " is invalid.");
|
|
84
|
+
}
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
function parseUncertainty(value, path) {
|
|
88
|
+
const record = requireRecord(value, path);
|
|
89
|
+
if (record.kind === "relative") {
|
|
90
|
+
return {
|
|
91
|
+
kind: "relative",
|
|
92
|
+
fraction: requireFraction(record.fraction, path + ".fraction"),
|
|
93
|
+
basis: requireNonEmptyString(record.basis, path + ".basis")
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (record.kind ===
|
|
97
|
+
"not-quantified") {
|
|
98
|
+
return {
|
|
99
|
+
kind: "not-quantified",
|
|
100
|
+
limitation: requireNonEmptyString(record.limitation, path + ".limitation")
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
throw new InvalidConfigurationError(path + ".kind is invalid.");
|
|
104
|
+
}
|
|
105
|
+
function parseLimitations(value, path) {
|
|
106
|
+
if (!Array.isArray(value)) {
|
|
107
|
+
throw new InvalidConfigurationError(path + " must be an array.");
|
|
108
|
+
}
|
|
109
|
+
const parsed = value.map((entry, index) => requireNonEmptyString(entry, path +
|
|
110
|
+
"[" +
|
|
111
|
+
index +
|
|
112
|
+
"]"));
|
|
113
|
+
if (new Set(parsed).size !==
|
|
114
|
+
parsed.length) {
|
|
115
|
+
throw new InvalidConfigurationError(path +
|
|
116
|
+
" must not contain duplicates.");
|
|
117
|
+
}
|
|
118
|
+
return parsed;
|
|
119
|
+
}
|
|
120
|
+
function parseReusableNumericEvidence(value, path) {
|
|
121
|
+
const evidence = parseEvidenceList(value, path);
|
|
122
|
+
if (evidence.some((entry) => entry.reuseStatus ===
|
|
123
|
+
"factual-reference-only")) {
|
|
124
|
+
throw new InvalidConfigurationError(path +
|
|
125
|
+
" for numeric optical curve data must be reusable-data or photivra-owned.");
|
|
126
|
+
}
|
|
127
|
+
return evidence;
|
|
128
|
+
}
|
|
129
|
+
function parseSpectralSamples(value, path) {
|
|
130
|
+
if (!Array.isArray(value) ||
|
|
131
|
+
value.length < 2) {
|
|
132
|
+
throw new InvalidConfigurationError(path +
|
|
133
|
+
" must contain at least two samples.");
|
|
134
|
+
}
|
|
135
|
+
let previous = Number.NEGATIVE_INFINITY;
|
|
136
|
+
return value.map((entry, index) => {
|
|
137
|
+
const samplePath = path +
|
|
138
|
+
"[" +
|
|
139
|
+
index +
|
|
140
|
+
"]";
|
|
141
|
+
const record = requireRecord(entry, samplePath);
|
|
142
|
+
const wavelengthNanometers = requirePositiveFinite(record.wavelengthNanometers, samplePath +
|
|
143
|
+
".wavelengthNanometers");
|
|
144
|
+
if (wavelengthNanometers <=
|
|
145
|
+
previous) {
|
|
146
|
+
throw new InvalidConfigurationError(path +
|
|
147
|
+
" wavelengths must be strictly increasing.");
|
|
148
|
+
}
|
|
149
|
+
previous =
|
|
150
|
+
wavelengthNanometers;
|
|
151
|
+
return {
|
|
152
|
+
wavelengthNanometers,
|
|
153
|
+
linearTransmissionFactor: requireFraction(record.linearTransmissionFactor, samplePath +
|
|
154
|
+
".linearTransmissionFactor")
|
|
155
|
+
};
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
function parseTransmission(value, path) {
|
|
159
|
+
const record = requireRecord(value, path);
|
|
160
|
+
if (record.kind ===
|
|
161
|
+
"spectral-transmission") {
|
|
162
|
+
if (record.workingTStop !==
|
|
163
|
+
undefined ||
|
|
164
|
+
record.wavelengthRangeNanometers !==
|
|
165
|
+
undefined) {
|
|
166
|
+
throw new InvalidConfigurationError(path +
|
|
167
|
+
" spectral-transmission must not include T-stop-only fields.");
|
|
168
|
+
}
|
|
169
|
+
const status = parseScientificStatus(record.scientificStatus, path +
|
|
170
|
+
".scientificStatus");
|
|
171
|
+
const samplesFact = requireRecord(record.samples, path + ".samples");
|
|
172
|
+
const uncertainty = parseUncertainty(record.uncertainty, path + ".uncertainty");
|
|
173
|
+
if (status === "calibrated" &&
|
|
174
|
+
uncertainty.kind !==
|
|
175
|
+
"relative") {
|
|
176
|
+
throw new InvalidConfigurationError(path +
|
|
177
|
+
" calibrated spectral transmission requires quantified relative uncertainty.");
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
kind: "spectral-transmission",
|
|
181
|
+
scientificStatus: status,
|
|
182
|
+
wavelengthBasis: parseResolvedBasis(record.wavelengthBasis, path +
|
|
183
|
+
".wavelengthBasis"),
|
|
184
|
+
samples: {
|
|
185
|
+
value: parseSpectralSamples(samplesFact.value, path +
|
|
186
|
+
".samples.value"),
|
|
187
|
+
evidence: parseReusableNumericEvidence(samplesFact.evidence, path +
|
|
188
|
+
".samples.evidence")
|
|
189
|
+
},
|
|
190
|
+
uncertainty
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
if (record.kind ===
|
|
194
|
+
"effective-working-t-stop-approximation") {
|
|
195
|
+
if (record.samples !==
|
|
196
|
+
undefined) {
|
|
197
|
+
throw new InvalidConfigurationError(path +
|
|
198
|
+
" T-stop approximation must not include spectral transmission samples.");
|
|
199
|
+
}
|
|
200
|
+
if (record.scientificStatus !==
|
|
201
|
+
"approximation") {
|
|
202
|
+
throw new InvalidConfigurationError(path +
|
|
203
|
+
' T-stop scientificStatus must be "approximation".');
|
|
204
|
+
}
|
|
205
|
+
const workingTStopFact = requireRecord(record.workingTStop, path +
|
|
206
|
+
".workingTStop");
|
|
207
|
+
return {
|
|
208
|
+
kind: "effective-working-t-stop-approximation",
|
|
209
|
+
scientificStatus: "approximation",
|
|
210
|
+
workingTStop: {
|
|
211
|
+
value: requirePositiveFinite(workingTStopFact.value, path +
|
|
212
|
+
".workingTStop.value"),
|
|
213
|
+
evidence: parseEvidenceList(workingTStopFact.evidence, path +
|
|
214
|
+
".workingTStop.evidence")
|
|
215
|
+
},
|
|
216
|
+
wavelengthBasis: parseResolvedBasis(record.wavelengthBasis, path +
|
|
217
|
+
".wavelengthBasis"),
|
|
218
|
+
wavelengthRangeNanometers: parseRange(record.wavelengthRangeNanometers, path +
|
|
219
|
+
".wavelengthRangeNanometers"),
|
|
220
|
+
uncertainty: parseUncertainty(record.uncertainty, path + ".uncertainty"),
|
|
221
|
+
limitation: requireNonEmptyString(record.limitation, path +
|
|
222
|
+
".limitation")
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
throw new InvalidConfigurationError(path + ".kind is invalid.");
|
|
226
|
+
}
|
|
227
|
+
function parseResolvedBasis(value, path) {
|
|
228
|
+
const parsed = parseSpectralWavelengthBasis(value, path);
|
|
229
|
+
if (parsed === "unspecified") {
|
|
230
|
+
throw new InvalidConfigurationError(path +
|
|
231
|
+
' must resolve to "air" or "vacuum".');
|
|
232
|
+
}
|
|
233
|
+
return parsed;
|
|
234
|
+
}
|
|
235
|
+
function parseFocusApplicability(value, path) {
|
|
236
|
+
const record = requireRecord(value, path);
|
|
237
|
+
if (record.kind === "any") {
|
|
238
|
+
return {
|
|
239
|
+
kind: "any"
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
if (record.kind ===
|
|
243
|
+
"finite-distance-range") {
|
|
244
|
+
return {
|
|
245
|
+
kind: "finite-distance-range",
|
|
246
|
+
objectDistanceM: parseRange(record.objectDistanceM, path +
|
|
247
|
+
".objectDistanceM")
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
throw new InvalidConfigurationError(path + ".kind is invalid.");
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Validate an untrusted declaration and return the normalized typed contract. Unknown enum values,
|
|
254
|
+
* missing required fields and incompatible scientific data fail at this boundary.
|
|
255
|
+
*
|
|
256
|
+
* The optical bridge maps outgoing W/m²/sr/nm radiance to pre-sensor-stack W/m²/nm irradiance.
|
|
257
|
+
* Circular paraxial acceptance is pi/(4*Nworking²); finite-focus unity-pupil geometry uses N*(1+m).
|
|
258
|
+
* Spectral transmission and effective working T-stop are alternative paths, and field throughput is
|
|
259
|
+
* applied exactly once. Sensor response and PSF redistribution are downstream.
|
|
260
|
+
* @param value - unknown. Treated as untrusted data; static typing alone is not validation.
|
|
261
|
+
* @returns SceneToSensorIrradianceProfile. Return shape and scientific status are explicit; no calibration is inferred from successful execution.
|
|
262
|
+
*
|
|
263
|
+
* @see docs/API_REFERENCE.md for the root export and exact type graph.
|
|
264
|
+
*/
|
|
265
|
+
export function parseSceneToSensorIrradianceProfile(value) {
|
|
266
|
+
const record = requireRecord(value, "sceneToSensorIrradianceProfile");
|
|
267
|
+
if (record.schemaVersion !==
|
|
268
|
+
SCENE_TO_SENSOR_IRRADIANCE_PROFILE_SCHEMA_VERSION) {
|
|
269
|
+
throw new InvalidConfigurationError('sceneToSensorIrradianceProfile.schemaVersion must be "' +
|
|
270
|
+
SCENE_TO_SENSOR_IRRADIANCE_PROFILE_SCHEMA_VERSION +
|
|
271
|
+
'".');
|
|
272
|
+
}
|
|
273
|
+
const applicability = requireRecord(record.applicability, "sceneToSensorIrradianceProfile.applicability");
|
|
274
|
+
const status = parseScientificStatus(record.scientificStatus, "sceneToSensorIrradianceProfile.scientificStatus");
|
|
275
|
+
const transmission = parseTransmission(record.transmission, "sceneToSensorIrradianceProfile.transmission");
|
|
276
|
+
if (status === "calibrated" &&
|
|
277
|
+
transmission.scientificStatus !==
|
|
278
|
+
"calibrated") {
|
|
279
|
+
throw new InvalidConfigurationError("A calibrated optical bridge profile requires calibrated spectral transmission.");
|
|
280
|
+
}
|
|
281
|
+
if (record.distortionAreaMappingOwnership !==
|
|
282
|
+
"not-applied-by-bridge" ||
|
|
283
|
+
record.psfRedistributionOwnership !==
|
|
284
|
+
"downstream-normalized-energy-redistribution" ||
|
|
285
|
+
record.sensorOpticalStackIncluded !==
|
|
286
|
+
false ||
|
|
287
|
+
record.strayLightIncluded !==
|
|
288
|
+
false ||
|
|
289
|
+
record.polarizationModeled !==
|
|
290
|
+
false ||
|
|
291
|
+
record.wavelengthChangingBehaviorModeled !==
|
|
292
|
+
false ||
|
|
293
|
+
record.volumetricScatteringModeled !==
|
|
294
|
+
false) {
|
|
295
|
+
throw new InvalidConfigurationError("sceneToSensorIrradianceProfile ownership/completeness flags are invalid for schema 0.1.0.");
|
|
296
|
+
}
|
|
297
|
+
return {
|
|
298
|
+
schemaVersion: SCENE_TO_SENSOR_IRRADIANCE_PROFILE_SCHEMA_VERSION,
|
|
299
|
+
profileId: requireNonEmptyString(record.profileId, "sceneToSensorIrradianceProfile.profileId"),
|
|
300
|
+
profileVersion: requireNonEmptyString(record.profileVersion, "sceneToSensorIrradianceProfile.profileVersion"),
|
|
301
|
+
lensProfileId: requireNonEmptyString(record.lensProfileId, "sceneToSensorIrradianceProfile.lensProfileId"),
|
|
302
|
+
scientificStatus: status,
|
|
303
|
+
applicability: {
|
|
304
|
+
focalLengthMm: parseRange(applicability.focalLengthMm, "sceneToSensorIrradianceProfile.applicability.focalLengthMm"),
|
|
305
|
+
nominalFNumber: parseRange(applicability.nominalFNumber, "sceneToSensorIrradianceProfile.applicability.nominalFNumber"),
|
|
306
|
+
focus: parseFocusApplicability(applicability.focus, "sceneToSensorIrradianceProfile.applicability.focus")
|
|
307
|
+
},
|
|
308
|
+
transmission,
|
|
309
|
+
distortionAreaMappingOwnership: "not-applied-by-bridge",
|
|
310
|
+
psfRedistributionOwnership: "downstream-normalized-energy-redistribution",
|
|
311
|
+
sensorOpticalStackIncluded: false,
|
|
312
|
+
strayLightIncluded: false,
|
|
313
|
+
polarizationModeled: false,
|
|
314
|
+
wavelengthChangingBehaviorModeled: false,
|
|
315
|
+
volumetricScatteringModeled: false,
|
|
316
|
+
evidence: parseEvidenceList(record.evidence, "sceneToSensorIrradianceProfile.evidence"),
|
|
317
|
+
limitations: parseLimitations(record.limitations, "sceneToSensorIrradianceProfile.limitations")
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
function ensureWithin(value, range, path) {
|
|
321
|
+
if (value < range.minimum ||
|
|
322
|
+
value > range.maximum) {
|
|
323
|
+
throw new InvalidScientificInputError(path +
|
|
324
|
+
" lies outside the optical profile applicability range.");
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
function workingFNumber(focus, focalLengthMm, nominalFNumber) {
|
|
328
|
+
if (focus.kind === "infinity-focus") {
|
|
329
|
+
return {
|
|
330
|
+
value: nominalFNumber,
|
|
331
|
+
evidence: []
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
if (focus.kind ===
|
|
335
|
+
"ideal-symmetric-thin-lens") {
|
|
336
|
+
if (focus
|
|
337
|
+
.pupilMagnificationAssumption !==
|
|
338
|
+
"unity") {
|
|
339
|
+
throw new InvalidScientificInputError('Ideal symmetric thin-lens focus requires pupilMagnificationAssumption "unity".');
|
|
340
|
+
}
|
|
341
|
+
const thinLens = calculateThinLensImageDistance({
|
|
342
|
+
focalLengthMm,
|
|
343
|
+
objectDistanceM: focus.objectDistanceM
|
|
344
|
+
}).value;
|
|
345
|
+
return {
|
|
346
|
+
value: nominalFNumber *
|
|
347
|
+
(1 + thinLens.magnification),
|
|
348
|
+
evidence: []
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
if (focus.kind ===
|
|
352
|
+
"supplied-working-f-number") {
|
|
353
|
+
const value = requirePositiveFiniteScientific(focus.workingFNumber.value, "focus.workingFNumber.value");
|
|
354
|
+
return {
|
|
355
|
+
value,
|
|
356
|
+
evidence: parseEvidenceList(focus.workingFNumber.evidence, "focus.workingFNumber.evidence")
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
throw new InvalidScientificInputError("focus.kind is invalid.");
|
|
360
|
+
}
|
|
361
|
+
function requirePositiveFiniteScientific(value, path) {
|
|
362
|
+
if (typeof value !== "number" ||
|
|
363
|
+
!Number.isFinite(value) ||
|
|
364
|
+
value <= 0) {
|
|
365
|
+
throw new InvalidScientificInputError(path +
|
|
366
|
+
" must be finite and greater than zero.");
|
|
367
|
+
}
|
|
368
|
+
return value;
|
|
369
|
+
}
|
|
370
|
+
function finiteFocusDistance(focus) {
|
|
371
|
+
if (focus.kind ===
|
|
372
|
+
"ideal-symmetric-thin-lens") {
|
|
373
|
+
return requirePositiveFiniteScientific(focus.objectDistanceM, "focus.objectDistanceM");
|
|
374
|
+
}
|
|
375
|
+
if (focus.kind ===
|
|
376
|
+
"supplied-working-f-number" &&
|
|
377
|
+
focus.focus.kind === "finite") {
|
|
378
|
+
return requirePositiveFiniteScientific(focus.focus.objectDistanceM, "focus.focus.objectDistanceM");
|
|
379
|
+
}
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
function interpolateTransmission(model, wavelengthNanometers) {
|
|
383
|
+
const samples = model.samples.value;
|
|
384
|
+
const first = samples[0];
|
|
385
|
+
const last = samples[samples.length - 1];
|
|
386
|
+
if (wavelengthNanometers <
|
|
387
|
+
first.wavelengthNanometers ||
|
|
388
|
+
wavelengthNanometers >
|
|
389
|
+
last.wavelengthNanometers) {
|
|
390
|
+
throw new InvalidScientificInputError("Scene wavelength lies outside the spectral transmission sample range.");
|
|
391
|
+
}
|
|
392
|
+
if (wavelengthNanometers ===
|
|
393
|
+
first.wavelengthNanometers) {
|
|
394
|
+
return first
|
|
395
|
+
.linearTransmissionFactor;
|
|
396
|
+
}
|
|
397
|
+
for (let index = 1; index < samples.length; index += 1) {
|
|
398
|
+
const right = samples[index];
|
|
399
|
+
if (wavelengthNanometers <=
|
|
400
|
+
right.wavelengthNanometers) {
|
|
401
|
+
const left = samples[index - 1];
|
|
402
|
+
if (wavelengthNanometers ===
|
|
403
|
+
right.wavelengthNanometers) {
|
|
404
|
+
return right
|
|
405
|
+
.linearTransmissionFactor;
|
|
406
|
+
}
|
|
407
|
+
const phase = (wavelengthNanometers -
|
|
408
|
+
left.wavelengthNanometers) /
|
|
409
|
+
(right.wavelengthNanometers -
|
|
410
|
+
left.wavelengthNanometers);
|
|
411
|
+
return (left
|
|
412
|
+
.linearTransmissionFactor +
|
|
413
|
+
phase *
|
|
414
|
+
(right
|
|
415
|
+
.linearTransmissionFactor -
|
|
416
|
+
left
|
|
417
|
+
.linearTransmissionFactor));
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
return last
|
|
421
|
+
.linearTransmissionFactor;
|
|
422
|
+
}
|
|
423
|
+
function fieldFactor(field, imagePointMm) {
|
|
424
|
+
if (field.kind === "unity") {
|
|
425
|
+
return 1;
|
|
426
|
+
}
|
|
427
|
+
if (field.kind ===
|
|
428
|
+
"illumination-vignetting-result") {
|
|
429
|
+
const result = field.result;
|
|
430
|
+
const scale = Math.max(1, Math.abs(imagePointMm.x), Math.abs(imagePointMm.y), Math.abs(result.imagePointMm.x), Math.abs(result.imagePointMm.y));
|
|
431
|
+
const tolerance = Number.EPSILON *
|
|
432
|
+
64 *
|
|
433
|
+
scale;
|
|
434
|
+
if (Math.abs(result.imagePointMm.x -
|
|
435
|
+
imagePointMm.x) > tolerance ||
|
|
436
|
+
Math.abs(result.imagePointMm.y -
|
|
437
|
+
imagePointMm.y) > tolerance) {
|
|
438
|
+
throw new InvalidScientificInputError("Illumination-vignetting result imagePointMm must match the optical bridge imagePointMm.");
|
|
439
|
+
}
|
|
440
|
+
const factor = result.linearThroughputFactor;
|
|
441
|
+
if (!Number.isFinite(factor) ||
|
|
442
|
+
factor <= 0 ||
|
|
443
|
+
factor > 1) {
|
|
444
|
+
throw new InvalidScientificInputError("Field throughput factor must be finite and in (0, 1].");
|
|
445
|
+
}
|
|
446
|
+
return factor;
|
|
447
|
+
}
|
|
448
|
+
throw new InvalidScientificInputError("fieldThroughput.kind is invalid.");
|
|
449
|
+
}
|
|
450
|
+
function validateSceneIdentity(request, result) {
|
|
451
|
+
if (request.sampleId !==
|
|
452
|
+
result.sampleId ||
|
|
453
|
+
request.providerProfileId !==
|
|
454
|
+
result.providerProfileId ||
|
|
455
|
+
request.sceneId !==
|
|
456
|
+
result.sceneId ||
|
|
457
|
+
request.wavelengthNanometers !==
|
|
458
|
+
result.wavelengthNanometers ||
|
|
459
|
+
request.wavelengthBasis !==
|
|
460
|
+
result.wavelengthBasis) {
|
|
461
|
+
throw new InvalidScientificInputError("Scene-radiance request/result identity must match exactly.");
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Apply declared pupil acceptance and exactly one transmission/field-throughput path to spectral scene
|
|
466
|
+
* radiance, returning pre-stack irradiance with conservative evidence.
|
|
467
|
+
*
|
|
468
|
+
* The optical bridge maps outgoing W/m²/sr/nm radiance to pre-sensor-stack W/m²/nm irradiance.
|
|
469
|
+
* Circular paraxial acceptance is pi/(4*Nworking²); finite-focus unity-pupil geometry uses N*(1+m).
|
|
470
|
+
* Spectral transmission and effective working T-stop are alternative paths, and field throughput is
|
|
471
|
+
* applied exactly once. Sensor response and PSF redistribution are downstream.
|
|
472
|
+
* @param input - CalculateSceneRadianceToSensorIrradianceInput. See the linked contract for coordinate, unit and profile binding semantics.
|
|
473
|
+
* @returns CalculationResult<
|
|
474
|
+
SceneToSensorIrradianceResult
|
|
475
|
+
>. Return shape and scientific status are explicit; no calibration is inferred from successful execution.
|
|
476
|
+
*
|
|
477
|
+
* @see docs/API_REFERENCE.md for the root export and exact type graph.
|
|
478
|
+
*/
|
|
479
|
+
export function calculateSceneRadianceToSensorIrradiance(input) {
|
|
480
|
+
const request = parseSceneRadianceEvaluationRequest(input.sceneRadianceRequest);
|
|
481
|
+
const sceneResult = parseSceneRadianceEvaluationResult(input.sceneRadianceResult);
|
|
482
|
+
validateSceneIdentity(request, sceneResult);
|
|
483
|
+
const profile = parseSceneToSensorIrradianceProfile(input.profile);
|
|
484
|
+
const focalLengthMm = requirePositiveFiniteScientific(input.focalLengthMm, "focalLengthMm");
|
|
485
|
+
const nominalFNumber = requirePositiveFiniteScientific(input.nominalFNumber, "nominalFNumber");
|
|
486
|
+
ensureWithin(focalLengthMm, profile.applicability
|
|
487
|
+
.focalLengthMm, "focalLengthMm");
|
|
488
|
+
ensureWithin(nominalFNumber, profile.applicability
|
|
489
|
+
.nominalFNumber, "nominalFNumber");
|
|
490
|
+
const focusDistanceM = finiteFocusDistance(input.focus);
|
|
491
|
+
if (profile.applicability.focus.kind ===
|
|
492
|
+
"finite-distance-range") {
|
|
493
|
+
if (focusDistanceM === null) {
|
|
494
|
+
throw new InvalidScientificInputError("Optical profile requires a finite focus distance.");
|
|
495
|
+
}
|
|
496
|
+
ensureWithin(focusDistanceM, profile.applicability
|
|
497
|
+
.focus.objectDistanceM, "focus object distance");
|
|
498
|
+
}
|
|
499
|
+
const working = workingFNumber(input.focus, focalLengthMm, nominalFNumber);
|
|
500
|
+
const workingFNumberValue = working.value;
|
|
501
|
+
const geometricAcceptance = Math.PI /
|
|
502
|
+
(4 *
|
|
503
|
+
workingFNumberValue *
|
|
504
|
+
workingFNumberValue);
|
|
505
|
+
if (!Number.isFinite(geometricAcceptance) ||
|
|
506
|
+
geometricAcceptance <= 0) {
|
|
507
|
+
throw new InvalidScientificInputError("Paraxial geometric acceptance must remain finite and greater than zero.");
|
|
508
|
+
}
|
|
509
|
+
const transmission = profile.transmission;
|
|
510
|
+
if (request.wavelengthBasis !==
|
|
511
|
+
transmission.wavelengthBasis) {
|
|
512
|
+
throw new InvalidScientificInputError("Scene-radiance and optical-transmission wavelength bases must match; implicit air/vacuum conversion is not performed.");
|
|
513
|
+
}
|
|
514
|
+
let spectralTransmissionFactor = null;
|
|
515
|
+
let effectiveWorkingTStop = null;
|
|
516
|
+
let tStopEquivalentTransmissionFactor = null;
|
|
517
|
+
let effectiveAcceptance = geometricAcceptance;
|
|
518
|
+
let transmissionEvidence;
|
|
519
|
+
if (transmission.kind ===
|
|
520
|
+
"spectral-transmission") {
|
|
521
|
+
spectralTransmissionFactor =
|
|
522
|
+
interpolateTransmission(transmission, request.wavelengthNanometers);
|
|
523
|
+
effectiveAcceptance *=
|
|
524
|
+
spectralTransmissionFactor;
|
|
525
|
+
transmissionEvidence =
|
|
526
|
+
transmission.samples.evidence;
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
ensureWithin(request.wavelengthNanometers, transmission
|
|
530
|
+
.wavelengthRangeNanometers, "scene wavelength");
|
|
531
|
+
effectiveWorkingTStop =
|
|
532
|
+
transmission.workingTStop.value;
|
|
533
|
+
if (effectiveWorkingTStop <
|
|
534
|
+
workingFNumberValue) {
|
|
535
|
+
throw new InvalidScientificInputError("effective working T-stop must not be smaller than the geometric working f-number for a passive optical approximation.");
|
|
536
|
+
}
|
|
537
|
+
tStopEquivalentTransmissionFactor =
|
|
538
|
+
(workingFNumberValue /
|
|
539
|
+
effectiveWorkingTStop) **
|
|
540
|
+
2;
|
|
541
|
+
effectiveAcceptance =
|
|
542
|
+
Math.PI /
|
|
543
|
+
(4 *
|
|
544
|
+
effectiveWorkingTStop *
|
|
545
|
+
effectiveWorkingTStop);
|
|
546
|
+
transmissionEvidence =
|
|
547
|
+
transmission
|
|
548
|
+
.workingTStop.evidence;
|
|
549
|
+
}
|
|
550
|
+
let frontOfLensFilterCount = 0;
|
|
551
|
+
let frontOfLensFilterTransmissionFactor = 1;
|
|
552
|
+
let frontOfLensFilterAttenuationStops = 0;
|
|
553
|
+
let frontOfLensFilterEvidence = [];
|
|
554
|
+
let frontOfLensFilterLimitations = [];
|
|
555
|
+
if (input.frontOfLensFilters !==
|
|
556
|
+
undefined) {
|
|
557
|
+
const composed = composeFrontOfLensFilterTransmission({
|
|
558
|
+
filters: input.frontOfLensFilters,
|
|
559
|
+
wavelengthNanometers: request.wavelengthNanometers,
|
|
560
|
+
wavelengthBasis: request.wavelengthBasis
|
|
561
|
+
});
|
|
562
|
+
frontOfLensFilterCount =
|
|
563
|
+
composed.appliedFilterCount;
|
|
564
|
+
frontOfLensFilterTransmissionFactor =
|
|
565
|
+
composed
|
|
566
|
+
.combinedLinearTransmissionFactor;
|
|
567
|
+
frontOfLensFilterAttenuationStops =
|
|
568
|
+
composed
|
|
569
|
+
.combinedAttenuationStops;
|
|
570
|
+
frontOfLensFilterEvidence =
|
|
571
|
+
composed.components.flatMap((component) => component.evidence);
|
|
572
|
+
frontOfLensFilterLimitations =
|
|
573
|
+
composed.components.flatMap((component) => component.limitations);
|
|
574
|
+
effectiveAcceptance *=
|
|
575
|
+
frontOfLensFilterTransmissionFactor;
|
|
576
|
+
}
|
|
577
|
+
const fieldThroughputFactor = fieldFactor(input.fieldThroughput, input.imagePointMm);
|
|
578
|
+
effectiveAcceptance *=
|
|
579
|
+
fieldThroughputFactor;
|
|
580
|
+
const sceneRadiance = sceneResult
|
|
581
|
+
.spectralRadianceWattsPerSquareMeterSteradianNanometer;
|
|
582
|
+
const irradiance = sceneRadiance *
|
|
583
|
+
effectiveAcceptance;
|
|
584
|
+
if (!Number.isFinite(irradiance) ||
|
|
585
|
+
irradiance < 0) {
|
|
586
|
+
throw new InvalidScientificInputError("Sensor-plane spectral irradiance must remain finite and non-negative.");
|
|
587
|
+
}
|
|
588
|
+
const limitations = [
|
|
589
|
+
...profile.limitations,
|
|
590
|
+
...frontOfLensFilterLimitations,
|
|
591
|
+
"Front-of-lens filter transmission is applied outside the lens throughput path exactly once and does not change geometric working f-number.",
|
|
592
|
+
"Paraxial circular-pupil acceptance uses pi/(4*N_working^2); no universal cos^4 field falloff is added.",
|
|
593
|
+
"Field throughput is supplied separately and applied exactly once.",
|
|
594
|
+
"Geometric distortion area-density/Jacobian correction is not applied by this bridge.",
|
|
595
|
+
"PSF/diffraction energy redistribution is downstream and must preserve normalized energy apart from separately owned throughput losses.",
|
|
596
|
+
"Sensor optical stack, microlens, CFA, QE/responsivity and charge conversion are downstream.",
|
|
597
|
+
"Flare, ghosting, veiling glare, polarization, volumetric scattering and wavelength-changing behavior are not modeled."
|
|
598
|
+
];
|
|
599
|
+
return approximationResult({
|
|
600
|
+
schemaVersion: SCENE_TO_SENSOR_IRRADIANCE_PROFILE_SCHEMA_VERSION,
|
|
601
|
+
profileId: profile.profileId,
|
|
602
|
+
profileVersion: profile.profileVersion,
|
|
603
|
+
lensProfileId: profile.lensProfileId,
|
|
604
|
+
sampleId: request.sampleId,
|
|
605
|
+
providerProfileId: request.providerProfileId,
|
|
606
|
+
sceneId: request.sceneId,
|
|
607
|
+
timeSecondsFromExposureStart: request
|
|
608
|
+
.timeSecondsFromExposureStart,
|
|
609
|
+
wavelengthNanometers: request.wavelengthNanometers,
|
|
610
|
+
wavelengthBasis: request.wavelengthBasis,
|
|
611
|
+
inputQuantity: "outgoing-spectral-radiance",
|
|
612
|
+
inputUnit: "W/m^2/sr/nm",
|
|
613
|
+
outputQuantity: "sensor-plane-spectral-irradiance",
|
|
614
|
+
outputUnit: "W/m^2/nm",
|
|
615
|
+
sceneSpectralRadianceWattsPerSquareMeterSteradianNanometer: sceneRadiance,
|
|
616
|
+
focalLengthMm,
|
|
617
|
+
nominalFNumber,
|
|
618
|
+
workingFNumber: workingFNumberValue,
|
|
619
|
+
focusModel: input.focus.kind,
|
|
620
|
+
paraxialGeometricAcceptanceSolidAngleSteradians: geometricAcceptance,
|
|
621
|
+
transmissionPath: transmission.kind,
|
|
622
|
+
spectralTransmissionFactor,
|
|
623
|
+
effectiveWorkingTStop,
|
|
624
|
+
tStopEquivalentTransmissionFactor,
|
|
625
|
+
frontOfLensFilterCount,
|
|
626
|
+
frontOfLensFilterTransmissionFactor,
|
|
627
|
+
frontOfLensFilterAttenuationStops,
|
|
628
|
+
frontOfLensFilterTransmissionAppliedExactlyOnce: true,
|
|
629
|
+
frontOfLensFilterPolarizationModeled: false,
|
|
630
|
+
fieldThroughputFactor,
|
|
631
|
+
effectiveAcceptanceAfterTransmissionAndFieldSteradians: effectiveAcceptance,
|
|
632
|
+
sensorPlaneSpectralIrradianceWattsPerSquareMeterNanometer: irradiance,
|
|
633
|
+
scientificStatus: "approximation",
|
|
634
|
+
sceneRadianceScientificStatus: sceneResult.scientificStatus,
|
|
635
|
+
opticalProfileScientificStatus: profile.scientificStatus,
|
|
636
|
+
sceneRadianceUncertainty: sceneResult.uncertainty,
|
|
637
|
+
opticalUncertainty: transmission.uncertainty,
|
|
638
|
+
radianceAmplificationApplied: false,
|
|
639
|
+
fieldThroughputAppliedExactlyOnce: true,
|
|
640
|
+
universalCos4FalloffApplied: false,
|
|
641
|
+
distortionAreaCorrectionApplied: false,
|
|
642
|
+
psfRedistributionApplied: false,
|
|
643
|
+
sensorOpticalStackApplied: false,
|
|
644
|
+
cfaApplied: false,
|
|
645
|
+
quantumEfficiencyApplied: false,
|
|
646
|
+
spectralResponsivityApplied: false,
|
|
647
|
+
strayLightApplied: false,
|
|
648
|
+
polarizationModeled: false,
|
|
649
|
+
wavelengthChangingBehaviorModeled: false,
|
|
650
|
+
volumetricScatteringModeled: false,
|
|
651
|
+
calibratedSensorPlaneIrradianceClaimAuthorized: false,
|
|
652
|
+
componentEvidence: {
|
|
653
|
+
sceneRadiance: sceneResult.evidence,
|
|
654
|
+
opticalProfile: profile.evidence,
|
|
655
|
+
transmission: transmissionEvidence,
|
|
656
|
+
workingFNumber: working.evidence,
|
|
657
|
+
frontOfLensFilters: frontOfLensFilterEvidence
|
|
658
|
+
},
|
|
659
|
+
limitations
|
|
660
|
+
}, "scene-radiance-to-sensor-irradiance", "1.1.0", limitations);
|
|
661
|
+
}
|
|
662
|
+
//# sourceMappingURL=scene-to-sensor-irradiance.js.map
|