@photivra/engine 2.18.0 → 2.20.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 +179 -1
- package/CITATION.cff +1 -1
- package/NODE_SUPPORT.md +7 -5
- package/README.md +6 -6
- package/SECURITY.md +1 -1
- package/THIRD_PARTY.md +14 -10
- package/dist/capture/dng-lens-correction-opcodes.d.ts +32 -0
- package/dist/capture/dng-lens-correction-opcodes.js +119 -0
- package/dist/capture/dng-lens-correction-opcodes.js.map +1 -0
- package/dist/capture/focus-control.js +2 -75
- package/dist/capture/focus-control.js.map +1 -1
- package/dist/capture/native-environment-lean.d.ts +1 -0
- package/dist/capture/native-environment-lean.js +2 -6
- package/dist/capture/native-environment-lean.js.map +1 -1
- package/dist/capture/native-environment-optical-stage.d.ts +1 -0
- package/dist/capture/native-environment-optical-stage.js +2 -5
- package/dist/capture/native-environment-optical-stage.js.map +1 -1
- package/dist/capture/native-environment-raw.js +1 -5
- package/dist/capture/native-environment-raw.js.map +1 -1
- package/dist/capture/native-raw-dng.d.ts +6 -0
- package/dist/capture/native-raw-dng.js +16 -2
- package/dist/capture/native-raw-dng.js.map +1 -1
- package/dist/capture/release-sequence.js +2 -47
- package/dist/capture/release-sequence.js.map +1 -1
- package/dist/capture/sensor-raw-producer.js +3 -5
- package/dist/capture/sensor-raw-producer.js.map +1 -1
- package/dist/color/white-balance.d.ts +2 -0
- package/dist/color/white-balance.js +3 -56
- package/dist/color/white-balance.js.map +1 -1
- package/dist/composition/image-formation-plan.d.ts +1 -0
- package/dist/composition/image-formation-plan.js +3 -49
- package/dist/composition/image-formation-plan.js.map +1 -1
- package/dist/core/evidence-provenance.js +1 -16
- package/dist/core/evidence-provenance.js.map +1 -1
- package/dist/core/record-validation.d.ts +54 -0
- package/dist/core/record-validation.js +176 -0
- package/dist/core/record-validation.js.map +1 -1
- package/dist/core/scientific-assurance.js +1 -18
- package/dist/core/scientific-assurance.js.map +1 -1
- package/dist/core/shared-helpers.d.ts +35 -0
- package/dist/core/shared-helpers.js +38 -0
- package/dist/core/shared-helpers.js.map +1 -0
- package/dist/core/spectral-composition.js +1 -36
- package/dist/core/spectral-composition.js.map +1 -1
- package/dist/core/spectral.js +1 -19
- package/dist/core/spectral.js.map +1 -1
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/dist/core/version.js.map +1 -1
- package/dist/equipment/exposure-capabilities.d.ts +1 -0
- package/dist/equipment/exposure-capabilities.js +2 -36
- package/dist/equipment/exposure-capabilities.js.map +1 -1
- package/dist/equipment/generic-lens-catalogue.d.ts +8 -2
- package/dist/equipment/generic-lens-catalogue.js +31 -2
- package/dist/equipment/generic-lens-catalogue.js.map +1 -1
- package/dist/equipment/generic-tier-assets.js +2 -3
- package/dist/equipment/generic-tier-assets.js.map +1 -1
- package/dist/equipment/generic-tier-presets.js +2 -3
- package/dist/equipment/generic-tier-presets.js.map +1 -1
- package/dist/equipment/iso-capabilities.js +2 -49
- package/dist/equipment/iso-capabilities.js.map +1 -1
- package/dist/equipment/metering-capabilities.js +1 -26
- package/dist/equipment/metering-capabilities.js.map +1 -1
- package/dist/equipment/release-capabilities.js +1 -53
- package/dist/equipment/release-capabilities.js.map +1 -1
- package/dist/exposure/auto-iso-slowest-shutter.js +1 -7
- package/dist/exposure/auto-iso-slowest-shutter.js.map +1 -1
- package/dist/exposure/exposure-duration-control.js +1 -16
- package/dist/exposure/exposure-duration-control.js.map +1 -1
- package/dist/exposure/exposure-mode-resolver.js +1 -17
- package/dist/exposure/exposure-mode-resolver.js.map +1 -1
- package/dist/exposure/filtered-exposure-time.d.ts +93 -0
- package/dist/exposure/filtered-exposure-time.js +129 -0
- package/dist/exposure/filtered-exposure-time.js.map +1 -0
- package/dist/exposure/flash-ttl.d.ts +1 -0
- package/dist/exposure/flash-ttl.js +1 -1
- package/dist/exposure/flash-ttl.js.map +1 -1
- package/dist/exposure/flash.js +1 -49
- package/dist/exposure/flash.js.map +1 -1
- package/dist/exposure/metering-scene-radiance.js +1 -25
- package/dist/exposure/metering-scene-radiance.js.map +1 -1
- package/dist/exposure/metering-target.js +1 -30
- package/dist/exposure/metering-target.js.map +1 -1
- package/dist/exposure/metering-temporal.js +1 -8
- package/dist/exposure/metering-temporal.js.map +1 -1
- package/dist/exposure/metering.js +1 -72
- package/dist/exposure/metering.js.map +1 -1
- package/dist/exposure/program-line.js +1 -45
- package/dist/exposure/program-line.js.map +1 -1
- package/dist/facade/develop-joined-parts.d.ts +29 -0
- package/dist/facade/develop-joined-parts.js +33 -0
- package/dist/facade/develop-joined-parts.js.map +1 -0
- package/dist/facade/display-view-gpu.d.ts +7 -4
- package/dist/facade/display-view-gpu.js +4 -4
- package/dist/facade/display-view-gpu.js.map +1 -1
- package/dist/facade/display-view-lens-signal.d.ts +1 -1
- package/dist/facade/display-view-lens-signal.js +5 -3
- package/dist/facade/display-view-lens-signal.js.map +1 -1
- package/dist/facade/display-view.d.ts +3 -1
- package/dist/facade/display-view.js +1 -1
- package/dist/facade/display-view.js.map +1 -1
- package/dist/facade/fast-methods.d.ts +50 -0
- package/dist/facade/fast-methods.js +50 -0
- package/dist/facade/fast-methods.js.map +1 -0
- package/dist/facade/fast-resolution.d.ts +12 -0
- package/dist/facade/fast-resolution.js +18 -0
- package/dist/facade/fast-resolution.js.map +1 -0
- package/dist/facade/generic-lens-capture.d.ts +6 -3
- package/dist/facade/generic-lens-capture.js +6 -3
- package/dist/facade/generic-lens-capture.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +88 -16
- package/dist/facade/simulate-capture.js +279 -153
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/facade/simulate-display-view.d.ts +3 -2
- package/dist/facade/simulate-display-view.js +22 -12
- package/dist/facade/simulate-display-view.js.map +1 -1
- package/dist/gpu/chart-composite-gpu.js +1 -3
- package/dist/gpu/chart-composite-gpu.js.map +1 -1
- package/dist/gpu/chart-radiance-gpu.js +1 -5
- package/dist/gpu/chart-radiance-gpu.js.map +1 -1
- package/dist/gpu/display-view-quality-gpu.d.ts +13 -1
- package/dist/gpu/display-view-quality-gpu.js +4 -8
- package/dist/gpu/display-view-quality-gpu.js.map +1 -1
- package/dist/gpu/display-view-speed-gpu.js +3 -25
- package/dist/gpu/display-view-speed-gpu.js.map +1 -1
- package/dist/gpu/sensor-stage-gpu.js +1 -5
- package/dist/gpu/sensor-stage-gpu.js.map +1 -1
- package/dist/gpu/webgpu-runtime.d.ts +2 -0
- package/dist/gpu/webgpu-runtime.js +3 -0
- package/dist/gpu/webgpu-runtime.js.map +1 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/motion/camera-rotation.js +1 -6
- package/dist/motion/camera-rotation.js.map +1 -1
- package/dist/motion/capture-rotation-inverse-mapping.d.ts +12 -0
- package/dist/motion/capture-rotation-inverse-mapping.js +2 -2
- package/dist/motion/capture-rotation-inverse-mapping.js.map +1 -1
- package/dist/motion/capture-rotation-temporal-quadrature.d.ts +1 -0
- package/dist/motion/capture-rotation-temporal-quadrature.js +1 -1
- package/dist/motion/capture-rotation-temporal-quadrature.js.map +1 -1
- package/dist/motion/capture-rotation-trajectory.js +2 -17
- package/dist/motion/capture-rotation-trajectory.js.map +1 -1
- package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts +1 -0
- package/dist/motion/capture-translation-parallax-temporal-quadrature.js +3 -14
- package/dist/motion/capture-translation-parallax-temporal-quadrature.js.map +1 -1
- package/dist/motion/extended-object-projection.js +5 -40
- package/dist/motion/extended-object-projection.js.map +1 -1
- package/dist/optics/aperture-diameter.d.ts +47 -0
- package/dist/optics/aperture-diameter.js +50 -0
- package/dist/optics/aperture-diameter.js.map +1 -0
- package/dist/optics/atmospheric-haze.js +1 -7
- package/dist/optics/atmospheric-haze.js.map +1 -1
- package/dist/optics/brown-conrady-distortion.js +1 -7
- package/dist/optics/brown-conrady-distortion.js.map +1 -1
- package/dist/optics/complex-pupil-psf.d.ts +1 -0
- package/dist/optics/complex-pupil-psf.js +2 -84
- package/dist/optics/complex-pupil-psf.js.map +1 -1
- package/dist/optics/detail-limit.d.ts +182 -0
- package/dist/optics/detail-limit.js +336 -0
- package/dist/optics/detail-limit.js.map +1 -0
- package/dist/optics/focus-state.js +1 -11
- package/dist/optics/focus-state.js.map +1 -1
- package/dist/optics/front-of-lens-filter.d.ts +5 -0
- package/dist/optics/front-of-lens-filter.js +3 -65
- package/dist/optics/front-of-lens-filter.js.map +1 -1
- package/dist/optics/generic-lens-psf.d.ts +18 -2
- package/dist/optics/generic-lens-psf.js +25 -2
- package/dist/optics/generic-lens-psf.js.map +1 -1
- package/dist/optics/generic-nd-filter-presets.d.ts +12 -0
- package/dist/optics/generic-nd-filter-presets.js +48 -0
- package/dist/optics/generic-nd-filter-presets.js.map +1 -0
- package/dist/optics/illumination-vignetting.js +1 -6
- package/dist/optics/illumination-vignetting.js.map +1 -1
- package/dist/optics/lens-psf-profile.d.ts +4 -1
- package/dist/optics/lens-psf-profile.js +12 -111
- package/dist/optics/lens-psf-profile.js.map +1 -1
- package/dist/optics/longitudinal-chromatic-aberration.js +1 -7
- package/dist/optics/longitudinal-chromatic-aberration.js.map +1 -1
- package/dist/optics/pupil-vignetting.js +1 -7
- package/dist/optics/pupil-vignetting.js.map +1 -1
- package/dist/optics/radial-distortion.js +1 -6
- package/dist/optics/radial-distortion.js.map +1 -1
- package/dist/optics/scene-to-sensor-irradiance.d.ts +13 -0
- package/dist/optics/scene-to-sensor-irradiance.js +11 -96
- package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
- package/dist/optics/stray-light.d.ts +1 -0
- package/dist/optics/stray-light.js +1 -1
- package/dist/optics/stray-light.js.map +1 -1
- package/dist/optics/zernike-wavefront.js +1 -7
- package/dist/optics/zernike-wavefront.js.map +1 -1
- package/dist/output/capture-geometry.js +1 -8
- package/dist/output/capture-geometry.js.map +1 -1
- package/dist/output/crop-to-match-focal-length.d.ts +62 -0
- package/dist/output/crop-to-match-focal-length.js +63 -0
- package/dist/output/crop-to-match-focal-length.js.map +1 -0
- package/dist/output/developed-lens-corrections.d.ts +62 -0
- package/dist/output/developed-lens-corrections.js +135 -0
- package/dist/output/developed-lens-corrections.js.map +1 -0
- package/dist/output/generic-lens-corrections.d.ts +5 -7
- package/dist/output/generic-lens-corrections.js +11 -10
- package/dist/output/generic-lens-corrections.js.map +1 -1
- package/dist/output/geometric-transforms.js +1 -4
- package/dist/output/geometric-transforms.js.map +1 -1
- package/dist/output/lens-corrections.d.ts +12 -2
- package/dist/output/lens-corrections.js +22 -7
- package/dist/output/lens-corrections.js.map +1 -1
- package/dist/output/native-capture-sdr.d.ts +2 -2
- package/dist/output/native-capture-sdr.js +3 -2
- package/dist/output/native-capture-sdr.js.map +1 -1
- package/dist/output/print-contrast-reference.js +1 -1
- package/dist/output/print-contrast-reference.js.map +1 -1
- package/dist/output/print-size-blur-noise.d.ts +110 -0
- package/dist/output/print-size-blur-noise.js +138 -0
- package/dist/output/print-size-blur-noise.js.map +1 -0
- package/dist/processing/development-detail.d.ts +29 -0
- package/dist/processing/development-detail.js +128 -107
- package/dist/processing/development-detail.js.map +1 -1
- package/dist/schema/illumination-temporal.js +3 -72
- package/dist/schema/illumination-temporal.js.map +1 -1
- package/dist/schema/illumination.d.ts +1 -0
- package/dist/schema/illumination.js +2 -65
- package/dist/schema/illumination.js.map +1 -1
- package/dist/schema/scene-radiance-temporal.js +2 -14
- package/dist/schema/scene-radiance-temporal.js.map +1 -1
- package/dist/schema/scene-radiance.js +2 -60
- package/dist/schema/scene-radiance.js.map +1 -1
- package/dist/schema/validation.d.ts +2 -0
- package/dist/schema/validation.js +2 -17
- package/dist/schema/validation.js.map +1 -1
- package/dist/sensor/accumulated-charge.js +2 -59
- package/dist/sensor/accumulated-charge.js.map +1 -1
- package/dist/sensor/architecture.js +1 -16
- package/dist/sensor/architecture.js.map +1 -1
- package/dist/sensor/camera-saturation-capacity.d.ts +1 -0
- package/dist/sensor/camera-saturation-capacity.js +3 -55
- package/dist/sensor/camera-saturation-capacity.js.map +1 -1
- package/dist/sensor/capture-color-sampling-binding.js +1 -26
- package/dist/sensor/capture-color-sampling-binding.js.map +1 -1
- package/dist/sensor/capture-mode-timing.js +1 -39
- package/dist/sensor/capture-mode-timing.js.map +1 -1
- package/dist/sensor/capture-mode.js +1 -23
- package/dist/sensor/capture-mode.js.map +1 -1
- package/dist/sensor/color-sampling.js +1 -26
- package/dist/sensor/color-sampling.js.map +1 -1
- package/dist/sensor/constant-rate-temporal-integration.js +2 -46
- package/dist/sensor/constant-rate-temporal-integration.js.map +1 -1
- package/dist/sensor/dark-current.js +2 -45
- package/dist/sensor/dark-current.js.map +1 -1
- package/dist/sensor/eqe-electron-rate.js +2 -41
- package/dist/sensor/eqe-electron-rate.js.map +1 -1
- package/dist/sensor/exposure-window.d.ts +7 -0
- package/dist/sensor/exposure-window.js +9 -24
- package/dist/sensor/exposure-window.js.map +1 -1
- package/dist/sensor/iso-gain.js +1 -7
- package/dist/sensor/iso-gain.js.map +1 -1
- package/dist/sensor/iso-signal-chain.js +1 -43
- package/dist/sensor/iso-signal-chain.js.map +1 -1
- package/dist/sensor/optical-stack.js +1 -25
- package/dist/sensor/optical-stack.js.map +1 -1
- package/dist/sensor/photon-energy.js +1 -26
- package/dist/sensor/photon-energy.js.map +1 -1
- package/dist/sensor/physical-charge-capacity.js +3 -77
- package/dist/sensor/physical-charge-capacity.js.map +1 -1
- package/dist/sensor/radiometry-readiness.js +2 -23
- package/dist/sensor/radiometry-readiness.js.map +1 -1
- package/dist/sensor/raw-readout.d.ts +3 -0
- package/dist/sensor/raw-readout.js +4 -66
- package/dist/sensor/raw-readout.js.map +1 -1
- package/dist/sensor/raw-reconstruction.js +2 -64
- package/dist/sensor/raw-reconstruction.js.map +1 -1
- package/dist/sensor/readout-exposure-linkage.js +1 -9
- package/dist/sensor/readout-exposure-linkage.js.map +1 -1
- package/dist/sensor/readout-timing.js +4 -79
- package/dist/sensor/readout-timing.js.map +1 -1
- package/dist/sensor/response-application-compatibility.d.ts +2 -0
- package/dist/sensor/response-application-compatibility.js +4 -35
- package/dist/sensor/response-application-compatibility.js.map +1 -1
- package/dist/sensor/response-operating-range.d.ts +1 -0
- package/dist/sensor/response-operating-range.js +3 -79
- package/dist/sensor/response-operating-range.js.map +1 -1
- package/dist/sensor/responsivity-photocurrent.js +4 -114
- package/dist/sensor/responsivity-photocurrent.js.map +1 -1
- package/dist/sensor/sampling-aperture.js +1 -25
- package/dist/sensor/sampling-aperture.js.map +1 -1
- package/dist/sensor/sensor-characteristics.d.ts +137 -0
- package/dist/sensor/sensor-characteristics.js +115 -0
- package/dist/sensor/sensor-characteristics.js.map +1 -0
- package/dist/sensor/spatial-sample-reduction.js +3 -24
- package/dist/sensor/spatial-sample-reduction.js.map +1 -1
- package/dist/sensor/spatial-sampling-quadrature.js +1 -3
- package/dist/sensor/spatial-sampling-quadrature.js.map +1 -1
- package/dist/sensor/spatio-spectral-reduction.js +1 -18
- package/dist/sensor/spatio-spectral-reduction.js.map +1 -1
- package/dist/sensor/spectral-coverage.d.ts +10 -1
- package/dist/sensor/spectral-coverage.js +1 -1
- package/dist/sensor/spectral-coverage.js.map +1 -1
- package/dist/sensor/spectral-quadrature.js +3 -41
- package/dist/sensor/spectral-quadrature.js.map +1 -1
- package/dist/sensor/spectral-response.js +1 -47
- package/dist/sensor/spectral-response.js.map +1 -1
- package/dist/sensor/temporal-photo-signal.d.ts +3 -0
- package/dist/sensor/temporal-photo-signal.js +5 -2
- package/dist/sensor/temporal-photo-signal.js.map +1 -1
- package/dist/stabilization/camera-shake.js +1 -6
- package/dist/stabilization/camera-shake.js.map +1 -1
- package/dist/stabilization/system.d.ts +9 -0
- package/dist/stabilization/system.js +7 -86
- package/dist/stabilization/system.js.map +1 -1
- package/docs/AGENT_GUIDE.md +5 -0
- package/docs/API_REFERENCE.md +116 -3
- package/docs/QUICK_START.md +178 -14
- package/docs/USAGE.md +111 -3
- package/docs/api/capture-native-raw-dng.md +6 -0
- package/docs/api/core-version.md +1 -1
- package/docs/api/equipment-generic-lens-catalogue.md +7 -2
- package/docs/api/exports.json +203 -3
- package/docs/api/exposure-filtered-exposure-time.md +105 -0
- package/docs/api/facade-develop-joined-parts.md +32 -0
- package/docs/api/facade-display-view-gpu.md +5 -2
- package/docs/api/facade-fast-methods.md +91 -0
- package/docs/api/facade-simulate-capture.md +72 -16
- package/docs/api/facade-simulate-display-view.md +3 -2
- package/docs/api/optics-aperture-diameter.md +51 -0
- package/docs/api/optics-detail-limit.md +203 -0
- package/docs/api/optics-generic-nd-filter-presets.md +34 -0
- package/docs/api/optics-lens-psf-profile.md +3 -1
- package/docs/api/output-crop-to-match-focal-length.md +67 -0
- package/docs/api/output-developed-lens-corrections.md +12 -0
- package/docs/api/output-generic-lens-corrections.md +3 -10
- package/docs/api/output-lens-corrections.md +11 -1
- package/docs/api/output-print-size-blur-noise.md +115 -0
- package/docs/api/sensor-sensor-characteristics.md +105 -0
- package/llms.txt +5 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scene-radiance-temporal.js","sourceRoot":"","sources":["../../src/schema/scene-radiance-temporal.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Scene radiance over an exposure window, in two steps.\n *\n * 1. Plan: list the times (nodes) at which a scene-radiance provider (a renderer or other\n * source of scene light) must report radiance during one local exposure window.\n * 2. Reduce: combine the provider's per-wavelength results over that window.\n *\n * Each returned sample must match its planned node, time and result identity exactly.\n * Uncertainty stays per node and is not combined, because no correlation or independence\n * is assumed.\n * @see docs/SCENE_RADIANCE_AND_ILLUMINATION.md for equations, coordinate/unit conventions, blockers\n * and support limits.\n */\n\nimport { InvalidScientificInputError, requirePositiveInteger } from \"../core/validation.js\";\nimport type { RasterPoint } from \"../output/capture-geometry.js\";\nimport {\n parseSceneRadianceEvaluationRequest,\n parseSceneRadianceEvaluationResult,\n type SceneRadianceEvaluationRequest,\n type SceneRadianceEvaluationResult\n} from \"./scene-radiance.js\";\nimport type {\n ResolvedCaptureModeTiming\n} from \"../sensor/capture-mode-timing.js\";\nimport { requireInputKeys } from \"../core/record-validation.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\n\nexport const SCENE_RADIANCE_TEMPORAL_SAMPLING_PLAN_VERSION =\n \"0.1.0\" as const;\n\nexport interface SceneRadianceTemporalQuery {\n providerProfileId: string;\n sceneId: string;\n illuminationProfileId: string;\n materialResponseProfileId: string;\n target:\n SceneRadianceEvaluationRequest[\"target\"];\n wavelengthNanometers: number;\n wavelengthBasis:\n SceneRadianceEvaluationRequest[\"wavelengthBasis\"];\n}\n\nexport interface CreateSceneRadianceTemporalSamplingPlanInput {\n planId: string;\n timing:\n ResolvedCaptureModeTiming;\n destinationPointNative:\n RasterPoint;\n temporalSampleCount: number;\n query:\n SceneRadianceTemporalQuery;\n}\n\nexport interface SceneRadianceTemporalSamplingNode {\n nodeId: string;\n expectedResultSampleId: string;\n temporalSampleIndex: number;\n localExposurePhase: number;\n captureTimeSecondsFromReference:\n number;\n normalizedTimeWeight: number;\n timeMeasureSeconds: number;\n}\n\nexport interface SceneRadianceTemporalSamplingPlan {\n version:\n typeof SCENE_RADIANCE_TEMPORAL_SAMPLING_PLAN_VERSION;\n planId: string;\n timeReference:\n \"first-opening-boundary-phase\";\n timingProfileIdentity: {\n profileId: string;\n profileVersion: string;\n captureModeId: string;\n };\n destinationPointNative:\n RasterPoint;\n localExposureWindow: {\n startSecondsFromCaptureReference:\n number;\n endSecondsFromCaptureReference:\n number;\n durationSeconds: number;\n };\n temporalSampleCount: number;\n quadratureScheme:\n \"uniform-midpoint\";\n query:\n SceneRadianceTemporalQuery;\n nodes:\n readonly SceneRadianceTemporalSamplingNode[];\n providerMustEvaluateAtNodeCaptureTime:\n true;\n sensorReadoutTimingUsedAsExposureTiming:\n false;\n}\n\nexport interface SceneRadianceTemporalEvaluatedSample {\n nodeId: string;\n captureTimeSecondsFromReference:\n number;\n result:\n SceneRadianceEvaluationResult;\n}\n\nexport interface ReduceSceneRadianceTemporalSamplesInput {\n plan:\n SceneRadianceTemporalSamplingPlan;\n samples:\n readonly SceneRadianceTemporalEvaluatedSample[];\n}\n\nexport interface ReducedSceneRadianceTemporalExposure {\n version:\n typeof SCENE_RADIANCE_TEMPORAL_SAMPLING_PLAN_VERSION;\n planId: string;\n timeReference:\n \"first-opening-boundary-phase\";\n localExposureWindow:\n SceneRadianceTemporalSamplingPlan[\"localExposureWindow\"];\n temporalSampleCount: number;\n quadratureScheme:\n \"uniform-midpoint\";\n providerProfileId: string;\n sceneId: string;\n wavelengthNanometers: number;\n wavelengthBasis:\n SceneRadianceEvaluationRequest[\"wavelengthBasis\"];\n quantity:\n \"outgoing-spectral-radiance\";\n averageSpectralRadianceWattsPerSquareMeterSteradianNanometer:\n number;\n integratedSpectralRadianceWattSecondsPerSquareMeterSteradianNanometer:\n number;\n nodes: readonly {\n nodeId: string;\n captureTimeSecondsFromReference:\n number;\n normalizedTimeWeight: number;\n timeMeasureSeconds: number;\n spectralRadianceWattsPerSquareMeterSteradianNanometer:\n number;\n evidence:\n SceneRadianceEvaluationResult[\"evidence\"];\n uncertainty:\n SceneRadianceEvaluationResult[\"uncertainty\"];\n }[];\n scientificStatus: \"approximation\";\n uncertaintyPropagation:\n \"not-propagated\";\n uncertaintyLimitation: string;\n sensorReadoutTimingUsedAsExposureTiming:\n false;\n}\n\nfunction requireNonEmptyString(\n value: string,\n path: string\n): string {\n if (\n typeof value !== \"string\" ||\n value.trim().length === 0\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must be a non-empty string.\"\n );\n }\n return value.trim();\n}\n\nfunction samePoint(\n a: RasterPoint,\n b: RasterPoint\n): boolean {\n return (\n a.x === b.x &&\n a.y === b.y\n );\n}\n\nfunction exposureForPoint(\n timing:\n ResolvedCaptureModeTiming,\n point:\n RasterPoint\n): ResolvedCaptureModeTiming[\"exposureWindows\"][\"samples\"][number] {\n const matches =\n timing.exposureWindows.samples.filter(\n (sample) =>\n samePoint(\n sample.pointNative,\n point\n )\n );\n if (matches.length !== 1) {\n throw new InvalidScientificInputError(\n \"destinationPointNative must match exactly one committed exposure-window sample.\"\n );\n }\n return matches[0]!;\n}\n\nfunction parseQuery(\n query:\n SceneRadianceTemporalQuery\n): SceneRadianceTemporalQuery {\n // Reuse the scene-radiance request parser for the shared scene and spectral\n // checks. The placeholder time it needs is not copied into the returned\n // temporal query, where it would be misleading.\n const parsed =\n parseSceneRadianceEvaluationRequest({\n schemaVersion: \"0.1.0\",\n sampleId:\n \"temporal-query-validation\",\n providerProfileId:\n query.providerProfileId,\n sceneId:\n query.sceneId,\n illuminationProfileId:\n query.illuminationProfileId,\n materialResponseProfileId:\n query.materialResponseProfileId,\n target:\n query.target,\n timeSecondsFromExposureStart:\n 0,\n wavelengthNanometers:\n query.wavelengthNanometers,\n wavelengthBasis:\n query.wavelengthBasis\n });\n\n return {\n providerProfileId:\n parsed.providerProfileId,\n sceneId:\n parsed.sceneId,\n illuminationProfileId:\n parsed.illuminationProfileId,\n materialResponseProfileId:\n parsed.materialResponseProfileId,\n target:\n parsed.target,\n wavelengthNanometers:\n parsed.wavelengthNanometers,\n wavelengthBasis:\n parsed.wavelengthBasis\n };\n}\n\n/**\n * Plans the times (nodes) at which a scene-radiance provider must report radiance\n * during one local exposure window. Works with any renderer or provider.\n *\n * Capture time is a separate field, not the older request field\n * timeSecondsFromExposureStart. Providers must evaluate radiance at\n * node.captureTimeSecondsFromReference, measured from the first opening boundary.\n */\nexport function createSceneRadianceTemporalSamplingPlan(\n input:\n CreateSceneRadianceTemporalSamplingPlanInput\n): SceneRadianceTemporalSamplingPlan {\n requireInputKeys(input, \"createSceneRadianceTemporalSamplingPlan\", [\"planId\", \"timing\", \"destinationPointNative\", \"temporalSampleCount\", \"query\"]);\n requirePositiveInteger(\n \"temporalSampleCount\",\n input.temporalSampleCount\n );\n const planId =\n requireNonEmptyString(\n input.planId,\n \"planId\"\n );\n const query =\n parseQuery(input.query);\n const exposure =\n exposureForPoint(\n input.timing,\n input\n .destinationPointNative\n );\n const duration =\n exposure\n .localExposureDurationSeconds;\n\n if (\n !Number.isFinite(duration) ||\n duration <= 0\n ) {\n throw new InvalidScientificInputError(\n \"Scene-radiance temporal sampling requires a positive finite local exposure duration.\"\n );\n }\n\n const normalizedTimeWeight =\n 1 /\n input.temporalSampleCount;\n const timeMeasureSeconds =\n duration /\n input.temporalSampleCount;\n\n const nodes =\n Array.from(\n {\n length:\n input.temporalSampleCount\n },\n (\n _,\n temporalSampleIndex\n ) => {\n const localExposurePhase =\n (temporalSampleIndex +\n 0.5) /\n input.temporalSampleCount;\n const captureTime =\n exposure\n .startOffsetSecondsFromOpeningReference +\n localExposurePhase *\n duration;\n return {\n nodeId:\n planId +\n \":node:\" +\n temporalSampleIndex,\n expectedResultSampleId:\n planId +\n \":radiance:\" +\n temporalSampleIndex,\n temporalSampleIndex,\n localExposurePhase,\n captureTimeSecondsFromReference:\n captureTime,\n normalizedTimeWeight,\n timeMeasureSeconds\n };\n }\n );\n\n return {\n version:\n SCENE_RADIANCE_TEMPORAL_SAMPLING_PLAN_VERSION,\n planId,\n timeReference:\n \"first-opening-boundary-phase\",\n timingProfileIdentity: {\n profileId:\n input.timing\n .timingProfileId,\n profileVersion:\n input.timing\n .timingProfileVersion,\n captureModeId:\n input.timing\n .captureModeId\n },\n destinationPointNative: {\n ...input\n .destinationPointNative\n },\n localExposureWindow: {\n startSecondsFromCaptureReference:\n exposure\n .startOffsetSecondsFromOpeningReference,\n endSecondsFromCaptureReference:\n exposure\n .endOffsetSecondsFromOpeningReference,\n durationSeconds:\n duration\n },\n temporalSampleCount:\n input.temporalSampleCount,\n quadratureScheme:\n \"uniform-midpoint\",\n query,\n nodes,\n providerMustEvaluateAtNodeCaptureTime:\n true,\n sensorReadoutTimingUsedAsExposureTiming:\n false\n };\n}\n\nfunction sameTime(\n a: number,\n b: number\n): boolean {\n const scale =\n Math.max(\n 1,\n Math.abs(a),\n Math.abs(b)\n );\n return (\n Math.abs(a - b) <=\n Number.EPSILON *\n 16 *\n scale\n );\n}\n\n/**\n * Combines the provider's per-wavelength scene radiance over the local exposure window.\n *\n * Each sample must match its planned node, time and result identity exactly.\n * Uncertainty stays per node and is not combined, because no correlation or\n * independence is assumed.\n */\nexport function reduceSceneRadianceTemporalSamples(\n input:\n ReduceSceneRadianceTemporalSamplesInput\n): ReducedSceneRadianceTemporalExposure {\n requireInputKeys(input, \"reduceSceneRadianceTemporalSamples\", [\"plan\", \"samples\"]);\n if (\n !Array.isArray(\n input.samples\n ) ||\n input.samples.length !==\n input.plan.nodes.length\n ) {\n throw new InvalidScientificInputError(\n \"samples must contain exactly one result for every temporal sampling node.\"\n );\n }\n\n const byNode =\n new Map(\n input.samples.map(\n (sample) => [\n sample.nodeId,\n sample\n ] as const\n )\n );\n if (\n byNode.size !==\n input.samples.length\n ) {\n throw new InvalidScientificInputError(\n \"samples must not contain duplicate nodeId values.\"\n );\n }\n\n let average = 0;\n let integrated = 0;\n\n const nodes =\n input.plan.nodes.map(\n (node) => {\n const supplied =\n byNode.get(\n node.nodeId\n );\n if (supplied === undefined) {\n throw new InvalidScientificInputError(\n \"A temporal scene-radiance node result is missing.\"\n );\n }\n if (\n !Number.isFinite(\n supplied\n .captureTimeSecondsFromReference\n ) ||\n !sameTime(\n supplied\n .captureTimeSecondsFromReference,\n node\n .captureTimeSecondsFromReference\n )\n ) {\n throw new InvalidScientificInputError(\n \"Temporal scene-radiance sample time must match its authoritative plan node.\"\n );\n }\n\n const result =\n parseSceneRadianceEvaluationResult(\n supplied.result\n );\n if (\n result.sampleId !==\n node.expectedResultSampleId ||\n result.providerProfileId !==\n input.plan.query\n .providerProfileId ||\n result.sceneId !==\n input.plan.query\n .sceneId ||\n result.wavelengthNanometers !==\n input.plan.query\n .wavelengthNanometers ||\n result.wavelengthBasis !==\n input.plan.query\n .wavelengthBasis\n ) {\n throw new InvalidScientificInputError(\n \"Temporal scene-radiance result identity must match the plan node/query exactly.\"\n );\n }\n\n const value =\n result\n .spectralRadianceWattsPerSquareMeterSteradianNanometer;\n average +=\n value *\n node\n .normalizedTimeWeight;\n integrated +=\n value *\n node\n .timeMeasureSeconds;\n\n return {\n nodeId:\n node.nodeId,\n captureTimeSecondsFromReference:\n node\n .captureTimeSecondsFromReference,\n normalizedTimeWeight:\n node\n .normalizedTimeWeight,\n timeMeasureSeconds:\n node\n .timeMeasureSeconds,\n spectralRadianceWattsPerSquareMeterSteradianNanometer:\n value,\n evidence:\n result.evidence,\n uncertainty:\n result.uncertainty\n };\n }\n );\n\n if (\n !Number.isFinite(average) ||\n average < 0 ||\n !Number.isFinite(\n integrated\n ) ||\n integrated < 0\n ) {\n throw new InvalidScientificInputError(\n \"Reduced temporal scene radiance must remain finite and non-negative.\"\n );\n }\n\n return {\n version:\n SCENE_RADIANCE_TEMPORAL_SAMPLING_PLAN_VERSION,\n planId:\n input.plan.planId,\n timeReference:\n \"first-opening-boundary-phase\",\n localExposureWindow: {\n ...input.plan\n .localExposureWindow\n },\n temporalSampleCount:\n input.plan\n .temporalSampleCount,\n quadratureScheme:\n \"uniform-midpoint\",\n providerProfileId:\n input.plan.query\n .providerProfileId,\n sceneId:\n input.plan.query.sceneId,\n wavelengthNanometers:\n input.plan.query\n .wavelengthNanometers,\n wavelengthBasis:\n input.plan.query\n .wavelengthBasis,\n quantity:\n \"outgoing-spectral-radiance\",\n averageSpectralRadianceWattsPerSquareMeterSteradianNanometer:\n average,\n integratedSpectralRadianceWattSecondsPerSquareMeterSteradianNanometer:\n integrated,\n nodes,\n scientificStatus:\n \"approximation\",\n uncertaintyPropagation:\n \"not-propagated\",\n uncertaintyLimitation:\n \"Per-node scene-radiance uncertainty is preserved; aggregate numeric uncertainty is not propagated because temporal correlation is not assumed.\",\n sensorReadoutTimingUsedAsExposureTiming:\n false\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scene-radiance-temporal.js","sourceRoot":"","sources":["../../src/schema/scene-radiance-temporal.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Scene radiance over an exposure window, in two steps.\n *\n * 1. Plan: list the times (nodes) at which a scene-radiance provider (a renderer or other\n * source of scene light) must report radiance during one local exposure window.\n * 2. Reduce: combine the provider's per-wavelength results over that window.\n *\n * Each returned sample must match its planned node, time and result identity exactly.\n * Uncertainty stays per node and is not combined, because no correlation or independence\n * is assumed.\n * @see docs/SCENE_RADIANCE_AND_ILLUMINATION.md for equations, coordinate/unit conventions, blockers\n * and support limits.\n */\n\nimport { InvalidScientificInputError, requirePositiveInteger } from \"../core/validation.js\";\nimport type { RasterPoint } from \"../output/capture-geometry.js\";\nimport {\n parseSceneRadianceEvaluationRequest,\n parseSceneRadianceEvaluationResult,\n type SceneRadianceEvaluationRequest,\n type SceneRadianceEvaluationResult\n} from \"./scene-radiance.js\";\nimport type {\n ResolvedCaptureModeTiming\n} from \"../sensor/capture-mode-timing.js\";\nimport { requireInputKeys, requireTrimmedConfigString as requireNonEmptyString } from \"../core/record-validation.js\";\nimport { sameSite as samePoint } from \"../core/shared-helpers.js\";\n\nexport const SCENE_RADIANCE_TEMPORAL_SAMPLING_PLAN_VERSION =\n \"0.1.0\" as const;\n\nexport interface SceneRadianceTemporalQuery {\n providerProfileId: string;\n sceneId: string;\n illuminationProfileId: string;\n materialResponseProfileId: string;\n target:\n SceneRadianceEvaluationRequest[\"target\"];\n wavelengthNanometers: number;\n wavelengthBasis:\n SceneRadianceEvaluationRequest[\"wavelengthBasis\"];\n}\n\nexport interface CreateSceneRadianceTemporalSamplingPlanInput {\n planId: string;\n timing:\n ResolvedCaptureModeTiming;\n destinationPointNative:\n RasterPoint;\n temporalSampleCount: number;\n query:\n SceneRadianceTemporalQuery;\n}\n\nexport interface SceneRadianceTemporalSamplingNode {\n nodeId: string;\n expectedResultSampleId: string;\n temporalSampleIndex: number;\n localExposurePhase: number;\n captureTimeSecondsFromReference:\n number;\n normalizedTimeWeight: number;\n timeMeasureSeconds: number;\n}\n\nexport interface SceneRadianceTemporalSamplingPlan {\n version:\n typeof SCENE_RADIANCE_TEMPORAL_SAMPLING_PLAN_VERSION;\n planId: string;\n timeReference:\n \"first-opening-boundary-phase\";\n timingProfileIdentity: {\n profileId: string;\n profileVersion: string;\n captureModeId: string;\n };\n destinationPointNative:\n RasterPoint;\n localExposureWindow: {\n startSecondsFromCaptureReference:\n number;\n endSecondsFromCaptureReference:\n number;\n durationSeconds: number;\n };\n temporalSampleCount: number;\n quadratureScheme:\n \"uniform-midpoint\";\n query:\n SceneRadianceTemporalQuery;\n nodes:\n readonly SceneRadianceTemporalSamplingNode[];\n providerMustEvaluateAtNodeCaptureTime:\n true;\n sensorReadoutTimingUsedAsExposureTiming:\n false;\n}\n\nexport interface SceneRadianceTemporalEvaluatedSample {\n nodeId: string;\n captureTimeSecondsFromReference:\n number;\n result:\n SceneRadianceEvaluationResult;\n}\n\nexport interface ReduceSceneRadianceTemporalSamplesInput {\n plan:\n SceneRadianceTemporalSamplingPlan;\n samples:\n readonly SceneRadianceTemporalEvaluatedSample[];\n}\n\nexport interface ReducedSceneRadianceTemporalExposure {\n version:\n typeof SCENE_RADIANCE_TEMPORAL_SAMPLING_PLAN_VERSION;\n planId: string;\n timeReference:\n \"first-opening-boundary-phase\";\n localExposureWindow:\n SceneRadianceTemporalSamplingPlan[\"localExposureWindow\"];\n temporalSampleCount: number;\n quadratureScheme:\n \"uniform-midpoint\";\n providerProfileId: string;\n sceneId: string;\n wavelengthNanometers: number;\n wavelengthBasis:\n SceneRadianceEvaluationRequest[\"wavelengthBasis\"];\n quantity:\n \"outgoing-spectral-radiance\";\n averageSpectralRadianceWattsPerSquareMeterSteradianNanometer:\n number;\n integratedSpectralRadianceWattSecondsPerSquareMeterSteradianNanometer:\n number;\n nodes: readonly {\n nodeId: string;\n captureTimeSecondsFromReference:\n number;\n normalizedTimeWeight: number;\n timeMeasureSeconds: number;\n spectralRadianceWattsPerSquareMeterSteradianNanometer:\n number;\n evidence:\n SceneRadianceEvaluationResult[\"evidence\"];\n uncertainty:\n SceneRadianceEvaluationResult[\"uncertainty\"];\n }[];\n scientificStatus: \"approximation\";\n uncertaintyPropagation:\n \"not-propagated\";\n uncertaintyLimitation: string;\n sensorReadoutTimingUsedAsExposureTiming:\n false;\n}\n\nfunction exposureForPoint(\n timing:\n ResolvedCaptureModeTiming,\n point:\n RasterPoint\n): ResolvedCaptureModeTiming[\"exposureWindows\"][\"samples\"][number] {\n const matches =\n timing.exposureWindows.samples.filter(\n (sample) =>\n samePoint(\n sample.pointNative,\n point\n )\n );\n if (matches.length !== 1) {\n throw new InvalidScientificInputError(\n \"destinationPointNative must match exactly one committed exposure-window sample.\"\n );\n }\n return matches[0]!;\n}\n\nfunction parseQuery(\n query:\n SceneRadianceTemporalQuery\n): SceneRadianceTemporalQuery {\n // Reuse the scene-radiance request parser for the shared scene and spectral\n // checks. The placeholder time it needs is not copied into the returned\n // temporal query, where it would be misleading.\n const parsed =\n parseSceneRadianceEvaluationRequest({\n schemaVersion: \"0.1.0\",\n sampleId:\n \"temporal-query-validation\",\n providerProfileId:\n query.providerProfileId,\n sceneId:\n query.sceneId,\n illuminationProfileId:\n query.illuminationProfileId,\n materialResponseProfileId:\n query.materialResponseProfileId,\n target:\n query.target,\n timeSecondsFromExposureStart:\n 0,\n wavelengthNanometers:\n query.wavelengthNanometers,\n wavelengthBasis:\n query.wavelengthBasis\n });\n\n return {\n providerProfileId:\n parsed.providerProfileId,\n sceneId:\n parsed.sceneId,\n illuminationProfileId:\n parsed.illuminationProfileId,\n materialResponseProfileId:\n parsed.materialResponseProfileId,\n target:\n parsed.target,\n wavelengthNanometers:\n parsed.wavelengthNanometers,\n wavelengthBasis:\n parsed.wavelengthBasis\n };\n}\n\n/**\n * Plans the times (nodes) at which a scene-radiance provider must report radiance\n * during one local exposure window. Works with any renderer or provider.\n *\n * Capture time is a separate field, not the older request field\n * timeSecondsFromExposureStart. Providers must evaluate radiance at\n * node.captureTimeSecondsFromReference, measured from the first opening boundary.\n */\nexport function createSceneRadianceTemporalSamplingPlan(\n input:\n CreateSceneRadianceTemporalSamplingPlanInput\n): SceneRadianceTemporalSamplingPlan {\n requireInputKeys(input, \"createSceneRadianceTemporalSamplingPlan\", [\"planId\", \"timing\", \"destinationPointNative\", \"temporalSampleCount\", \"query\"]);\n requirePositiveInteger(\n \"temporalSampleCount\",\n input.temporalSampleCount\n );\n const planId =\n requireNonEmptyString(\n input.planId,\n \"planId\"\n );\n const query =\n parseQuery(input.query);\n const exposure =\n exposureForPoint(\n input.timing,\n input\n .destinationPointNative\n );\n const duration =\n exposure\n .localExposureDurationSeconds;\n\n if (\n !Number.isFinite(duration) ||\n duration <= 0\n ) {\n throw new InvalidScientificInputError(\n \"Scene-radiance temporal sampling requires a positive finite local exposure duration.\"\n );\n }\n\n const normalizedTimeWeight =\n 1 /\n input.temporalSampleCount;\n const timeMeasureSeconds =\n duration /\n input.temporalSampleCount;\n\n const nodes =\n Array.from(\n {\n length:\n input.temporalSampleCount\n },\n (\n _,\n temporalSampleIndex\n ) => {\n const localExposurePhase =\n (temporalSampleIndex +\n 0.5) /\n input.temporalSampleCount;\n const captureTime =\n exposure\n .startOffsetSecondsFromOpeningReference +\n localExposurePhase *\n duration;\n return {\n nodeId:\n planId +\n \":node:\" +\n temporalSampleIndex,\n expectedResultSampleId:\n planId +\n \":radiance:\" +\n temporalSampleIndex,\n temporalSampleIndex,\n localExposurePhase,\n captureTimeSecondsFromReference:\n captureTime,\n normalizedTimeWeight,\n timeMeasureSeconds\n };\n }\n );\n\n return {\n version:\n SCENE_RADIANCE_TEMPORAL_SAMPLING_PLAN_VERSION,\n planId,\n timeReference:\n \"first-opening-boundary-phase\",\n timingProfileIdentity: {\n profileId:\n input.timing\n .timingProfileId,\n profileVersion:\n input.timing\n .timingProfileVersion,\n captureModeId:\n input.timing\n .captureModeId\n },\n destinationPointNative: {\n ...input\n .destinationPointNative\n },\n localExposureWindow: {\n startSecondsFromCaptureReference:\n exposure\n .startOffsetSecondsFromOpeningReference,\n endSecondsFromCaptureReference:\n exposure\n .endOffsetSecondsFromOpeningReference,\n durationSeconds:\n duration\n },\n temporalSampleCount:\n input.temporalSampleCount,\n quadratureScheme:\n \"uniform-midpoint\",\n query,\n nodes,\n providerMustEvaluateAtNodeCaptureTime:\n true,\n sensorReadoutTimingUsedAsExposureTiming:\n false\n };\n}\n\nfunction sameTime(\n a: number,\n b: number\n): boolean {\n const scale =\n Math.max(\n 1,\n Math.abs(a),\n Math.abs(b)\n );\n return (\n Math.abs(a - b) <=\n Number.EPSILON *\n 16 *\n scale\n );\n}\n\n/**\n * Combines the provider's per-wavelength scene radiance over the local exposure window.\n *\n * Each sample must match its planned node, time and result identity exactly.\n * Uncertainty stays per node and is not combined, because no correlation or\n * independence is assumed.\n */\nexport function reduceSceneRadianceTemporalSamples(\n input:\n ReduceSceneRadianceTemporalSamplesInput\n): ReducedSceneRadianceTemporalExposure {\n requireInputKeys(input, \"reduceSceneRadianceTemporalSamples\", [\"plan\", \"samples\"]);\n if (\n !Array.isArray(\n input.samples\n ) ||\n input.samples.length !==\n input.plan.nodes.length\n ) {\n throw new InvalidScientificInputError(\n \"samples must contain exactly one result for every temporal sampling node.\"\n );\n }\n\n const byNode =\n new Map(\n input.samples.map(\n (sample) => [\n sample.nodeId,\n sample\n ] as const\n )\n );\n if (\n byNode.size !==\n input.samples.length\n ) {\n throw new InvalidScientificInputError(\n \"samples must not contain duplicate nodeId values.\"\n );\n }\n\n let average = 0;\n let integrated = 0;\n\n const nodes =\n input.plan.nodes.map(\n (node) => {\n const supplied =\n byNode.get(\n node.nodeId\n );\n if (supplied === undefined) {\n throw new InvalidScientificInputError(\n \"A temporal scene-radiance node result is missing.\"\n );\n }\n if (\n !Number.isFinite(\n supplied\n .captureTimeSecondsFromReference\n ) ||\n !sameTime(\n supplied\n .captureTimeSecondsFromReference,\n node\n .captureTimeSecondsFromReference\n )\n ) {\n throw new InvalidScientificInputError(\n \"Temporal scene-radiance sample time must match its authoritative plan node.\"\n );\n }\n\n const result =\n parseSceneRadianceEvaluationResult(\n supplied.result\n );\n if (\n result.sampleId !==\n node.expectedResultSampleId ||\n result.providerProfileId !==\n input.plan.query\n .providerProfileId ||\n result.sceneId !==\n input.plan.query\n .sceneId ||\n result.wavelengthNanometers !==\n input.plan.query\n .wavelengthNanometers ||\n result.wavelengthBasis !==\n input.plan.query\n .wavelengthBasis\n ) {\n throw new InvalidScientificInputError(\n \"Temporal scene-radiance result identity must match the plan node/query exactly.\"\n );\n }\n\n const value =\n result\n .spectralRadianceWattsPerSquareMeterSteradianNanometer;\n average +=\n value *\n node\n .normalizedTimeWeight;\n integrated +=\n value *\n node\n .timeMeasureSeconds;\n\n return {\n nodeId:\n node.nodeId,\n captureTimeSecondsFromReference:\n node\n .captureTimeSecondsFromReference,\n normalizedTimeWeight:\n node\n .normalizedTimeWeight,\n timeMeasureSeconds:\n node\n .timeMeasureSeconds,\n spectralRadianceWattsPerSquareMeterSteradianNanometer:\n value,\n evidence:\n result.evidence,\n uncertainty:\n result.uncertainty\n };\n }\n );\n\n if (\n !Number.isFinite(average) ||\n average < 0 ||\n !Number.isFinite(\n integrated\n ) ||\n integrated < 0\n ) {\n throw new InvalidScientificInputError(\n \"Reduced temporal scene radiance must remain finite and non-negative.\"\n );\n }\n\n return {\n version:\n SCENE_RADIANCE_TEMPORAL_SAMPLING_PLAN_VERSION,\n planId:\n input.plan.planId,\n timeReference:\n \"first-opening-boundary-phase\",\n localExposureWindow: {\n ...input.plan\n .localExposureWindow\n },\n temporalSampleCount:\n input.plan\n .temporalSampleCount,\n quadratureScheme:\n \"uniform-midpoint\",\n providerProfileId:\n input.plan.query\n .providerProfileId,\n sceneId:\n input.plan.query.sceneId,\n wavelengthNanometers:\n input.plan.query\n .wavelengthNanometers,\n wavelengthBasis:\n input.plan.query\n .wavelengthBasis,\n quantity:\n \"outgoing-spectral-radiance\",\n averageSpectralRadianceWattsPerSquareMeterSteradianNanometer:\n average,\n integratedSpectralRadianceWattSecondsPerSquareMeterSteradianNanometer:\n integrated,\n nodes,\n scientificStatus:\n \"approximation\",\n uncertaintyPropagation:\n \"not-propagated\",\n uncertaintyLimitation:\n \"Per-node scene-radiance uncertainty is preserved; aggregate numeric uncertainty is not propagated because temporal correlation is not assumed.\",\n sensorReadoutTimingUsedAsExposureTiming:\n false\n };\n}\n"]}
|
|
@@ -12,59 +12,12 @@
|
|
|
12
12
|
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
13
13
|
import { parseEvidenceList } from "../core/evidence-provenance.js";
|
|
14
14
|
import { parseSpectralWavelengthBasis, parseSpectralWavelengthRangeNanometers } from "../core/spectral.js";
|
|
15
|
-
import { requireInputObject, requireInputArray, requireInputKeys,
|
|
15
|
+
import { requireInputObject, requireInputArray, requireInputKeys, rejectUnknownVariantFields, UNCERTAINTY_VARIANT_FIELDS, requireConfigRecord as requireRecord, requireTrimmedConfigString as requireNonEmptyString, requireConfigFiniteNumber as requireFinite, parseConfigLimitations as parseLimitations, requireConfigFraction as requireFraction, requireConfigNumberAtLeastZero as requireNonNegativeFinite } from "../core/record-validation.js";
|
|
16
16
|
import { hypot3 } from "../core/portable-math.js";
|
|
17
|
+
import { parseVector3 } from "./illumination.js";
|
|
17
18
|
export const SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION = "0.1.0";
|
|
18
19
|
export const SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION = "0.1.0";
|
|
19
20
|
export const SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION = "0.1.0";
|
|
20
|
-
function requireRecord(value, path, allowedKeys) {
|
|
21
|
-
if (typeof value !== "object" ||
|
|
22
|
-
value === null ||
|
|
23
|
-
Array.isArray(value)) {
|
|
24
|
-
throw new InvalidConfigurationError(path + " must be an object.");
|
|
25
|
-
}
|
|
26
|
-
if (allowedKeys !== null)
|
|
27
|
-
rejectUnknownFields(value, allowedKeys, path);
|
|
28
|
-
return value;
|
|
29
|
-
}
|
|
30
|
-
function requireNonEmptyString(value, path) {
|
|
31
|
-
if (typeof value !== "string" ||
|
|
32
|
-
value.trim().length === 0) {
|
|
33
|
-
throw new InvalidConfigurationError(path + " must be a non-empty string.");
|
|
34
|
-
}
|
|
35
|
-
return value.trim();
|
|
36
|
-
}
|
|
37
|
-
function requireFinite(value, path) {
|
|
38
|
-
if (typeof value !== "number" ||
|
|
39
|
-
!Number.isFinite(value)) {
|
|
40
|
-
throw new InvalidConfigurationError(path + " must be a finite number.");
|
|
41
|
-
}
|
|
42
|
-
return value;
|
|
43
|
-
}
|
|
44
|
-
function requireNonNegativeFinite(value, path) {
|
|
45
|
-
const number = requireFinite(value, path);
|
|
46
|
-
if (number < 0) {
|
|
47
|
-
throw new InvalidConfigurationError(path +
|
|
48
|
-
" must be greater than or equal to zero.");
|
|
49
|
-
}
|
|
50
|
-
return number;
|
|
51
|
-
}
|
|
52
|
-
function requireFraction(value, path) {
|
|
53
|
-
const number = requireFinite(value, path);
|
|
54
|
-
if (number < 0 || number > 1) {
|
|
55
|
-
throw new InvalidConfigurationError(path +
|
|
56
|
-
" must be a finite fraction from 0 through 1.");
|
|
57
|
-
}
|
|
58
|
-
return number;
|
|
59
|
-
}
|
|
60
|
-
function parseVector3(value, path) {
|
|
61
|
-
const record = requireRecord(value, path, ["x", "y", "z"]);
|
|
62
|
-
return {
|
|
63
|
-
x: requireFinite(record.x, path + ".x"),
|
|
64
|
-
y: requireFinite(record.y, path + ".y"),
|
|
65
|
-
z: requireFinite(record.z, path + ".z")
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
21
|
function parseUnitDirection(value, path) {
|
|
69
22
|
const vector = parseVector3(value, path);
|
|
70
23
|
const length = hypot3(vector.x, vector.y, vector.z);
|
|
@@ -93,17 +46,6 @@ function parseUncertainty(value, path) {
|
|
|
93
46
|
}
|
|
94
47
|
throw new InvalidConfigurationError(path + ".kind is invalid.");
|
|
95
48
|
}
|
|
96
|
-
function parseLimitations(value, path) {
|
|
97
|
-
if (!Array.isArray(value)) {
|
|
98
|
-
throw new InvalidConfigurationError(path + " must be an array.");
|
|
99
|
-
}
|
|
100
|
-
const limitations = value.map((entry, index) => requireNonEmptyString(entry, path + "[" + index + "]"));
|
|
101
|
-
if (new Set(limitations).size !==
|
|
102
|
-
limitations.length) {
|
|
103
|
-
throw new InvalidConfigurationError(path + " must not contain duplicates.");
|
|
104
|
-
}
|
|
105
|
-
return limitations;
|
|
106
|
-
}
|
|
107
49
|
function parseArtifact(value, path) {
|
|
108
50
|
const record = requireRecord(value, path, ["checksumSha256", "id"]);
|
|
109
51
|
const checksumSha256 = requireNonEmptyString(record.checksumSha256, path + ".checksumSha256");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scene-radiance.js","sourceRoot":"","sources":["../../src/schema/scene-radiance.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Contracts for scene-radiance providers: the renderer or other code that reports how much\n * light leaves a scene point toward the camera.\n *\n * It covers material-response metadata, provider capability profiles, single evaluation\n * requests and results, and identity checks between them. The engine validates this data\n * but does not compute scene radiance itself.\n * @see docs/SCENE_RADIANCE_AND_ILLUMINATION.md for equations, coordinate/unit conventions, blockers\n * and support limits.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport {\n parseEvidenceList,\n type EvidenceProvenance\n} from \"../core/evidence-provenance.js\";\nimport {\n parseSpectralWavelengthBasis,\n parseSpectralWavelengthRangeNanometers,\n type SpectralWavelengthBasis,\n type SpectralWavelengthRangeNanometers\n} from \"../core/spectral.js\";\nimport type {\n SceneIlluminationProfile\n} from \"./illumination.js\";\nimport type {\n SceneIlluminationTemporalProfile\n} from \"./illumination-temporal.js\";\nimport type { Vector3 } from \"./scene.js\";\nimport { requireInputObject, requireInputArray, requireInputKeys, rejectUnknownFields, rejectUnknownVariantFields, UNCERTAINTY_VARIANT_FIELDS } from \"../core/record-validation.js\";\nimport { hypot3 } from \"../core/portable-math.js\";\n\ntype UnknownRecord = Record<string, unknown>;\n\nexport const SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION =\n \"0.1.0\" as const;\nexport const SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION =\n \"0.1.0\" as const;\nexport const SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION =\n \"0.1.0\" as const;\n\nexport type SceneRadianceScientificStatus =\n | \"calibrated\"\n | \"approximation\";\n\nexport type SceneRadianceUncertainty =\n | {\n kind: \"relative\";\n fraction: number;\n basis: string;\n }\n | {\n kind: \"not-quantified\";\n limitation: string;\n };\n\nexport interface SceneRadianceDataArtifactReference {\n id: string;\n checksumSha256: string;\n}\n\nexport type SceneMaterialResponseRepresentation =\n | {\n kind: \"unresolved\";\n limitation: string;\n }\n | {\n kind: \"rgb-pbr-approximation\";\n colorSpace: \"linear-srgb\";\n baseColor: {\n red: number;\n green: number;\n blue: number;\n };\n metallic: number;\n roughness: number;\n limitation: string;\n }\n | {\n kind: \"spectral-wavelength-preserving-data\";\n dataArtifact:\n SceneRadianceDataArtifactReference;\n wavelengthBasis:\n SpectralWavelengthBasis;\n wavelengthRangeNanometers:\n SpectralWavelengthRangeNanometers;\n scatteringModel:\n \"provider-defined-wavelength-preserving\";\n scientificStatus:\n SceneRadianceScientificStatus;\n uncertainty:\n SceneRadianceUncertainty;\n wavelengthChangingBehaviorModeled: false;\n emissionModeled: false;\n };\n\nexport interface SceneMaterialResponseDefinition {\n materialResponseId: string;\n evidence: readonly EvidenceProvenance[];\n representation:\n SceneMaterialResponseRepresentation;\n}\n\nexport interface SceneMaterialResponseProfile {\n schemaVersion:\n typeof SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION;\n profileId: string;\n sceneId: string;\n evidence: readonly EvidenceProvenance[];\n materials:\n readonly SceneMaterialResponseDefinition[];\n fluorescenceModeled: false;\n volumetricMaterialTransportModeled: false;\n polarizationModeled: false;\n}\n\nexport type SceneMaterialResponseFidelity =\n | \"spectral-data\"\n | \"rgb-pbr-approximation\"\n | \"mixed\"\n | \"unresolved\";\n\nexport type SceneRadianceProviderSpectralFidelity =\n | \"wavelength-resolved\"\n | \"rgb-derived-approximation\";\n\nexport type SceneRadianceProviderVisibilityFidelity =\n | \"resolved\"\n | \"approximation\"\n | \"not-modeled\";\n\nexport type SceneRadianceProviderTransportFidelity =\n | \"resolved\"\n | \"approximation\"\n | \"not-modeled\";\n\nexport interface SceneRadianceProviderProfile {\n schemaVersion:\n typeof SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION;\n profileId: string;\n sceneId: string;\n illuminationProfileId: string;\n illuminationTemporalProfileId?: string;\n materialResponseProfileId: string;\n outputQuantity:\n \"outgoing-spectral-radiance\";\n outputUnit:\n \"W/m^2/sr/nm\";\n scientificStatus: \"approximation\";\n uncertainty: SceneRadianceUncertainty;\n fidelity: {\n spectral:\n SceneRadianceProviderSpectralFidelity;\n material:\n SceneMaterialResponseFidelity;\n visibility:\n SceneRadianceProviderVisibilityFidelity;\n directTransport:\n SceneRadianceProviderTransportFidelity;\n indirectTransport:\n SceneRadianceProviderTransportFidelity;\n };\n wavelengthChangingTransportModeled: false;\n volumetricTransportModeled: false;\n polarizationModeled: false;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport type SceneRadianceEvaluationTarget =\n | {\n kind: \"surface-point\";\n sceneObjectId: string;\n materialResponseId: string;\n positionM: Vector3;\n outgoingDirectionUnitVector: Vector3;\n }\n | {\n kind: \"environment-direction\";\n outgoingDirectionUnitVector: Vector3;\n };\n\nexport interface SceneRadianceEvaluationRequest {\n schemaVersion:\n typeof SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION;\n sampleId: string;\n providerProfileId: string;\n sceneId: string;\n illuminationProfileId: string;\n materialResponseProfileId: string;\n target: SceneRadianceEvaluationTarget;\n timeSecondsFromExposureStart: number;\n wavelengthNanometers: number;\n wavelengthBasis:\n Exclude<SpectralWavelengthBasis, \"unspecified\">;\n}\n\nexport interface SceneRadianceEvaluationResult {\n schemaVersion:\n typeof SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION;\n sampleId: string;\n providerProfileId: string;\n sceneId: string;\n wavelengthNanometers: number;\n wavelengthBasis:\n Exclude<SpectralWavelengthBasis, \"unspecified\">;\n quantity:\n \"outgoing-spectral-radiance\";\n unit: \"W/m^2/sr/nm\";\n spectralRadianceWattsPerSquareMeterSteradianNanometer:\n number;\n scientificStatus: \"approximation\";\n uncertainty: SceneRadianceUncertainty;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface ValidateSceneRadianceEvaluationBindingsInput {\n providerProfile: SceneRadianceProviderProfile;\n illuminationProfile: SceneIlluminationProfile;\n illuminationTemporalProfile?:\n SceneIlluminationTemporalProfile;\n materialResponseProfile:\n SceneMaterialResponseProfile;\n request: SceneRadianceEvaluationRequest;\n result: SceneRadianceEvaluationResult;\n}\n\nexport interface SceneRadianceEvaluationBindingAssessment {\n providerBindingsMatched: true;\n requestResultIdentityMatched: true;\n materialResponseFidelity:\n SceneMaterialResponseFidelity;\n temporalIlluminationProfileBound:\n boolean;\n calibratedRadianceClaimAuthorized: false;\n sensorPlaneIrradianceCalculated: false;\n opticsApplied: false;\n photonsCalculated: false;\n}\n\nfunction requireRecord(\n value: unknown,\n path: string,\n allowedKeys: readonly string[] | null\n): UnknownRecord {\n if (\n typeof value !== \"object\" ||\n value === null ||\n Array.isArray(value)\n ) {\n throw new InvalidConfigurationError(\n path + \" must be an object.\"\n );\n }\n if (allowedKeys !== null) rejectUnknownFields(value, allowedKeys, path);\n return value as UnknownRecord;\n}\n\nfunction requireNonEmptyString(\n value: unknown,\n path: string\n): string {\n if (\n typeof value !== \"string\" ||\n value.trim().length === 0\n ) {\n throw new InvalidConfigurationError(\n path + \" must be a non-empty string.\"\n );\n }\n return value.trim();\n}\n\nfunction requireFinite(\n value: unknown,\n path: string\n): number {\n if (\n typeof value !== \"number\" ||\n !Number.isFinite(value)\n ) {\n throw new InvalidConfigurationError(\n path + \" must be a finite number.\"\n );\n }\n return value;\n}\n\nfunction requireNonNegativeFinite(\n value: unknown,\n path: string\n): number {\n const number = requireFinite(value, path);\n if (number < 0) {\n throw new InvalidConfigurationError(\n path +\n \" must be greater than or equal to zero.\"\n );\n }\n return number;\n}\n\nfunction requireFraction(\n value: unknown,\n path: string\n): number {\n const number = requireFinite(value, path);\n if (number < 0 || number > 1) {\n throw new InvalidConfigurationError(\n path +\n \" must be a finite fraction from 0 through 1.\"\n );\n }\n return number;\n}\n\nfunction parseVector3(\n value: unknown,\n path: string\n): Vector3 {\n const record = requireRecord(value, path, [\"x\", \"y\", \"z\"]);\n return {\n x: requireFinite(record.x, path + \".x\"),\n y: requireFinite(record.y, path + \".y\"),\n z: requireFinite(record.z, path + \".z\")\n };\n}\n\nfunction parseUnitDirection(\n value: unknown,\n path: string\n): Vector3 {\n const vector = parseVector3(value, path);\n const length = hypot3(\n vector.x,\n vector.y,\n vector.z\n );\n if (\n !Number.isFinite(length) ||\n Math.abs(length - 1) > 1e-9\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must be a unit-length direction vector.\"\n );\n }\n return vector;\n}\n\nfunction parseUncertainty(\n value: unknown,\n path: string\n): SceneRadianceUncertainty {\n const record = requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", UNCERTAINTY_VARIANT_FIELDS, path);\n if (record.kind === \"relative\") {\n return {\n kind: \"relative\",\n fraction: requireNonNegativeFinite(\n record.fraction,\n path + \".fraction\"\n ),\n basis: requireNonEmptyString(\n record.basis,\n path + \".basis\"\n )\n };\n }\n if (record.kind === \"not-quantified\") {\n return {\n kind: \"not-quantified\",\n limitation: requireNonEmptyString(\n record.limitation,\n path + \".limitation\"\n )\n };\n }\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n}\n\nfunction parseLimitations(\n value: unknown,\n path: string\n): readonly string[] {\n if (!Array.isArray(value)) {\n throw new InvalidConfigurationError(\n path + \" must be an array.\"\n );\n }\n const limitations = value.map(\n (entry, index) =>\n requireNonEmptyString(\n entry,\n path + \"[\" + index + \"]\"\n )\n );\n if (\n new Set(limitations).size !==\n limitations.length\n ) {\n throw new InvalidConfigurationError(\n path + \" must not contain duplicates.\"\n );\n }\n return limitations;\n}\n\nfunction parseArtifact(\n value: unknown,\n path: string\n): SceneRadianceDataArtifactReference {\n const record = requireRecord(value, path, [\"checksumSha256\", \"id\"]);\n const checksumSha256 =\n requireNonEmptyString(\n record.checksumSha256,\n path + \".checksumSha256\"\n );\n if (\n !/^[a-f0-9]{64}$/iu.test(\n checksumSha256\n )\n ) {\n throw new InvalidConfigurationError(\n path +\n \".checksumSha256 must be a 64-character SHA-256 hex digest.\"\n );\n }\n return {\n id: requireNonEmptyString(\n record.id,\n path + \".id\"\n ),\n checksumSha256:\n checksumSha256.toLowerCase()\n };\n}\n\nfunction parseMaterialRepresentation(\n value: unknown,\n path: string\n): SceneMaterialResponseRepresentation {\n const record = requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", {\n unresolved: [\"kind\", \"limitation\"],\n \"rgb-pbr-approximation\": [\"kind\", \"colorSpace\", \"baseColor\", \"metallic\", \"roughness\", \"limitation\"],\n \"spectral-wavelength-preserving-data\": [\"kind\", \"dataArtifact\", \"wavelengthBasis\", \"wavelengthRangeNanometers\", \"scatteringModel\",\n \"scientificStatus\", \"uncertainty\", \"wavelengthChangingBehaviorModeled\", \"emissionModeled\"]\n }, path);\n\n if (record.kind === \"unresolved\") {\n return {\n kind: \"unresolved\",\n limitation: requireNonEmptyString(\n record.limitation,\n path + \".limitation\"\n )\n };\n }\n\n if (\n record.kind ===\n \"rgb-pbr-approximation\"\n ) {\n if (record.colorSpace !== \"linear-srgb\") {\n throw new InvalidConfigurationError(\n path +\n '.colorSpace must be \"linear-srgb\".'\n );\n }\n const baseColor = requireRecord(\n record.baseColor,\n path + \".baseColor\", [\"red\", \"green\", \"blue\"]\n );\n return {\n kind: \"rgb-pbr-approximation\",\n colorSpace: \"linear-srgb\",\n baseColor: {\n red: requireFraction(\n baseColor.red,\n path + \".baseColor.red\"\n ),\n green: requireFraction(\n baseColor.green,\n path + \".baseColor.green\"\n ),\n blue: requireFraction(\n baseColor.blue,\n path + \".baseColor.blue\"\n )\n },\n metallic: requireFraction(\n record.metallic,\n path + \".metallic\"\n ),\n roughness: requireFraction(\n record.roughness,\n path + \".roughness\"\n ),\n limitation: requireNonEmptyString(\n record.limitation,\n path + \".limitation\"\n )\n };\n }\n\n if (\n record.kind !==\n \"spectral-wavelength-preserving-data\"\n ) {\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n }\n\n if (\n record.scatteringModel !==\n \"provider-defined-wavelength-preserving\"\n ) {\n throw new InvalidConfigurationError(\n path +\n '.scatteringModel must be \"provider-defined-wavelength-preserving\".'\n );\n }\n if (\n record.scientificStatus !==\n \"calibrated\" &&\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n path + \".scientificStatus is invalid.\"\n );\n }\n const scientificStatus =\n record.scientificStatus;\n const wavelengthBasis =\n parseSpectralWavelengthBasis(\n record.wavelengthBasis,\n path + \".wavelengthBasis\"\n );\n const uncertainty = parseUncertainty(\n record.uncertainty,\n path + \".uncertainty\"\n );\n if (\n scientificStatus === \"calibrated\" &&\n wavelengthBasis === \"unspecified\"\n ) {\n throw new InvalidConfigurationError(\n path +\n \" calibrated spectral material data requires an air or vacuum wavelength basis.\"\n );\n }\n if (\n scientificStatus === \"calibrated\" &&\n uncertainty.kind !== \"relative\"\n ) {\n throw new InvalidConfigurationError(\n path +\n \" calibrated spectral material data requires quantified relative uncertainty.\"\n );\n }\n if (\n record.wavelengthChangingBehaviorModeled !==\n false\n ) {\n throw new InvalidConfigurationError(\n path +\n \".wavelengthChangingBehaviorModeled must be false in schema 0.1.0.\"\n );\n }\n if (record.emissionModeled !== false) {\n throw new InvalidConfigurationError(\n path +\n \".emissionModeled must be false in schema 0.1.0.\"\n );\n }\n\n return {\n kind:\n \"spectral-wavelength-preserving-data\",\n dataArtifact: parseArtifact(\n record.dataArtifact,\n path + \".dataArtifact\"\n ),\n wavelengthBasis,\n wavelengthRangeNanometers:\n parseSpectralWavelengthRangeNanometers(\n record.wavelengthRangeNanometers,\n path + \".wavelengthRangeNanometers\"\n ),\n scatteringModel:\n \"provider-defined-wavelength-preserving\",\n scientificStatus,\n uncertainty,\n wavelengthChangingBehaviorModeled:\n false,\n emissionModeled: false\n };\n}\n\n/**\n * Parses material-response metadata used by a scene-radiance provider.\n *\n * RGB or PBR (physically based rendering) material data is always an approximation.\n * Spectral data is a per-wavelength provider input. It does not itself compute a BSDF\n * (how a surface scatters light), scene radiance, fluorescence, emission, volumetric\n * effects or polarization.\n */\nexport function parseSceneMaterialResponseProfile(\n value: unknown\n): SceneMaterialResponseProfile {\n const record = requireRecord(\n value,\n \"sceneMaterialResponseProfile\", [\"schemaVersion\", \"materials\", \"fluorescenceModeled\", \"volumetricMaterialTransportModeled\", \"polarizationModeled\", \"profileId\", \"sceneId\", \"evidence\"]\n );\n if (\n record.schemaVersion !==\n SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneMaterialResponseProfile.schemaVersion must be \"' +\n SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION +\n '\".'\n );\n }\n if (!Array.isArray(record.materials)) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.materials must be an array.\"\n );\n }\n\n const materials = record.materials.map(\n (entry, index) => {\n const path =\n \"sceneMaterialResponseProfile.materials[\" +\n index +\n \"]\";\n const material = requireRecord(\n entry,\n path, [\"materialResponseId\", \"evidence\", \"representation\"]\n );\n return {\n materialResponseId:\n requireNonEmptyString(\n material.materialResponseId,\n path + \".materialResponseId\"\n ),\n evidence: parseEvidenceList(\n material.evidence,\n path + \".evidence\"\n ),\n representation:\n parseMaterialRepresentation(\n material.representation,\n path + \".representation\"\n )\n };\n }\n );\n const ids = materials.map(\n (entry) => entry.materialResponseId\n );\n if (new Set(ids).size !== ids.length) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.materials[].materialResponseId must not contain duplicates.\"\n );\n }\n\n if (record.fluorescenceModeled !== false) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.fluorescenceModeled must be false in schema 0.1.0.\"\n );\n }\n if (\n record.volumetricMaterialTransportModeled !==\n false\n ) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.volumetricMaterialTransportModeled must be false in schema 0.1.0.\"\n );\n }\n if (record.polarizationModeled !== false) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.polarizationModeled must be false in schema 0.1.0.\"\n );\n }\n\n return {\n schemaVersion:\n SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION,\n profileId: requireNonEmptyString(\n record.profileId,\n \"sceneMaterialResponseProfile.profileId\"\n ),\n sceneId: requireNonEmptyString(\n record.sceneId,\n \"sceneMaterialResponseProfile.sceneId\"\n ),\n evidence: parseEvidenceList(\n record.evidence,\n \"sceneMaterialResponseProfile.evidence\"\n ),\n materials,\n fluorescenceModeled: false,\n volumetricMaterialTransportModeled:\n false,\n polarizationModeled: false\n };\n}\n\n/**\n * Returns the material fidelity a profile supports, choosing the lower level when in doubt.\n */\nexport function assessSceneMaterialResponseFidelity(\n profile: SceneMaterialResponseProfile\n): SceneMaterialResponseFidelity {\n requireInputObject(profile, \"assessSceneMaterialResponseFidelity input\");\n // 2.0.0: the whole profile is validated, so an unknown field at any level is rejected.\n parseSceneMaterialResponseProfile(profile);\n requireInputArray(profile.materials, \"profile.materials\");\n if (\n profile.materials.some(\n (entry) =>\n entry.representation.kind ===\n \"unresolved\"\n )\n ) {\n return \"unresolved\";\n }\n\n const kinds = new Set(\n profile.materials.map(\n (entry) => entry.representation.kind\n )\n );\n if (\n kinds.size === 0 ||\n kinds.has(\"unresolved\")\n ) {\n return \"unresolved\";\n }\n if (\n kinds.size === 1 &&\n kinds.has(\n \"spectral-wavelength-preserving-data\"\n )\n ) {\n return \"spectral-data\";\n }\n if (\n kinds.size === 1 &&\n kinds.has(\"rgb-pbr-approximation\")\n ) {\n return \"rgb-pbr-approximation\";\n }\n return \"mixed\";\n}\n\nfunction parseProviderFidelity(\n value: unknown,\n path: string\n): SceneRadianceProviderProfile[\"fidelity\"] {\n const record = requireRecord(value, path, [\"spectral\", \"material\", \"visibility\", \"directTransport\", \"indirectTransport\"]);\n const spectral = record.spectral;\n if (\n spectral !== \"wavelength-resolved\" &&\n spectral !==\n \"rgb-derived-approximation\"\n ) {\n throw new InvalidConfigurationError(\n path + \".spectral is invalid.\"\n );\n }\n const material = record.material;\n if (\n material !== \"spectral-data\" &&\n material !== \"rgb-pbr-approximation\" &&\n material !== \"mixed\" &&\n material !== \"unresolved\"\n ) {\n throw new InvalidConfigurationError(\n path + \".material is invalid.\"\n );\n }\n const parseVisibility = (\n candidate: unknown,\n candidatePath: string\n ): SceneRadianceProviderVisibilityFidelity => {\n if (\n candidate !== \"resolved\" &&\n candidate !== \"approximation\" &&\n candidate !== \"not-modeled\"\n ) {\n throw new InvalidConfigurationError(\n candidatePath + \" is invalid.\"\n );\n }\n return candidate;\n };\n const parseTransport = (\n candidate: unknown,\n candidatePath: string\n ): SceneRadianceProviderTransportFidelity => {\n if (\n candidate !== \"resolved\" &&\n candidate !== \"approximation\" &&\n candidate !== \"not-modeled\"\n ) {\n throw new InvalidConfigurationError(\n candidatePath + \" is invalid.\"\n );\n }\n return candidate;\n };\n\n return {\n spectral,\n material,\n visibility: parseVisibility(\n record.visibility,\n path + \".visibility\"\n ),\n directTransport: parseTransport(\n record.directTransport,\n path + \".directTransport\"\n ),\n indirectTransport: parseTransport(\n record.indirectTransport,\n path + \".indirectTransport\"\n )\n };\n}\n\n/**\n * Parses a provider's declaration of what it can do (its profile). Works with any renderer.\n *\n * Schema 0.1.0 is approximation-only by design. A provider may use calibrated inputs,\n * but this contract cannot support a claim of calibrated outgoing radiance. That needs\n * later work on complete spectral and light-transport models.\n */\nexport function parseSceneRadianceProviderProfile(\n value: unknown\n): SceneRadianceProviderProfile {\n const record = requireRecord(\n value,\n \"sceneRadianceProviderProfile\", [\"schemaVersion\", \"outputQuantity\", \"outputUnit\", \"scientificStatus\", \"wavelengthChangingTransportModeled\", \"volumetricTransportModeled\", \"polarizationModeled\", \"profileId\", \"sceneId\", \"illuminationProfileId\", \"illuminationTemporalProfileId\", \"materialResponseProfileId\", \"uncertainty\", \"fidelity\", \"evidence\", \"limitations\"]\n );\n if (\n record.schemaVersion !==\n SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceProviderProfile.schemaVersion must be \"' +\n SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION +\n '\".'\n );\n }\n if (\n record.outputQuantity !==\n \"outgoing-spectral-radiance\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceProviderProfile.outputQuantity must be \"outgoing-spectral-radiance\".'\n );\n }\n if (record.outputUnit !== \"W/m^2/sr/nm\") {\n throw new InvalidConfigurationError(\n 'sceneRadianceProviderProfile.outputUnit must be \"W/m^2/sr/nm\".'\n );\n }\n if (\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceProviderProfile.scientificStatus must be \"approximation\" in schema 0.1.0.'\n );\n }\n if (\n record.wavelengthChangingTransportModeled !==\n false ||\n record.volumetricTransportModeled !==\n false ||\n record.polarizationModeled !== false\n ) {\n throw new InvalidConfigurationError(\n \"sceneRadianceProviderProfile wavelength-changing, volumetric, and polarization transport flags must all be false in schema 0.1.0.\"\n );\n }\n\n return {\n schemaVersion:\n SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION,\n profileId: requireNonEmptyString(\n record.profileId,\n \"sceneRadianceProviderProfile.profileId\"\n ),\n sceneId: requireNonEmptyString(\n record.sceneId,\n \"sceneRadianceProviderProfile.sceneId\"\n ),\n illuminationProfileId:\n requireNonEmptyString(\n record.illuminationProfileId,\n \"sceneRadianceProviderProfile.illuminationProfileId\"\n ),\n ...(record.illuminationTemporalProfileId ===\n undefined\n ? {}\n : {\n illuminationTemporalProfileId:\n requireNonEmptyString(\n record.illuminationTemporalProfileId,\n \"sceneRadianceProviderProfile.illuminationTemporalProfileId\"\n )\n }),\n materialResponseProfileId:\n requireNonEmptyString(\n record.materialResponseProfileId,\n \"sceneRadianceProviderProfile.materialResponseProfileId\"\n ),\n outputQuantity:\n \"outgoing-spectral-radiance\",\n outputUnit: \"W/m^2/sr/nm\",\n scientificStatus: \"approximation\",\n uncertainty: parseUncertainty(\n record.uncertainty,\n \"sceneRadianceProviderProfile.uncertainty\"\n ),\n fidelity: parseProviderFidelity(\n record.fidelity,\n \"sceneRadianceProviderProfile.fidelity\"\n ),\n wavelengthChangingTransportModeled:\n false,\n volumetricTransportModeled: false,\n polarizationModeled: false,\n evidence: parseEvidenceList(\n record.evidence,\n \"sceneRadianceProviderProfile.evidence\"\n ),\n limitations: parseLimitations(\n record.limitations,\n \"sceneRadianceProviderProfile.limitations\"\n )\n };\n}\n\nfunction parsePositiveWavelengthNanometers(\n value: unknown,\n path: string\n): number {\n const wavelength = requireFinite(\n value,\n path\n );\n if (wavelength <= 0) {\n throw new InvalidConfigurationError(\n path + \" must be greater than zero.\"\n );\n }\n return wavelength;\n}\n\nfunction parseResolvedWavelengthBasis(\n value: unknown,\n path: string\n): Exclude<\n SpectralWavelengthBasis,\n \"unspecified\"\n> {\n const basis = parseSpectralWavelengthBasis(\n value,\n path\n );\n if (basis === \"unspecified\") {\n throw new InvalidConfigurationError(\n path +\n \" must be air or vacuum for outgoing spectral radiance.\"\n );\n }\n return basis;\n}\n\nfunction parseEvaluationTarget(\n value: unknown,\n path: string\n): SceneRadianceEvaluationTarget {\n const record = requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", {\n \"surface-point\": [\"kind\", \"sceneObjectId\", \"materialResponseId\", \"positionM\", \"outgoingDirectionUnitVector\"],\n \"environment-direction\": [\"kind\", \"outgoingDirectionUnitVector\"]\n }, path);\n if (record.kind === \"surface-point\") {\n return {\n kind: \"surface-point\",\n sceneObjectId: requireNonEmptyString(\n record.sceneObjectId,\n path + \".sceneObjectId\"\n ),\n materialResponseId:\n requireNonEmptyString(\n record.materialResponseId,\n path + \".materialResponseId\"\n ),\n positionM: parseVector3(\n record.positionM,\n path + \".positionM\"\n ),\n outgoingDirectionUnitVector:\n parseUnitDirection(\n record.outgoingDirectionUnitVector,\n path +\n \".outgoingDirectionUnitVector\"\n )\n };\n }\n if (\n record.kind ===\n \"environment-direction\"\n ) {\n return {\n kind: \"environment-direction\",\n outgoingDirectionUnitVector:\n parseUnitDirection(\n record.outgoingDirectionUnitVector,\n path +\n \".outgoingDirectionUnitVector\"\n )\n };\n }\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n}\n\n/**\n * Parses one provider evaluation request at an explicit scene target,\n * physical time, wavelength, and outgoing direction.\n */\nexport function parseSceneRadianceEvaluationRequest(\n value: unknown\n): SceneRadianceEvaluationRequest {\n const record = requireRecord(\n value,\n \"sceneRadianceEvaluationRequest\", [\"schemaVersion\", \"sampleId\", \"providerProfileId\", \"sceneId\", \"illuminationProfileId\", \"materialResponseProfileId\", \"target\", \"timeSecondsFromExposureStart\", \"wavelengthNanometers\", \"wavelengthBasis\"]\n );\n if (\n record.schemaVersion !==\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationRequest.schemaVersion must be \"' +\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION +\n '\".'\n );\n }\n\n return {\n schemaVersion:\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION,\n sampleId: requireNonEmptyString(\n record.sampleId,\n \"sceneRadianceEvaluationRequest.sampleId\"\n ),\n providerProfileId:\n requireNonEmptyString(\n record.providerProfileId,\n \"sceneRadianceEvaluationRequest.providerProfileId\"\n ),\n sceneId: requireNonEmptyString(\n record.sceneId,\n \"sceneRadianceEvaluationRequest.sceneId\"\n ),\n illuminationProfileId:\n requireNonEmptyString(\n record.illuminationProfileId,\n \"sceneRadianceEvaluationRequest.illuminationProfileId\"\n ),\n materialResponseProfileId:\n requireNonEmptyString(\n record.materialResponseProfileId,\n \"sceneRadianceEvaluationRequest.materialResponseProfileId\"\n ),\n target: parseEvaluationTarget(\n record.target,\n \"sceneRadianceEvaluationRequest.target\"\n ),\n timeSecondsFromExposureStart:\n requireNonNegativeFinite(\n record.timeSecondsFromExposureStart,\n \"sceneRadianceEvaluationRequest.timeSecondsFromExposureStart\"\n ),\n wavelengthNanometers:\n parsePositiveWavelengthNanometers(\n record.wavelengthNanometers,\n \"sceneRadianceEvaluationRequest.wavelengthNanometers\"\n ),\n wavelengthBasis:\n parseResolvedWavelengthBasis(\n record.wavelengthBasis,\n \"sceneRadianceEvaluationRequest.wavelengthBasis\"\n )\n };\n}\n\n/**\n * Parses one outgoing spectral-radiance result from a provider.\n *\n * The number is accepted as the provider reported it. Parsing checks units, that the\n * value is finite and nonnegative, provenance and identity fields. It does not prove\n * the provider's light-transport calculation is physically correct.\n */\nexport function parseSceneRadianceEvaluationResult(\n value: unknown\n): SceneRadianceEvaluationResult {\n const record = requireRecord(\n value,\n \"sceneRadianceEvaluationResult\", SCENE_RADIANCE_EVALUATION_RESULT_KEYS\n );\n return parseSceneRadianceEvaluationResultRecord(record, undefined);\n}\n\nconst SCENE_RADIANCE_EVALUATION_RESULT_KEYS = [\"schemaVersion\", \"quantity\", \"unit\", \"scientificStatus\", \"sampleId\", \"providerProfileId\", \"sceneId\", \"wavelengthNanometers\", \"wavelengthBasis\", \"spectralRadianceWattsPerSquareMeterSteradianNanometer\", \"uncertainty\", \"evidence\", \"limitations\"] as const;\n\n/** An earlier fully parsed result whose deep-frozen uncertainty, evidence and limitations records may be reused. */\nexport interface ValidatedSceneRadianceRecords {\n readonly uncertainty: unknown;\n readonly evidence: unknown;\n readonly limitations: unknown;\n readonly parsed: SceneRadianceEvaluationResult;\n}\n\n/**\n * Internal (2.6; not exported from the package): parses a result of an engine-built evaluator\n * (`isInternalSceneRadianceEvaluator`). It runs every check of `parseSceneRadianceEvaluationResult` with the same\n * helpers, order and messages (object shape, schema version, quantity, unit, status, the three identifiers, the\n * wavelength, its basis and the radiance value) except two: the scan for unknown keys, and re-parsing uncertainty,\n * evidence and limitations when they are the very (deep-frozen) objects of `validated`, an earlier result that\n * passed the full parse. Any other result takes the full parse.\n */\nexport function parseSceneRadianceEvaluationResultWithValidatedRecords(\n value: unknown,\n validated: ValidatedSceneRadianceRecords\n): SceneRadianceEvaluationResult {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return parseSceneRadianceEvaluationResult(value);\n const record = value as UnknownRecord;\n if (record.uncertainty !== validated.uncertainty || record.evidence !== validated.evidence || record.limitations !== validated.limitations) {\n return parseSceneRadianceEvaluationResult(value);\n }\n return parseSceneRadianceEvaluationResultRecord(record, validated.parsed);\n}\n\nfunction parseSceneRadianceEvaluationResultRecord(\n record: UnknownRecord,\n validated: SceneRadianceEvaluationResult | undefined\n): SceneRadianceEvaluationResult {\n if (\n record.schemaVersion !==\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationResult.schemaVersion must be \"' +\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION +\n '\".'\n );\n }\n if (\n record.quantity !==\n \"outgoing-spectral-radiance\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationResult.quantity must be \"outgoing-spectral-radiance\".'\n );\n }\n if (record.unit !== \"W/m^2/sr/nm\") {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationResult.unit must be \"W/m^2/sr/nm\".'\n );\n }\n if (\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationResult.scientificStatus must be \"approximation\" in schema 0.1.0.'\n );\n }\n\n return {\n schemaVersion:\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION,\n sampleId: requireNonEmptyString(\n record.sampleId,\n \"sceneRadianceEvaluationResult.sampleId\"\n ),\n providerProfileId:\n requireNonEmptyString(\n record.providerProfileId,\n \"sceneRadianceEvaluationResult.providerProfileId\"\n ),\n sceneId: requireNonEmptyString(\n record.sceneId,\n \"sceneRadianceEvaluationResult.sceneId\"\n ),\n wavelengthNanometers:\n parsePositiveWavelengthNanometers(\n record.wavelengthNanometers,\n \"sceneRadianceEvaluationResult.wavelengthNanometers\"\n ),\n wavelengthBasis:\n parseResolvedWavelengthBasis(\n record.wavelengthBasis,\n \"sceneRadianceEvaluationResult.wavelengthBasis\"\n ),\n quantity:\n \"outgoing-spectral-radiance\",\n unit: \"W/m^2/sr/nm\",\n spectralRadianceWattsPerSquareMeterSteradianNanometer:\n requireNonNegativeFinite(\n record.spectralRadianceWattsPerSquareMeterSteradianNanometer,\n \"sceneRadianceEvaluationResult.spectralRadianceWattsPerSquareMeterSteradianNanometer\"\n ),\n scientificStatus: \"approximation\",\n uncertainty: validated ? validated.uncertainty : parseUncertainty(\n record.uncertainty,\n \"sceneRadianceEvaluationResult.uncertainty\"\n ),\n evidence: validated ? validated.evidence : parseEvidenceList(\n record.evidence,\n \"sceneRadianceEvaluationResult.evidence\"\n ),\n limitations: validated ? validated.limitations : parseLimitations(\n record.limitations,\n \"sceneRadianceEvaluationResult.limitations\"\n )\n };\n}\n\nfunction requireEqual(\n actual: unknown,\n expected: unknown,\n message: string\n): void {\n if (actual !== expected) {\n throw new InvalidConfigurationError(\n message\n );\n }\n}\n\n/**\n * Internal (#453; not exported from the package): the request and result checks of\n * {@link validateSceneRadianceEvaluationBindings} (the request against the three profiles, a surface target's material, and\n * the result against the request), with its messages and order. The profile-to-profile checks before them depend only on the\n * profiles; an engine caller that has run the full function once for these profile objects may run only this part for\n * further requests and results.\n */\nexport function validateSceneRadianceRequestResultBindings(\n providerProfile: ValidateSceneRadianceEvaluationBindingsInput[\"providerProfile\"],\n illuminationProfile: ValidateSceneRadianceEvaluationBindingsInput[\"illuminationProfile\"],\n materialResponseProfile: ValidateSceneRadianceEvaluationBindingsInput[\"materialResponseProfile\"],\n request: ValidateSceneRadianceEvaluationBindingsInput[\"request\"],\n result: ValidateSceneRadianceEvaluationBindingsInput[\"result\"]\n): void {\n requireEqual(\n request.providerProfileId,\n providerProfile.profileId,\n \"Request providerProfileId must match the supplied provider profile.\"\n );\n requireEqual(\n request.sceneId,\n providerProfile.sceneId,\n \"Request sceneId must match the supplied provider profile.\"\n );\n requireEqual(\n request.illuminationProfileId,\n illuminationProfile.profileId,\n \"Request illuminationProfileId must match the supplied illumination profile.\"\n );\n requireEqual(\n request.materialResponseProfileId,\n materialResponseProfile.profileId,\n \"Request materialResponseProfileId must match the supplied material-response profile.\"\n );\n\n if (request.target.kind === \"surface-point\") {\n const target = request.target;\n if (\n !materialResponseProfile.materials.some(\n (material) =>\n material.materialResponseId ===\n target.materialResponseId\n )\n ) {\n throw new InvalidConfigurationError(\n \"Request surface target materialResponseId is not declared by the supplied material-response profile.\"\n );\n }\n }\n\n requireEqual(\n result.sampleId,\n request.sampleId,\n \"Result sampleId must match the request.\"\n );\n requireEqual(\n result.providerProfileId,\n request.providerProfileId,\n \"Result providerProfileId must match the request.\"\n );\n requireEqual(\n result.sceneId,\n request.sceneId,\n \"Result sceneId must match the request.\"\n );\n requireEqual(\n result.wavelengthNanometers,\n request.wavelengthNanometers,\n \"Result wavelengthNanometers must match the request exactly.\"\n );\n requireEqual(\n result.wavelengthBasis,\n request.wavelengthBasis,\n \"Result wavelengthBasis must match the request.\"\n );\n}\n\n/**\n * Checks that a provider result matches its request and profile identities exactly.\n *\n * It never recomputes the radiance value, and never upgrades the provider's\n * approximation to calibrated radiometry.\n */\nexport function validateSceneRadianceEvaluationBindings(\n input:\n ValidateSceneRadianceEvaluationBindingsInput\n): SceneRadianceEvaluationBindingAssessment {\n requireInputKeys(input, \"validateSceneRadianceEvaluationBindings\", [\"providerProfile\", \"illuminationProfile\", \"illuminationTemporalProfile\", \"materialResponseProfile\", \"request\", \"result\"]);\n const {\n providerProfile,\n illuminationProfile,\n illuminationTemporalProfile,\n materialResponseProfile,\n request,\n result\n } = input;\n\n requireInputObject(providerProfile, \"providerProfile input\");\n requireEqual(\n providerProfile.sceneId,\n illuminationProfile.sceneId,\n \"Provider and illumination profiles must reference the same sceneId.\"\n );\n requireEqual(\n providerProfile.sceneId,\n materialResponseProfile.sceneId,\n \"Provider and material-response profiles must reference the same sceneId.\"\n );\n requireEqual(\n providerProfile.illuminationProfileId,\n illuminationProfile.profileId,\n \"Provider illuminationProfileId must match the supplied illumination profile.\"\n );\n requireEqual(\n providerProfile.materialResponseProfileId,\n materialResponseProfile.profileId,\n \"Provider materialResponseProfileId must match the supplied material-response profile.\"\n );\n\n if (\n providerProfile\n .illuminationTemporalProfileId ===\n undefined\n ) {\n if (\n illuminationTemporalProfile !==\n undefined\n ) {\n throw new InvalidConfigurationError(\n \"A temporal illumination profile was supplied but the provider profile does not bind one.\"\n );\n }\n } else {\n if (\n illuminationTemporalProfile ===\n undefined\n ) {\n throw new InvalidConfigurationError(\n \"Provider illuminationTemporalProfileId requires the matching temporal illumination profile.\"\n );\n }\n requireEqual(\n providerProfile\n .illuminationTemporalProfileId,\n illuminationTemporalProfile\n .profileId,\n \"Provider illuminationTemporalProfileId must match the supplied temporal illumination profile.\"\n );\n requireEqual(\n providerProfile.sceneId,\n illuminationTemporalProfile.sceneId,\n \"Provider and temporal illumination profiles must reference the same sceneId.\"\n );\n requireEqual(\n providerProfile\n .illuminationProfileId,\n illuminationTemporalProfile\n .illuminationProfileId,\n \"Temporal illumination profile must bind the provider's illuminationProfileId.\"\n );\n }\n\n const materialResponseFidelity =\n assessSceneMaterialResponseFidelity(\n materialResponseProfile\n );\n requireEqual(\n providerProfile.fidelity.material,\n materialResponseFidelity,\n \"Provider material fidelity must match the supplied material-response profile.\"\n );\n\n validateSceneRadianceRequestResultBindings(providerProfile, illuminationProfile, materialResponseProfile, request, result);\n\n return {\n providerBindingsMatched: true,\n requestResultIdentityMatched: true,\n materialResponseFidelity,\n temporalIlluminationProfileBound:\n illuminationTemporalProfile !==\n undefined,\n calibratedRadianceClaimAuthorized: false,\n sensorPlaneIrradianceCalculated:\n false,\n opticsApplied: false,\n photonsCalculated: false\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scene-radiance.js","sourceRoot":"","sources":["../../src/schema/scene-radiance.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;;;;GASG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EACL,iBAAiB,EAElB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,4BAA4B,EAC5B,sCAAsC,EAGvC,MAAM,qBAAqB,CAAC;AAQ7B,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,mBAAmB,IAAI,aAAa,EAAE,0BAA0B,IAAI,qBAAqB,EAAE,yBAAyB,IAAI,aAAa,EAAE,sBAAsB,IAAI,gBAAgB,EAAE,qBAAqB,IAAI,eAAe,EAAE,8BAA8B,IAAI,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxb,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIjD,MAAM,CAAC,MAAM,8CAA8C,GACzD,OAAgB,CAAC;AACnB,MAAM,CAAC,MAAM,8CAA8C,GACzD,OAAgB,CAAC;AACnB,MAAM,CAAC,MAAM,wCAAwC,GACnD,OAAgB,CAAC;AA0MnB,SAAS,kBAAkB,CACzB,KAAc,EACd,IAAY;IAEZ,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,CACnB,MAAM,CAAC,CAAC,EACR,MAAM,CAAC,CAAC,EACR,MAAM,CAAC,CAAC,CACT,CAAC;IACF,IACE,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,EAC3B,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;YACF,0CAA0C,CAC7C,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,gBAAgB,CACvB,KAAc,EACd,IAAY;IAEZ,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAChD,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,0BAA0B,EAAE,IAAI,CAAC,CAAC;IAC7E,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,wBAAwB,CAChC,MAAM,CAAC,QAAQ,EACf,IAAI,GAAG,WAAW,CACnB;YACD,KAAK,EAAE,qBAAqB,CAC1B,MAAM,CAAC,KAAK,EACZ,IAAI,GAAG,QAAQ,CAChB;SACF,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACrC,OAAO;YACL,IAAI,EAAE,gBAAgB;YACtB,UAAU,EAAE,qBAAqB,CAC/B,MAAM,CAAC,UAAU,EACjB,IAAI,GAAG,aAAa,CACrB;SACF,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,yBAAyB,CACjC,IAAI,GAAG,mBAAmB,CAC3B,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CACpB,KAAc,EACd,IAAY;IAEZ,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC;IACpE,MAAM,cAAc,GAClB,qBAAqB,CACnB,MAAM,CAAC,cAAc,EACrB,IAAI,GAAG,iBAAiB,CACzB,CAAC;IACJ,IACE,CAAC,kBAAkB,CAAC,IAAI,CACtB,cAAc,CACf,EACD,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;YACF,4DAA4D,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO;QACL,EAAE,EAAE,qBAAqB,CACvB,MAAM,CAAC,EAAE,EACT,IAAI,GAAG,KAAK,CACb;QACD,cAAc,EACZ,cAAc,CAAC,WAAW,EAAE;KAC/B,CAAC;AACJ,CAAC;AAED,SAAS,2BAA2B,CAClC,KAAc,EACd,IAAY;IAEZ,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAChD,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE;QACzC,UAAU,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC;QAClC,uBAAuB,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,CAAC;QACnG,qCAAqC,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,iBAAiB;YAC/H,kBAAkB,EAAE,aAAa,EAAE,mCAAmC,EAAE,iBAAiB,CAAC;KAC7F,EAAE,IAAI,CAAC,CAAC;IAET,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QACjC,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,UAAU,EAAE,qBAAqB,CAC/B,MAAM,CAAC,UAAU,EACjB,IAAI,GAAG,aAAa,CACrB;SACF,CAAC;IACJ,CAAC;IAED,IACE,MAAM,CAAC,IAAI;QACX,uBAAuB,EACvB,CAAC;QACD,IAAI,MAAM,CAAC,UAAU,KAAK,aAAa,EAAE,CAAC;YACxC,MAAM,IAAI,yBAAyB,CACjC,IAAI;gBACF,oCAAoC,CACvC,CAAC;QACJ,CAAC;QACD,MAAM,SAAS,GAAG,aAAa,CAC7B,MAAM,CAAC,SAAS,EAChB,IAAI,GAAG,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAC9C,CAAC;QACF,OAAO;YACL,IAAI,EAAE,uBAAuB;YAC7B,UAAU,EAAE,aAAa;YACzB,SAAS,EAAE;gBACT,GAAG,EAAE,eAAe,CAClB,SAAS,CAAC,GAAG,EACb,IAAI,GAAG,gBAAgB,CACxB;gBACD,KAAK,EAAE,eAAe,CACpB,SAAS,CAAC,KAAK,EACf,IAAI,GAAG,kBAAkB,CAC1B;gBACD,IAAI,EAAE,eAAe,CACnB,SAAS,CAAC,IAAI,EACd,IAAI,GAAG,iBAAiB,CACzB;aACF;YACD,QAAQ,EAAE,eAAe,CACvB,MAAM,CAAC,QAAQ,EACf,IAAI,GAAG,WAAW,CACnB;YACD,SAAS,EAAE,eAAe,CACxB,MAAM,CAAC,SAAS,EAChB,IAAI,GAAG,YAAY,CACpB;YACD,UAAU,EAAE,qBAAqB,CAC/B,MAAM,CAAC,UAAU,EACjB,IAAI,GAAG,aAAa,CACrB;SACF,CAAC;IACJ,CAAC;IAED,IACE,MAAM,CAAC,IAAI;QACX,qCAAqC,EACrC,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI,GAAG,mBAAmB,CAC3B,CAAC;IACJ,CAAC;IAED,IACE,MAAM,CAAC,eAAe;QACtB,wCAAwC,EACxC,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;YACF,oEAAoE,CACvE,CAAC;IACJ,CAAC;IACD,IACE,MAAM,CAAC,gBAAgB;QACrB,YAAY;QACd,MAAM,CAAC,gBAAgB;YACrB,eAAe,EACjB,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI,GAAG,+BAA+B,CACvC,CAAC;IACJ,CAAC;IACD,MAAM,gBAAgB,GACpB,MAAM,CAAC,gBAAgB,CAAC;IAC1B,MAAM,eAAe,GACnB,4BAA4B,CAC1B,MAAM,CAAC,eAAe,EACtB,IAAI,GAAG,kBAAkB,CAC1B,CAAC;IACJ,MAAM,WAAW,GAAG,gBAAgB,CAClC,MAAM,CAAC,WAAW,EAClB,IAAI,GAAG,cAAc,CACtB,CAAC;IACF,IACE,gBAAgB,KAAK,YAAY;QACjC,eAAe,KAAK,aAAa,EACjC,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;YACF,gFAAgF,CACnF,CAAC;IACJ,CAAC;IACD,IACE,gBAAgB,KAAK,YAAY;QACjC,WAAW,CAAC,IAAI,KAAK,UAAU,EAC/B,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;YACF,8EAA8E,CACjF,CAAC;IACJ,CAAC;IACD,IACE,MAAM,CAAC,iCAAiC;QACxC,KAAK,EACL,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI;YACF,mEAAmE,CACtE,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,eAAe,KAAK,KAAK,EAAE,CAAC;QACrC,MAAM,IAAI,yBAAyB,CACjC,IAAI;YACF,iDAAiD,CACpD,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EACF,qCAAqC;QACvC,YAAY,EAAE,aAAa,CACzB,MAAM,CAAC,YAAY,EACnB,IAAI,GAAG,eAAe,CACvB;QACD,eAAe;QACf,yBAAyB,EACvB,sCAAsC,CACpC,MAAM,CAAC,yBAAyB,EAChC,IAAI,GAAG,4BAA4B,CACpC;QACH,eAAe,EACb,wCAAwC;QAC1C,gBAAgB;QAChB,WAAW;QACX,iCAAiC,EAC/B,KAAK;QACP,eAAe,EAAE,KAAK;KACvB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iCAAiC,CAC/C,KAAc;IAEd,MAAM,MAAM,GAAG,aAAa,CAC1B,KAAK,EACL,8BAA8B,EAAE,CAAC,eAAe,EAAE,WAAW,EAAE,qBAAqB,EAAE,oCAAoC,EAAE,qBAAqB,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CACvL,CAAC;IACF,IACE,MAAM,CAAC,aAAa;QACpB,8CAA8C,EAC9C,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,sDAAsD;YACpD,8CAA8C;YAC9C,IAAI,CACP,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,yBAAyB,CACjC,0DAA0D,CAC3D,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CACpC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACf,MAAM,IAAI,GACR,yCAAyC;YACzC,KAAK;YACL,GAAG,CAAC;QACN,MAAM,QAAQ,GAAG,aAAa,CAC5B,KAAK,EACL,IAAI,EAAE,CAAC,oBAAoB,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAC3D,CAAC;QACF,OAAO;YACL,kBAAkB,EAChB,qBAAqB,CACnB,QAAQ,CAAC,kBAAkB,EAC3B,IAAI,GAAG,qBAAqB,CAC7B;YACH,QAAQ,EAAE,iBAAiB,CACzB,QAAQ,CAAC,QAAQ,EACjB,IAAI,GAAG,WAAW,CACnB;YACD,cAAc,EACZ,2BAA2B,CACzB,QAAQ,CAAC,cAAc,EACvB,IAAI,GAAG,iBAAiB,CACzB;SACJ,CAAC;IACJ,CAAC,CACF,CAAC;IACF,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CACvB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,kBAAkB,CACpC,CAAC;IACF,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC;QACrC,MAAM,IAAI,yBAAyB,CACjC,0FAA0F,CAC3F,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,mBAAmB,KAAK,KAAK,EAAE,CAAC;QACzC,MAAM,IAAI,yBAAyB,CACjC,iFAAiF,CAClF,CAAC;IACJ,CAAC;IACD,IACE,MAAM,CAAC,kCAAkC;QACzC,KAAK,EACL,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,gGAAgG,CACjG,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,mBAAmB,KAAK,KAAK,EAAE,CAAC;QACzC,MAAM,IAAI,yBAAyB,CACjC,iFAAiF,CAClF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,aAAa,EACX,8CAA8C;QAChD,SAAS,EAAE,qBAAqB,CAC9B,MAAM,CAAC,SAAS,EAChB,wCAAwC,CACzC;QACD,OAAO,EAAE,qBAAqB,CAC5B,MAAM,CAAC,OAAO,EACd,sCAAsC,CACvC;QACD,QAAQ,EAAE,iBAAiB,CACzB,MAAM,CAAC,QAAQ,EACf,uCAAuC,CACxC;QACD,SAAS;QACT,mBAAmB,EAAE,KAAK;QAC1B,kCAAkC,EAChC,KAAK;QACP,mBAAmB,EAAE,KAAK;KAC3B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mCAAmC,CACjD,OAAqC;IAErC,kBAAkB,CAAC,OAAO,EAAE,2CAA2C,CAAC,CAAC;IACzE,uFAAuF;IACvF,iCAAiC,CAAC,OAAO,CAAC,CAAC;IAC3C,iBAAiB,CAAC,OAAO,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;IAC1D,IACE,OAAO,CAAC,SAAS,CAAC,IAAI,CACpB,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,cAAc,CAAC,IAAI;QACzB,YAAY,CACf,EACD,CAAC;QACD,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,GAAG,CACnB,OAAO,CAAC,SAAS,CAAC,GAAG,CACnB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CACrC,CACF,CAAC;IACF,IACE,KAAK,CAAC,IAAI,KAAK,CAAC;QAChB,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,EACvB,CAAC;QACD,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,IACE,KAAK,CAAC,IAAI,KAAK,CAAC;QAChB,KAAK,CAAC,GAAG,CACP,qCAAqC,CACtC,EACD,CAAC;QACD,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,IACE,KAAK,CAAC,IAAI,KAAK,CAAC;QAChB,KAAK,CAAC,GAAG,CAAC,uBAAuB,CAAC,EAClC,CAAC;QACD,OAAO,uBAAuB,CAAC;IACjC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,qBAAqB,CAC5B,KAAc,EACd,IAAY;IAEZ,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAC1H,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACjC,IACE,QAAQ,KAAK,qBAAqB;QAClC,QAAQ;YACN,2BAA2B,EAC7B,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI,GAAG,uBAAuB,CAC/B,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACjC,IACE,QAAQ,KAAK,eAAe;QAC5B,QAAQ,KAAK,uBAAuB;QACpC,QAAQ,KAAK,OAAO;QACpB,QAAQ,KAAK,YAAY,EACzB,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI,GAAG,uBAAuB,CAC/B,CAAC;IACJ,CAAC;IACD,MAAM,eAAe,GAAG,CACtB,SAAkB,EAClB,aAAqB,EACoB,EAAE;QAC3C,IACE,SAAS,KAAK,UAAU;YACxB,SAAS,KAAK,eAAe;YAC7B,SAAS,KAAK,aAAa,EAC3B,CAAC;YACD,MAAM,IAAI,yBAAyB,CACjC,aAAa,GAAG,cAAc,CAC/B,CAAC;QACJ,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IACF,MAAM,cAAc,GAAG,CACrB,SAAkB,EAClB,aAAqB,EACmB,EAAE;QAC1C,IACE,SAAS,KAAK,UAAU;YACxB,SAAS,KAAK,eAAe;YAC7B,SAAS,KAAK,aAAa,EAC3B,CAAC;YACD,MAAM,IAAI,yBAAyB,CACjC,aAAa,GAAG,cAAc,CAC/B,CAAC;QACJ,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,OAAO;QACL,QAAQ;QACR,QAAQ;QACR,UAAU,EAAE,eAAe,CACzB,MAAM,CAAC,UAAU,EACjB,IAAI,GAAG,aAAa,CACrB;QACD,eAAe,EAAE,cAAc,CAC7B,MAAM,CAAC,eAAe,EACtB,IAAI,GAAG,kBAAkB,CAC1B;QACD,iBAAiB,EAAE,cAAc,CAC/B,MAAM,CAAC,iBAAiB,EACxB,IAAI,GAAG,oBAAoB,CAC5B;KACF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iCAAiC,CAC/C,KAAc;IAEd,MAAM,MAAM,GAAG,aAAa,CAC1B,KAAK,EACL,8BAA8B,EAAE,CAAC,eAAe,EAAE,gBAAgB,EAAE,YAAY,EAAE,kBAAkB,EAAE,oCAAoC,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,WAAW,EAAE,SAAS,EAAE,uBAAuB,EAAE,+BAA+B,EAAE,2BAA2B,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,CAAC,CACtW,CAAC;IACF,IACE,MAAM,CAAC,aAAa;QACpB,8CAA8C,EAC9C,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,sDAAsD;YACpD,8CAA8C;YAC9C,IAAI,CACP,CAAC;IACJ,CAAC;IACD,IACE,MAAM,CAAC,cAAc;QACrB,4BAA4B,EAC5B,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,mFAAmF,CACpF,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,UAAU,KAAK,aAAa,EAAE,CAAC;QACxC,MAAM,IAAI,yBAAyB,CACjC,gEAAgE,CACjE,CAAC;IACJ,CAAC;IACD,IACE,MAAM,CAAC,gBAAgB;QACvB,eAAe,EACf,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,wFAAwF,CACzF,CAAC;IACJ,CAAC;IACD,IACE,MAAM,CAAC,kCAAkC;QACzC,KAAK;QACL,MAAM,CAAC,0BAA0B;YACjC,KAAK;QACL,MAAM,CAAC,mBAAmB,KAAK,KAAK,EACpC,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,mIAAmI,CACpI,CAAC;IACJ,CAAC;IAED,OAAO;QACL,aAAa,EACX,8CAA8C;QAChD,SAAS,EAAE,qBAAqB,CAC9B,MAAM,CAAC,SAAS,EAChB,wCAAwC,CACzC;QACD,OAAO,EAAE,qBAAqB,CAC5B,MAAM,CAAC,OAAO,EACd,sCAAsC,CACvC;QACD,qBAAqB,EACnB,qBAAqB,CACnB,MAAM,CAAC,qBAAqB,EAC5B,oDAAoD,CACrD;QACH,GAAG,CAAC,MAAM,CAAC,6BAA6B;YACxC,SAAS;YACP,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,6BAA6B,EAC3B,qBAAqB,CACnB,MAAM,CAAC,6BAA6B,EACpC,4DAA4D,CAC7D;aACJ,CAAC;QACN,yBAAyB,EACvB,qBAAqB,CACnB,MAAM,CAAC,yBAAyB,EAChC,wDAAwD,CACzD;QACH,cAAc,EACZ,4BAA4B;QAC9B,UAAU,EAAE,aAAa;QACzB,gBAAgB,EAAE,eAAe;QACjC,WAAW,EAAE,gBAAgB,CAC3B,MAAM,CAAC,WAAW,EAClB,0CAA0C,CAC3C;QACD,QAAQ,EAAE,qBAAqB,CAC7B,MAAM,CAAC,QAAQ,EACf,uCAAuC,CACxC;QACD,kCAAkC,EAChC,KAAK;QACP,0BAA0B,EAAE,KAAK;QACjC,mBAAmB,EAAE,KAAK;QAC1B,QAAQ,EAAE,iBAAiB,CACzB,MAAM,CAAC,QAAQ,EACf,uCAAuC,CACxC;QACD,WAAW,EAAE,gBAAgB,CAC3B,MAAM,CAAC,WAAW,EAClB,0CAA0C,CAC3C;KACF,CAAC;AACJ,CAAC;AAED,SAAS,iCAAiC,CACxC,KAAc,EACd,IAAY;IAEZ,MAAM,UAAU,GAAG,aAAa,CAC9B,KAAK,EACL,IAAI,CACL,CAAC;IACF,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,yBAAyB,CACjC,IAAI,GAAG,6BAA6B,CACrC,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,4BAA4B,CACnC,KAAc,EACd,IAAY;IAKZ,MAAM,KAAK,GAAG,4BAA4B,CACxC,KAAK,EACL,IAAI,CACL,CAAC;IACF,IAAI,KAAK,KAAK,aAAa,EAAE,CAAC;QAC5B,MAAM,IAAI,yBAAyB,CACjC,IAAI;YACF,wDAAwD,CAC3D,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,qBAAqB,CAC5B,KAAc,EACd,IAAY;IAEZ,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAChD,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE;QACzC,eAAe,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,oBAAoB,EAAE,WAAW,EAAE,6BAA6B,CAAC;QAC5G,uBAAuB,EAAE,CAAC,MAAM,EAAE,6BAA6B,CAAC;KACjE,EAAE,IAAI,CAAC,CAAC;IACT,IAAI,MAAM,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QACpC,OAAO;YACL,IAAI,EAAE,eAAe;YACrB,aAAa,EAAE,qBAAqB,CAClC,MAAM,CAAC,aAAa,EACpB,IAAI,GAAG,gBAAgB,CACxB;YACD,kBAAkB,EAChB,qBAAqB,CACnB,MAAM,CAAC,kBAAkB,EACzB,IAAI,GAAG,qBAAqB,CAC7B;YACH,SAAS,EAAE,YAAY,CACrB,MAAM,CAAC,SAAS,EAChB,IAAI,GAAG,YAAY,CACpB;YACD,2BAA2B,EACzB,kBAAkB,CAChB,MAAM,CAAC,2BAA2B,EAClC,IAAI;gBACF,8BAA8B,CACjC;SACJ,CAAC;IACJ,CAAC;IACD,IACE,MAAM,CAAC,IAAI;QACX,uBAAuB,EACvB,CAAC;QACD,OAAO;YACL,IAAI,EAAE,uBAAuB;YAC7B,2BAA2B,EACzB,kBAAkB,CAChB,MAAM,CAAC,2BAA2B,EAClC,IAAI;gBACF,8BAA8B,CACjC;SACJ,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,yBAAyB,CACjC,IAAI,GAAG,mBAAmB,CAC3B,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mCAAmC,CACjD,KAAc;IAEd,MAAM,MAAM,GAAG,aAAa,CAC1B,KAAK,EACL,gCAAgC,EAAE,CAAC,eAAe,EAAE,UAAU,EAAE,mBAAmB,EAAE,SAAS,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,QAAQ,EAAE,8BAA8B,EAAE,sBAAsB,EAAE,iBAAiB,CAAC,CAC3O,CAAC;IACF,IACE,MAAM,CAAC,aAAa;QACpB,wCAAwC,EACxC,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,wDAAwD;YACtD,wCAAwC;YACxC,IAAI,CACP,CAAC;IACJ,CAAC;IAED,OAAO;QACL,aAAa,EACX,wCAAwC;QAC1C,QAAQ,EAAE,qBAAqB,CAC7B,MAAM,CAAC,QAAQ,EACf,yCAAyC,CAC1C;QACD,iBAAiB,EACf,qBAAqB,CACnB,MAAM,CAAC,iBAAiB,EACxB,kDAAkD,CACnD;QACH,OAAO,EAAE,qBAAqB,CAC5B,MAAM,CAAC,OAAO,EACd,wCAAwC,CACzC;QACD,qBAAqB,EACnB,qBAAqB,CACnB,MAAM,CAAC,qBAAqB,EAC5B,sDAAsD,CACvD;QACH,yBAAyB,EACvB,qBAAqB,CACnB,MAAM,CAAC,yBAAyB,EAChC,0DAA0D,CAC3D;QACH,MAAM,EAAE,qBAAqB,CAC3B,MAAM,CAAC,MAAM,EACb,uCAAuC,CACxC;QACD,4BAA4B,EAC1B,wBAAwB,CACtB,MAAM,CAAC,4BAA4B,EACnC,6DAA6D,CAC9D;QACH,oBAAoB,EAClB,iCAAiC,CAC/B,MAAM,CAAC,oBAAoB,EAC3B,qDAAqD,CACtD;QACH,eAAe,EACb,4BAA4B,CAC1B,MAAM,CAAC,eAAe,EACtB,gDAAgD,CACjD;KACJ,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kCAAkC,CAChD,KAAc;IAEd,MAAM,MAAM,GAAG,aAAa,CAC1B,KAAK,EACL,+BAA+B,EAAE,qCAAqC,CACvE,CAAC;IACF,OAAO,wCAAwC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,qCAAqC,GAAG,CAAC,eAAe,EAAE,UAAU,EAAE,MAAM,EAAE,kBAAkB,EAAE,UAAU,EAAE,mBAAmB,EAAE,SAAS,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,uDAAuD,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,CAAU,CAAC;AAU3S;;;;;;;GAOG;AACH,MAAM,UAAU,sDAAsD,CACpE,KAAc,EACd,SAAwC;IAExC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,kCAAkC,CAAC,KAAK,CAAC,CAAC;IAC1H,MAAM,MAAM,GAAG,KAAsB,CAAC;IACtC,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,CAAC,WAAW,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,QAAQ,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,CAAC,WAAW,EAAE,CAAC;QAC3I,OAAO,kCAAkC,CAAC,KAAK,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,wCAAwC,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,wCAAwC,CAC/C,MAAqB,EACrB,SAAoD;IAEpD,IACE,MAAM,CAAC,aAAa;QACpB,wCAAwC,EACxC,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,uDAAuD;YACrD,wCAAwC;YACxC,IAAI,CACP,CAAC;IACJ,CAAC;IACD,IACE,MAAM,CAAC,QAAQ;QACf,4BAA4B,EAC5B,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,8EAA8E,CAC/E,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QAClC,MAAM,IAAI,yBAAyB,CACjC,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IACD,IACE,MAAM,CAAC,gBAAgB;QACvB,eAAe,EACf,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,yFAAyF,CAC1F,CAAC;IACJ,CAAC;IAED,OAAO;QACL,aAAa,EACX,wCAAwC;QAC1C,QAAQ,EAAE,qBAAqB,CAC7B,MAAM,CAAC,QAAQ,EACf,wCAAwC,CACzC;QACD,iBAAiB,EACf,qBAAqB,CACnB,MAAM,CAAC,iBAAiB,EACxB,iDAAiD,CAClD;QACH,OAAO,EAAE,qBAAqB,CAC5B,MAAM,CAAC,OAAO,EACd,uCAAuC,CACxC;QACD,oBAAoB,EAClB,iCAAiC,CAC/B,MAAM,CAAC,oBAAoB,EAC3B,oDAAoD,CACrD;QACH,eAAe,EACb,4BAA4B,CAC1B,MAAM,CAAC,eAAe,EACtB,+CAA+C,CAChD;QACH,QAAQ,EACN,4BAA4B;QAC9B,IAAI,EAAE,aAAa;QACnB,qDAAqD,EACnD,wBAAwB,CACtB,MAAM,CAAC,qDAAqD,EAC5D,qFAAqF,CACtF;QACH,gBAAgB,EAAE,eAAe;QACjC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAC/D,MAAM,CAAC,WAAW,EAClB,2CAA2C,CAC5C;QACD,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAC1D,MAAM,CAAC,QAAQ,EACf,wCAAwC,CACzC;QACD,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAC/D,MAAM,CAAC,WAAW,EAClB,2CAA2C,CAC5C;KACF,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CACnB,MAAe,EACf,QAAiB,EACjB,OAAe;IAEf,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,IAAI,yBAAyB,CACjC,OAAO,CACR,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,0CAA0C,CACxD,eAAgF,EAChF,mBAAwF,EACxF,uBAAgG,EAChG,OAAgE,EAChE,MAA8D;IAE9D,YAAY,CACV,OAAO,CAAC,iBAAiB,EACzB,eAAe,CAAC,SAAS,EACzB,qEAAqE,CACtE,CAAC;IACF,YAAY,CACV,OAAO,CAAC,OAAO,EACf,eAAe,CAAC,OAAO,EACvB,2DAA2D,CAC5D,CAAC;IACF,YAAY,CACV,OAAO,CAAC,qBAAqB,EAC7B,mBAAmB,CAAC,SAAS,EAC7B,6EAA6E,CAC9E,CAAC;IACF,YAAY,CACV,OAAO,CAAC,yBAAyB,EACjC,uBAAuB,CAAC,SAAS,EACjC,sFAAsF,CACvF,CAAC;IAEF,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QAC5C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC9B,IACE,CAAC,uBAAuB,CAAC,SAAS,CAAC,IAAI,CACrC,CAAC,QAAQ,EAAE,EAAE,CACX,QAAQ,CAAC,kBAAkB;YAC3B,MAAM,CAAC,kBAAkB,CAC5B,EACD,CAAC;YACD,MAAM,IAAI,yBAAyB,CACjC,sGAAsG,CACvG,CAAC;QACJ,CAAC;IACH,CAAC;IAED,YAAY,CACV,MAAM,CAAC,QAAQ,EACf,OAAO,CAAC,QAAQ,EAChB,yCAAyC,CAC1C,CAAC;IACF,YAAY,CACV,MAAM,CAAC,iBAAiB,EACxB,OAAO,CAAC,iBAAiB,EACzB,kDAAkD,CACnD,CAAC;IACF,YAAY,CACV,MAAM,CAAC,OAAO,EACd,OAAO,CAAC,OAAO,EACf,wCAAwC,CACzC,CAAC;IACF,YAAY,CACV,MAAM,CAAC,oBAAoB,EAC3B,OAAO,CAAC,oBAAoB,EAC5B,6DAA6D,CAC9D,CAAC;IACF,YAAY,CACV,MAAM,CAAC,eAAe,EACtB,OAAO,CAAC,eAAe,EACvB,gDAAgD,CACjD,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uCAAuC,CACrD,KAC8C;IAE9C,gBAAgB,CAAC,KAAK,EAAE,yCAAyC,EAAE,CAAC,iBAAiB,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,yBAAyB,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC9L,MAAM,EACJ,eAAe,EACf,mBAAmB,EACnB,2BAA2B,EAC3B,uBAAuB,EACvB,OAAO,EACP,MAAM,EACP,GAAG,KAAK,CAAC;IAEV,kBAAkB,CAAC,eAAe,EAAE,uBAAuB,CAAC,CAAC;IAC7D,YAAY,CACV,eAAe,CAAC,OAAO,EACvB,mBAAmB,CAAC,OAAO,EAC3B,qEAAqE,CACtE,CAAC;IACF,YAAY,CACV,eAAe,CAAC,OAAO,EACvB,uBAAuB,CAAC,OAAO,EAC/B,0EAA0E,CAC3E,CAAC;IACF,YAAY,CACV,eAAe,CAAC,qBAAqB,EACrC,mBAAmB,CAAC,SAAS,EAC7B,8EAA8E,CAC/E,CAAC;IACF,YAAY,CACV,eAAe,CAAC,yBAAyB,EACzC,uBAAuB,CAAC,SAAS,EACjC,uFAAuF,CACxF,CAAC;IAEF,IACE,eAAe;SACZ,6BAA6B;QAChC,SAAS,EACT,CAAC;QACD,IACE,2BAA2B;YAC3B,SAAS,EACT,CAAC;YACD,MAAM,IAAI,yBAAyB,CACjC,0FAA0F,CAC3F,CAAC;QACJ,CAAC;IACH,CAAC;SAAM,CAAC;QACN,IACE,2BAA2B;YAC3B,SAAS,EACT,CAAC;YACD,MAAM,IAAI,yBAAyB,CACjC,6FAA6F,CAC9F,CAAC;QACJ,CAAC;QACD,YAAY,CACV,eAAe;aACZ,6BAA6B,EAChC,2BAA2B;aACxB,SAAS,EACZ,+FAA+F,CAChG,CAAC;QACF,YAAY,CACV,eAAe,CAAC,OAAO,EACvB,2BAA2B,CAAC,OAAO,EACnC,8EAA8E,CAC/E,CAAC;QACF,YAAY,CACV,eAAe;aACZ,qBAAqB,EACxB,2BAA2B;aACxB,qBAAqB,EACxB,+EAA+E,CAChF,CAAC;IACJ,CAAC;IAED,MAAM,wBAAwB,GAC5B,mCAAmC,CACjC,uBAAuB,CACxB,CAAC;IACJ,YAAY,CACV,eAAe,CAAC,QAAQ,CAAC,QAAQ,EACjC,wBAAwB,EACxB,+EAA+E,CAChF,CAAC;IAEF,0CAA0C,CAAC,eAAe,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAE3H,OAAO;QACL,uBAAuB,EAAE,IAAI;QAC7B,4BAA4B,EAAE,IAAI;QAClC,wBAAwB;QACxB,gCAAgC,EAC9B,2BAA2B;YAC3B,SAAS;QACX,iCAAiC,EAAE,KAAK;QACxC,+BAA+B,EAC7B,KAAK;QACP,aAAa,EAAE,KAAK;QACpB,iBAAiB,EAAE,KAAK;KACzB,CAAC;AACJ,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Contracts for scene-radiance providers: the renderer or other code that reports how much\n * light leaves a scene point toward the camera.\n *\n * It covers material-response metadata, provider capability profiles, single evaluation\n * requests and results, and identity checks between them. The engine validates this data\n * but does not compute scene radiance itself.\n * @see docs/SCENE_RADIANCE_AND_ILLUMINATION.md for equations, coordinate/unit conventions, blockers\n * and support limits.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport {\n parseEvidenceList,\n type EvidenceProvenance\n} from \"../core/evidence-provenance.js\";\nimport {\n parseSpectralWavelengthBasis,\n parseSpectralWavelengthRangeNanometers,\n type SpectralWavelengthBasis,\n type SpectralWavelengthRangeNanometers\n} from \"../core/spectral.js\";\nimport type {\n SceneIlluminationProfile\n} from \"./illumination.js\";\nimport type {\n SceneIlluminationTemporalProfile\n} from \"./illumination-temporal.js\";\nimport type { Vector3 } from \"./scene.js\";\nimport { requireInputObject, requireInputArray, requireInputKeys, rejectUnknownVariantFields, UNCERTAINTY_VARIANT_FIELDS, requireConfigRecord as requireRecord, requireTrimmedConfigString as requireNonEmptyString, requireConfigFiniteNumber as requireFinite, parseConfigLimitations as parseLimitations, requireConfigFraction as requireFraction, requireConfigNumberAtLeastZero as requireNonNegativeFinite } from \"../core/record-validation.js\";\nimport { hypot3 } from \"../core/portable-math.js\";\nimport { parseVector3 } from \"./illumination.js\";\n\ntype UnknownRecord = Record<string, unknown>;\n\nexport const SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION =\n \"0.1.0\" as const;\nexport const SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION =\n \"0.1.0\" as const;\nexport const SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION =\n \"0.1.0\" as const;\n\nexport type SceneRadianceScientificStatus =\n | \"calibrated\"\n | \"approximation\";\n\nexport type SceneRadianceUncertainty =\n | {\n kind: \"relative\";\n fraction: number;\n basis: string;\n }\n | {\n kind: \"not-quantified\";\n limitation: string;\n };\n\nexport interface SceneRadianceDataArtifactReference {\n id: string;\n checksumSha256: string;\n}\n\nexport type SceneMaterialResponseRepresentation =\n | {\n kind: \"unresolved\";\n limitation: string;\n }\n | {\n kind: \"rgb-pbr-approximation\";\n colorSpace: \"linear-srgb\";\n baseColor: {\n red: number;\n green: number;\n blue: number;\n };\n metallic: number;\n roughness: number;\n limitation: string;\n }\n | {\n kind: \"spectral-wavelength-preserving-data\";\n dataArtifact:\n SceneRadianceDataArtifactReference;\n wavelengthBasis:\n SpectralWavelengthBasis;\n wavelengthRangeNanometers:\n SpectralWavelengthRangeNanometers;\n scatteringModel:\n \"provider-defined-wavelength-preserving\";\n scientificStatus:\n SceneRadianceScientificStatus;\n uncertainty:\n SceneRadianceUncertainty;\n wavelengthChangingBehaviorModeled: false;\n emissionModeled: false;\n };\n\nexport interface SceneMaterialResponseDefinition {\n materialResponseId: string;\n evidence: readonly EvidenceProvenance[];\n representation:\n SceneMaterialResponseRepresentation;\n}\n\nexport interface SceneMaterialResponseProfile {\n schemaVersion:\n typeof SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION;\n profileId: string;\n sceneId: string;\n evidence: readonly EvidenceProvenance[];\n materials:\n readonly SceneMaterialResponseDefinition[];\n fluorescenceModeled: false;\n volumetricMaterialTransportModeled: false;\n polarizationModeled: false;\n}\n\nexport type SceneMaterialResponseFidelity =\n | \"spectral-data\"\n | \"rgb-pbr-approximation\"\n | \"mixed\"\n | \"unresolved\";\n\nexport type SceneRadianceProviderSpectralFidelity =\n | \"wavelength-resolved\"\n | \"rgb-derived-approximation\";\n\nexport type SceneRadianceProviderVisibilityFidelity =\n | \"resolved\"\n | \"approximation\"\n | \"not-modeled\";\n\nexport type SceneRadianceProviderTransportFidelity =\n | \"resolved\"\n | \"approximation\"\n | \"not-modeled\";\n\nexport interface SceneRadianceProviderProfile {\n schemaVersion:\n typeof SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION;\n profileId: string;\n sceneId: string;\n illuminationProfileId: string;\n illuminationTemporalProfileId?: string;\n materialResponseProfileId: string;\n outputQuantity:\n \"outgoing-spectral-radiance\";\n outputUnit:\n \"W/m^2/sr/nm\";\n scientificStatus: \"approximation\";\n uncertainty: SceneRadianceUncertainty;\n fidelity: {\n spectral:\n SceneRadianceProviderSpectralFidelity;\n material:\n SceneMaterialResponseFidelity;\n visibility:\n SceneRadianceProviderVisibilityFidelity;\n directTransport:\n SceneRadianceProviderTransportFidelity;\n indirectTransport:\n SceneRadianceProviderTransportFidelity;\n };\n wavelengthChangingTransportModeled: false;\n volumetricTransportModeled: false;\n polarizationModeled: false;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport type SceneRadianceEvaluationTarget =\n | {\n kind: \"surface-point\";\n sceneObjectId: string;\n materialResponseId: string;\n positionM: Vector3;\n outgoingDirectionUnitVector: Vector3;\n }\n | {\n kind: \"environment-direction\";\n outgoingDirectionUnitVector: Vector3;\n };\n\nexport interface SceneRadianceEvaluationRequest {\n schemaVersion:\n typeof SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION;\n sampleId: string;\n providerProfileId: string;\n sceneId: string;\n illuminationProfileId: string;\n materialResponseProfileId: string;\n target: SceneRadianceEvaluationTarget;\n timeSecondsFromExposureStart: number;\n wavelengthNanometers: number;\n wavelengthBasis:\n Exclude<SpectralWavelengthBasis, \"unspecified\">;\n}\n\nexport interface SceneRadianceEvaluationResult {\n schemaVersion:\n typeof SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION;\n sampleId: string;\n providerProfileId: string;\n sceneId: string;\n wavelengthNanometers: number;\n wavelengthBasis:\n Exclude<SpectralWavelengthBasis, \"unspecified\">;\n quantity:\n \"outgoing-spectral-radiance\";\n unit: \"W/m^2/sr/nm\";\n spectralRadianceWattsPerSquareMeterSteradianNanometer:\n number;\n scientificStatus: \"approximation\";\n uncertainty: SceneRadianceUncertainty;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface ValidateSceneRadianceEvaluationBindingsInput {\n providerProfile: SceneRadianceProviderProfile;\n illuminationProfile: SceneIlluminationProfile;\n illuminationTemporalProfile?:\n SceneIlluminationTemporalProfile;\n materialResponseProfile:\n SceneMaterialResponseProfile;\n request: SceneRadianceEvaluationRequest;\n result: SceneRadianceEvaluationResult;\n}\n\nexport interface SceneRadianceEvaluationBindingAssessment {\n providerBindingsMatched: true;\n requestResultIdentityMatched: true;\n materialResponseFidelity:\n SceneMaterialResponseFidelity;\n temporalIlluminationProfileBound:\n boolean;\n calibratedRadianceClaimAuthorized: false;\n sensorPlaneIrradianceCalculated: false;\n opticsApplied: false;\n photonsCalculated: false;\n}\n\nfunction parseUnitDirection(\n value: unknown,\n path: string\n): Vector3 {\n const vector = parseVector3(value, path);\n const length = hypot3(\n vector.x,\n vector.y,\n vector.z\n );\n if (\n !Number.isFinite(length) ||\n Math.abs(length - 1) > 1e-9\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must be a unit-length direction vector.\"\n );\n }\n return vector;\n}\n\nfunction parseUncertainty(\n value: unknown,\n path: string\n): SceneRadianceUncertainty {\n const record = requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", UNCERTAINTY_VARIANT_FIELDS, path);\n if (record.kind === \"relative\") {\n return {\n kind: \"relative\",\n fraction: requireNonNegativeFinite(\n record.fraction,\n path + \".fraction\"\n ),\n basis: requireNonEmptyString(\n record.basis,\n path + \".basis\"\n )\n };\n }\n if (record.kind === \"not-quantified\") {\n return {\n kind: \"not-quantified\",\n limitation: requireNonEmptyString(\n record.limitation,\n path + \".limitation\"\n )\n };\n }\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n}\n\nfunction parseArtifact(\n value: unknown,\n path: string\n): SceneRadianceDataArtifactReference {\n const record = requireRecord(value, path, [\"checksumSha256\", \"id\"]);\n const checksumSha256 =\n requireNonEmptyString(\n record.checksumSha256,\n path + \".checksumSha256\"\n );\n if (\n !/^[a-f0-9]{64}$/iu.test(\n checksumSha256\n )\n ) {\n throw new InvalidConfigurationError(\n path +\n \".checksumSha256 must be a 64-character SHA-256 hex digest.\"\n );\n }\n return {\n id: requireNonEmptyString(\n record.id,\n path + \".id\"\n ),\n checksumSha256:\n checksumSha256.toLowerCase()\n };\n}\n\nfunction parseMaterialRepresentation(\n value: unknown,\n path: string\n): SceneMaterialResponseRepresentation {\n const record = requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", {\n unresolved: [\"kind\", \"limitation\"],\n \"rgb-pbr-approximation\": [\"kind\", \"colorSpace\", \"baseColor\", \"metallic\", \"roughness\", \"limitation\"],\n \"spectral-wavelength-preserving-data\": [\"kind\", \"dataArtifact\", \"wavelengthBasis\", \"wavelengthRangeNanometers\", \"scatteringModel\",\n \"scientificStatus\", \"uncertainty\", \"wavelengthChangingBehaviorModeled\", \"emissionModeled\"]\n }, path);\n\n if (record.kind === \"unresolved\") {\n return {\n kind: \"unresolved\",\n limitation: requireNonEmptyString(\n record.limitation,\n path + \".limitation\"\n )\n };\n }\n\n if (\n record.kind ===\n \"rgb-pbr-approximation\"\n ) {\n if (record.colorSpace !== \"linear-srgb\") {\n throw new InvalidConfigurationError(\n path +\n '.colorSpace must be \"linear-srgb\".'\n );\n }\n const baseColor = requireRecord(\n record.baseColor,\n path + \".baseColor\", [\"red\", \"green\", \"blue\"]\n );\n return {\n kind: \"rgb-pbr-approximation\",\n colorSpace: \"linear-srgb\",\n baseColor: {\n red: requireFraction(\n baseColor.red,\n path + \".baseColor.red\"\n ),\n green: requireFraction(\n baseColor.green,\n path + \".baseColor.green\"\n ),\n blue: requireFraction(\n baseColor.blue,\n path + \".baseColor.blue\"\n )\n },\n metallic: requireFraction(\n record.metallic,\n path + \".metallic\"\n ),\n roughness: requireFraction(\n record.roughness,\n path + \".roughness\"\n ),\n limitation: requireNonEmptyString(\n record.limitation,\n path + \".limitation\"\n )\n };\n }\n\n if (\n record.kind !==\n \"spectral-wavelength-preserving-data\"\n ) {\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n }\n\n if (\n record.scatteringModel !==\n \"provider-defined-wavelength-preserving\"\n ) {\n throw new InvalidConfigurationError(\n path +\n '.scatteringModel must be \"provider-defined-wavelength-preserving\".'\n );\n }\n if (\n record.scientificStatus !==\n \"calibrated\" &&\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n path + \".scientificStatus is invalid.\"\n );\n }\n const scientificStatus =\n record.scientificStatus;\n const wavelengthBasis =\n parseSpectralWavelengthBasis(\n record.wavelengthBasis,\n path + \".wavelengthBasis\"\n );\n const uncertainty = parseUncertainty(\n record.uncertainty,\n path + \".uncertainty\"\n );\n if (\n scientificStatus === \"calibrated\" &&\n wavelengthBasis === \"unspecified\"\n ) {\n throw new InvalidConfigurationError(\n path +\n \" calibrated spectral material data requires an air or vacuum wavelength basis.\"\n );\n }\n if (\n scientificStatus === \"calibrated\" &&\n uncertainty.kind !== \"relative\"\n ) {\n throw new InvalidConfigurationError(\n path +\n \" calibrated spectral material data requires quantified relative uncertainty.\"\n );\n }\n if (\n record.wavelengthChangingBehaviorModeled !==\n false\n ) {\n throw new InvalidConfigurationError(\n path +\n \".wavelengthChangingBehaviorModeled must be false in schema 0.1.0.\"\n );\n }\n if (record.emissionModeled !== false) {\n throw new InvalidConfigurationError(\n path +\n \".emissionModeled must be false in schema 0.1.0.\"\n );\n }\n\n return {\n kind:\n \"spectral-wavelength-preserving-data\",\n dataArtifact: parseArtifact(\n record.dataArtifact,\n path + \".dataArtifact\"\n ),\n wavelengthBasis,\n wavelengthRangeNanometers:\n parseSpectralWavelengthRangeNanometers(\n record.wavelengthRangeNanometers,\n path + \".wavelengthRangeNanometers\"\n ),\n scatteringModel:\n \"provider-defined-wavelength-preserving\",\n scientificStatus,\n uncertainty,\n wavelengthChangingBehaviorModeled:\n false,\n emissionModeled: false\n };\n}\n\n/**\n * Parses material-response metadata used by a scene-radiance provider.\n *\n * RGB or PBR (physically based rendering) material data is always an approximation.\n * Spectral data is a per-wavelength provider input. It does not itself compute a BSDF\n * (how a surface scatters light), scene radiance, fluorescence, emission, volumetric\n * effects or polarization.\n */\nexport function parseSceneMaterialResponseProfile(\n value: unknown\n): SceneMaterialResponseProfile {\n const record = requireRecord(\n value,\n \"sceneMaterialResponseProfile\", [\"schemaVersion\", \"materials\", \"fluorescenceModeled\", \"volumetricMaterialTransportModeled\", \"polarizationModeled\", \"profileId\", \"sceneId\", \"evidence\"]\n );\n if (\n record.schemaVersion !==\n SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneMaterialResponseProfile.schemaVersion must be \"' +\n SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION +\n '\".'\n );\n }\n if (!Array.isArray(record.materials)) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.materials must be an array.\"\n );\n }\n\n const materials = record.materials.map(\n (entry, index) => {\n const path =\n \"sceneMaterialResponseProfile.materials[\" +\n index +\n \"]\";\n const material = requireRecord(\n entry,\n path, [\"materialResponseId\", \"evidence\", \"representation\"]\n );\n return {\n materialResponseId:\n requireNonEmptyString(\n material.materialResponseId,\n path + \".materialResponseId\"\n ),\n evidence: parseEvidenceList(\n material.evidence,\n path + \".evidence\"\n ),\n representation:\n parseMaterialRepresentation(\n material.representation,\n path + \".representation\"\n )\n };\n }\n );\n const ids = materials.map(\n (entry) => entry.materialResponseId\n );\n if (new Set(ids).size !== ids.length) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.materials[].materialResponseId must not contain duplicates.\"\n );\n }\n\n if (record.fluorescenceModeled !== false) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.fluorescenceModeled must be false in schema 0.1.0.\"\n );\n }\n if (\n record.volumetricMaterialTransportModeled !==\n false\n ) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.volumetricMaterialTransportModeled must be false in schema 0.1.0.\"\n );\n }\n if (record.polarizationModeled !== false) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.polarizationModeled must be false in schema 0.1.0.\"\n );\n }\n\n return {\n schemaVersion:\n SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION,\n profileId: requireNonEmptyString(\n record.profileId,\n \"sceneMaterialResponseProfile.profileId\"\n ),\n sceneId: requireNonEmptyString(\n record.sceneId,\n \"sceneMaterialResponseProfile.sceneId\"\n ),\n evidence: parseEvidenceList(\n record.evidence,\n \"sceneMaterialResponseProfile.evidence\"\n ),\n materials,\n fluorescenceModeled: false,\n volumetricMaterialTransportModeled:\n false,\n polarizationModeled: false\n };\n}\n\n/**\n * Returns the material fidelity a profile supports, choosing the lower level when in doubt.\n */\nexport function assessSceneMaterialResponseFidelity(\n profile: SceneMaterialResponseProfile\n): SceneMaterialResponseFidelity {\n requireInputObject(profile, \"assessSceneMaterialResponseFidelity input\");\n // 2.0.0: the whole profile is validated, so an unknown field at any level is rejected.\n parseSceneMaterialResponseProfile(profile);\n requireInputArray(profile.materials, \"profile.materials\");\n if (\n profile.materials.some(\n (entry) =>\n entry.representation.kind ===\n \"unresolved\"\n )\n ) {\n return \"unresolved\";\n }\n\n const kinds = new Set(\n profile.materials.map(\n (entry) => entry.representation.kind\n )\n );\n if (\n kinds.size === 0 ||\n kinds.has(\"unresolved\")\n ) {\n return \"unresolved\";\n }\n if (\n kinds.size === 1 &&\n kinds.has(\n \"spectral-wavelength-preserving-data\"\n )\n ) {\n return \"spectral-data\";\n }\n if (\n kinds.size === 1 &&\n kinds.has(\"rgb-pbr-approximation\")\n ) {\n return \"rgb-pbr-approximation\";\n }\n return \"mixed\";\n}\n\nfunction parseProviderFidelity(\n value: unknown,\n path: string\n): SceneRadianceProviderProfile[\"fidelity\"] {\n const record = requireRecord(value, path, [\"spectral\", \"material\", \"visibility\", \"directTransport\", \"indirectTransport\"]);\n const spectral = record.spectral;\n if (\n spectral !== \"wavelength-resolved\" &&\n spectral !==\n \"rgb-derived-approximation\"\n ) {\n throw new InvalidConfigurationError(\n path + \".spectral is invalid.\"\n );\n }\n const material = record.material;\n if (\n material !== \"spectral-data\" &&\n material !== \"rgb-pbr-approximation\" &&\n material !== \"mixed\" &&\n material !== \"unresolved\"\n ) {\n throw new InvalidConfigurationError(\n path + \".material is invalid.\"\n );\n }\n const parseVisibility = (\n candidate: unknown,\n candidatePath: string\n ): SceneRadianceProviderVisibilityFidelity => {\n if (\n candidate !== \"resolved\" &&\n candidate !== \"approximation\" &&\n candidate !== \"not-modeled\"\n ) {\n throw new InvalidConfigurationError(\n candidatePath + \" is invalid.\"\n );\n }\n return candidate;\n };\n const parseTransport = (\n candidate: unknown,\n candidatePath: string\n ): SceneRadianceProviderTransportFidelity => {\n if (\n candidate !== \"resolved\" &&\n candidate !== \"approximation\" &&\n candidate !== \"not-modeled\"\n ) {\n throw new InvalidConfigurationError(\n candidatePath + \" is invalid.\"\n );\n }\n return candidate;\n };\n\n return {\n spectral,\n material,\n visibility: parseVisibility(\n record.visibility,\n path + \".visibility\"\n ),\n directTransport: parseTransport(\n record.directTransport,\n path + \".directTransport\"\n ),\n indirectTransport: parseTransport(\n record.indirectTransport,\n path + \".indirectTransport\"\n )\n };\n}\n\n/**\n * Parses a provider's declaration of what it can do (its profile). Works with any renderer.\n *\n * Schema 0.1.0 is approximation-only by design. A provider may use calibrated inputs,\n * but this contract cannot support a claim of calibrated outgoing radiance. That needs\n * later work on complete spectral and light-transport models.\n */\nexport function parseSceneRadianceProviderProfile(\n value: unknown\n): SceneRadianceProviderProfile {\n const record = requireRecord(\n value,\n \"sceneRadianceProviderProfile\", [\"schemaVersion\", \"outputQuantity\", \"outputUnit\", \"scientificStatus\", \"wavelengthChangingTransportModeled\", \"volumetricTransportModeled\", \"polarizationModeled\", \"profileId\", \"sceneId\", \"illuminationProfileId\", \"illuminationTemporalProfileId\", \"materialResponseProfileId\", \"uncertainty\", \"fidelity\", \"evidence\", \"limitations\"]\n );\n if (\n record.schemaVersion !==\n SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceProviderProfile.schemaVersion must be \"' +\n SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION +\n '\".'\n );\n }\n if (\n record.outputQuantity !==\n \"outgoing-spectral-radiance\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceProviderProfile.outputQuantity must be \"outgoing-spectral-radiance\".'\n );\n }\n if (record.outputUnit !== \"W/m^2/sr/nm\") {\n throw new InvalidConfigurationError(\n 'sceneRadianceProviderProfile.outputUnit must be \"W/m^2/sr/nm\".'\n );\n }\n if (\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceProviderProfile.scientificStatus must be \"approximation\" in schema 0.1.0.'\n );\n }\n if (\n record.wavelengthChangingTransportModeled !==\n false ||\n record.volumetricTransportModeled !==\n false ||\n record.polarizationModeled !== false\n ) {\n throw new InvalidConfigurationError(\n \"sceneRadianceProviderProfile wavelength-changing, volumetric, and polarization transport flags must all be false in schema 0.1.0.\"\n );\n }\n\n return {\n schemaVersion:\n SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION,\n profileId: requireNonEmptyString(\n record.profileId,\n \"sceneRadianceProviderProfile.profileId\"\n ),\n sceneId: requireNonEmptyString(\n record.sceneId,\n \"sceneRadianceProviderProfile.sceneId\"\n ),\n illuminationProfileId:\n requireNonEmptyString(\n record.illuminationProfileId,\n \"sceneRadianceProviderProfile.illuminationProfileId\"\n ),\n ...(record.illuminationTemporalProfileId ===\n undefined\n ? {}\n : {\n illuminationTemporalProfileId:\n requireNonEmptyString(\n record.illuminationTemporalProfileId,\n \"sceneRadianceProviderProfile.illuminationTemporalProfileId\"\n )\n }),\n materialResponseProfileId:\n requireNonEmptyString(\n record.materialResponseProfileId,\n \"sceneRadianceProviderProfile.materialResponseProfileId\"\n ),\n outputQuantity:\n \"outgoing-spectral-radiance\",\n outputUnit: \"W/m^2/sr/nm\",\n scientificStatus: \"approximation\",\n uncertainty: parseUncertainty(\n record.uncertainty,\n \"sceneRadianceProviderProfile.uncertainty\"\n ),\n fidelity: parseProviderFidelity(\n record.fidelity,\n \"sceneRadianceProviderProfile.fidelity\"\n ),\n wavelengthChangingTransportModeled:\n false,\n volumetricTransportModeled: false,\n polarizationModeled: false,\n evidence: parseEvidenceList(\n record.evidence,\n \"sceneRadianceProviderProfile.evidence\"\n ),\n limitations: parseLimitations(\n record.limitations,\n \"sceneRadianceProviderProfile.limitations\"\n )\n };\n}\n\nfunction parsePositiveWavelengthNanometers(\n value: unknown,\n path: string\n): number {\n const wavelength = requireFinite(\n value,\n path\n );\n if (wavelength <= 0) {\n throw new InvalidConfigurationError(\n path + \" must be greater than zero.\"\n );\n }\n return wavelength;\n}\n\nfunction parseResolvedWavelengthBasis(\n value: unknown,\n path: string\n): Exclude<\n SpectralWavelengthBasis,\n \"unspecified\"\n> {\n const basis = parseSpectralWavelengthBasis(\n value,\n path\n );\n if (basis === \"unspecified\") {\n throw new InvalidConfigurationError(\n path +\n \" must be air or vacuum for outgoing spectral radiance.\"\n );\n }\n return basis;\n}\n\nfunction parseEvaluationTarget(\n value: unknown,\n path: string\n): SceneRadianceEvaluationTarget {\n const record = requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", {\n \"surface-point\": [\"kind\", \"sceneObjectId\", \"materialResponseId\", \"positionM\", \"outgoingDirectionUnitVector\"],\n \"environment-direction\": [\"kind\", \"outgoingDirectionUnitVector\"]\n }, path);\n if (record.kind === \"surface-point\") {\n return {\n kind: \"surface-point\",\n sceneObjectId: requireNonEmptyString(\n record.sceneObjectId,\n path + \".sceneObjectId\"\n ),\n materialResponseId:\n requireNonEmptyString(\n record.materialResponseId,\n path + \".materialResponseId\"\n ),\n positionM: parseVector3(\n record.positionM,\n path + \".positionM\"\n ),\n outgoingDirectionUnitVector:\n parseUnitDirection(\n record.outgoingDirectionUnitVector,\n path +\n \".outgoingDirectionUnitVector\"\n )\n };\n }\n if (\n record.kind ===\n \"environment-direction\"\n ) {\n return {\n kind: \"environment-direction\",\n outgoingDirectionUnitVector:\n parseUnitDirection(\n record.outgoingDirectionUnitVector,\n path +\n \".outgoingDirectionUnitVector\"\n )\n };\n }\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n}\n\n/**\n * Parses one provider evaluation request at an explicit scene target,\n * physical time, wavelength, and outgoing direction.\n */\nexport function parseSceneRadianceEvaluationRequest(\n value: unknown\n): SceneRadianceEvaluationRequest {\n const record = requireRecord(\n value,\n \"sceneRadianceEvaluationRequest\", [\"schemaVersion\", \"sampleId\", \"providerProfileId\", \"sceneId\", \"illuminationProfileId\", \"materialResponseProfileId\", \"target\", \"timeSecondsFromExposureStart\", \"wavelengthNanometers\", \"wavelengthBasis\"]\n );\n if (\n record.schemaVersion !==\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationRequest.schemaVersion must be \"' +\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION +\n '\".'\n );\n }\n\n return {\n schemaVersion:\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION,\n sampleId: requireNonEmptyString(\n record.sampleId,\n \"sceneRadianceEvaluationRequest.sampleId\"\n ),\n providerProfileId:\n requireNonEmptyString(\n record.providerProfileId,\n \"sceneRadianceEvaluationRequest.providerProfileId\"\n ),\n sceneId: requireNonEmptyString(\n record.sceneId,\n \"sceneRadianceEvaluationRequest.sceneId\"\n ),\n illuminationProfileId:\n requireNonEmptyString(\n record.illuminationProfileId,\n \"sceneRadianceEvaluationRequest.illuminationProfileId\"\n ),\n materialResponseProfileId:\n requireNonEmptyString(\n record.materialResponseProfileId,\n \"sceneRadianceEvaluationRequest.materialResponseProfileId\"\n ),\n target: parseEvaluationTarget(\n record.target,\n \"sceneRadianceEvaluationRequest.target\"\n ),\n timeSecondsFromExposureStart:\n requireNonNegativeFinite(\n record.timeSecondsFromExposureStart,\n \"sceneRadianceEvaluationRequest.timeSecondsFromExposureStart\"\n ),\n wavelengthNanometers:\n parsePositiveWavelengthNanometers(\n record.wavelengthNanometers,\n \"sceneRadianceEvaluationRequest.wavelengthNanometers\"\n ),\n wavelengthBasis:\n parseResolvedWavelengthBasis(\n record.wavelengthBasis,\n \"sceneRadianceEvaluationRequest.wavelengthBasis\"\n )\n };\n}\n\n/**\n * Parses one outgoing spectral-radiance result from a provider.\n *\n * The number is accepted as the provider reported it. Parsing checks units, that the\n * value is finite and nonnegative, provenance and identity fields. It does not prove\n * the provider's light-transport calculation is physically correct.\n */\nexport function parseSceneRadianceEvaluationResult(\n value: unknown\n): SceneRadianceEvaluationResult {\n const record = requireRecord(\n value,\n \"sceneRadianceEvaluationResult\", SCENE_RADIANCE_EVALUATION_RESULT_KEYS\n );\n return parseSceneRadianceEvaluationResultRecord(record, undefined);\n}\n\nconst SCENE_RADIANCE_EVALUATION_RESULT_KEYS = [\"schemaVersion\", \"quantity\", \"unit\", \"scientificStatus\", \"sampleId\", \"providerProfileId\", \"sceneId\", \"wavelengthNanometers\", \"wavelengthBasis\", \"spectralRadianceWattsPerSquareMeterSteradianNanometer\", \"uncertainty\", \"evidence\", \"limitations\"] as const;\n\n/** An earlier fully parsed result whose deep-frozen uncertainty, evidence and limitations records may be reused. */\nexport interface ValidatedSceneRadianceRecords {\n readonly uncertainty: unknown;\n readonly evidence: unknown;\n readonly limitations: unknown;\n readonly parsed: SceneRadianceEvaluationResult;\n}\n\n/**\n * Internal (2.6; not exported from the package): parses a result of an engine-built evaluator\n * (`isInternalSceneRadianceEvaluator`). It runs every check of `parseSceneRadianceEvaluationResult` with the same\n * helpers, order and messages (object shape, schema version, quantity, unit, status, the three identifiers, the\n * wavelength, its basis and the radiance value) except two: the scan for unknown keys, and re-parsing uncertainty,\n * evidence and limitations when they are the very (deep-frozen) objects of `validated`, an earlier result that\n * passed the full parse. Any other result takes the full parse.\n */\nexport function parseSceneRadianceEvaluationResultWithValidatedRecords(\n value: unknown,\n validated: ValidatedSceneRadianceRecords\n): SceneRadianceEvaluationResult {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return parseSceneRadianceEvaluationResult(value);\n const record = value as UnknownRecord;\n if (record.uncertainty !== validated.uncertainty || record.evidence !== validated.evidence || record.limitations !== validated.limitations) {\n return parseSceneRadianceEvaluationResult(value);\n }\n return parseSceneRadianceEvaluationResultRecord(record, validated.parsed);\n}\n\nfunction parseSceneRadianceEvaluationResultRecord(\n record: UnknownRecord,\n validated: SceneRadianceEvaluationResult | undefined\n): SceneRadianceEvaluationResult {\n if (\n record.schemaVersion !==\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationResult.schemaVersion must be \"' +\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION +\n '\".'\n );\n }\n if (\n record.quantity !==\n \"outgoing-spectral-radiance\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationResult.quantity must be \"outgoing-spectral-radiance\".'\n );\n }\n if (record.unit !== \"W/m^2/sr/nm\") {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationResult.unit must be \"W/m^2/sr/nm\".'\n );\n }\n if (\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationResult.scientificStatus must be \"approximation\" in schema 0.1.0.'\n );\n }\n\n return {\n schemaVersion:\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION,\n sampleId: requireNonEmptyString(\n record.sampleId,\n \"sceneRadianceEvaluationResult.sampleId\"\n ),\n providerProfileId:\n requireNonEmptyString(\n record.providerProfileId,\n \"sceneRadianceEvaluationResult.providerProfileId\"\n ),\n sceneId: requireNonEmptyString(\n record.sceneId,\n \"sceneRadianceEvaluationResult.sceneId\"\n ),\n wavelengthNanometers:\n parsePositiveWavelengthNanometers(\n record.wavelengthNanometers,\n \"sceneRadianceEvaluationResult.wavelengthNanometers\"\n ),\n wavelengthBasis:\n parseResolvedWavelengthBasis(\n record.wavelengthBasis,\n \"sceneRadianceEvaluationResult.wavelengthBasis\"\n ),\n quantity:\n \"outgoing-spectral-radiance\",\n unit: \"W/m^2/sr/nm\",\n spectralRadianceWattsPerSquareMeterSteradianNanometer:\n requireNonNegativeFinite(\n record.spectralRadianceWattsPerSquareMeterSteradianNanometer,\n \"sceneRadianceEvaluationResult.spectralRadianceWattsPerSquareMeterSteradianNanometer\"\n ),\n scientificStatus: \"approximation\",\n uncertainty: validated ? validated.uncertainty : parseUncertainty(\n record.uncertainty,\n \"sceneRadianceEvaluationResult.uncertainty\"\n ),\n evidence: validated ? validated.evidence : parseEvidenceList(\n record.evidence,\n \"sceneRadianceEvaluationResult.evidence\"\n ),\n limitations: validated ? validated.limitations : parseLimitations(\n record.limitations,\n \"sceneRadianceEvaluationResult.limitations\"\n )\n };\n}\n\nfunction requireEqual(\n actual: unknown,\n expected: unknown,\n message: string\n): void {\n if (actual !== expected) {\n throw new InvalidConfigurationError(\n message\n );\n }\n}\n\n/**\n * Internal (#453; not exported from the package): the request and result checks of\n * {@link validateSceneRadianceEvaluationBindings} (the request against the three profiles, a surface target's material, and\n * the result against the request), with its messages and order. The profile-to-profile checks before them depend only on the\n * profiles; an engine caller that has run the full function once for these profile objects may run only this part for\n * further requests and results.\n */\nexport function validateSceneRadianceRequestResultBindings(\n providerProfile: ValidateSceneRadianceEvaluationBindingsInput[\"providerProfile\"],\n illuminationProfile: ValidateSceneRadianceEvaluationBindingsInput[\"illuminationProfile\"],\n materialResponseProfile: ValidateSceneRadianceEvaluationBindingsInput[\"materialResponseProfile\"],\n request: ValidateSceneRadianceEvaluationBindingsInput[\"request\"],\n result: ValidateSceneRadianceEvaluationBindingsInput[\"result\"]\n): void {\n requireEqual(\n request.providerProfileId,\n providerProfile.profileId,\n \"Request providerProfileId must match the supplied provider profile.\"\n );\n requireEqual(\n request.sceneId,\n providerProfile.sceneId,\n \"Request sceneId must match the supplied provider profile.\"\n );\n requireEqual(\n request.illuminationProfileId,\n illuminationProfile.profileId,\n \"Request illuminationProfileId must match the supplied illumination profile.\"\n );\n requireEqual(\n request.materialResponseProfileId,\n materialResponseProfile.profileId,\n \"Request materialResponseProfileId must match the supplied material-response profile.\"\n );\n\n if (request.target.kind === \"surface-point\") {\n const target = request.target;\n if (\n !materialResponseProfile.materials.some(\n (material) =>\n material.materialResponseId ===\n target.materialResponseId\n )\n ) {\n throw new InvalidConfigurationError(\n \"Request surface target materialResponseId is not declared by the supplied material-response profile.\"\n );\n }\n }\n\n requireEqual(\n result.sampleId,\n request.sampleId,\n \"Result sampleId must match the request.\"\n );\n requireEqual(\n result.providerProfileId,\n request.providerProfileId,\n \"Result providerProfileId must match the request.\"\n );\n requireEqual(\n result.sceneId,\n request.sceneId,\n \"Result sceneId must match the request.\"\n );\n requireEqual(\n result.wavelengthNanometers,\n request.wavelengthNanometers,\n \"Result wavelengthNanometers must match the request exactly.\"\n );\n requireEqual(\n result.wavelengthBasis,\n request.wavelengthBasis,\n \"Result wavelengthBasis must match the request.\"\n );\n}\n\n/**\n * Checks that a provider result matches its request and profile identities exactly.\n *\n * It never recomputes the radiance value, and never upgrades the provider's\n * approximation to calibrated radiometry.\n */\nexport function validateSceneRadianceEvaluationBindings(\n input:\n ValidateSceneRadianceEvaluationBindingsInput\n): SceneRadianceEvaluationBindingAssessment {\n requireInputKeys(input, \"validateSceneRadianceEvaluationBindings\", [\"providerProfile\", \"illuminationProfile\", \"illuminationTemporalProfile\", \"materialResponseProfile\", \"request\", \"result\"]);\n const {\n providerProfile,\n illuminationProfile,\n illuminationTemporalProfile,\n materialResponseProfile,\n request,\n result\n } = input;\n\n requireInputObject(providerProfile, \"providerProfile input\");\n requireEqual(\n providerProfile.sceneId,\n illuminationProfile.sceneId,\n \"Provider and illumination profiles must reference the same sceneId.\"\n );\n requireEqual(\n providerProfile.sceneId,\n materialResponseProfile.sceneId,\n \"Provider and material-response profiles must reference the same sceneId.\"\n );\n requireEqual(\n providerProfile.illuminationProfileId,\n illuminationProfile.profileId,\n \"Provider illuminationProfileId must match the supplied illumination profile.\"\n );\n requireEqual(\n providerProfile.materialResponseProfileId,\n materialResponseProfile.profileId,\n \"Provider materialResponseProfileId must match the supplied material-response profile.\"\n );\n\n if (\n providerProfile\n .illuminationTemporalProfileId ===\n undefined\n ) {\n if (\n illuminationTemporalProfile !==\n undefined\n ) {\n throw new InvalidConfigurationError(\n \"A temporal illumination profile was supplied but the provider profile does not bind one.\"\n );\n }\n } else {\n if (\n illuminationTemporalProfile ===\n undefined\n ) {\n throw new InvalidConfigurationError(\n \"Provider illuminationTemporalProfileId requires the matching temporal illumination profile.\"\n );\n }\n requireEqual(\n providerProfile\n .illuminationTemporalProfileId,\n illuminationTemporalProfile\n .profileId,\n \"Provider illuminationTemporalProfileId must match the supplied temporal illumination profile.\"\n );\n requireEqual(\n providerProfile.sceneId,\n illuminationTemporalProfile.sceneId,\n \"Provider and temporal illumination profiles must reference the same sceneId.\"\n );\n requireEqual(\n providerProfile\n .illuminationProfileId,\n illuminationTemporalProfile\n .illuminationProfileId,\n \"Temporal illumination profile must bind the provider's illuminationProfileId.\"\n );\n }\n\n const materialResponseFidelity =\n assessSceneMaterialResponseFidelity(\n materialResponseProfile\n );\n requireEqual(\n providerProfile.fidelity.material,\n materialResponseFidelity,\n \"Provider material fidelity must match the supplied material-response profile.\"\n );\n\n validateSceneRadianceRequestResultBindings(providerProfile, illuminationProfile, materialResponseProfile, request, result);\n\n return {\n providerBindingsMatched: true,\n requestResultIdentityMatched: true,\n materialResponseFidelity,\n temporalIlluminationProfileBound:\n illuminationTemporalProfile !==\n undefined,\n calibratedRadianceClaimAuthorized: false,\n sensorPlaneIrradianceCalculated:\n false,\n opticsApplied: false,\n photonsCalculated: false\n };\n}\n"]}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
2
2
|
import type { CameraConfiguration } from "./camera.js";
|
|
3
3
|
import type { SceneDefinition } from "./scene.js";
|
|
4
|
+
type UnknownRecord = Record<string, unknown>;
|
|
5
|
+
export declare function requirePositiveNumber(record: UnknownRecord, key: string, path: string): number;
|
|
4
6
|
/**
|
|
5
7
|
* Parses and validates an untrusted camera configuration.
|
|
6
8
|
*
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @see docs/SCENE_RADIANCE_AND_ILLUMINATION.md for equations, coordinate/unit conventions, blockers
|
|
5
5
|
* and support limits.
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import { rejectUnknownVariantFields, requireConfigRecord as requireRecord, requireConfigRecordString as requireString } from "../core/record-validation.js";
|
|
8
8
|
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
9
9
|
export { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
10
10
|
const CAMERA_SUPPORTS = new Set([
|
|
@@ -23,21 +23,6 @@ const SCENE_CAPABILITIES = new Set([
|
|
|
23
23
|
"multi-resolution-layers",
|
|
24
24
|
"absolute-radiometry"
|
|
25
25
|
]);
|
|
26
|
-
function requireRecord(value, path, allowedKeys) {
|
|
27
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
28
|
-
throw new InvalidConfigurationError(`${path} must be an object.`);
|
|
29
|
-
}
|
|
30
|
-
if (allowedKeys !== null)
|
|
31
|
-
rejectUnknownFields(value, allowedKeys, path);
|
|
32
|
-
return value;
|
|
33
|
-
}
|
|
34
|
-
function requireString(record, key, path) {
|
|
35
|
-
const value = record[key];
|
|
36
|
-
if (typeof value !== "string" || value.trim().length === 0) {
|
|
37
|
-
throw new InvalidConfigurationError(`${path}.${key} must be a non-empty string.`);
|
|
38
|
-
}
|
|
39
|
-
return value;
|
|
40
|
-
}
|
|
41
26
|
function requireBoolean(record, key, path) {
|
|
42
27
|
const value = record[key];
|
|
43
28
|
if (typeof value !== "boolean") {
|
|
@@ -45,7 +30,7 @@ function requireBoolean(record, key, path) {
|
|
|
45
30
|
}
|
|
46
31
|
return value;
|
|
47
32
|
}
|
|
48
|
-
function requirePositiveNumber(record, key, path) {
|
|
33
|
+
export function requirePositiveNumber(record, key, path) {
|
|
49
34
|
const value = record[key];
|
|
50
35
|
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
51
36
|
throw new InvalidConfigurationError(`${path}.${key} must be a finite number greater than zero.`);
|