@photivra/engine 2.9.0 → 2.11.1
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 +223 -1
- package/CITATION.cff +1 -1
- package/NODE_SUPPORT.md +21 -3
- package/README.md +6 -6
- package/SECURITY.md +1 -1
- package/THIRD_PARTY.md +2 -0
- package/dist/capture/native-environment-lean.js +89 -5
- package/dist/capture/native-environment-lean.js.map +1 -1
- package/dist/capture/native-environment-tabulated.d.ts +37 -0
- package/dist/capture/native-environment-tabulated.js +42 -6
- package/dist/capture/native-environment-tabulated.js.map +1 -1
- package/dist/core/portable-math.d.ts +19 -0
- package/dist/core/portable-math.js +82 -0
- package/dist/core/portable-math.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/facade/channel-response.d.ts +15 -0
- package/dist/facade/channel-response.js +33 -0
- package/dist/facade/channel-response.js.map +1 -0
- package/dist/facade/chart-material-layers.d.ts +115 -0
- package/dist/facade/chart-material-layers.js +224 -0
- package/dist/facade/chart-material-layers.js.map +1 -0
- package/dist/facade/chart-radiance-batch.d.ts +8 -2
- package/dist/facade/chart-radiance-batch.js +11 -4
- package/dist/facade/chart-radiance-batch.js.map +1 -1
- package/dist/facade/chart-scenes.d.ts +134 -0
- package/dist/facade/chart-scenes.js +32 -22
- package/dist/facade/chart-scenes.js.map +1 -1
- package/dist/facade/diffraction-provider.d.ts +8 -2
- package/dist/facade/diffraction-provider.js +120 -16
- package/dist/facade/diffraction-provider.js.map +1 -1
- package/dist/facade/display-view-gpu-session.d.ts +18 -0
- package/dist/facade/display-view-gpu-session.js +280 -0
- package/dist/facade/display-view-gpu-session.js.map +1 -0
- package/dist/facade/display-view-gpu.d.ts +146 -0
- package/dist/facade/display-view-gpu.js +59 -0
- package/dist/facade/display-view-gpu.js.map +1 -0
- package/dist/facade/display-view.d.ts +123 -1
- package/dist/facade/display-view.js +478 -116
- package/dist/facade/display-view.js.map +1 -1
- package/dist/facade/expected-signal-setup.d.ts +5 -0
- package/dist/facade/expected-signal-setup.js +18 -1
- package/dist/facade/expected-signal-setup.js.map +1 -1
- package/dist/facade/expected-signal.d.ts +80 -6
- package/dist/facade/expected-signal.js +200 -24
- package/dist/facade/expected-signal.js.map +1 -1
- package/dist/facade/scene-radiance.d.ts +4 -2
- package/dist/facade/scene-radiance.js +7 -4
- package/dist/facade/scene-radiance.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +81 -7
- package/dist/facade/simulate-capture.js +276 -53
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/facade/simulate-display-view.d.ts +54 -3
- package/dist/facade/simulate-display-view.js +120 -27
- package/dist/facade/simulate-display-view.js.map +1 -1
- package/dist/gpu/chart-composite-gpu.d.ts +119 -0
- package/dist/gpu/chart-composite-gpu.js +572 -0
- package/dist/gpu/chart-composite-gpu.js.map +1 -0
- package/dist/gpu/chart-radiance-gpu.d.ts +6 -6
- package/dist/gpu/chart-radiance-gpu.js +9 -11
- package/dist/gpu/chart-radiance-gpu.js.map +1 -1
- package/dist/gpu/display-view-chart-material-module.d.ts +10 -0
- package/dist/gpu/display-view-chart-material-module.js +58 -0
- package/dist/gpu/display-view-chart-material-module.js.map +1 -0
- package/dist/gpu/display-view-composite-material-module.d.ts +68 -0
- package/dist/gpu/display-view-composite-material-module.js +248 -0
- package/dist/gpu/display-view-composite-material-module.js.map +1 -0
- package/dist/gpu/display-view-quality-gpu.d.ts +185 -0
- package/dist/gpu/display-view-quality-gpu.js +1000 -0
- package/dist/gpu/display-view-quality-gpu.js.map +1 -0
- package/dist/gpu/display-view-speed-gpu.d.ts +156 -0
- package/dist/gpu/display-view-speed-gpu.js +524 -0
- package/dist/gpu/display-view-speed-gpu.js.map +1 -0
- package/dist/gpu/image-kernel-accelerator.d.ts +23 -4
- package/dist/gpu/image-kernel-accelerator.js +58 -10
- package/dist/gpu/image-kernel-accelerator.js.map +1 -1
- package/dist/gpu/image-kernel-execution.d.ts +60 -3
- package/dist/gpu/image-kernel-execution.js +2 -2
- package/dist/gpu/image-kernel-execution.js.map +1 -1
- package/dist/gpu/sensor-stage-gpu.d.ts +11 -0
- package/dist/gpu/sensor-stage-gpu.js +42 -13
- package/dist/gpu/sensor-stage-gpu.js.map +1 -1
- package/dist/gpu/webgpu-runtime.d.ts +4 -2
- package/dist/gpu/webgpu-runtime.js +13 -4
- package/dist/gpu/webgpu-runtime.js.map +1 -1
- package/dist/gpu/webgpu-switch.d.ts +4 -0
- package/dist/gpu/webgpu-switch.js +29 -0
- package/dist/gpu/webgpu-switch.js.map +1 -0
- package/dist/gpu/wgsl-chart-composite-kernel.d.ts +52 -0
- package/dist/gpu/wgsl-chart-composite-kernel.js +515 -0
- package/dist/gpu/wgsl-chart-composite-kernel.js.map +1 -0
- package/dist/gpu/wgsl-chart-kernel.d.ts +11 -9
- package/dist/gpu/wgsl-chart-kernel.js +33 -27
- package/dist/gpu/wgsl-chart-kernel.js.map +1 -1
- package/dist/gpu/wgsl-display-view-quality-kernel.d.ts +95 -0
- package/dist/gpu/wgsl-display-view-quality-kernel.js +769 -0
- package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -0
- package/dist/gpu/wgsl-display-view-speed-kernel.d.ts +75 -0
- package/dist/gpu/wgsl-display-view-speed-kernel.js +386 -0
- package/dist/gpu/wgsl-display-view-speed-kernel.js.map +1 -0
- package/dist/gpu/wgsl-sensor-kernel.d.ts +28 -9
- package/dist/gpu/wgsl-sensor-kernel.js +94 -50
- package/dist/gpu/wgsl-sensor-kernel.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/optics/defocus-disc-kernel.d.ts +61 -0
- package/dist/optics/defocus-disc-kernel.js +191 -0
- package/dist/optics/defocus-disc-kernel.js.map +1 -0
- package/dist/optics/irradiance-convolution.d.ts +11 -0
- package/dist/optics/irradiance-convolution.js +64 -24
- package/dist/optics/irradiance-convolution.js.map +1 -1
- package/dist/optics/scene-to-sensor-irradiance.d.ts +13 -0
- package/dist/optics/scene-to-sensor-irradiance.js +58 -24
- package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
- package/dist/optics/sensor-aperture-rays.js +2 -1
- package/dist/optics/sensor-aperture-rays.js.map +1 -1
- package/dist/optics/sensor-environment-query.js +4 -3
- package/dist/optics/sensor-environment-query.js.map +1 -1
- package/dist/optics/site-diffraction-kernel.d.ts +16 -0
- package/dist/optics/site-diffraction-kernel.js +60 -8
- package/dist/optics/site-diffraction-kernel.js.map +1 -1
- package/dist/processing/demosaic.js +114 -37
- package/dist/processing/demosaic.js.map +1 -1
- package/dist/schema/scene-radiance.d.ts +8 -0
- package/dist/schema/scene-radiance.js +28 -17
- package/dist/schema/scene-radiance.js.map +1 -1
- package/dist/sensor/environment-photo-signal.d.ts +21 -0
- package/dist/sensor/environment-photo-signal.js +68 -2
- package/dist/sensor/environment-photo-signal.js.map +1 -1
- package/docs/API_REFERENCE.md +60 -1
- package/docs/QUICK_START.md +120 -11
- package/docs/USAGE.md +82 -2
- package/docs/api/core-version.md +1 -1
- package/docs/api/exports.json +157 -2
- package/docs/api/facade-chart-material-layers.md +137 -0
- package/docs/api/facade-chart-radiance-batch.md +7 -2
- package/docs/api/facade-display-view-gpu.md +94 -0
- package/docs/api/facade-display-view.md +50 -0
- package/docs/api/facade-scene-radiance.md +3 -2
- package/docs/api/facade-simulate-capture.md +81 -12
- package/docs/api/facade-simulate-display-view.md +39 -2
- package/docs/api/gpu-image-kernel-accelerator.md +10 -3
- package/docs/api/gpu-image-kernel-execution.md +76 -4
- package/docs/api/gpu-webgpu-switch.md +23 -0
- package/package.json +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment-photo-signal.js","sourceRoot":"","sources":["../../src/sensor/environment-photo-signal.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Photo signal for one sensor site from a scene-radiance provider (the \"environment\"): asks the\n * provider for radiance along each sampled direction, then applies optics and the sensor response.\n *\n * Work is split into a plan and an execution step. Planning checks spatial, spectral and temporal\n * coverage and builds an internal plan before any provider code runs. Each query gives an explicit\n * scene direction, a wavelength (air or vacuum) and a time in seconds from the shutter's opening\n * reference. Optical throughput, an optional local PSF (point-spread function) and the EQE (external\n * quantum efficiency) response then give the expected photo signal. Calling the provider does not\n * verify its light transport, visibility or calibration.\n * @see docs/ENVIRONMENT_RAW_CAPTURE.md for equations, coordinate/unit conventions, blockers and\n * support limits.\n */\n\nimport { approximationResult, type CalculationResult } from \"../core/calculation-result.js\";\nimport { freezeOwnedData } from \"../core/owned-data.js\";\nimport { requirePublicOpaqueId, requireInputKeys } from \"../core/record-validation.js\";\nimport { parseEvidenceList, type EvidenceProvenance } from \"../core/evidence-provenance.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport { parseSceneIlluminationProfile } from \"../schema/illumination.js\";\nimport { parseSceneIlluminationTemporalProfile } from \"../schema/illumination-temporal.js\";\nimport { parseSceneMaterialResponseProfile, parseSceneRadianceProviderProfile, parseSceneRadianceEvaluationResult,\n validateSceneRadianceEvaluationBindings, type SceneRadianceEvaluationRequest,\n type SceneRadianceEvaluationResult } from \"../schema/scene-radiance.js\";\nimport { calculateMappedSensorEnvironmentRadianceQuery, calculateSensorEnvironmentRadianceQuery, prepareEnvironmentLensFieldMapping,\n type CalculateSensorEnvironmentRadianceQueryInput, type EnvironmentLensFieldMapping } from \"../optics/sensor-environment-query.js\";\nimport { calculateSceneRadianceToSensorIrradiance, type CalculateSceneRadianceToSensorIrradianceInput } from \"../optics/scene-to-sensor-irradiance.js\";\nimport { calculateSensorPsfIrradianceQuadrature, type CalculateSensorPsfIrradianceQuadratureInput } from \"../optics/sensor-psf-quadrature.js\";\nimport { calculateIlluminationVignetting, type IlluminationVignettingProfile } from \"../optics/illumination-vignetting.js\";\nimport { calculateSensorApertureRays, type IdealCircularPupil, type SensorApertureRay } from \"../optics/sensor-aperture-rays.js\";\nimport { sensorPsfSourcePoint } from \"../optics/sensor-psf-support.js\";\nimport { markEngineOwnedLensSampledPsfProfile, resolveLensSampledPsf } from \"../optics/lens-psf-profile.js\";\nimport { calculateSensorSpatialSamplingQuadrature } from \"./spatial-sampling-quadrature.js\";\nimport { calculateSensorSpectralQuadrature } from \"./spectral-quadrature.js\";\nimport { resolveNativeEffectiveRasterColorSamplingBinding } from \"./capture-color-sampling-binding.js\";\nimport { calculateCaptureExposureWindows } from \"./exposure-window.js\";\nimport { createSensorEqeTemporalPhotoSignal } from \"./temporal-photo-signal.js\";\nimport type { CalculateSensorEqeTemporalExposureInput } from \"./eqe-temporal-exposure.js\";\nimport type { CalculateSceneToSensorIrradianceQuadratureInput } from \"../optics/scene-to-sensor-quadrature.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\n\n/** Caller-supplied synchronous radiance function, run locally. Calling it does not prove its light transport is physical. */\nexport type EnvironmentRadianceEvaluator = (request: Readonly<SceneRadianceEvaluationRequest>) => SceneRadianceEvaluationResult;\nexport type EnvironmentApertureRadianceEvaluator = (request: Readonly<SceneRadianceEvaluationRequest>, apertureRay: Readonly<SensorApertureRay>) => SceneRadianceEvaluationResult;\nexport interface CalculateEnvironmentSensorPhotoSignalInput {\n temporalIntegrationId: string;\n sensor: Omit<CalculateSensorEqeTemporalExposureInput, \"samples\">;\n sceneBindings: CalculateSceneToSensorIrradianceQuadratureInput[\"sceneBindings\"];\n optics: Omit<CalculateSceneRadianceToSensorIrradianceInput,\n \"sceneRadianceRequest\" | \"sceneRadianceResult\" | \"imagePointMm\" | \"fieldThroughput\">;\n motion: Pick<CalculateSensorEnvironmentRadianceQueryInput,\n \"angularVelocityRadPerSec\" | \"timeReference\" | \"environmentDirectionConvention\">;\n temporalSampleCount: number;\n /** Optional ideal circular pupil, for geometric depth of field (DOF) and visibility. Cannot be combined with a sampled PSF. */\n pupil?: IdealCircularPupil;\n /**\n * Optional lens field mapping (added in 2.0): a projection model and radial or Brown-Conrady\n * distortion for the scene-ray query. Its distortion area factor is applied to irradiance exactly\n * once. If omitted, the ideal rectilinear, distortion-free path is unchanged. Cannot be combined\n * with `pupil`.\n */\n lensFieldMapping?: EnvironmentLensFieldMapping;\n /** Explicit attenuation across the field (such as vignetting), applied once before the PSF spreads the light. */\n fieldThroughput: { kind: \"unity\"; evidence: readonly EvidenceProvenance[]; limitation: string } | {\n kind: \"radial-illumination-vignetting\"; profile: IlluminationVignettingProfile;\n evidence: readonly EvidenceProvenance[]; limitation: string;\n };\n psf: { kind: \"not-applied\"; evidence: readonly EvidenceProvenance[]; limitation: string } | {\n kind: \"sampled-local\";\n configuration: Pick<CalculateSensorPsfIrradianceQuadratureInput, \"psf\" | \"psfWavelengthBasis\" | \"spatialModel\">;\n };\n evaluateRadiance: EnvironmentRadianceEvaluator;\n /** Required with `pupil`: rays start at different points on the aperture, so a direction-only function cannot be used. */\n evaluateApertureRadiance?: EnvironmentApertureRadianceEvaluator;\n}\nexport interface EnvironmentSensorPhotoSignal {\n sourceTargetProjectionCalculated: true;\n providerCallbackExecuted: true;\n providerTransportVerified: false;\n sceneVisibilityCalculated: false;\n productionPlanActivated: false;\n providerEvaluationCount: number;\n sourcePlane: \"sensor-package-incident\";\n fieldThroughputEvidence: readonly EvidenceProvenance[];\n fieldThroughputLimitation: string;\n psfOmission: { evidence: readonly EvidenceProvenance[]; limitation: string } | null;\n psfRedistributionApplied: boolean;\n pupilIntegrationApplied: boolean;\n pupilIntegrationProfile: IdealCircularPupil | null;\n photo: ReturnType<typeof createSensorEqeTemporalPhotoSignal>;\n instants: readonly {\n temporalSampleIndex: number;\n timeSecondsFromOpeningReference: number;\n psf: ReturnType<typeof calculateSensorPsfIrradianceQuadrature> | null;\n evaluations: readonly {\n query: ReturnType<typeof calculateSensorEnvironmentRadianceQuery>;\n result: SceneRadianceEvaluationResult;\n bindings: ReturnType<typeof validateSceneRadianceEvaluationBindings>;\n optics: ReturnType<typeof calculateSceneRadianceToSensorIrradiance>;\n apertureRay?: SensorApertureRay;\n apertureRequest?: SceneRadianceEvaluationRequest;\n }[];\n }[];\n}\n\n/** Internal plan, shared with the full-frame composer, so all work is bounded before any callback runs. */\ninterface EnvironmentPhotoPlan {\n owned: Omit<CalculateEnvironmentSensorPhotoSignalInput, \"evaluateRadiance\" | \"evaluateApertureRadiance\">;\n sceneBindings: CalculateSceneToSensorIrradianceQuadratureInput[\"sceneBindings\"];\n fieldThroughputEvidence: readonly EvidenceProvenance[];\n spatialQuadrature: ReturnType<typeof calculateSensorSpatialSamplingQuadrature>[\"value\"];\n spectralQuadrature: ReturnType<typeof calculateSensorSpectralQuadrature>[\"value\"];\n count: number;\n focus: CalculateSensorEnvironmentRadianceQueryInput[\"focus\"];\n instants: { temporalSampleIndex: number; time: number; groups: {\n node: CalculateSensorPsfIrradianceQuadratureInput[\"samples\"][number][\"node\"];\n taps: { kernelSampleX: number; kernelSampleY: number; point: { x: number; y: number };\n /** Deep-frozen provider request of the planned query (the same object as query.value.request). */\n request: SceneRadianceEvaluationRequest;\n /** The planned query's image-plane source point (the same object as query.value.sourcePointImagePlaneMm). */\n sourcePointImagePlaneMm: { x: number; y: number };\n /** The complete query result. Kept only by \"full\" plans, whose per-evaluation records include it. */\n query?: ReturnType<typeof calculateSensorEnvironmentRadianceQuery>;\n apertureRays?: readonly SensorApertureRay[];\n /** 1 / det(d distorted / d ideal), the change in area from distortion. Present only with a lens field mapping. */\n distortionAreaFactor?: number;\n fieldThroughput: CalculateSceneRadianceToSensorIrradianceInput[\"fieldThroughput\"] }[];\n }[] }[];\n}\n/**\n * Builds an internal execution plan covering all optical, spatial, spectral and temporal sampling,\n * without calling any provider code.\n *\n * Coverage is checked completely before any supplied radiance function runs. Each query gives an\n * explicit scene direction, a wavelength (air or vacuum) and seconds from the opening reference.\n * @param input - The photo-signal input without its radiance functions; see\n * `CalculateEnvironmentSensorPhotoSignalInput`.\n * @param ownership - Internal. \"copy\" (default) makes a structured clone of the input. \"engine-owned\"\n * uses the input as the plan's own data without cloning again. Only engine callers that already hold a\n * private structured clone, never shown to supplied code and never changed afterwards, may pass it.\n * @param retention - Internal. \"full\" (default) keeps every planned query result for \"full\" execution\n * records. \"photo-only\" keeps only each query's frozen request and image-plane point, which is all that\n * photo-only execution reads. Every query is still computed and validated at plan time, so limit checks\n * and errors are unchanged.\n * @returns The result. Success does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the package export and its full type definitions.\n */\nexport function planEnvironmentSensorPhotoSignal(input: Omit<CalculateEnvironmentSensorPhotoSignalInput, \"evaluateRadiance\" | \"evaluateApertureRadiance\">,\n ownership: \"copy\" | \"engine-owned\" = \"copy\", retention: \"full\" | \"photo-only\" = \"full\"): EnvironmentPhotoPlan {\n const owned = ownership === \"engine-owned\" ? input : structuredClone(input);\n requirePublicOpaqueId(owned.temporalIntegrationId, \"Environment integration requires a public identity.\");\n if (!Number.isSafeInteger(owned.temporalSampleCount) || owned.temporalSampleCount < 1 || owned.temporalSampleCount > 256 ||\n owned.sensor.responseApplication.sourcePlane.value !== \"sensor-package-incident\" ||\n (owned.fieldThroughput?.kind !== \"unity\" && owned.fieldThroughput?.kind !== \"radial-illumination-vignetting\") || typeof owned.fieldThroughput.limitation !== \"string\" || !owned.fieldThroughput.limitation.trim()) {\n throw new InvalidScientificInputError(\"Environment exposure requires package-incident response, 1..256 midpoints and explicit supported field throughput.\");\n }\n if (owned.fieldThroughput.kind === \"radial-illumination-vignetting\" &&\n (typeof owned.fieldThroughput.profile !== \"object\" || owned.fieldThroughput.profile === null ||\n typeof owned.fieldThroughput.profile.coefficients !== \"object\" || owned.fieldThroughput.profile.coefficients === null)) {\n throw new InvalidScientificInputError(\"Radial throughput requires a declared profile and coefficients.\");\n }\n const fieldThroughputEvidence = parseEvidenceList(owned.fieldThroughput.evidence, \"environmentFieldThroughput.evidence\");\n const sceneBindings = { providerProfile: parseSceneRadianceProviderProfile(owned.sceneBindings.providerProfile),\n illuminationProfile: parseSceneIlluminationProfile(owned.sceneBindings.illuminationProfile),\n materialResponseProfile: parseSceneMaterialResponseProfile(owned.sceneBindings.materialResponseProfile),\n ...(owned.sceneBindings.illuminationTemporalProfile === undefined ? {} : {\n illuminationTemporalProfile: parseSceneIlluminationTemporalProfile(owned.sceneBindings.illuminationTemporalProfile) }) };\n if (sceneBindings.providerProfile.fidelity.spectral !== \"wavelength-resolved\") throw new InvalidScientificInputError(\"Environment exposure requires wavelength-resolved provider fidelity.\");\n const sensor = owned.sensor;\n const nativeRaster = sensor.localExposure.exposureWindowInput.nativeRaster;\n const binding = resolveNativeEffectiveRasterColorSamplingBinding({ nativeRaster, colorSamplingProfile: sensor.colorSamplingProfile,\n bindingProfile: sensor.localExposure.bindingProfile });\n if (binding.relationshipMeaning !== \"one-native-effective-sample-to-one-color-site\") throw new InvalidScientificInputError(\"Environment exposure requires explicit one-to-one native/color timing.\");\n const spatialQuadrature = calculateSensorSpatialSamplingQuadrature({ ...sensor.spatialSampling, nativeRaster,\n colorSamplingProfile: sensor.colorSamplingProfile, colorSamplingBindingProfile: sensor.localExposure.bindingProfile }).value;\n const spectralQuadrature = calculateSensorSpectralQuadrature({ ...sensor.spectralSampling,\n colorSamplingProfile: sensor.colorSamplingProfile, spectralResponseProfile: sensor.spectralResponseProfile }).value;\n if (spectralQuadrature.wavelengthBasis === \"unspecified\") throw new InvalidScientificInputError(\"Environment spectral basis must be explicit.\");\n const wavelengthBasis = spectralQuadrature.wavelengthBasis;\n const site = sensor.spatialSampling.site;\n const window = calculateCaptureExposureWindows({ ...sensor.localExposure.exposureWindowInput,\n samplePointsNative: [{ x: site.x+.5, y: site.y+.5 }] }).value.samples[0]!;\n const focus = owned.optics.focus.kind === \"infinity-focus\" ? { kind: \"infinity\" as const } :\n owned.optics.focus.kind === \"ideal-symmetric-thin-lens\" ? { kind: \"finite\" as const, distanceM: owned.optics.focus.objectDistanceM } :\n owned.optics.focus.focus.kind === \"infinity\" ? { kind: \"infinity\" as const } : { kind: \"finite\" as const, distanceM: owned.optics.focus.focus.objectDistanceM };\n if (owned.psf.kind === \"not-applied\") {\n parseEvidenceList(owned.psf.evidence, \"environmentPsfOmission.evidence\");\n if (typeof owned.psf.limitation !== \"string\" || !owned.psf.limitation.trim()) throw new InvalidScientificInputError(\"PSF omission needs an explicit limitation.\");\n } else if (owned.psf.kind !== \"sampled-local\") throw new InvalidConfigurationError(\"Unknown environment PSF selection.\");\n if (owned.psf.kind === \"sampled-local\") {\n const p = owned.psf.configuration.psf;\n // The profile belongs only to this plan, so its parse can be cached across nodes and time instants.\n markEngineOwnedLensSampledPsfProfile(p.profile);\n if (p.focalLengthMm !== owned.optics.focalLengthMm || p.apertureFNumber !== owned.optics.nominalFNumber ||\n p.focus.kind !== focus.kind || (p.focus.kind === \"finite\" && focus.kind === \"finite\" && p.focus.distanceM !== focus.distanceM)) {\n throw new InvalidScientificInputError(\"PSF and optical focal/aperture/focus state must match exactly.\");\n }\n }\n if (owned.pupil !== undefined && owned.psf.kind !== \"not-applied\") throw new InvalidScientificInputError(\"Ideal pupil integration cannot mix with a sampled PSF; geometric defocus would be ambiguous.\");\n const lensMapping = owned.lensFieldMapping === undefined ? undefined : prepareEnvironmentLensFieldMapping(owned.lensFieldMapping);\n if (lensMapping !== undefined && owned.pupil !== undefined) {\n throw new InvalidScientificInputError(\"Ideal pupil rays use the rectilinear distortion-free projection and cannot combine with a lens field mapping.\");\n }\n const pupilCount = owned.pupil === undefined ? 1 : calculateSensorApertureRays({sourcePointNativeSensorMm:{x:0,y:0},\n focalLengthMm:owned.optics.focalLengthMm,nominalFNumber:owned.optics.nominalFNumber,focus,pupil:owned.pupil,\n angularVelocityRadPerSec:owned.motion.angularVelocityRadPerSec,timeSecondsFromOpeningReference:window.startOffsetSecondsFromOpeningReference}).value.rays.length;\n let count = 0;\n const nodes = spectralQuadrature.nodes.flatMap(spectral => spatialQuadrature.nodes.map(spatial => {\n const node = { spatialNode: { antiAliasingComponentIndex: spatial.antiAliasingComponentIndex,\n apertureSampleXIndex: spatial.apertureSampleXIndex, apertureSampleYIndex: spatial.apertureSampleYIndex },\n spectralSampleIndex: spectral.spectralSampleIndex, wavelengthNanometers: spectral.wavelengthNanometers };\n const destination = spatial.preAntiAliasingSourcePointMm;\n const resolved = owned.psf.kind === \"sampled-local\" ? resolveLensSampledPsf({ ...owned.psf.configuration.psf,\n wavelengthNm: spectral.wavelengthNanometers, fieldPointMm: { x: destination.x, y: -destination.y } }) : null;\n const kernel = resolved?.value.kernel;\n const taps = kernel ? kernel.widthSamples*kernel.heightSamples : 1;\n count += taps*owned.temporalSampleCount*pupilCount;\n if (count > 100000) throw new InvalidScientificInputError(\"Environment exposure exceeds the 100000-provider-evaluation budget.\");\n const points = Array.from({ length: taps }, (_, i) => ({ kernelSampleX: kernel ? i%kernel.widthSamples : 0,\n kernelSampleY: kernel ? Math.floor(i/kernel.widthSamples) : 0,\n point: kernel ? sensorPsfSourcePoint(destination, kernel, i%kernel.widthSamples, Math.floor(i/kernel.widthSamples)) : { ...destination } }));\n return { node, points: points.map(p => ({ ...p, fieldThroughput: owned.fieldThroughput.kind === \"unity\"\n ? { kind: \"unity\" as const }\n : { kind: \"illumination-vignetting-result\" as const, result: calculateIlluminationVignetting({\n imagePointMm: { x: p.point.x, y: -p.point.y }, profile: owned.fieldThroughput.profile }).value } })) };\n }));\n const measure = window.localExposureDurationSeconds/owned.temporalSampleCount;\n let previous = -Infinity;\n const instants = Array.from({ length: owned.temporalSampleCount }, (_, temporalSampleIndex) => {\n const time = window.startOffsetSecondsFromOpeningReference+(temporalSampleIndex+.5)*measure;\n if (!(time > window.startOffsetSecondsFromOpeningReference && time > previous && time < window.endOffsetSecondsFromOpeningReference)) throw new InvalidScientificInputError(\"Local midpoints must be representable and strictly ordered.\");\n previous = time;\n const groups = nodes.map((n, ni) => ({ node: n.node, taps: n.points.map((p, pi) => {\n const apertureRays = owned.pupil === undefined ? undefined : calculateSensorApertureRays({sourcePointNativeSensorMm:p.point,\n focalLengthMm:owned.optics.focalLengthMm,nominalFNumber:owned.optics.nominalFNumber,focus,pupil:owned.pupil,\n angularVelocityRadPerSec:owned.motion.angularVelocityRadPerSec,timeSecondsFromOpeningReference:time}).value.rays;\n const queryInput: CalculateSensorEnvironmentRadianceQueryInput = { ...owned.motion, sourcePointNativeSensorMm: p.point,\n focalLengthMm: owned.optics.focalLengthMm, focus, timeSecondsFromOpeningReference: time,\n request: { schemaVersion: \"0.1.0\", sampleId: `${owned.temporalIntegrationId}-t${temporalSampleIndex}-n${ni}-p${pi}`,\n providerProfileId: sceneBindings.providerProfile.profileId, sceneId: sceneBindings.providerProfile.sceneId,\n illuminationProfileId: sceneBindings.illuminationProfile.profileId, materialResponseProfileId: sceneBindings.materialResponseProfile.profileId,\n wavelengthNanometers: n.node.wavelengthNanometers, wavelengthBasis } };\n const query = freezePlannedRequest(lensMapping === undefined ? calculateSensorEnvironmentRadianceQuery(queryInput)\n : calculateMappedSensorEnvironmentRadianceQuery(queryInput, lensMapping));\n const areaFactor = query.value.lensFieldMapping?.distortionAreaFactor;\n // Photo-only plans drop the query result (projection, diagnostics) once it is validated (a 2.0 memory saving).\n return { ...p, ...(apertureRays === undefined ? {} : { apertureRays }),\n ...(areaFactor === undefined ? {} : { distortionAreaFactor: areaFactor }), request: query.value.request,\n sourcePointImagePlaneMm: query.value.sourcePointImagePlaneMm, ...(retention === \"full\" ? { query } : {}) };\n }) }));\n // Validate PSF evidence/basis/support before supplied code is invoked.\n if (owned.psf.kind === \"sampled-local\") calculateSensorPsfIrradianceQuadrature({ ...owned.psf.configuration,\n spatialQuadrature, spectralQuadrature, timeSecondsFromOpeningReference: time,\n inputMeaning: \"pre-psf-pre-sensor-stack-pre-aa-spectral-irradiance\", samples: groups.map(g => ({ node: g.node,\n sourceSamples: g.taps.map(t => ({ kernelSampleX: t.kernelSampleX, kernelSampleY: t.kernelSampleY,\n sourcePointNativeSensorMm: t.point, timeSecondsFromOpeningReference: time, spectralIrradianceWattsPerSquareMeterPerNanometer: 0 })) })) });\n return { temporalSampleIndex, time, groups };\n });\n return { owned, sceneBindings, fieldThroughputEvidence, spatialQuadrature, spectralQuadrature, instants, count, focus };\n}\n\n/** Aperture queries already built for a batched provider, keyed by the planned ray; each is used once. */\nconst PREBUILT_APERTURE_QUERIES = new WeakMap<object, { base: object; request: SceneRadianceEvaluationRequest; apertureRay: SensorApertureRay }>();\n\n/**\n * Internal: the frozen provider request and frozen private ray copy of one ideal-pupil query (sample ID suffix \"-a\"\n * and the pupil index, reversed ray direction). If prebuildApertureRadianceQuery already built this query for a batch,\n * the same objects are returned once, so the batch and the executor share them; otherwise new ones are built.\n */\nexport function apertureRadianceQuery(base: SceneRadianceEvaluationRequest, ray: SensorApertureRay):\n { request: SceneRadianceEvaluationRequest; apertureRay: SensorApertureRay } {\n const prebuilt = PREBUILT_APERTURE_QUERIES.get(ray);\n if (prebuilt !== undefined && prebuilt.base === base) {\n PREBUILT_APERTURE_QUERIES.delete(ray);\n return { request: prebuilt.request, apertureRay: prebuilt.apertureRay };\n }\n return { request: freezeOwnedData({ ...base, sampleId: base.sampleId+\"-a\"+ray.pupilSampleIndex,\n target: { kind: \"environment-direction\" as const, outgoingDirectionUnitVector: {\n x: -ray.directionUnitVector.x, y: -ray.directionUnitVector.y, z: -ray.directionUnitVector.z } } }),\n apertureRay: freezeOwnedData(copyRay(ray)) };\n}\n/**\n * A private copy of an engine-computed ray: plain records of numbers, copied key by key in the same order, so it\n * equals what structuredClone returns for this data (a 2.0 performance change: structuredClone dominated pupil runs).\n */\nfunction copyRay(ray: SensorApertureRay): SensorApertureRay {\n const copy = (value: unknown): unknown => {\n if (typeof value !== \"object\" || value === null) return value;\n if (Array.isArray(value)) return value.map(copy);\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(value)) out[key] = copy((value as Record<string, unknown>)[key]);\n return out;\n };\n return copy(ray) as SensorApertureRay;\n}\n/** Internal: builds a pupil query for a batched provider and keeps it for the executor's apertureRadianceQuery call. */\nexport function prebuildApertureRadianceQuery(base: SceneRadianceEvaluationRequest, ray: SensorApertureRay):\n { request: SceneRadianceEvaluationRequest; apertureRay: SensorApertureRay } {\n PREBUILT_APERTURE_QUERIES.delete(ray);\n const query = apertureRadianceQuery(base, ray);\n PREBUILT_APERTURE_QUERIES.set(ray, { base, ...query });\n return query;\n}\n\n/** Deep-freezes a planned provider request once, so execution can hand the same immutable request to supplied code. */\nfunction freezePlannedRequest<T extends { value: { request: object } }>(query: T): T {\n freezeOwnedData(query.value.request);\n return query;\n}\n\n/**\n * Internal: runs a completed, bounded plan. On failure nothing partial is returned.\n * With retention \"full\" (default), every per-evaluation record is kept in value.instants[].evaluations.\n * With \"photo-only\", those lists are empty, for engine callers that read only value.photo. Photo values\n * are identical either way.\n */\nexport function executeEnvironmentSensorPhotoSignal(plan: ReturnType<typeof planEnvironmentSensorPhotoSignal>, evaluate: EnvironmentRadianceEvaluator, evaluateAperture?: EnvironmentApertureRadianceEvaluator,\n retention: \"full\" | \"photo-only\" = \"full\"): CalculationResult<EnvironmentSensorPhotoSignal> {\n if (typeof evaluate !== \"function\") throw new InvalidScientificInputError(\"Environment radiance evaluator must be synchronous callable code.\");\n const { owned } = plan;\n if (owned.pupil !== undefined && typeof evaluateAperture !== \"function\") throw new InvalidScientificInputError(\"Pupil integration requires an origin-aware aperture evaluator.\");\n if (retention === \"full\" && plan.instants.some(instant => instant.groups.some(group => group.taps.some(tap => tap.query === undefined)))) {\n throw new InvalidScientificInputError(\"Full environment execution records require a full plan.\");\n }\n const irradiance = [];\n const instants: EnvironmentSensorPhotoSignal[\"instants\"][number][] = [];\n for (const instant of plan.instants) {\n const evaluations: EnvironmentSensorPhotoSignal[\"instants\"][number][\"evaluations\"][number][] = [];\n const samples = instant.groups.map(group => ({ node: group.node, sourceSamples: group.taps.map(tap => {\n let integratedIrradiance = 0;\n const support: readonly (SensorApertureRay | undefined)[] = tap.apertureRays ?? [undefined];\n for (const ray of support) {\n // Planned requests are deep-frozen once at plan time (freezePlannedRequest); no per-evaluation clone.\n const query = ray === undefined ? undefined : apertureRadianceQuery(tap.request, ray);\n const request = query === undefined ? tap.request : query.request, apertureRay = query?.apertureRay;\n const result = parseSceneRadianceEvaluationResult(apertureRay === undefined ? evaluate(request) : evaluateAperture!(request,apertureRay));\n const bindings = validateSceneRadianceEvaluationBindings({ ...plan.sceneBindings, request, result });\n const optics = calculateSceneRadianceToSensorIrradiance({ ...owned.optics, sceneRadianceRequest: request,\n sceneRadianceResult: result, imagePointMm: tap.sourcePointImagePlaneMm, fieldThroughput: tap.fieldThroughput });\n if (retention === \"full\") evaluations.push({ query: tap.query!, result, bindings, optics,\n ...(apertureRay === undefined ? {} : {apertureRay,apertureRequest:request}) });\n integratedIrradiance += optics.value.sensorPlaneSpectralIrradianceWattsPerSquareMeterNanometer*(ray?.weight ?? 1);\n }\n if (tap.distortionAreaFactor !== undefined) {\n // Distortion squeezes or stretches the ideal image. Flux is conserved, so irradiance scales by 1/det, once.\n integratedIrradiance *= tap.distortionAreaFactor;\n }\n return { kernelSampleX: tap.kernelSampleX, kernelSampleY: tap.kernelSampleY, sourcePointNativeSensorMm: tap.point,\n timeSecondsFromOpeningReference: instant.time, spectralIrradianceWattsPerSquareMeterPerNanometer: integratedIrradiance };\n }) }));\n const psf = owned.psf.kind === \"sampled-local\" ? calculateSensorPsfIrradianceQuadrature({ ...owned.psf.configuration,\n spatialQuadrature: plan.spatialQuadrature, spectralQuadrature: plan.spectralQuadrature,\n timeSecondsFromOpeningReference: instant.time, inputMeaning: \"pre-psf-pre-sensor-stack-pre-aa-spectral-irradiance\", samples }) : null;\n irradiance.push({ temporalSampleIndex: instant.temporalSampleIndex, timeSecondsFromOpeningReference: instant.time,\n irradianceSamples: psf ? psf.value.irradianceSamples : samples.map(s => ({ node: s.node,\n spectralIrradianceWattsPerSquareMeterPerNanometer: s.sourceSamples[0]!.spectralIrradianceWattsPerSquareMeterPerNanometer })) });\n instants.push({ temporalSampleIndex: instant.temporalSampleIndex, timeSecondsFromOpeningReference: instant.time, psf, evaluations });\n }\n const photo = createSensorEqeTemporalPhotoSignal({ temporalIntegrationId: owned.temporalIntegrationId,\n exposure: { ...owned.sensor, samples: irradiance } });\n return approximationResult({ sourceTargetProjectionCalculated: true, providerCallbackExecuted: true,\n providerTransportVerified: false, sceneVisibilityCalculated: false, productionPlanActivated: false,\n providerEvaluationCount: plan.count, sourcePlane: \"sensor-package-incident\", fieldThroughputEvidence: plan.fieldThroughputEvidence,\n fieldThroughputLimitation: owned.fieldThroughput.limitation,\n psfOmission: owned.psf.kind === \"not-applied\" ? { evidence: parseEvidenceList(owned.psf.evidence, \"psfOmission.evidence\"), limitation: owned.psf.limitation } : null,\n psfRedistributionApplied: owned.psf.kind === \"sampled-local\", pupilIntegrationApplied: owned.pupil !== undefined, pupilIntegrationProfile: owned.pupil ?? null, photo, instants\n }, \"environment-sensor-photo-signal\", owned.lensFieldMapping === undefined ? \"0.3.0\" : \"0.4.0\", [\n \"Supplied synchronous provider code was invoked at each generated environment query; physical transport and visibility are not verified.\",\n \"Ideal focus-aware rotation/projection, explicit evidence-bound field throughput and optional destination-local sampled PSF are bounded approximations.\",\n \"Optional ideal pupil rays use normalized radiance averaging; source intersections remain provider-owned and convergence is unverified.\",\n \"PSF pupil throughput is not applied; child uncertainty, finite-support and quadrature convergence are not combined or established.\",\n ...(owned.lensFieldMapping === undefined ? [] : [\n \"Lens field mapping: rays use the declared projection after inverse distortion; irradiance is multiplied once by the distortion area factor 1/det(d distorted/d ideal); field throughput and sampled PSFs remain evaluated at the physical sensor point.\"\n ])\n ]);\n}\n\n/** Plans, queries the provider and integrates the photo signal for one site, at the site's own midpoint sample positions. */\nexport function calculateEnvironmentSensorPhotoSignal(input: CalculateEnvironmentSensorPhotoSignalInput): CalculationResult<EnvironmentSensorPhotoSignal> {\n requireInputKeys(input, \"calculateEnvironmentSensorPhotoSignal\", [\"temporalIntegrationId\", \"sensor\", \"sceneBindings\", \"optics\", \"motion\", \"temporalSampleCount\", \"pupil\", \"lensFieldMapping\", \"fieldThroughput\", \"psf\", \"evaluateRadiance\", \"evaluateApertureRadiance\"]);\n const { evaluateRadiance, evaluateApertureRadiance, ...data } = input;\n return executeEnvironmentSensorPhotoSignal(planEnvironmentSensorPhotoSignal(data), evaluateRadiance, evaluateApertureRadiance);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"environment-photo-signal.js","sourceRoot":"","sources":["../../src/sensor/environment-photo-signal.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Photo signal for one sensor site from a scene-radiance provider (the \"environment\"): asks the\n * provider for radiance along each sampled direction, then applies optics and the sensor response.\n *\n * Work is split into a plan and an execution step. Planning checks spatial, spectral and temporal\n * coverage and builds an internal plan before any provider code runs. Each query gives an explicit\n * scene direction, a wavelength (air or vacuum) and a time in seconds from the shutter's opening\n * reference. Optical throughput, an optional local PSF (point-spread function) and the EQE (external\n * quantum efficiency) response then give the expected photo signal. Calling the provider does not\n * verify its light transport, visibility or calibration.\n * @see docs/ENVIRONMENT_RAW_CAPTURE.md for equations, coordinate/unit conventions, blockers and\n * support limits.\n */\n\nimport { approximationResult, type CalculationResult } from \"../core/calculation-result.js\";\nimport { freezeOwnedData } from \"../core/owned-data.js\";\nimport { requirePublicOpaqueId, requireInputKeys } from \"../core/record-validation.js\";\nimport { parseEvidenceList, type EvidenceProvenance } from \"../core/evidence-provenance.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport { parseSceneIlluminationProfile } from \"../schema/illumination.js\";\nimport { parseSceneIlluminationTemporalProfile } from \"../schema/illumination-temporal.js\";\nimport { parseSceneMaterialResponseProfile, parseSceneRadianceProviderProfile, parseSceneRadianceEvaluationResult,\n parseSceneRadianceEvaluationResultWithValidatedRecords, validateSceneRadianceEvaluationBindings, validateSceneRadianceRequestResultBindings,\n type SceneRadianceEvaluationRequest, type SceneRadianceEvaluationResult, type ValidatedSceneRadianceRecords } from \"../schema/scene-radiance.js\";\nimport { calculateMappedSensorEnvironmentRadianceQuery, calculateSensorEnvironmentRadianceQuery, prepareEnvironmentLensFieldMapping,\n type CalculateSensorEnvironmentRadianceQueryInput, type EnvironmentLensFieldMapping } from \"../optics/sensor-environment-query.js\";\nimport { calculateSceneRadianceToSensorIrradiance, prepareSceneRadianceToSensorIrradianceValue,\n type CalculateSceneRadianceToSensorIrradianceInput } from \"../optics/scene-to-sensor-irradiance.js\";\nimport { isDeeplyFrozen } from \"../core/internal-radiance-evaluator.js\";\nimport { calculateSensorPsfIrradianceQuadrature, type CalculateSensorPsfIrradianceQuadratureInput } from \"../optics/sensor-psf-quadrature.js\";\nimport { calculateIlluminationVignetting, type IlluminationVignettingProfile } from \"../optics/illumination-vignetting.js\";\nimport { calculateSensorApertureRays, type IdealCircularPupil, type SensorApertureRay } from \"../optics/sensor-aperture-rays.js\";\nimport { sensorPsfSourcePoint } from \"../optics/sensor-psf-support.js\";\nimport { markEngineOwnedLensSampledPsfProfile, resolveLensSampledPsf } from \"../optics/lens-psf-profile.js\";\nimport { calculateSensorSpatialSamplingQuadrature } from \"./spatial-sampling-quadrature.js\";\nimport { calculateSensorSpectralQuadrature } from \"./spectral-quadrature.js\";\nimport { resolveNativeEffectiveRasterColorSamplingBinding } from \"./capture-color-sampling-binding.js\";\nimport { calculateCaptureExposureWindows } from \"./exposure-window.js\";\nimport { createSensorEqeTemporalPhotoSignal } from \"./temporal-photo-signal.js\";\nimport type { CalculateSensorEqeTemporalExposureInput } from \"./eqe-temporal-exposure.js\";\nimport type { CalculateSceneToSensorIrradianceQuadratureInput } from \"../optics/scene-to-sensor-quadrature.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\n\n/** Caller-supplied synchronous radiance function, run locally. Calling it does not prove its light transport is physical. */\nexport type EnvironmentRadianceEvaluator = (request: Readonly<SceneRadianceEvaluationRequest>) => SceneRadianceEvaluationResult;\nexport type EnvironmentApertureRadianceEvaluator = (request: Readonly<SceneRadianceEvaluationRequest>, apertureRay: Readonly<SensorApertureRay>) => SceneRadianceEvaluationResult;\nexport interface CalculateEnvironmentSensorPhotoSignalInput {\n temporalIntegrationId: string;\n sensor: Omit<CalculateSensorEqeTemporalExposureInput, \"samples\">;\n sceneBindings: CalculateSceneToSensorIrradianceQuadratureInput[\"sceneBindings\"];\n optics: Omit<CalculateSceneRadianceToSensorIrradianceInput,\n \"sceneRadianceRequest\" | \"sceneRadianceResult\" | \"imagePointMm\" | \"fieldThroughput\">;\n motion: Pick<CalculateSensorEnvironmentRadianceQueryInput,\n \"angularVelocityRadPerSec\" | \"timeReference\" | \"environmentDirectionConvention\">;\n temporalSampleCount: number;\n /** Optional ideal circular pupil, for geometric depth of field (DOF) and visibility. Cannot be combined with a sampled PSF. */\n pupil?: IdealCircularPupil;\n /**\n * Optional lens field mapping (added in 2.0): a projection model and radial or Brown-Conrady\n * distortion for the scene-ray query. Its distortion area factor is applied to irradiance exactly\n * once. If omitted, the ideal rectilinear, distortion-free path is unchanged. Cannot be combined\n * with `pupil`.\n */\n lensFieldMapping?: EnvironmentLensFieldMapping;\n /** Explicit attenuation across the field (such as vignetting), applied once before the PSF spreads the light. */\n fieldThroughput: { kind: \"unity\"; evidence: readonly EvidenceProvenance[]; limitation: string } | {\n kind: \"radial-illumination-vignetting\"; profile: IlluminationVignettingProfile;\n evidence: readonly EvidenceProvenance[]; limitation: string;\n };\n psf: { kind: \"not-applied\"; evidence: readonly EvidenceProvenance[]; limitation: string } | {\n kind: \"sampled-local\";\n configuration: Pick<CalculateSensorPsfIrradianceQuadratureInput, \"psf\" | \"psfWavelengthBasis\" | \"spatialModel\">;\n };\n evaluateRadiance: EnvironmentRadianceEvaluator;\n /** Required with `pupil`: rays start at different points on the aperture, so a direction-only function cannot be used. */\n evaluateApertureRadiance?: EnvironmentApertureRadianceEvaluator;\n}\nexport interface EnvironmentSensorPhotoSignal {\n sourceTargetProjectionCalculated: true;\n providerCallbackExecuted: true;\n providerTransportVerified: false;\n sceneVisibilityCalculated: false;\n productionPlanActivated: false;\n providerEvaluationCount: number;\n sourcePlane: \"sensor-package-incident\";\n fieldThroughputEvidence: readonly EvidenceProvenance[];\n fieldThroughputLimitation: string;\n psfOmission: { evidence: readonly EvidenceProvenance[]; limitation: string } | null;\n psfRedistributionApplied: boolean;\n pupilIntegrationApplied: boolean;\n pupilIntegrationProfile: IdealCircularPupil | null;\n photo: ReturnType<typeof createSensorEqeTemporalPhotoSignal>;\n instants: readonly {\n temporalSampleIndex: number;\n timeSecondsFromOpeningReference: number;\n psf: ReturnType<typeof calculateSensorPsfIrradianceQuadrature> | null;\n evaluations: readonly {\n query: ReturnType<typeof calculateSensorEnvironmentRadianceQuery>;\n result: SceneRadianceEvaluationResult;\n bindings: ReturnType<typeof validateSceneRadianceEvaluationBindings>;\n optics: ReturnType<typeof calculateSceneRadianceToSensorIrradiance>;\n apertureRay?: SensorApertureRay;\n apertureRequest?: SceneRadianceEvaluationRequest;\n }[];\n }[];\n}\n\n/** Internal plan, shared with the full-frame composer, so all work is bounded before any callback runs. */\ninterface EnvironmentPhotoPlan {\n owned: Omit<CalculateEnvironmentSensorPhotoSignalInput, \"evaluateRadiance\" | \"evaluateApertureRadiance\">;\n sceneBindings: CalculateSceneToSensorIrradianceQuadratureInput[\"sceneBindings\"];\n fieldThroughputEvidence: readonly EvidenceProvenance[];\n spatialQuadrature: ReturnType<typeof calculateSensorSpatialSamplingQuadrature>[\"value\"];\n spectralQuadrature: ReturnType<typeof calculateSensorSpectralQuadrature>[\"value\"];\n count: number;\n focus: CalculateSensorEnvironmentRadianceQueryInput[\"focus\"];\n instants: { temporalSampleIndex: number; time: number; groups: {\n node: CalculateSensorPsfIrradianceQuadratureInput[\"samples\"][number][\"node\"];\n taps: { kernelSampleX: number; kernelSampleY: number; point: { x: number; y: number };\n /** Deep-frozen provider request of the planned query (the same object as query.value.request). */\n request: SceneRadianceEvaluationRequest;\n /** The planned query's image-plane source point (the same object as query.value.sourcePointImagePlaneMm). */\n sourcePointImagePlaneMm: { x: number; y: number };\n /** The complete query result. Kept only by \"full\" plans, whose per-evaluation records include it. */\n query?: ReturnType<typeof calculateSensorEnvironmentRadianceQuery>;\n apertureRays?: readonly SensorApertureRay[];\n /** 1 / det(d distorted / d ideal), the change in area from distortion. Present only with a lens field mapping. */\n distortionAreaFactor?: number;\n fieldThroughput: CalculateSceneRadianceToSensorIrradianceInput[\"fieldThroughput\"] }[];\n }[] }[];\n}\n/**\n * Builds an internal execution plan covering all optical, spatial, spectral and temporal sampling,\n * without calling any provider code.\n *\n * Coverage is checked completely before any supplied radiance function runs. Each query gives an\n * explicit scene direction, a wavelength (air or vacuum) and seconds from the opening reference.\n * @param input - The photo-signal input without its radiance functions; see\n * `CalculateEnvironmentSensorPhotoSignalInput`.\n * @param ownership - Internal. \"copy\" (default) makes a structured clone of the input. \"engine-owned\"\n * uses the input as the plan's own data without cloning again. Only engine callers that already hold a\n * private structured clone, never shown to supplied code and never changed afterwards, may pass it.\n * @param retention - Internal. \"full\" (default) keeps every planned query result for \"full\" execution\n * records. \"photo-only\" keeps only each query's frozen request and image-plane point, which is all that\n * photo-only execution reads. Every query is still computed and validated at plan time, so limit checks\n * and errors are unchanged.\n * @returns The result. Success does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the package export and its full type definitions.\n */\nexport function planEnvironmentSensorPhotoSignal(input: Omit<CalculateEnvironmentSensorPhotoSignalInput, \"evaluateRadiance\" | \"evaluateApertureRadiance\">,\n ownership: \"copy\" | \"engine-owned\" = \"copy\", retention: \"full\" | \"photo-only\" = \"full\"): EnvironmentPhotoPlan {\n const owned = ownership === \"engine-owned\" ? input : structuredClone(input);\n requirePublicOpaqueId(owned.temporalIntegrationId, \"Environment integration requires a public identity.\");\n if (!Number.isSafeInteger(owned.temporalSampleCount) || owned.temporalSampleCount < 1 || owned.temporalSampleCount > 256 ||\n owned.sensor.responseApplication.sourcePlane.value !== \"sensor-package-incident\" ||\n (owned.fieldThroughput?.kind !== \"unity\" && owned.fieldThroughput?.kind !== \"radial-illumination-vignetting\") || typeof owned.fieldThroughput.limitation !== \"string\" || !owned.fieldThroughput.limitation.trim()) {\n throw new InvalidScientificInputError(\"Environment exposure requires package-incident response, 1..256 midpoints and explicit supported field throughput.\");\n }\n if (owned.fieldThroughput.kind === \"radial-illumination-vignetting\" &&\n (typeof owned.fieldThroughput.profile !== \"object\" || owned.fieldThroughput.profile === null ||\n typeof owned.fieldThroughput.profile.coefficients !== \"object\" || owned.fieldThroughput.profile.coefficients === null)) {\n throw new InvalidScientificInputError(\"Radial throughput requires a declared profile and coefficients.\");\n }\n const fieldThroughputEvidence = parseEvidenceList(owned.fieldThroughput.evidence, \"environmentFieldThroughput.evidence\");\n const sceneBindings = { providerProfile: parseSceneRadianceProviderProfile(owned.sceneBindings.providerProfile),\n illuminationProfile: parseSceneIlluminationProfile(owned.sceneBindings.illuminationProfile),\n materialResponseProfile: parseSceneMaterialResponseProfile(owned.sceneBindings.materialResponseProfile),\n ...(owned.sceneBindings.illuminationTemporalProfile === undefined ? {} : {\n illuminationTemporalProfile: parseSceneIlluminationTemporalProfile(owned.sceneBindings.illuminationTemporalProfile) }) };\n if (sceneBindings.providerProfile.fidelity.spectral !== \"wavelength-resolved\") throw new InvalidScientificInputError(\"Environment exposure requires wavelength-resolved provider fidelity.\");\n const sensor = owned.sensor;\n const nativeRaster = sensor.localExposure.exposureWindowInput.nativeRaster;\n const binding = resolveNativeEffectiveRasterColorSamplingBinding({ nativeRaster, colorSamplingProfile: sensor.colorSamplingProfile,\n bindingProfile: sensor.localExposure.bindingProfile });\n if (binding.relationshipMeaning !== \"one-native-effective-sample-to-one-color-site\") throw new InvalidScientificInputError(\"Environment exposure requires explicit one-to-one native/color timing.\");\n const spatialQuadrature = calculateSensorSpatialSamplingQuadrature({ ...sensor.spatialSampling, nativeRaster,\n colorSamplingProfile: sensor.colorSamplingProfile, colorSamplingBindingProfile: sensor.localExposure.bindingProfile }).value;\n const spectralQuadrature = calculateSensorSpectralQuadrature({ ...sensor.spectralSampling,\n colorSamplingProfile: sensor.colorSamplingProfile, spectralResponseProfile: sensor.spectralResponseProfile }).value;\n if (spectralQuadrature.wavelengthBasis === \"unspecified\") throw new InvalidScientificInputError(\"Environment spectral basis must be explicit.\");\n const wavelengthBasis = spectralQuadrature.wavelengthBasis;\n const site = sensor.spatialSampling.site;\n const window = calculateCaptureExposureWindows({ ...sensor.localExposure.exposureWindowInput,\n samplePointsNative: [{ x: site.x+.5, y: site.y+.5 }] }).value.samples[0]!;\n const focus = owned.optics.focus.kind === \"infinity-focus\" ? { kind: \"infinity\" as const } :\n owned.optics.focus.kind === \"ideal-symmetric-thin-lens\" ? { kind: \"finite\" as const, distanceM: owned.optics.focus.objectDistanceM } :\n owned.optics.focus.focus.kind === \"infinity\" ? { kind: \"infinity\" as const } : { kind: \"finite\" as const, distanceM: owned.optics.focus.focus.objectDistanceM };\n if (owned.psf.kind === \"not-applied\") {\n parseEvidenceList(owned.psf.evidence, \"environmentPsfOmission.evidence\");\n if (typeof owned.psf.limitation !== \"string\" || !owned.psf.limitation.trim()) throw new InvalidScientificInputError(\"PSF omission needs an explicit limitation.\");\n } else if (owned.psf.kind !== \"sampled-local\") throw new InvalidConfigurationError(\"Unknown environment PSF selection.\");\n if (owned.psf.kind === \"sampled-local\") {\n const p = owned.psf.configuration.psf;\n // The profile belongs only to this plan, so its parse can be cached across nodes and time instants.\n markEngineOwnedLensSampledPsfProfile(p.profile);\n if (p.focalLengthMm !== owned.optics.focalLengthMm || p.apertureFNumber !== owned.optics.nominalFNumber ||\n p.focus.kind !== focus.kind || (p.focus.kind === \"finite\" && focus.kind === \"finite\" && p.focus.distanceM !== focus.distanceM)) {\n throw new InvalidScientificInputError(\"PSF and optical focal/aperture/focus state must match exactly.\");\n }\n }\n if (owned.pupil !== undefined && owned.psf.kind !== \"not-applied\") throw new InvalidScientificInputError(\"Ideal pupil integration cannot mix with a sampled PSF; geometric defocus would be ambiguous.\");\n const lensMapping = owned.lensFieldMapping === undefined ? undefined : prepareEnvironmentLensFieldMapping(owned.lensFieldMapping);\n if (lensMapping !== undefined && owned.pupil !== undefined) {\n throw new InvalidScientificInputError(\"Ideal pupil rays use the rectilinear distortion-free projection and cannot combine with a lens field mapping.\");\n }\n const pupilCount = owned.pupil === undefined ? 1 : calculateSensorApertureRays({sourcePointNativeSensorMm:{x:0,y:0},\n focalLengthMm:owned.optics.focalLengthMm,nominalFNumber:owned.optics.nominalFNumber,focus,pupil:owned.pupil,\n angularVelocityRadPerSec:owned.motion.angularVelocityRadPerSec,timeSecondsFromOpeningReference:window.startOffsetSecondsFromOpeningReference}).value.rays.length;\n let count = 0;\n const nodes = spectralQuadrature.nodes.flatMap(spectral => spatialQuadrature.nodes.map(spatial => {\n const node = { spatialNode: { antiAliasingComponentIndex: spatial.antiAliasingComponentIndex,\n apertureSampleXIndex: spatial.apertureSampleXIndex, apertureSampleYIndex: spatial.apertureSampleYIndex },\n spectralSampleIndex: spectral.spectralSampleIndex, wavelengthNanometers: spectral.wavelengthNanometers };\n const destination = spatial.preAntiAliasingSourcePointMm;\n const resolved = owned.psf.kind === \"sampled-local\" ? resolveLensSampledPsf({ ...owned.psf.configuration.psf,\n wavelengthNm: spectral.wavelengthNanometers, fieldPointMm: { x: destination.x, y: -destination.y } }) : null;\n const kernel = resolved?.value.kernel;\n const taps = kernel ? kernel.widthSamples*kernel.heightSamples : 1;\n count += taps*owned.temporalSampleCount*pupilCount;\n if (count > 100000) throw new InvalidScientificInputError(\"Environment exposure exceeds the 100000-provider-evaluation budget.\");\n const points = Array.from({ length: taps }, (_, i) => ({ kernelSampleX: kernel ? i%kernel.widthSamples : 0,\n kernelSampleY: kernel ? Math.floor(i/kernel.widthSamples) : 0,\n point: kernel ? sensorPsfSourcePoint(destination, kernel, i%kernel.widthSamples, Math.floor(i/kernel.widthSamples)) : { ...destination } }));\n return { node, points: points.map(p => ({ ...p, fieldThroughput: owned.fieldThroughput.kind === \"unity\"\n ? { kind: \"unity\" as const }\n : { kind: \"illumination-vignetting-result\" as const, result: calculateIlluminationVignetting({\n imagePointMm: { x: p.point.x, y: -p.point.y }, profile: owned.fieldThroughput.profile }).value } })) };\n }));\n const measure = window.localExposureDurationSeconds/owned.temporalSampleCount;\n let previous = -Infinity;\n const instants = Array.from({ length: owned.temporalSampleCount }, (_, temporalSampleIndex) => {\n const time = window.startOffsetSecondsFromOpeningReference+(temporalSampleIndex+.5)*measure;\n if (!(time > window.startOffsetSecondsFromOpeningReference && time > previous && time < window.endOffsetSecondsFromOpeningReference)) throw new InvalidScientificInputError(\"Local midpoints must be representable and strictly ordered.\");\n previous = time;\n const groups = nodes.map((n, ni) => ({ node: n.node, taps: n.points.map((p, pi) => {\n const apertureRays = owned.pupil === undefined ? undefined : calculateSensorApertureRays({sourcePointNativeSensorMm:p.point,\n focalLengthMm:owned.optics.focalLengthMm,nominalFNumber:owned.optics.nominalFNumber,focus,pupil:owned.pupil,\n angularVelocityRadPerSec:owned.motion.angularVelocityRadPerSec,timeSecondsFromOpeningReference:time}).value.rays;\n const queryInput: CalculateSensorEnvironmentRadianceQueryInput = { ...owned.motion, sourcePointNativeSensorMm: p.point,\n focalLengthMm: owned.optics.focalLengthMm, focus, timeSecondsFromOpeningReference: time,\n request: { schemaVersion: \"0.1.0\", sampleId: `${owned.temporalIntegrationId}-t${temporalSampleIndex}-n${ni}-p${pi}`,\n providerProfileId: sceneBindings.providerProfile.profileId, sceneId: sceneBindings.providerProfile.sceneId,\n illuminationProfileId: sceneBindings.illuminationProfile.profileId, materialResponseProfileId: sceneBindings.materialResponseProfile.profileId,\n wavelengthNanometers: n.node.wavelengthNanometers, wavelengthBasis } };\n const query = freezePlannedRequest(lensMapping === undefined ? calculateSensorEnvironmentRadianceQuery(queryInput)\n : calculateMappedSensorEnvironmentRadianceQuery(queryInput, lensMapping));\n const areaFactor = query.value.lensFieldMapping?.distortionAreaFactor;\n // Photo-only plans drop the query result (projection, diagnostics) once it is validated (a 2.0 memory saving).\n return { ...p, ...(apertureRays === undefined ? {} : { apertureRays }),\n ...(areaFactor === undefined ? {} : { distortionAreaFactor: areaFactor }), request: query.value.request,\n sourcePointImagePlaneMm: query.value.sourcePointImagePlaneMm, ...(retention === \"full\" ? { query } : {}) };\n }) }));\n // Validate PSF evidence/basis/support before supplied code is invoked.\n if (owned.psf.kind === \"sampled-local\") calculateSensorPsfIrradianceQuadrature({ ...owned.psf.configuration,\n spatialQuadrature, spectralQuadrature, timeSecondsFromOpeningReference: time,\n inputMeaning: \"pre-psf-pre-sensor-stack-pre-aa-spectral-irradiance\", samples: groups.map(g => ({ node: g.node,\n sourceSamples: g.taps.map(t => ({ kernelSampleX: t.kernelSampleX, kernelSampleY: t.kernelSampleY,\n sourcePointNativeSensorMm: t.point, timeSecondsFromOpeningReference: time, spectralIrradianceWattsPerSquareMeterPerNanometer: 0 })) })) });\n return { temporalSampleIndex, time, groups };\n });\n return { owned, sceneBindings, fieldThroughputEvidence, spatialQuadrature, spectralQuadrature, instants, count, focus };\n}\n\n/** Aperture queries already built for a batched provider, keyed by the planned ray; each is used once. */\nconst PREBUILT_APERTURE_QUERIES = new WeakMap<object, { base: object; request: SceneRadianceEvaluationRequest; apertureRay: SensorApertureRay }>();\n\n/**\n * Internal: the frozen provider request and frozen private ray copy of one ideal-pupil query (sample ID suffix \"-a\"\n * and the pupil index, reversed ray direction). If prebuildApertureRadianceQuery already built this query for a batch,\n * the same objects are returned once, so the batch and the executor share them; otherwise new ones are built.\n */\nexport function apertureRadianceQuery(base: SceneRadianceEvaluationRequest, ray: SensorApertureRay):\n { request: SceneRadianceEvaluationRequest; apertureRay: SensorApertureRay } {\n const prebuilt = PREBUILT_APERTURE_QUERIES.get(ray);\n if (prebuilt !== undefined && prebuilt.base === base) {\n PREBUILT_APERTURE_QUERIES.delete(ray);\n return { request: prebuilt.request, apertureRay: prebuilt.apertureRay };\n }\n return { request: freezeOwnedData({ ...base, sampleId: base.sampleId+\"-a\"+ray.pupilSampleIndex,\n target: { kind: \"environment-direction\" as const, outgoingDirectionUnitVector: {\n x: -ray.directionUnitVector.x, y: -ray.directionUnitVector.y, z: -ray.directionUnitVector.z } } }),\n apertureRay: freezeOwnedData(copyRay(ray)) };\n}\n/**\n * A private copy of an engine-computed ray: plain records of numbers, copied key by key in the same order, so it\n * equals what structuredClone returns for this data (a 2.0 performance change: structuredClone dominated pupil runs).\n */\nfunction copyRay(ray: SensorApertureRay): SensorApertureRay {\n const copy = (value: unknown): unknown => {\n if (typeof value !== \"object\" || value === null) return value;\n if (Array.isArray(value)) return value.map(copy);\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(value)) out[key] = copy((value as Record<string, unknown>)[key]);\n return out;\n };\n return copy(ray) as SensorApertureRay;\n}\n/** Internal: builds a pupil query for a batched provider and keeps it for the executor's apertureRadianceQuery call. */\nexport function prebuildApertureRadianceQuery(base: SceneRadianceEvaluationRequest, ray: SensorApertureRay):\n { request: SceneRadianceEvaluationRequest; apertureRay: SensorApertureRay } {\n PREBUILT_APERTURE_QUERIES.delete(ray);\n const query = apertureRadianceQuery(base, ray);\n PREBUILT_APERTURE_QUERIES.set(ray, { base, ...query });\n return query;\n}\n\n/** Deep-freezes a planned provider request once, so execution can hand the same immutable request to supplied code. */\nfunction freezePlannedRequest<T extends { value: { request: object } }>(query: T): T {\n freezeOwnedData(query.value.request);\n return query;\n}\n\n/**\n * Internal: runs a completed, bounded plan. On failure nothing partial is returned.\n * With retention \"full\" (default), every per-evaluation record is kept in value.instants[].evaluations.\n * With \"photo-only\", those lists are empty, for engine callers that read only value.photo. Photo values\n * are identical either way.\n */\nexport function executeEnvironmentSensorPhotoSignal(plan: ReturnType<typeof planEnvironmentSensorPhotoSignal>, evaluate: EnvironmentRadianceEvaluator, evaluateAperture?: EnvironmentApertureRadianceEvaluator,\n retention: \"full\" | \"photo-only\" = \"full\"): CalculationResult<EnvironmentSensorPhotoSignal> {\n if (typeof evaluate !== \"function\") throw new InvalidScientificInputError(\"Environment radiance evaluator must be synchronous callable code.\");\n const { owned } = plan;\n if (owned.pupil !== undefined && typeof evaluateAperture !== \"function\") throw new InvalidScientificInputError(\"Pupil integration requires an origin-aware aperture evaluator.\");\n if (retention === \"full\" && plan.instants.some(instant => instant.groups.some(group => group.taps.some(tap => tap.query === undefined)))) {\n throw new InvalidScientificInputError(\"Full environment execution records require a full plan.\");\n }\n const irradiance = [];\n const instants: EnvironmentSensorPhotoSignal[\"instants\"][number][] = [];\n for (const instant of plan.instants) {\n const evaluations: EnvironmentSensorPhotoSignal[\"instants\"][number][\"evaluations\"][number][] = [];\n const samples = instant.groups.map(group => ({ node: group.node, sourceSamples: group.taps.map(tap => {\n let integratedIrradiance = 0;\n const support: readonly (SensorApertureRay | undefined)[] = tap.apertureRays ?? [undefined];\n for (const ray of support) {\n // Planned requests are deep-frozen once at plan time (freezePlannedRequest); no per-evaluation clone.\n const query = ray === undefined ? undefined : apertureRadianceQuery(tap.request, ray);\n const request = query === undefined ? tap.request : query.request, apertureRay = query?.apertureRay;\n const result = parseSceneRadianceEvaluationResult(apertureRay === undefined ? evaluate(request) : evaluateAperture!(request,apertureRay));\n const bindings = validateSceneRadianceEvaluationBindings({ ...plan.sceneBindings, request, result });\n const optics = calculateSceneRadianceToSensorIrradiance({ ...owned.optics, sceneRadianceRequest: request,\n sceneRadianceResult: result, imagePointMm: tap.sourcePointImagePlaneMm, fieldThroughput: tap.fieldThroughput });\n if (retention === \"full\") evaluations.push({ query: tap.query!, result, bindings, optics,\n ...(apertureRay === undefined ? {} : {apertureRay,apertureRequest:request}) });\n integratedIrradiance += optics.value.sensorPlaneSpectralIrradianceWattsPerSquareMeterNanometer*(ray?.weight ?? 1);\n }\n if (tap.distortionAreaFactor !== undefined) {\n // Distortion squeezes or stretches the ideal image. Flux is conserved, so irradiance scales by 1/det, once.\n integratedIrradiance *= tap.distortionAreaFactor;\n }\n return { kernelSampleX: tap.kernelSampleX, kernelSampleY: tap.kernelSampleY, sourcePointNativeSensorMm: tap.point,\n timeSecondsFromOpeningReference: instant.time, spectralIrradianceWattsPerSquareMeterPerNanometer: integratedIrradiance };\n }) }));\n const psf = owned.psf.kind === \"sampled-local\" ? calculateSensorPsfIrradianceQuadrature({ ...owned.psf.configuration,\n spatialQuadrature: plan.spatialQuadrature, spectralQuadrature: plan.spectralQuadrature,\n timeSecondsFromOpeningReference: instant.time, inputMeaning: \"pre-psf-pre-sensor-stack-pre-aa-spectral-irradiance\", samples }) : null;\n irradiance.push({ temporalSampleIndex: instant.temporalSampleIndex, timeSecondsFromOpeningReference: instant.time,\n irradianceSamples: psf ? psf.value.irradianceSamples : samples.map(s => ({ node: s.node,\n spectralIrradianceWattsPerSquareMeterPerNanometer: s.sourceSamples[0]!.spectralIrradianceWattsPerSquareMeterPerNanometer })) });\n instants.push({ temporalSampleIndex: instant.temporalSampleIndex, timeSecondsFromOpeningReference: instant.time, psf, evaluations });\n }\n const photo = createSensorEqeTemporalPhotoSignal({ temporalIntegrationId: owned.temporalIntegrationId,\n exposure: { ...owned.sensor, samples: irradiance } });\n return approximationResult({ sourceTargetProjectionCalculated: true, providerCallbackExecuted: true,\n providerTransportVerified: false, sceneVisibilityCalculated: false, productionPlanActivated: false,\n providerEvaluationCount: plan.count, sourcePlane: \"sensor-package-incident\", fieldThroughputEvidence: plan.fieldThroughputEvidence,\n fieldThroughputLimitation: owned.fieldThroughput.limitation,\n psfOmission: owned.psf.kind === \"not-applied\" ? { evidence: parseEvidenceList(owned.psf.evidence, \"psfOmission.evidence\"), limitation: owned.psf.limitation } : null,\n psfRedistributionApplied: owned.psf.kind === \"sampled-local\", pupilIntegrationApplied: owned.pupil !== undefined, pupilIntegrationProfile: owned.pupil ?? null, photo, instants\n }, \"environment-sensor-photo-signal\", owned.lensFieldMapping === undefined ? \"0.3.0\" : \"0.4.0\", [\n \"Supplied synchronous provider code was invoked at each generated environment query; physical transport and visibility are not verified.\",\n \"Ideal focus-aware rotation/projection, explicit evidence-bound field throughput and optional destination-local sampled PSF are bounded approximations.\",\n \"Optional ideal pupil rays use normalized radiance averaging; source intersections remain provider-owned and convergence is unverified.\",\n \"PSF pupil throughput is not applied; child uncertainty, finite-support and quadrature convergence are not combined or established.\",\n ...(owned.lensFieldMapping === undefined ? [] : [\n \"Lens field mapping: rays use the declared projection after inverse distortion; irradiance is multiplied once by the distortion area factor 1/det(d distorted/d ideal); field throughput and sampled PSFs remain evaluated at the physical sensor point.\"\n ])\n ]);\n}\n\n/**\n * Internal (#453; not exported from the package): the photo signal of {@link executeEnvironmentSensorPhotoSignal} with\n * retention \"photo-only\" (its `value.photo`), for a plan of engine-built records (planned as \"engine-owned\" from a record the\n * engine built, never shown to supplied code and never changed). It is the same chain with the same operations: every query of\n * the plan calls `evaluate` once with the same frozen request, in the same order; each result is parsed and its bindings and\n * identity checked; the optical bridge forms each irradiance with its own code; the taps, nodes and instants are assembled as\n * the full executor does; and `createSensorEqeTemporalPhotoSignal` forms the photo signal from the same input. So the photo\n * signal is the full executor's, value for value.\n *\n * What it skips is only re-validation of records that cannot have changed since they passed it, and records nobody reads:\n * - the first query runs the full per-query steps (full result parse, `validateSceneRadianceEvaluationBindings`,\n * `calculateSceneRadianceToSensorIrradiance`); later queries skip the profile-to-profile binding checks and the optical\n * bridge's re-parse of its unchanged optical inputs, request and result, keeping every per-query check\n * (`validateSceneRadianceRequestResultBindings`, `prepareSceneRadianceToSensorIrradianceValue`), with the same messages;\n * - with `engineBuiltResults` (an evaluator marked by `markInternalSceneRadianceEvaluator`, or one returning such an\n * evaluator's results), later results reuse the first result's parsed uncertainty, evidence and limitations when they are\n * the same deep-frozen objects (`parseSceneRadianceEvaluationResultWithValidatedRecords`, as the lean executor does);\n * - no per-query optical result envelopes and no outer execution envelope are built.\n * Plans with ideal-pupil rays or a sampled PSF run the full executor.\n */\nexport function executeEngineOwnedEnvironmentPhotoSignal(plan: ReturnType<typeof planEnvironmentSensorPhotoSignal>, evaluate: EnvironmentRadianceEvaluator,\n engineBuiltResults: boolean): EnvironmentSensorPhotoSignal[\"photo\"] {\n const { owned } = plan;\n if (owned.pupil !== undefined || owned.psf.kind !== \"not-applied\") return executeEnvironmentSensorPhotoSignal(plan, evaluate, undefined, \"photo-only\").value.photo;\n if (typeof evaluate !== \"function\") throw new InvalidScientificInputError(\"Environment radiance evaluator must be synchronous callable code.\");\n const { providerProfile, illuminationProfile, materialResponseProfile } = plan.sceneBindings;\n let validated: ValidatedSceneRadianceRecords | undefined;\n let irradianceOf: ReturnType<typeof prepareSceneRadianceToSensorIrradianceValue> | undefined;\n const irradiance = [];\n for (const instant of plan.instants) {\n const samples = instant.groups.map(group => ({ node: group.node, sourceSamples: group.taps.map(tap => {\n let integratedIrradiance = 0;\n const request = tap.request, value = evaluate(request);\n let sensorPlane: number;\n if (irradianceOf === undefined) {\n const result = parseSceneRadianceEvaluationResult(value);\n validateSceneRadianceEvaluationBindings({ ...plan.sceneBindings, request, result });\n sensorPlane = calculateSceneRadianceToSensorIrradiance({ ...owned.optics, sceneRadianceRequest: request,\n sceneRadianceResult: result, imagePointMm: tap.sourcePointImagePlaneMm, fieldThroughput: tap.fieldThroughput }).value.sensorPlaneSpectralIrradianceWattsPerSquareMeterNanometer;\n const record = value as unknown as Record<string, unknown>;\n if (engineBuiltResults && isDeeplyFrozen(record.uncertainty) && isDeeplyFrozen(record.evidence) && isDeeplyFrozen(record.limitations)) {\n validated = { uncertainty: record.uncertainty, evidence: record.evidence, limitations: record.limitations, parsed: result };\n }\n irradianceOf = prepareSceneRadianceToSensorIrradianceValue(owned.optics);\n } else {\n const result = validated ? parseSceneRadianceEvaluationResultWithValidatedRecords(value, validated) : parseSceneRadianceEvaluationResult(value);\n validateSceneRadianceRequestResultBindings(providerProfile, illuminationProfile, materialResponseProfile, request, result);\n sensorPlane = irradianceOf(request, result, tap.sourcePointImagePlaneMm, tap.fieldThroughput);\n }\n // The full executor's sum over the tap's support (one direction, weight 1 without pupil rays).\n integratedIrradiance += sensorPlane*1;\n if (tap.distortionAreaFactor !== undefined) integratedIrradiance *= tap.distortionAreaFactor;\n return { kernelSampleX: tap.kernelSampleX, kernelSampleY: tap.kernelSampleY, sourcePointNativeSensorMm: tap.point,\n timeSecondsFromOpeningReference: instant.time, spectralIrradianceWattsPerSquareMeterPerNanometer: integratedIrradiance };\n }) }));\n irradiance.push({ temporalSampleIndex: instant.temporalSampleIndex, timeSecondsFromOpeningReference: instant.time,\n irradianceSamples: samples.map(s => ({ node: s.node,\n spectralIrradianceWattsPerSquareMeterPerNanometer: s.sourceSamples[0]!.spectralIrradianceWattsPerSquareMeterPerNanometer })) });\n }\n return createSensorEqeTemporalPhotoSignal({ temporalIntegrationId: owned.temporalIntegrationId,\n exposure: { ...owned.sensor, samples: irradiance } });\n}\n\n/** Plans, queries the provider and integrates the photo signal for one site, at the site's own midpoint sample positions. */\nexport function calculateEnvironmentSensorPhotoSignal(input: CalculateEnvironmentSensorPhotoSignalInput): CalculationResult<EnvironmentSensorPhotoSignal> {\n requireInputKeys(input, \"calculateEnvironmentSensorPhotoSignal\", [\"temporalIntegrationId\", \"sensor\", \"sceneBindings\", \"optics\", \"motion\", \"temporalSampleCount\", \"pupil\", \"lensFieldMapping\", \"fieldThroughput\", \"psf\", \"evaluateRadiance\", \"evaluateApertureRadiance\"]);\n const { evaluateRadiance, evaluateApertureRadiance, ...data } = input;\n return executeEnvironmentSensorPhotoSignal(planEnvironmentSensorPhotoSignal(data), evaluateRadiance, evaluateApertureRadiance);\n}\n"]}
|
package/docs/API_REFERENCE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Public API reference
|
|
2
2
|
|
|
3
|
-
Generated from the exact root exports for **@photivra/engine 2.
|
|
3
|
+
Generated from the exact root exports for **@photivra/engine 2.11.1 / root contract 2.11.1** by `node scripts/generate-api-reference.mjs`. No module deep import is supported.
|
|
4
4
|
|
|
5
5
|
Use [the developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md) for executable paths and scientific boundaries. Types are contracts, not runtime validation: parse untrusted data, preserve units/reference frames, read assessment blockers, and retain evidence/limitations. Optional properties do not imply a universal default. Model/schema IDs remain independent of the distribution.
|
|
6
6
|
|
|
@@ -1102,6 +1102,24 @@ Start here to find a function by task. [Using Photivra from an agent](AGENT_GUID
|
|
|
1102
1102
|
| [`ExposureProgramLineProfile`](api/exposure-program-line.md#exposureprogramlineprofile) | Type |
|
|
1103
1103
|
| [`parseExposureProgramLineProfile`](api/exposure-program-line.md#parseexposureprogramlineprofile) | Runtime |
|
|
1104
1104
|
|
|
1105
|
+
## facade/chart-material-layers.ts
|
|
1106
|
+
|
|
1107
|
+
[Detailed contracts](api/facade-chart-material-layers.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/facade/chart-material-layers.ts)
|
|
1108
|
+
|
|
1109
|
+
| Export | Kind |
|
|
1110
|
+
| --- | --- |
|
|
1111
|
+
| [`CHART_MASK_INDEX_GRAIN`](api/facade-chart-material-layers.md#chart_mask_index_grain) | Runtime |
|
|
1112
|
+
| [`CHART_MATERIAL_LAYER_LIMITS`](api/facade-chart-material-layers.md#chart_material_layer_limits) | Runtime |
|
|
1113
|
+
| [`ChartMaskAnnulus`](api/facade-chart-material-layers.md#chartmaskannulus) | Type |
|
|
1114
|
+
| [`ChartMaskLayer`](api/facade-chart-material-layers.md#chartmasklayer) | Type |
|
|
1115
|
+
| [`ChartMaskPolygon`](api/facade-chart-material-layers.md#chartmaskpolygon) | Type |
|
|
1116
|
+
| [`ChartMaskShape`](api/facade-chart-material-layers.md#chartmaskshape) | Type |
|
|
1117
|
+
| [`ChartMaterialLayerScene`](api/facade-chart-material-layers.md#chartmateriallayerscene) | Type |
|
|
1118
|
+
| [`resolveChartMaterialLayers`](api/facade-chart-material-layers.md#resolvechartmateriallayers) | Runtime |
|
|
1119
|
+
| [`ResolvedChartMaskLayer`](api/facade-chart-material-layers.md#resolvedchartmasklayer) | Type |
|
|
1120
|
+
| [`ResolvedChartMaskShape`](api/facade-chart-material-layers.md#resolvedchartmaskshape) | Type |
|
|
1121
|
+
| [`ResolvedChartMaterialLayers`](api/facade-chart-material-layers.md#resolvedchartmateriallayers) | Type |
|
|
1122
|
+
|
|
1105
1123
|
## facade/chart-radiance-batch.ts
|
|
1106
1124
|
|
|
1107
1125
|
[Detailed contracts](api/facade-chart-radiance-batch.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/facade/chart-radiance-batch.ts)
|
|
@@ -1157,6 +1175,30 @@ Start here to find a function by task. [Using Photivra from an agent](AGENT_GUID
|
|
|
1157
1175
|
| [`UniformChartScene`](api/facade-chart-scenes.md#uniformchartscene) | Type |
|
|
1158
1176
|
| [`ZonePlateChartScene`](api/facade-chart-scenes.md#zoneplatechartscene) | Type |
|
|
1159
1177
|
|
|
1178
|
+
## facade/display-view-gpu.ts
|
|
1179
|
+
|
|
1180
|
+
[Detailed contracts](api/facade-display-view-gpu.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/facade/display-view-gpu.ts)
|
|
1181
|
+
|
|
1182
|
+
| Export | Kind |
|
|
1183
|
+
| --- | --- |
|
|
1184
|
+
| [`DisplayViewExecution`](api/facade-display-view-gpu.md#displayviewexecution) | Type |
|
|
1185
|
+
| [`DisplayViewFastReport`](api/facade-display-view-gpu.md#displayviewfastreport) | Type |
|
|
1186
|
+
| [`DisplayViewGpuConformance`](api/facade-display-view-gpu.md#displayviewgpuconformance) | Type |
|
|
1187
|
+
| [`DisplayViewGpuFallbackReason`](api/facade-display-view-gpu.md#displayviewgpufallbackreason) | Type |
|
|
1188
|
+
| [`DisplayViewGpuMode`](api/facade-display-view-gpu.md#displayviewgpumode) | Type |
|
|
1189
|
+
| [`PrepareDisplayViewOptions`](api/facade-display-view-gpu.md#preparedisplayviewoptions) | Type |
|
|
1190
|
+
|
|
1191
|
+
## facade/display-view.ts
|
|
1192
|
+
|
|
1193
|
+
[Detailed contracts](api/facade-display-view.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/facade/display-view.ts)
|
|
1194
|
+
|
|
1195
|
+
| Export | Kind |
|
|
1196
|
+
| --- | --- |
|
|
1197
|
+
| [`bindDisplayViewCorrectionStates`](api/facade-display-view.md#binddisplayviewcorrectionstates) | Runtime |
|
|
1198
|
+
| [`DisplayViewCorrectionStateKeys`](api/facade-display-view.md#displayviewcorrectionstatekeys) | Type |
|
|
1199
|
+
| [`DisplayViewCorrectionStateSet`](api/facade-display-view.md#displayviewcorrectionstateset) | Type |
|
|
1200
|
+
| [`serializeDisplayViewCorrectionStates`](api/facade-display-view.md#serializedisplayviewcorrectionstates) | Runtime |
|
|
1201
|
+
|
|
1160
1202
|
## facade/scene-radiance.ts
|
|
1161
1203
|
|
|
1162
1204
|
[Detailed contracts](api/facade-scene-radiance.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/facade/scene-radiance.ts)
|
|
@@ -1191,6 +1233,7 @@ Start here to find a function by task. [Using Photivra from an agent](AGENT_GUID
|
|
|
1191
1233
|
| [`SIMULATE_CAPTURE_COST_OPTIONS`](api/facade-simulate-capture.md#simulate_capture_cost_options) | Runtime |
|
|
1192
1234
|
| [`SIMULATE_CAPTURE_DEFAULT_ILLUMINANCE_LUX`](api/facade-simulate-capture.md#simulate_capture_default_illuminance_lux) | Runtime |
|
|
1193
1235
|
| [`SIMULATE_CAPTURE_FACADE_VERSION`](api/facade-simulate-capture.md#simulate_capture_facade_version) | Runtime |
|
|
1236
|
+
| [`SIMULATE_CAPTURE_FAST_OPTIONS`](api/facade-simulate-capture.md#simulate_capture_fast_options) | Runtime |
|
|
1194
1237
|
| [`SIMULATE_DISPLAY_VIEW_DEFAULT_SAMPLES_PER_AXIS`](api/facade-simulate-capture.md#simulate_display_view_default_samples_per_axis) | Runtime |
|
|
1195
1238
|
| [`simulateCapture`](api/facade-simulate-capture.md#simulatecapture) | Runtime |
|
|
1196
1239
|
| [`SimulateCaptureAssumption`](api/facade-simulate-capture.md#simulatecaptureassumption) | Type |
|
|
@@ -1198,8 +1241,11 @@ Start here to find a function by task. [Using Photivra from an agent](AGENT_GUID
|
|
|
1198
1241
|
| [`SimulateCaptureColorEncoding`](api/facade-simulate-capture.md#simulatecapturecolorencoding) | Type |
|
|
1199
1242
|
| [`SimulateCaptureCostOption`](api/facade-simulate-capture.md#simulatecapturecostoption) | Type |
|
|
1200
1243
|
| [`SimulateCaptureDemosaic`](api/facade-simulate-capture.md#simulatecapturedemosaic) | Type |
|
|
1244
|
+
| [`SimulateCaptureDemosaicRecord`](api/facade-simulate-capture.md#simulatecapturedemosaicrecord) | Type |
|
|
1201
1245
|
| [`SimulateCaptureDngPart`](api/facade-simulate-capture.md#simulatecapturedngpart) | Type |
|
|
1202
1246
|
| [`SimulateCaptureExposureMode`](api/facade-simulate-capture.md#simulatecaptureexposuremode) | Type |
|
|
1247
|
+
| [`SimulateCaptureFastOption`](api/facade-simulate-capture.md#simulatecapturefastoption) | Type |
|
|
1248
|
+
| [`SimulateCaptureFastReport`](api/facade-simulate-capture.md#simulatecapturefastreport) | Type |
|
|
1203
1249
|
| [`SimulateCaptureLensDistortion`](api/facade-simulate-capture.md#simulatecapturelensdistortion) | Type |
|
|
1204
1250
|
| [`SimulateCaptureMotion`](api/facade-simulate-capture.md#simulatecapturemotion) | Type |
|
|
1205
1251
|
| [`SimulateCaptureOptions`](api/facade-simulate-capture.md#simulatecaptureoptions) | Type |
|
|
@@ -1261,7 +1307,11 @@ Start here to find a function by task. [Using Photivra from an agent](AGENT_GUID
|
|
|
1261
1307
|
|
|
1262
1308
|
| Export | Kind |
|
|
1263
1309
|
| --- | --- |
|
|
1310
|
+
| [`ChartCompositeProbeComponent`](api/gpu-image-kernel-execution.md#chartcompositeprobecomponent) | Type |
|
|
1311
|
+
| [`ChartCompositeProbeMismatch`](api/gpu-image-kernel-execution.md#chartcompositeprobemismatch) | Type |
|
|
1312
|
+
| [`ChartCompositeProbeRecord`](api/gpu-image-kernel-execution.md#chartcompositeproberecord) | Type |
|
|
1264
1313
|
| [`composeRelativeErrorBounds`](api/gpu-image-kernel-execution.md#composerelativeerrorbounds) | Runtime |
|
|
1314
|
+
| [`ImageKernelAdapterDescription`](api/gpu-image-kernel-execution.md#imagekerneladapterdescription) | Type |
|
|
1265
1315
|
| [`ImageKernelBackend`](api/gpu-image-kernel-execution.md#imagekernelbackend) | Type |
|
|
1266
1316
|
| [`ImageKernelCodeErrorBound`](api/gpu-image-kernel-execution.md#imagekernelcodeerrorbound) | Type |
|
|
1267
1317
|
| [`ImageKernelExecution`](api/gpu-image-kernel-execution.md#imagekernelexecution) | Type |
|
|
@@ -1273,6 +1323,15 @@ Start here to find a function by task. [Using Photivra from an agent](AGENT_GUID
|
|
|
1273
1323
|
| [`WEBGPU_F32_TRANSFER_ABSOLUTE_BOUND`](api/gpu-image-kernel-execution.md#webgpu_f32_transfer_absolute_bound) | Runtime |
|
|
1274
1324
|
| [`WEBGPU_F32_UNIT_ROUNDOFF`](api/gpu-image-kernel-execution.md#webgpu_f32_unit_roundoff) | Runtime |
|
|
1275
1325
|
|
|
1326
|
+
## gpu/webgpu-switch.ts
|
|
1327
|
+
|
|
1328
|
+
[Detailed contracts](api/gpu-webgpu-switch.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/gpu/webgpu-switch.ts)
|
|
1329
|
+
|
|
1330
|
+
| Export | Kind |
|
|
1331
|
+
| --- | --- |
|
|
1332
|
+
| [`getWebGpuEnabled`](api/gpu-webgpu-switch.md#getwebgpuenabled) | Runtime |
|
|
1333
|
+
| [`setWebGpuEnabled`](api/gpu-webgpu-switch.md#setwebgpuenabled) | Runtime |
|
|
1334
|
+
|
|
1276
1335
|
## motion/camera-rotation.ts
|
|
1277
1336
|
|
|
1278
1337
|
[Detailed contracts](api/motion-camera-rotation.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/motion/camera-rotation.ts)
|
package/docs/QUICK_START.md
CHANGED
|
@@ -72,7 +72,8 @@ modelling choices (such as "no lens PSF") as `kind: "model"`.
|
|
|
72
72
|
| `lens.distortion` | none | `{ kind: "radial", profile }` or `{ kind: "brown-conrady", profile }`. |
|
|
73
73
|
| `lens.vignetting` | none | An `IlluminationVignettingProfile` (radial relative illumination). |
|
|
74
74
|
| `lens.psf` | none | A `{ kind: "sampled-local", configuration }` sampled lens PSF, passed to the environment contract unchanged. |
|
|
75
|
-
| `lens.
|
|
75
|
+
| `lens.defocus` | off | `{ model: "geometric-disc" }`: defocus of the scene plane as the geometric blur disc (see [Optics](#optics)). `simulateCapture` and `simulateDisplayView` render it. |
|
|
76
|
+
| `lens.diffraction` | off | 2.1: `"circular-aperture"` or `{ kind: "circular-aperture", kernelRadiusSamples, fast }`: diffraction blur of an ideal lens at the resolved f-number (see [Optics](#optics)). `aperture` is accepted as a deprecated alias of `kind` until 3.0.0. |
|
|
76
77
|
| `exposure.mode` | `"manual"` | Also `"aperture-priority"`, `"shutter-priority"`, `"program"`. |
|
|
77
78
|
| `exposure.iso` | 100 | Selects the body's ISO readout regime (gain and read noise). |
|
|
78
79
|
| `exposure.shutterSeconds` | 1/125 | Used in `manual` and `shutter-priority`. |
|
|
@@ -91,7 +92,7 @@ modelling choices (such as "no lens PSF") as `kind: "model"`.
|
|
|
91
92
|
| `output.gamutMapping` | `"clip"` | PNG only: or `"perceptual"`. |
|
|
92
93
|
| `output.dng.capturedAtUtc` | none | DNG only: capture time for the date tags. |
|
|
93
94
|
| `output.metadata` | none | 2.4: `{ description?, software?, copyright?, comment? }` written into JPEG, PNG and DNG files unchanged (see [Text metadata](#text-metadata-24)). |
|
|
94
|
-
| `output.demosaic` | the 1.0 bilinear kernels | `"bilinear"` or, from 2.1, `"ahd"` (see [Demosaic](#demosaic))
|
|
95
|
+
| `output.demosaic` | the 1.0 bilinear kernels | `"bilinear"` or, from 2.1, `"ahd"` (see [Demosaic](#demosaic)); or the record `{ kind, fast }`. |
|
|
95
96
|
| `output.borderHandling` | `"margin"` | Or `"mirror"`. |
|
|
96
97
|
| `output.toneCurve` | `"identity"` | Any `SdrToneCurve`, for example `"positive-reinhard-per-channel"`. |
|
|
97
98
|
| `output.toneCurveParameters` | none | Required by the luminance curves (`extended-reinhard-luminance`, `naka-rushton-luminance`); the facade invents no curve parameters. |
|
|
@@ -102,8 +103,9 @@ modelling choices (such as "no lens PSF") as `kind: "model"`.
|
|
|
102
103
|
| `sensor.spectralStepNanometers` | 20 | Spectral quadrature over 380–780 nm. |
|
|
103
104
|
| `sensor.temporalSampleCount` | 1, or 8 when the camera rotates | Midpoints across each site's exposure window. |
|
|
104
105
|
| `sensor.noiseSeed` | 1 | Output is deterministic for a given seed. |
|
|
105
|
-
| `sensor.antiAliasing` | off | 2.1: an optical low-pass (anti-aliasing) filter: `{ kind: "four-spot", separationSites? }`, `{ kind: "two-spot", axis, separationSites? }` or `{ kind: "point-splitting", components }` (see [Anti-aliasing filter](#anti-aliasing-filter)). |
|
|
106
|
-
| `sensor.pixelAperture` | `"point"` | 2.3: `"box"` or `{ kind: "box", samplesPerAxis }` integrates each square photosite (see [Pixel aperture](#pixel-aperture-23)). |
|
|
106
|
+
| `sensor.antiAliasing` | off | 2.1: an optical low-pass (anti-aliasing) filter: `{ kind: "four-spot", separationSites? }`, `{ kind: "two-spot", axis, separationSites? }` or `{ kind: "point-splitting", components }` (see [Anti-aliasing filter](#anti-aliasing-filter)). Each record also takes `fast`. |
|
|
107
|
+
| `sensor.pixelAperture` | `"point"` | 2.3: `"box"` or `{ kind: "box", samplesPerAxis, fast }` integrates each square photosite (see [Pixel aperture](#pixel-aperture-23)). |
|
|
108
|
+
| `fast` | `false` | Exact or fast for every option in `SIMULATE_CAPTURE_FAST_OPTIONS`; an option's record `fast` overrides it. No option has a fast method yet, so results are exact; `diagnostics.fast` reports what was requested and what ran (see [Exact and fast modes](https://github.com/Photivra/photivra/blob/main/docs/API_STYLE.md#exact-and-fast-modes)). |
|
|
107
109
|
| `motion.angularVelocityRadPerSec` | still | `{ pitch?, yaw?, roll? }` in rad/s (see [Motion](#motion)). |
|
|
108
110
|
| `motion.shutter` | `"global"` | Or `"rolling"`. |
|
|
109
111
|
| `motion.rollingShutterSkewSeconds` | the body's readout skew | Rolling only. |
|
|
@@ -477,6 +479,11 @@ const view = await simulateDisplayView({
|
|
|
477
479
|
console.log(view.diagnostics.sceneLookups);
|
|
478
480
|
```
|
|
479
481
|
|
|
482
|
+
The same scene can be declared as data instead of a function: `{ kind: "material-layers", sceneId, chart, layers }`, an
|
|
483
|
+
engine chart under shape-mask layers (polygons and annuli in the mask's own units; `resolveChartMaterialLayers`). Every
|
|
484
|
+
CPU result is that of its `callerScene`, byte for byte, and `prepareDisplayView(request, { gpu: "auto" })` can render it
|
|
485
|
+
on the GPU, which a caller function cannot (docs/DISPLAY_VIEW.md, "Rendering on the GPU").
|
|
486
|
+
|
|
480
487
|
The display view's expected values match the reflectance-function form to rounding, because they are the same
|
|
481
488
|
quantities summed in another order. Measured on the app's chart with a maker label (a 24 MP frame, the 2028 × 1352 view's
|
|
482
489
|
centre strip, one thread), the material form took 1.15 s instead of 3.2 s with the defaults, and 3.0 s instead of 111 s
|
|
@@ -755,6 +762,97 @@ The optics options feed only what the environment site contract accepts:
|
|
|
755
762
|
is sampled at its centre). It cannot be
|
|
756
763
|
combined with `lens.psf` or `lens.pupilSampling`.
|
|
757
764
|
|
|
765
|
+
- `lens.defocus: { model: "geometric-disc" }` (#492; the capture renders it, the display view does not yet) models defocus of the flat scene plane when
|
|
766
|
+
`lens.focusDistanceM` differs from `subjectDistanceM`.
|
|
767
|
+
- The model is a geometric approximation for an ideal uniform circular pupil. Each in-focus image point spreads
|
|
768
|
+
into a uniform disc of diameter c = f²·|s − d| / (N·d·(s − f)) on the sensor (`calculateDefocusCircle`, thin-lens
|
|
769
|
+
model 1.1.0), at the resolved f-number. There is no diffraction of the defocused wave, no aberrations and no
|
|
770
|
+
pupil vignetting. The disc is the same at every wavelength, so defocus of a plane is one convolution.
|
|
771
|
+
- The engine samples the disc on the site lattice. Each site's weight is the exact area of the disc inside that
|
|
772
|
+
site's square cell, a closed-form circle–rectangle area, divided by the disc's area.
|
|
773
|
+
- The weights are computed with the engine's portable arithmetic, so they are bit-identical in every
|
|
774
|
+
JavaScript engine.
|
|
775
|
+
- Their exact sum is 1, to the last bit of the centre weight.
|
|
776
|
+
- A disc smaller than one site gives the identity.
|
|
777
|
+
- A test blurs a sampled straight edge with the kernel and compares it with the disc's closed-form
|
|
778
|
+
edge-spread function, the circular-segment area. They agree to rounding (2e-13) when the edge lies on cell
|
|
779
|
+
boundaries. Elsewhere they agree within the site sampling of the edge.
|
|
780
|
+
- The kernel radius is capped at 64 sites, a 129 × 129 window (`DEFOCUS_DISC_KERNEL_MAXIMUM_RADIUS_SITES`). A larger
|
|
781
|
+
blur is refused with an error that names the cap and the radius needed; the disc is never clipped.
|
|
782
|
+
- **The capture renders it** (#492, step 2a). The scene radiance on the site lattice is convolved with the disc,
|
|
783
|
+
the same kernel at every spectral node, and each site query is answered with the result. This is the object-space
|
|
784
|
+
convolution that `lens.diffraction` uses.
|
|
785
|
+
- The capture keeps its tabulated fast path. Regions, strips and DNG parts stay byte-identical to the whole frame.
|
|
786
|
+
- The `lens.defocus` assumption records `execution: "object-space-convolution"`.
|
|
787
|
+
- `diagnostics.options` lists `lens.defocus`, and `diagnostics.timingsMs.defocus` times the provider's convolution.
|
|
788
|
+
- The site inputs declare no PSF, because the defocus is applied upstream.
|
|
789
|
+
- **With `lens.diffraction`**, each spectral node's diffraction kernel is convolved with the disc and applied as
|
|
790
|
+
one kernel. The combined radius is the diffraction radius plus the defocus radius, at most 32 + 64 = 96 sites.
|
|
791
|
+
- This is a further approximation, and the assumption says so. The defocused wave PSF of a circular pupil is not
|
|
792
|
+
exactly the in-focus Airy pattern convolved with the geometric disc. Where the two differ is measured in a
|
|
793
|
+
later step of #492.
|
|
794
|
+
- Building the combined kernels cost 0.5 ms per spectral node at diffraction radius 2 with defocus radius 41. It
|
|
795
|
+
cost 90 ms per node at 32 with 64, the largest pair (Node, one thread).
|
|
796
|
+
- **The display view renders it** (#492, step 2b) with the same per-node kernels: its expected-signal tables read
|
|
797
|
+
the scene on the site lattice through the disc (with `lens.diffraction`, through each node's diffraction kernel
|
|
798
|
+
convolved with the disc), so the view's estimators run unchanged on the blurred signal. The `view.defocus`
|
|
799
|
+
assumption records the kernel and its radii. The GPU display-view renderer does not take the kernel yet:
|
|
800
|
+
`gpu: "auto"` renders such a view on the CPU, labelled `unsupported-on-backend`. Validation and cost per radius:
|
|
801
|
+
[Display view, Defocus](https://github.com/Photivra/photivra/blob/main/docs/DISPLAY_VIEW.md#defocus).
|
|
802
|
+
- In focus (c = 0) no kernel is applied, and the image is byte-identical to the same request without the option.
|
|
803
|
+
`simulateIdealReference`, which has no camera effects, only records the disc.
|
|
804
|
+
- **Refused out of focus** with camera rotation, `lens.projection` or `lens.distortion`, and `lens.vignetting`. Each
|
|
805
|
+
of these moves the scene points that a site sees off the site lattice, so the convolution does not apply. In
|
|
806
|
+
focus they render as without `lens.defocus`.
|
|
807
|
+
- **Sampling.** The scene enters at the lattice points the sites query: site centres, or the pixel-aperture nodes
|
|
808
|
+
and anti-aliasing spots. So near an edge the result can differ from the continuous disc integral by the lattice's
|
|
809
|
+
point sampling of the edge. Measured on a 16 × 12 slanted edge, as the relative difference in expected electrons
|
|
810
|
+
per site (max / RMS):
|
|
811
|
+
|
|
812
|
+
| Disc | Pixel aperture | Convolution vs continuous integral | 4 × 8 rays | 8 × 16 rays | 16 × 16 rays |
|
|
813
|
+
| --- | --- | --- | --- | --- | --- |
|
|
814
|
+
| 5.95 sites (R 3) | point | 0.112 / 0.026 | 0.089 / 0.021 | 0.023 / 0.0049 | 0.018 / 0.0035 |
|
|
815
|
+
| 5.95 sites (R 3) | 4 × 4 box | 0.035 / 0.0065 | 0.048 / 0.010 | 0.0067 / 0.0014 | 0.0044 / 0.0007 |
|
|
816
|
+
| 13.4 sites (R 7) | point | 0.030 / 0.0056 | 0.094 / 0.032 | 0.029 / 0.0077 | 0.023 / 0.0053 |
|
|
817
|
+
| 13.4 sites (R 7) | 4 × 4 box | 0.0051 / 0.0013 | 0.070 / 0.026 | 0.012 / 0.0034 | 0.0090 / 0.0021 |
|
|
818
|
+
|
|
819
|
+
The ray columns are `lens.pupilSampling` (the independent reference, without diffraction) against the same
|
|
820
|
+
continuous integral. They converge toward it as the rays increase. Against the convolution, the 13.4-site disc
|
|
821
|
+
with the box aperture gives 0.070, 0.012 and 0.0093 (max). In the test (the 5.95-site disc, point aperture), the rays
|
|
822
|
+
and the convolution agree to 1e-9 at every site more than one site beyond the disc's reach of the edge.
|
|
823
|
+
- **Validation** (`test/simulate-capture-defocus-render.test.ts`):
|
|
824
|
+
- A vertical edge halfway between two lattice columns gives the exact circular-segment fraction at every site,
|
|
825
|
+
to 1e-12.
|
|
826
|
+
- A 48 × 480 slanted-edge capture's averaged edge profile is compared with the disc's closed-form edge-spread
|
|
827
|
+
function. It uses RAW codes, green sites and quarter-site bins. The largest difference was 0.0093 of the
|
|
828
|
+
step (noise seed 1).
|
|
829
|
+
- The tabulated and environment paths give the same RAW.
|
|
830
|
+
- Regions and DNG parts equal the whole frame: chart, Quality options with diffraction, a `material-layers`
|
|
831
|
+
scene and a caller function.
|
|
832
|
+
- **Cost and the 64-site cap.** Direct convolution costs (2R + 1)² multiply-adds per site and node wherever the disc
|
|
833
|
+
sees more than one material. Uniform areas cost almost nothing on the tabulated path. Measured on the tabulated
|
|
834
|
+
capture path (Node 24, one thread, rounds interleaved over the radii, median [range] of 3 rounds; 2 at 2048 × 1366;
|
|
835
|
+
a shared 4-vCPU host):
|
|
836
|
+
|
|
837
|
+
| Scene, size | in focus | R 2 | R 8 | R 16 | R 32 | R 41 | R 64 |
|
|
838
|
+
| --- | --- | --- | --- | --- | --- | --- | --- |
|
|
839
|
+
| Siemens star, 1024 × 683 | 0.37 s | 0.37 s | 0.51 s | 0.98 s | 2.9 s | 4.7 s | 11.6 s [11.4–11.8] |
|
|
840
|
+
| Dead leaves, 1024 × 683 | 0.37 s | 0.38 s | 0.66 s | 1.6 s | 5.0 s | 7.9 s | 17.7 s [17.6–18.0] |
|
|
841
|
+
| Slanted edge, 1024 × 683 | 0.32 s | 0.33 s | 0.35 s | 0.40 s | 0.70 s | 1.05 s | 2.7 s |
|
|
842
|
+
| Siemens star, 1024 × 683, Quality (diffraction, four-spot, 2 × 2 box, AHD) | 0.81 s | 0.87 s | 1.7 s | 4.1 s | 12.5 s | 20.0 s | 52.9 s [52.0–53.2] |
|
|
843
|
+
| Siemens star, 2048 × 1366 | 1.39 s | | 1.8 s | | 10.4 s | | 38.3 s [37.5–38.3] |
|
|
844
|
+
|
|
845
|
+
- The cap stays at 64 sites, set from these numbers. It covers the 1.4 µm example of #492 (50 mm f/2.8, subject
|
|
846
|
+
2 m, focus 1.6 m: R = 41) with room for larger blurs.
|
|
847
|
+
- The time grows with R² per edge site, and the caller chooses it through the focus distance. Past the cap the
|
|
848
|
+
request fails and names the radius it needed.
|
|
849
|
+
- A 24 MP frame costs proportionally more. Render it in parts across workers, as for diffraction.
|
|
850
|
+
- Off the tabulated path (caller reflectance or radiance functions), the provider gathers only each 32-row band's
|
|
851
|
+
own values, not the 2R extra rows `calculateIrradianceConvolution` would return (#419). On a 256 × 171
|
|
852
|
+
function scene the convolution took 0.3 s at R 8, 3.5 s at R 32 and 12.9 s at R 64.
|
|
853
|
+
- It cannot be combined with `lens.pupilSampling` (the rays already render defocus) or `lens.psf` (a caller PSF
|
|
854
|
+
declares its own defocus). It can be combined with `lens.diffraction`.
|
|
855
|
+
|
|
758
856
|
### Pixel aperture (2.3)
|
|
759
857
|
|
|
760
858
|
By default each site samples the irradiance at its centre (`sensor.pixelAperture: "point"`). Scene
|
|
@@ -1293,9 +1391,14 @@ Validated against real full-resolution captures resized in linear light: three s
|
|
|
1293
1391
|
100 MP medium format), five charts, f/2.8–f/16, ISO 100–6400, 96–800 display pixels wide, Speed and Quality options (see
|
|
1294
1392
|
[Validation results](https://github.com/Photivra/photivra/blob/main/docs/DISPLAY_VIEW.md#validation-results)).
|
|
1295
1393
|
|
|
1296
|
-
**Cost.**
|
|
1297
|
-
|
|
1298
|
-
|
|
1394
|
+
**Cost.** Where a display pixel covers more than 25 real pixels, the cost follows the detailed display pixels ×
|
|
1395
|
+
`samplesPerAxis`², not the real pixel count; at 25 or fewer (the exact area mean) it follows the real pixels the region
|
|
1396
|
+
touches. A device-pixel view of a 24 MP frame, 2028 × 1352 in 96 × 96 parts from one prepared view, takes about 0.09 s
|
|
1397
|
+
per part with the engine defaults and about 0.18 s with the Quality options (2.9.0, Node 24.21.0, one thread on a
|
|
1398
|
+
4-vCPU 2.80 GHz Xeon; [the table](https://github.com/Photivra/photivra/blob/main/docs/DISPLAY_VIEW.md#a-device-pixel-view-rendered-in-parts),
|
|
1399
|
+
`node scripts/benchmark-display-view.mjs --app`). The table below is the 2.6.0 record of whole views against the
|
|
1400
|
+
whole-frame view of the same request (Siemens star, f/8, ISO 100, one run, same host; every row, and the times before
|
|
1401
|
+
the exact speed-ups, in [DISPLAY_VIEW.md](https://github.com/Photivra/photivra/blob/main/docs/DISPLAY_VIEW.md#cost)):
|
|
1299
1402
|
|
|
1300
1403
|
| Sensor | Options | 96 wide | 384 wide | 800 wide |
|
|
1301
1404
|
| --- | --- | --- | --- | --- |
|
|
@@ -1321,7 +1424,11 @@ view allocates nothing at full resolution).
|
|
|
1321
1424
|
|
|
1322
1425
|
**Many regions of one view (2.7).** Each `simulateDisplayView` call repeats the request's setup: the camera, lens,
|
|
1323
1426
|
scene and illuminant, the channel responses, the diffraction kernels and the colour tables. That is about 0.25 s with
|
|
1324
|
-
the engine defaults and 0.7 s with the Quality options on a 24 MP request
|
|
1427
|
+
the engine defaults and 0.7 s with the Quality options on a 24 MP request (measured before #443). The channel responses
|
|
1428
|
+
do not depend on the scene and are kept across calls, so a call after a chart, illuminant or illuminance change costs
|
|
1429
|
+
less than one after an aperture or shutter change: with the Quality options, about 30–50 ms after a chart, illuminant or
|
|
1430
|
+
illuminance change and about 55–70 ms after an aperture or shutter change, against about 0.4 s for each before #443
|
|
1431
|
+
(Node 24.21.0, one thread, prepares in one process after a warm-up). To render one view in many regions, prepare
|
|
1325
1432
|
the request once and render each region from it; each region then costs only its own pixels:
|
|
1326
1433
|
|
|
1327
1434
|
```ts
|
|
@@ -1335,14 +1442,16 @@ console.log(tile.image.width, tile.diagnostics.timingsMs.view);
|
|
|
1335
1442
|
```
|
|
1336
1443
|
|
|
1337
1444
|
`render(view)` returns what `simulateDisplayView(request, view)` returns, byte for byte (only `diagnostics.timingsMs`
|
|
1338
|
-
differ, and they cover the render only).
|
|
1445
|
+
differ, and they cover the render only). A second argument `{ gpu: "auto" | "require", gpuDevice }` (2.11, #481) asks for
|
|
1446
|
+
the WebGPU renderer, with the CPU reference as the labelled fallback or as a failure; `diagnostics.fast.execution` names
|
|
1447
|
+
what ran (see [Rendering on the GPU](https://github.com/Photivra/photivra/blob/main/docs/DISPLAY_VIEW.md#rendering-on-the-gpu)). Renders may run concurrently and share only read-only setup. The request's own
|
|
1339
1448
|
`signal` applies to preparing; give each render its own. Keep one prepared view per request in each worker: measured on
|
|
1340
1449
|
a 24 MP request, an 8 × 8 region took 6–40 ms through a prepared view instead of 0.24–0.41 s as its own call (Speed).
|
|
1341
1450
|
|
|
1342
1451
|
**Not supported** (refused with an `InvalidConfigurationError`): `lens.pupilSampling`, `lens.projection`,
|
|
1343
1452
|
`lens.distortion`, `lens.vignetting`, `lens.psf`, camera rotation, `output.whiteBalance: "auto"`, the luminance tone
|
|
1344
|
-
curves, `output.highlightMode: "reconstruct"` and `output.region` (use `view.region`). `
|
|
1345
|
-
`signal` cancels.
|
|
1453
|
+
curves, `output.highlightMode: "reconstruct"` and `output.region` (use `view.region`). `lens.defocus` is rendered as a
|
|
1454
|
+
site kernel in the expected signal (#492; see [Optics](#optics)). `onProgress` is not called; `signal` cancels.
|
|
1346
1455
|
|
|
1347
1456
|
The result is labelled `kind: "display-view"` with a `label` for the user interface; it has no RAW, plan or file, and
|
|
1348
1457
|
the `view.*` assumptions state the definition, the estimator, the noise model, the demosaic treatment and which capture
|