@photivra/engine 2.19.0 → 2.21.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.
Files changed (242) hide show
  1. package/CHANGELOG.md +289 -1
  2. package/CITATION.cff +1 -1
  3. package/NODE_SUPPORT.md +7 -5
  4. package/README.md +7 -6
  5. package/SECURITY.md +1 -1
  6. package/THIRD_PARTY.md +21 -10
  7. package/dist/capture/dng-lens-correction-opcodes.d.ts +32 -0
  8. package/dist/capture/dng-lens-correction-opcodes.js +119 -0
  9. package/dist/capture/dng-lens-correction-opcodes.js.map +1 -0
  10. package/dist/capture/exposure-build-up-stage.d.ts +16 -0
  11. package/dist/capture/exposure-build-up-stage.js +4 -0
  12. package/dist/capture/exposure-build-up-stage.js.map +1 -0
  13. package/dist/capture/native-environment-lean.d.ts +2 -1
  14. package/dist/capture/native-environment-lean.js +42 -78
  15. package/dist/capture/native-environment-lean.js.map +1 -1
  16. package/dist/capture/native-environment-tabulated.js +4 -3
  17. package/dist/capture/native-environment-tabulated.js.map +1 -1
  18. package/dist/capture/native-raw-dng.d.ts +6 -0
  19. package/dist/capture/native-raw-dng.js +16 -2
  20. package/dist/capture/native-raw-dng.js.map +1 -1
  21. package/dist/capture/native-raw.d.ts +3 -2
  22. package/dist/capture/native-raw.js +5 -4
  23. package/dist/capture/native-raw.js.map +1 -1
  24. package/dist/capture/sensor-raw-producer.d.ts +4 -1
  25. package/dist/capture/sensor-raw-producer.js +15 -8
  26. package/dist/capture/sensor-raw-producer.js.map +1 -1
  27. package/dist/core/shared-helpers.d.ts +2 -0
  28. package/dist/core/shared-helpers.js +4 -0
  29. package/dist/core/shared-helpers.js.map +1 -1
  30. package/dist/core/version.d.ts +1 -1
  31. package/dist/core/version.js +1 -1
  32. package/dist/core/version.js.map +1 -1
  33. package/dist/equipment/generic-lens-catalogue.d.ts +11 -4
  34. package/dist/equipment/generic-lens-catalogue.js +49 -7
  35. package/dist/equipment/generic-lens-catalogue.js.map +1 -1
  36. package/dist/equipment/generic-tier-assets.d.ts +32 -0
  37. package/dist/equipment/generic-tier-assets.js +18 -14
  38. package/dist/equipment/generic-tier-assets.js.map +1 -1
  39. package/dist/equipment/generic-tier-presets.js +2 -3
  40. package/dist/equipment/generic-tier-presets.js.map +1 -1
  41. package/dist/equipment/sensor-profile-body.d.ts +78 -0
  42. package/dist/equipment/sensor-profile-body.js +77 -0
  43. package/dist/equipment/sensor-profile-body.js.map +1 -0
  44. package/dist/equipment/sensor-profiles.d.ts +8 -0
  45. package/dist/equipment/sensor-profiles.js +82 -0
  46. package/dist/equipment/sensor-profiles.js.map +1 -0
  47. package/dist/facade/catalogue-lens-signal.d.ts +2 -2
  48. package/dist/facade/catalogue-lens-signal.js +58 -71
  49. package/dist/facade/catalogue-lens-signal.js.map +1 -1
  50. package/dist/facade/chart-radiance-batch.js +2 -1
  51. package/dist/facade/chart-radiance-batch.js.map +1 -1
  52. package/dist/facade/defocus-image-space-provider.d.ts +7 -0
  53. package/dist/facade/defocus-image-space-provider.js +64 -76
  54. package/dist/facade/defocus-image-space-provider.js.map +1 -1
  55. package/dist/facade/display-view-gpu-session.js +2 -0
  56. package/dist/facade/display-view-gpu-session.js.map +1 -1
  57. package/dist/facade/display-view-gpu.d.ts +13 -5
  58. package/dist/facade/display-view-gpu.js +4 -4
  59. package/dist/facade/display-view-gpu.js.map +1 -1
  60. package/dist/facade/display-view-lens-signal.d.ts +1 -1
  61. package/dist/facade/display-view-lens-signal.js +30 -26
  62. package/dist/facade/display-view-lens-signal.js.map +1 -1
  63. package/dist/facade/display-view.d.ts +3 -1
  64. package/dist/facade/display-view.js +6 -24
  65. package/dist/facade/display-view.js.map +1 -1
  66. package/dist/facade/expected-signal-setup.d.ts +3 -1
  67. package/dist/facade/expected-signal-setup.js +1 -1
  68. package/dist/facade/expected-signal-setup.js.map +1 -1
  69. package/dist/facade/expected-signal.d.ts +47 -14
  70. package/dist/facade/expected-signal.js +117 -112
  71. package/dist/facade/expected-signal.js.map +1 -1
  72. package/dist/facade/exposure-build-up.d.ts +70 -0
  73. package/dist/facade/exposure-build-up.js +164 -0
  74. package/dist/facade/exposure-build-up.js.map +1 -0
  75. package/dist/facade/fast-methods.d.ts +50 -0
  76. package/dist/facade/fast-methods.js +58 -0
  77. package/dist/facade/fast-methods.js.map +1 -0
  78. package/dist/facade/fast-resolution.d.ts +12 -0
  79. package/dist/facade/fast-resolution.js +18 -0
  80. package/dist/facade/fast-resolution.js.map +1 -0
  81. package/dist/facade/generic-lens-capture.d.ts +5 -4
  82. package/dist/facade/generic-lens-capture.js +5 -4
  83. package/dist/facade/generic-lens-capture.js.map +1 -1
  84. package/dist/facade/image-plane-enable.d.ts +7 -0
  85. package/dist/facade/image-plane-enable.js +17 -0
  86. package/dist/facade/image-plane-enable.js.map +1 -0
  87. package/dist/facade/image-plane-lattice-data.d.ts +6 -0
  88. package/dist/facade/image-plane-lattice-data.js +10 -0
  89. package/dist/facade/image-plane-lattice-data.js.map +1 -0
  90. package/dist/facade/image-plane-support.d.ts +33 -0
  91. package/dist/facade/image-plane-support.js +11 -0
  92. package/dist/facade/image-plane-support.js.map +1 -0
  93. package/dist/facade/image-plane.d.ts +36 -0
  94. package/dist/facade/image-plane.js +353 -0
  95. package/dist/facade/image-plane.js.map +1 -0
  96. package/dist/facade/mixed-illumination.d.ts +108 -0
  97. package/dist/facade/mixed-illumination.js +174 -0
  98. package/dist/facade/mixed-illumination.js.map +1 -0
  99. package/dist/facade/representative-light-sources.d.ts +72 -0
  100. package/dist/facade/representative-light-sources.js +124 -0
  101. package/dist/facade/representative-light-sources.js.map +1 -0
  102. package/dist/facade/scene-radiance.d.ts +129 -4
  103. package/dist/facade/scene-radiance.js +48 -13
  104. package/dist/facade/scene-radiance.js.map +1 -1
  105. package/dist/facade/simulate-capture.d.ts +88 -19
  106. package/dist/facade/simulate-capture.js +374 -145
  107. package/dist/facade/simulate-capture.js.map +1 -1
  108. package/dist/facade/simulate-display-view.d.ts +3 -2
  109. package/dist/facade/simulate-display-view.js +36 -18
  110. package/dist/facade/simulate-display-view.js.map +1 -1
  111. package/dist/gpu/chart-composite-gpu.d.ts +13 -1
  112. package/dist/gpu/chart-composite-gpu.js +48 -9
  113. package/dist/gpu/chart-composite-gpu.js.map +1 -1
  114. package/dist/gpu/chart-radiance-gpu.js +4 -30
  115. package/dist/gpu/chart-radiance-gpu.js.map +1 -1
  116. package/dist/gpu/display-view-composite-material-module.d.ts +10 -4
  117. package/dist/gpu/display-view-composite-material-module.js +39 -13
  118. package/dist/gpu/display-view-composite-material-module.js.map +1 -1
  119. package/dist/gpu/display-view-image-material-module.d.ts +86 -0
  120. package/dist/gpu/display-view-image-material-module.js +339 -0
  121. package/dist/gpu/display-view-image-material-module.js.map +1 -0
  122. package/dist/gpu/display-view-image-quality.d.ts +45 -0
  123. package/dist/gpu/display-view-image-quality.js +380 -0
  124. package/dist/gpu/display-view-image-quality.js.map +1 -0
  125. package/dist/gpu/display-view-quality-gpu.d.ts +67 -1
  126. package/dist/gpu/display-view-quality-gpu.js +136 -205
  127. package/dist/gpu/display-view-quality-gpu.js.map +1 -1
  128. package/dist/gpu/display-view-speed-gpu.d.ts +51 -3
  129. package/dist/gpu/display-view-speed-gpu.js +131 -93
  130. package/dist/gpu/display-view-speed-gpu.js.map +1 -1
  131. package/dist/gpu/wgsl-display-view-quality-kernel.d.ts +29 -15
  132. package/dist/gpu/wgsl-display-view-quality-kernel.js +58 -36
  133. package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -1
  134. package/dist/gpu/wgsl-display-view-speed-kernel.d.ts +21 -6
  135. package/dist/gpu/wgsl-display-view-speed-kernel.js +46 -11
  136. package/dist/gpu/wgsl-display-view-speed-kernel.js.map +1 -1
  137. package/dist/gpu/wgsl-exact-sum.d.ts +20 -0
  138. package/dist/gpu/wgsl-exact-sum.js +42 -0
  139. package/dist/gpu/wgsl-exact-sum.js.map +1 -0
  140. package/dist/index.d.ts +18 -3
  141. package/dist/index.js +12 -1
  142. package/dist/index.js.map +1 -1
  143. package/dist/motion/subject-motion.d.ts +66 -0
  144. package/dist/motion/subject-motion.js +52 -0
  145. package/dist/motion/subject-motion.js.map +1 -0
  146. package/dist/optics/aperture-diameter.d.ts +47 -0
  147. package/dist/optics/aperture-diameter.js +50 -0
  148. package/dist/optics/aperture-diameter.js.map +1 -0
  149. package/dist/optics/detail-limit.d.ts +182 -0
  150. package/dist/optics/detail-limit.js +336 -0
  151. package/dist/optics/detail-limit.js.map +1 -0
  152. package/dist/optics/generic-lens-lateral-color.d.ts +83 -0
  153. package/dist/optics/generic-lens-lateral-color.js +77 -0
  154. package/dist/optics/generic-lens-lateral-color.js.map +1 -0
  155. package/dist/optics/generic-lens-psf.d.ts +18 -2
  156. package/dist/optics/generic-lens-psf.js +79 -48
  157. package/dist/optics/generic-lens-psf.js.map +1 -1
  158. package/dist/optics/lens-psf-profile.d.ts +7 -0
  159. package/dist/optics/lens-psf-profile.js +2 -1
  160. package/dist/optics/lens-psf-profile.js.map +1 -1
  161. package/dist/optics/scene-to-sensor-irradiance.d.ts +13 -0
  162. package/dist/optics/scene-to-sensor-irradiance.js +7 -0
  163. package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
  164. package/dist/output/crop-to-match-focal-length.d.ts +62 -0
  165. package/dist/output/crop-to-match-focal-length.js +63 -0
  166. package/dist/output/crop-to-match-focal-length.js.map +1 -0
  167. package/dist/output/developed-lens-corrections.d.ts +19 -5
  168. package/dist/output/developed-lens-corrections.js +30 -11
  169. package/dist/output/developed-lens-corrections.js.map +1 -1
  170. package/dist/output/generic-lens-corrections.d.ts +41 -3
  171. package/dist/output/generic-lens-corrections.js +57 -9
  172. package/dist/output/generic-lens-corrections.js.map +1 -1
  173. package/dist/output/lens-corrections.d.ts +12 -2
  174. package/dist/output/lens-corrections.js +22 -7
  175. package/dist/output/lens-corrections.js.map +1 -1
  176. package/dist/output/print-contrast-reference.js +1 -1
  177. package/dist/output/print-contrast-reference.js.map +1 -1
  178. package/dist/output/print-plan.d.ts +41 -5
  179. package/dist/output/print-plan.js +59 -14
  180. package/dist/output/print-plan.js.map +1 -1
  181. package/dist/output/print-size-blur-noise.d.ts +110 -0
  182. package/dist/output/print-size-blur-noise.js +138 -0
  183. package/dist/output/print-size-blur-noise.js.map +1 -0
  184. package/dist/sensor/binomial-sample.d.ts +3 -0
  185. package/dist/sensor/binomial-sample.js +86 -0
  186. package/dist/sensor/binomial-sample.js.map +1 -0
  187. package/dist/sensor/eqe-electron-rate.js +1 -7
  188. package/dist/sensor/eqe-electron-rate.js.map +1 -1
  189. package/dist/sensor/exposure-window.d.ts +2 -0
  190. package/dist/sensor/exposure-window.js +2 -2
  191. package/dist/sensor/exposure-window.js.map +1 -1
  192. package/dist/sensor/readout-timing.js +2 -23
  193. package/dist/sensor/readout-timing.js.map +1 -1
  194. package/dist/sensor/response-application-compatibility.js +1 -6
  195. package/dist/sensor/response-application-compatibility.js.map +1 -1
  196. package/dist/sensor/responsivity-photocurrent.js +1 -7
  197. package/dist/sensor/responsivity-photocurrent.js.map +1 -1
  198. package/dist/sensor/sensor-characteristics.d.ts +147 -0
  199. package/dist/sensor/sensor-characteristics.js +126 -0
  200. package/dist/sensor/sensor-characteristics.js.map +1 -0
  201. package/dist/sensor/spatial-sample-reduction.js +1 -5
  202. package/dist/sensor/spatial-sample-reduction.js.map +1 -1
  203. package/dist/sensor/spectral-quadrature.js +1 -6
  204. package/dist/sensor/spectral-quadrature.js.map +1 -1
  205. package/dist/sensor/temporal-photo-signal.d.ts +3 -0
  206. package/dist/sensor/temporal-photo-signal.js +5 -2
  207. package/dist/sensor/temporal-photo-signal.js.map +1 -1
  208. package/dist/stabilization/system.d.ts +9 -0
  209. package/dist/stabilization/system.js +5 -6
  210. package/dist/stabilization/system.js.map +1 -1
  211. package/docs/AGENT_GUIDE.md +5 -0
  212. package/docs/API_REFERENCE.md +173 -2
  213. package/docs/QUICK_START.md +213 -6
  214. package/docs/USAGE.md +157 -3
  215. package/docs/api/capture-native-raw-dng.md +6 -0
  216. package/docs/api/core-version.md +1 -1
  217. package/docs/api/equipment-generic-lens-catalogue.md +17 -7
  218. package/docs/api/equipment-sensor-profile-body.md +64 -0
  219. package/docs/api/equipment-sensor-profiles.md +86 -0
  220. package/docs/api/exports.json +357 -2
  221. package/docs/api/facade-display-view-gpu.md +5 -2
  222. package/docs/api/facade-exposure-build-up.md +105 -0
  223. package/docs/api/facade-fast-methods.md +99 -0
  224. package/docs/api/facade-image-plane-enable.md +16 -0
  225. package/docs/api/facade-mixed-illumination.md +67 -0
  226. package/docs/api/facade-representative-light-sources.md +131 -0
  227. package/docs/api/facade-scene-radiance.md +54 -3
  228. package/docs/api/facade-simulate-capture.md +60 -15
  229. package/docs/api/facade-simulate-display-view.md +3 -2
  230. package/docs/api/motion-subject-motion.md +23 -0
  231. package/docs/api/optics-aperture-diameter.md +51 -0
  232. package/docs/api/optics-detail-limit.md +203 -0
  233. package/docs/api/optics-generic-lens-lateral-color.md +79 -0
  234. package/docs/api/output-crop-to-match-focal-length.md +67 -0
  235. package/docs/api/output-developed-lens-corrections.md +10 -1
  236. package/docs/api/output-generic-lens-corrections.md +40 -2
  237. package/docs/api/output-lens-corrections.md +11 -1
  238. package/docs/api/output-print-plan.md +35 -1
  239. package/docs/api/output-print-size-blur-noise.md +115 -0
  240. package/docs/api/sensor-sensor-characteristics.md +105 -0
  241. package/llms.txt +6 -0
  242. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"generic-tier-assets.js","sourceRoot":"","sources":["../../src/equipment/generic-tier-assets.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Synthetic catalog data, owned by the project, for generic camera tiers. Bodies (capabilities and\n * readout) and lenses (optical and correction profiles) are defined separately.\n *\n * Choosing a tier changes explicit profile values. It never applies a universal quality multiplier.\n * The caller still supplies the CFA (colour filter array) and light-collection geometry and the\n * actual capture raster. The numbers are not measured calibration.\n * @see docs/RELEASE_1_0.md and the corresponding domain guide.\n */\n\nimport type { EvidenceBackedFact, EvidenceProvenance } from \"../core/evidence-provenance.js\";\nimport { parseGenericBodyExposureCapabilityProfile, parseGenericLensExposureCapabilityProfile,\n type GenericBodyExposureCapabilityProfile, type GenericLensExposureCapabilityProfile } from \"./exposure-capabilities.js\";\nimport { parseIsoCapabilityProfile, type IsoCapabilityProfile } from \"./iso-capabilities.js\";\nimport { parseGenericReleaseCapabilityProfile, type GenericReleaseCapabilityProfile } from \"./release-capabilities.js\";\nimport { parseFocusControlProfile, type FocusControlProfile } from \"../capture/focus-control.js\";\nimport { parseWhiteBalanceProfile, type WhiteBalanceProfile } from \"../color/white-balance.js\";\nimport { parseStabilizationSystemProfile, type StabilizationSystemProfile } from \"../stabilization/system.js\";\nimport { parseSensorReadoutConversionProfile, type SensorReadoutConversionProfile } from \"../sensor/raw-readout.js\";\nimport { parseGenericIsoSignalChainProfile, type GenericIsoSignalChainProfile } from \"../sensor/iso-signal-chain.js\";\nimport { parseExposureMeteringProfile, type ExposureMeteringProfile } from \"../exposure/metering.js\";\nimport { parseGenericBodyMeteringCapabilityProfile, type GenericBodyMeteringCapabilityProfile } from \"./metering-capabilities.js\";\nimport { parseFlashSyncCapabilityProfile, type FlashSyncCapabilityProfile } from \"../exposure/flash.js\";\nimport type { SensorReadoutTimingDeclaration } from \"../sensor/readout-timing.js\";\nimport { createIsoGainReadoutRegimes } from \"../sensor/iso-gain.js\";\nimport { parseSensorFixedPatternNoiseProfile, type SensorFixedPatternNoiseProfile } from \"../sensor/fixed-pattern-noise.js\";\n\nexport type GenericEquipmentTier = \"consumer\" | \"prosumer\" | \"professional\";\nexport interface GenericVersionedAsset<T> { assetId: string; assetVersion: string; profile: T }\nexport interface GenericTierBodyAssets {\n exposure: GenericBodyExposureCapabilityProfile;\n iso: IsoCapabilityProfile;\n signalChain: GenericIsoSignalChainProfile;\n readout: readonly GenericVersionedAsset<SensorReadoutConversionProfile>[];\n /** Global data readout (no skew across the frame). The default timing asset. */\n readoutTiming: GenericVersionedAsset<SensorReadoutTimingDeclaration>;\n /** Optional rolling readout variant, with an explicit top-to-bottom skew across the frame. */\n rollingReadoutTiming: GenericVersionedAsset<SensorReadoutTimingDeclaration>;\n /** Optional synthetic fixed-pattern noise for this body. Never applied unless a caller attaches it. */\n fixedPatternNoise: GenericVersionedAsset<SensorFixedPatternNoiseProfile>;\n release: GenericReleaseCapabilityProfile;\n focus: FocusControlProfile;\n stabilization: StabilizationSystemProfile;\n whiteBalance: WhiteBalanceProfile;\n metering: readonly GenericVersionedAsset<ExposureMeteringProfile>[];\n meteringCapabilities: GenericBodyMeteringCapabilityProfile;\n flashSync: FlashSyncCapabilityProfile;\n}\nexport interface GenericTierLensAssets {\n form: \"prime\";\n exposure: GenericLensExposureCapabilityProfile;\n /** Explicit synthetic coefficients, not measured calibration or a quality score. */\n matchedReference: {\n focalLengthMm: 50; aperture: 4; focusDistanceM: 5; wavelengthNm: 550;\n normalizationRadiusMm: number;\n distortionK1: number; lateralCaK1Offset: number; vignettingR2: number;\n breathingProjectionScale: number; transmission: number;\n correctionGainStrength: number; correctionCaFraction: number;\n ghostPowerFraction: number; veilPowerFraction: number;\n pupilAmplitudeByField: readonly (readonly number[])[];\n pupilOpdMicrometersByDefocus: readonly (readonly number[])[];\n pupilThroughputByField: readonly number[];\n };\n profileReferences: readonly { profileId: string; profileVersion: string }[];\n limitations: readonly string[];\n}\nexport interface GenericEquipmentTierPreset {\n tier: GenericEquipmentTier;\n label: \"Consumer\" | \"Prosumer\" | \"Professional\";\n presetId: string; presetVersion: GenericTierPresetVersion;\n scientificStatus: \"approximation\";\n evidence: readonly EvidenceProvenance[];\n body: GenericTierBodyAssets;\n lens: GenericTierLensAssets;\n tradeoffs: readonly string[];\n}\n\nconst evidence: readonly EvidenceProvenance[] = [{ sourceOrigin: \"photivra\", sourceReference: \"photivra:generic-tier-assets-v1\",\n reuseStatus: \"photivra-owned\" }];\nconst limitations = [\"Synthetic educational design values; no named camera/lens calibration or population ranking.\"];\nconst fact = <T>(value: T): EvidenceBackedFact<T> => ({ value, evidence });\n/**\n * The exact versions of the generic tier presets (no \"latest\" alias). 2.1.0 (2.14, round 5) adds the third-stop ISO\n * settings; 2.0.0 is kept, whole-stop, so saved selections and records of it still resolve to exactly what they named.\n */\nexport type GenericTierPresetVersion = \"2.0.0\" | \"2.1.0\";\n/** Whole-stop ISO settings of the 2.0.0 bodies (each body's list stops at its maximum). */\nexport const GENERIC_WHOLE_STOP_ISO_SETTINGS = /* @__PURE__ */ Object.freeze([100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600] as const);\n/**\n * Third-stop ISO settings of the 2.1.0 bodies: the conventional rounded markings of S = 100·2^(k/3), k = 0 … 24 (125 for\n * 126.0, 160 for 158.7 …; each within 2 % of the exact value). The engine takes the setting as the exact ISO speed.\n */\n/**\n * The standard third-stop shutter times, seconds, from 1/8000 s to 30 s: the conventional markings of t = 2^(k/3) s\n * (1/8000 for 2^−13, 1/6 for 2^−8/3, 0.3 for 2^−5/3, 30 for 2^5; each within 7 % of the exact value). The generic bodies'\n * shutters are continuous over 1/8000–30 s and take any time as exact, so these are the values to offer in a third-stop\n * dial, not a restriction.\n */\nexport const GENERIC_THIRD_STOP_SHUTTER_SECONDS = /* @__PURE__ */ Object.freeze([1 / 8000, 1 / 6400, 1 / 5000, 1 / 4000, 1 / 3200, 1 / 2500, 1 / 2000,\n 1 / 1600, 1 / 1250, 1 / 1000, 1 / 800, 1 / 640, 1 / 500, 1 / 400, 1 / 320, 1 / 250, 1 / 200, 1 / 160, 1 / 125, 1 / 100, 1 / 80, 1 / 60, 1 / 50, 1 / 40,\n 1 / 30, 1 / 25, 1 / 20, 1 / 15, 1 / 13, 1 / 10, 1 / 8, 1 / 6, 1 / 5, 1 / 4, 0.3, 0.4, 0.5, 0.6, 0.8, 1, 1.3, 1.6, 2, 2.5, 3.2, 4, 5, 6, 8, 10, 13,\n 15, 20, 25, 30] as const);\nexport const GENERIC_THIRD_STOP_ISO_SETTINGS = /* @__PURE__ */ Object.freeze([100, 125, 160, 200, 250, 320, 400, 500, 640, 800, 1000, 1250, 1600,\n 2000, 2500, 3200, 4000, 5000, 6400, 8000, 10000, 12800, 16000, 20000, 25600] as const);\nconst disk = [0,0,1,0,0, 0,1,1,1,0, 1,1,1,1,1, 0,1,1,1,0, 0,0,1,0,0];\nconst clipped = [0,0,1,0,0, 0,1,1,1,0, 0,1,1,1,1, 0,1,1,1,0, 0,0,1,0,0];\nconst clippedMore = [0,0,0,0,0, 0,0,1,1,0, 0,0,1,1,1, 0,0,1,1,0, 0,0,0,0,0];\nconst near = [0,0,.12,0,0, 0,.06,0,.06,0, .12,0,-.04,0,.12, 0,.06,0,.06,0, 0,0,.12,0,0];\nconst flat = Array<number>(25).fill(0);\nconst far = near.map((v) => -v);\n\n/**\n * Synthetic, educational sensor design values for each tier: ADC (analogue-to-digital converter),\n * saturation signal Q0 at base ISO, analogue gain range, read noise for each conversion-gain mode,\n * and fixed-pattern noise sizes. They are plausible orders of magnitude for consumer\n * interchangeable-lens sensors. They are not data from any real camera.\n */\ninterface SyntheticSensorDesign {\n bitDepth: number; blackLevelCode: number; saturationElectrons: number; maximumAnalogGain: number;\n lowGainReadNoise: number; highGainReadNoise: number; highGainFromIso: number; highGainMaximumCharge: number;\n prnu: number; dsnu: number; hotFraction: number; hotMultiplier: number; rowRms: number; columnRms: number; instanceSeed: number;\n}\n/** Used only to build data. Tier labels never enter any scientific equation. */\nfunction bodyAssets(version: GenericTierPresetVersion, id: string, isoMax: number, cadence: number, frames: number, sensor: SyntheticSensorDesign,\n dataReadoutSeconds: number, gain: number, maxAngle: number, continuousAf: boolean, advancedPolicies: boolean): GenericTierBodyAssets {\n const isoValues: number[] = (version === \"2.0.0\" ? GENERIC_WHOLE_STOP_ISO_SETTINGS : GENERIC_THIRD_STOP_ISO_SETTINGS).filter((v) => v <= isoMax);\n const exposure = parseGenericBodyExposureCapabilityProfile({ schemaVersion: \"0.1.0\", profileId: id+\":exposure\", profileVersion: version,\n scientificStatus: \"approximation\", evidence, shutter: { durationSecondsRange: fact({ minimum: 1/8000, maximum: 30 }), settingGrid: { kind: \"continuous-within-range\" } },\n iso: { range: fact({ minimum: 100, maximum: isoMax }), settingGrid: { kind: \"discrete-values\", values: fact(isoValues) }, autoIso: fact(\"supported\") } });\n const iso = parseIsoCapabilityProfile({ schemaVersion: \"0.1.0\", profileId: id+\":iso\", profileVersion: version,\n capabilityMeaning: \"reported-exposure-index-capability-not-physical-gain\", standard: { exposureIndexRange: { minimum: 100, maximum: isoMax },\n settingGrid: { kind: \"discrete-values\", values: isoValues } }, expandedSettings: [], autoIso: { availability: \"supported\", standardExposureIndexRange: { minimum: 100, maximum: isoMax }, evidence },\n captureModePolicies: [], evidence });\n const isoGain = createIsoGainReadoutRegimes({ regimeIdPrefix: \"\", scientificStatus: \"approximation\", baseExposureIndex: 100,\n exposureIndices: isoValues, baseSaturationElectronEquivalent: fact(sensor.saturationElectrons), maximumAnalogGain: fact(sensor.maximumAnalogGain),\n adc: { bitDepth: sensor.bitDepth, blackLevelCode: sensor.blackLevelCode, digitalSaturationCode: 2**sensor.bitDepth-1 },\n conversionGainModes: [{ mode: \"low-conversion-gain\", minimumExposureIndex: 100, readNoiseRmsElectrons: fact(sensor.lowGainReadNoise) },\n { mode: \"high-conversion-gain\", minimumExposureIndex: sensor.highGainFromIso, readNoiseRmsElectrons: fact(sensor.highGainReadNoise),\n maximumChargeElectrons: fact(sensor.highGainMaximumCharge) }],\n evidence, limitations: [...limitations, \"ISO gain follows the declared base-ISO saturation signal and analog range; read noise per conversion-gain mode is a synthetic design value.\"] });\n const readout = [\"red\", \"green\", \"blue\"].map((channelId): GenericVersionedAsset<SensorReadoutConversionProfile> => ({ assetId: id+\":readout:\"+channelId, assetVersion: version,\n profile: parseSensorReadoutConversionProfile({ schemaVersion: \"0.1.0\", profileId: id+\":readout\", colorSamplingProfileId: \"photivra-generic-bayer\", channelId,\n regimeSelectionOwnedBy: \"explicit-upstream-camera-state-not-inferred-from-iso\", evidence, regimes: isoGain.regimes }) }));\n const signalChain = parseGenericIsoSignalChainProfile({ schemaVersion: \"0.1.0\", profileId: id+\":signal-chain\", profileVersion: version,\n scientificStatus: \"approximation\", isoCapabilityProfileId: iso.profileId, readoutProfileId: id+\":readout\",\n behaviorMeaning: \"iso-state-selects-explicit-readout-regime-not-noise-equation\", captureModeBindings: [{ captureModeId: \"native-still\",\n standardRegimeBands: isoGain.standardRegimeBands, expandedRegimeBindings: [], evidence }],\n photonShotNoiseOwnedUpstream: true, processedImageBehaviorIncluded: false, fixedPatternNoiseModeled: false, lowSignalColorDegradationModeled: false,\n evidence, limitations });\n const release = parseGenericReleaseCapabilityProfile({ schemaVersion: \"0.1.0\", profileId: id+\":release\", profileVersion: version,\n scientificStatus: \"approximation\", evidence, supportedDriveModes: fact([\"single\", \"burst\", \"self-timer\"]), maximumLogicalFramesPerSequence: fact(frames),\n maximumCadenceFps: fact(cadence), minimumInterFrameGapSeconds: fact(0), overlappingOrdinaryStillExposures: false,\n exposureBracketing: { availability: fact(\"supported\"), supportedAxes: [\"shutter\", \"iso\"] }, focusBracketing: { availability: fact(\"unsupported\") } });\n const focus = parseFocusControlProfile({ schemaVersion: \"0.1.0\", profileId: id+\":focus\", profileVersion: version, scientificStatus: \"approximation\",\n supportedModes: continuousAf ? [\"manual\", \"single-af\", \"continuous-af\"] : [\"manual\", \"single-af\"], actuator: { kind: \"ideal-instantaneous\", evidence },\n continuousTargetLossPolicy: \"hold-last-focus-require-explicit-reacquisition\", supportedReleasePriorities: [\"focus-priority\", \"release-priority\", \"balanced\"],\n evidence, limitations: [...limitations, \"AF actuator speed and subject recognition are not tier performance claims.\"] });\n const stabilization = parseStabilizationSystemProfile({ schemaVersion: \"0.1.0\", profileId: id+\":stabilization\", profileVersion: version,\n profileKind: \"generic-synthetic\", scientificStatus: \"approximation\", architecture: \"sensor-shift\", captureKind: \"still\",\n axisResponses: [\"pitch\", \"yaw\", \"roll\"].map((axis) => ({ axis, correctionGain: fact(gain), latencySeconds: fact(.001), maximumCorrectionAngleRad: fact(maxAngle) })),\n panningPolicy: { kind: \"none\" }, controlTransientModeled: false, spontaneousDriftModeled: false, cameraTranslationCorrectionModeled: false,\n digitalStabilizationIncluded: false, supportPolicyIncluded: false, stopRatingUsedAsDynamicResponse: false, evidence, limitations });\n const whiteBalance = parseWhiteBalanceProfile({ schemaVersion: \"0.1.0\", profileId: id+\":white-balance\", profileVersion: version,\n scientificStatus: \"approximation\", inputDomain: \"relative-pre-wb-camera-linear-rgb\", presets: [{ presetId: \"neutral\", label: \"Neutral reference\",\n channelGains: fact({ red: 1, green: 1, blue: 1 }) }], awbPolicies: [\n { policyId: \"neutral-priority\", intent: \"neutral-priority\", correctionStrength: fact(1) },\n ...(advancedPolicies ? [{ policyId: \"ambience\", intent: \"ambience-preserving\", correctionStrength: fact(.5) }] : [])], evidence, limitations });\n const metering = [{ kind: \"multi-zone-uniform\" }, ...(advancedPolicies ? [{ kind: \"highlight-weighted\", minimumWeightFraction: .2, exponent: 2 }] : [])]\n .map((policy): GenericVersionedAsset<ExposureMeteringProfile> => ({ assetId: id+\":meter:\"+policy.kind, assetVersion: version,\n profile: parseExposureMeteringProfile({ schemaVersion: \"0.1.0\", profileId: id+\":meter:\"+policy.kind, scientificStatus: \"approximation\",\n inputDomain: \"relative-pre-exposure-linear-signal\", captureRegion: \"oriented-active-capture\", policy,\n target: { kind: \"relative-signal-reference\", targetRelativeSignal: .18, evidence }, evidence,\n limitations: [...limitations, \"0.18 is a declared target policy, not universal scene/camera truth.\"] }) }));\n const meteringCapabilities = parseGenericBodyMeteringCapabilityProfile({ schemaVersion: \"0.1.0\", profileId: id+\":metering-capabilities\", profileVersion: version,\n scientificStatus: \"approximation\", evidence, supportedMeteringProfiles: metering.map((m) => ({ meteringProfileId: m.profile.profileId, policyKind: m.profile.policy.kind, evidence })),\n spotFocusPointLinkage: { availability: \"unsupported\", evidence } });\n const timingId = id+\":data-readout\";\n const fixedPatternNoise = parseSensorFixedPatternNoiseProfile({ schemaVersion: \"0.1.0\", profileId: id+\":fixed-pattern\",\n colorSamplingProfileId: \"photivra-generic-bayer\", scientificStatus: \"approximation\", sensorInstanceSeedUint32: sensor.instanceSeed,\n photoResponseNonUniformity: { relativeStandardDeviation: fact(sensor.prnu) }, darkSignalNonUniformity: { relativeStandardDeviation: fact(sensor.dsnu) },\n hotPixels: { siteFraction: fact(sensor.hotFraction), darkCurrentMultiplier: fact(sensor.hotMultiplier) },\n rowOffset: { rmsElectrons: fact(sensor.rowRms) }, columnOffset: { rmsElectrons: fact(sensor.columnRms) },\n patternDistribution: \"normal-factors-truncated-at-zero\", evidence,\n limitations: [...limitations, \"Synthetic fixed-pattern magnitudes for teaching; opt-in only and not a measured sensor population.\"] });\n return { exposure, iso, signalChain, readout, release, focus, stabilization, whiteBalance, metering, meteringCapabilities,\n readoutTiming: { assetId: timingId, assetVersion: version, profile: { readoutMode: \"global\", captureReadoutDurationSeconds: {\n value: dataReadoutSeconds, unit: \"s\", evidence } } },\n rollingReadoutTiming: { assetId: id+\":rolling-data-readout\", assetVersion: version, profile: { readoutMode: \"rolling\",\n captureReadoutDurationSeconds: { value: dataReadoutSeconds, unit: \"s\", evidence }, scanDirectionNative: fact(\"top-to-bottom\"),\n spatialSamplingSkewSeconds: { value: dataReadoutSeconds, unit: \"s\", evidence } } },\n fixedPatternNoise: { assetId: id+\":fixed-pattern\", assetVersion: version, profile: fixedPatternNoise },\n flashSync: parseFlashSyncCapabilityProfile({ schemaVersion: \"0.1.0\", profileId: id+\":flash-sync\", profileVersion: version,\n captureModeId: \"native-still\", timingProfileId: timingId, supportedOrdinarySyncModes: [\"front-curtain\", \"rear-curtain\"],\n highSpeedSyncSupported: false, ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed: true, evidence, limitations }) };\n}\nfunction lensAssets(version: GenericTierPresetVersion, id: string, r: GenericTierLensAssets[\"matchedReference\"]): GenericTierLensAssets {\n return { form: \"prime\", exposure: parseGenericLensExposureCapabilityProfile({ schemaVersion: \"0.1.0\", profileId: id+\":exposure\", profileVersion: version,\n scientificStatus: \"approximation\", evidence, focalLengthMmRange: fact({ minimum: 50, maximum: 50 }), aperture: { widestAvailableFNumber: {\n kind: \"constant\", fNumber: fact(4) }, narrowestAvailableFNumber: fact(16), settingGrid: { kind: \"continuous-within-range\" } } }),\n matchedReference: r, profileReferences: [\"radial\", \"lateral-ca\", \"vignetting\", \"breathing\", \"transmission\", \"pupil\", \"stray\", \"correction\"]\n .map((role) => ({ profileId: id+\":\"+role, profileVersion: version })),\n limitations: [...limitations, \"Optical reference response is limited to 50 mm, f/4, focus 5 m and explicit field/defocus/wavelength slices; capabilities do not authorize extrapolation.\",\n \"The initial prime has no OIS; body stabilization is separate.\"] };\n}\nconst common = { focalLengthMm: 50 as const, aperture: 4 as const, focusDistanceM: 5 as const, wavelengthNm: 550 as const,\n normalizationRadiusMm: Math.hypot(18,12), correctionCaFraction: .8 };\nfunction buildGenericTierAssets(version: GenericTierPresetVersion): readonly GenericEquipmentTierPreset[] {\n return [\n { tier: \"consumer\", label: \"Consumer\", presetId: \"photivra-consumer\", presetVersion: version, scientificStatus: \"approximation\", evidence,\n body: bodyAssets(version, \"photivra-consumer-body\", 6400, 4, 8, { bitDepth: 12, blackLevelCode: 256, saturationElectrons: 20000,\n maximumAnalogGain: 32, lowGainReadNoise: 6, highGainReadNoise: 2.5, highGainFromIso: 800, highGainMaximumCharge: 6000,\n prnu: .01, dsnu: .3, hotFraction: 2e-4, hotMultiplier: 50, rowRms: .6, columnRms: .4, instanceSeed: 0x51ed270b }, .03, .35, .005, false, false),\n lens: lensAssets(version, \"photivra-consumer-prime\", { ...common, distortionK1: -.06, lateralCaK1Offset: .008, vignettingR2: -.5,\n breathingProjectionScale: 1.03, transmission: .75, correctionGainStrength: .8, ghostPowerFraction: .006, veilPowerFraction: .012,\n pupilAmplitudeByField: [disk, clipped, clippedMore], pupilOpdMicrometersByDefocus: [near, flat, far], pupilThroughputByField: [1,.85,.65] }),\n tradeoffs: [\"Limited continuous AF; heavier digital correction and edge pupil clipping in matched reference.\"] },\n { tier: \"prosumer\", label: \"Prosumer\", presetId: \"photivra-prosumer\", presetVersion: version, scientificStatus: \"approximation\", evidence,\n body: bodyAssets(version, \"photivra-prosumer-body\", 12800, 8, 16, { bitDepth: 14, blackLevelCode: 1024, saturationElectrons: 40000,\n maximumAnalogGain: 64, lowGainReadNoise: 3, highGainReadNoise: 1.4, highGainFromIso: 800, highGainMaximumCharge: 12000,\n prnu: .006, dsnu: .2, hotFraction: 1e-4, hotMultiplier: 40, rowRms: .3, columnRms: .2, instanceSeed: 0x2c1b3c6d }, .015, .65, .01, true, true),\n lens: lensAssets(version, \"photivra-prosumer-prime\", { ...common, distortionK1: -.025, lateralCaK1Offset: .004, vignettingR2: -.25,\n breathingProjectionScale: 1.015, transmission: .85, correctionGainStrength: .6, ghostPowerFraction: .003, veilPowerFraction: .006,\n pupilAmplitudeByField: [disk, disk, clipped], pupilOpdMicrometersByDefocus: [near.map((v)=>v*.7), flat, far.map((v)=>v*.7)], pupilThroughputByField: [1,.95,.85] }),\n tradeoffs: [\"Lower matched-reference peripheral gain/noise amplification than Professional; not universally inferior.\"] },\n { tier: \"professional\", label: \"Professional\", presetId: \"photivra-professional\", presetVersion: version, scientificStatus: \"approximation\", evidence,\n body: bodyAssets(version, \"photivra-professional-body\", 25600, 12, 24, { bitDepth: 14, blackLevelCode: 1024, saturationElectrons: 60000,\n maximumAnalogGain: 128, lowGainReadNoise: 2, highGainReadNoise: 1.1, highGainFromIso: 800, highGainMaximumCharge: 16000,\n prnu: .004, dsnu: .15, hotFraction: 5e-5, hotMultiplier: 30, rowRms: .15, columnRms: .1, instanceSeed: 0x6a09e667 }, .008, .85, .02, true, true),\n lens: lensAssets(version, \"photivra-professional-prime\", { ...common, distortionK1: -.01, lateralCaK1Offset: .002, vignettingR2: -.35,\n breathingProjectionScale: 1.005, transmission: .9, correctionGainStrength: .8, ghostPowerFraction: .001, veilPowerFraction: .002,\n pupilAmplitudeByField: [disk, disk, disk], pupilOpdMicrometersByDefocus: [near.map((v)=>v*.9), flat, far.map((v)=>v*.6)], pupilThroughputByField: [1,.98,.95] }),\n tradeoffs: [\"Less edge clipping/stray light, with greater f/4 falloff/gain cost than Prosumer and asymmetric near/far wavefront character.\"] }\n ];\n}\n\n/** The presets of the current version, 2.1.0 (third-stop ISO settings). */\nexport const GENERIC_TIER_ASSETS: readonly GenericEquipmentTierPreset[] = buildGenericTierAssets(\"2.1.0\");\nlet historical: readonly GenericEquipmentTierPreset[] | undefined;\n/** The presets of an exact version; 2.0.0 (whole-stop ISO) is built on first use. */\nexport function genericTierAssets(version: GenericTierPresetVersion): readonly GenericEquipmentTierPreset[] {\n if (version === \"2.1.0\") return GENERIC_TIER_ASSETS;\n return historical ??= buildGenericTierAssets(\"2.0.0\");\n}\n"]}
