@photivra/engine 2.5.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +129 -1
- package/CITATION.cff +1 -1
- package/README.md +6 -6
- package/SECURITY.md +1 -1
- package/THIRD_PARTY.md +1 -0
- package/dist/capture/native-environment-lean.d.ts +1 -1
- package/dist/capture/native-environment-lean.js +17 -3
- package/dist/capture/native-environment-lean.js.map +1 -1
- package/dist/capture/native-environment-raw.d.ts +0 -4
- package/dist/capture/native-environment-raw.js +6 -2
- package/dist/capture/native-environment-raw.js.map +1 -1
- package/dist/color/illuminants.d.ts +15 -0
- package/dist/color/illuminants.js +81 -24
- package/dist/color/illuminants.js.map +1 -1
- package/dist/color/srgb-transfer.d.ts +6 -0
- package/dist/color/srgb-transfer.js +9 -0
- package/dist/color/srgb-transfer.js.map +1 -1
- package/dist/color/white-balance.d.ts +6 -0
- package/dist/color/white-balance.js +15 -2
- package/dist/color/white-balance.js.map +1 -1
- package/dist/core/internal-radiance-evaluator.d.ts +6 -0
- package/dist/core/internal-radiance-evaluator.js +33 -0
- package/dist/core/internal-radiance-evaluator.js.map +1 -0
- package/dist/core/portable-math.d.ts +33 -0
- package/dist/core/portable-math.js +342 -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/chart-radiance-batch.js +3 -2
- package/dist/facade/chart-radiance-batch.js.map +1 -1
- package/dist/facade/chart-scenes.d.ts +11 -0
- package/dist/facade/chart-scenes.js +21 -7
- package/dist/facade/chart-scenes.js.map +1 -1
- package/dist/facade/diffraction-provider.d.ts +10 -0
- package/dist/facade/diffraction-provider.js +38 -17
- package/dist/facade/diffraction-provider.js.map +1 -1
- package/dist/facade/display-view.d.ts +213 -0
- package/dist/facade/display-view.js +1543 -0
- package/dist/facade/display-view.js.map +1 -0
- package/dist/facade/scene-radiance.d.ts +45 -5
- package/dist/facade/scene-radiance.js +97 -28
- package/dist/facade/scene-radiance.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +233 -5
- package/dist/facade/simulate-capture.js +120 -37
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/facade/simulate-display-view.d.ts +45 -0
- package/dist/facade/simulate-display-view.js +214 -0
- package/dist/facade/simulate-display-view.js.map +1 -0
- package/dist/facade/subject-framing.d.ts +16 -0
- package/dist/facade/subject-framing.js +8 -2
- package/dist/facade/subject-framing.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/optics/diffraction-psf-profile.d.ts +9 -2
- package/dist/optics/diffraction-psf-profile.js +33 -4
- package/dist/optics/diffraction-psf-profile.js.map +1 -1
- package/dist/optics/irradiance-convolution.js +1 -1
- package/dist/optics/irradiance-convolution.js.map +1 -1
- package/dist/optics/scene-to-sensor-irradiance.d.ts +7 -0
- package/dist/optics/scene-to-sensor-irradiance.js +10 -5
- package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
- package/dist/output/print-plan.d.ts +8 -1
- package/dist/output/print-plan.js +8 -1
- package/dist/output/print-plan.js.map +1 -1
- package/dist/schema/scene-radiance.d.ts +16 -0
- package/dist/schema/scene-radiance.js +25 -4
- package/dist/schema/scene-radiance.js.map +1 -1
- package/dist/sensor/raw-readout.d.ts +12 -0
- package/dist/sensor/raw-readout.js +131 -9
- package/dist/sensor/raw-readout.js.map +1 -1
- package/dist/sensor/stochastic-seed.d.ts +13 -0
- package/dist/sensor/stochastic-seed.js +42 -8
- package/dist/sensor/stochastic-seed.js.map +1 -1
- package/docs/AGENT_GUIDE.md +1 -0
- package/docs/API_REFERENCE.md +19 -1
- package/docs/QUICK_START.md +203 -4
- package/docs/USAGE.md +15 -0
- package/docs/api/core-version.md +1 -1
- package/docs/api/exports.json +52 -2
- package/docs/api/facade-scene-radiance.md +34 -1
- package/docs/api/facade-simulate-capture.md +66 -2
- package/docs/api/facade-simulate-display-view.md +57 -0
- package/docs/api/facade-subject-framing.md +16 -0
- package/docs/api/output-print-plan.md +8 -1
- package/package.json +3 -2
|
@@ -450,7 +450,28 @@ export function parseSceneRadianceEvaluationRequest(value) {
|
|
|
450
450
|
* the provider's light-transport calculation is physically correct.
|
|
451
451
|
*/
|
|
452
452
|
export function parseSceneRadianceEvaluationResult(value) {
|
|
453
|
-
const record = requireRecord(value, "sceneRadianceEvaluationResult",
|
|
453
|
+
const record = requireRecord(value, "sceneRadianceEvaluationResult", SCENE_RADIANCE_EVALUATION_RESULT_KEYS);
|
|
454
|
+
return parseSceneRadianceEvaluationResultRecord(record, undefined);
|
|
455
|
+
}
|
|
456
|
+
const SCENE_RADIANCE_EVALUATION_RESULT_KEYS = ["schemaVersion", "quantity", "unit", "scientificStatus", "sampleId", "providerProfileId", "sceneId", "wavelengthNanometers", "wavelengthBasis", "spectralRadianceWattsPerSquareMeterSteradianNanometer", "uncertainty", "evidence", "limitations"];
|
|
457
|
+
/**
|
|
458
|
+
* Internal (2.6; not exported from the package): parses a result of an engine-built evaluator
|
|
459
|
+
* (`isInternalSceneRadianceEvaluator`). It runs every check of `parseSceneRadianceEvaluationResult` with the same
|
|
460
|
+
* helpers, order and messages (object shape, schema version, quantity, unit, status, the three identifiers, the
|
|
461
|
+
* wavelength, its basis and the radiance value) except two: the scan for unknown keys, and re-parsing uncertainty,
|
|
462
|
+
* evidence and limitations when they are the very (deep-frozen) objects of `validated`, an earlier result that
|
|
463
|
+
* passed the full parse. Any other result takes the full parse.
|
|
464
|
+
*/
|
|
465
|
+
export function parseSceneRadianceEvaluationResultWithValidatedRecords(value, validated) {
|
|
466
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
467
|
+
return parseSceneRadianceEvaluationResult(value);
|
|
468
|
+
const record = value;
|
|
469
|
+
if (record.uncertainty !== validated.uncertainty || record.evidence !== validated.evidence || record.limitations !== validated.limitations) {
|
|
470
|
+
return parseSceneRadianceEvaluationResult(value);
|
|
471
|
+
}
|
|
472
|
+
return parseSceneRadianceEvaluationResultRecord(record, validated.parsed);
|
|
473
|
+
}
|
|
474
|
+
function parseSceneRadianceEvaluationResultRecord(record, validated) {
|
|
454
475
|
if (record.schemaVersion !==
|
|
455
476
|
SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION) {
|
|
456
477
|
throw new InvalidConfigurationError('sceneRadianceEvaluationResult.schemaVersion must be "' +
|
|
@@ -479,9 +500,9 @@ export function parseSceneRadianceEvaluationResult(value) {
|
|
|
479
500
|
unit: "W/m^2/sr/nm",
|
|
480
501
|
spectralRadianceWattsPerSquareMeterSteradianNanometer: requireNonNegativeFinite(record.spectralRadianceWattsPerSquareMeterSteradianNanometer, "sceneRadianceEvaluationResult.spectralRadianceWattsPerSquareMeterSteradianNanometer"),
|
|
481
502
|
scientificStatus: "approximation",
|
|
482
|
-
uncertainty: parseUncertainty(record.uncertainty, "sceneRadianceEvaluationResult.uncertainty"),
|
|
483
|
-
evidence: parseEvidenceList(record.evidence, "sceneRadianceEvaluationResult.evidence"),
|
|
484
|
-
limitations: parseLimitations(record.limitations, "sceneRadianceEvaluationResult.limitations")
|
|
503
|
+
uncertainty: validated ? validated.uncertainty : parseUncertainty(record.uncertainty, "sceneRadianceEvaluationResult.uncertainty"),
|
|
504
|
+
evidence: validated ? validated.evidence : parseEvidenceList(record.evidence, "sceneRadianceEvaluationResult.evidence"),
|
|
505
|
+
limitations: validated ? validated.limitations : parseLimitations(record.limitations, "sceneRadianceEvaluationResult.limitations")
|
|
485
506
|
};
|
|
486
507
|
}
|
|
487
508
|
function requireEqual(actual, expected, message) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scene-radiance.js","sourceRoot":"","sources":["../../src/schema/scene-radiance.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Contracts for scene-radiance providers: the renderer or other code that reports how much\n * light leaves a scene point toward the camera.\n *\n * It covers material-response metadata, provider capability profiles, single evaluation\n * requests and results, and identity checks between them. The engine validates this data\n * but does not compute scene radiance itself.\n * @see docs/SCENE_RADIANCE_AND_ILLUMINATION.md for equations, coordinate/unit conventions, blockers\n * and support limits.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport {\n parseEvidenceList,\n type EvidenceProvenance\n} from \"../core/evidence-provenance.js\";\nimport {\n parseSpectralWavelengthBasis,\n parseSpectralWavelengthRangeNanometers,\n type SpectralWavelengthBasis,\n type SpectralWavelengthRangeNanometers\n} from \"../core/spectral.js\";\nimport type {\n SceneIlluminationProfile\n} from \"./illumination.js\";\nimport type {\n SceneIlluminationTemporalProfile\n} from \"./illumination-temporal.js\";\nimport type { Vector3 } from \"./scene.js\";\nimport { requireInputObject, requireInputArray, requireInputKeys, rejectUnknownFields, rejectUnknownVariantFields, UNCERTAINTY_VARIANT_FIELDS } from \"../core/record-validation.js\";\n\ntype UnknownRecord = Record<string, unknown>;\n\nexport const SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION =\n \"0.1.0\" as const;\nexport const SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION =\n \"0.1.0\" as const;\nexport const SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION =\n \"0.1.0\" as const;\n\nexport type SceneRadianceScientificStatus =\n | \"calibrated\"\n | \"approximation\";\n\nexport type SceneRadianceUncertainty =\n | {\n kind: \"relative\";\n fraction: number;\n basis: string;\n }\n | {\n kind: \"not-quantified\";\n limitation: string;\n };\n\nexport interface SceneRadianceDataArtifactReference {\n id: string;\n checksumSha256: string;\n}\n\nexport type SceneMaterialResponseRepresentation =\n | {\n kind: \"unresolved\";\n limitation: string;\n }\n | {\n kind: \"rgb-pbr-approximation\";\n colorSpace: \"linear-srgb\";\n baseColor: {\n red: number;\n green: number;\n blue: number;\n };\n metallic: number;\n roughness: number;\n limitation: string;\n }\n | {\n kind: \"spectral-wavelength-preserving-data\";\n dataArtifact:\n SceneRadianceDataArtifactReference;\n wavelengthBasis:\n SpectralWavelengthBasis;\n wavelengthRangeNanometers:\n SpectralWavelengthRangeNanometers;\n scatteringModel:\n \"provider-defined-wavelength-preserving\";\n scientificStatus:\n SceneRadianceScientificStatus;\n uncertainty:\n SceneRadianceUncertainty;\n wavelengthChangingBehaviorModeled: false;\n emissionModeled: false;\n };\n\nexport interface SceneMaterialResponseDefinition {\n materialResponseId: string;\n evidence: readonly EvidenceProvenance[];\n representation:\n SceneMaterialResponseRepresentation;\n}\n\nexport interface SceneMaterialResponseProfile {\n schemaVersion:\n typeof SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION;\n profileId: string;\n sceneId: string;\n evidence: readonly EvidenceProvenance[];\n materials:\n readonly SceneMaterialResponseDefinition[];\n fluorescenceModeled: false;\n volumetricMaterialTransportModeled: false;\n polarizationModeled: false;\n}\n\nexport type SceneMaterialResponseFidelity =\n | \"spectral-data\"\n | \"rgb-pbr-approximation\"\n | \"mixed\"\n | \"unresolved\";\n\nexport type SceneRadianceProviderSpectralFidelity =\n | \"wavelength-resolved\"\n | \"rgb-derived-approximation\";\n\nexport type SceneRadianceProviderVisibilityFidelity =\n | \"resolved\"\n | \"approximation\"\n | \"not-modeled\";\n\nexport type SceneRadianceProviderTransportFidelity =\n | \"resolved\"\n | \"approximation\"\n | \"not-modeled\";\n\nexport interface SceneRadianceProviderProfile {\n schemaVersion:\n typeof SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION;\n profileId: string;\n sceneId: string;\n illuminationProfileId: string;\n illuminationTemporalProfileId?: string;\n materialResponseProfileId: string;\n outputQuantity:\n \"outgoing-spectral-radiance\";\n outputUnit:\n \"W/m^2/sr/nm\";\n scientificStatus: \"approximation\";\n uncertainty: SceneRadianceUncertainty;\n fidelity: {\n spectral:\n SceneRadianceProviderSpectralFidelity;\n material:\n SceneMaterialResponseFidelity;\n visibility:\n SceneRadianceProviderVisibilityFidelity;\n directTransport:\n SceneRadianceProviderTransportFidelity;\n indirectTransport:\n SceneRadianceProviderTransportFidelity;\n };\n wavelengthChangingTransportModeled: false;\n volumetricTransportModeled: false;\n polarizationModeled: false;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport type SceneRadianceEvaluationTarget =\n | {\n kind: \"surface-point\";\n sceneObjectId: string;\n materialResponseId: string;\n positionM: Vector3;\n outgoingDirectionUnitVector: Vector3;\n }\n | {\n kind: \"environment-direction\";\n outgoingDirectionUnitVector: Vector3;\n };\n\nexport interface SceneRadianceEvaluationRequest {\n schemaVersion:\n typeof SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION;\n sampleId: string;\n providerProfileId: string;\n sceneId: string;\n illuminationProfileId: string;\n materialResponseProfileId: string;\n target: SceneRadianceEvaluationTarget;\n timeSecondsFromExposureStart: number;\n wavelengthNanometers: number;\n wavelengthBasis:\n Exclude<SpectralWavelengthBasis, \"unspecified\">;\n}\n\nexport interface SceneRadianceEvaluationResult {\n schemaVersion:\n typeof SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION;\n sampleId: string;\n providerProfileId: string;\n sceneId: string;\n wavelengthNanometers: number;\n wavelengthBasis:\n Exclude<SpectralWavelengthBasis, \"unspecified\">;\n quantity:\n \"outgoing-spectral-radiance\";\n unit: \"W/m^2/sr/nm\";\n spectralRadianceWattsPerSquareMeterSteradianNanometer:\n number;\n scientificStatus: \"approximation\";\n uncertainty: SceneRadianceUncertainty;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface ValidateSceneRadianceEvaluationBindingsInput {\n providerProfile: SceneRadianceProviderProfile;\n illuminationProfile: SceneIlluminationProfile;\n illuminationTemporalProfile?:\n SceneIlluminationTemporalProfile;\n materialResponseProfile:\n SceneMaterialResponseProfile;\n request: SceneRadianceEvaluationRequest;\n result: SceneRadianceEvaluationResult;\n}\n\nexport interface SceneRadianceEvaluationBindingAssessment {\n providerBindingsMatched: true;\n requestResultIdentityMatched: true;\n materialResponseFidelity:\n SceneMaterialResponseFidelity;\n temporalIlluminationProfileBound:\n boolean;\n calibratedRadianceClaimAuthorized: false;\n sensorPlaneIrradianceCalculated: false;\n opticsApplied: false;\n photonsCalculated: false;\n}\n\nfunction requireRecord(\n value: unknown,\n path: string,\n allowedKeys: readonly string[] | null\n): UnknownRecord {\n if (\n typeof value !== \"object\" ||\n value === null ||\n Array.isArray(value)\n ) {\n throw new InvalidConfigurationError(\n path + \" must be an object.\"\n );\n }\n if (allowedKeys !== null) rejectUnknownFields(value, allowedKeys, path);\n return value as UnknownRecord;\n}\n\nfunction requireNonEmptyString(\n value: unknown,\n path: string\n): string {\n if (\n typeof value !== \"string\" ||\n value.trim().length === 0\n ) {\n throw new InvalidConfigurationError(\n path + \" must be a non-empty string.\"\n );\n }\n return value.trim();\n}\n\nfunction requireFinite(\n value: unknown,\n path: string\n): number {\n if (\n typeof value !== \"number\" ||\n !Number.isFinite(value)\n ) {\n throw new InvalidConfigurationError(\n path + \" must be a finite number.\"\n );\n }\n return value;\n}\n\nfunction requireNonNegativeFinite(\n value: unknown,\n path: string\n): number {\n const number = requireFinite(value, path);\n if (number < 0) {\n throw new InvalidConfigurationError(\n path +\n \" must be greater than or equal to zero.\"\n );\n }\n return number;\n}\n\nfunction requireFraction(\n value: unknown,\n path: string\n): number {\n const number = requireFinite(value, path);\n if (number < 0 || number > 1) {\n throw new InvalidConfigurationError(\n path +\n \" must be a finite fraction from 0 through 1.\"\n );\n }\n return number;\n}\n\nfunction parseVector3(\n value: unknown,\n path: string\n): Vector3 {\n const record = requireRecord(value, path, [\"x\", \"y\", \"z\"]);\n return {\n x: requireFinite(record.x, path + \".x\"),\n y: requireFinite(record.y, path + \".y\"),\n z: requireFinite(record.z, path + \".z\")\n };\n}\n\nfunction parseUnitDirection(\n value: unknown,\n path: string\n): Vector3 {\n const vector = parseVector3(value, path);\n const length = Math.hypot(\n vector.x,\n vector.y,\n vector.z\n );\n if (\n !Number.isFinite(length) ||\n Math.abs(length - 1) > 1e-9\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must be a unit-length direction vector.\"\n );\n }\n return vector;\n}\n\nfunction parseUncertainty(\n value: unknown,\n path: string\n): SceneRadianceUncertainty {\n const record = requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", UNCERTAINTY_VARIANT_FIELDS, path);\n if (record.kind === \"relative\") {\n return {\n kind: \"relative\",\n fraction: requireNonNegativeFinite(\n record.fraction,\n path + \".fraction\"\n ),\n basis: requireNonEmptyString(\n record.basis,\n path + \".basis\"\n )\n };\n }\n if (record.kind === \"not-quantified\") {\n return {\n kind: \"not-quantified\",\n limitation: requireNonEmptyString(\n record.limitation,\n path + \".limitation\"\n )\n };\n }\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n}\n\nfunction parseLimitations(\n value: unknown,\n path: string\n): readonly string[] {\n if (!Array.isArray(value)) {\n throw new InvalidConfigurationError(\n path + \" must be an array.\"\n );\n }\n const limitations = value.map(\n (entry, index) =>\n requireNonEmptyString(\n entry,\n path + \"[\" + index + \"]\"\n )\n );\n if (\n new Set(limitations).size !==\n limitations.length\n ) {\n throw new InvalidConfigurationError(\n path + \" must not contain duplicates.\"\n );\n }\n return limitations;\n}\n\nfunction parseArtifact(\n value: unknown,\n path: string\n): SceneRadianceDataArtifactReference {\n const record = requireRecord(value, path, [\"checksumSha256\", \"id\"]);\n const checksumSha256 =\n requireNonEmptyString(\n record.checksumSha256,\n path + \".checksumSha256\"\n );\n if (\n !/^[a-f0-9]{64}$/iu.test(\n checksumSha256\n )\n ) {\n throw new InvalidConfigurationError(\n path +\n \".checksumSha256 must be a 64-character SHA-256 hex digest.\"\n );\n }\n return {\n id: requireNonEmptyString(\n record.id,\n path + \".id\"\n ),\n checksumSha256:\n checksumSha256.toLowerCase()\n };\n}\n\nfunction parseMaterialRepresentation(\n value: unknown,\n path: string\n): SceneMaterialResponseRepresentation {\n const record = requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", {\n unresolved: [\"kind\", \"limitation\"],\n \"rgb-pbr-approximation\": [\"kind\", \"colorSpace\", \"baseColor\", \"metallic\", \"roughness\", \"limitation\"],\n \"spectral-wavelength-preserving-data\": [\"kind\", \"dataArtifact\", \"wavelengthBasis\", \"wavelengthRangeNanometers\", \"scatteringModel\",\n \"scientificStatus\", \"uncertainty\", \"wavelengthChangingBehaviorModeled\", \"emissionModeled\"]\n }, path);\n\n if (record.kind === \"unresolved\") {\n return {\n kind: \"unresolved\",\n limitation: requireNonEmptyString(\n record.limitation,\n path + \".limitation\"\n )\n };\n }\n\n if (\n record.kind ===\n \"rgb-pbr-approximation\"\n ) {\n if (record.colorSpace !== \"linear-srgb\") {\n throw new InvalidConfigurationError(\n path +\n '.colorSpace must be \"linear-srgb\".'\n );\n }\n const baseColor = requireRecord(\n record.baseColor,\n path + \".baseColor\", [\"red\", \"green\", \"blue\"]\n );\n return {\n kind: \"rgb-pbr-approximation\",\n colorSpace: \"linear-srgb\",\n baseColor: {\n red: requireFraction(\n baseColor.red,\n path + \".baseColor.red\"\n ),\n green: requireFraction(\n baseColor.green,\n path + \".baseColor.green\"\n ),\n blue: requireFraction(\n baseColor.blue,\n path + \".baseColor.blue\"\n )\n },\n metallic: requireFraction(\n record.metallic,\n path + \".metallic\"\n ),\n roughness: requireFraction(\n record.roughness,\n path + \".roughness\"\n ),\n limitation: requireNonEmptyString(\n record.limitation,\n path + \".limitation\"\n )\n };\n }\n\n if (\n record.kind !==\n \"spectral-wavelength-preserving-data\"\n ) {\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n }\n\n if (\n record.scatteringModel !==\n \"provider-defined-wavelength-preserving\"\n ) {\n throw new InvalidConfigurationError(\n path +\n '.scatteringModel must be \"provider-defined-wavelength-preserving\".'\n );\n }\n if (\n record.scientificStatus !==\n \"calibrated\" &&\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n path + \".scientificStatus is invalid.\"\n );\n }\n const scientificStatus =\n record.scientificStatus;\n const wavelengthBasis =\n parseSpectralWavelengthBasis(\n record.wavelengthBasis,\n path + \".wavelengthBasis\"\n );\n const uncertainty = parseUncertainty(\n record.uncertainty,\n path + \".uncertainty\"\n );\n if (\n scientificStatus === \"calibrated\" &&\n wavelengthBasis === \"unspecified\"\n ) {\n throw new InvalidConfigurationError(\n path +\n \" calibrated spectral material data requires an air or vacuum wavelength basis.\"\n );\n }\n if (\n scientificStatus === \"calibrated\" &&\n uncertainty.kind !== \"relative\"\n ) {\n throw new InvalidConfigurationError(\n path +\n \" calibrated spectral material data requires quantified relative uncertainty.\"\n );\n }\n if (\n record.wavelengthChangingBehaviorModeled !==\n false\n ) {\n throw new InvalidConfigurationError(\n path +\n \".wavelengthChangingBehaviorModeled must be false in schema 0.1.0.\"\n );\n }\n if (record.emissionModeled !== false) {\n throw new InvalidConfigurationError(\n path +\n \".emissionModeled must be false in schema 0.1.0.\"\n );\n }\n\n return {\n kind:\n \"spectral-wavelength-preserving-data\",\n dataArtifact: parseArtifact(\n record.dataArtifact,\n path + \".dataArtifact\"\n ),\n wavelengthBasis,\n wavelengthRangeNanometers:\n parseSpectralWavelengthRangeNanometers(\n record.wavelengthRangeNanometers,\n path + \".wavelengthRangeNanometers\"\n ),\n scatteringModel:\n \"provider-defined-wavelength-preserving\",\n scientificStatus,\n uncertainty,\n wavelengthChangingBehaviorModeled:\n false,\n emissionModeled: false\n };\n}\n\n/**\n * Parses material-response metadata used by a scene-radiance provider.\n *\n * RGB or PBR (physically based rendering) material data is always an approximation.\n * Spectral data is a per-wavelength provider input. It does not itself compute a BSDF\n * (how a surface scatters light), scene radiance, fluorescence, emission, volumetric\n * effects or polarization.\n */\nexport function parseSceneMaterialResponseProfile(\n value: unknown\n): SceneMaterialResponseProfile {\n const record = requireRecord(\n value,\n \"sceneMaterialResponseProfile\", [\"schemaVersion\", \"materials\", \"fluorescenceModeled\", \"volumetricMaterialTransportModeled\", \"polarizationModeled\", \"profileId\", \"sceneId\", \"evidence\"]\n );\n if (\n record.schemaVersion !==\n SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneMaterialResponseProfile.schemaVersion must be \"' +\n SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION +\n '\".'\n );\n }\n if (!Array.isArray(record.materials)) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.materials must be an array.\"\n );\n }\n\n const materials = record.materials.map(\n (entry, index) => {\n const path =\n \"sceneMaterialResponseProfile.materials[\" +\n index +\n \"]\";\n const material = requireRecord(\n entry,\n path, [\"materialResponseId\", \"evidence\", \"representation\"]\n );\n return {\n materialResponseId:\n requireNonEmptyString(\n material.materialResponseId,\n path + \".materialResponseId\"\n ),\n evidence: parseEvidenceList(\n material.evidence,\n path + \".evidence\"\n ),\n representation:\n parseMaterialRepresentation(\n material.representation,\n path + \".representation\"\n )\n };\n }\n );\n const ids = materials.map(\n (entry) => entry.materialResponseId\n );\n if (new Set(ids).size !== ids.length) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.materials[].materialResponseId must not contain duplicates.\"\n );\n }\n\n if (record.fluorescenceModeled !== false) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.fluorescenceModeled must be false in schema 0.1.0.\"\n );\n }\n if (\n record.volumetricMaterialTransportModeled !==\n false\n ) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.volumetricMaterialTransportModeled must be false in schema 0.1.0.\"\n );\n }\n if (record.polarizationModeled !== false) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.polarizationModeled must be false in schema 0.1.0.\"\n );\n }\n\n return {\n schemaVersion:\n SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION,\n profileId: requireNonEmptyString(\n record.profileId,\n \"sceneMaterialResponseProfile.profileId\"\n ),\n sceneId: requireNonEmptyString(\n record.sceneId,\n \"sceneMaterialResponseProfile.sceneId\"\n ),\n evidence: parseEvidenceList(\n record.evidence,\n \"sceneMaterialResponseProfile.evidence\"\n ),\n materials,\n fluorescenceModeled: false,\n volumetricMaterialTransportModeled:\n false,\n polarizationModeled: false\n };\n}\n\n/**\n * Returns the material fidelity a profile supports, choosing the lower level when in doubt.\n */\nexport function assessSceneMaterialResponseFidelity(\n profile: SceneMaterialResponseProfile\n): SceneMaterialResponseFidelity {\n requireInputObject(profile, \"assessSceneMaterialResponseFidelity input\");\n // 2.0.0: the whole profile is validated, so an unknown field at any level is rejected.\n parseSceneMaterialResponseProfile(profile);\n requireInputArray(profile.materials, \"profile.materials\");\n if (\n profile.materials.some(\n (entry) =>\n entry.representation.kind ===\n \"unresolved\"\n )\n ) {\n return \"unresolved\";\n }\n\n const kinds = new Set(\n profile.materials.map(\n (entry) => entry.representation.kind\n )\n );\n if (\n kinds.size === 0 ||\n kinds.has(\"unresolved\")\n ) {\n return \"unresolved\";\n }\n if (\n kinds.size === 1 &&\n kinds.has(\n \"spectral-wavelength-preserving-data\"\n )\n ) {\n return \"spectral-data\";\n }\n if (\n kinds.size === 1 &&\n kinds.has(\"rgb-pbr-approximation\")\n ) {\n return \"rgb-pbr-approximation\";\n }\n return \"mixed\";\n}\n\nfunction parseProviderFidelity(\n value: unknown,\n path: string\n): SceneRadianceProviderProfile[\"fidelity\"] {\n const record = requireRecord(value, path, [\"spectral\", \"material\", \"visibility\", \"directTransport\", \"indirectTransport\"]);\n const spectral = record.spectral;\n if (\n spectral !== \"wavelength-resolved\" &&\n spectral !==\n \"rgb-derived-approximation\"\n ) {\n throw new InvalidConfigurationError(\n path + \".spectral is invalid.\"\n );\n }\n const material = record.material;\n if (\n material !== \"spectral-data\" &&\n material !== \"rgb-pbr-approximation\" &&\n material !== \"mixed\" &&\n material !== \"unresolved\"\n ) {\n throw new InvalidConfigurationError(\n path + \".material is invalid.\"\n );\n }\n const parseVisibility = (\n candidate: unknown,\n candidatePath: string\n ): SceneRadianceProviderVisibilityFidelity => {\n if (\n candidate !== \"resolved\" &&\n candidate !== \"approximation\" &&\n candidate !== \"not-modeled\"\n ) {\n throw new InvalidConfigurationError(\n candidatePath + \" is invalid.\"\n );\n }\n return candidate;\n };\n const parseTransport = (\n candidate: unknown,\n candidatePath: string\n ): SceneRadianceProviderTransportFidelity => {\n if (\n candidate !== \"resolved\" &&\n candidate !== \"approximation\" &&\n candidate !== \"not-modeled\"\n ) {\n throw new InvalidConfigurationError(\n candidatePath + \" is invalid.\"\n );\n }\n return candidate;\n };\n\n return {\n spectral,\n material,\n visibility: parseVisibility(\n record.visibility,\n path + \".visibility\"\n ),\n directTransport: parseTransport(\n record.directTransport,\n path + \".directTransport\"\n ),\n indirectTransport: parseTransport(\n record.indirectTransport,\n path + \".indirectTransport\"\n )\n };\n}\n\n/**\n * Parses a provider's declaration of what it can do (its profile). Works with any renderer.\n *\n * Schema 0.1.0 is approximation-only by design. A provider may use calibrated inputs,\n * but this contract cannot support a claim of calibrated outgoing radiance. That needs\n * later work on complete spectral and light-transport models.\n */\nexport function parseSceneRadianceProviderProfile(\n value: unknown\n): SceneRadianceProviderProfile {\n const record = requireRecord(\n value,\n \"sceneRadianceProviderProfile\", [\"schemaVersion\", \"outputQuantity\", \"outputUnit\", \"scientificStatus\", \"wavelengthChangingTransportModeled\", \"volumetricTransportModeled\", \"polarizationModeled\", \"profileId\", \"sceneId\", \"illuminationProfileId\", \"illuminationTemporalProfileId\", \"materialResponseProfileId\", \"uncertainty\", \"fidelity\", \"evidence\", \"limitations\"]\n );\n if (\n record.schemaVersion !==\n SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceProviderProfile.schemaVersion must be \"' +\n SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION +\n '\".'\n );\n }\n if (\n record.outputQuantity !==\n \"outgoing-spectral-radiance\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceProviderProfile.outputQuantity must be \"outgoing-spectral-radiance\".'\n );\n }\n if (record.outputUnit !== \"W/m^2/sr/nm\") {\n throw new InvalidConfigurationError(\n 'sceneRadianceProviderProfile.outputUnit must be \"W/m^2/sr/nm\".'\n );\n }\n if (\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceProviderProfile.scientificStatus must be \"approximation\" in schema 0.1.0.'\n );\n }\n if (\n record.wavelengthChangingTransportModeled !==\n false ||\n record.volumetricTransportModeled !==\n false ||\n record.polarizationModeled !== false\n ) {\n throw new InvalidConfigurationError(\n \"sceneRadianceProviderProfile wavelength-changing, volumetric, and polarization transport flags must all be false in schema 0.1.0.\"\n );\n }\n\n return {\n schemaVersion:\n SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION,\n profileId: requireNonEmptyString(\n record.profileId,\n \"sceneRadianceProviderProfile.profileId\"\n ),\n sceneId: requireNonEmptyString(\n record.sceneId,\n \"sceneRadianceProviderProfile.sceneId\"\n ),\n illuminationProfileId:\n requireNonEmptyString(\n record.illuminationProfileId,\n \"sceneRadianceProviderProfile.illuminationProfileId\"\n ),\n ...(record.illuminationTemporalProfileId ===\n undefined\n ? {}\n : {\n illuminationTemporalProfileId:\n requireNonEmptyString(\n record.illuminationTemporalProfileId,\n \"sceneRadianceProviderProfile.illuminationTemporalProfileId\"\n )\n }),\n materialResponseProfileId:\n requireNonEmptyString(\n record.materialResponseProfileId,\n \"sceneRadianceProviderProfile.materialResponseProfileId\"\n ),\n outputQuantity:\n \"outgoing-spectral-radiance\",\n outputUnit: \"W/m^2/sr/nm\",\n scientificStatus: \"approximation\",\n uncertainty: parseUncertainty(\n record.uncertainty,\n \"sceneRadianceProviderProfile.uncertainty\"\n ),\n fidelity: parseProviderFidelity(\n record.fidelity,\n \"sceneRadianceProviderProfile.fidelity\"\n ),\n wavelengthChangingTransportModeled:\n false,\n volumetricTransportModeled: false,\n polarizationModeled: false,\n evidence: parseEvidenceList(\n record.evidence,\n \"sceneRadianceProviderProfile.evidence\"\n ),\n limitations: parseLimitations(\n record.limitations,\n \"sceneRadianceProviderProfile.limitations\"\n )\n };\n}\n\nfunction parsePositiveWavelengthNanometers(\n value: unknown,\n path: string\n): number {\n const wavelength = requireFinite(\n value,\n path\n );\n if (wavelength <= 0) {\n throw new InvalidConfigurationError(\n path + \" must be greater than zero.\"\n );\n }\n return wavelength;\n}\n\nfunction parseResolvedWavelengthBasis(\n value: unknown,\n path: string\n): Exclude<\n SpectralWavelengthBasis,\n \"unspecified\"\n> {\n const basis = parseSpectralWavelengthBasis(\n value,\n path\n );\n if (basis === \"unspecified\") {\n throw new InvalidConfigurationError(\n path +\n \" must be air or vacuum for outgoing spectral radiance.\"\n );\n }\n return basis;\n}\n\nfunction parseEvaluationTarget(\n value: unknown,\n path: string\n): SceneRadianceEvaluationTarget {\n const record = requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", {\n \"surface-point\": [\"kind\", \"sceneObjectId\", \"materialResponseId\", \"positionM\", \"outgoingDirectionUnitVector\"],\n \"environment-direction\": [\"kind\", \"outgoingDirectionUnitVector\"]\n }, path);\n if (record.kind === \"surface-point\") {\n return {\n kind: \"surface-point\",\n sceneObjectId: requireNonEmptyString(\n record.sceneObjectId,\n path + \".sceneObjectId\"\n ),\n materialResponseId:\n requireNonEmptyString(\n record.materialResponseId,\n path + \".materialResponseId\"\n ),\n positionM: parseVector3(\n record.positionM,\n path + \".positionM\"\n ),\n outgoingDirectionUnitVector:\n parseUnitDirection(\n record.outgoingDirectionUnitVector,\n path +\n \".outgoingDirectionUnitVector\"\n )\n };\n }\n if (\n record.kind ===\n \"environment-direction\"\n ) {\n return {\n kind: \"environment-direction\",\n outgoingDirectionUnitVector:\n parseUnitDirection(\n record.outgoingDirectionUnitVector,\n path +\n \".outgoingDirectionUnitVector\"\n )\n };\n }\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n}\n\n/**\n * Parses one provider evaluation request at an explicit scene target,\n * physical time, wavelength, and outgoing direction.\n */\nexport function parseSceneRadianceEvaluationRequest(\n value: unknown\n): SceneRadianceEvaluationRequest {\n const record = requireRecord(\n value,\n \"sceneRadianceEvaluationRequest\", [\"schemaVersion\", \"sampleId\", \"providerProfileId\", \"sceneId\", \"illuminationProfileId\", \"materialResponseProfileId\", \"target\", \"timeSecondsFromExposureStart\", \"wavelengthNanometers\", \"wavelengthBasis\"]\n );\n if (\n record.schemaVersion !==\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationRequest.schemaVersion must be \"' +\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION +\n '\".'\n );\n }\n\n return {\n schemaVersion:\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION,\n sampleId: requireNonEmptyString(\n record.sampleId,\n \"sceneRadianceEvaluationRequest.sampleId\"\n ),\n providerProfileId:\n requireNonEmptyString(\n record.providerProfileId,\n \"sceneRadianceEvaluationRequest.providerProfileId\"\n ),\n sceneId: requireNonEmptyString(\n record.sceneId,\n \"sceneRadianceEvaluationRequest.sceneId\"\n ),\n illuminationProfileId:\n requireNonEmptyString(\n record.illuminationProfileId,\n \"sceneRadianceEvaluationRequest.illuminationProfileId\"\n ),\n materialResponseProfileId:\n requireNonEmptyString(\n record.materialResponseProfileId,\n \"sceneRadianceEvaluationRequest.materialResponseProfileId\"\n ),\n target: parseEvaluationTarget(\n record.target,\n \"sceneRadianceEvaluationRequest.target\"\n ),\n timeSecondsFromExposureStart:\n requireNonNegativeFinite(\n record.timeSecondsFromExposureStart,\n \"sceneRadianceEvaluationRequest.timeSecondsFromExposureStart\"\n ),\n wavelengthNanometers:\n parsePositiveWavelengthNanometers(\n record.wavelengthNanometers,\n \"sceneRadianceEvaluationRequest.wavelengthNanometers\"\n ),\n wavelengthBasis:\n parseResolvedWavelengthBasis(\n record.wavelengthBasis,\n \"sceneRadianceEvaluationRequest.wavelengthBasis\"\n )\n };\n}\n\n/**\n * Parses one outgoing spectral-radiance result from a provider.\n *\n * The number is accepted as the provider reported it. Parsing checks units, that the\n * value is finite and nonnegative, provenance and identity fields. It does not prove\n * the provider's light-transport calculation is physically correct.\n */\nexport function parseSceneRadianceEvaluationResult(\n value: unknown\n): SceneRadianceEvaluationResult {\n const record = requireRecord(\n value,\n \"sceneRadianceEvaluationResult\", [\"schemaVersion\", \"quantity\", \"unit\", \"scientificStatus\", \"sampleId\", \"providerProfileId\", \"sceneId\", \"wavelengthNanometers\", \"wavelengthBasis\", \"spectralRadianceWattsPerSquareMeterSteradianNanometer\", \"uncertainty\", \"evidence\", \"limitations\"]\n );\n if (\n record.schemaVersion !==\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationResult.schemaVersion must be \"' +\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION +\n '\".'\n );\n }\n if (\n record.quantity !==\n \"outgoing-spectral-radiance\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationResult.quantity must be \"outgoing-spectral-radiance\".'\n );\n }\n if (record.unit !== \"W/m^2/sr/nm\") {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationResult.unit must be \"W/m^2/sr/nm\".'\n );\n }\n if (\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationResult.scientificStatus must be \"approximation\" in schema 0.1.0.'\n );\n }\n\n return {\n schemaVersion:\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION,\n sampleId: requireNonEmptyString(\n record.sampleId,\n \"sceneRadianceEvaluationResult.sampleId\"\n ),\n providerProfileId:\n requireNonEmptyString(\n record.providerProfileId,\n \"sceneRadianceEvaluationResult.providerProfileId\"\n ),\n sceneId: requireNonEmptyString(\n record.sceneId,\n \"sceneRadianceEvaluationResult.sceneId\"\n ),\n wavelengthNanometers:\n parsePositiveWavelengthNanometers(\n record.wavelengthNanometers,\n \"sceneRadianceEvaluationResult.wavelengthNanometers\"\n ),\n wavelengthBasis:\n parseResolvedWavelengthBasis(\n record.wavelengthBasis,\n \"sceneRadianceEvaluationResult.wavelengthBasis\"\n ),\n quantity:\n \"outgoing-spectral-radiance\",\n unit: \"W/m^2/sr/nm\",\n spectralRadianceWattsPerSquareMeterSteradianNanometer:\n requireNonNegativeFinite(\n record.spectralRadianceWattsPerSquareMeterSteradianNanometer,\n \"sceneRadianceEvaluationResult.spectralRadianceWattsPerSquareMeterSteradianNanometer\"\n ),\n scientificStatus: \"approximation\",\n uncertainty: parseUncertainty(\n record.uncertainty,\n \"sceneRadianceEvaluationResult.uncertainty\"\n ),\n evidence: parseEvidenceList(\n record.evidence,\n \"sceneRadianceEvaluationResult.evidence\"\n ),\n limitations: parseLimitations(\n record.limitations,\n \"sceneRadianceEvaluationResult.limitations\"\n )\n };\n}\n\nfunction requireEqual(\n actual: unknown,\n expected: unknown,\n message: string\n): void {\n if (actual !== expected) {\n throw new InvalidConfigurationError(\n message\n );\n }\n}\n\n/**\n * Checks that a provider result matches its request and profile identities exactly.\n *\n * It never recomputes the radiance value, and never upgrades the provider's\n * approximation to calibrated radiometry.\n */\nexport function validateSceneRadianceEvaluationBindings(\n input:\n ValidateSceneRadianceEvaluationBindingsInput\n): SceneRadianceEvaluationBindingAssessment {\n requireInputKeys(input, \"validateSceneRadianceEvaluationBindings\", [\"providerProfile\", \"illuminationProfile\", \"illuminationTemporalProfile\", \"materialResponseProfile\", \"request\", \"result\"]);\n const {\n providerProfile,\n illuminationProfile,\n illuminationTemporalProfile,\n materialResponseProfile,\n request,\n result\n } = input;\n\n requireInputObject(providerProfile, \"providerProfile input\");\n requireEqual(\n providerProfile.sceneId,\n illuminationProfile.sceneId,\n \"Provider and illumination profiles must reference the same sceneId.\"\n );\n requireEqual(\n providerProfile.sceneId,\n materialResponseProfile.sceneId,\n \"Provider and material-response profiles must reference the same sceneId.\"\n );\n requireEqual(\n providerProfile.illuminationProfileId,\n illuminationProfile.profileId,\n \"Provider illuminationProfileId must match the supplied illumination profile.\"\n );\n requireEqual(\n providerProfile.materialResponseProfileId,\n materialResponseProfile.profileId,\n \"Provider materialResponseProfileId must match the supplied material-response profile.\"\n );\n\n if (\n providerProfile\n .illuminationTemporalProfileId ===\n undefined\n ) {\n if (\n illuminationTemporalProfile !==\n undefined\n ) {\n throw new InvalidConfigurationError(\n \"A temporal illumination profile was supplied but the provider profile does not bind one.\"\n );\n }\n } else {\n if (\n illuminationTemporalProfile ===\n undefined\n ) {\n throw new InvalidConfigurationError(\n \"Provider illuminationTemporalProfileId requires the matching temporal illumination profile.\"\n );\n }\n requireEqual(\n providerProfile\n .illuminationTemporalProfileId,\n illuminationTemporalProfile\n .profileId,\n \"Provider illuminationTemporalProfileId must match the supplied temporal illumination profile.\"\n );\n requireEqual(\n providerProfile.sceneId,\n illuminationTemporalProfile.sceneId,\n \"Provider and temporal illumination profiles must reference the same sceneId.\"\n );\n requireEqual(\n providerProfile\n .illuminationProfileId,\n illuminationTemporalProfile\n .illuminationProfileId,\n \"Temporal illumination profile must bind the provider's illuminationProfileId.\"\n );\n }\n\n const materialResponseFidelity =\n assessSceneMaterialResponseFidelity(\n materialResponseProfile\n );\n requireEqual(\n providerProfile.fidelity.material,\n materialResponseFidelity,\n \"Provider material fidelity must match the supplied material-response profile.\"\n );\n\n requireEqual(\n request.providerProfileId,\n providerProfile.profileId,\n \"Request providerProfileId must match the supplied provider profile.\"\n );\n requireEqual(\n request.sceneId,\n providerProfile.sceneId,\n \"Request sceneId must match the supplied provider profile.\"\n );\n requireEqual(\n request.illuminationProfileId,\n illuminationProfile.profileId,\n \"Request illuminationProfileId must match the supplied illumination profile.\"\n );\n requireEqual(\n request.materialResponseProfileId,\n materialResponseProfile.profileId,\n \"Request materialResponseProfileId must match the supplied material-response profile.\"\n );\n\n if (request.target.kind === \"surface-point\") {\n const target = request.target;\n if (\n !materialResponseProfile.materials.some(\n (material) =>\n material.materialResponseId ===\n target.materialResponseId\n )\n ) {\n throw new InvalidConfigurationError(\n \"Request surface target materialResponseId is not declared by the supplied material-response profile.\"\n );\n }\n }\n\n requireEqual(\n result.sampleId,\n request.sampleId,\n \"Result sampleId must match the request.\"\n );\n requireEqual(\n result.providerProfileId,\n request.providerProfileId,\n \"Result providerProfileId must match the request.\"\n );\n requireEqual(\n result.sceneId,\n request.sceneId,\n \"Result sceneId must match the request.\"\n );\n requireEqual(\n result.wavelengthNanometers,\n request.wavelengthNanometers,\n \"Result wavelengthNanometers must match the request exactly.\"\n );\n requireEqual(\n result.wavelengthBasis,\n request.wavelengthBasis,\n \"Result wavelengthBasis must match the request.\"\n );\n\n return {\n providerBindingsMatched: true,\n requestResultIdentityMatched: true,\n materialResponseFidelity,\n temporalIlluminationProfileBound:\n illuminationTemporalProfile !==\n undefined,\n calibratedRadianceClaimAuthorized: false,\n sensorPlaneIrradianceCalculated:\n false,\n opticsApplied: false,\n photonsCalculated: false\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scene-radiance.js","sourceRoot":"","sources":["../../src/schema/scene-radiance.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Contracts for scene-radiance providers: the renderer or other code that reports how much\n * light leaves a scene point toward the camera.\n *\n * It covers material-response metadata, provider capability profiles, single evaluation\n * requests and results, and identity checks between them. The engine validates this data\n * but does not compute scene radiance itself.\n * @see docs/SCENE_RADIANCE_AND_ILLUMINATION.md for equations, coordinate/unit conventions, blockers\n * and support limits.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport {\n parseEvidenceList,\n type EvidenceProvenance\n} from \"../core/evidence-provenance.js\";\nimport {\n parseSpectralWavelengthBasis,\n parseSpectralWavelengthRangeNanometers,\n type SpectralWavelengthBasis,\n type SpectralWavelengthRangeNanometers\n} from \"../core/spectral.js\";\nimport type {\n SceneIlluminationProfile\n} from \"./illumination.js\";\nimport type {\n SceneIlluminationTemporalProfile\n} from \"./illumination-temporal.js\";\nimport type { Vector3 } from \"./scene.js\";\nimport { requireInputObject, requireInputArray, requireInputKeys, rejectUnknownFields, rejectUnknownVariantFields, UNCERTAINTY_VARIANT_FIELDS } from \"../core/record-validation.js\";\n\ntype UnknownRecord = Record<string, unknown>;\n\nexport const SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION =\n \"0.1.0\" as const;\nexport const SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION =\n \"0.1.0\" as const;\nexport const SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION =\n \"0.1.0\" as const;\n\nexport type SceneRadianceScientificStatus =\n | \"calibrated\"\n | \"approximation\";\n\nexport type SceneRadianceUncertainty =\n | {\n kind: \"relative\";\n fraction: number;\n basis: string;\n }\n | {\n kind: \"not-quantified\";\n limitation: string;\n };\n\nexport interface SceneRadianceDataArtifactReference {\n id: string;\n checksumSha256: string;\n}\n\nexport type SceneMaterialResponseRepresentation =\n | {\n kind: \"unresolved\";\n limitation: string;\n }\n | {\n kind: \"rgb-pbr-approximation\";\n colorSpace: \"linear-srgb\";\n baseColor: {\n red: number;\n green: number;\n blue: number;\n };\n metallic: number;\n roughness: number;\n limitation: string;\n }\n | {\n kind: \"spectral-wavelength-preserving-data\";\n dataArtifact:\n SceneRadianceDataArtifactReference;\n wavelengthBasis:\n SpectralWavelengthBasis;\n wavelengthRangeNanometers:\n SpectralWavelengthRangeNanometers;\n scatteringModel:\n \"provider-defined-wavelength-preserving\";\n scientificStatus:\n SceneRadianceScientificStatus;\n uncertainty:\n SceneRadianceUncertainty;\n wavelengthChangingBehaviorModeled: false;\n emissionModeled: false;\n };\n\nexport interface SceneMaterialResponseDefinition {\n materialResponseId: string;\n evidence: readonly EvidenceProvenance[];\n representation:\n SceneMaterialResponseRepresentation;\n}\n\nexport interface SceneMaterialResponseProfile {\n schemaVersion:\n typeof SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION;\n profileId: string;\n sceneId: string;\n evidence: readonly EvidenceProvenance[];\n materials:\n readonly SceneMaterialResponseDefinition[];\n fluorescenceModeled: false;\n volumetricMaterialTransportModeled: false;\n polarizationModeled: false;\n}\n\nexport type SceneMaterialResponseFidelity =\n | \"spectral-data\"\n | \"rgb-pbr-approximation\"\n | \"mixed\"\n | \"unresolved\";\n\nexport type SceneRadianceProviderSpectralFidelity =\n | \"wavelength-resolved\"\n | \"rgb-derived-approximation\";\n\nexport type SceneRadianceProviderVisibilityFidelity =\n | \"resolved\"\n | \"approximation\"\n | \"not-modeled\";\n\nexport type SceneRadianceProviderTransportFidelity =\n | \"resolved\"\n | \"approximation\"\n | \"not-modeled\";\n\nexport interface SceneRadianceProviderProfile {\n schemaVersion:\n typeof SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION;\n profileId: string;\n sceneId: string;\n illuminationProfileId: string;\n illuminationTemporalProfileId?: string;\n materialResponseProfileId: string;\n outputQuantity:\n \"outgoing-spectral-radiance\";\n outputUnit:\n \"W/m^2/sr/nm\";\n scientificStatus: \"approximation\";\n uncertainty: SceneRadianceUncertainty;\n fidelity: {\n spectral:\n SceneRadianceProviderSpectralFidelity;\n material:\n SceneMaterialResponseFidelity;\n visibility:\n SceneRadianceProviderVisibilityFidelity;\n directTransport:\n SceneRadianceProviderTransportFidelity;\n indirectTransport:\n SceneRadianceProviderTransportFidelity;\n };\n wavelengthChangingTransportModeled: false;\n volumetricTransportModeled: false;\n polarizationModeled: false;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport type SceneRadianceEvaluationTarget =\n | {\n kind: \"surface-point\";\n sceneObjectId: string;\n materialResponseId: string;\n positionM: Vector3;\n outgoingDirectionUnitVector: Vector3;\n }\n | {\n kind: \"environment-direction\";\n outgoingDirectionUnitVector: Vector3;\n };\n\nexport interface SceneRadianceEvaluationRequest {\n schemaVersion:\n typeof SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION;\n sampleId: string;\n providerProfileId: string;\n sceneId: string;\n illuminationProfileId: string;\n materialResponseProfileId: string;\n target: SceneRadianceEvaluationTarget;\n timeSecondsFromExposureStart: number;\n wavelengthNanometers: number;\n wavelengthBasis:\n Exclude<SpectralWavelengthBasis, \"unspecified\">;\n}\n\nexport interface SceneRadianceEvaluationResult {\n schemaVersion:\n typeof SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION;\n sampleId: string;\n providerProfileId: string;\n sceneId: string;\n wavelengthNanometers: number;\n wavelengthBasis:\n Exclude<SpectralWavelengthBasis, \"unspecified\">;\n quantity:\n \"outgoing-spectral-radiance\";\n unit: \"W/m^2/sr/nm\";\n spectralRadianceWattsPerSquareMeterSteradianNanometer:\n number;\n scientificStatus: \"approximation\";\n uncertainty: SceneRadianceUncertainty;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface ValidateSceneRadianceEvaluationBindingsInput {\n providerProfile: SceneRadianceProviderProfile;\n illuminationProfile: SceneIlluminationProfile;\n illuminationTemporalProfile?:\n SceneIlluminationTemporalProfile;\n materialResponseProfile:\n SceneMaterialResponseProfile;\n request: SceneRadianceEvaluationRequest;\n result: SceneRadianceEvaluationResult;\n}\n\nexport interface SceneRadianceEvaluationBindingAssessment {\n providerBindingsMatched: true;\n requestResultIdentityMatched: true;\n materialResponseFidelity:\n SceneMaterialResponseFidelity;\n temporalIlluminationProfileBound:\n boolean;\n calibratedRadianceClaimAuthorized: false;\n sensorPlaneIrradianceCalculated: false;\n opticsApplied: false;\n photonsCalculated: false;\n}\n\nfunction requireRecord(\n value: unknown,\n path: string,\n allowedKeys: readonly string[] | null\n): UnknownRecord {\n if (\n typeof value !== \"object\" ||\n value === null ||\n Array.isArray(value)\n ) {\n throw new InvalidConfigurationError(\n path + \" must be an object.\"\n );\n }\n if (allowedKeys !== null) rejectUnknownFields(value, allowedKeys, path);\n return value as UnknownRecord;\n}\n\nfunction requireNonEmptyString(\n value: unknown,\n path: string\n): string {\n if (\n typeof value !== \"string\" ||\n value.trim().length === 0\n ) {\n throw new InvalidConfigurationError(\n path + \" must be a non-empty string.\"\n );\n }\n return value.trim();\n}\n\nfunction requireFinite(\n value: unknown,\n path: string\n): number {\n if (\n typeof value !== \"number\" ||\n !Number.isFinite(value)\n ) {\n throw new InvalidConfigurationError(\n path + \" must be a finite number.\"\n );\n }\n return value;\n}\n\nfunction requireNonNegativeFinite(\n value: unknown,\n path: string\n): number {\n const number = requireFinite(value, path);\n if (number < 0) {\n throw new InvalidConfigurationError(\n path +\n \" must be greater than or equal to zero.\"\n );\n }\n return number;\n}\n\nfunction requireFraction(\n value: unknown,\n path: string\n): number {\n const number = requireFinite(value, path);\n if (number < 0 || number > 1) {\n throw new InvalidConfigurationError(\n path +\n \" must be a finite fraction from 0 through 1.\"\n );\n }\n return number;\n}\n\nfunction parseVector3(\n value: unknown,\n path: string\n): Vector3 {\n const record = requireRecord(value, path, [\"x\", \"y\", \"z\"]);\n return {\n x: requireFinite(record.x, path + \".x\"),\n y: requireFinite(record.y, path + \".y\"),\n z: requireFinite(record.z, path + \".z\")\n };\n}\n\nfunction parseUnitDirection(\n value: unknown,\n path: string\n): Vector3 {\n const vector = parseVector3(value, path);\n const length = Math.hypot(\n vector.x,\n vector.y,\n vector.z\n );\n if (\n !Number.isFinite(length) ||\n Math.abs(length - 1) > 1e-9\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must be a unit-length direction vector.\"\n );\n }\n return vector;\n}\n\nfunction parseUncertainty(\n value: unknown,\n path: string\n): SceneRadianceUncertainty {\n const record = requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", UNCERTAINTY_VARIANT_FIELDS, path);\n if (record.kind === \"relative\") {\n return {\n kind: \"relative\",\n fraction: requireNonNegativeFinite(\n record.fraction,\n path + \".fraction\"\n ),\n basis: requireNonEmptyString(\n record.basis,\n path + \".basis\"\n )\n };\n }\n if (record.kind === \"not-quantified\") {\n return {\n kind: \"not-quantified\",\n limitation: requireNonEmptyString(\n record.limitation,\n path + \".limitation\"\n )\n };\n }\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n}\n\nfunction parseLimitations(\n value: unknown,\n path: string\n): readonly string[] {\n if (!Array.isArray(value)) {\n throw new InvalidConfigurationError(\n path + \" must be an array.\"\n );\n }\n const limitations = value.map(\n (entry, index) =>\n requireNonEmptyString(\n entry,\n path + \"[\" + index + \"]\"\n )\n );\n if (\n new Set(limitations).size !==\n limitations.length\n ) {\n throw new InvalidConfigurationError(\n path + \" must not contain duplicates.\"\n );\n }\n return limitations;\n}\n\nfunction parseArtifact(\n value: unknown,\n path: string\n): SceneRadianceDataArtifactReference {\n const record = requireRecord(value, path, [\"checksumSha256\", \"id\"]);\n const checksumSha256 =\n requireNonEmptyString(\n record.checksumSha256,\n path + \".checksumSha256\"\n );\n if (\n !/^[a-f0-9]{64}$/iu.test(\n checksumSha256\n )\n ) {\n throw new InvalidConfigurationError(\n path +\n \".checksumSha256 must be a 64-character SHA-256 hex digest.\"\n );\n }\n return {\n id: requireNonEmptyString(\n record.id,\n path + \".id\"\n ),\n checksumSha256:\n checksumSha256.toLowerCase()\n };\n}\n\nfunction parseMaterialRepresentation(\n value: unknown,\n path: string\n): SceneMaterialResponseRepresentation {\n const record = requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", {\n unresolved: [\"kind\", \"limitation\"],\n \"rgb-pbr-approximation\": [\"kind\", \"colorSpace\", \"baseColor\", \"metallic\", \"roughness\", \"limitation\"],\n \"spectral-wavelength-preserving-data\": [\"kind\", \"dataArtifact\", \"wavelengthBasis\", \"wavelengthRangeNanometers\", \"scatteringModel\",\n \"scientificStatus\", \"uncertainty\", \"wavelengthChangingBehaviorModeled\", \"emissionModeled\"]\n }, path);\n\n if (record.kind === \"unresolved\") {\n return {\n kind: \"unresolved\",\n limitation: requireNonEmptyString(\n record.limitation,\n path + \".limitation\"\n )\n };\n }\n\n if (\n record.kind ===\n \"rgb-pbr-approximation\"\n ) {\n if (record.colorSpace !== \"linear-srgb\") {\n throw new InvalidConfigurationError(\n path +\n '.colorSpace must be \"linear-srgb\".'\n );\n }\n const baseColor = requireRecord(\n record.baseColor,\n path + \".baseColor\", [\"red\", \"green\", \"blue\"]\n );\n return {\n kind: \"rgb-pbr-approximation\",\n colorSpace: \"linear-srgb\",\n baseColor: {\n red: requireFraction(\n baseColor.red,\n path + \".baseColor.red\"\n ),\n green: requireFraction(\n baseColor.green,\n path + \".baseColor.green\"\n ),\n blue: requireFraction(\n baseColor.blue,\n path + \".baseColor.blue\"\n )\n },\n metallic: requireFraction(\n record.metallic,\n path + \".metallic\"\n ),\n roughness: requireFraction(\n record.roughness,\n path + \".roughness\"\n ),\n limitation: requireNonEmptyString(\n record.limitation,\n path + \".limitation\"\n )\n };\n }\n\n if (\n record.kind !==\n \"spectral-wavelength-preserving-data\"\n ) {\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n }\n\n if (\n record.scatteringModel !==\n \"provider-defined-wavelength-preserving\"\n ) {\n throw new InvalidConfigurationError(\n path +\n '.scatteringModel must be \"provider-defined-wavelength-preserving\".'\n );\n }\n if (\n record.scientificStatus !==\n \"calibrated\" &&\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n path + \".scientificStatus is invalid.\"\n );\n }\n const scientificStatus =\n record.scientificStatus;\n const wavelengthBasis =\n parseSpectralWavelengthBasis(\n record.wavelengthBasis,\n path + \".wavelengthBasis\"\n );\n const uncertainty = parseUncertainty(\n record.uncertainty,\n path + \".uncertainty\"\n );\n if (\n scientificStatus === \"calibrated\" &&\n wavelengthBasis === \"unspecified\"\n ) {\n throw new InvalidConfigurationError(\n path +\n \" calibrated spectral material data requires an air or vacuum wavelength basis.\"\n );\n }\n if (\n scientificStatus === \"calibrated\" &&\n uncertainty.kind !== \"relative\"\n ) {\n throw new InvalidConfigurationError(\n path +\n \" calibrated spectral material data requires quantified relative uncertainty.\"\n );\n }\n if (\n record.wavelengthChangingBehaviorModeled !==\n false\n ) {\n throw new InvalidConfigurationError(\n path +\n \".wavelengthChangingBehaviorModeled must be false in schema 0.1.0.\"\n );\n }\n if (record.emissionModeled !== false) {\n throw new InvalidConfigurationError(\n path +\n \".emissionModeled must be false in schema 0.1.0.\"\n );\n }\n\n return {\n kind:\n \"spectral-wavelength-preserving-data\",\n dataArtifact: parseArtifact(\n record.dataArtifact,\n path + \".dataArtifact\"\n ),\n wavelengthBasis,\n wavelengthRangeNanometers:\n parseSpectralWavelengthRangeNanometers(\n record.wavelengthRangeNanometers,\n path + \".wavelengthRangeNanometers\"\n ),\n scatteringModel:\n \"provider-defined-wavelength-preserving\",\n scientificStatus,\n uncertainty,\n wavelengthChangingBehaviorModeled:\n false,\n emissionModeled: false\n };\n}\n\n/**\n * Parses material-response metadata used by a scene-radiance provider.\n *\n * RGB or PBR (physically based rendering) material data is always an approximation.\n * Spectral data is a per-wavelength provider input. It does not itself compute a BSDF\n * (how a surface scatters light), scene radiance, fluorescence, emission, volumetric\n * effects or polarization.\n */\nexport function parseSceneMaterialResponseProfile(\n value: unknown\n): SceneMaterialResponseProfile {\n const record = requireRecord(\n value,\n \"sceneMaterialResponseProfile\", [\"schemaVersion\", \"materials\", \"fluorescenceModeled\", \"volumetricMaterialTransportModeled\", \"polarizationModeled\", \"profileId\", \"sceneId\", \"evidence\"]\n );\n if (\n record.schemaVersion !==\n SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneMaterialResponseProfile.schemaVersion must be \"' +\n SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION +\n '\".'\n );\n }\n if (!Array.isArray(record.materials)) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.materials must be an array.\"\n );\n }\n\n const materials = record.materials.map(\n (entry, index) => {\n const path =\n \"sceneMaterialResponseProfile.materials[\" +\n index +\n \"]\";\n const material = requireRecord(\n entry,\n path, [\"materialResponseId\", \"evidence\", \"representation\"]\n );\n return {\n materialResponseId:\n requireNonEmptyString(\n material.materialResponseId,\n path + \".materialResponseId\"\n ),\n evidence: parseEvidenceList(\n material.evidence,\n path + \".evidence\"\n ),\n representation:\n parseMaterialRepresentation(\n material.representation,\n path + \".representation\"\n )\n };\n }\n );\n const ids = materials.map(\n (entry) => entry.materialResponseId\n );\n if (new Set(ids).size !== ids.length) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.materials[].materialResponseId must not contain duplicates.\"\n );\n }\n\n if (record.fluorescenceModeled !== false) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.fluorescenceModeled must be false in schema 0.1.0.\"\n );\n }\n if (\n record.volumetricMaterialTransportModeled !==\n false\n ) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.volumetricMaterialTransportModeled must be false in schema 0.1.0.\"\n );\n }\n if (record.polarizationModeled !== false) {\n throw new InvalidConfigurationError(\n \"sceneMaterialResponseProfile.polarizationModeled must be false in schema 0.1.0.\"\n );\n }\n\n return {\n schemaVersion:\n SCENE_MATERIAL_RESPONSE_PROFILE_SCHEMA_VERSION,\n profileId: requireNonEmptyString(\n record.profileId,\n \"sceneMaterialResponseProfile.profileId\"\n ),\n sceneId: requireNonEmptyString(\n record.sceneId,\n \"sceneMaterialResponseProfile.sceneId\"\n ),\n evidence: parseEvidenceList(\n record.evidence,\n \"sceneMaterialResponseProfile.evidence\"\n ),\n materials,\n fluorescenceModeled: false,\n volumetricMaterialTransportModeled:\n false,\n polarizationModeled: false\n };\n}\n\n/**\n * Returns the material fidelity a profile supports, choosing the lower level when in doubt.\n */\nexport function assessSceneMaterialResponseFidelity(\n profile: SceneMaterialResponseProfile\n): SceneMaterialResponseFidelity {\n requireInputObject(profile, \"assessSceneMaterialResponseFidelity input\");\n // 2.0.0: the whole profile is validated, so an unknown field at any level is rejected.\n parseSceneMaterialResponseProfile(profile);\n requireInputArray(profile.materials, \"profile.materials\");\n if (\n profile.materials.some(\n (entry) =>\n entry.representation.kind ===\n \"unresolved\"\n )\n ) {\n return \"unresolved\";\n }\n\n const kinds = new Set(\n profile.materials.map(\n (entry) => entry.representation.kind\n )\n );\n if (\n kinds.size === 0 ||\n kinds.has(\"unresolved\")\n ) {\n return \"unresolved\";\n }\n if (\n kinds.size === 1 &&\n kinds.has(\n \"spectral-wavelength-preserving-data\"\n )\n ) {\n return \"spectral-data\";\n }\n if (\n kinds.size === 1 &&\n kinds.has(\"rgb-pbr-approximation\")\n ) {\n return \"rgb-pbr-approximation\";\n }\n return \"mixed\";\n}\n\nfunction parseProviderFidelity(\n value: unknown,\n path: string\n): SceneRadianceProviderProfile[\"fidelity\"] {\n const record = requireRecord(value, path, [\"spectral\", \"material\", \"visibility\", \"directTransport\", \"indirectTransport\"]);\n const spectral = record.spectral;\n if (\n spectral !== \"wavelength-resolved\" &&\n spectral !==\n \"rgb-derived-approximation\"\n ) {\n throw new InvalidConfigurationError(\n path + \".spectral is invalid.\"\n );\n }\n const material = record.material;\n if (\n material !== \"spectral-data\" &&\n material !== \"rgb-pbr-approximation\" &&\n material !== \"mixed\" &&\n material !== \"unresolved\"\n ) {\n throw new InvalidConfigurationError(\n path + \".material is invalid.\"\n );\n }\n const parseVisibility = (\n candidate: unknown,\n candidatePath: string\n ): SceneRadianceProviderVisibilityFidelity => {\n if (\n candidate !== \"resolved\" &&\n candidate !== \"approximation\" &&\n candidate !== \"not-modeled\"\n ) {\n throw new InvalidConfigurationError(\n candidatePath + \" is invalid.\"\n );\n }\n return candidate;\n };\n const parseTransport = (\n candidate: unknown,\n candidatePath: string\n ): SceneRadianceProviderTransportFidelity => {\n if (\n candidate !== \"resolved\" &&\n candidate !== \"approximation\" &&\n candidate !== \"not-modeled\"\n ) {\n throw new InvalidConfigurationError(\n candidatePath + \" is invalid.\"\n );\n }\n return candidate;\n };\n\n return {\n spectral,\n material,\n visibility: parseVisibility(\n record.visibility,\n path + \".visibility\"\n ),\n directTransport: parseTransport(\n record.directTransport,\n path + \".directTransport\"\n ),\n indirectTransport: parseTransport(\n record.indirectTransport,\n path + \".indirectTransport\"\n )\n };\n}\n\n/**\n * Parses a provider's declaration of what it can do (its profile). Works with any renderer.\n *\n * Schema 0.1.0 is approximation-only by design. A provider may use calibrated inputs,\n * but this contract cannot support a claim of calibrated outgoing radiance. That needs\n * later work on complete spectral and light-transport models.\n */\nexport function parseSceneRadianceProviderProfile(\n value: unknown\n): SceneRadianceProviderProfile {\n const record = requireRecord(\n value,\n \"sceneRadianceProviderProfile\", [\"schemaVersion\", \"outputQuantity\", \"outputUnit\", \"scientificStatus\", \"wavelengthChangingTransportModeled\", \"volumetricTransportModeled\", \"polarizationModeled\", \"profileId\", \"sceneId\", \"illuminationProfileId\", \"illuminationTemporalProfileId\", \"materialResponseProfileId\", \"uncertainty\", \"fidelity\", \"evidence\", \"limitations\"]\n );\n if (\n record.schemaVersion !==\n SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceProviderProfile.schemaVersion must be \"' +\n SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION +\n '\".'\n );\n }\n if (\n record.outputQuantity !==\n \"outgoing-spectral-radiance\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceProviderProfile.outputQuantity must be \"outgoing-spectral-radiance\".'\n );\n }\n if (record.outputUnit !== \"W/m^2/sr/nm\") {\n throw new InvalidConfigurationError(\n 'sceneRadianceProviderProfile.outputUnit must be \"W/m^2/sr/nm\".'\n );\n }\n if (\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceProviderProfile.scientificStatus must be \"approximation\" in schema 0.1.0.'\n );\n }\n if (\n record.wavelengthChangingTransportModeled !==\n false ||\n record.volumetricTransportModeled !==\n false ||\n record.polarizationModeled !== false\n ) {\n throw new InvalidConfigurationError(\n \"sceneRadianceProviderProfile wavelength-changing, volumetric, and polarization transport flags must all be false in schema 0.1.0.\"\n );\n }\n\n return {\n schemaVersion:\n SCENE_RADIANCE_PROVIDER_PROFILE_SCHEMA_VERSION,\n profileId: requireNonEmptyString(\n record.profileId,\n \"sceneRadianceProviderProfile.profileId\"\n ),\n sceneId: requireNonEmptyString(\n record.sceneId,\n \"sceneRadianceProviderProfile.sceneId\"\n ),\n illuminationProfileId:\n requireNonEmptyString(\n record.illuminationProfileId,\n \"sceneRadianceProviderProfile.illuminationProfileId\"\n ),\n ...(record.illuminationTemporalProfileId ===\n undefined\n ? {}\n : {\n illuminationTemporalProfileId:\n requireNonEmptyString(\n record.illuminationTemporalProfileId,\n \"sceneRadianceProviderProfile.illuminationTemporalProfileId\"\n )\n }),\n materialResponseProfileId:\n requireNonEmptyString(\n record.materialResponseProfileId,\n \"sceneRadianceProviderProfile.materialResponseProfileId\"\n ),\n outputQuantity:\n \"outgoing-spectral-radiance\",\n outputUnit: \"W/m^2/sr/nm\",\n scientificStatus: \"approximation\",\n uncertainty: parseUncertainty(\n record.uncertainty,\n \"sceneRadianceProviderProfile.uncertainty\"\n ),\n fidelity: parseProviderFidelity(\n record.fidelity,\n \"sceneRadianceProviderProfile.fidelity\"\n ),\n wavelengthChangingTransportModeled:\n false,\n volumetricTransportModeled: false,\n polarizationModeled: false,\n evidence: parseEvidenceList(\n record.evidence,\n \"sceneRadianceProviderProfile.evidence\"\n ),\n limitations: parseLimitations(\n record.limitations,\n \"sceneRadianceProviderProfile.limitations\"\n )\n };\n}\n\nfunction parsePositiveWavelengthNanometers(\n value: unknown,\n path: string\n): number {\n const wavelength = requireFinite(\n value,\n path\n );\n if (wavelength <= 0) {\n throw new InvalidConfigurationError(\n path + \" must be greater than zero.\"\n );\n }\n return wavelength;\n}\n\nfunction parseResolvedWavelengthBasis(\n value: unknown,\n path: string\n): Exclude<\n SpectralWavelengthBasis,\n \"unspecified\"\n> {\n const basis = parseSpectralWavelengthBasis(\n value,\n path\n );\n if (basis === \"unspecified\") {\n throw new InvalidConfigurationError(\n path +\n \" must be air or vacuum for outgoing spectral radiance.\"\n );\n }\n return basis;\n}\n\nfunction parseEvaluationTarget(\n value: unknown,\n path: string\n): SceneRadianceEvaluationTarget {\n const record = requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", {\n \"surface-point\": [\"kind\", \"sceneObjectId\", \"materialResponseId\", \"positionM\", \"outgoingDirectionUnitVector\"],\n \"environment-direction\": [\"kind\", \"outgoingDirectionUnitVector\"]\n }, path);\n if (record.kind === \"surface-point\") {\n return {\n kind: \"surface-point\",\n sceneObjectId: requireNonEmptyString(\n record.sceneObjectId,\n path + \".sceneObjectId\"\n ),\n materialResponseId:\n requireNonEmptyString(\n record.materialResponseId,\n path + \".materialResponseId\"\n ),\n positionM: parseVector3(\n record.positionM,\n path + \".positionM\"\n ),\n outgoingDirectionUnitVector:\n parseUnitDirection(\n record.outgoingDirectionUnitVector,\n path +\n \".outgoingDirectionUnitVector\"\n )\n };\n }\n if (\n record.kind ===\n \"environment-direction\"\n ) {\n return {\n kind: \"environment-direction\",\n outgoingDirectionUnitVector:\n parseUnitDirection(\n record.outgoingDirectionUnitVector,\n path +\n \".outgoingDirectionUnitVector\"\n )\n };\n }\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n}\n\n/**\n * Parses one provider evaluation request at an explicit scene target,\n * physical time, wavelength, and outgoing direction.\n */\nexport function parseSceneRadianceEvaluationRequest(\n value: unknown\n): SceneRadianceEvaluationRequest {\n const record = requireRecord(\n value,\n \"sceneRadianceEvaluationRequest\", [\"schemaVersion\", \"sampleId\", \"providerProfileId\", \"sceneId\", \"illuminationProfileId\", \"materialResponseProfileId\", \"target\", \"timeSecondsFromExposureStart\", \"wavelengthNanometers\", \"wavelengthBasis\"]\n );\n if (\n record.schemaVersion !==\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationRequest.schemaVersion must be \"' +\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION +\n '\".'\n );\n }\n\n return {\n schemaVersion:\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION,\n sampleId: requireNonEmptyString(\n record.sampleId,\n \"sceneRadianceEvaluationRequest.sampleId\"\n ),\n providerProfileId:\n requireNonEmptyString(\n record.providerProfileId,\n \"sceneRadianceEvaluationRequest.providerProfileId\"\n ),\n sceneId: requireNonEmptyString(\n record.sceneId,\n \"sceneRadianceEvaluationRequest.sceneId\"\n ),\n illuminationProfileId:\n requireNonEmptyString(\n record.illuminationProfileId,\n \"sceneRadianceEvaluationRequest.illuminationProfileId\"\n ),\n materialResponseProfileId:\n requireNonEmptyString(\n record.materialResponseProfileId,\n \"sceneRadianceEvaluationRequest.materialResponseProfileId\"\n ),\n target: parseEvaluationTarget(\n record.target,\n \"sceneRadianceEvaluationRequest.target\"\n ),\n timeSecondsFromExposureStart:\n requireNonNegativeFinite(\n record.timeSecondsFromExposureStart,\n \"sceneRadianceEvaluationRequest.timeSecondsFromExposureStart\"\n ),\n wavelengthNanometers:\n parsePositiveWavelengthNanometers(\n record.wavelengthNanometers,\n \"sceneRadianceEvaluationRequest.wavelengthNanometers\"\n ),\n wavelengthBasis:\n parseResolvedWavelengthBasis(\n record.wavelengthBasis,\n \"sceneRadianceEvaluationRequest.wavelengthBasis\"\n )\n };\n}\n\n/**\n * Parses one outgoing spectral-radiance result from a provider.\n *\n * The number is accepted as the provider reported it. Parsing checks units, that the\n * value is finite and nonnegative, provenance and identity fields. It does not prove\n * the provider's light-transport calculation is physically correct.\n */\nexport function parseSceneRadianceEvaluationResult(\n value: unknown\n): SceneRadianceEvaluationResult {\n const record = requireRecord(\n value,\n \"sceneRadianceEvaluationResult\", SCENE_RADIANCE_EVALUATION_RESULT_KEYS\n );\n return parseSceneRadianceEvaluationResultRecord(record, undefined);\n}\n\nconst SCENE_RADIANCE_EVALUATION_RESULT_KEYS = [\"schemaVersion\", \"quantity\", \"unit\", \"scientificStatus\", \"sampleId\", \"providerProfileId\", \"sceneId\", \"wavelengthNanometers\", \"wavelengthBasis\", \"spectralRadianceWattsPerSquareMeterSteradianNanometer\", \"uncertainty\", \"evidence\", \"limitations\"] as const;\n\n/** An earlier fully parsed result whose deep-frozen uncertainty, evidence and limitations records may be reused. */\nexport interface ValidatedSceneRadianceRecords {\n readonly uncertainty: unknown;\n readonly evidence: unknown;\n readonly limitations: unknown;\n readonly parsed: SceneRadianceEvaluationResult;\n}\n\n/**\n * Internal (2.6; not exported from the package): parses a result of an engine-built evaluator\n * (`isInternalSceneRadianceEvaluator`). It runs every check of `parseSceneRadianceEvaluationResult` with the same\n * helpers, order and messages (object shape, schema version, quantity, unit, status, the three identifiers, the\n * wavelength, its basis and the radiance value) except two: the scan for unknown keys, and re-parsing uncertainty,\n * evidence and limitations when they are the very (deep-frozen) objects of `validated`, an earlier result that\n * passed the full parse. Any other result takes the full parse.\n */\nexport function parseSceneRadianceEvaluationResultWithValidatedRecords(\n value: unknown,\n validated: ValidatedSceneRadianceRecords\n): SceneRadianceEvaluationResult {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return parseSceneRadianceEvaluationResult(value);\n const record = value as UnknownRecord;\n if (record.uncertainty !== validated.uncertainty || record.evidence !== validated.evidence || record.limitations !== validated.limitations) {\n return parseSceneRadianceEvaluationResult(value);\n }\n return parseSceneRadianceEvaluationResultRecord(record, validated.parsed);\n}\n\nfunction parseSceneRadianceEvaluationResultRecord(\n record: UnknownRecord,\n validated: SceneRadianceEvaluationResult | undefined\n): SceneRadianceEvaluationResult {\n if (\n record.schemaVersion !==\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationResult.schemaVersion must be \"' +\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION +\n '\".'\n );\n }\n if (\n record.quantity !==\n \"outgoing-spectral-radiance\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationResult.quantity must be \"outgoing-spectral-radiance\".'\n );\n }\n if (record.unit !== \"W/m^2/sr/nm\") {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationResult.unit must be \"W/m^2/sr/nm\".'\n );\n }\n if (\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceEvaluationResult.scientificStatus must be \"approximation\" in schema 0.1.0.'\n );\n }\n\n return {\n schemaVersion:\n SCENE_RADIANCE_EVALUATION_SCHEMA_VERSION,\n sampleId: requireNonEmptyString(\n record.sampleId,\n \"sceneRadianceEvaluationResult.sampleId\"\n ),\n providerProfileId:\n requireNonEmptyString(\n record.providerProfileId,\n \"sceneRadianceEvaluationResult.providerProfileId\"\n ),\n sceneId: requireNonEmptyString(\n record.sceneId,\n \"sceneRadianceEvaluationResult.sceneId\"\n ),\n wavelengthNanometers:\n parsePositiveWavelengthNanometers(\n record.wavelengthNanometers,\n \"sceneRadianceEvaluationResult.wavelengthNanometers\"\n ),\n wavelengthBasis:\n parseResolvedWavelengthBasis(\n record.wavelengthBasis,\n \"sceneRadianceEvaluationResult.wavelengthBasis\"\n ),\n quantity:\n \"outgoing-spectral-radiance\",\n unit: \"W/m^2/sr/nm\",\n spectralRadianceWattsPerSquareMeterSteradianNanometer:\n requireNonNegativeFinite(\n record.spectralRadianceWattsPerSquareMeterSteradianNanometer,\n \"sceneRadianceEvaluationResult.spectralRadianceWattsPerSquareMeterSteradianNanometer\"\n ),\n scientificStatus: \"approximation\",\n uncertainty: validated ? validated.uncertainty : parseUncertainty(\n record.uncertainty,\n \"sceneRadianceEvaluationResult.uncertainty\"\n ),\n evidence: validated ? validated.evidence : parseEvidenceList(\n record.evidence,\n \"sceneRadianceEvaluationResult.evidence\"\n ),\n limitations: validated ? validated.limitations : parseLimitations(\n record.limitations,\n \"sceneRadianceEvaluationResult.limitations\"\n )\n };\n}\n\nfunction requireEqual(\n actual: unknown,\n expected: unknown,\n message: string\n): void {\n if (actual !== expected) {\n throw new InvalidConfigurationError(\n message\n );\n }\n}\n\n/**\n * Checks that a provider result matches its request and profile identities exactly.\n *\n * It never recomputes the radiance value, and never upgrades the provider's\n * approximation to calibrated radiometry.\n */\nexport function validateSceneRadianceEvaluationBindings(\n input:\n ValidateSceneRadianceEvaluationBindingsInput\n): SceneRadianceEvaluationBindingAssessment {\n requireInputKeys(input, \"validateSceneRadianceEvaluationBindings\", [\"providerProfile\", \"illuminationProfile\", \"illuminationTemporalProfile\", \"materialResponseProfile\", \"request\", \"result\"]);\n const {\n providerProfile,\n illuminationProfile,\n illuminationTemporalProfile,\n materialResponseProfile,\n request,\n result\n } = input;\n\n requireInputObject(providerProfile, \"providerProfile input\");\n requireEqual(\n providerProfile.sceneId,\n illuminationProfile.sceneId,\n \"Provider and illumination profiles must reference the same sceneId.\"\n );\n requireEqual(\n providerProfile.sceneId,\n materialResponseProfile.sceneId,\n \"Provider and material-response profiles must reference the same sceneId.\"\n );\n requireEqual(\n providerProfile.illuminationProfileId,\n illuminationProfile.profileId,\n \"Provider illuminationProfileId must match the supplied illumination profile.\"\n );\n requireEqual(\n providerProfile.materialResponseProfileId,\n materialResponseProfile.profileId,\n \"Provider materialResponseProfileId must match the supplied material-response profile.\"\n );\n\n if (\n providerProfile\n .illuminationTemporalProfileId ===\n undefined\n ) {\n if (\n illuminationTemporalProfile !==\n undefined\n ) {\n throw new InvalidConfigurationError(\n \"A temporal illumination profile was supplied but the provider profile does not bind one.\"\n );\n }\n } else {\n if (\n illuminationTemporalProfile ===\n undefined\n ) {\n throw new InvalidConfigurationError(\n \"Provider illuminationTemporalProfileId requires the matching temporal illumination profile.\"\n );\n }\n requireEqual(\n providerProfile\n .illuminationTemporalProfileId,\n illuminationTemporalProfile\n .profileId,\n \"Provider illuminationTemporalProfileId must match the supplied temporal illumination profile.\"\n );\n requireEqual(\n providerProfile.sceneId,\n illuminationTemporalProfile.sceneId,\n \"Provider and temporal illumination profiles must reference the same sceneId.\"\n );\n requireEqual(\n providerProfile\n .illuminationProfileId,\n illuminationTemporalProfile\n .illuminationProfileId,\n \"Temporal illumination profile must bind the provider's illuminationProfileId.\"\n );\n }\n\n const materialResponseFidelity =\n assessSceneMaterialResponseFidelity(\n materialResponseProfile\n );\n requireEqual(\n providerProfile.fidelity.material,\n materialResponseFidelity,\n \"Provider material fidelity must match the supplied material-response profile.\"\n );\n\n requireEqual(\n request.providerProfileId,\n providerProfile.profileId,\n \"Request providerProfileId must match the supplied provider profile.\"\n );\n requireEqual(\n request.sceneId,\n providerProfile.sceneId,\n \"Request sceneId must match the supplied provider profile.\"\n );\n requireEqual(\n request.illuminationProfileId,\n illuminationProfile.profileId,\n \"Request illuminationProfileId must match the supplied illumination profile.\"\n );\n requireEqual(\n request.materialResponseProfileId,\n materialResponseProfile.profileId,\n \"Request materialResponseProfileId must match the supplied material-response profile.\"\n );\n\n if (request.target.kind === \"surface-point\") {\n const target = request.target;\n if (\n !materialResponseProfile.materials.some(\n (material) =>\n material.materialResponseId ===\n target.materialResponseId\n )\n ) {\n throw new InvalidConfigurationError(\n \"Request surface target materialResponseId is not declared by the supplied material-response profile.\"\n );\n }\n }\n\n requireEqual(\n result.sampleId,\n request.sampleId,\n \"Result sampleId must match the request.\"\n );\n requireEqual(\n result.providerProfileId,\n request.providerProfileId,\n \"Result providerProfileId must match the request.\"\n );\n requireEqual(\n result.sceneId,\n request.sceneId,\n \"Result sceneId must match the request.\"\n );\n requireEqual(\n result.wavelengthNanometers,\n request.wavelengthNanometers,\n \"Result wavelengthNanometers must match the request exactly.\"\n );\n requireEqual(\n result.wavelengthBasis,\n request.wavelengthBasis,\n \"Result wavelengthBasis must match the request.\"\n );\n\n return {\n providerBindingsMatched: true,\n requestResultIdentityMatched: true,\n materialResponseFidelity,\n temporalIlluminationProfileBound:\n illuminationTemporalProfile !==\n undefined,\n calibratedRadianceClaimAuthorized: false,\n sensorPlaneIrradianceCalculated:\n false,\n opticsApplied: false,\n photonsCalculated: false\n };\n}\n"]}
|
|
@@ -346,6 +346,18 @@ type DeterministicRandom = DeterministicUniformStream;
|
|
|
346
346
|
* draw exactly as simulateSensorChargeRealization does; not exported from the package.
|
|
347
347
|
*/
|
|
348
348
|
export declare function samplePoisson(mean: number, random: DeterministicRandom): number;
|
|
349
|
+
/**
|
|
350
|
+
* Internal (not exported from the package): `samplePoisson` for one fixed mean, with the per-mean constants (e^(−mean),
|
|
351
|
+
* the PTRS constants and ln mean) computed once. Each draw takes the same branch, reads the same random values and
|
|
352
|
+
* forms every value with the same expressions as `samplePoisson(mean, random)`, so the draws are identical; it is for
|
|
353
|
+
* callers that draw many times with one mean (the display view's AHD correction).
|
|
354
|
+
*
|
|
355
|
+
* With `portable` true, every exponential, logarithm and normal draw uses the engine's portable functions
|
|
356
|
+
* (`portableExp`, `portableLog`, `samplePortableStandardNormal`) instead of Math.exp, Math.log and the Box–Muller of
|
|
357
|
+
* Math.log/Math.cos, so the draws are the same in every JavaScript engine; they then equal `samplePoisson`'s except
|
|
358
|
+
* where a comparison falls within the last-bit difference of those functions. The display view uses this form.
|
|
359
|
+
*/
|
|
360
|
+
export declare function createPoissonSampler(mean: number, portable?: boolean): (random: DeterministicRandom) => number;
|
|
349
361
|
/**
|
|
350
362
|
* Internal (not exported from the package): draws `count` Poisson samples of one mean from one seeded
|
|
351
363
|
* stream, exactly as the charge realization does. Used by the sampler's distribution tests.
|
|
@@ -22,7 +22,8 @@ import { approximationResult } from "../core/calculation-result.js";
|
|
|
22
22
|
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
23
23
|
import { parseEvidenceList } from "../core/evidence-provenance.js";
|
|
24
24
|
import { InvalidScientificInputError } from "../core/validation.js";
|
|
25
|
-
import { createDeterministicUniformStream, sampleDeterministicStandardNormal } from "./stochastic-seed.js";
|
|
25
|
+
import { createDeterministicUniformStream, sampleDeterministicStandardNormal, samplePortableStandardNormal } from "./stochastic-seed.js";
|
|
26
|
+
import { portableExp, portableLog } from "../core/portable-math.js";
|
|
26
27
|
import { requireInputKeys, rejectUnknownFields } from "../core/record-validation.js";
|
|
27
28
|
import { evaluateParsedFixedPatternSite, parseSensorFixedPatternNoiseProfile } from "./fixed-pattern-noise.js";
|
|
28
29
|
export const SENSOR_CHARGE_SAMPLING_PROFILE_SCHEMA_VERSION = "0.1.0";
|
|
@@ -513,22 +514,31 @@ function additionalPolicyMap(profile, charge) {
|
|
|
513
514
|
function createRandom(seedUint32) {
|
|
514
515
|
return createDeterministicUniformStream(seedUint32);
|
|
515
516
|
}
|
|
517
|
+
/**
|
|
518
|
+
* log(n!) for n < 256: entry n is ln 2 + ln 3 + … + ln n, summed in that order, so each entry
|
|
519
|
+
* is bit-identical to summing the logarithms on demand (the partial sums of one loop).
|
|
520
|
+
*/
|
|
521
|
+
const SMALL_LOG_FACTORIALS = (() => {
|
|
522
|
+
const table = new Float64Array(256);
|
|
523
|
+
let sum = 0;
|
|
524
|
+
for (let value = 2; value < 256; value += 1) {
|
|
525
|
+
sum += Math.log(value);
|
|
526
|
+
table[value] = sum;
|
|
527
|
+
}
|
|
528
|
+
return table;
|
|
529
|
+
})();
|
|
516
530
|
/**
|
|
517
531
|
* Computes log(n!) without forming the factorial, which would overflow. Small counts
|
|
518
|
-
* sum the logarithms directly
|
|
519
|
-
* correction terms 1/(12n) - 1/(360n³). This is internal
|
|
520
|
-
* sampler; it is not a claim about physical accuracy or uncertainty.
|
|
532
|
+
* sum the logarithms directly (read from a table of the same partial sums). Larger counts
|
|
533
|
+
* use Stirling's formula with the correction terms 1/(12n) - 1/(360n³). This is internal
|
|
534
|
+
* to the Poisson rejection sampler; it is not a claim about physical accuracy or uncertainty.
|
|
521
535
|
*/
|
|
522
536
|
function logFactorial(n) {
|
|
523
537
|
if (n < 2) {
|
|
524
538
|
return 0;
|
|
525
539
|
}
|
|
526
540
|
if (n < 256) {
|
|
527
|
-
|
|
528
|
-
for (let value = 2; value <= n; value += 1) {
|
|
529
|
-
sum += Math.log(value);
|
|
530
|
-
}
|
|
531
|
-
return sum;
|
|
541
|
+
return SMALL_LOG_FACTORIALS[n];
|
|
532
542
|
}
|
|
533
543
|
const inverse = 1 / n;
|
|
534
544
|
const inverseCubed = inverse * inverse * inverse;
|
|
@@ -632,6 +642,118 @@ export function samplePoisson(mean, random) {
|
|
|
632
642
|
}
|
|
633
643
|
}
|
|
634
644
|
}
|
|
645
|
+
/** log(n!) as `logFactorial` computes it, with the portable logarithm (`portableLog`) in place of Math.log. */
|
|
646
|
+
let portableSmallLogFactorials;
|
|
647
|
+
function portableLogFactorial(n) {
|
|
648
|
+
if (n < 2)
|
|
649
|
+
return 0;
|
|
650
|
+
if (n < 256) {
|
|
651
|
+
if (!portableSmallLogFactorials) {
|
|
652
|
+
const table = new Float64Array(256);
|
|
653
|
+
let sum = 0;
|
|
654
|
+
for (let value = 2; value < 256; value += 1) {
|
|
655
|
+
sum += portableLog(value);
|
|
656
|
+
table[value] = sum;
|
|
657
|
+
}
|
|
658
|
+
portableSmallLogFactorials = table;
|
|
659
|
+
}
|
|
660
|
+
return portableSmallLogFactorials[n];
|
|
661
|
+
}
|
|
662
|
+
const inverse = 1 / n, inverseCubed = inverse * inverse * inverse;
|
|
663
|
+
// 0.5·ln(2π), as logFactorial forms it; computed on first use, so a bundle without the portable sampler need not evaluate it.
|
|
664
|
+
portableHalfLogTwoPi ??= 0.5 * portableLog(2 * Math.PI);
|
|
665
|
+
return (n + 0.5) * portableLog(n) - n + portableHalfLogTwoPi + inverse / 12 - inverseCubed / 360;
|
|
666
|
+
}
|
|
667
|
+
let portableHalfLogTwoPi;
|
|
668
|
+
/**
|
|
669
|
+
* Internal (not exported from the package): `samplePoisson` for one fixed mean, with the per-mean constants (e^(−mean),
|
|
670
|
+
* the PTRS constants and ln mean) computed once. Each draw takes the same branch, reads the same random values and
|
|
671
|
+
* forms every value with the same expressions as `samplePoisson(mean, random)`, so the draws are identical; it is for
|
|
672
|
+
* callers that draw many times with one mean (the display view's AHD correction).
|
|
673
|
+
*
|
|
674
|
+
* With `portable` true, every exponential, logarithm and normal draw uses the engine's portable functions
|
|
675
|
+
* (`portableExp`, `portableLog`, `samplePortableStandardNormal`) instead of Math.exp, Math.log and the Box–Muller of
|
|
676
|
+
* Math.log/Math.cos, so the draws are the same in every JavaScript engine; they then equal `samplePoisson`'s except
|
|
677
|
+
* where a comparison falls within the last-bit difference of those functions. The display view uses this form.
|
|
678
|
+
*/
|
|
679
|
+
export function createPoissonSampler(mean, portable = false) {
|
|
680
|
+
if (!Number.isFinite(mean) ||
|
|
681
|
+
mean < 0) {
|
|
682
|
+
throw new InvalidScientificInputError("Poisson mean must be finite and nonnegative.");
|
|
683
|
+
}
|
|
684
|
+
if (mean === 0) {
|
|
685
|
+
return () => 0;
|
|
686
|
+
}
|
|
687
|
+
const exp = portable ? portableExp : Math.exp, log = portable ? portableLog : Math.log;
|
|
688
|
+
const logFactorialOf = portable ? portableLogFactorial : logFactorial;
|
|
689
|
+
if (mean >=
|
|
690
|
+
POISSON_NORMAL_APPROXIMATION_MINIMUM_MEAN) {
|
|
691
|
+
if (!portable)
|
|
692
|
+
return (random) => samplePoisson(mean, random);
|
|
693
|
+
const sqrtMean = Math.sqrt(mean);
|
|
694
|
+
return (random) => Math.max(0, Math.floor(mean + sqrtMean * samplePortableStandardNormal(random) + 0.5));
|
|
695
|
+
}
|
|
696
|
+
if (mean < 30) {
|
|
697
|
+
const threshold = exp(-mean);
|
|
698
|
+
return (random) => {
|
|
699
|
+
let product = 1;
|
|
700
|
+
let count = 0;
|
|
701
|
+
do {
|
|
702
|
+
count += 1;
|
|
703
|
+
product *=
|
|
704
|
+
random.next();
|
|
705
|
+
} while (product > threshold);
|
|
706
|
+
return count - 1;
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
const sqrtMean = Math.sqrt(mean);
|
|
710
|
+
const b = 0.931 +
|
|
711
|
+
2.53 * sqrtMean;
|
|
712
|
+
const a = -0.059 +
|
|
713
|
+
0.02483 * b;
|
|
714
|
+
const inverseAlpha = 1.1239 +
|
|
715
|
+
1.1328 /
|
|
716
|
+
(b - 3.4);
|
|
717
|
+
const vR = 0.9277 -
|
|
718
|
+
3.6224 /
|
|
719
|
+
(b - 2);
|
|
720
|
+
const logMean = log(mean);
|
|
721
|
+
return (random) => {
|
|
722
|
+
for (;;) {
|
|
723
|
+
const u = random.next() - 0.5;
|
|
724
|
+
const v = random.next();
|
|
725
|
+
const uS = 0.5 - Math.abs(u);
|
|
726
|
+
if (uS <= 0) {
|
|
727
|
+
continue;
|
|
728
|
+
}
|
|
729
|
+
const k = Math.floor((2 * a / uS + b) *
|
|
730
|
+
u +
|
|
731
|
+
mean +
|
|
732
|
+
0.43);
|
|
733
|
+
if (uS >= 0.07 &&
|
|
734
|
+
v <= vR &&
|
|
735
|
+
k >= 0) {
|
|
736
|
+
return k;
|
|
737
|
+
}
|
|
738
|
+
if (k < 0 ||
|
|
739
|
+
(uS < 0.013 &&
|
|
740
|
+
v > uS)) {
|
|
741
|
+
continue;
|
|
742
|
+
}
|
|
743
|
+
const lhs = log(v *
|
|
744
|
+
inverseAlpha /
|
|
745
|
+
(a /
|
|
746
|
+
(uS * uS) +
|
|
747
|
+
b));
|
|
748
|
+
const rhs = -mean +
|
|
749
|
+
k * logMean -
|
|
750
|
+
logFactorialOf(k);
|
|
751
|
+
if (lhs <= rhs) {
|
|
752
|
+
return k;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
}
|
|
635
757
|
/**
|
|
636
758
|
* Internal (not exported from the package): draws `count` Poisson samples of one mean from one seeded
|
|
637
759
|
* stream, exactly as the charge realization does. Used by the sampler's distribution tests.
|