1
+ {"version":3,"file":"generic-tier-assets.js","sourceRoot":"","sources":["../../src/equipment/generic-tier-assets.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Synthetic catalog data, owned by the project, for generic camera tiers. Bodies (capabilities and\n * readout) and lenses (optical and correction profiles) are defined separately.\n *\n * Choosing a tier changes explicit profile values. It never applies a universal quality multiplier.\n * The caller still supplies the CFA (colour filter array) and light-collection geometry and the\n * actual capture raster. The numbers are not measured calibration.\n * @see docs/RELEASE_1_0.md and the corresponding domain guide.\n */\n\nimport type { EvidenceBackedFact, EvidenceProvenance } from \"../core/evidence-provenance.js\";\nimport { parseGenericBodyExposureCapabilityProfile, parseGenericLensExposureCapabilityProfile,\n type GenericBodyExposureCapabilityProfile, type GenericLensExposureCapabilityProfile } from \"./exposure-capabilities.js\";\nimport { parseIsoCapabilityProfile, type IsoCapabilityProfile } from \"./iso-capabilities.js\";\nimport { parseGenericReleaseCapabilityProfile, type GenericReleaseCapabilityProfile } from \"./release-capabilities.js\";\nimport { parseFocusControlProfile, type FocusControlProfile } from \"../capture/focus-control.js\";\nimport { parseWhiteBalanceProfile, type WhiteBalanceProfile } from \"../color/white-balance.js\";\nimport { parseStabilizationSystemProfile, STABILIZATION_UNMODELED_SCOPE, type StabilizationSystemProfile } from \"../stabilization/system.js\";\nimport { parseSensorReadoutConversionProfile, type SensorReadoutConversionProfile } from \"../sensor/raw-readout.js\";\nimport { parseGenericIsoSignalChainProfile, type GenericIsoSignalChainProfile } from \"../sensor/iso-signal-chain.js\";\nimport { parseExposureMeteringProfile, type ExposureMeteringProfile } from \"../exposure/metering.js\";\nimport { parseGenericBodyMeteringCapabilityProfile, type GenericBodyMeteringCapabilityProfile } from \"./metering-capabilities.js\";\nimport { parseFlashSyncCapabilityProfile, type FlashSyncCapabilityProfile } from \"../exposure/flash.js\";\nimport type { SensorReadoutTimingDeclaration } from \"../sensor/readout-timing.js\";\nimport { createIsoGainReadoutRegimes } from \"../sensor/iso-gain.js\";\nimport { parseSensorFixedPatternNoiseProfile, type SensorFixedPatternNoiseProfile } from \"../sensor/fixed-pattern-noise.js\";\n\nexport type GenericEquipmentTier = \"consumer\" | \"prosumer\" | \"professional\";\nexport interface GenericVersionedAsset<T> { assetId: string; assetVersion: string; profile: T }\nexport interface GenericTierBodyAssets {\n exposure: GenericBodyExposureCapabilityProfile;\n iso: IsoCapabilityProfile;\n signalChain: GenericIsoSignalChainProfile;\n readout: readonly GenericVersionedAsset<SensorReadoutConversionProfile>[];\n /** Global data readout (no skew across the frame). The default timing asset. */\n readoutTiming: GenericVersionedAsset<SensorReadoutTimingDeclaration>;\n /** Optional rolling readout variant, with an explicit top-to-bottom skew across the frame. */\n rollingReadoutTiming: GenericVersionedAsset<SensorReadoutTimingDeclaration>;\n /** Optional synthetic fixed-pattern noise for this body. Never applied unless a caller attaches it. */\n fixedPatternNoise: GenericVersionedAsset<SensorFixedPatternNoiseProfile>;\n release: GenericReleaseCapabilityProfile;\n focus: FocusControlProfile;\n stabilization: StabilizationSystemProfile;\n whiteBalance: WhiteBalanceProfile;\n metering: readonly GenericVersionedAsset<ExposureMeteringProfile>[];\n meteringCapabilities: GenericBodyMeteringCapabilityProfile;\n flashSync: FlashSyncCapabilityProfile;\n}\nexport interface GenericTierLensAssets {\n form: \"prime\";\n exposure: GenericLensExposureCapabilityProfile;\n /** Explicit synthetic coefficients, not measured calibration or a quality score. */\n matchedReference: {\n focalLengthMm: 50; aperture: 4; focusDistanceM: 5; wavelengthNm: 550;\n normalizationRadiusMm: number;\n distortionK1: number; lateralCaK1Offset: number; vignettingR2: number;\n breathingProjectionScale: number; transmission: number;\n correctionGainStrength: number; correctionCaFraction: number;\n ghostPowerFraction: number; veilPowerFraction: number;\n pupilAmplitudeByField: readonly (readonly number[])[];\n pupilOpdMicrometersByDefocus: readonly (readonly number[])[];\n pupilThroughputByField: readonly number[];\n };\n profileReferences: readonly { profileId: string; profileVersion: string }[];\n limitations: readonly string[];\n}\nexport interface GenericEquipmentTierPreset {\n tier: GenericEquipmentTier;\n label: \"Consumer\" | \"Prosumer\" | \"Professional\";\n presetId: string; presetVersion: GenericTierPresetVersion;\n scientificStatus: \"approximation\";\n evidence: readonly EvidenceProvenance[];\n body: GenericTierBodyAssets;\n lens: GenericTierLensAssets;\n tradeoffs: readonly string[];\n}\n\nconst tierEvidence: readonly EvidenceProvenance[] = [{ sourceOrigin: \"photivra\", sourceReference: \"photivra:generic-tier-assets-v1\",\n reuseStatus: \"photivra-owned\" }];\nconst tierLimitations = [\"Synthetic educational design values; no named camera/lens calibration or population ranking.\"];\nconst evidence = tierEvidence, limitations = tierLimitations;\nconst fact = <T>(value: T): EvidenceBackedFact<T> => ({ value, evidence });\n/**\n * The exact versions of the generic tier presets (no \"latest\" alias). 2.1.0 (2.14, round 5) adds the third-stop ISO\n * settings; 2.0.0 is kept, whole-stop, so saved selections and records of it still resolve to exactly what they named.\n */\nexport type GenericTierPresetVersion = \"2.0.0\" | \"2.1.0\";\n/** Whole-stop ISO settings of the 2.0.0 bodies (each body's list stops at its maximum). */\nexport const GENERIC_WHOLE_STOP_ISO_SETTINGS = /* @__PURE__ */ Object.freeze([100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600] as const);\n/**\n * Third-stop ISO settings of the 2.1.0 bodies: the conventional rounded markings of S = 100·2^(k/3), k = 0 … 24 (125 for\n * 126.0, 160 for 158.7 …; each within 2 % of the exact value). The engine takes the setting as the exact ISO speed.\n */\n/**\n * The standard third-stop shutter times, seconds, from 1/8000 s to 30 s: the conventional markings of t = 2^(k/3) s\n * (1/8000 for 2^−13, 1/6 for 2^−8/3, 0.3 for 2^−5/3, 30 for 2^5; each within 7 % of the exact value). The generic bodies'\n * shutters are continuous over 1/8000–30 s and take any time as exact, so these are the values to offer in a third-stop\n * dial, not a restriction.\n */\nexport const GENERIC_THIRD_STOP_SHUTTER_SECONDS = /* @__PURE__ */ Object.freeze([1 / 8000, 1 / 6400, 1 / 5000, 1 / 4000, 1 / 3200, 1 / 2500, 1 / 2000,\n 1 / 1600, 1 / 1250, 1 / 1000, 1 / 800, 1 / 640, 1 / 500, 1 / 400, 1 / 320, 1 / 250, 1 / 200, 1 / 160, 1 / 125, 1 / 100, 1 / 80, 1 / 60, 1 / 50, 1 / 40,\n 1 / 30, 1 / 25, 1 / 20, 1 / 15, 1 / 13, 1 / 10, 1 / 8, 1 / 6, 1 / 5, 1 / 4, 0.3, 0.4, 0.5, 0.6, 0.8, 1, 1.3, 1.6, 2, 2.5, 3.2, 4, 5, 6, 8, 10, 13,\n 15, 20, 25, 30] as const);\nexport const GENERIC_THIRD_STOP_ISO_SETTINGS = /* @__PURE__ */ Object.freeze([100, 125, 160, 200, 250, 320, 400, 500, 640, 800, 1000, 1250, 1600,\n 2000, 2500, 3200, 4000, 5000, 6400, 8000, 10000, 12800, 16000, 20000, 25600] as const);\nconst disk = [0,0,1,0,0, 0,1,1,1,0, 1,1,1,1,1, 0,1,1,1,0, 0,0,1,0,0];\nconst clipped = [0,0,1,0,0, 0,1,1,1,0, 0,1,1,1,1, 0,1,1,1,0, 0,0,1,0,0];\nconst clippedMore = [0,0,0,0,0, 0,0,1,1,0, 0,0,1,1,1, 0,0,1,1,0, 0,0,0,0,0];\nconst near = [0,0,.12,0,0, 0,.06,0,.06,0, .12,0,-.04,0,.12, 0,.06,0,.06,0, 0,0,.12,0,0];\nconst flat = Array<number>(25).fill(0);\nconst far = near.map((v) => -v);\n\n/**\n * Synthetic, educational sensor design values for each tier: ADC (analogue-to-digital converter),\n * saturation signal Q0 at base ISO, analogue gain range, read noise for each conversion-gain mode,\n * and fixed-pattern noise sizes. They are plausible orders of magnitude for consumer\n * interchangeable-lens sensors. They are not data from any real camera.\n */\nexport interface SyntheticSensorDesign {\n bitDepth: number; blackLevelCode: number; saturationElectrons: number; maximumAnalogGain: number;\n /** #554: a high gain from above the top ISO (or equal read noise) is one conversion gain, `single-conversion-gain`. */\n lowGainReadNoise: number; highGainReadNoise: number; highGainFromIso: number; highGainMaximumCharge: number;\n prnu: number; dsnu: number; hotFraction: number; hotMultiplier: number; rowRms: number; columnRms: number; instanceSeed: number;\n}\n/** #554: a sensor profile's own ISO settings (base first) and provenance; the tiers use ISO 100 and their own. */\nexport interface GenericBodyAssetsSource { isoValues: readonly number[]; evidence: readonly EvidenceProvenance[]; limitations: readonly string[] }\n/** Used only to build data. Tier labels never enter any scientific equation. */\nexport function bodyAssets(version: GenericTierPresetVersion, id: string, isoMax: number, cadence: number, frames: number, sensor: SyntheticSensorDesign,\n dataReadoutSeconds: number, gain: number, maxAngle: number, continuousAf: boolean, advancedPolicies: boolean, source?: GenericBodyAssetsSource): GenericTierBodyAssets {\n const evidence = source?.evidence ?? tierEvidence, limitations = source?.limitations ?? tierLimitations;\n const fact = <T>(value: T): EvidenceBackedFact<T> => ({ value, evidence });\n const isoValues: number[] = source ? [...source.isoValues] : (version === \"2.0.0\" ? GENERIC_WHOLE_STOP_ISO_SETTINGS : GENERIC_THIRD_STOP_ISO_SETTINGS).filter((v) => v <= isoMax);\n const baseIso = isoValues[0]!, single = sensor.highGainFromIso > isoMax;\n const exposure = parseGenericBodyExposureCapabilityProfile({ schemaVersion: \"0.1.0\", profileId: id+\":exposure\", profileVersion: version,\n scientificStatus: \"approximation\", evidence, shutter: { durationSecondsRange: fact({ minimum: 1/8000, maximum: 30 }), settingGrid: { kind: \"continuous-within-range\" } },\n iso: { range: fact({ minimum: baseIso, maximum: isoMax }), settingGrid: { kind: \"discrete-values\", values: fact(isoValues) }, autoIso: fact(\"supported\") } });\n const iso = parseIsoCapabilityProfile({ schemaVersion: \"0.1.0\", profileId: id+\":iso\", profileVersion: version,\n capabilityMeaning: \"reported-exposure-index-capability-not-physical-gain\", standard: { exposureIndexRange: { minimum: baseIso, maximum: isoMax },\n settingGrid: { kind: \"discrete-values\", values: isoValues } }, expandedSettings: [], autoIso: { availability: \"supported\", standardExposureIndexRange: { minimum: baseIso, maximum: isoMax }, evidence },\n captureModePolicies: [], evidence });\n const isoGain = createIsoGainReadoutRegimes({ regimeIdPrefix: \"\", scientificStatus: \"approximation\", baseExposureIndex: baseIso,\n exposureIndices: isoValues, baseSaturationElectronEquivalent: fact(sensor.saturationElectrons), maximumAnalogGain: fact(sensor.maximumAnalogGain),\n adc: { bitDepth: sensor.bitDepth, blackLevelCode: sensor.blackLevelCode, digitalSaturationCode: 2**sensor.bitDepth-1 },\n conversionGainModes: single ? [{ mode: \"single-conversion-gain\", minimumExposureIndex: baseIso, readNoiseRmsElectrons: fact(sensor.lowGainReadNoise) }] :\n [{ mode: \"low-conversion-gain\", minimumExposureIndex: baseIso, readNoiseRmsElectrons: fact(sensor.lowGainReadNoise) },\n { mode: \"high-conversion-gain\", minimumExposureIndex: sensor.highGainFromIso, readNoiseRmsElectrons: fact(sensor.highGainReadNoise),\n maximumChargeElectrons: fact(sensor.highGainMaximumCharge) }],\n evidence, limitations: [...limitations, \"ISO gain follows the declared base-ISO saturation signal and analog range; read noise per conversion-gain mode is a synthetic design value.\"] });\n const readout = [\"red\", \"green\", \"blue\"].map((channelId): GenericVersionedAsset<SensorReadoutConversionProfile> => ({ assetId: id+\":readout:\"+channelId, assetVersion: version,\n profile: parseSensorReadoutConversionProfile({ schemaVersion: \"0.1.0\", profileId: id+\":readout\", colorSamplingProfileId: \"photivra-generic-bayer\", channelId,\n regimeSelectionOwnedBy: \"explicit-upstream-camera-state-not-inferred-from-iso\", evidence, regimes: isoGain.regimes }) }));\n const signalChain = parseGenericIsoSignalChainProfile({ schemaVersion: \"0.1.0\", profileId: id+\":signal-chain\", profileVersion: version,\n scientificStatus: \"approximation\", isoCapabilityProfileId: iso.profileId, readoutProfileId: id+\":readout\",\n behaviorMeaning: \"iso-state-selects-explicit-readout-regime-not-noise-equation\", captureModeBindings: [{ captureModeId: \"native-still\",\n standardRegimeBands: isoGain.standardRegimeBands, expandedRegimeBindings: [], evidence }],\n photonShotNoiseOwnedUpstream: true, processedImageBehaviorIncluded: false, fixedPatternNoiseModeled: false, lowSignalColorDegradationModeled: false,\n evidence, limitations });\n const release = parseGenericReleaseCapabilityProfile({ schemaVersion: \"0.1.0\", profileId: id+\":release\", profileVersion: version,\n scientificStatus: \"approximation\", evidence, supportedDriveModes: fact([\"single\", \"burst\", \"self-timer\"]), maximumLogicalFramesPerSequence: fact(frames),\n maximumCadenceFps: fact(cadence), minimumInterFrameGapSeconds: fact(0), overlappingOrdinaryStillExposures: false,\n exposureBracketing: { availability: fact(\"supported\"), supportedAxes: [\"shutter\", \"iso\"] }, focusBracketing: { availability: fact(\"unsupported\") } });\n const focus = parseFocusControlProfile({ schemaVersion: \"0.1.0\", profileId: id+\":focus\", profileVersion: version, scientificStatus: \"approximation\",\n supportedModes: continuousAf ? [\"manual\", \"single-af\", \"continuous-af\"] : [\"manual\", \"single-af\"], actuator: { kind: \"ideal-instantaneous\", evidence },\n continuousTargetLossPolicy: \"hold-last-focus-require-explicit-reacquisition\", supportedReleasePriorities: [\"focus-priority\", \"release-priority\", \"balanced\"],\n evidence, limitations: [...limitations, \"AF actuator speed and subject recognition are not tier performance claims.\"] });\n const stabilization = parseStabilizationSystemProfile({ schemaVersion: \"0.1.0\", profileId: id+\":stabilization\", profileVersion: version,\n profileKind: \"generic-synthetic\", scientificStatus: \"approximation\", architecture: \"sensor-shift\", captureKind: \"still\",\n axisResponses: [\"pitch\", \"yaw\", \"roll\"].map((axis) => ({ axis, correctionGain: fact(gain), latencySeconds: fact(.001), maximumCorrectionAngleRad: fact(maxAngle) })),\n panningPolicy: { kind: \"none\" }, ...STABILIZATION_UNMODELED_SCOPE, evidence, limitations });\n const whiteBalance = parseWhiteBalanceProfile({ schemaVersion: \"0.1.0\", profileId: id+\":white-balance\", profileVersion: version,\n scientificStatus: \"approximation\", inputDomain: \"relative-pre-wb-camera-linear-rgb\", presets: [{ presetId: \"neutral\", label: \"Neutral reference\",\n channelGains: fact({ red: 1, green: 1, blue: 1 }) }], awbPolicies: [\n { policyId: \"neutral-priority\", intent: \"neutral-priority\", correctionStrength: fact(1) },\n ...(advancedPolicies ? [{ policyId: \"ambience\", intent: \"ambience-preserving\", correctionStrength: fact(.5) }] : [])], evidence, limitations });\n const metering = [{ kind: \"multi-zone-uniform\" }, ...(advancedPolicies ? [{ kind: \"highlight-weighted\", minimumWeightFraction: .2, exponent: 2 }] : [])]\n .map((policy): GenericVersionedAsset<ExposureMeteringProfile> => ({ assetId: id+\":meter:\"+policy.kind, assetVersion: version,\n profile: parseExposureMeteringProfile({ schemaVersion: \"0.1.0\", profileId: id+\":meter:\"+policy.kind, scientificStatus: \"approximation\",\n inputDomain: \"relative-pre-exposure-linear-signal\", captureRegion: \"oriented-active-capture\", policy,\n target: { kind: \"relative-signal-reference\", targetRelativeSignal: .18, evidence }, evidence,\n limitations: [...limitations, \"0.18 is a declared target policy, not universal scene/camera truth.\"] }) }));\n const meteringCapabilities = parseGenericBodyMeteringCapabilityProfile({ schemaVersion: \"0.1.0\", profileId: id+\":metering-capabilities\", profileVersion: version,\n scientificStatus: \"approximation\", evidence, supportedMeteringProfiles: metering.map((m) => ({ meteringProfileId: m.profile.profileId, policyKind: m.profile.policy.kind, evidence })),\n spotFocusPointLinkage: { availability: \"unsupported\", evidence } });\n const timingId = id+\":data-readout\";\n const fixedPatternNoise = parseSensorFixedPatternNoiseProfile({ schemaVersion: \"0.1.0\", profileId: id+\":fixed-pattern\",\n colorSamplingProfileId: \"photivra-generic-bayer\", scientificStatus: \"approximation\", sensorInstanceSeedUint32: sensor.instanceSeed,\n photoResponseNonUniformity: { relativeStandardDeviation: fact(sensor.prnu) }, darkSignalNonUniformity: { relativeStandardDeviation: fact(sensor.dsnu) },\n hotPixels: { siteFraction: fact(sensor.hotFraction), darkCurrentMultiplier: fact(sensor.hotMultiplier) },\n rowOffset: { rmsElectrons: fact(sensor.rowRms) }, columnOffset: { rmsElectrons: fact(sensor.columnRms) },\n patternDistribution: \"normal-factors-truncated-at-zero\", evidence,\n limitations: [...limitations, \"Synthetic fixed-pattern magnitudes for teaching; opt-in only and not a measured sensor population.\"] });\n return { exposure, iso, signalChain, readout, release, focus, stabilization, whiteBalance, metering, meteringCapabilities,\n readoutTiming: { assetId: timingId, assetVersion: version, profile: { readoutMode: \"global\", captureReadoutDurationSeconds: {\n value: dataReadoutSeconds, unit: \"s\", evidence } } },\n rollingReadoutTiming: { assetId: id+\":rolling-data-readout\", assetVersion: version, profile: { readoutMode: \"rolling\",\n captureReadoutDurationSeconds: { value: dataReadoutSeconds, unit: \"s\", evidence }, scanDirectionNative: fact(\"top-to-bottom\"),\n spatialSamplingSkewSeconds: { value: dataReadoutSeconds, unit: \"s\", evidence } } },\n fixedPatternNoise: { assetId: id+\":fixed-pattern\", assetVersion: version, profile: fixedPatternNoise },\n flashSync: parseFlashSyncCapabilityProfile({ schemaVersion: \"0.1.0\", profileId: id+\":flash-sync\", profileVersion: version,\n captureModeId: \"native-still\", timingProfileId: timingId, supportedOrdinarySyncModes: [\"front-curtain\", \"rear-curtain\"],\n highSpeedSyncSupported: false, ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed: true, evidence, limitations }) };\n}\nfunction lensAssets(version: GenericTierPresetVersion, id: string, r: GenericTierLensAssets[\"matchedReference\"]): GenericTierLensAssets {\n return { form: \"prime\", exposure: parseGenericLensExposureCapabilityProfile({ schemaVersion: \"0.1.0\", profileId: id+\":exposure\", profileVersion: version,\n scientificStatus: \"approximation\", evidence, focalLengthMmRange: fact({ minimum: 50, maximum: 50 }), aperture: { widestAvailableFNumber: {\n kind: \"constant\", fNumber: fact(4) }, narrowestAvailableFNumber: fact(16), settingGrid: { kind: \"continuous-within-range\" } } }),\n matchedReference: r, profileReferences: [\"radial\", \"lateral-ca\", \"vignetting\", \"breathing\", \"transmission\", \"pupil\", \"stray\", \"correction\"]\n .map((role) => ({ profileId: id+\":\"+role, profileVersion: version })),\n limitations: [...limitations, \"Optical reference response is limited to 50 mm, f/4, focus 5 m and explicit field/defocus/wavelength slices; capabilities do not authorize extrapolation.\",\n \"The initial prime has no OIS; body stabilization is separate.\"] };\n}\nconst common = { focalLengthMm: 50 as const, aperture: 4 as const, focusDistanceM: 5 as const, wavelengthNm: 550 as const,\n normalizationRadiusMm: Math.hypot(18,12), correctionCaFraction: .8 };\nfunction buildGenericTierAssets(version: GenericTierPresetVersion): readonly GenericEquipmentTierPreset[] {\n return [\n { tier: \"consumer\", label: \"Consumer\", presetId: \"photivra-consumer\", presetVersion: version, scientificStatus: \"approximation\", evidence,\n body: bodyAssets(version, \"photivra-consumer-body\", 6400, 4, 8, { bitDepth: 12, blackLevelCode: 256, saturationElectrons: 20000,\n maximumAnalogGain: 32, lowGainReadNoise: 6, highGainReadNoise: 2.5, highGainFromIso: 800, highGainMaximumCharge: 6000,\n prnu: .01, dsnu: .3, hotFraction: 2e-4, hotMultiplier: 50, rowRms: .6, columnRms: .4, instanceSeed: 0x51ed270b }, .03, .35, .005, false, false),\n lens: lensAssets(version, \"photivra-consumer-prime\", { ...common, distortionK1: -.06, lateralCaK1Offset: .008, vignettingR2: -.5,\n breathingProjectionScale: 1.03, transmission: .75, correctionGainStrength: .8, ghostPowerFraction: .006, veilPowerFraction: .012,\n pupilAmplitudeByField: [disk, clipped, clippedMore], pupilOpdMicrometersByDefocus: [near, flat, far], pupilThroughputByField: [1,.85,.65] }),\n tradeoffs: [\"Limited continuous AF; heavier digital correction and edge pupil clipping in matched reference.\"] },\n { tier: \"prosumer\", label: \"Prosumer\", presetId: \"photivra-prosumer\", presetVersion: version, scientificStatus: \"approximation\", evidence,\n body: bodyAssets(version, \"photivra-prosumer-body\", 12800, 8, 16, { bitDepth: 14, blackLevelCode: 1024, saturationElectrons: 40000,\n maximumAnalogGain: 64, lowGainReadNoise: 3, highGainReadNoise: 1.4, highGainFromIso: 800, highGainMaximumCharge: 12000,\n prnu: .006, dsnu: .2, hotFraction: 1e-4, hotMultiplier: 40, rowRms: .3, columnRms: .2, instanceSeed: 0x2c1b3c6d }, .015, .65, .01, true, true),\n lens: lensAssets(version, \"photivra-prosumer-prime\", { ...common, distortionK1: -.025, lateralCaK1Offset: .004, vignettingR2: -.25,\n breathingProjectionScale: 1.015, transmission: .85, correctionGainStrength: .6, ghostPowerFraction: .003, veilPowerFraction: .006,\n pupilAmplitudeByField: [disk, disk, clipped], pupilOpdMicrometersByDefocus: [near.map((v)=>v*.7), flat, far.map((v)=>v*.7)], pupilThroughputByField: [1,.95,.85] }),\n tradeoffs: [\"Lower matched-reference peripheral gain/noise amplification than Professional; not universally inferior.\"] },\n { tier: \"professional\", label: \"Professional\", presetId: \"photivra-professional\", presetVersion: version, scientificStatus: \"approximation\", evidence,\n body: bodyAssets(version, \"photivra-professional-body\", 25600, 12, 24, { bitDepth: 14, blackLevelCode: 1024, saturationElectrons: 60000,\n maximumAnalogGain: 128, lowGainReadNoise: 2, highGainReadNoise: 1.1, highGainFromIso: 800, highGainMaximumCharge: 16000,\n prnu: .004, dsnu: .15, hotFraction: 5e-5, hotMultiplier: 30, rowRms: .15, columnRms: .1, instanceSeed: 0x6a09e667 }, .008, .85, .02, true, true),\n lens: lensAssets(version, \"photivra-professional-prime\", { ...common, distortionK1: -.01, lateralCaK1Offset: .002, vignettingR2: -.35,\n breathingProjectionScale: 1.005, transmission: .9, correctionGainStrength: .8, ghostPowerFraction: .001, veilPowerFraction: .002,\n pupilAmplitudeByField: [disk, disk, disk], pupilOpdMicrometersByDefocus: [near.map((v)=>v*.9), flat, far.map((v)=>v*.6)], pupilThroughputByField: [1,.98,.95] }),\n tradeoffs: [\"Less edge clipping/stray light, with greater f/4 falloff/gain cost than Prosumer and asymmetric near/far wavefront character.\"] }\n ];\n}\n\n/** The presets of the current version, 2.1.0 (third-stop ISO settings). */\nexport const GENERIC_TIER_ASSETS: readonly GenericEquipmentTierPreset[] = buildGenericTierAssets(\"2.1.0\");\nlet historical: readonly GenericEquipmentTierPreset[] | undefined;\n/** The presets of an exact version; 2.0.0 (whole-stop ISO) is built on first use. */\nexport function genericTierAssets(version: GenericTierPresetVersion): readonly GenericEquipmentTierPreset[] {\n if (version === \"2.1.0\") return GENERIC_TIER_ASSETS;\n return historical ??= buildGenericTierAssets(\"2.0.0\");\n}\n"]}
@@ -15,7 +15,7 @@ import { resolveGenericEquipmentExposureCapabilities } from "./exposure-capabili
15
15
  import { parseGenericLensCorrectionProfile } from "../output/lens-corrections.js";
16
16
  import { parseLensStrayLightProfile } from "../optics/stray-light.js";
17
17
  import { parseLensComplexPupilProfile } from "../optics/complex-pupil-psf.js";
18
- import { parseSceneToSensorIrradianceProfile } from "../optics/scene-to-sensor-irradiance.js";
18
+ import { parseSceneToSensorIrradianceProfile, SCENE_TO_SENSOR_BRIDGE_SCOPE } from "../optics/scene-to-sensor-irradiance.js";
19
19
  /** The current preset version (2.14: 2.1.0, third-stop ISO settings). */
20
20
  export const GENERIC_EQUIPMENT_TIER_PRESET_VERSION = "2.1.0";
21
21
  /** Every exact preset version that resolves, oldest first. A version is never retuned in place (`test/generic-tier-presets.test.ts`). */
@@ -118,8 +118,7 @@ export function resolveGenericEquipmentTierLensProfiles(input) {
118
118
  focus: { kind: "finite-distance-range", objectDistanceM: { minimum: 5, maximum: 5 } } }, transmission: { kind: "spectral-transmission", scientificStatus: "approximation",
119
119
  wavelengthBasis: "vacuum", samples: { value: [{ wavelengthNanometers: 380, linearTransmissionFactor: a.transmission },
120
120
  { wavelengthNanometers: 780, linearTransmissionFactor: a.transmission }], evidence }, uncertainty: { kind: "not-quantified", limitation: "Synthetic spectrally flat reference over 380-780 nm." } },
121
- distortionAreaMappingOwnership: "not-applied-by-bridge", psfRedistributionOwnership: "downstream-normalized-energy-redistribution", sensorOpticalStackIncluded: false,
122
- strayLightIncluded: false, polarizationModeled: false, wavelengthChangingBehaviorModeled: false, volumetricScatteringModeled: false, evidence, limitations: l.lens.limitations });
121
+ ...SCENE_TO_SENSOR_BRIDGE_SCOPE, evidence, limitations: l.lens.limitations });
123
122
  const pupils = [0, 1, 2].flatMap((field) => [-20, 0, 20].map((defocus, index) => parseLensComplexPupilProfile({ schemaVersion: "0.1.0",
124
123
  profileId: id + ":pupil:" + field + ":" + index, profileVersion: version, scientificStatus: "approximation", opticalDomain: "lens-primary-optical-path-only",
125
124
  representation: "complex-pupil-amplitude-plus-opd", pupilCoordinateSystem: "pupil-plane-metric-aligned-to-image-plane", imageFieldAxes: "+X right, +Y up",
@@ -1 +1 @@
1
- {"version":3,"file":"generic-tier-presets.js","sourceRoot":"","sources":["../../src/equipment/generic-tier-presets.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Generic tier presets: a catalog of exact preset versions for bodies and lenses.\n *\n * There is no hidden \"latest\" alias and no default sensor size. By default the lens tier matches the\n * body tier, but mixing tiers is a normal, supported choice.\n * @see docs/GENERIC_TIER_PRESETS.md for the equations, units, coordinate conventions, known blockers\n * and support limits.\n */\n\nimport { freezeOwnedData } from \"../core/owned-data.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { choice, record, parseOpticalProfileState, type OpticalProfileState, type GenericOpticalEvidence } from \"../optics/profile-contract.js\";\nimport { genericTierAssets, type GenericEquipmentTier, type GenericEquipmentTierPreset, type GenericTierPresetVersion } from \"./generic-tier-assets.js\";\nimport { resolveGenericEquipmentExposureCapabilities } from \"./exposure-capabilities.js\";\nimport { parseGenericLensCorrectionProfile, type GenericLensCorrectionProfile } from \"../output/lens-corrections.js\";\nimport { parseLensStrayLightProfile, type LensStrayLightProfile } from \"../optics/stray-light.js\";\nimport { parseLensComplexPupilProfile, type LensComplexPupilProfile } from \"../optics/complex-pupil-psf.js\";\nimport { parseSceneToSensorIrradianceProfile, type SceneToSensorIrradianceProfile } from \"../optics/scene-to-sensor-irradiance.js\";\nimport type { RadialDistortionProfile } from \"../optics/radial-distortion.js\";\nimport type { LateralChromaticAberrationProfile } from \"../optics/lateral-chromatic-aberration.js\";\nimport type { IlluminationVignettingProfile } from \"../optics/illumination-vignetting.js\";\n\n/** The current preset version (2.14: 2.1.0, third-stop ISO settings). */\nexport const GENERIC_EQUIPMENT_TIER_PRESET_VERSION = \"2.1.0\" as const;\n/** Every exact preset version that resolves, oldest first. A version is never retuned in place (`test/generic-tier-presets.test.ts`). */\nexport const GENERIC_EQUIPMENT_TIER_PRESET_VERSIONS = /* @__PURE__ */ Object.freeze([\"2.0.0\", \"2.1.0\"] as const);\nexport const GENERIC_EQUIPMENT_TIERS = /* @__PURE__ */ Object.freeze([\"consumer\", \"prosumer\", \"professional\"] as const);\nexport interface GenericEquipmentTierProfileReference { profileId: string; profileVersion: string }\nexport interface GenericEquipmentTierSelection {\n schemaVersion: \"0.1.0\"; presetVersion: GenericTierPresetVersion;\n bodyTier: GenericEquipmentTier; lensTier: GenericEquipmentTier;\n bodyPresetId: string; lensPresetId: string;\n profileReferences: readonly GenericEquipmentTierProfileReference[];\n sensorFormatSelectedByTier: false; scientificTierMultiplierApplied: false;\n}\nexport interface ResolvedGenericTierLensProfiles {\n selection: GenericEquipmentTierSelection;\n state: OpticalProfileState;\n radial: RadialDistortionProfile;\n lateralCa: LateralChromaticAberrationProfile;\n vignetting: IlluminationVignettingProfile;\n breathingProjectionScale: number;\n transmission: SceneToSensorIrradianceProfile;\n pupils: readonly LensComplexPupilProfile[];\n stray: LensStrayLightProfile;\n correction: GenericLensCorrectionProfile;\n scientificStatus: \"approximation\";\n}\nconst catalogs = new Map<GenericTierPresetVersion, readonly GenericEquipmentTierPreset[]>();\nfunction catalogOf(version: GenericTierPresetVersion): readonly GenericEquipmentTierPreset[] {\n let catalog = catalogs.get(version);\n if (!catalog) catalogs.set(version, catalog = freezeOwnedData(genericTierAssets(version)));\n return catalog;\n}\nfunction preset(version: GenericTierPresetVersion, tier: GenericEquipmentTier): GenericEquipmentTierPreset {\n return catalogOf(version).find((p) => p.tier === tier)!;\n}\nfunction exactVersion(value: unknown): GenericTierPresetVersion {\n if (!(GENERIC_EQUIPMENT_TIER_PRESET_VERSIONS as readonly unknown[]).includes(value)) {\n throw new InvalidConfigurationError(\"Unknown equipment preset version; historical definitions may not silently fall back.\");\n }\n return value as GenericTierPresetVersion;\n}\n/** Catalog of exact versions. No hidden \"latest\" alias and no default sensor size. */\nexport function resolveGenericEquipmentTierCatalog(input: { presetVersion: string }): readonly GenericEquipmentTierPreset[] {\n const r = record(input, [\"presetVersion\"]);\n return catalogOf(exactVersion(r.presetVersion));\n}\nfunction bodyReferences(p: GenericEquipmentTierPreset): GenericEquipmentTierProfileReference[] {\n const b = p.body;\n return [b.exposure, b.iso, b.signalChain, b.release, b.focus, b.stabilization, b.whiteBalance, b.meteringCapabilities, b.flashSync]\n .map((profile) => ({ profileId: profile.profileId, profileVersion: profile.profileVersion }))\n .concat([...b.readout, b.readoutTiming, b.rollingReadoutTiming, b.fixedPatternNoise, ...b.metering]\n .map((a) => ({ profileId: a.assetId, profileVersion: a.assetVersion })));\n}\n/** The lens tier matches the body tier by default. Mixing tiers is a normal, supported choice. */\nexport function createGenericEquipmentTierSelection(input: {\n presetVersion: string; bodyTier: GenericEquipmentTier; lensTier?: GenericEquipmentTier;\n}): GenericEquipmentTierSelection {\n const r = record(input, [\"presetVersion\", \"bodyTier\", \"lensTier\"]);\n const presetVersion = exactVersion(r.presetVersion);\n const bodyTier = choice(r.bodyTier, GENERIC_EQUIPMENT_TIERS), lensTier = choice(r.lensTier === undefined ? bodyTier : r.lensTier, GENERIC_EQUIPMENT_TIERS);\n const body = preset(presetVersion, bodyTier), lens = preset(presetVersion, lensTier);\n return freezeOwnedData({ schemaVersion: \"0.1.0\", presetVersion, bodyTier, lensTier,\n bodyPresetId: body.presetId+\":body\", lensPresetId: lens.presetId+\":lens\",\n profileReferences: [...bodyReferences(body), { profileId: lens.lens.exposure.profileId, profileVersion: lens.lens.exposure.profileVersion }, ...lens.lens.profileReferences],\n sensorFormatSelectedByTier: false, scientificTierMultiplierApplied: false });\n}\n/** On a saved simulation, rejects profile versions that are stale, missing or retuned, instead of picking today's defaults. */\nexport function parseGenericEquipmentTierSelection(value: unknown): GenericEquipmentTierSelection {\n const r = record(value, [\"schemaVersion\", \"presetVersion\", \"bodyTier\", \"lensTier\", \"bodyPresetId\", \"lensPresetId\", \"profileReferences\",\n \"sensorFormatSelectedByTier\", \"scientificTierMultiplierApplied\"]);\n const expected = createGenericEquipmentTierSelection({ presetVersion: r.presetVersion as string,\n bodyTier: r.bodyTier as GenericEquipmentTier, lensTier: choice(r.lensTier, GENERIC_EQUIPMENT_TIERS) });\n if (r.schemaVersion !== expected.schemaVersion || r.bodyPresetId !== expected.bodyPresetId || r.lensPresetId !== expected.lensPresetId ||\n r.sensorFormatSelectedByTier !== false || r.scientificTierMultiplierApplied !== false || !Array.isArray(r.profileReferences) ||\n r.profileReferences.length !== expected.profileReferences.length) throw new InvalidConfigurationError(\"Saved equipment selection differs from its exact preset manifest.\");\n for (let i = 0; i < expected.profileReferences.length; i++) {\n const ref = record(r.profileReferences[i], [\"profileId\", \"profileVersion\"]), actual = expected.profileReferences[i]!;\n if (ref.profileId !== actual.profileId || ref.profileVersion !== actual.profileVersion) throw new InvalidConfigurationError(\"Saved equipment profile reference drift.\");\n }\n return expected;\n}\n/** Ties the finite matched-reference optical data to one exact generic selected state. Never extrapolates. */\nexport function resolveGenericEquipmentTierLensProfiles(input: { selection: GenericEquipmentTierSelection; state: OpticalProfileState }): ResolvedGenericTierLensProfiles {\n const request = record(input, [\"selection\", \"state\"]), selection = parseGenericEquipmentTierSelection(request.selection), state = parseOpticalProfileState(request.state);\n const b = preset(selection.presetVersion, selection.bodyTier), l = preset(selection.presetVersion, selection.lensTier), a = l.lens.matchedReference;\n if (state.bodyId !== b.body.exposure.profileId.replace(/:exposure$/, \"\") || state.bodyVersion !== selection.presetVersion ||\n state.lensId !== l.lens.exposure.profileId.replace(/:exposure$/, \"\") || state.lensVersion !== selection.presetVersion ||\n state.focalLengthMm !== a.focalLengthMm || state.aperture !== a.aperture || state.focusDistanceM !== a.focusDistanceM ||\n state.captureMode !== \"still\" || state.stabilizationMode !== \"off\") throw new InvalidConfigurationError(\"No optical reference slice for this exact generic system/acquisition state.\");\n resolveGenericEquipmentExposureCapabilities({ bodyProfile: b.body.exposure, lensProfile: l.lens.exposure, selectedFocalLengthMm: state.focalLengthMm });\n const id = state.lensId, version = state.lensVersion, evidence = l.evidence;\n const opticalEvidence: GenericOpticalEvidence = { kind: \"generic-parametric\", basis: \"Photivra-owned educational tier design values, not measured calibration.\",\n residualNote: \"Finite matched-reference approximation; no branded signature or aggregate physical error bound.\", sources: evidence };\n const coeff = (k1: number): RadialDistortionProfile => ({ normalizationRadiusMm: a.normalizationRadiusMm, maximumNormalizedRadius: 1.1,\n coefficients: { k1, k2: 0, k3: 0 } });\n const radial = coeff(a.distortionK1), lateralCa: LateralChromaticAberrationProfile = { normalizationRadiusMm: a.normalizationRadiusMm,\n maximumNormalizedRadius: 1.1, baseDistortionCoefficients: radial.coefficients,\n redCoefficientOffset: { k1: a.lateralCaK1Offset, k2: 0, k3: 0 }, blueCoefficientOffset: { k1: -a.lateralCaK1Offset, k2: 0, k3: 0 } };\n const vignetting: IlluminationVignettingProfile = { normalizationRadiusMm: a.normalizationRadiusMm, maximumNormalizedRadius: 1.1,\n coefficients: { r2: a.vignettingR2, r4: 0, r6: 0 } };\n const identity = { version, domain: \"reconstructed-linear\" as const, availability: \"toggle\" as const, defaultEnabled: true,\n dependencies: [], requiredByStabilizationModes: [], residualNote: opticalEvidence.residualNote };\n const correction = parseGenericLensCorrectionProfile({ schemaVersion: \"0.1.0\", id: id+\":correction\", version, state, evidence: opticalEvidence,\n components: [{ ...identity, id: \"geometry\", kind: \"geometry\", transform: { id: id+\":radial-map\", version,\n domain: \"reconstructed-linear\", purpose: \"distortion\", kind: \"radial\", profile: radial } },\n { ...identity, id: \"lateral-ca\", kind: \"lateral-ca\", transforms: Object.fromEntries([\"red\", \"green\", \"blue\"].map((channel, i) => [channel, {\n id: id+\":ca-map:\"+channel, version, domain: \"reconstructed-linear\", purpose: \"lateral-ca\", kind: \"radial\",\n profile: coeff([a.lateralCaK1Offset*a.correctionCaFraction, 0, -a.lateralCaK1Offset*a.correctionCaFraction][i]!) }])) },\n { ...identity, id: \"gain\", kind: \"peripheral-illumination\", profile: vignetting, strength: a.correctionGainStrength }] });\n const stray = parseLensStrayLightProfile({ schemaVersion: \"0.1.0\", id: id+\":stray\", version, state, evidence: opticalEvidence,\n interaction: \"lens-reflections\", wavelengthNm: a.wavelengthNm, wavelengthBasis: \"vacuum\", maximumSourceAngleDegrees: 60,\n referenceEntranceAreaMm2: Math.PI*(50/4/2)**2, responses: [\n { id: \"ghost\", kind: \"ghost\", centroidMmPerDegree: [-.02,0,0,-.02], offsetMm: { x: 1, y: 0 }, sigmaMm: .5, axisPowerFraction: a.ghostPowerFraction, angularSlope: 1 },\n { id: \"veil\", kind: \"veil\", centroidMmPerDegree: [0,0,0,0], offsetMm: { x: 0, y: 0 }, sigmaMm: 10, axisPowerFraction: a.veilPowerFraction, angularSlope: 0 }] });\n const transmission = parseSceneToSensorIrradianceProfile({ schemaVersion: \"0.1.0\", profileId: id+\":transmission\", profileVersion: version, lensProfileId: id,\n scientificStatus: \"approximation\", applicability: { focalLengthMm: { minimum: 50, maximum: 50 }, nominalFNumber: { minimum: 4, maximum: 4 },\n focus: { kind: \"finite-distance-range\", objectDistanceM: { minimum: 5, maximum: 5 } } }, transmission: { kind: \"spectral-transmission\", scientificStatus: \"approximation\",\n wavelengthBasis: \"vacuum\", samples: { value: [{ wavelengthNanometers: 380, linearTransmissionFactor: a.transmission },\n { wavelengthNanometers: 780, linearTransmissionFactor: a.transmission }], evidence }, uncertainty: { kind: \"not-quantified\", limitation: \"Synthetic spectrally flat reference over 380-780 nm.\" } },\n distortionAreaMappingOwnership: \"not-applied-by-bridge\", psfRedistributionOwnership: \"downstream-normalized-energy-redistribution\", sensorOpticalStackIncluded: false,\n strayLightIncluded: false, polarizationModeled: false, wavelengthChangingBehaviorModeled: false, volumetricScatteringModeled: false, evidence, limitations: l.lens.limitations });\n const pupils = [0,1,2].flatMap((field) => [-20,0,20].map((defocus, index) => parseLensComplexPupilProfile({ schemaVersion: \"0.1.0\",\n profileId: id+\":pupil:\"+field+\":\"+index, profileVersion: version, scientificStatus: \"approximation\", opticalDomain: \"lens-primary-optical-path-only\",\n representation: \"complex-pupil-amplitude-plus-opd\", pupilCoordinateSystem: \"pupil-plane-metric-aligned-to-image-plane\", imageFieldAxes: \"+X right, +Y up\",\n amplitudeMeaning: \"relative-complex-pupil-amplitude-shape\", wavefrontMeaning: \"optical-path-difference-micrometers\",\n throughputOwnership: \"separate-relative-pupil-throughput-factor\", kernelEnergyNormalization: \"unit-energy-shape\", propagationModel: \"scalar-fraunhofer-discrete-reference\",\n context: { focalLengthMm: 50, focus: { kind: \"finite\", distanceM: 5 }, apertureFNumber: 4, fieldPointMm: [{x:0,y:0},{x:10,y:6},{x:18,y:12}][field],\n wavelengthNm: 550, signedDefocusImagePlaneMicrometers: defocus }, responseIncludes: { diffraction: true, aberration: true, defocus: true, pupilClippingShape: true },\n relativePupilThroughputFactor: a.pupilThroughputByField[field], grid: { widthSamples: 5, heightSamples: 5, pupilSamplePitchMmX: 3.125, pupilSamplePitchMmY: 3.125,\n centerSampleX: 2, centerSampleY: 2, relativeAmplitude: a.pupilAmplitudeByField[field], opticalPathDifferenceMicrometers: a.pupilOpdMicrometersByDefocus[index] },\n sensorOpticalStackIncluded: false, sensorSamplingIncluded: false, reconstructionIncluded: false, strayLightIncluded: false, evidence,\n uncertainty: { kind: \"not-quantified\", limitation: \"Coarse independently designed pupil-grid reference only.\" }, limitations: l.lens.limitations })));\n return freezeOwnedData({ selection, state, radial, lateralCa, vignetting, breathingProjectionScale: a.breathingProjectionScale, transmission, pupils, stray, correction,\n scientificStatus: \"approximation\" });\n}\n"]}
1
+ {"version":3,"file":"generic-tier-presets.js","sourceRoot":"","sources":["../../src/equipment/generic-tier-presets.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Generic tier presets: a catalog of exact preset versions for bodies and lenses.\n *\n * There is no hidden \"latest\" alias and no default sensor size. By default the lens tier matches the\n * body tier, but mixing tiers is a normal, supported choice.\n * @see docs/GENERIC_TIER_PRESETS.md for the equations, units, coordinate conventions, known blockers\n * and support limits.\n */\n\nimport { freezeOwnedData } from \"../core/owned-data.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { choice, record, parseOpticalProfileState, type OpticalProfileState, type GenericOpticalEvidence } from \"../optics/profile-contract.js\";\nimport { genericTierAssets, type GenericEquipmentTier, type GenericEquipmentTierPreset, type GenericTierPresetVersion } from \"./generic-tier-assets.js\";\nimport { resolveGenericEquipmentExposureCapabilities } from \"./exposure-capabilities.js\";\nimport { parseGenericLensCorrectionProfile, type GenericLensCorrectionProfile } from \"../output/lens-corrections.js\";\nimport { parseLensStrayLightProfile, type LensStrayLightProfile } from \"../optics/stray-light.js\";\nimport { parseLensComplexPupilProfile, type LensComplexPupilProfile } from \"../optics/complex-pupil-psf.js\";\nimport { parseSceneToSensorIrradianceProfile, SCENE_TO_SENSOR_BRIDGE_SCOPE, type SceneToSensorIrradianceProfile } from \"../optics/scene-to-sensor-irradiance.js\";\nimport type { RadialDistortionProfile } from \"../optics/radial-distortion.js\";\nimport type { LateralChromaticAberrationProfile } from \"../optics/lateral-chromatic-aberration.js\";\nimport type { IlluminationVignettingProfile } from \"../optics/illumination-vignetting.js\";\n\n/** The current preset version (2.14: 2.1.0, third-stop ISO settings). */\nexport const GENERIC_EQUIPMENT_TIER_PRESET_VERSION = \"2.1.0\" as const;\n/** Every exact preset version that resolves, oldest first. A version is never retuned in place (`test/generic-tier-presets.test.ts`). */\nexport const GENERIC_EQUIPMENT_TIER_PRESET_VERSIONS = /* @__PURE__ */ Object.freeze([\"2.0.0\", \"2.1.0\"] as const);\nexport const GENERIC_EQUIPMENT_TIERS = /* @__PURE__ */ Object.freeze([\"consumer\", \"prosumer\", \"professional\"] as const);\nexport interface GenericEquipmentTierProfileReference { profileId: string; profileVersion: string }\nexport interface GenericEquipmentTierSelection {\n schemaVersion: \"0.1.0\"; presetVersion: GenericTierPresetVersion;\n bodyTier: GenericEquipmentTier; lensTier: GenericEquipmentTier;\n bodyPresetId: string; lensPresetId: string;\n profileReferences: readonly GenericEquipmentTierProfileReference[];\n sensorFormatSelectedByTier: false; scientificTierMultiplierApplied: false;\n}\nexport interface ResolvedGenericTierLensProfiles {\n selection: GenericEquipmentTierSelection;\n state: OpticalProfileState;\n radial: RadialDistortionProfile;\n lateralCa: LateralChromaticAberrationProfile;\n vignetting: IlluminationVignettingProfile;\n breathingProjectionScale: number;\n transmission: SceneToSensorIrradianceProfile;\n pupils: readonly LensComplexPupilProfile[];\n stray: LensStrayLightProfile;\n correction: GenericLensCorrectionProfile;\n scientificStatus: \"approximation\";\n}\nconst catalogs = new Map<GenericTierPresetVersion, readonly GenericEquipmentTierPreset[]>();\nfunction catalogOf(version: GenericTierPresetVersion): readonly GenericEquipmentTierPreset[] {\n let catalog = catalogs.get(version);\n if (!catalog) catalogs.set(version, catalog = freezeOwnedData(genericTierAssets(version)));\n return catalog;\n}\nfunction preset(version: GenericTierPresetVersion, tier: GenericEquipmentTier): GenericEquipmentTierPreset {\n return catalogOf(version).find((p) => p.tier === tier)!;\n}\nfunction exactVersion(value: unknown): GenericTierPresetVersion {\n if (!(GENERIC_EQUIPMENT_TIER_PRESET_VERSIONS as readonly unknown[]).includes(value)) {\n throw new InvalidConfigurationError(\"Unknown equipment preset version; historical definitions may not silently fall back.\");\n }\n return value as GenericTierPresetVersion;\n}\n/** Catalog of exact versions. No hidden \"latest\" alias and no default sensor size. */\nexport function resolveGenericEquipmentTierCatalog(input: { presetVersion: string }): readonly GenericEquipmentTierPreset[] {\n const r = record(input, [\"presetVersion\"]);\n return catalogOf(exactVersion(r.presetVersion));\n}\nfunction bodyReferences(p: GenericEquipmentTierPreset): GenericEquipmentTierProfileReference[] {\n const b = p.body;\n return [b.exposure, b.iso, b.signalChain, b.release, b.focus, b.stabilization, b.whiteBalance, b.meteringCapabilities, b.flashSync]\n .map((profile) => ({ profileId: profile.profileId, profileVersion: profile.profileVersion }))\n .concat([...b.readout, b.readoutTiming, b.rollingReadoutTiming, b.fixedPatternNoise, ...b.metering]\n .map((a) => ({ profileId: a.assetId, profileVersion: a.assetVersion })));\n}\n/** The lens tier matches the body tier by default. Mixing tiers is a normal, supported choice. */\nexport function createGenericEquipmentTierSelection(input: {\n presetVersion: string; bodyTier: GenericEquipmentTier; lensTier?: GenericEquipmentTier;\n}): GenericEquipmentTierSelection {\n const r = record(input, [\"presetVersion\", \"bodyTier\", \"lensTier\"]);\n const presetVersion = exactVersion(r.presetVersion);\n const bodyTier = choice(r.bodyTier, GENERIC_EQUIPMENT_TIERS), lensTier = choice(r.lensTier === undefined ? bodyTier : r.lensTier, GENERIC_EQUIPMENT_TIERS);\n const body = preset(presetVersion, bodyTier), lens = preset(presetVersion, lensTier);\n return freezeOwnedData({ schemaVersion: \"0.1.0\", presetVersion, bodyTier, lensTier,\n bodyPresetId: body.presetId+\":body\", lensPresetId: lens.presetId+\":lens\",\n profileReferences: [...bodyReferences(body), { profileId: lens.lens.exposure.profileId, profileVersion: lens.lens.exposure.profileVersion }, ...lens.lens.profileReferences],\n sensorFormatSelectedByTier: false, scientificTierMultiplierApplied: false });\n}\n/** On a saved simulation, rejects profile versions that are stale, missing or retuned, instead of picking today's defaults. */\nexport function parseGenericEquipmentTierSelection(value: unknown): GenericEquipmentTierSelection {\n const r = record(value, [\"schemaVersion\", \"presetVersion\", \"bodyTier\", \"lensTier\", \"bodyPresetId\", \"lensPresetId\", \"profileReferences\",\n \"sensorFormatSelectedByTier\", \"scientificTierMultiplierApplied\"]);\n const expected = createGenericEquipmentTierSelection({ presetVersion: r.presetVersion as string,\n bodyTier: r.bodyTier as GenericEquipmentTier, lensTier: choice(r.lensTier, GENERIC_EQUIPMENT_TIERS) });\n if (r.schemaVersion !== expected.schemaVersion || r.bodyPresetId !== expected.bodyPresetId || r.lensPresetId !== expected.lensPresetId ||\n r.sensorFormatSelectedByTier !== false || r.scientificTierMultiplierApplied !== false || !Array.isArray(r.profileReferences) ||\n r.profileReferences.length !== expected.profileReferences.length) throw new InvalidConfigurationError(\"Saved equipment selection differs from its exact preset manifest.\");\n for (let i = 0; i < expected.profileReferences.length; i++) {\n const ref = record(r.profileReferences[i], [\"profileId\", \"profileVersion\"]), actual = expected.profileReferences[i]!;\n if (ref.profileId !== actual.profileId || ref.profileVersion !== actual.profileVersion) throw new InvalidConfigurationError(\"Saved equipment profile reference drift.\");\n }\n return expected;\n}\n/** Ties the finite matched-reference optical data to one exact generic selected state. Never extrapolates. */\nexport function resolveGenericEquipmentTierLensProfiles(input: { selection: GenericEquipmentTierSelection; state: OpticalProfileState }): ResolvedGenericTierLensProfiles {\n const request = record(input, [\"selection\", \"state\"]), selection = parseGenericEquipmentTierSelection(request.selection), state = parseOpticalProfileState(request.state);\n const b = preset(selection.presetVersion, selection.bodyTier), l = preset(selection.presetVersion, selection.lensTier), a = l.lens.matchedReference;\n if (state.bodyId !== b.body.exposure.profileId.replace(/:exposure$/, \"\") || state.bodyVersion !== selection.presetVersion ||\n state.lensId !== l.lens.exposure.profileId.replace(/:exposure$/, \"\") || state.lensVersion !== selection.presetVersion ||\n state.focalLengthMm !== a.focalLengthMm || state.aperture !== a.aperture || state.focusDistanceM !== a.focusDistanceM ||\n state.captureMode !== \"still\" || state.stabilizationMode !== \"off\") throw new InvalidConfigurationError(\"No optical reference slice for this exact generic system/acquisition state.\");\n resolveGenericEquipmentExposureCapabilities({ bodyProfile: b.body.exposure, lensProfile: l.lens.exposure, selectedFocalLengthMm: state.focalLengthMm });\n const id = state.lensId, version = state.lensVersion, evidence = l.evidence;\n const opticalEvidence: GenericOpticalEvidence = { kind: \"generic-parametric\", basis: \"Photivra-owned educational tier design values, not measured calibration.\",\n residualNote: \"Finite matched-reference approximation; no branded signature or aggregate physical error bound.\", sources: evidence };\n const coeff = (k1: number): RadialDistortionProfile => ({ normalizationRadiusMm: a.normalizationRadiusMm, maximumNormalizedRadius: 1.1,\n coefficients: { k1, k2: 0, k3: 0 } });\n const radial = coeff(a.distortionK1), lateralCa: LateralChromaticAberrationProfile = { normalizationRadiusMm: a.normalizationRadiusMm,\n maximumNormalizedRadius: 1.1, baseDistortionCoefficients: radial.coefficients,\n redCoefficientOffset: { k1: a.lateralCaK1Offset, k2: 0, k3: 0 }, blueCoefficientOffset: { k1: -a.lateralCaK1Offset, k2: 0, k3: 0 } };\n const vignetting: IlluminationVignettingProfile = { normalizationRadiusMm: a.normalizationRadiusMm, maximumNormalizedRadius: 1.1,\n coefficients: { r2: a.vignettingR2, r4: 0, r6: 0 } };\n const identity = { version, domain: \"reconstructed-linear\" as const, availability: \"toggle\" as const, defaultEnabled: true,\n dependencies: [], requiredByStabilizationModes: [], residualNote: opticalEvidence.residualNote };\n const correction = parseGenericLensCorrectionProfile({ schemaVersion: \"0.1.0\", id: id+\":correction\", version, state, evidence: opticalEvidence,\n components: [{ ...identity, id: \"geometry\", kind: \"geometry\", transform: { id: id+\":radial-map\", version,\n domain: \"reconstructed-linear\", purpose: \"distortion\", kind: \"radial\", profile: radial } },\n { ...identity, id: \"lateral-ca\", kind: \"lateral-ca\", transforms: Object.fromEntries([\"red\", \"green\", \"blue\"].map((channel, i) => [channel, {\n id: id+\":ca-map:\"+channel, version, domain: \"reconstructed-linear\", purpose: \"lateral-ca\", kind: \"radial\",\n profile: coeff([a.lateralCaK1Offset*a.correctionCaFraction, 0, -a.lateralCaK1Offset*a.correctionCaFraction][i]!) }])) },\n { ...identity, id: \"gain\", kind: \"peripheral-illumination\", profile: vignetting, strength: a.correctionGainStrength }] });\n const stray = parseLensStrayLightProfile({ schemaVersion: \"0.1.0\", id: id+\":stray\", version, state, evidence: opticalEvidence,\n interaction: \"lens-reflections\", wavelengthNm: a.wavelengthNm, wavelengthBasis: \"vacuum\", maximumSourceAngleDegrees: 60,\n referenceEntranceAreaMm2: Math.PI*(50/4/2)**2, responses: [\n { id: \"ghost\", kind: \"ghost\", centroidMmPerDegree: [-.02,0,0,-.02], offsetMm: { x: 1, y: 0 }, sigmaMm: .5, axisPowerFraction: a.ghostPowerFraction, angularSlope: 1 },\n { id: \"veil\", kind: \"veil\", centroidMmPerDegree: [0,0,0,0], offsetMm: { x: 0, y: 0 }, sigmaMm: 10, axisPowerFraction: a.veilPowerFraction, angularSlope: 0 }] });\n const transmission = parseSceneToSensorIrradianceProfile({ schemaVersion: \"0.1.0\", profileId: id+\":transmission\", profileVersion: version, lensProfileId: id,\n scientificStatus: \"approximation\", applicability: { focalLengthMm: { minimum: 50, maximum: 50 }, nominalFNumber: { minimum: 4, maximum: 4 },\n focus: { kind: \"finite-distance-range\", objectDistanceM: { minimum: 5, maximum: 5 } } }, transmission: { kind: \"spectral-transmission\", scientificStatus: \"approximation\",\n wavelengthBasis: \"vacuum\", samples: { value: [{ wavelengthNanometers: 380, linearTransmissionFactor: a.transmission },\n { wavelengthNanometers: 780, linearTransmissionFactor: a.transmission }], evidence }, uncertainty: { kind: \"not-quantified\", limitation: \"Synthetic spectrally flat reference over 380-780 nm.\" } },\n ...SCENE_TO_SENSOR_BRIDGE_SCOPE, evidence, limitations: l.lens.limitations });\n const pupils = [0,1,2].flatMap((field) => [-20,0,20].map((defocus, index) => parseLensComplexPupilProfile({ schemaVersion: \"0.1.0\",\n profileId: id+\":pupil:\"+field+\":\"+index, profileVersion: version, scientificStatus: \"approximation\", opticalDomain: \"lens-primary-optical-path-only\",\n representation: \"complex-pupil-amplitude-plus-opd\", pupilCoordinateSystem: \"pupil-plane-metric-aligned-to-image-plane\", imageFieldAxes: \"+X right, +Y up\",\n amplitudeMeaning: \"relative-complex-pupil-amplitude-shape\", wavefrontMeaning: \"optical-path-difference-micrometers\",\n throughputOwnership: \"separate-relative-pupil-throughput-factor\", kernelEnergyNormalization: \"unit-energy-shape\", propagationModel: \"scalar-fraunhofer-discrete-reference\",\n context: { focalLengthMm: 50, focus: { kind: \"finite\", distanceM: 5 }, apertureFNumber: 4, fieldPointMm: [{x:0,y:0},{x:10,y:6},{x:18,y:12}][field],\n wavelengthNm: 550, signedDefocusImagePlaneMicrometers: defocus }, responseIncludes: { diffraction: true, aberration: true, defocus: true, pupilClippingShape: true },\n relativePupilThroughputFactor: a.pupilThroughputByField[field], grid: { widthSamples: 5, heightSamples: 5, pupilSamplePitchMmX: 3.125, pupilSamplePitchMmY: 3.125,\n centerSampleX: 2, centerSampleY: 2, relativeAmplitude: a.pupilAmplitudeByField[field], opticalPathDifferenceMicrometers: a.pupilOpdMicrometersByDefocus[index] },\n sensorOpticalStackIncluded: false, sensorSamplingIncluded: false, reconstructionIncluded: false, strayLightIncluded: false, evidence,\n uncertainty: { kind: \"not-quantified\", limitation: \"Coarse independently designed pupil-grid reference only.\" }, limitations: l.lens.limitations })));\n return freezeOwnedData({ selection, state, radial, lateralCa, vignetting, breathingProjectionScale: a.breathingProjectionScale, transmission, pupils, stray, correction,\n scientificStatus: \"approximation\" });\n}\n"]}
@@ -0,0 +1,78 @@
1
+ import { type GenericTierBodyAssets, type GenericTierPresetVersion } from "./generic-tier-assets.js";
2
+ /** How a profile value was obtained: copied from a source, calculated from sourced values, or Photivra's design value. */
3
+ export type SensorProfileValueKind = "published" | "derived" | "design";
4
+ /** One sensor profile. Every number is per photosite unless stated; see `provenance` for each value's kind. */
5
+ export interface SensorProfile {
6
+ id: string;
7
+ /** Format, resolution, architecture and era; no maker or product name. */
8
+ name: string;
9
+ /** A market category, not a specification: it is a label and changes nothing. */
10
+ marketTag: "consumer" | "professional";
11
+ architecture: "front-illuminated" | "back-illuminated" | "stacked";
12
+ sensorWidthMm: number;
13
+ sensorHeightMm: number;
14
+ pixelsWide: number;
15
+ pixelsHigh: number;
16
+ pixelPitchMicrometers: number;
17
+ /** The green channel's peak EQE (#555 `peakQuantumEfficiency`). */
18
+ peakQuantumEfficiency: number;
19
+ /** Full-well capacity, e⁻: the charge at the RAW white level at base ISO. */
20
+ fullWellElectrons: number;
21
+ /** Read noise, RMS e⁻; `highGainFromIso` null for one conversion gain throughout. */
22
+ readNoise: {
23
+ lowGainElectrons: number;
24
+ highGainElectrons: number;
25
+ highGainFromIso: number | null;
26
+ };
27
+ /** Charge storage limit of the high conversion gain, e⁻ (null without one): full well × base ISO / switch ISO. */
28
+ highGainFullWellElectrons: number | null;
29
+ adcBitDepth: 12 | 14 | 16;
30
+ /** Re-rated base ISO (see the module comment) and the highest ISO setting. */
31
+ baseIso: number;
32
+ maximumIso: number;
33
+ /** Largest analog gain relative to base ISO; above it the gain is digital. */
34
+ maximumAnalogGain: number;
35
+ /** Rolling readout, s: the top-to-bottom skew with `motion.shutter: "rolling"`. */
36
+ readoutSeconds: number;
37
+ /** Fixed-pattern noise used with `sensor.fixedPatternNoise` (EMVA 1288 Release 4.0 non-uniformities). */
38
+ fixedPattern: {
39
+ prnu: number;
40
+ dsnu: number;
41
+ hotPixelFraction: number;
42
+ hotPixelMultiplier: number;
43
+ rowElectrons: number;
44
+ columnElectrons: number;
45
+ };
46
+ /** What the profile is good for (text only). */
47
+ goodFor: readonly string[];
48
+ description: string;
49
+ /** "phone": the profile takes only the catalogue's phone lenses (`lens.catalogue`), which need it. */
50
+ fixedLenses: "phone" | null;
51
+ /**
52
+ * Each value's kind and source key (S1–S10, docs/SENSOR_PROFILES.md "Sources"); a value not listed is a design value.
53
+ * For example `fullWellElectrons: "published S1"` or `baseIso: "derived"`.
54
+ */
55
+ provenance: Readonly<Partial<Record<keyof SensorProfile | "sensorSize" | "pixels" | "highGainFromIso", string>>>;
56
+ }
57
+ /** Third-stop ISO markings from ISO 32 to 102 400 (S = 100·2^(k/3), rounded; the tiers' list in the middle): a profile's ISO settings. */
58
+ export declare const SENSOR_PROFILE_ISO_MARKINGS: readonly number[];
59
+ /**
60
+ * The profile record checked strictly: every field present, no unknown field, each value in range, base ISO no higher than
61
+ * the maximum, and a dual-gain switch above base ISO with its storage limit (no switch: one read noise, no storage limit).
62
+ * Fixed-pattern magnitudes and the ISO regimes are checked again by the engine's parsers when the body is built.
63
+ */
64
+ export declare function parseSensorProfile(value: unknown, path?: string): SensorProfile;
65
+ /** The engine's ISO anchor (see the module comment): white charge 60 000 e⁻ at ISO 100, 36 µm², QE 0.5. */
66
+ export declare const SENSOR_PROFILE_ISO_ANCHOR: Readonly<{
67
+ iso: 100;
68
+ fullWellElectrons: 60000;
69
+ pixelAreaSquareMicrometers: 36;
70
+ peakQuantumEfficiency: 0.5;
71
+ }>;
72
+ /** The unrounded re-rated base ISO S0 = 100 · (η/0.5) · (A/36 µm²) · (60 000 e⁻ / FW). */
73
+ export declare function sensorProfileSaturationIso(p: Pick<SensorProfile, "peakQuantumEfficiency" | "pixelPitchMicrometers" | "fullWellElectrons">): number;
74
+ /**
75
+ * The profile's sensor assets on a camera body: the body's other capabilities are kept. `readNoiseScale` (≥ 1) multiplies both
76
+ * read noises: √N for a site that sums N photosites (a downsized view, #554).
77
+ */
78
+ export declare function sensorProfileBody(p: SensorProfile, body: GenericTierBodyAssets, version: GenericTierPresetVersion, readNoiseScale?: number): GenericTierBodyAssets;
@@ -0,0 +1,77 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * Sensor profiles (#554): the profile record, its strict parser and the camera-body sensor assets built from it. The
4
+ * catalogue's data are in `sensor-profiles.ts`, which nothing in a capture imports: a caller passes a profile record
5
+ * (`simulateCapture({ sensor: { profile: SENSOR_PROFILES[i] } })`), so a capture bundle never contains the catalogue.
6
+ *
7
+ * ISO rating (owner decision, 2026-11-09): each profile's base ISO is re-rated from its full well, QE and pixel area,
8
+ * S0 = 100 · (η / 0.5) · (A / 36 µm²) · (60 000 e⁻ / FW), rounded to the nearest third-stop marking, so the RAW white at base
9
+ * ISO is the full well and every ISO keeps the engine's anchor (the Professional tier's ISO 100: 60 000 e⁻ at the white,
10
+ * 6 µm pixels, QE 0.5; S = 10/H, CIPA DC-004-2020 §3.2). The rounding is reported as `sensitivityOffsetStops` in the
11
+ * `sensor.profile` assumption. The high gain's charge storage is the white charge at its switch ISO.
12
+ * @see docs/SENSOR_PROFILES.md for every value's source or design basis.
13
+ */
14
+ import { InvalidConfigurationError } from "../core/configuration-error.js";
15
+ import { requireInputObject } from "../core/record-validation.js";
16
+ import { checkFieldRanges } from "../sensor/sensor-characteristics.js";
17
+ import { bodyAssets, GENERIC_THIRD_STOP_ISO_SETTINGS } from "./generic-tier-assets.js";
18
+ /** Third-stop ISO markings from ISO 32 to 102 400 (S = 100·2^(k/3), rounded; the tiers' list in the middle): a profile's ISO settings. */
19
+ export const SENSOR_PROFILE_ISO_MARKINGS = /* @__PURE__ */ Object.freeze([32, 40, 50, 64, 80, ...GENERIC_THIRD_STOP_ISO_SETTINGS, 32000, 40000, 51200, 64000, 80000, 102400]);
20
+ const ISO_MARKINGS = SENSOR_PROFILE_ISO_MARKINGS;
21
+ const fail = (message) => { throw new InvalidConfigurationError(message); };
22
+ const isoMarking = (v) => ISO_MARKINGS.includes(v);
23
+ const text = (v) => typeof v === "string" && v.length > 0 && v.length <= 400;
24
+ const FRACTION = [0, 1], ELECTRONS = [0, 100];
25
+ /** The record's fields, by path (#555's range checker: [minimum, maximum], the values allowed, 0 a nested record, or a predicate). */
26
+ const SCHEMA = { id: text, name: text, marketTag: ["consumer", "professional"], architecture: ["front-illuminated", "back-illuminated", "stacked"],
27
+ sensorWidthMm: [1, 100], sensorHeightMm: [1, 100], pixelsWide: [1, 1e5], pixelsHigh: [1, 1e5], pixelPitchMicrometers: [0.5, 100], peakQuantumEfficiency: [0.05, 0.9],
28
+ fullWellElectrons: [100, 1e10], readNoise: 0, "readNoise.lowGainElectrons": ELECTRONS, "readNoise.highGainElectrons": ELECTRONS, "readNoise.highGainFromIso": (v) => v === null || isoMarking(v),
29
+ highGainFullWellElectrons: (v) => v === null || typeof v === "number" && v >= 1 && v <= 1e10, adcBitDepth: [12, 14, 16], baseIso: isoMarking, maximumIso: isoMarking,
30
+ maximumAnalogGain: [1, 1024], readoutSeconds: [1e-6, 1], fixedPattern: 0, "fixedPattern.prnu": FRACTION, "fixedPattern.dsnu": [0, 100], "fixedPattern.hotPixelFraction": FRACTION,
31
+ "fixedPattern.hotPixelMultiplier": [1, 1e4], "fixedPattern.rowElectrons": ELECTRONS, "fixedPattern.columnElectrons": ELECTRONS,
32
+ goodFor: (v) => Array.isArray(v) && v.length <= 16 && v.every(text), description: text, fixedLenses: [null, "phone"],
33
+ provenance: (v) => typeof v === "object" && v !== null && !Array.isArray(v) && Object.entries(v).every(([k, s]) => k.length <= 64 && text(s)) };
34
+ /**
35
+ * The profile record checked strictly: every field present, no unknown field, each value in range, base ISO no higher than
36
+ * the maximum, and a dual-gain switch above base ISO with its storage limit (no switch: one read noise, no storage limit).
37
+ * Fixed-pattern magnitudes and the ISO regimes are checked again by the engine's parsers when the body is built.
38
+ */
39
+ export function parseSensorProfile(value, path = "sensor.profile") {
40
+ requireInputObject(value, path);
41
+ checkFieldRanges(value, Object.keys(value), "", SCHEMA, path + ".", true);
42
+ const p = value, n = p.readNoise;
43
+ if (!Number.isInteger(p.pixelsWide) || !Number.isInteger(p.pixelsHigh))
44
+ fail(path + ".pixelsWide and pixelsHigh must be whole numbers.");
45
+ if (p.baseIso > p.maximumIso)
46
+ fail(path + ".baseIso must not exceed maximumIso.");
47
+ if (n.highGainFromIso === null ? p.highGainFullWellElectrons !== null || n.highGainElectrons !== n.lowGainElectrons :
48
+ p.highGainFullWellElectrons === null || n.highGainFromIso <= p.baseIso || p.highGainFullWellElectrons > p.fullWellElectrons)
49
+ fail(path + ": a dual-gain switch above baseIso needs highGainFullWellElectrons up to the full well; without one, equal read noises and a null storage.");
50
+ return p;
51
+ }
52
+ /** The engine's ISO anchor (see the module comment): white charge 60 000 e⁻ at ISO 100, 36 µm², QE 0.5. */
53
+ export const SENSOR_PROFILE_ISO_ANCHOR = /* @__PURE__ */ Object.freeze({ iso: 100, fullWellElectrons: 60000, pixelAreaSquareMicrometers: 36, peakQuantumEfficiency: .5 });
54
+ /** The unrounded re-rated base ISO S0 = 100 · (η/0.5) · (A/36 µm²) · (60 000 e⁻ / FW). */
55
+ export function sensorProfileSaturationIso(p) {
56
+ const a = SENSOR_PROFILE_ISO_ANCHOR;
57
+ return a.iso * p.peakQuantumEfficiency / a.peakQuantumEfficiency * p.pixelPitchMicrometers ** 2 / a.pixelAreaSquareMicrometers * a.fullWellElectrons / p.fullWellElectrons;
58
+ }
59
+ /**
60
+ * The profile's sensor assets on a camera body: the body's other capabilities are kept. `readNoiseScale` (≥ 1) multiplies both
61
+ * read noises: √N for a site that sums N photosites (a downsized view, #554).
62
+ */
63
+ export function sensorProfileBody(p, body, version, readNoiseScale = 1) {
64
+ const evidence = [{ sourceOrigin: "manufacturer", sourceReference: "photivra:sensor-profiles-v1#" + p.id, reuseStatus: "factual-reference-only",
65
+ note: "Published specifications and open papers (docs/SENSOR_PROFILES.md); unpublished values are Photivra design values." }];
66
+ const black = { 12: 256, 14: 1024, 16: 4096 }[p.adcBitDepth], n = p.readNoise;
67
+ const built = bodyAssets(version, "photivra-sensor-profile-" + p.id, p.maximumIso, 1, 1, { bitDepth: p.adcBitDepth, blackLevelCode: black,
68
+ saturationElectrons: p.fullWellElectrons, maximumAnalogGain: p.maximumAnalogGain, lowGainReadNoise: n.lowGainElectrons * readNoiseScale, highGainReadNoise: n.highGainElectrons * readNoiseScale,
69
+ highGainFromIso: n.highGainFromIso ?? Infinity, highGainMaximumCharge: (p.highGainFullWellElectrons ?? p.fullWellElectrons) * (1 + 1e-12),
70
+ prnu: p.fixedPattern.prnu, dsnu: p.fixedPattern.dsnu, hotFraction: p.fixedPattern.hotPixelFraction, hotMultiplier: p.fixedPattern.hotPixelMultiplier,
71
+ rowRms: p.fixedPattern.rowElectrons, columnRms: p.fixedPattern.columnElectrons, instanceSeed: (0x9e3779b9 ^ (p.pixelsWide * 8191 + p.pixelsHigh)) >>> 0 }, p.readoutSeconds, .5, .01, false, false, { isoValues: ISO_MARKINGS.filter((iso) => iso >= p.baseIso && iso <= p.maximumIso), evidence,
72
+ limitations: ["Sensor profile " + p.name + " (#554): published, derived and design values (docs/SENSOR_PROFILES.md); not a calibration of any camera."] });
73
+ // Only the sensor assets are taken; the placeholders above (release, stabilization …) are the body's own.
74
+ return { ...body, exposure: built.exposure, iso: built.iso, signalChain: built.signalChain, readout: built.readout, readoutTiming: built.readoutTiming,
75
+ rollingReadoutTiming: built.rollingReadoutTiming, fixedPatternNoise: built.fixedPatternNoise, flashSync: built.flashSync };
76
+ }
77
+ //# sourceMappingURL=sensor-profile-body.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sensor-profile-body.js","sourceRoot":"","sources":["../../src/equipment/sensor-profile-body.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Sensor profiles (#554): the profile record, its strict parser and the camera-body sensor assets built from it. The\n * catalogue's data are in `sensor-profiles.ts`, which nothing in a capture imports: a caller passes a profile record\n * (`simulateCapture({ sensor: { profile: SENSOR_PROFILES[i] } })`), so a capture bundle never contains the catalogue.\n *\n * ISO rating (owner decision, 2026-11-09): each profile's base ISO is re-rated from its full well, QE and pixel area,\n * S0 = 100 · (η / 0.5) · (A / 36 µm²) · (60 000 e⁻ / FW), rounded to the nearest third-stop marking, so the RAW white at base\n * ISO is the full well and every ISO keeps the engine's anchor (the Professional tier's ISO 100: 60 000 e⁻ at the white,\n * 6 µm pixels, QE 0.5; S = 10/H, CIPA DC-004-2020 §3.2). The rounding is reported as `sensitivityOffsetStops` in the\n * `sensor.profile` assumption. The high gain's charge storage is the white charge at its switch ISO.\n * @see docs/SENSOR_PROFILES.md for every value's source or design basis.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport type { EvidenceProvenance } from \"../core/evidence-provenance.js\";\nimport { requireInputObject } from \"../core/record-validation.js\";\nimport { checkFieldRanges, type FieldRange } from \"../sensor/sensor-characteristics.js\";\nimport { bodyAssets, GENERIC_THIRD_STOP_ISO_SETTINGS, type GenericTierBodyAssets, type GenericTierPresetVersion } from \"./generic-tier-assets.js\";\n\n/** How a profile value was obtained: copied from a source, calculated from sourced values, or Photivra's design value. */\nexport type SensorProfileValueKind = \"published\" | \"derived\" | \"design\";\n\n/** One sensor profile. Every number is per photosite unless stated; see `provenance` for each value's kind. */\nexport interface SensorProfile {\n id: string;\n /** Format, resolution, architecture and era; no maker or product name. */\n name: string;\n /** A market category, not a specification: it is a label and changes nothing. */\n marketTag: \"consumer\" | \"professional\";\n architecture: \"front-illuminated\" | \"back-illuminated\" | \"stacked\";\n sensorWidthMm: number; sensorHeightMm: number;\n pixelsWide: number; pixelsHigh: number;\n pixelPitchMicrometers: number;\n /** The green channel's peak EQE (#555 `peakQuantumEfficiency`). */\n peakQuantumEfficiency: number;\n /** Full-well capacity, e⁻: the charge at the RAW white level at base ISO. */\n fullWellElectrons: number;\n /** Read noise, RMS e⁻; `highGainFromIso` null for one conversion gain throughout. */\n readNoise: { lowGainElectrons: number; highGainElectrons: number; highGainFromIso: number | null };\n /** Charge storage limit of the high conversion gain, e⁻ (null without one): full well × base ISO / switch ISO. */\n highGainFullWellElectrons: number | null;\n adcBitDepth: 12 | 14 | 16;\n /** Re-rated base ISO (see the module comment) and the highest ISO setting. */\n baseIso: number; maximumIso: number;\n /** Largest analog gain relative to base ISO; above it the gain is digital. */\n maximumAnalogGain: number;\n /** Rolling readout, s: the top-to-bottom skew with `motion.shutter: \"rolling\"`. */\n readoutSeconds: number;\n /** Fixed-pattern noise used with `sensor.fixedPatternNoise` (EMVA 1288 Release 4.0 non-uniformities). */\n fixedPattern: { prnu: number; dsnu: number; hotPixelFraction: number; hotPixelMultiplier: number; rowElectrons: number; columnElectrons: number };\n /** What the profile is good for (text only). */\n goodFor: readonly string[];\n description: string;\n /** \"phone\": the profile takes only the catalogue's phone lenses (`lens.catalogue`), which need it. */\n fixedLenses: \"phone\" | null;\n /**\n * Each value's kind and source key (S1–S10, docs/SENSOR_PROFILES.md \"Sources\"); a value not listed is a design value.\n * For example `fullWellElectrons: \"published S1\"` or `baseIso: \"derived\"`.\n */\n provenance: Readonly<Partial<Record<keyof SensorProfile | \"sensorSize\" | \"pixels\" | \"highGainFromIso\", string>>>;\n}\n\n/** Third-stop ISO markings from ISO 32 to 102 400 (S = 100·2^(k/3), rounded; the tiers' list in the middle): a profile's ISO settings. */\nexport const SENSOR_PROFILE_ISO_MARKINGS: readonly number[] = /* @__PURE__ */ Object.freeze([32, 40, 50, 64, 80, ...GENERIC_THIRD_STOP_ISO_SETTINGS, 32000, 40000, 51200, 64000, 80000, 102400]);\nconst ISO_MARKINGS = SENSOR_PROFILE_ISO_MARKINGS;\n\nconst fail = (message: string): never => { throw new InvalidConfigurationError(message); };\nconst isoMarking = (v: unknown): boolean => ISO_MARKINGS.includes(v as number);\nconst text = (v: unknown): boolean => typeof v === \"string\" && v.length > 0 && v.length <= 400;\nconst FRACTION = [0, 1] as const, ELECTRONS = [0, 100] as const;\n/** The record's fields, by path (#555's range checker: [minimum, maximum], the values allowed, 0 a nested record, or a predicate). */\nconst SCHEMA: Readonly<Record<string, FieldRange>> = { id: text, name: text, marketTag: [\"consumer\", \"professional\"], architecture: [\"front-illuminated\", \"back-illuminated\", \"stacked\"],\n sensorWidthMm: [1, 100], sensorHeightMm: [1, 100], pixelsWide: [1, 1e5], pixelsHigh: [1, 1e5], pixelPitchMicrometers: [0.5, 100], peakQuantumEfficiency: [0.05, 0.9],\n fullWellElectrons: [100, 1e10], readNoise: 0, \"readNoise.lowGainElectrons\": ELECTRONS, \"readNoise.highGainElectrons\": ELECTRONS, \"readNoise.highGainFromIso\": (v) => v === null || isoMarking(v),\n highGainFullWellElectrons: (v) => v === null || typeof v === \"number\" && v >= 1 && v <= 1e10, adcBitDepth: [12, 14, 16], baseIso: isoMarking, maximumIso: isoMarking,\n maximumAnalogGain: [1, 1024], readoutSeconds: [1e-6, 1], fixedPattern: 0, \"fixedPattern.prnu\": FRACTION, \"fixedPattern.dsnu\": [0, 100], \"fixedPattern.hotPixelFraction\": FRACTION,\n \"fixedPattern.hotPixelMultiplier\": [1, 1e4], \"fixedPattern.rowElectrons\": ELECTRONS, \"fixedPattern.columnElectrons\": ELECTRONS,\n goodFor: (v) => Array.isArray(v) && v.length <= 16 && v.every(text), description: text, fixedLenses: [null, \"phone\"],\n provenance: (v) => typeof v === \"object\" && v !== null && !Array.isArray(v) && Object.entries(v).every(([k, s]) => k.length <= 64 && text(s)) };\n/**\n * The profile record checked strictly: every field present, no unknown field, each value in range, base ISO no higher than\n * the maximum, and a dual-gain switch above base ISO with its storage limit (no switch: one read noise, no storage limit).\n * Fixed-pattern magnitudes and the ISO regimes are checked again by the engine's parsers when the body is built.\n */\nexport function parseSensorProfile(value: unknown, path = \"sensor.profile\"): SensorProfile {\n requireInputObject(value, path);\n checkFieldRanges(value as Record<string, unknown>, Object.keys(value as object), \"\", SCHEMA, path + \".\", true);\n const p = value as SensorProfile, n = p.readNoise;\n if (!Number.isInteger(p.pixelsWide) || !Number.isInteger(p.pixelsHigh)) fail(path + \".pixelsWide and pixelsHigh must be whole numbers.\");\n if (p.baseIso > p.maximumIso) fail(path + \".baseIso must not exceed maximumIso.\");\n if (n.highGainFromIso === null ? p.highGainFullWellElectrons !== null || n.highGainElectrons !== n.lowGainElectrons :\n p.highGainFullWellElectrons === null || n.highGainFromIso <= p.baseIso || p.highGainFullWellElectrons > p.fullWellElectrons)\n fail(path + \": a dual-gain switch above baseIso needs highGainFullWellElectrons up to the full well; without one, equal read noises and a null storage.\");\n return p;\n}\n\n/** The engine's ISO anchor (see the module comment): white charge 60 000 e⁻ at ISO 100, 36 µm², QE 0.5. */\nexport const SENSOR_PROFILE_ISO_ANCHOR = /* @__PURE__ */ Object.freeze({ iso: 100, fullWellElectrons: 60000, pixelAreaSquareMicrometers: 36, peakQuantumEfficiency: .5 });\n/** The unrounded re-rated base ISO S0 = 100 · (η/0.5) · (A/36 µm²) · (60 000 e⁻ / FW). */\nexport function sensorProfileSaturationIso(p: Pick<SensorProfile, \"peakQuantumEfficiency\" | \"pixelPitchMicrometers\" | \"fullWellElectrons\">): number {\n const a = SENSOR_PROFILE_ISO_ANCHOR;\n return a.iso * p.peakQuantumEfficiency / a.peakQuantumEfficiency * p.pixelPitchMicrometers ** 2 / a.pixelAreaSquareMicrometers * a.fullWellElectrons / p.fullWellElectrons;\n}\n\n\n/**\n * The profile's sensor assets on a camera body: the body's other capabilities are kept. `readNoiseScale` (≥ 1) multiplies both\n * read noises: √N for a site that sums N photosites (a downsized view, #554).\n */\nexport function sensorProfileBody(p: SensorProfile, body: GenericTierBodyAssets, version: GenericTierPresetVersion, readNoiseScale = 1): GenericTierBodyAssets {\n const evidence: readonly EvidenceProvenance[] = [{ sourceOrigin: \"manufacturer\", sourceReference: \"photivra:sensor-profiles-v1#\" + p.id, reuseStatus: \"factual-reference-only\",\n note: \"Published specifications and open papers (docs/SENSOR_PROFILES.md); unpublished values are Photivra design values.\" }];\n const black = { 12: 256, 14: 1024, 16: 4096 }[p.adcBitDepth], n = p.readNoise;\n const built = bodyAssets(version, \"photivra-sensor-profile-\" + p.id, p.maximumIso, 1, 1, { bitDepth: p.adcBitDepth, blackLevelCode: black,\n saturationElectrons: p.fullWellElectrons, maximumAnalogGain: p.maximumAnalogGain, lowGainReadNoise: n.lowGainElectrons * readNoiseScale, highGainReadNoise: n.highGainElectrons * readNoiseScale,\n highGainFromIso: n.highGainFromIso ?? Infinity, highGainMaximumCharge: (p.highGainFullWellElectrons ?? p.fullWellElectrons) * (1 + 1e-12),\n prnu: p.fixedPattern.prnu, dsnu: p.fixedPattern.dsnu, hotFraction: p.fixedPattern.hotPixelFraction, hotMultiplier: p.fixedPattern.hotPixelMultiplier,\n rowRms: p.fixedPattern.rowElectrons, columnRms: p.fixedPattern.columnElectrons, instanceSeed: (0x9e3779b9 ^ (p.pixelsWide * 8191 + p.pixelsHigh)) >>> 0 },\n p.readoutSeconds, .5, .01, false, false, { isoValues: ISO_MARKINGS.filter((iso) => iso >= p.baseIso && iso <= p.maximumIso), evidence,\n limitations: [\"Sensor profile \" + p.name + \" (#554): published, derived and design values (docs/SENSOR_PROFILES.md); not a calibration of any camera.\"] });\n // Only the sensor assets are taken; the placeholders above (release, stabilization …) are the body's own.\n return { ...body, exposure: built.exposure, iso: built.iso, signalChain: built.signalChain, readout: built.readout, readoutTiming: built.readoutTiming,\n rollingReadoutTiming: built.rollingReadoutTiming, fixedPatternNoise: built.fixedPatternNoise, flashSync: built.flashSync };\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import type { SensorProfile } from "./sensor-profile-body.js";
2
+ export type { SensorProfile, SensorProfileValueKind } from "./sensor-profile-body.js";
3
+ /** The catalogue, in the issue's order. Frozen. */
4
+ export declare const SENSOR_PROFILES: readonly SensorProfile[];
5
+ /** The profile ids, in catalogue order. */
6
+ export declare const SENSOR_PROFILE_IDS: readonly string[];
7
+ /** The profile record with this id (for `sensor.profile`); a clear error listing the ids otherwise. */
8
+ export declare function resolveSensorProfile(id: unknown): SensorProfile;