@photivra/engine 1.5.0 → 2.1.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 (1085) hide show
  1. package/CHANGELOG.md +414 -6
  2. package/CITATION.cff +1 -1
  3. package/NODE_SUPPORT.md +64 -12
  4. package/README.md +301 -182
  5. package/SECURITY.md +37 -28
  6. package/THIRD_PARTY.md +148 -4
  7. package/dist/camera/equivalent-focal-length.d.ts +13 -14
  8. package/dist/camera/equivalent-focal-length.js +15 -13
  9. package/dist/camera/equivalent-focal-length.js.map +1 -1
  10. package/dist/camera/field-of-view.d.ts +30 -19
  11. package/dist/camera/field-of-view.js +67 -18
  12. package/dist/camera/field-of-view.js.map +1 -1
  13. package/dist/camera/lens-projection.d.ts +170 -0
  14. package/dist/camera/lens-projection.js +444 -0
  15. package/dist/camera/lens-projection.js.map +1 -0
  16. package/dist/camera/projected-object-size.d.ts +10 -11
  17. package/dist/camera/projected-object-size.js +12 -10
  18. package/dist/camera/projected-object-size.js.map +1 -1
  19. package/dist/capture/capture-export-metadata.d.ts +9 -10
  20. package/dist/capture/capture-export-metadata.js +8 -5
  21. package/dist/capture/capture-export-metadata.js.map +1 -1
  22. package/dist/capture/dng-import.d.ts +91 -0
  23. package/dist/capture/dng-import.js +343 -0
  24. package/dist/capture/dng-import.js.map +1 -0
  25. package/dist/capture/environment-raw-producer.d.ts +37 -17
  26. package/dist/capture/environment-raw-producer.js +43 -19
  27. package/dist/capture/environment-raw-producer.js.map +1 -1
  28. package/dist/capture/export-jpeg.d.ts +35 -4
  29. package/dist/capture/export-jpeg.js +133 -47
  30. package/dist/capture/export-jpeg.js.map +1 -1
  31. package/dist/capture/export-tiff.d.ts +48 -24
  32. package/dist/capture/export-tiff.js +91 -31
  33. package/dist/capture/export-tiff.js.map +1 -1
  34. package/dist/capture/focus-control.d.ts +42 -65
  35. package/dist/capture/focus-control.js +56 -75
  36. package/dist/capture/focus-control.js.map +1 -1
  37. package/dist/capture/host-yield-cadence.d.ts +25 -0
  38. package/dist/capture/host-yield-cadence.js +25 -0
  39. package/dist/capture/host-yield-cadence.js.map +1 -0
  40. package/dist/capture/linear-encoding.d.ts +14 -12
  41. package/dist/capture/linear-encoding.js +14 -13
  42. package/dist/capture/linear-encoding.js.map +1 -1
  43. package/dist/capture/lossless-jpeg.d.ts +27 -0
  44. package/dist/capture/lossless-jpeg.js +237 -0
  45. package/dist/capture/lossless-jpeg.js.map +1 -0
  46. package/dist/capture/native-environment-lean.d.ts +227 -0
  47. package/dist/capture/native-environment-lean.js +974 -0
  48. package/dist/capture/native-environment-lean.js.map +1 -0
  49. package/dist/capture/native-environment-optical-stage.d.ts +97 -0
  50. package/dist/capture/native-environment-optical-stage.js +340 -0
  51. package/dist/capture/native-environment-optical-stage.js.map +1 -0
  52. package/dist/capture/native-environment-raw.d.ts +140 -6
  53. package/dist/capture/native-environment-raw.js +435 -34
  54. package/dist/capture/native-environment-raw.js.map +1 -1
  55. package/dist/capture/native-raw-development.d.ts +116 -9
  56. package/dist/capture/native-raw-development.js +221 -62
  57. package/dist/capture/native-raw-development.js.map +1 -1
  58. package/dist/capture/native-raw-dng.d.ts +60 -0
  59. package/dist/capture/native-raw-dng.js +167 -0
  60. package/dist/capture/native-raw-dng.js.map +1 -0
  61. package/dist/capture/native-raw.d.ts +65 -12
  62. package/dist/capture/native-raw.js +81 -19
  63. package/dist/capture/native-raw.js.map +1 -1
  64. package/dist/capture/packed-sensor-raw.d.ts +160 -0
  65. package/dist/capture/packed-sensor-raw.js +221 -0
  66. package/dist/capture/packed-sensor-raw.js.map +1 -0
  67. package/dist/capture/photographic-export.d.ts +58 -35
  68. package/dist/capture/photographic-export.js +177 -70
  69. package/dist/capture/photographic-export.js.map +1 -1
  70. package/dist/capture/raw-development-kernel.d.ts +52 -0
  71. package/dist/capture/raw-development-kernel.js +88 -0
  72. package/dist/capture/raw-development-kernel.js.map +1 -0
  73. package/dist/capture/raw-frame-limits.d.ts +7 -7
  74. package/dist/capture/raw-frame-limits.js +7 -6
  75. package/dist/capture/raw-frame-limits.js.map +1 -1
  76. package/dist/capture/raw-frame-reconstruction.d.ts +8 -9
  77. package/dist/capture/raw-frame-reconstruction.js +9 -8
  78. package/dist/capture/raw-frame-reconstruction.js.map +1 -1
  79. package/dist/capture/raw-white-level.d.ts +55 -0
  80. package/dist/capture/raw-white-level.js +165 -0
  81. package/dist/capture/raw-white-level.js.map +1 -0
  82. package/dist/capture/release-sequence.d.ts +5 -7
  83. package/dist/capture/release-sequence.js +15 -13
  84. package/dist/capture/release-sequence.js.map +1 -1
  85. package/dist/capture/sensor-raw-frame.d.ts +5 -6
  86. package/dist/capture/sensor-raw-frame.js +26 -9
  87. package/dist/capture/sensor-raw-frame.js.map +1 -1
  88. package/dist/capture/sensor-raw-producer.d.ts +21 -13
  89. package/dist/capture/sensor-raw-producer.js +86 -25
  90. package/dist/capture/sensor-raw-producer.js.map +1 -1
  91. package/dist/capture/simulated-capture.d.ts +15 -16
  92. package/dist/capture/simulated-capture.js +22 -12
  93. package/dist/capture/simulated-capture.js.map +1 -1
  94. package/dist/color/camera-color-matrix.d.ts +69 -0
  95. package/dist/color/camera-color-matrix.js +132 -0
  96. package/dist/color/camera-color-matrix.js.map +1 -0
  97. package/dist/color/capture-color.d.ts +17 -10
  98. package/dist/color/capture-color.js +50 -17
  99. package/dist/color/capture-color.js.map +1 -1
  100. package/dist/color/chromatic-adaptation.d.ts +63 -0
  101. package/dist/color/chromatic-adaptation.js +91 -0
  102. package/dist/color/chromatic-adaptation.js.map +1 -0
  103. package/dist/color/color-difference.d.ts +104 -0
  104. package/dist/color/color-difference.js +205 -0
  105. package/dist/color/color-difference.js.map +1 -0
  106. package/dist/color/color-matching-functions.d.ts +168 -0
  107. package/dist/color/color-matching-functions.js +309 -0
  108. package/dist/color/color-matching-functions.js.map +1 -0
  109. package/dist/color/colorimetry-math.d.ts +52 -0
  110. package/dist/color/colorimetry-math.js +144 -0
  111. package/dist/color/colorimetry-math.js.map +1 -0
  112. package/dist/color/gamut-mapping.d.ts +54 -0
  113. package/dist/color/gamut-mapping.js +107 -0
  114. package/dist/color/gamut-mapping.js.map +1 -0
  115. package/dist/color/illuminants.d.ts +182 -0
  116. package/dist/color/illuminants.js +434 -0
  117. package/dist/color/illuminants.js.map +1 -0
  118. package/dist/color/rgb-color-spaces.d.ts +79 -0
  119. package/dist/color/rgb-color-spaces.js +115 -0
  120. package/dist/color/rgb-color-spaces.js.map +1 -0
  121. package/dist/color/sensor-color-development.d.ts +33 -11
  122. package/dist/color/sensor-color-development.js +104 -30
  123. package/dist/color/sensor-color-development.js.map +1 -1
  124. package/dist/color/srgb-icc.d.ts +9 -2
  125. package/dist/color/srgb-icc.js +16 -5
  126. package/dist/color/srgb-icc.js.map +1 -1
  127. package/dist/color/srgb-transfer.d.ts +1 -2
  128. package/dist/color/srgb-transfer.js +1 -1
  129. package/dist/color/srgb-transfer.js.map +1 -1
  130. package/dist/color/white-balance.d.ts +68 -19
  131. package/dist/color/white-balance.js +168 -35
  132. package/dist/color/white-balance.js.map +1 -1
  133. package/dist/composition/image-formation-plan.d.ts +152 -128
  134. package/dist/composition/image-formation-plan.js +292 -138
  135. package/dist/composition/image-formation-plan.js.map +1 -1
  136. package/dist/composition/plan-consumer.d.ts +6 -7
  137. package/dist/composition/plan-consumer.js +14 -11
  138. package/dist/composition/plan-consumer.js.map +1 -1
  139. package/dist/core/calculation-result.d.ts +21 -14
  140. package/dist/core/calculation-result.js +209 -11
  141. package/dist/core/calculation-result.js.map +1 -1
  142. package/dist/core/canonical-json.d.ts +13 -8
  143. package/dist/core/canonical-json.js +34 -15
  144. package/dist/core/canonical-json.js.map +1 -1
  145. package/dist/core/configuration-error.d.ts +5 -4
  146. package/dist/core/configuration-error.js +5 -3
  147. package/dist/core/configuration-error.js.map +1 -1
  148. package/dist/core/evidence-provenance.d.ts +12 -12
  149. package/dist/core/evidence-provenance.js +10 -9
  150. package/dist/core/evidence-provenance.js.map +1 -1
  151. package/dist/core/image-formation.d.ts +11 -10
  152. package/dist/core/image-formation.js +11 -9
  153. package/dist/core/image-formation.js.map +1 -1
  154. package/dist/core/owned-data.d.ts +9 -17
  155. package/dist/core/owned-data.js +9 -16
  156. package/dist/core/owned-data.js.map +1 -1
  157. package/dist/core/portable-math.d.ts +15 -0
  158. package/dist/core/portable-math.js +56 -0
  159. package/dist/core/portable-math.js.map +1 -0
  160. package/dist/core/record-validation.d.ts +48 -9
  161. package/dist/core/record-validation.js +93 -19
  162. package/dist/core/record-validation.js.map +1 -1
  163. package/dist/core/scientific-assurance.d.ts +16 -14
  164. package/dist/core/scientific-assurance.js +22 -18
  165. package/dist/core/scientific-assurance.js.map +1 -1
  166. package/dist/core/spectral-composition.d.ts +13 -14
  167. package/dist/core/spectral-composition.js +30 -27
  168. package/dist/core/spectral-composition.js.map +1 -1
  169. package/dist/core/spectral.d.ts +5 -6
  170. package/dist/core/spectral.js +9 -7
  171. package/dist/core/spectral.js.map +1 -1
  172. package/dist/core/validation.d.ts +3 -6
  173. package/dist/core/validation.js +3 -5
  174. package/dist/core/validation.js.map +1 -1
  175. package/dist/core/version.d.ts +6 -6
  176. package/dist/core/version.js +6 -5
  177. package/dist/core/version.js.map +1 -1
  178. package/dist/equipment/exposure-capabilities.d.ts +10 -10
  179. package/dist/equipment/exposure-capabilities.js +40 -30
  180. package/dist/equipment/exposure-capabilities.js.map +1 -1
  181. package/dist/equipment/generic-tier-assets.d.ts +13 -6
  182. package/dist/equipment/generic-tier-assets.js +34 -15
  183. package/dist/equipment/generic-tier-assets.js.map +1 -1
  184. package/dist/equipment/generic-tier-presets.d.ts +5 -6
  185. package/dist/equipment/generic-tier-presets.js +15 -13
  186. package/dist/equipment/generic-tier-presets.js.map +1 -1
  187. package/dist/equipment/iso-capabilities.d.ts +21 -22
  188. package/dist/equipment/iso-capabilities.js +49 -44
  189. package/dist/equipment/iso-capabilities.js.map +1 -1
  190. package/dist/equipment/metering-capabilities.d.ts +5 -6
  191. package/dist/equipment/metering-capabilities.js +22 -19
  192. package/dist/equipment/metering-capabilities.js.map +1 -1
  193. package/dist/equipment/release-capabilities.d.ts +3 -4
  194. package/dist/equipment/release-capabilities.js +18 -14
  195. package/dist/equipment/release-capabilities.js.map +1 -1
  196. package/dist/exposure/exposure-duration-control.d.ts +19 -17
  197. package/dist/exposure/exposure-duration-control.js +27 -23
  198. package/dist/exposure/exposure-duration-control.js.map +1 -1
  199. package/dist/exposure/exposure-mode-resolver.d.ts +42 -39
  200. package/dist/exposure/exposure-mode-resolver.js +127 -82
  201. package/dist/exposure/exposure-mode-resolver.js.map +1 -1
  202. package/dist/exposure/exposure.d.ts +17 -16
  203. package/dist/exposure/exposure.js +22 -15
  204. package/dist/exposure/exposure.js.map +1 -1
  205. package/dist/exposure/flash-ttl.d.ts +135 -0
  206. package/dist/exposure/flash-ttl.js +193 -0
  207. package/dist/exposure/flash-ttl.js.map +1 -0
  208. package/dist/exposure/flash.d.ts +144 -36
  209. package/dist/exposure/flash.js +259 -59
  210. package/dist/exposure/flash.js.map +1 -1
  211. package/dist/exposure/metering-scene-radiance.d.ts +10 -10
  212. package/dist/exposure/metering-scene-radiance.js +42 -23
  213. package/dist/exposure/metering-scene-radiance.js.map +1 -1
  214. package/dist/exposure/metering-target.d.ts +8 -8
  215. package/dist/exposure/metering-target.js +30 -20
  216. package/dist/exposure/metering-target.js.map +1 -1
  217. package/dist/exposure/metering-temporal.d.ts +16 -15
  218. package/dist/exposure/metering-temporal.js +41 -19
  219. package/dist/exposure/metering-temporal.js.map +1 -1
  220. package/dist/exposure/metering.d.ts +64 -17
  221. package/dist/exposure/metering.js +159 -30
  222. package/dist/exposure/metering.js.map +1 -1
  223. package/dist/exposure/program-line.d.ts +5 -5
  224. package/dist/exposure/program-line.js +20 -13
  225. package/dist/exposure/program-line.js.map +1 -1
  226. package/dist/facade/camera-preset.d.ts +8 -0
  227. package/dist/facade/camera-preset.js +102 -0
  228. package/dist/facade/camera-preset.js.map +1 -0
  229. package/dist/facade/chart-radiance-batch.d.ts +57 -0
  230. package/dist/facade/chart-radiance-batch.js +121 -0
  231. package/dist/facade/chart-radiance-batch.js.map +1 -0
  232. package/dist/facade/chart-scenes.d.ts +177 -0
  233. package/dist/facade/chart-scenes.js +232 -0
  234. package/dist/facade/chart-scenes.js.map +1 -0
  235. package/dist/facade/diffraction-provider.d.ts +30 -0
  236. package/dist/facade/diffraction-provider.js +127 -0
  237. package/dist/facade/diffraction-provider.js.map +1 -0
  238. package/dist/facade/host-yield.d.ts +7 -0
  239. package/dist/facade/host-yield.js +19 -0
  240. package/dist/facade/host-yield.js.map +1 -0
  241. package/dist/facade/scene-radiance.d.ts +117 -0
  242. package/dist/facade/scene-radiance.js +205 -0
  243. package/dist/facade/scene-radiance.js.map +1 -0
  244. package/dist/facade/simulate-capture.d.ts +363 -0
  245. package/dist/facade/simulate-capture.js +1281 -0
  246. package/dist/facade/simulate-capture.js.map +1 -0
  247. package/dist/gpu/chart-radiance-gpu.d.ts +17 -0
  248. package/dist/gpu/chart-radiance-gpu.js +176 -0
  249. package/dist/gpu/chart-radiance-gpu.js.map +1 -0
  250. package/dist/gpu/image-kernel-accelerator.d.ts +132 -0
  251. package/dist/gpu/image-kernel-accelerator.js +720 -0
  252. package/dist/gpu/image-kernel-accelerator.js.map +1 -0
  253. package/dist/gpu/image-kernel-execution.d.ts +92 -0
  254. package/dist/gpu/image-kernel-execution.js +84 -0
  255. package/dist/gpu/image-kernel-execution.js.map +1 -0
  256. package/dist/gpu/sensor-stage-gpu.d.ts +44 -0
  257. package/dist/gpu/sensor-stage-gpu.js +317 -0
  258. package/dist/gpu/sensor-stage-gpu.js.map +1 -0
  259. package/dist/gpu/temporal-sum-gpu.d.ts +23 -0
  260. package/dist/gpu/temporal-sum-gpu.js +150 -0
  261. package/dist/gpu/temporal-sum-gpu.js.map +1 -0
  262. package/dist/gpu/webgpu-runtime.d.ts +63 -0
  263. package/dist/gpu/webgpu-runtime.js +215 -0
  264. package/dist/gpu/webgpu-runtime.js.map +1 -0
  265. package/dist/gpu/wgsl-chart-kernel.d.ts +30 -0
  266. package/dist/gpu/wgsl-chart-kernel.js +165 -0
  267. package/dist/gpu/wgsl-chart-kernel.js.map +1 -0
  268. package/dist/gpu/wgsl-kernels.d.ts +53 -0
  269. package/dist/gpu/wgsl-kernels.js +365 -0
  270. package/dist/gpu/wgsl-kernels.js.map +1 -0
  271. package/dist/gpu/wgsl-sensor-kernel.d.ts +64 -0
  272. package/dist/gpu/wgsl-sensor-kernel.js +409 -0
  273. package/dist/gpu/wgsl-sensor-kernel.js.map +1 -0
  274. package/dist/index.d.ts +91 -25
  275. package/dist/index.js +60 -15
  276. package/dist/index.js.map +1 -1
  277. package/dist/motion/camera-rotation.d.ts +92 -40
  278. package/dist/motion/camera-rotation.js +84 -47
  279. package/dist/motion/camera-rotation.js.map +1 -1
  280. package/dist/motion/capture-rotation-inverse-mapping.d.ts +37 -34
  281. package/dist/motion/capture-rotation-inverse-mapping.js +32 -24
  282. package/dist/motion/capture-rotation-inverse-mapping.js.map +1 -1
  283. package/dist/motion/capture-rotation-temporal-quadrature.d.ts +39 -35
  284. package/dist/motion/capture-rotation-temporal-quadrature.js +37 -28
  285. package/dist/motion/capture-rotation-temporal-quadrature.js.map +1 -1
  286. package/dist/motion/capture-rotation-trajectory.d.ts +32 -28
  287. package/dist/motion/capture-rotation-trajectory.js +36 -26
  288. package/dist/motion/capture-rotation-trajectory.js.map +1 -1
  289. package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts +23 -21
  290. package/dist/motion/capture-translation-parallax-temporal-quadrature.js +33 -14
  291. package/dist/motion/capture-translation-parallax-temporal-quadrature.js.map +1 -1
  292. package/dist/motion/extended-object-projection.d.ts +19 -16
  293. package/dist/motion/extended-object-projection.js +38 -18
  294. package/dist/motion/extended-object-projection.js.map +1 -1
  295. package/dist/motion/projected-motion.d.ts +18 -17
  296. package/dist/motion/projected-motion.js +25 -17
  297. package/dist/motion/projected-motion.js.map +1 -1
  298. package/dist/motion/temporal-exposure-sum.d.ts +55 -0
  299. package/dist/motion/temporal-exposure-sum.js +141 -0
  300. package/dist/motion/temporal-exposure-sum.js.map +1 -0
  301. package/dist/motion/video-sequence.d.ts +111 -0
  302. package/dist/motion/video-sequence.js +179 -0
  303. package/dist/motion/video-sequence.js.map +1 -0
  304. package/dist/optics/aperture.d.ts +14 -15
  305. package/dist/optics/aperture.js +13 -11
  306. package/dist/optics/aperture.js.map +1 -1
  307. package/dist/optics/atmospheric-haze.d.ts +83 -0
  308. package/dist/optics/atmospheric-haze.js +113 -0
  309. package/dist/optics/atmospheric-haze.js.map +1 -0
  310. package/dist/optics/brown-conrady-distortion.d.ts +116 -0
  311. package/dist/optics/brown-conrady-distortion.js +291 -0
  312. package/dist/optics/brown-conrady-distortion.js.map +1 -0
  313. package/dist/optics/circle-of-confusion.d.ts +10 -10
  314. package/dist/optics/circle-of-confusion.js +15 -11
  315. package/dist/optics/circle-of-confusion.js.map +1 -1
  316. package/dist/optics/complex-pupil-psf.d.ts +64 -33
  317. package/dist/optics/complex-pupil-psf.js +190 -98
  318. package/dist/optics/complex-pupil-psf.js.map +1 -1
  319. package/dist/optics/depth-of-field.d.ts +25 -15
  320. package/dist/optics/depth-of-field.js +67 -27
  321. package/dist/optics/depth-of-field.js.map +1 -1
  322. package/dist/optics/diffraction-psf-profile.d.ts +118 -0
  323. package/dist/optics/diffraction-psf-profile.js +252 -0
  324. package/dist/optics/diffraction-psf-profile.js.map +1 -0
  325. package/dist/optics/diffraction.d.ts +14 -13
  326. package/dist/optics/diffraction.js +14 -10
  327. package/dist/optics/diffraction.js.map +1 -1
  328. package/dist/optics/focus-breathing.d.ts +88 -27
  329. package/dist/optics/focus-breathing.js +114 -23
  330. package/dist/optics/focus-breathing.js.map +1 -1
  331. package/dist/optics/focus-state.d.ts +18 -18
  332. package/dist/optics/focus-state.js +21 -15
  333. package/dist/optics/focus-state.js.map +1 -1
  334. package/dist/optics/front-of-lens-filter.d.ts +45 -14
  335. package/dist/optics/front-of-lens-filter.js +259 -88
  336. package/dist/optics/front-of-lens-filter.js.map +1 -1
  337. package/dist/optics/illumination-vignetting.d.ts +16 -17
  338. package/dist/optics/illumination-vignetting.js +40 -17
  339. package/dist/optics/illumination-vignetting.js.map +1 -1
  340. package/dist/optics/irradiance-convolution.d.ts +59 -0
  341. package/dist/optics/irradiance-convolution.js +138 -0
  342. package/dist/optics/irradiance-convolution.js.map +1 -0
  343. package/dist/optics/lateral-chromatic-aberration.d.ts +33 -30
  344. package/dist/optics/lateral-chromatic-aberration.js +33 -23
  345. package/dist/optics/lateral-chromatic-aberration.js.map +1 -1
  346. package/dist/optics/lens-psf-kernels.d.ts +89 -0
  347. package/dist/optics/lens-psf-kernels.js +175 -0
  348. package/dist/optics/lens-psf-kernels.js.map +1 -0
  349. package/dist/optics/lens-psf-profile.d.ts +78 -46
  350. package/dist/optics/lens-psf-profile.js +335 -124
  351. package/dist/optics/lens-psf-profile.js.map +1 -1
  352. package/dist/optics/longitudinal-chromatic-aberration.d.ts +102 -0
  353. package/dist/optics/longitudinal-chromatic-aberration.js +210 -0
  354. package/dist/optics/longitudinal-chromatic-aberration.js.map +1 -0
  355. package/dist/optics/polygon-diffraction.d.ts +80 -23
  356. package/dist/optics/polygon-diffraction.js +130 -25
  357. package/dist/optics/polygon-diffraction.js.map +1 -1
  358. package/dist/optics/profile-contract.d.ts +5 -6
  359. package/dist/optics/profile-contract.js +14 -11
  360. package/dist/optics/profile-contract.js.map +1 -1
  361. package/dist/optics/psf-foundation.d.ts +23 -23
  362. package/dist/optics/psf-foundation.js +24 -21
  363. package/dist/optics/psf-foundation.js.map +1 -1
  364. package/dist/optics/pupil-vignetting.d.ts +118 -0
  365. package/dist/optics/pupil-vignetting.js +264 -0
  366. package/dist/optics/pupil-vignetting.js.map +1 -0
  367. package/dist/optics/radial-distortion.d.ts +34 -33
  368. package/dist/optics/radial-distortion.js +37 -30
  369. package/dist/optics/radial-distortion.js.map +1 -1
  370. package/dist/optics/scene-to-sensor-irradiance.d.ts +47 -33
  371. package/dist/optics/scene-to-sensor-irradiance.js +73 -45
  372. package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
  373. package/dist/optics/scene-to-sensor-quadrature.d.ts +23 -18
  374. package/dist/optics/scene-to-sensor-quadrature.js +16 -11
  375. package/dist/optics/scene-to-sensor-quadrature.js.map +1 -1
  376. package/dist/optics/sensor-aperture-rays.d.ts +20 -4
  377. package/dist/optics/sensor-aperture-rays.js +32 -14
  378. package/dist/optics/sensor-aperture-rays.js.map +1 -1
  379. package/dist/optics/sensor-environment-query.d.ts +81 -16
  380. package/dist/optics/sensor-environment-query.js +145 -12
  381. package/dist/optics/sensor-environment-query.js.map +1 -1
  382. package/dist/optics/sensor-psf-quadrature.d.ts +12 -10
  383. package/dist/optics/sensor-psf-quadrature.js +18 -11
  384. package/dist/optics/sensor-psf-quadrature.js.map +1 -1
  385. package/dist/optics/sensor-psf-support.d.ts +8 -6
  386. package/dist/optics/sensor-psf-support.js +8 -5
  387. package/dist/optics/sensor-psf-support.js.map +1 -1
  388. package/dist/optics/stray-light.d.ts +22 -19
  389. package/dist/optics/stray-light.js +18 -12
  390. package/dist/optics/stray-light.js.map +1 -1
  391. package/dist/optics/thin-lens.d.ts +10 -9
  392. package/dist/optics/thin-lens.js +12 -8
  393. package/dist/optics/thin-lens.js.map +1 -1
  394. package/dist/optics/zernike-wavefront.d.ts +154 -0
  395. package/dist/optics/zernike-wavefront.js +352 -0
  396. package/dist/optics/zernike-wavefront.js.map +1 -0
  397. package/dist/output/capture-corrected-sdr.d.ts +16 -8
  398. package/dist/output/capture-corrected-sdr.js +16 -8
  399. package/dist/output/capture-corrected-sdr.js.map +1 -1
  400. package/dist/output/capture-geometry.d.ts +34 -36
  401. package/dist/output/capture-geometry.js +52 -32
  402. package/dist/output/capture-geometry.js.map +1 -1
  403. package/dist/output/capture-sdr.d.ts +7 -6
  404. package/dist/output/capture-sdr.js +11 -8
  405. package/dist/output/capture-sdr.js.map +1 -1
  406. package/dist/output/crop.d.ts +22 -6
  407. package/dist/output/crop.js +40 -6
  408. package/dist/output/crop.js.map +1 -1
  409. package/dist/output/geometric-transforms.d.ts +60 -23
  410. package/dist/output/geometric-transforms.js +111 -24
  411. package/dist/output/geometric-transforms.js.map +1 -1
  412. package/dist/output/lens-corrections.d.ts +27 -19
  413. package/dist/output/lens-corrections.js +29 -13
  414. package/dist/output/lens-corrections.js.map +1 -1
  415. package/dist/output/native-capture-sdr.d.ts +71 -16
  416. package/dist/output/native-capture-sdr.js +190 -33
  417. package/dist/output/native-capture-sdr.js.map +1 -1
  418. package/dist/output/png-encoder.d.ts +65 -0
  419. package/dist/output/png-encoder.js +461 -0
  420. package/dist/output/png-encoder.js.map +1 -0
  421. package/dist/output/print-contrast-reference.d.ts +10 -9
  422. package/dist/output/print-contrast-reference.js +10 -8
  423. package/dist/output/print-contrast-reference.js.map +1 -1
  424. package/dist/output/print-detail.d.ts +18 -17
  425. package/dist/output/print-detail.js +12 -10
  426. package/dist/output/print-detail.js.map +1 -1
  427. package/dist/output/print-jpeg.d.ts +26 -5
  428. package/dist/output/print-jpeg.js +117 -50
  429. package/dist/output/print-jpeg.js.map +1 -1
  430. package/dist/output/print-plan.d.ts +19 -19
  431. package/dist/output/print-plan.js +11 -10
  432. package/dist/output/print-plan.js.map +1 -1
  433. package/dist/output/print-region-statistics.d.ts +14 -15
  434. package/dist/output/print-region-statistics.js +11 -11
  435. package/dist/output/print-region-statistics.js.map +1 -1
  436. package/dist/output/sdr-rendering.d.ts +48 -10
  437. package/dist/output/sdr-rendering.js +114 -25
  438. package/dist/output/sdr-rendering.js.map +1 -1
  439. package/dist/output/subject-framing-crop.d.ts +6 -10
  440. package/dist/output/subject-framing-crop.js +23 -13
  441. package/dist/output/subject-framing-crop.js.map +1 -1
  442. package/dist/processing/demosaic.d.ts +90 -0
  443. package/dist/processing/demosaic.js +275 -0
  444. package/dist/processing/demosaic.js.map +1 -0
  445. package/dist/processing/denoise.d.ts +68 -0
  446. package/dist/processing/denoise.js +214 -0
  447. package/dist/processing/denoise.js.map +1 -0
  448. package/dist/processing/focus-stacking.d.ts +17 -0
  449. package/dist/processing/focus-stacking.js +80 -0
  450. package/dist/processing/focus-stacking.js.map +1 -0
  451. package/dist/processing/hdr.d.ts +54 -0
  452. package/dist/processing/hdr.js +172 -0
  453. package/dist/processing/hdr.js.map +1 -0
  454. package/dist/processing/image-ops.d.ts +66 -0
  455. package/dist/processing/image-ops.js +192 -0
  456. package/dist/processing/image-ops.js.map +1 -0
  457. package/dist/processing/panorama.d.ts +51 -0
  458. package/dist/processing/panorama.js +305 -0
  459. package/dist/processing/panorama.js.map +1 -0
  460. package/dist/processing/processing-task.d.ts +85 -0
  461. package/dist/processing/processing-task.js +164 -0
  462. package/dist/processing/processing-task.js.map +1 -0
  463. package/dist/processing/tone-mapping.d.ts +69 -0
  464. package/dist/processing/tone-mapping.js +310 -0
  465. package/dist/processing/tone-mapping.js.map +1 -0
  466. package/dist/schema/camera.d.ts +5 -4
  467. package/dist/schema/illumination-spectral.d.ts +13 -19
  468. package/dist/schema/illumination-spectral.js +23 -19
  469. package/dist/schema/illumination-spectral.js.map +1 -1
  470. package/dist/schema/illumination-temporal.d.ts +12 -15
  471. package/dist/schema/illumination-temporal.js +43 -28
  472. package/dist/schema/illumination-temporal.js.map +1 -1
  473. package/dist/schema/illumination.d.ts +5 -4
  474. package/dist/schema/illumination.js +55 -20
  475. package/dist/schema/illumination.js.map +1 -1
  476. package/dist/schema/scene-radiance-temporal.d.ts +9 -11
  477. package/dist/schema/scene-radiance-temporal.js +26 -23
  478. package/dist/schema/scene-radiance-temporal.js.map +1 -1
  479. package/dist/schema/scene-radiance.d.ts +17 -17
  480. package/dist/schema/scene-radiance.js +56 -34
  481. package/dist/schema/scene-radiance.js.map +1 -1
  482. package/dist/schema/scene.d.ts +14 -13
  483. package/dist/schema/validation.d.ts +0 -1
  484. package/dist/schema/validation.js +17 -15
  485. package/dist/schema/validation.js.map +1 -1
  486. package/dist/sensor/accumulated-charge.d.ts +45 -64
  487. package/dist/sensor/accumulated-charge.js +41 -47
  488. package/dist/sensor/accumulated-charge.js.map +1 -1
  489. package/dist/sensor/architecture.d.ts +22 -25
  490. package/dist/sensor/architecture.js +17 -16
  491. package/dist/sensor/architecture.js.map +1 -1
  492. package/dist/sensor/camera-saturation-capacity.d.ts +21 -28
  493. package/dist/sensor/camera-saturation-capacity.js +36 -34
  494. package/dist/sensor/camera-saturation-capacity.js.map +1 -1
  495. package/dist/sensor/capture-color-sampling-binding.d.ts +46 -51
  496. package/dist/sensor/capture-color-sampling-binding.js +39 -41
  497. package/dist/sensor/capture-color-sampling-binding.js.map +1 -1
  498. package/dist/sensor/capture-mode-timing.d.ts +8 -9
  499. package/dist/sensor/capture-mode-timing.js +24 -21
  500. package/dist/sensor/capture-mode-timing.js.map +1 -1
  501. package/dist/sensor/capture-mode.d.ts +28 -30
  502. package/dist/sensor/capture-mode.js +33 -31
  503. package/dist/sensor/capture-mode.js.map +1 -1
  504. package/dist/sensor/color-sampling.d.ts +30 -33
  505. package/dist/sensor/color-sampling.js +32 -37
  506. package/dist/sensor/color-sampling.js.map +1 -1
  507. package/dist/sensor/constant-rate-temporal-integration.d.ts +19 -23
  508. package/dist/sensor/constant-rate-temporal-integration.js +28 -26
  509. package/dist/sensor/constant-rate-temporal-integration.js.map +1 -1
  510. package/dist/sensor/dark-current.d.ts +53 -49
  511. package/dist/sensor/dark-current.js +87 -46
  512. package/dist/sensor/dark-current.js.map +1 -1
  513. package/dist/sensor/environment-photo-signal.d.ts +71 -30
  514. package/dist/sensor/environment-photo-signal.js +127 -46
  515. package/dist/sensor/environment-photo-signal.js.map +1 -1
  516. package/dist/sensor/eqe-electron-rate.d.ts +14 -13
  517. package/dist/sensor/eqe-electron-rate.js +34 -14
  518. package/dist/sensor/eqe-electron-rate.js.map +1 -1
  519. package/dist/sensor/eqe-local-exposure.d.ts +24 -24
  520. package/dist/sensor/eqe-local-exposure.js +15 -11
  521. package/dist/sensor/eqe-local-exposure.js.map +1 -1
  522. package/dist/sensor/eqe-temporal-exposure.d.ts +11 -11
  523. package/dist/sensor/eqe-temporal-exposure.js +15 -10
  524. package/dist/sensor/eqe-temporal-exposure.js.map +1 -1
  525. package/dist/sensor/exposure-window.d.ts +48 -34
  526. package/dist/sensor/exposure-window.js +77 -36
  527. package/dist/sensor/exposure-window.js.map +1 -1
  528. package/dist/sensor/fixed-pattern-noise.d.ts +108 -0
  529. package/dist/sensor/fixed-pattern-noise.js +166 -0
  530. package/dist/sensor/fixed-pattern-noise.js.map +1 -0
  531. package/dist/sensor/iso-gain.d.ts +44 -0
  532. package/dist/sensor/iso-gain.js +119 -0
  533. package/dist/sensor/iso-gain.js.map +1 -0
  534. package/dist/sensor/iso-signal-chain.d.ts +25 -48
  535. package/dist/sensor/iso-signal-chain.js +52 -66
  536. package/dist/sensor/iso-signal-chain.js.map +1 -1
  537. package/dist/sensor/local-exposure-binding.d.ts +21 -21
  538. package/dist/sensor/local-exposure-binding.js +22 -18
  539. package/dist/sensor/local-exposure-binding.js.map +1 -1
  540. package/dist/sensor/optical-stack.d.ts +36 -40
  541. package/dist/sensor/optical-stack.js +34 -37
  542. package/dist/sensor/optical-stack.js.map +1 -1
  543. package/dist/sensor/photon-energy.d.ts +22 -28
  544. package/dist/sensor/photon-energy.js +42 -34
  545. package/dist/sensor/photon-energy.js.map +1 -1
  546. package/dist/sensor/physical-charge-capacity.d.ts +20 -30
  547. package/dist/sensor/physical-charge-capacity.js +35 -36
  548. package/dist/sensor/physical-charge-capacity.js.map +1 -1
  549. package/dist/sensor/pixel-pitch.d.ts +2 -3
  550. package/dist/sensor/pixel-pitch.js +4 -2
  551. package/dist/sensor/pixel-pitch.js.map +1 -1
  552. package/dist/sensor/radiometry-readiness.d.ts +13 -15
  553. package/dist/sensor/radiometry-readiness.js +20 -17
  554. package/dist/sensor/radiometry-readiness.js.map +1 -1
  555. package/dist/sensor/raw-readout.d.ts +173 -83
  556. package/dist/sensor/raw-readout.js +425 -160
  557. package/dist/sensor/raw-readout.js.map +1 -1
  558. package/dist/sensor/raw-reconstruction.d.ts +112 -44
  559. package/dist/sensor/raw-reconstruction.js +200 -47
  560. package/dist/sensor/raw-reconstruction.js.map +1 -1
  561. package/dist/sensor/readout-exposure-linkage.d.ts +103 -34
  562. package/dist/sensor/readout-exposure-linkage.js +125 -27
  563. package/dist/sensor/readout-exposure-linkage.js.map +1 -1
  564. package/dist/sensor/readout-timing.d.ts +43 -44
  565. package/dist/sensor/readout-timing.js +38 -30
  566. package/dist/sensor/readout-timing.js.map +1 -1
  567. package/dist/sensor/response-application-compatibility.d.ts +21 -28
  568. package/dist/sensor/response-application-compatibility.js +35 -34
  569. package/dist/sensor/response-application-compatibility.js.map +1 -1
  570. package/dist/sensor/response-operating-range.d.ts +26 -35
  571. package/dist/sensor/response-operating-range.js +40 -39
  572. package/dist/sensor/response-operating-range.js.map +1 -1
  573. package/dist/sensor/responsivity-photocurrent.d.ts +21 -29
  574. package/dist/sensor/responsivity-photocurrent.js +57 -40
  575. package/dist/sensor/responsivity-photocurrent.js.map +1 -1
  576. package/dist/sensor/sampling-aperture.d.ts +21 -25
  577. package/dist/sensor/sampling-aperture.js +29 -28
  578. package/dist/sensor/sampling-aperture.js.map +1 -1
  579. package/dist/sensor/scene-eqe-temporal-exposure.d.ts +14 -12
  580. package/dist/sensor/scene-eqe-temporal-exposure.js +13 -8
  581. package/dist/sensor/scene-eqe-temporal-exposure.js.map +1 -1
  582. package/dist/sensor/sensor-geometry.d.ts +28 -32
  583. package/dist/sensor/sensor-geometry.js +35 -20
  584. package/dist/sensor/sensor-geometry.js.map +1 -1
  585. package/dist/sensor/signal-noise.d.ts +14 -16
  586. package/dist/sensor/signal-noise.js +15 -13
  587. package/dist/sensor/signal-noise.js.map +1 -1
  588. package/dist/sensor/spatial-sample-reduction.d.ts +45 -60
  589. package/dist/sensor/spatial-sample-reduction.js +39 -48
  590. package/dist/sensor/spatial-sample-reduction.js.map +1 -1
  591. package/dist/sensor/spatial-sampling-quadrature.d.ts +46 -54
  592. package/dist/sensor/spatial-sampling-quadrature.js +31 -36
  593. package/dist/sensor/spatial-sampling-quadrature.js.map +1 -1
  594. package/dist/sensor/spatio-spectral-reduction.d.ts +32 -42
  595. package/dist/sensor/spatio-spectral-reduction.js +24 -29
  596. package/dist/sensor/spatio-spectral-reduction.js.map +1 -1
  597. package/dist/sensor/spectral-coverage.d.ts +6 -9
  598. package/dist/sensor/spectral-coverage.js +9 -6
  599. package/dist/sensor/spectral-coverage.js.map +1 -1
  600. package/dist/sensor/spectral-quadrature.d.ts +46 -60
  601. package/dist/sensor/spectral-quadrature.js +38 -48
  602. package/dist/sensor/spectral-quadrature.js.map +1 -1
  603. package/dist/sensor/spectral-response.d.ts +53 -41
  604. package/dist/sensor/spectral-response.js +80 -47
  605. package/dist/sensor/spectral-response.js.map +1 -1
  606. package/dist/sensor/stochastic-seed.d.ts +50 -0
  607. package/dist/sensor/stochastic-seed.js +123 -0
  608. package/dist/sensor/stochastic-seed.js.map +1 -0
  609. package/dist/sensor/temporal-eqe-sum.d.ts +2 -4
  610. package/dist/sensor/temporal-eqe-sum.js +5 -6
  611. package/dist/sensor/temporal-eqe-sum.js.map +1 -1
  612. package/dist/sensor/temporal-photo-signal.d.ts +5 -6
  613. package/dist/sensor/temporal-photo-signal.js +11 -10
  614. package/dist/sensor/temporal-photo-signal.js.map +1 -1
  615. package/dist/sensor/temporal-sample-binding.d.ts +1 -2
  616. package/dist/sensor/temporal-sample-binding.js +3 -3
  617. package/dist/sensor/temporal-sample-binding.js.map +1 -1
  618. package/dist/simulation/poc-simulation.d.ts +16 -16
  619. package/dist/simulation/poc-simulation.js +20 -15
  620. package/dist/simulation/poc-simulation.js.map +1 -1
  621. package/dist/stabilization/camera-shake.d.ts +42 -18
  622. package/dist/stabilization/camera-shake.js +43 -20
  623. package/dist/stabilization/camera-shake.js.map +1 -1
  624. package/dist/stabilization/system.d.ts +44 -41
  625. package/dist/stabilization/system.js +196 -108
  626. package/dist/stabilization/system.js.map +1 -1
  627. package/docs/AGENT_GUIDE.md +183 -0
  628. package/docs/API_REFERENCE.md +777 -2
  629. package/docs/QUICK_START.md +663 -0
  630. package/docs/USAGE.md +1719 -714
  631. package/docs/api/camera-equivalent-focal-length.md +6 -7
  632. package/docs/api/camera-field-of-view.md +16 -8
  633. package/docs/api/camera-lens-projection.md +246 -0
  634. package/docs/api/camera-projected-object-size.md +6 -5
  635. package/docs/api/capture-capture-export-metadata.md +10 -10
  636. package/docs/api/capture-dng-import.md +134 -0
  637. package/docs/api/capture-environment-raw-producer.md +17 -11
  638. package/docs/api/capture-export-jpeg.md +16 -0
  639. package/docs/api/capture-focus-control.md +25 -47
  640. package/docs/api/capture-linear-encoding.md +21 -12
  641. package/docs/api/capture-lossless-jpeg.md +49 -0
  642. package/docs/api/capture-native-environment-optical-stage.md +75 -0
  643. package/docs/api/capture-native-environment-raw.md +161 -4
  644. package/docs/api/capture-native-raw-development.md +69 -8
  645. package/docs/api/capture-native-raw-dng.md +84 -0
  646. package/docs/api/capture-native-raw.md +21 -10
  647. package/docs/api/capture-packed-sensor-raw.md +156 -0
  648. package/docs/api/capture-photographic-export.md +69 -31
  649. package/docs/api/capture-raw-frame-reconstruction.md +8 -8
  650. package/docs/api/capture-raw-white-level.md +37 -0
  651. package/docs/api/capture-release-sequence.md +6 -7
  652. package/docs/api/capture-sensor-raw-frame.md +6 -6
  653. package/docs/api/capture-sensor-raw-producer.md +17 -11
  654. package/docs/api/capture-simulated-capture.md +15 -15
  655. package/docs/api/color-camera-color-matrix.md +103 -0
  656. package/docs/api/color-capture-color.md +22 -11
  657. package/docs/api/color-chromatic-adaptation.md +82 -0
  658. package/docs/api/color-color-difference.md +134 -0
  659. package/docs/api/color-color-matching-functions.md +259 -0
  660. package/docs/api/color-colorimetry-math.md +54 -0
  661. package/docs/api/color-gamut-mapping.md +72 -0
  662. package/docs/api/color-illuminants.md +280 -0
  663. package/docs/api/color-rgb-color-spaces.md +151 -0
  664. package/docs/api/color-sensor-color-development.md +27 -0
  665. package/docs/api/color-srgb-icc.md +2 -4
  666. package/docs/api/color-white-balance.md +95 -19
  667. package/docs/api/composition-image-formation-plan.md +124 -95
  668. package/docs/api/composition-plan-consumer.md +7 -7
  669. package/docs/api/core-calculation-result.md +18 -14
  670. package/docs/api/core-configuration-error.md +1 -1
  671. package/docs/api/core-image-formation.md +7 -7
  672. package/docs/api/core-scientific-assurance.md +12 -10
  673. package/docs/api/core-spectral-composition.md +14 -14
  674. package/docs/api/core-spectral.md +6 -6
  675. package/docs/api/core-validation.md +3 -3
  676. package/docs/api/core-version.md +7 -6
  677. package/docs/api/equipment-exposure-capabilities.md +11 -10
  678. package/docs/api/equipment-generic-tier-assets.md +7 -2
  679. package/docs/api/equipment-generic-tier-presets.md +6 -6
  680. package/docs/api/equipment-iso-capabilities.md +18 -18
  681. package/docs/api/equipment-metering-capabilities.md +6 -6
  682. package/docs/api/equipment-release-capabilities.md +4 -4
  683. package/docs/api/exports.json +2253 -3
  684. package/docs/api/exposure-exposure-duration-control.md +9 -9
  685. package/docs/api/exposure-exposure-mode-resolver.md +35 -31
  686. package/docs/api/exposure-exposure.md +10 -10
  687. package/docs/api/exposure-flash-ttl.md +182 -0
  688. package/docs/api/exposure-flash.md +183 -28
  689. package/docs/api/exposure-metering-scene-radiance.md +11 -10
  690. package/docs/api/exposure-metering-target.md +9 -8
  691. package/docs/api/exposure-metering-temporal.md +8 -8
  692. package/docs/api/exposure-metering.md +69 -9
  693. package/docs/api/exposure-program-line.md +6 -5
  694. package/docs/api/facade-chart-radiance-batch.md +96 -0
  695. package/docs/api/facade-chart-scenes.md +240 -0
  696. package/docs/api/facade-scene-radiance.md +122 -0
  697. package/docs/api/facade-simulate-capture.md +397 -0
  698. package/docs/api/gpu-image-kernel-accelerator.md +157 -0
  699. package/docs/api/gpu-image-kernel-execution.md +152 -0
  700. package/docs/api/motion-camera-rotation.md +43 -26
  701. package/docs/api/motion-capture-rotation-inverse-mapping.md +24 -23
  702. package/docs/api/motion-capture-rotation-temporal-quadrature.md +22 -22
  703. package/docs/api/motion-capture-rotation-trajectory.md +15 -15
  704. package/docs/api/motion-capture-translation-parallax-temporal-quadrature.md +15 -14
  705. package/docs/api/motion-extended-object-projection.md +10 -8
  706. package/docs/api/motion-projected-motion.md +8 -8
  707. package/docs/api/motion-temporal-exposure-sum.md +98 -0
  708. package/docs/api/motion-video-sequence.md +159 -0
  709. package/docs/api/optics-aperture.md +8 -8
  710. package/docs/api/optics-atmospheric-haze.md +104 -0
  711. package/docs/api/optics-brown-conrady-distortion.md +123 -0
  712. package/docs/api/optics-circle-of-confusion.md +5 -4
  713. package/docs/api/optics-complex-pupil-psf.md +57 -16
  714. package/docs/api/optics-depth-of-field.md +12 -6
  715. package/docs/api/optics-diffraction-psf-profile.md +96 -0
  716. package/docs/api/optics-diffraction.md +8 -7
  717. package/docs/api/optics-focus-breathing.md +104 -16
  718. package/docs/api/optics-focus-state.md +9 -10
  719. package/docs/api/optics-front-of-lens-filter.md +72 -14
  720. package/docs/api/optics-illumination-vignetting.md +10 -10
  721. package/docs/api/optics-irradiance-convolution.md +95 -0
  722. package/docs/api/optics-lateral-chromatic-aberration.md +22 -21
  723. package/docs/api/optics-lens-psf-kernels.md +72 -0
  724. package/docs/api/optics-lens-psf-profile.md +48 -26
  725. package/docs/api/optics-longitudinal-chromatic-aberration.md +128 -0
  726. package/docs/api/optics-polygon-diffraction.md +78 -13
  727. package/docs/api/optics-profile-contract.md +4 -4
  728. package/docs/api/optics-psf-foundation.md +12 -12
  729. package/docs/api/optics-pupil-vignetting.md +132 -0
  730. package/docs/api/optics-radial-distortion.md +12 -12
  731. package/docs/api/optics-scene-to-sensor-irradiance.md +25 -14
  732. package/docs/api/optics-scene-to-sensor-quadrature.md +15 -12
  733. package/docs/api/optics-sensor-aperture-rays.md +3 -2
  734. package/docs/api/optics-sensor-environment-query.md +52 -9
  735. package/docs/api/optics-sensor-psf-quadrature.md +13 -10
  736. package/docs/api/optics-stray-light.md +12 -11
  737. package/docs/api/optics-thin-lens.md +4 -3
  738. package/docs/api/optics-zernike-wavefront.md +229 -0
  739. package/docs/api/output-capture-corrected-sdr.md +10 -7
  740. package/docs/api/output-capture-geometry.md +35 -36
  741. package/docs/api/output-capture-sdr.md +4 -4
  742. package/docs/api/output-crop.md +7 -4
  743. package/docs/api/output-geometric-transforms.md +65 -19
  744. package/docs/api/output-lens-corrections.md +17 -15
  745. package/docs/api/output-native-capture-sdr.md +26 -13
  746. package/docs/api/output-png-encoder.md +105 -0
  747. package/docs/api/output-print-contrast-reference.md +8 -8
  748. package/docs/api/output-print-detail.md +14 -14
  749. package/docs/api/output-print-jpeg.md +22 -5
  750. package/docs/api/output-print-plan.md +18 -18
  751. package/docs/api/output-print-region-statistics.md +14 -14
  752. package/docs/api/output-sdr-rendering.md +52 -10
  753. package/docs/api/output-subject-framing-crop.md +5 -6
  754. package/docs/api/processing-demosaic.md +120 -0
  755. package/docs/api/processing-denoise.md +148 -0
  756. package/docs/api/processing-focus-stacking.md +41 -0
  757. package/docs/api/processing-hdr.md +113 -0
  758. package/docs/api/processing-panorama.md +82 -0
  759. package/docs/api/processing-processing-task.md +107 -0
  760. package/docs/api/processing-tone-mapping.md +142 -0
  761. package/docs/api/schema-camera.md +6 -4
  762. package/docs/api/schema-illumination-spectral.md +10 -11
  763. package/docs/api/schema-illumination-temporal.md +13 -15
  764. package/docs/api/schema-illumination.md +4 -4
  765. package/docs/api/schema-scene-radiance-temporal.md +10 -11
  766. package/docs/api/schema-scene-radiance.md +18 -17
  767. package/docs/api/schema-scene.md +9 -9
  768. package/docs/api/schema-validation.md +1 -1
  769. package/docs/api/sensor-accumulated-charge.md +12 -20
  770. package/docs/api/sensor-architecture.md +15 -16
  771. package/docs/api/sensor-camera-saturation-capacity.md +9 -11
  772. package/docs/api/sensor-capture-color-sampling-binding.md +47 -51
  773. package/docs/api/sensor-capture-mode-timing.md +9 -9
  774. package/docs/api/sensor-capture-mode.md +29 -30
  775. package/docs/api/sensor-color-sampling.md +31 -33
  776. package/docs/api/sensor-constant-rate-temporal-integration.md +10 -11
  777. package/docs/api/sensor-dark-current.md +30 -14
  778. package/docs/api/sensor-environment-photo-signal.md +13 -6
  779. package/docs/api/sensor-eqe-electron-rate.md +9 -8
  780. package/docs/api/sensor-eqe-local-exposure.md +18 -17
  781. package/docs/api/sensor-eqe-temporal-exposure.md +12 -11
  782. package/docs/api/sensor-exposure-window.md +24 -24
  783. package/docs/api/sensor-fixed-pattern-noise.md +104 -0
  784. package/docs/api/sensor-iso-gain.md +63 -0
  785. package/docs/api/sensor-iso-signal-chain.md +13 -22
  786. package/docs/api/sensor-local-exposure-binding.md +12 -13
  787. package/docs/api/sensor-optical-stack.md +37 -40
  788. package/docs/api/sensor-photon-energy.md +10 -11
  789. package/docs/api/sensor-physical-charge-capacity.md +8 -13
  790. package/docs/api/sensor-pixel-pitch.md +1 -1
  791. package/docs/api/sensor-radiometry-readiness.md +9 -9
  792. package/docs/api/sensor-raw-readout.md +118 -52
  793. package/docs/api/sensor-raw-reconstruction.md +97 -20
  794. package/docs/api/sensor-readout-exposure-linkage.md +120 -24
  795. package/docs/api/sensor-readout-timing.md +33 -35
  796. package/docs/api/sensor-response-application-compatibility.md +9 -11
  797. package/docs/api/sensor-response-operating-range.md +14 -18
  798. package/docs/api/sensor-responsivity-photocurrent.md +9 -12
  799. package/docs/api/sensor-sampling-aperture.md +22 -25
  800. package/docs/api/sensor-scene-eqe-temporal-exposure.md +9 -8
  801. package/docs/api/sensor-sensor-geometry.md +23 -24
  802. package/docs/api/sensor-signal-noise.md +10 -10
  803. package/docs/api/sensor-spatial-sample-reduction.md +27 -30
  804. package/docs/api/sensor-spatial-sampling-quadrature.md +37 -39
  805. package/docs/api/sensor-spatio-spectral-reduction.md +27 -29
  806. package/docs/api/sensor-spectral-coverage.md +5 -5
  807. package/docs/api/sensor-spectral-quadrature.md +33 -35
  808. package/docs/api/sensor-spectral-response.md +28 -16
  809. package/docs/api/sensor-temporal-photo-signal.md +6 -6
  810. package/docs/api/simulation-poc-simulation.md +17 -16
  811. package/docs/api/stabilization-camera-shake.md +29 -10
  812. package/docs/api/stabilization-system.md +25 -21
  813. package/docs/examples/production-request.json +3821 -2157
  814. package/docs/examples/simulate-capture.mjs +14 -0
  815. package/llms.txt +35 -0
  816. package/package.json +32 -11
  817. package/AGENTS.md +0 -674
  818. package/CONTRIBUTING.md +0 -76
  819. package/DCO +0 -33
  820. package/dist/camera/equivalent-focal-length.d.ts.map +0 -1
  821. package/dist/camera/field-of-view.d.ts.map +0 -1
  822. package/dist/camera/projected-object-size.d.ts.map +0 -1
  823. package/dist/capture/capture-export-metadata.d.ts.map +0 -1
  824. package/dist/capture/environment-raw-producer.d.ts.map +0 -1
  825. package/dist/capture/export-jpeg.d.ts.map +0 -1
  826. package/dist/capture/export-tiff.d.ts.map +0 -1
  827. package/dist/capture/focus-control.d.ts.map +0 -1
  828. package/dist/capture/linear-encoding.d.ts.map +0 -1
  829. package/dist/capture/native-environment-raw.d.ts.map +0 -1
  830. package/dist/capture/native-raw-development.d.ts.map +0 -1
  831. package/dist/capture/native-raw.d.ts.map +0 -1
  832. package/dist/capture/photographic-export.d.ts.map +0 -1
  833. package/dist/capture/raw-frame-limits.d.ts.map +0 -1
  834. package/dist/capture/raw-frame-reconstruction.d.ts.map +0 -1
  835. package/dist/capture/release-sequence.d.ts.map +0 -1
  836. package/dist/capture/sensor-raw-frame.d.ts.map +0 -1
  837. package/dist/capture/sensor-raw-producer.d.ts.map +0 -1
  838. package/dist/capture/simulated-capture.d.ts.map +0 -1
  839. package/dist/color/capture-color.d.ts.map +0 -1
  840. package/dist/color/sensor-color-development.d.ts.map +0 -1
  841. package/dist/color/srgb-icc.d.ts.map +0 -1
  842. package/dist/color/srgb-transfer.d.ts.map +0 -1
  843. package/dist/color/white-balance.d.ts.map +0 -1
  844. package/dist/composition/image-formation-plan.d.ts.map +0 -1
  845. package/dist/composition/plan-consumer.d.ts.map +0 -1
  846. package/dist/core/calculation-result.d.ts.map +0 -1
  847. package/dist/core/canonical-json.d.ts.map +0 -1
  848. package/dist/core/configuration-error.d.ts.map +0 -1
  849. package/dist/core/evidence-provenance.d.ts.map +0 -1
  850. package/dist/core/image-formation.d.ts.map +0 -1
  851. package/dist/core/owned-data.d.ts.map +0 -1
  852. package/dist/core/record-validation.d.ts.map +0 -1
  853. package/dist/core/scientific-assurance.d.ts.map +0 -1
  854. package/dist/core/spectral-composition.d.ts.map +0 -1
  855. package/dist/core/spectral.d.ts.map +0 -1
  856. package/dist/core/validation.d.ts.map +0 -1
  857. package/dist/core/version.d.ts.map +0 -1
  858. package/dist/equipment/exposure-capabilities.d.ts.map +0 -1
  859. package/dist/equipment/generic-tier-assets.d.ts.map +0 -1
  860. package/dist/equipment/generic-tier-presets.d.ts.map +0 -1
  861. package/dist/equipment/iso-capabilities.d.ts.map +0 -1
  862. package/dist/equipment/metering-capabilities.d.ts.map +0 -1
  863. package/dist/equipment/release-capabilities.d.ts.map +0 -1
  864. package/dist/exposure/exposure-duration-control.d.ts.map +0 -1
  865. package/dist/exposure/exposure-mode-resolver.d.ts.map +0 -1
  866. package/dist/exposure/exposure.d.ts.map +0 -1
  867. package/dist/exposure/flash.d.ts.map +0 -1
  868. package/dist/exposure/metering-scene-radiance.d.ts.map +0 -1
  869. package/dist/exposure/metering-target.d.ts.map +0 -1
  870. package/dist/exposure/metering-temporal.d.ts.map +0 -1
  871. package/dist/exposure/metering.d.ts.map +0 -1
  872. package/dist/exposure/program-line.d.ts.map +0 -1
  873. package/dist/index.d.ts.map +0 -1
  874. package/dist/motion/camera-rotation.d.ts.map +0 -1
  875. package/dist/motion/capture-rotation-inverse-mapping.d.ts.map +0 -1
  876. package/dist/motion/capture-rotation-temporal-quadrature.d.ts.map +0 -1
  877. package/dist/motion/capture-rotation-trajectory.d.ts.map +0 -1
  878. package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts.map +0 -1
  879. package/dist/motion/extended-object-projection.d.ts.map +0 -1
  880. package/dist/motion/projected-motion.d.ts.map +0 -1
  881. package/dist/optics/aperture.d.ts.map +0 -1
  882. package/dist/optics/circle-of-confusion.d.ts.map +0 -1
  883. package/dist/optics/complex-pupil-psf.d.ts.map +0 -1
  884. package/dist/optics/depth-of-field.d.ts.map +0 -1
  885. package/dist/optics/diffraction.d.ts.map +0 -1
  886. package/dist/optics/focus-breathing.d.ts.map +0 -1
  887. package/dist/optics/focus-state.d.ts.map +0 -1
  888. package/dist/optics/front-of-lens-filter.d.ts.map +0 -1
  889. package/dist/optics/illumination-vignetting.d.ts.map +0 -1
  890. package/dist/optics/lateral-chromatic-aberration.d.ts.map +0 -1
  891. package/dist/optics/lens-psf-profile.d.ts.map +0 -1
  892. package/dist/optics/polygon-diffraction.d.ts.map +0 -1
  893. package/dist/optics/profile-contract.d.ts.map +0 -1
  894. package/dist/optics/psf-foundation.d.ts.map +0 -1
  895. package/dist/optics/radial-distortion.d.ts.map +0 -1
  896. package/dist/optics/scene-to-sensor-irradiance.d.ts.map +0 -1
  897. package/dist/optics/scene-to-sensor-quadrature.d.ts.map +0 -1
  898. package/dist/optics/sensor-aperture-rays.d.ts.map +0 -1
  899. package/dist/optics/sensor-environment-query.d.ts.map +0 -1
  900. package/dist/optics/sensor-psf-quadrature.d.ts.map +0 -1
  901. package/dist/optics/sensor-psf-support.d.ts.map +0 -1
  902. package/dist/optics/stray-light.d.ts.map +0 -1
  903. package/dist/optics/thin-lens.d.ts.map +0 -1
  904. package/dist/output/capture-corrected-sdr.d.ts.map +0 -1
  905. package/dist/output/capture-geometry.d.ts.map +0 -1
  906. package/dist/output/capture-sdr.d.ts.map +0 -1
  907. package/dist/output/crop.d.ts.map +0 -1
  908. package/dist/output/geometric-transforms.d.ts.map +0 -1
  909. package/dist/output/lens-corrections.d.ts.map +0 -1
  910. package/dist/output/native-capture-sdr.d.ts.map +0 -1
  911. package/dist/output/print-contrast-reference.d.ts.map +0 -1
  912. package/dist/output/print-detail.d.ts.map +0 -1
  913. package/dist/output/print-jpeg.d.ts.map +0 -1
  914. package/dist/output/print-plan.d.ts.map +0 -1
  915. package/dist/output/print-region-statistics.d.ts.map +0 -1
  916. package/dist/output/sdr-rendering.d.ts.map +0 -1
  917. package/dist/output/subject-framing-crop.d.ts.map +0 -1
  918. package/dist/schema/camera.d.ts.map +0 -1
  919. package/dist/schema/camera.js +0 -3
  920. package/dist/schema/camera.js.map +0 -1
  921. package/dist/schema/illumination-spectral.d.ts.map +0 -1
  922. package/dist/schema/illumination-temporal.d.ts.map +0 -1
  923. package/dist/schema/illumination.d.ts.map +0 -1
  924. package/dist/schema/scene-radiance-temporal.d.ts.map +0 -1
  925. package/dist/schema/scene-radiance.d.ts.map +0 -1
  926. package/dist/schema/scene.d.ts.map +0 -1
  927. package/dist/schema/scene.js +0 -3
  928. package/dist/schema/scene.js.map +0 -1
  929. package/dist/schema/validation.d.ts.map +0 -1
  930. package/dist/sensor/accumulated-charge.d.ts.map +0 -1
  931. package/dist/sensor/architecture.d.ts.map +0 -1
  932. package/dist/sensor/camera-saturation-capacity.d.ts.map +0 -1
  933. package/dist/sensor/capture-color-sampling-binding.d.ts.map +0 -1
  934. package/dist/sensor/capture-mode-timing.d.ts.map +0 -1
  935. package/dist/sensor/capture-mode.d.ts.map +0 -1
  936. package/dist/sensor/color-sampling.d.ts.map +0 -1
  937. package/dist/sensor/constant-rate-temporal-integration.d.ts.map +0 -1
  938. package/dist/sensor/dark-current.d.ts.map +0 -1
  939. package/dist/sensor/environment-photo-signal.d.ts.map +0 -1
  940. package/dist/sensor/eqe-electron-rate.d.ts.map +0 -1
  941. package/dist/sensor/eqe-local-exposure.d.ts.map +0 -1
  942. package/dist/sensor/eqe-temporal-exposure.d.ts.map +0 -1
  943. package/dist/sensor/exposure-window.d.ts.map +0 -1
  944. package/dist/sensor/iso-signal-chain.d.ts.map +0 -1
  945. package/dist/sensor/local-exposure-binding.d.ts.map +0 -1
  946. package/dist/sensor/optical-stack.d.ts.map +0 -1
  947. package/dist/sensor/photon-energy.d.ts.map +0 -1
  948. package/dist/sensor/physical-charge-capacity.d.ts.map +0 -1
  949. package/dist/sensor/pixel-pitch.d.ts.map +0 -1
  950. package/dist/sensor/radiometry-readiness.d.ts.map +0 -1
  951. package/dist/sensor/raw-readout.d.ts.map +0 -1
  952. package/dist/sensor/raw-reconstruction.d.ts.map +0 -1
  953. package/dist/sensor/readout-exposure-linkage.d.ts.map +0 -1
  954. package/dist/sensor/readout-timing.d.ts.map +0 -1
  955. package/dist/sensor/response-application-compatibility.d.ts.map +0 -1
  956. package/dist/sensor/response-operating-range.d.ts.map +0 -1
  957. package/dist/sensor/responsivity-photocurrent.d.ts.map +0 -1
  958. package/dist/sensor/sampling-aperture.d.ts.map +0 -1
  959. package/dist/sensor/scene-eqe-temporal-exposure.d.ts.map +0 -1
  960. package/dist/sensor/sensor-geometry.d.ts.map +0 -1
  961. package/dist/sensor/signal-noise.d.ts.map +0 -1
  962. package/dist/sensor/spatial-sample-reduction.d.ts.map +0 -1
  963. package/dist/sensor/spatial-sampling-quadrature.d.ts.map +0 -1
  964. package/dist/sensor/spatio-spectral-reduction.d.ts.map +0 -1
  965. package/dist/sensor/spectral-coverage.d.ts.map +0 -1
  966. package/dist/sensor/spectral-quadrature.d.ts.map +0 -1
  967. package/dist/sensor/spectral-response.d.ts.map +0 -1
  968. package/dist/sensor/temporal-eqe-sum.d.ts.map +0 -1
  969. package/dist/sensor/temporal-photo-signal.d.ts.map +0 -1
  970. package/dist/sensor/temporal-sample-binding.d.ts.map +0 -1
  971. package/dist/simulation/poc-simulation.d.ts.map +0 -1
  972. package/dist/stabilization/camera-shake.d.ts.map +0 -1
  973. package/dist/stabilization/system.d.ts.map +0 -1
  974. package/docs/API_STYLE.md +0 -235
  975. package/docs/ARCHITECTURE.md +0 -356
  976. package/docs/AUTOMATION_COORDINATION.md +0 -190
  977. package/docs/CAPTURE_COLOR.md +0 -25
  978. package/docs/CAPTURE_CORRECTED_SDR.md +0 -25
  979. package/docs/CAPTURE_EXPORT_METADATA.md +0 -27
  980. package/docs/CAPTURE_SDR.md +0 -22
  981. package/docs/DENSE_PUPIL_QUALIFICATION.md +0 -121
  982. package/docs/DEVELOPERS.md +0 -68
  983. package/docs/DIGITAL_OPTICS_FOUNDATION.md +0 -69
  984. package/docs/ENVIRONMENT_RAW_CAPTURE.md +0 -208
  985. package/docs/EXPORT_ACCEPTANCE.md +0 -133
  986. package/docs/GENERIC_TIER_PRESETS.md +0 -269
  987. package/docs/GEOMETRIC_PREPARATION_REUSE.md +0 -141
  988. package/docs/IMAGE_FORMATION.md +0 -247
  989. package/docs/LINEAR_CAPTURE_ENCODING.md +0 -25
  990. package/docs/MOTION_AND_SIGNAL.md +0 -250
  991. package/docs/NATIVE_CAPTURE_SDR.md +0 -70
  992. package/docs/NATIVE_CAPTURE_SDR_REVIEW.md +0 -37
  993. package/docs/NATIVE_CAPTURE_SDR_VALIDATION.md +0 -34
  994. package/docs/NATIVE_RAW_AND_PRINT.md +0 -54
  995. package/docs/NUMERICAL_CORRECTNESS.md +0 -191
  996. package/docs/PERFORMANCE_BASELINE.md +0 -56
  997. package/docs/PHOTOGRAPHIC_EXPORT.md +0 -206
  998. package/docs/PHYSICS_FOUNDATION.md +0 -426
  999. package/docs/POC_API.md +0 -278
  1000. package/docs/POC_PROJECTION_PLATFORM_REFERENCE.md +0 -12
  1001. package/docs/POC_PROJECTION_REUSE.md +0 -124
  1002. package/docs/PRINT_195_196_REVIEW.md +0 -93
  1003. package/docs/PRINT_196_ENGINE_ACCEPTANCE.md +0 -45
  1004. package/docs/PRINT_CONTRAST_REFERENCE.md +0 -43
  1005. package/docs/PRINT_DETAIL_ASSESSMENT.md +0 -81
  1006. package/docs/PRINT_DETAIL_JPEG_EVIDENCE.md +0 -36
  1007. package/docs/PRINT_DETAIL_SDR_EVIDENCE.md +0 -29
  1008. package/docs/PRINT_DETAIL_VALIDATION.md +0 -36
  1009. package/docs/PRINT_PLANNING.md +0 -75
  1010. package/docs/PRINT_REGION_STATISTICS.md +0 -38
  1011. package/docs/PROCESSED_OUTPUT.md +0 -157
  1012. package/docs/PRODUCTION_COMPOSITION.md +0 -373
  1013. package/docs/PRODUCTION_ENVIRONMENT_CAPTURE.md +0 -131
  1014. package/docs/PROVENANCE.md +0 -115
  1015. package/docs/PSF_FOUNDATION.md +0 -165
  1016. package/docs/RAW_FRAME_ENVELOPE.md +0 -56
  1017. package/docs/RAW_FRAME_RECONSTRUCTION.md +0 -30
  1018. package/docs/RELEASE_1_0.md +0 -66
  1019. package/docs/RELEASE_1_0_1.md +0 -61
  1020. package/docs/RELEASE_1_1_0.md +0 -25
  1021. package/docs/RELEASE_1_2_0.md +0 -51
  1022. package/docs/RELEASE_1_3_0.md +0 -15
  1023. package/docs/RELEASE_1_4_0.md +0 -23
  1024. package/docs/RELEASE_1_5_0.md +0 -105
  1025. package/docs/RELEASE_AUDIT.md +0 -39
  1026. package/docs/SCENE_RADIANCE_AND_ILLUMINATION.md +0 -298
  1027. package/docs/SCENE_SENSOR_QUADRATURE.md +0 -98
  1028. package/docs/SCENE_SENSOR_TEMPORAL_EXPOSURE.md +0 -86
  1029. package/docs/SCIENTIFIC_ASSURANCE.md +0 -280
  1030. package/docs/SCIENTIFIC_CONFORMANCE.md +0 -83
  1031. package/docs/SDR_RENDERING.md +0 -33
  1032. package/docs/SENSOR_APERTURE_RAYS.md +0 -23
  1033. package/docs/SENSOR_ENVIRONMENT_QUERY.md +0 -86
  1034. package/docs/SENSOR_EQE_LOCAL_EXPOSURE.md +0 -104
  1035. package/docs/SENSOR_EQE_TEMPORAL_EXPOSURE.md +0 -74
  1036. package/docs/SENSOR_PSF_QUADRATURE.md +0 -90
  1037. package/docs/SENSOR_RAW_FRAME.md +0 -20
  1038. package/docs/SENSOR_RAW_PRODUCER.md +0 -77
  1039. package/docs/SEPARABLE_EMISSION_DRAFT.md +0 -103
  1040. package/docs/SIGNAL_CONFORMANCE.md +0 -23
  1041. package/docs/SIMULATED_CAPTURE.md +0 -65
  1042. package/docs/STABILIZATION.md +0 -234
  1043. package/docs/TEMPORAL_PHOTO_RAW.md +0 -83
  1044. package/docs/TIER_ACCEPTANCE.md +0 -129
  1045. package/docs/TIER_PRESET_ACCEPTANCE.md +0 -59
  1046. package/docs/V1_COMPOSITION_MAP.md +0 -123
  1047. package/docs/V1_HELPER_REUSE_REVIEW.md +0 -60
  1048. package/docs/V1_PERFORMANCE_DISPOSITION.md +0 -88
  1049. package/docs/benchmarks/2026-10-01-main-baseline.json +0 -694
  1050. package/docs/benchmarks/2026-10-02-geometric-preparation-reuse.json +0 -2190
  1051. package/docs/benchmarks/2026-10-02-poc-projection-reuse.json +0 -2423
  1052. package/docs/benchmarks/2026-10-02-v1-environment-gc-profile.json +0 -210
  1053. package/docs/benchmarks/2026-10-02-v1-environment-ordinary.json +0 -187
  1054. package/docs/benchmarks/2026-10-02-v1-geometry-gc-profile.json +0 -756
  1055. package/docs/benchmarks/2026-10-02-v1-geometry-ordinary-1.json +0 -711
  1056. package/docs/benchmarks/2026-10-02-v1-geometry-ordinary-2.json +0 -711
  1057. package/docs/benchmarks/2026-10-02-v1-poc-gc-profile.json +0 -885
  1058. package/docs/benchmarks/2026-10-02-v1-poc-ordinary-1.json +0 -868
  1059. package/docs/benchmarks/2026-10-02-v1-poc-ordinary-2.json +0 -868
  1060. package/docs/licenses/castleCSF-MIT.txt +0 -21
  1061. package/docs/validation/dense-pupil-2026-10-06/pilot.jsonl +0 -6
  1062. package/docs/validation/documentation-fragments.json +0 -212
  1063. package/docs/validation/native-capture-sdr-darwin-arm64-node26-review.jsonl +0 -4
  1064. package/docs/validation/native-capture-sdr-darwin-arm64.jsonl +0 -3
  1065. package/docs/validation/native-raw-print-2026-10-04/fractional-asymmetric-crop.jpg +0 -0
  1066. package/docs/validation/native-raw-print-2026-10-04/gray-ramp.jpg +0 -0
  1067. package/docs/validation/native-raw-print-2026-10-04/linear-area-checker.jpg +0 -0
  1068. package/docs/validation/native-raw-print-2026-10-04/manifest.json +0 -218
  1069. package/docs/validation/native-raw-print-2026-10-04/megapixel-native.jpg +0 -0
  1070. package/docs/validation/native-raw-print-2026-10-04/native-color.jpg +0 -0
  1071. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel-validation.json +0 -9
  1072. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json +0 -29
  1073. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.codes.u16le.gz +0 -0
  1074. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.jpg +0 -0
  1075. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.rgb.gz +0 -0
  1076. package/docs/validation/native-raw-print-2026-10-04/srgb.icc +0 -0
  1077. package/docs/validation/native-raw-print-2026-10-04/validation.json +0 -41
  1078. package/docs/validation/print-196-candidate-capabilities.json +0 -28
  1079. package/docs/validation/print-196-candidate-evidence.json +0 -356
  1080. package/docs/validation/print-196-engine-acceptance.json +0 -81
  1081. package/docs/validation/print-detail-capabilities.json +0 -103
  1082. package/docs/validation/print-detail-jpeg-evidence.json +0 -116
  1083. package/docs/validation/print-detail-sdr-evidence.json +0 -81
  1084. package/docs/validation/release-audit-inventory.json +0 -1306
  1085. package/docs/validation/tier-acceptance-report-v1.json +0 -2538
@@ -1,28 +1,40 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  /**
3
- * Module boundary and integration notes.
4
- * Calculates thin-lens depth-of-field limits using the conventional hyperfocal-distance formulation.
5
- * The model is geometric and does not include diffraction, aberrations, focus breathing, pupil
6
- * magnification, or macro/high-magnification effects.
7
- * Calculates the geometric defocus-circle diameter at the sensor plane for a subject plane away from
8
- * the selected focus plane.
9
- * @see docs/PHYSICS_FOUNDATION.md for equations, coordinate/unit conventions, blockers and support
10
- * limits.
3
+ * Thin-lens depth of field (DoF) and defocus blur.
4
+ *
5
+ * Depth-of-field limits are exact for a thin lens. They use the hyperfocal distance
6
+ * H = f^2/(Nc) + f:
7
+ * near = s(H - f)/(H + s - 2f)
8
+ * far = s(H - f)/(H - s), infinite (null) when s >= H
9
+ * The model is geometric. It does not include diffraction, aberrations, focus breathing, pupil
10
+ * magnification or macro (high-magnification) effects.
11
+ *
12
+ * The defocus circle is the geometric blur-circle diameter at the sensor for a subject plane that is
13
+ * not at the focus distance.
14
+ * @see docs/PHYSICS_FOUNDATION.md for the equations, units, coordinate conventions, known blockers
15
+ * and support limits.
11
16
  */
12
17
  import { calculatedResult } from "../core/calculation-result.js";
13
18
  import { InvalidScientificInputError, requirePositiveFinite } from "../core/validation.js";
14
19
  import { calculateThinLensImageDistance } from "./thin-lens.js";
20
+ import { requireInputKeys } from "../core/record-validation.js";
15
21
  /**
16
- * Calculates thin-lens depth-of-field limits using the conventional
17
- * hyperfocal-distance formulation.
22
+ * Calculates exact thin-lens depth-of-field limits. With hyperfocal
23
+ * distance H = f^2/(Nc) + f and focus distance s, the near limit is
24
+ * s(H - f)/(H + s - 2f) and the far limit is s(H - f)/(H - s), which is
25
+ * infinite (`null`) when s >= H. At both limits the geometric defocus circle
26
+ * from {@link calculateDefocusCircle} equals the supplied circle of confusion.
27
+ * The circle of confusion must be smaller than the aperture diameter f/N;
28
+ * otherwise the near limit would fall inside the focal length.
18
29
  *
19
- * The model is geometric and does not include diffraction, aberrations,
20
- * focus breathing, pupil magnification, or macro/high-magnification effects.
30
+ * The model is geometric. It does not include diffraction, aberrations,
31
+ * focus breathing, pupil magnification or macro (high-magnification) effects.
21
32
  *
22
33
  * @param input Lens, focus, aperture, and acceptable blur-circle inputs.
23
34
  * @returns Hyperfocal, near, and far depth-of-field distances.
24
35
  */
25
36
  export function calculateDepthOfField(input) {
37
+ requireInputKeys(input, "calculateDepthOfField", ["focalLengthMm", "aperture", "focusDistanceM", "circleOfConfusionMm"]);
26
38
  requirePositiveFinite("focalLengthMm", input.focalLengthMm);
27
39
  requirePositiveFinite("aperture", input.aperture);
28
40
  requirePositiveFinite("focusDistanceM", input.focusDistanceM);
@@ -31,22 +43,37 @@ export function calculateDepthOfField(input) {
31
43
  if (focusDistanceMm <= input.focalLengthMm) {
32
44
  throw new InvalidScientificInputError("focusDistanceM must place the focus plane beyond the focal length.");
33
45
  }
34
- const hyperfocalDistanceMm = (input.focalLengthMm * input.focalLengthMm) /
35
- (input.aperture * input.circleOfConfusionMm) +
36
- input.focalLengthMm;
37
- const focusOffsetMm = focusDistanceMm - input.focalLengthMm;
38
- const nearLimitMm = (hyperfocalDistanceMm * focusDistanceMm) /
39
- (hyperfocalDistanceMm + focusOffsetMm);
40
- const farDenominator = hyperfocalDistanceMm - focusOffsetMm;
41
- const farLimitMm = farDenominator <= 0
46
+ // The near limit lies beyond the focal length only when H - f = f^2/(Nc) > f,
47
+ // i.e. c < f/N (the entrance-pupil diameter). A blur circle at least as large
48
+ // as the pupil itself has no real-image depth-of-field solution.
49
+ if (input.circleOfConfusionMm >= input.focalLengthMm / input.aperture) {
50
+ throw new InvalidScientificInputError("circleOfConfusionMm must be smaller than the aperture diameter focalLengthMm / aperture.");
51
+ }
52
+ // H - f = f^2 / (N c), kept separately to avoid cancellation.
53
+ const hyperfocalOffsetMm = (input.focalLengthMm * input.focalLengthMm) /
54
+ (input.aperture * input.circleOfConfusionMm);
55
+ const hyperfocalDistanceMm = hyperfocalOffsetMm + input.focalLengthMm;
56
+ // Exact thin-lens limits. The defocus-circle diameter for a subject at d
57
+ // while focused at s is c(d) = f^2 |s - d| / (N d (s - f)). Solving
58
+ // c(d) = c with H = f^2 / (N c) + f gives
59
+ // near = s (H - f) / (H + s - 2f) = s (H - f) / ((H - f) + (s - f))
60
+ // far = s (H - f) / (H - s), infinite when s >= H.
61
+ const nearLimitMm = (focusDistanceMm * hyperfocalOffsetMm) /
62
+ (hyperfocalOffsetMm + (focusDistanceMm - input.focalLengthMm));
63
+ // Compare against the reported hyperfocal distance in metres as well, so a
64
+ // caller focusing at exactly the returned hyperfocalDistanceM always gets an
65
+ // infinite far limit despite millimetre/metre rounding.
66
+ const hyperfocalDistanceM = hyperfocalDistanceMm / 1000;
67
+ const farDenominator = hyperfocalDistanceMm - focusDistanceMm;
68
+ const farLimitMm = farDenominator <= 0 || input.focusDistanceM >= hyperfocalDistanceM
42
69
  ? null
43
- : (hyperfocalDistanceMm * focusDistanceMm) / farDenominator;
70
+ : (focusDistanceMm * hyperfocalOffsetMm) / farDenominator;
44
71
  return calculatedResult({
45
- hyperfocalDistanceM: hyperfocalDistanceMm / 1000,
72
+ hyperfocalDistanceM,
46
73
  nearLimitM: nearLimitMm / 1000,
47
74
  farLimitM: farLimitMm === null ? null : farLimitMm / 1000,
48
75
  totalDepthOfFieldM: farLimitMm === null ? null : (farLimitMm - nearLimitMm) / 1000
49
- }, "thin-lens-depth-of-field", "1.0.0", [
76
+ }, "thin-lens-depth-of-field", "1.1.0", [
50
77
  "Geometric thin-lens model",
51
78
  "Circle of confusion is supplied by the caller",
52
79
  "Macro/high-magnification effects are not modeled"
@@ -54,12 +81,14 @@ export function calculateDepthOfField(input) {
54
81
  }
55
82
  /**
56
83
  * Calculates the geometric defocus-circle diameter at the sensor plane for a
57
- * subject plane away from the selected focus plane.
84
+ * subject plane away from the selected focus plane, using the stable closed
85
+ * form c = f^2 |s - d| / (N d (s - f)) (model 1.1.0).
58
86
  *
59
87
  * @param input Lens, aperture, focus-plane, and subject-plane distances.
60
88
  * @returns Geometric blur-circle diameter.
61
89
  */
62
90
  export function calculateDefocusCircle(input) {
91
+ requireInputKeys(input, "calculateDefocusCircle", ["focalLengthMm", "aperture", "focusDistanceM", "subjectDistanceM"]);
63
92
  return calculateDefocusCircleUsingFocusProjection(input);
64
93
  }
65
94
  /** @internal Reuses a projection already calculated for this exact POC request. */
@@ -97,10 +126,21 @@ export function calculateDefocusCircleUsingFocusProjection(input, projection) {
97
126
  }
98
127
  throw error;
99
128
  }
129
+ // Both image distances are still resolved above, so the thin-lens domain checks
130
+ // and the reused-projection identity check still run.
131
+ void focusImageDistanceMm;
132
+ void subjectImageDistanceMm;
100
133
  const apertureDiameterMm = input.focalLengthMm / input.aperture;
134
+ const focusDistanceMm = input.focusDistanceM * 1000;
135
+ const subjectDistanceMm = input.subjectDistanceM * 1000;
136
+ // Closed form of D |v_d - v_s| / v_d with v = f x / (x - f) (Gaussian thin lens):
137
+ // c = f^2 |s - d| / (N d (s - f)).
138
+ // It avoids subtracting two nearly equal image distances (catastrophic
139
+ // cancellation for distant subjects) and is grouped as bounded ratios so the
140
+ // intermediate products cannot overflow for finite in-domain inputs.
101
141
  const diameterMm = apertureDiameterMm *
102
- (Math.abs(subjectImageDistanceMm - focusImageDistanceMm) /
103
- subjectImageDistanceMm);
104
- return calculatedResult({ diameterMm }, "thin-lens-defocus-circle", "1.0.0", ["Geometric thin-lens model", "Ideal circular entrance pupil"]);
142
+ (Math.abs(focusDistanceMm - subjectDistanceMm) / subjectDistanceMm) *
143
+ (input.focalLengthMm / (focusDistanceMm - input.focalLengthMm));
144
+ return calculatedResult({ diameterMm }, "thin-lens-defocus-circle", "1.1.0", ["Geometric thin-lens model", "Ideal circular entrance pupil"]);
105
145
  }
106
146
  //# sourceMappingURL=depth-of-field.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"depth-of-field.js","sourceRoot":"","sources":["../../src/optics/depth-of-field.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"depth-of-field.js","sourceRoot":"","sources":["../../src/optics/depth-of-field.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,gBAAgB,EAEjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,EACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAsBhE;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAiC;IAEjC,gBAAgB,CAAC,KAAK,EAAE,uBAAuB,EAAE,CAAC,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,qBAAqB,CAAC,CAAC,CAAC;IACzH,qBAAqB,CAAC,eAAe,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IAC5D,qBAAqB,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAClD,qBAAqB,CAAC,gBAAgB,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IAC9D,qBAAqB,CAAC,qBAAqB,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAExE,MAAM,eAAe,GAAG,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC;IACpD,IAAI,eAAe,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;QAC3C,MAAM,IAAI,2BAA2B,CACnC,oEAAoE,CACrE,CAAC;IACJ,CAAC;IACD,8EAA8E;IAC9E,8EAA8E;IAC9E,iEAAiE;IACjE,IAAI,KAAK,CAAC,mBAAmB,IAAI,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QACtE,MAAM,IAAI,2BAA2B,CACnC,0FAA0F,CAC3F,CAAC;IACJ,CAAC;IAED,8DAA8D;IAC9D,MAAM,kBAAkB,GACtB,CAAC,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;QAC3C,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC/C,MAAM,oBAAoB,GAAG,kBAAkB,GAAG,KAAK,CAAC,aAAa,CAAC;IAEtE,yEAAyE;IACzE,oEAAoE;IACpE,0CAA0C;IAC1C,sEAAsE;IACtE,sDAAsD;IACtD,MAAM,WAAW,GACf,CAAC,eAAe,GAAG,kBAAkB,CAAC;QACtC,CAAC,kBAAkB,GAAG,CAAC,eAAe,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;IAEjE,2EAA2E;IAC3E,6EAA6E;IAC7E,wDAAwD;IACxD,MAAM,mBAAmB,GAAG,oBAAoB,GAAG,IAAI,CAAC;IACxD,MAAM,cAAc,GAAG,oBAAoB,GAAG,eAAe,CAAC;IAC9D,MAAM,UAAU,GACd,cAAc,IAAI,CAAC,IAAI,KAAK,CAAC,cAAc,IAAI,mBAAmB;QAChE,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,eAAe,GAAG,kBAAkB,CAAC,GAAG,cAAc,CAAC;IAE9D,OAAO,gBAAgB,CACrB;QACE,mBAAmB;QACnB,UAAU,EAAE,WAAW,GAAG,IAAI;QAC9B,SAAS,EAAE,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,GAAG,IAAI;QACzD,kBAAkB,EAChB,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,WAAW,CAAC,GAAG,IAAI;KACjE,EACD,0BAA0B,EAC1B,OAAO,EACP;QACE,2BAA2B;QAC3B,+CAA+C;QAC/C,kDAAkD;KACnD,CACF,CAAC;AACJ,CAAC;AAkBD;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CACpC,KAAkC;IAElC,gBAAgB,CAAC,KAAK,EAAE,wBAAwB,EAAE,CAAC,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACvH,OAAO,0CAA0C,CAAC,KAAK,CAAC,CAAC;AAC3D,CAAC;AASD,mFAAmF;AACnF,MAAM,UAAU,0CAA0C,CACxD,KAAkC,EAClC,UAA2C;IAE3C,qBAAqB,CAAC,eAAe,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IAC5D,qBAAqB,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAClD,qBAAqB,CAAC,gBAAgB,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IAC9D,qBAAqB,CAAC,kBAAkB,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAElE,IAAI,oBAA4B,CAAC;IACjC,IAAI,sBAA8B,CAAC;IACnC,IAAI,CAAC;QACH,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,UAAU,CAAC,aAAa,KAAK,KAAK,CAAC,aAAa;gBAChD,UAAU,CAAC,cAAc,KAAK,KAAK,CAAC,cAAc;gBAClD,KAAK,CAAC,cAAc,GAAG,IAAI,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;gBACvD,MAAM,IAAI,2BAA2B,CAAC,8DAA8D,CAAC,CAAC;YACxG,CAAC;YACD,qBAAqB,CAAC,8BAA8B,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC;YAClF,oBAAoB,GAAG,UAAU,CAAC,eAAe,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,oBAAoB,GAAG,8BAA8B,CAAC;gBACpD,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,eAAe,EAAE,KAAK,CAAC,cAAc;aACtC,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC;QAC3B,CAAC;QACD,sBAAsB,GAAG,8BAA8B,CAAC;YACtD,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,eAAe,EAAE,KAAK,CAAC,gBAAgB;SACxC,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,2BAA2B,EAAE,CAAC;YACjD,MAAM,IAAI,2BAA2B,CACnC,sEAAsE,CACvE,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IACD,gFAAgF;IAChF,sDAAsD;IACtD,KAAK,oBAAoB,CAAC;IAC1B,KAAK,sBAAsB,CAAC;IAC5B,MAAM,kBAAkB,GAAG,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChE,MAAM,eAAe,GAAG,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC;IACpD,MAAM,iBAAiB,GAAG,KAAK,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAExD,kFAAkF;IAClF,qCAAqC;IACrC,uEAAuE;IACvE,6EAA6E;IAC7E,qEAAqE;IACrE,MAAM,UAAU,GACd,kBAAkB;QAClB,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,GAAG,iBAAiB,CAAC,GAAG,iBAAiB,CAAC;QACnE,CAAC,KAAK,CAAC,aAAa,GAAG,CAAC,eAAe,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;IAElE,OAAO,gBAAgB,CACrB,EAAE,UAAU,EAAE,EACd,0BAA0B,EAC1B,OAAO,EACP,CAAC,2BAA2B,EAAE,+BAA+B,CAAC,CAC/D,CAAC;AACJ,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Thin-lens depth of field (DoF) and defocus blur.\n *\n * Depth-of-field limits are exact for a thin lens. They use the hyperfocal distance\n * H = f^2/(Nc) + f:\n * near = s(H - f)/(H + s - 2f)\n * far = s(H - f)/(H - s), infinite (null) when s >= H\n * The model is geometric. It does not include diffraction, aberrations, focus breathing, pupil\n * magnification or macro (high-magnification) effects.\n *\n * The defocus circle is the geometric blur-circle diameter at the sensor for a subject plane that is\n * not at the focus distance.\n * @see docs/PHYSICS_FOUNDATION.md for the equations, units, coordinate conventions, known blockers\n * and support limits.\n */\n\nimport {\n calculatedResult,\n type CalculationResult\n} from \"../core/calculation-result.js\";\nimport {\n InvalidScientificInputError,\n requirePositiveFinite\n} from \"../core/validation.js\";\nimport { calculateThinLensImageDistance } from \"./thin-lens.js\";\nimport { requireInputKeys } from \"../core/record-validation.js\";\n\nexport interface CalculateDepthOfFieldInput {\n /** Lens focal length in millimetres. */\n focalLengthMm: number;\n /** F-number. */\n aperture: number;\n /** Focus distance from the lens plane in metres. */\n focusDistanceM: number;\n /** Acceptable circle of confusion diameter in millimetres. */\n circleOfConfusionMm: number;\n}\n\nexport interface DepthOfField {\n hyperfocalDistanceM: number;\n nearLimitM: number;\n /** Null represents an infinite far limit. */\n farLimitM: number | null;\n /** Null represents infinite total depth of field. */\n totalDepthOfFieldM: number | null;\n}\n\n/**\n * Calculates exact thin-lens depth-of-field limits. With hyperfocal\n * distance H = f^2/(Nc) + f and focus distance s, the near limit is\n * s(H - f)/(H + s - 2f) and the far limit is s(H - f)/(H - s), which is\n * infinite (`null`) when s >= H. At both limits the geometric defocus circle\n * from {@link calculateDefocusCircle} equals the supplied circle of confusion.\n * The circle of confusion must be smaller than the aperture diameter f/N;\n * otherwise the near limit would fall inside the focal length.\n *\n * The model is geometric. It does not include diffraction, aberrations,\n * focus breathing, pupil magnification or macro (high-magnification) effects.\n *\n * @param input Lens, focus, aperture, and acceptable blur-circle inputs.\n * @returns Hyperfocal, near, and far depth-of-field distances.\n */\nexport function calculateDepthOfField(\n input: CalculateDepthOfFieldInput\n): CalculationResult<DepthOfField> {\n requireInputKeys(input, \"calculateDepthOfField\", [\"focalLengthMm\", \"aperture\", \"focusDistanceM\", \"circleOfConfusionMm\"]);\n requirePositiveFinite(\"focalLengthMm\", input.focalLengthMm);\n requirePositiveFinite(\"aperture\", input.aperture);\n requirePositiveFinite(\"focusDistanceM\", input.focusDistanceM);\n requirePositiveFinite(\"circleOfConfusionMm\", input.circleOfConfusionMm);\n\n const focusDistanceMm = input.focusDistanceM * 1000;\n if (focusDistanceMm <= input.focalLengthMm) {\n throw new InvalidScientificInputError(\n \"focusDistanceM must place the focus plane beyond the focal length.\"\n );\n }\n // The near limit lies beyond the focal length only when H - f = f^2/(Nc) > f,\n // i.e. c < f/N (the entrance-pupil diameter). A blur circle at least as large\n // as the pupil itself has no real-image depth-of-field solution.\n if (input.circleOfConfusionMm >= input.focalLengthMm / input.aperture) {\n throw new InvalidScientificInputError(\n \"circleOfConfusionMm must be smaller than the aperture diameter focalLengthMm / aperture.\"\n );\n }\n\n // H - f = f^2 / (N c), kept separately to avoid cancellation.\n const hyperfocalOffsetMm =\n (input.focalLengthMm * input.focalLengthMm) /\n (input.aperture * input.circleOfConfusionMm);\n const hyperfocalDistanceMm = hyperfocalOffsetMm + input.focalLengthMm;\n\n // Exact thin-lens limits. The defocus-circle diameter for a subject at d\n // while focused at s is c(d) = f^2 |s - d| / (N d (s - f)). Solving\n // c(d) = c with H = f^2 / (N c) + f gives\n // near = s (H - f) / (H + s - 2f) = s (H - f) / ((H - f) + (s - f))\n // far = s (H - f) / (H - s), infinite when s >= H.\n const nearLimitMm =\n (focusDistanceMm * hyperfocalOffsetMm) /\n (hyperfocalOffsetMm + (focusDistanceMm - input.focalLengthMm));\n\n // Compare against the reported hyperfocal distance in metres as well, so a\n // caller focusing at exactly the returned hyperfocalDistanceM always gets an\n // infinite far limit despite millimetre/metre rounding.\n const hyperfocalDistanceM = hyperfocalDistanceMm / 1000;\n const farDenominator = hyperfocalDistanceMm - focusDistanceMm;\n const farLimitMm =\n farDenominator <= 0 || input.focusDistanceM >= hyperfocalDistanceM\n ? null\n : (focusDistanceMm * hyperfocalOffsetMm) / farDenominator;\n\n return calculatedResult(\n {\n hyperfocalDistanceM,\n nearLimitM: nearLimitMm / 1000,\n farLimitM: farLimitMm === null ? null : farLimitMm / 1000,\n totalDepthOfFieldM:\n farLimitMm === null ? null : (farLimitMm - nearLimitMm) / 1000\n },\n \"thin-lens-depth-of-field\",\n \"1.1.0\",\n [\n \"Geometric thin-lens model\",\n \"Circle of confusion is supplied by the caller\",\n \"Macro/high-magnification effects are not modeled\"\n ]\n );\n}\n\nexport interface CalculateDefocusCircleInput {\n /** Lens focal length in millimetres. */\n focalLengthMm: number;\n /** F-number. */\n aperture: number;\n /** Focus-plane distance from the lens plane in metres. */\n focusDistanceM: number;\n /** Subject-plane distance from the lens plane in metres. */\n subjectDistanceM: number;\n}\n\nexport interface DefocusCircle {\n /** Geometric blur-circle diameter at the sensor plane in millimetres. */\n diameterMm: number;\n}\n\n/**\n * Calculates the geometric defocus-circle diameter at the sensor plane for a\n * subject plane away from the selected focus plane, using the stable closed\n * form c = f^2 |s - d| / (N d (s - f)) (model 1.1.0).\n *\n * @param input Lens, aperture, focus-plane, and subject-plane distances.\n * @returns Geometric blur-circle diameter.\n */\nexport function calculateDefocusCircle(\n input: CalculateDefocusCircleInput\n): CalculationResult<DefocusCircle> {\n requireInputKeys(input, \"calculateDefocusCircle\", [\"focalLengthMm\", \"aperture\", \"focusDistanceM\", \"subjectDistanceM\"]);\n return calculateDefocusCircleUsingFocusProjection(input);\n}\n\n/** @internal Immutable identity for one request. Not a public cache or API. */\nexport interface ResolvedDefocusFocusProjection {\n readonly focalLengthMm: number;\n readonly focusDistanceM: number;\n readonly imageDistanceMm: number;\n}\n\n/** @internal Reuses a projection already calculated for this exact POC request. */\nexport function calculateDefocusCircleUsingFocusProjection(\n input: CalculateDefocusCircleInput,\n projection?: ResolvedDefocusFocusProjection\n): CalculationResult<DefocusCircle> {\n requirePositiveFinite(\"focalLengthMm\", input.focalLengthMm);\n requirePositiveFinite(\"aperture\", input.aperture);\n requirePositiveFinite(\"focusDistanceM\", input.focusDistanceM);\n requirePositiveFinite(\"subjectDistanceM\", input.subjectDistanceM);\n\n let focusImageDistanceMm: number;\n let subjectImageDistanceMm: number;\n try {\n if (projection !== undefined) {\n if (projection.focalLengthMm !== input.focalLengthMm ||\n projection.focusDistanceM !== input.focusDistanceM ||\n input.focusDistanceM * 1000 <= input.focalLengthMm) {\n throw new InvalidScientificInputError(\"Resolved focus projection identity differs from the request.\");\n }\n requirePositiveFinite(\"resolvedFocusImageDistanceMm\", projection.imageDistanceMm);\n focusImageDistanceMm = projection.imageDistanceMm;\n } else {\n focusImageDistanceMm = calculateThinLensImageDistance({\n focalLengthMm: input.focalLengthMm,\n objectDistanceM: input.focusDistanceM\n }).value.imageDistanceMm;\n }\n subjectImageDistanceMm = calculateThinLensImageDistance({\n focalLengthMm: input.focalLengthMm,\n objectDistanceM: input.subjectDistanceM\n }).value.imageDistanceMm;\n } catch (error) {\n if (error instanceof InvalidScientificInputError) {\n throw new InvalidScientificInputError(\n \"focusDistanceM and subjectDistanceM must be beyond the focal length.\"\n );\n }\n throw error;\n }\n // Both image distances are still resolved above, so the thin-lens domain checks\n // and the reused-projection identity check still run.\n void focusImageDistanceMm;\n void subjectImageDistanceMm;\n const apertureDiameterMm = input.focalLengthMm / input.aperture;\n const focusDistanceMm = input.focusDistanceM * 1000;\n const subjectDistanceMm = input.subjectDistanceM * 1000;\n\n // Closed form of D |v_d - v_s| / v_d with v = f x / (x - f) (Gaussian thin lens):\n // c = f^2 |s - d| / (N d (s - f)).\n // It avoids subtracting two nearly equal image distances (catastrophic\n // cancellation for distant subjects) and is grouped as bounded ratios so the\n // intermediate products cannot overflow for finite in-domain inputs.\n const diameterMm =\n apertureDiameterMm *\n (Math.abs(focusDistanceMm - subjectDistanceMm) / subjectDistanceMm) *\n (input.focalLengthMm / (focusDistanceMm - input.focalLengthMm));\n\n return calculatedResult(\n { diameterMm },\n \"thin-lens-defocus-circle\",\n \"1.1.0\",\n [\"Geometric thin-lens model\", \"Ideal circular entrance pupil\"]\n );\n}\n"]}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Builds a `LensSampledPsfProfile` for an ideal, aberration-free, in-focus lens with a uniformly lit
3
+ * circular pupil: the Airy pattern of scalar Fraunhofer diffraction, one unit-sum kernel per declared
4
+ * wavelength on ONE shared sample grid (2.1.0).
5
+ *
6
+ * **Model.** The pupil diameter is D = f/N (entrance pupil = exit pupil, unity pupil magnification) and
7
+ * the pupil-to-image distance z is the thin-lens image distance for the focus (f at infinity), so the
8
+ * image-side (working) f-number is N_w = z/D. The incoherent optical transfer function (OTF) of a
9
+ * uniform circular pupil is the normalized autocorrelation of the pupil,
10
+ * H(ρ) = (2/π)·(acos ρ − ρ·√(1 − ρ²)), ρ = |f|/f_c ≤ 1, f_c = 1/(λ·N_w),
11
+ * and the intensity PSF is its inverse Fourier transform (the Airy pattern, first zero at 1.21967·λ·N_w)
12
+ * (MIT OpenCourseWare 2.71 Optics, Spring 2009, lectures 21–22, free: the intensity PSF as the transform of
13
+ * the pupil autocorrelation and the circular-pupil MTF; also see: Goodman, Introduction to Fourier Optics,
14
+ * 4th ed., 2017, §6.3).
15
+ *
16
+ * **Cell integration (exact, no Bessel functions).** Kernel sample (i, j) is the PSF energy inside the
17
+ * square cell of side p centred on (i·p, j·p). The cell integral is the PSF convolved with the cell's
18
+ * indicator, evaluated at the cell centre, so in the frequency domain
19
+ * K(i, j) = p² ∫∫ H(|f|/f_c)·sinc(p·f_x)·sinc(p·f_y)·cos(2π·p·i·f_x)·cos(2π·p·j·f_y) d²f,
20
+ * with sinc(x) = sin(πx)/(πx) (the sine terms vanish because H is even). It is evaluated in polar
21
+ * coordinates: a trapezoid rule in angle (exponentially convergent for this smooth periodic integrand) and
22
+ * Gauss–Legendre in t with ρ = 1 − t², which removes the (1 − ρ)^{3/2} edge behaviour of H. The node counts
23
+ * follow from the integrand's bandwidth with a fixed margin; the tests check convergence by doubling them and
24
+ * check the values against an independent real-space integration of `calculateIdealPolygonDiffractionPsf` in
25
+ * its many-blade (circular) limit. The sum of all cells is exactly 1 (Parseval), so the energy captured by
26
+ * the finite kernel is Σ K over its window and the truncated energy is 1 − Σ K.
27
+ *
28
+ * **Truncation and normalization.** The kernel is the (2R+1)² window of cells. The Airy tails fall only as
29
+ * r⁻³, so a finite window always misses some energy: it is reported per wavelength, and the window is then
30
+ * renormalized to unit sum because the sampled-profile contract requires unit-energy kernels. The missing
31
+ * tail energy is thereby put back inside the window (an approximation that slightly raises low-frequency
32
+ * contrast compared with the untruncated pattern).
33
+ *
34
+ * **Approximations (labelled):** scalar (no polarization), aberration-free, uniform pupil amplitude, exactly in
35
+ * focus (no defocus), thin lens with unity pupil magnification, the on-axis PSF used across the declared field
36
+ * (isoplanatic), PSF energy binned into the sample cells, finite window renormalized. Not a measured lens.
37
+ * @see docs/PSF_FOUNDATION.md, "Diffraction-limited sampled profile (2.1)".
38
+ */
39
+ import { type CalculationResult } from "../core/calculation-result.js";
40
+ import type { FocusPlane } from "./focus-state.js";
41
+ import { type LensSampledPsfProfile } from "./lens-psf-profile.js";
42
+ export declare const DIFFRACTION_LIMITED_PSF_PROFILE_MODEL: Readonly<{
43
+ modelId: "photivra-diffraction-limited-circular-pupil-psf";
44
+ modelVersion: "1.0.0";
45
+ }>;
46
+ /** Input limits: at most 64 wavelengths, kernel radius 0–32 samples (the irradiance-convolution limit). */
47
+ export declare const DIFFRACTION_LIMITED_PSF_PROFILE_LIMITS: Readonly<{
48
+ maximumWavelengths: 64;
49
+ maximumKernelRadiusSamples: 32;
50
+ }>;
51
+ export interface CreateDiffractionLimitedPsfProfileInput {
52
+ /** Only `circular` in 2.1.0 (polygon pupils: `calculateIdealPolygonDiffractionPsf` gives point densities). */
53
+ aperture: "circular";
54
+ focalLengthMm: number;
55
+ apertureFNumber: number;
56
+ focus: FocusPlane;
57
+ /** Strictly increasing wavelengths, nm, in the medium of propagation (no air/vacuum conversion is applied). 1–64. */
58
+ wavelengthsNm: readonly number[];
59
+ /** Square sample pitch of every kernel, µm. */
60
+ samplePitchMicrometers: number;
61
+ /** Kernel half-width in samples; each kernel is (2R + 1)². 0–32. */
62
+ kernelRadiusSamples: number;
63
+ /** Half-extent of the image field over which the on-axis PSF is declared (profile field axes ±x, ±y), mm. */
64
+ fieldHalfExtentMm: {
65
+ x: number;
66
+ y: number;
67
+ };
68
+ profileId: string;
69
+ }
70
+ export interface DiffractionLimitedPsfWavelength {
71
+ wavelengthNm: number;
72
+ /** f_c = 1/(λ·N_w), cycles per µm. */
73
+ cutoffFrequencyCyclesPerMicrometer: number;
74
+ /** 1.21967·λ·N_w, µm. */
75
+ firstZeroRadiusMicrometers: number;
76
+ /** Σ of the cell energies inside the window before renormalization (of a total of 1). */
77
+ capturedEnergyFraction: number;
78
+ /** 1 − capturedEnergyFraction: the Airy tail energy outside the window, put back by renormalization. */
79
+ truncatedEnergyFraction: number;
80
+ /** Fraction of the renormalized kernel in the centre sample. */
81
+ centreSampleFraction: number;
82
+ }
83
+ export interface DiffractionLimitedPsfProfile {
84
+ profile: LensSampledPsfProfile;
85
+ model: typeof DIFFRACTION_LIMITED_PSF_PROFILE_MODEL;
86
+ pupilDiameterMm: number;
87
+ pupilToImageDistanceMm: number;
88
+ workingFNumber: number;
89
+ kernelRadiusSamples: number;
90
+ samplePitchMicrometers: number;
91
+ wavelengths: readonly DiffractionLimitedPsfWavelength[];
92
+ /** Largest truncated energy over the wavelengths. */
93
+ maximumTruncatedEnergyFraction: number;
94
+ quadrature: {
95
+ method: "polar-frequency-domain-trapezoid-gauss-legendre";
96
+ maximumRadialNodes: number;
97
+ maximumAngularNodes: number;
98
+ };
99
+ }
100
+ /**
101
+ * Cell energies K(i, j), 0 ≤ i, j ≤ R, of the Airy pattern for β = p·f_c (cell side in units of the cut-off
102
+ * period). `scale` multiplies the node counts (1 in production; the tests use 2 to check convergence).
103
+ */
104
+ export declare function calculateAiryCellEnergies(beta: number, radius: number, scale?: number): {
105
+ cells: Float64Array;
106
+ radialNodes: number;
107
+ angularNodes: number;
108
+ };
109
+ /**
110
+ * Creates a sampled lens PSF profile for an ideal diffraction-limited lens with a circular pupil: one
111
+ * unit-sum Airy kernel per wavelength on one shared (2R+1)² grid, with the truncated energy reported per
112
+ * wavelength. The profile declares the given focal length, f-number and focus exactly, and the field axes
113
+ * ±`fieldHalfExtentMm` with the same kernel at every field node.
114
+ * @param input - See `CreateDiffractionLimitedPsfProfileInput`.
115
+ * @returns The profile and its diffraction record. An approximation; not a measured lens.
116
+ * @see docs/PSF_FOUNDATION.md, "Diffraction-limited sampled profile (2.1)".
117
+ */
118
+ export declare function createDiffractionLimitedPsfProfile(input: CreateDiffractionLimitedPsfProfileInput): CalculationResult<DiffractionLimitedPsfProfile>;
@@ -0,0 +1,252 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * Builds a `LensSampledPsfProfile` for an ideal, aberration-free, in-focus lens with a uniformly lit
4
+ * circular pupil: the Airy pattern of scalar Fraunhofer diffraction, one unit-sum kernel per declared
5
+ * wavelength on ONE shared sample grid (2.1.0).
6
+ *
7
+ * **Model.** The pupil diameter is D = f/N (entrance pupil = exit pupil, unity pupil magnification) and
8
+ * the pupil-to-image distance z is the thin-lens image distance for the focus (f at infinity), so the
9
+ * image-side (working) f-number is N_w = z/D. The incoherent optical transfer function (OTF) of a
10
+ * uniform circular pupil is the normalized autocorrelation of the pupil,
11
+ * H(ρ) = (2/π)·(acos ρ − ρ·√(1 − ρ²)), ρ = |f|/f_c ≤ 1, f_c = 1/(λ·N_w),
12
+ * and the intensity PSF is its inverse Fourier transform (the Airy pattern, first zero at 1.21967·λ·N_w)
13
+ * (MIT OpenCourseWare 2.71 Optics, Spring 2009, lectures 21–22, free: the intensity PSF as the transform of
14
+ * the pupil autocorrelation and the circular-pupil MTF; also see: Goodman, Introduction to Fourier Optics,
15
+ * 4th ed., 2017, §6.3).
16
+ *
17
+ * **Cell integration (exact, no Bessel functions).** Kernel sample (i, j) is the PSF energy inside the
18
+ * square cell of side p centred on (i·p, j·p). The cell integral is the PSF convolved with the cell's
19
+ * indicator, evaluated at the cell centre, so in the frequency domain
20
+ * K(i, j) = p² ∫∫ H(|f|/f_c)·sinc(p·f_x)·sinc(p·f_y)·cos(2π·p·i·f_x)·cos(2π·p·j·f_y) d²f,
21
+ * with sinc(x) = sin(πx)/(πx) (the sine terms vanish because H is even). It is evaluated in polar
22
+ * coordinates: a trapezoid rule in angle (exponentially convergent for this smooth periodic integrand) and
23
+ * Gauss–Legendre in t with ρ = 1 − t², which removes the (1 − ρ)^{3/2} edge behaviour of H. The node counts
24
+ * follow from the integrand's bandwidth with a fixed margin; the tests check convergence by doubling them and
25
+ * check the values against an independent real-space integration of `calculateIdealPolygonDiffractionPsf` in
26
+ * its many-blade (circular) limit. The sum of all cells is exactly 1 (Parseval), so the energy captured by
27
+ * the finite kernel is Σ K over its window and the truncated energy is 1 − Σ K.
28
+ *
29
+ * **Truncation and normalization.** The kernel is the (2R+1)² window of cells. The Airy tails fall only as
30
+ * r⁻³, so a finite window always misses some energy: it is reported per wavelength, and the window is then
31
+ * renormalized to unit sum because the sampled-profile contract requires unit-energy kernels. The missing
32
+ * tail energy is thereby put back inside the window (an approximation that slightly raises low-frequency
33
+ * contrast compared with the untruncated pattern).
34
+ *
35
+ * **Approximations (labelled):** scalar (no polarization), aberration-free, uniform pupil amplitude, exactly in
36
+ * focus (no defocus), thin lens with unity pupil magnification, the on-axis PSF used across the declared field
37
+ * (isoplanatic), PSF energy binned into the sample cells, finite window renormalized. Not a measured lens.
38
+ * @see docs/PSF_FOUNDATION.md, "Diffraction-limited sampled profile (2.1)".
39
+ */
40
+ import { approximationResult } from "../core/calculation-result.js";
41
+ import { InvalidConfigurationError } from "../core/configuration-error.js";
42
+ import { requireAllowlistedRecord } from "../core/record-validation.js";
43
+ import { calculateThinLensImageDistance } from "./thin-lens.js";
44
+ import { parseLensSampledPsfProfile } from "./lens-psf-profile.js";
45
+ export const DIFFRACTION_LIMITED_PSF_PROFILE_MODEL = Object.freeze({
46
+ modelId: "photivra-diffraction-limited-circular-pupil-psf", modelVersion: "1.0.0"
47
+ });
48
+ /** Input limits: at most 64 wavelengths, kernel radius 0–32 samples (the irradiance-convolution limit). */
49
+ export const DIFFRACTION_LIMITED_PSF_PROFILE_LIMITS = Object.freeze({ maximumWavelengths: 64, maximumKernelRadiusSamples: 32 });
50
+ /** Radius of the first dark ring of the Airy pattern in units of λ·N_w: j₁,₁/π, j₁,₁ = 3.8317059702 (first zero of J₁). */
51
+ const AIRY_FIRST_ZERO_PER_LAMBDA_N = 3.8317059702075125 / Math.PI;
52
+ const EVIDENCE = Object.freeze([Object.freeze({ sourceOrigin: "photivra",
53
+ sourceReference: "photivra:diffraction-limited-psf-profile", reuseStatus: "photivra-owned" })]);
54
+ const LIMITATIONS = Object.freeze([
55
+ "Scalar Fraunhofer diffraction of an ideal, uniformly lit circular pupil (Airy pattern); no aberration, apodization, polarization or stray light.",
56
+ "Exactly in focus: no defocus or depth of field. Thin lens with unity pupil magnification; the pupil-to-image distance is the thin-lens image distance.",
57
+ "The on-axis PSF is declared unchanged across the field (isoplanatic); no field-dependent aberration or pupil clipping.",
58
+ "PSF energy is binned into square sample cells; the finite window misses the Airy tail energy listed per wavelength and is renormalized to unit sum.",
59
+ "Wavelengths are used as given, in the declared basis, without air/vacuum conversion."
60
+ ]);
61
+ function positive(value, name) {
62
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0)
63
+ throw new InvalidConfigurationError(name + " must be a positive finite number.");
64
+ return value;
65
+ }
66
+ /** Gauss–Legendre nodes and weights on [0, 1] (Newton iteration on Pₙ; DLMF §3.5(v)). Cached per n. */
67
+ const GAUSS_LEGENDRE = new Map();
68
+ function gaussLegendre(n) {
69
+ const cached = GAUSS_LEGENDRE.get(n);
70
+ if (cached)
71
+ return cached;
72
+ const nodes = new Float64Array(n), weights = new Float64Array(n);
73
+ for (let k = 0; k < Math.ceil(n / 2); k++) {
74
+ let x = Math.cos(Math.PI * (k + 0.75) / (n + 0.5));
75
+ for (let iteration = 0; iteration < 100; iteration++) {
76
+ let p0 = 1, p1 = x;
77
+ for (let m = 2; m <= n; m++) {
78
+ const p2 = ((2 * m - 1) * x * p1 - (m - 1) * p0) / m;
79
+ p0 = p1;
80
+ p1 = p2;
81
+ }
82
+ const step = p1 / (n * (x * p1 - p0) / (x * x - 1));
83
+ x -= step;
84
+ if (Math.abs(step) < 1e-16)
85
+ break;
86
+ }
87
+ let p0 = 1, p1 = x;
88
+ for (let m = 2; m <= n; m++) {
89
+ const p2 = ((2 * m - 1) * x * p1 - (m - 1) * p0) / m;
90
+ p0 = p1;
91
+ p1 = p2;
92
+ }
93
+ const derivative = n * (x * p1 - p0) / (x * x - 1);
94
+ const w = 1 / ((1 - x * x) * derivative * derivative);
95
+ // Map [-1, 1] to [0, 1]: t = (1 ± x)/2, weight w (2/(1-x²)P'² halved).
96
+ nodes[k] = (1 - x) / 2;
97
+ weights[k] = w;
98
+ nodes[n - 1 - k] = (1 + x) / 2;
99
+ weights[n - 1 - k] = w;
100
+ }
101
+ const result = { nodes, weights };
102
+ if (GAUSS_LEGENDRE.size < 64)
103
+ GAUSS_LEGENDRE.set(n, result);
104
+ return result;
105
+ }
106
+ function sinc(x) {
107
+ if (x === 0)
108
+ return 1;
109
+ const a = Math.PI * x;
110
+ return Math.sin(a) / a;
111
+ }
112
+ /**
113
+ * Cell energies K(i, j), 0 ≤ i, j ≤ R, of the Airy pattern for β = p·f_c (cell side in units of the cut-off
114
+ * period). `scale` multiplies the node counts (1 in production; the tests use 2 to check convergence).
115
+ */
116
+ export function calculateAiryCellEnergies(beta, radius, scale = 1) {
117
+ // Bandwidth of the angular and radial integrands: c = π·β·(2R + 1)·√2 (the sinc factors and the highest cosine).
118
+ const c = Math.PI * beta * (2 * radius + 1) * Math.SQRT2, margin = 10 * Math.cbrt(c) + 24;
119
+ const quarter = Math.ceil(scale * (c + margin) / 4), radialNodes = Math.ceil(scale * (c + margin));
120
+ const { nodes, weights } = gaussLegendre(radialNodes), size = radius + 1, cells = new Float64Array(size * size);
121
+ const ca = new Float64Array(size), cb = new Float64Array(size), angularStep = (Math.PI / 2) / quarter;
122
+ for (let r = 0; r < radialNodes; r++) {
123
+ const t = nodes[r], rho = 1 - t * t;
124
+ // H(1 − t²) without cancellation: acos(1 − t²) = 2·asin(t/√2), ρ·√(1 − ρ²) = ρ·t·√(2 − t²).
125
+ const otf = (2 / Math.PI) * (2 * Math.asin(t / Math.SQRT2) - rho * t * Math.sqrt(2 - t * t));
126
+ // ∫₀¹ g(ρ) dρ = ∫₀¹ g(1 − t²)·2t dt; the 4 is the four symmetric quadrants of the angular trapezoid.
127
+ const radialWeight = weights[r] * 2 * t * rho * otf * 4 * angularStep;
128
+ for (let k = 0; k <= quarter; k++) {
129
+ const theta = k * angularStep, x = beta * rho * Math.cos(theta), y = beta * rho * Math.sin(theta);
130
+ const w = radialWeight * (k === 0 || k === quarter ? 0.5 : 1) * sinc(x) * sinc(y);
131
+ // cos(2π·i·x) and cos(2π·j·y) by the Chebyshev recurrence.
132
+ const cx = Math.cos(2 * Math.PI * x), cy = Math.cos(2 * Math.PI * y);
133
+ ca[0] = 1;
134
+ cb[0] = 1;
135
+ if (size > 1) {
136
+ ca[1] = cx;
137
+ cb[1] = cy;
138
+ }
139
+ for (let i = 2; i < size; i++) {
140
+ ca[i] = 2 * cx * ca[i - 1] - ca[i - 2];
141
+ cb[i] = 2 * cy * cb[i - 1] - cb[i - 2];
142
+ }
143
+ for (let j = 0; j < size; j++) {
144
+ const wj = w * cb[j];
145
+ for (let i = 0; i < size; i++) {
146
+ const o = j * size + i;
147
+ cells[o] = cells[o] + wj * ca[i];
148
+ }
149
+ }
150
+ }
151
+ }
152
+ const area = beta * beta;
153
+ for (let i = 0; i < cells.length; i++)
154
+ cells[i] = cells[i] * area;
155
+ return { cells, radialNodes, angularNodes: 4 * quarter };
156
+ }
157
+ /**
158
+ * Creates a sampled lens PSF profile for an ideal diffraction-limited lens with a circular pupil: one
159
+ * unit-sum Airy kernel per wavelength on one shared (2R+1)² grid, with the truncated energy reported per
160
+ * wavelength. The profile declares the given focal length, f-number and focus exactly, and the field axes
161
+ * ±`fieldHalfExtentMm` with the same kernel at every field node.
162
+ * @param input - See `CreateDiffractionLimitedPsfProfileInput`.
163
+ * @returns The profile and its diffraction record. An approximation; not a measured lens.
164
+ * @see docs/PSF_FOUNDATION.md, "Diffraction-limited sampled profile (2.1)".
165
+ */
166
+ export function createDiffractionLimitedPsfProfile(input) {
167
+ const r = requireAllowlistedRecord(input, ["aperture", "focalLengthMm", "apertureFNumber", "focus", "wavelengthsNm", "samplePitchMicrometers",
168
+ "kernelRadiusSamples", "fieldHalfExtentMm", "profileId"], "Invalid diffraction-limited PSF profile input.");
169
+ if (r.aperture !== "circular")
170
+ throw new InvalidConfigurationError("aperture must be \"circular\".");
171
+ const focalLengthMm = positive(r.focalLengthMm, "focalLengthMm"), fNumber = positive(r.apertureFNumber, "apertureFNumber");
172
+ const pitch = positive(r.samplePitchMicrometers, "samplePitchMicrometers");
173
+ const L = DIFFRACTION_LIMITED_PSF_PROFILE_LIMITS;
174
+ const radius = r.kernelRadiusSamples;
175
+ if (typeof radius !== "number" || !Number.isSafeInteger(radius) || radius < 0 || radius > L.maximumKernelRadiusSamples) {
176
+ throw new InvalidConfigurationError("kernelRadiusSamples must be an integer from 0 to " + L.maximumKernelRadiusSamples + ".");
177
+ }
178
+ const focus = requireAllowlistedRecord(r.focus, ["kind", "distanceM"], "Invalid focus.");
179
+ let focusDiopters, distanceMm;
180
+ if (focus.kind === "infinity") {
181
+ if (focus.distanceM !== undefined)
182
+ throw new InvalidConfigurationError("An infinity focus has no distanceM.");
183
+ focusDiopters = 0;
184
+ distanceMm = focalLengthMm;
185
+ }
186
+ else if (focus.kind === "finite") {
187
+ const distanceM = positive(focus.distanceM, "focus.distanceM");
188
+ focusDiopters = 1 / distanceM;
189
+ distanceMm = calculateThinLensImageDistance({ focalLengthMm, objectDistanceM: distanceM }).value.imageDistanceMm;
190
+ }
191
+ else
192
+ throw new InvalidConfigurationError("focus.kind must be finite or infinity.");
193
+ const field = requireAllowlistedRecord(r.fieldHalfExtentMm, ["x", "y"], "Invalid fieldHalfExtentMm.");
194
+ const fieldX = positive(field.x, "fieldHalfExtentMm.x"), fieldY = positive(field.y, "fieldHalfExtentMm.y");
195
+ const list = r.wavelengthsNm;
196
+ if (!Array.isArray(list) || list.length < 1 || list.length > L.maximumWavelengths)
197
+ throw new InvalidConfigurationError("wavelengthsNm must list 1 to 64 wavelengths.");
198
+ const wavelengths = list.map((value, index) => positive(value, "wavelengthsNm[" + index + "]"));
199
+ for (let i = 1; i < wavelengths.length; i++)
200
+ if (!(wavelengths[i] > wavelengths[i - 1]))
201
+ throw new InvalidConfigurationError("wavelengthsNm must be strictly increasing.");
202
+ if (typeof r.profileId !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(r.profileId))
203
+ throw new InvalidConfigurationError("profileId must be a public opaque ID.");
204
+ const pupilDiameterMm = focalLengthMm / fNumber, workingFNumber = distanceMm / pupilDiameterMm, size = 2 * radius + 1;
205
+ let maximumRadialNodes = 0, maximumAngularNodes = 0, maximumTruncated = 0;
206
+ const records = [], kernels = [];
207
+ for (const nm of wavelengths) {
208
+ const lambdaN = nm / 1000 * workingFNumber, cutoff = 1 / lambdaN;
209
+ const airy = calculateAiryCellEnergies(pitch * cutoff, radius);
210
+ maximumRadialNodes = Math.max(maximumRadialNodes, airy.radialNodes);
211
+ maximumAngularNodes = Math.max(maximumAngularNodes, airy.angularNodes);
212
+ const values = new Array(size * size);
213
+ let captured = 0;
214
+ for (let ky = 0; ky < size; ky++)
215
+ for (let kx = 0; kx < size; kx++) {
216
+ const value = airy.cells[Math.abs(ky - radius) * (radius + 1) + Math.abs(kx - radius)];
217
+ // Every cell energy of a non-negative PSF is positive; a negative value would be a quadrature failure.
218
+ if (!(value > -1e-13))
219
+ throw new InvalidConfigurationError("Diffraction cell integration failed to converge.");
220
+ values[ky * size + kx] = Math.max(0, value);
221
+ captured += values[ky * size + kx];
222
+ }
223
+ if (!(captured > 0 && captured <= 1 + 1e-9))
224
+ throw new InvalidConfigurationError("Diffraction cell integration failed to converge.");
225
+ const truncated = Math.max(0, 1 - captured);
226
+ maximumTruncated = Math.max(maximumTruncated, truncated);
227
+ const kernel = values.map((v) => v / captured);
228
+ kernels.push(kernel);
229
+ records.push({ wavelengthNm: nm, cutoffFrequencyCyclesPerMicrometer: cutoff, firstZeroRadiusMicrometers: AIRY_FIRST_ZERO_PER_LAMBDA_N * lambdaN,
230
+ capturedEnergyFraction: captured, truncatedEnergyFraction: truncated, centreSampleFraction: kernel[radius * size + radius] });
231
+ }
232
+ const uncertainty = { kind: "not-quantified", limitation: "Ideal diffraction-limited model; no measured lens or quadrature error bound." };
233
+ const nodes = [-fieldX, fieldX].flatMap((fx) => [-fieldY, fieldY].flatMap((fy) => wavelengths.map((nm, index) => ({
234
+ nodeId: "airy-" + (fx < 0 ? "xm" : "xp") + "-" + (fy < 0 ? "ym" : "yp") + "-" + index,
235
+ coordinate: { focalLengthMm, focusDiopters, apertureFNumber: fNumber, fieldXmm: fx, fieldYmm: fy, wavelengthNm: nm, signedDefocusImagePlaneMicrometers: 0 },
236
+ kernel: { widthSamples: size, heightSamples: size, samplePitchMicrometersX: pitch, samplePitchMicrometersY: pitch, centerSampleX: radius, centerSampleY: radius,
237
+ normalizedIntensity: kernels[index] },
238
+ bestFocusImagePlaneOffsetMicrometers: 0, relativePupilThroughputFactor: 1, evidence: EVIDENCE, uncertainty
239
+ }))));
240
+ const profile = parseLensSampledPsfProfile({ schemaVersion: "0.1.0", profileId: r.profileId, profileVersion: DIFFRACTION_LIMITED_PSF_PROFILE_MODEL.modelVersion,
241
+ scientificStatus: "approximation", opticalDomain: "lens-primary-optical-path-only", coordinateSystem: "image-plane-metric", fieldAxes: "+X right, +Y up",
242
+ kernelEnergyNormalization: "unit-energy-shape", interpolation: "bounded-regular-grid-multilinear", throughputOwnership: "separate-relative-pupil-throughput-factor",
243
+ responseIncludes: { diffraction: true, aberration: false, defocus: false, pupilClippingShape: false },
244
+ sensorOpticalStackIncluded: false, sensorSamplingIncluded: false, reconstructionIncluded: false, strayLightIncluded: false,
245
+ axes: { focalLengthMm: [focalLengthMm], focusDiopters: [focusDiopters], apertureFNumber: [fNumber], fieldXmm: [-fieldX, fieldX], fieldYmm: [-fieldY, fieldY],
246
+ wavelengthNm: wavelengths, signedDefocusImagePlaneMicrometers: [0] },
247
+ nodes, evidence: EVIDENCE, limitations: [...LIMITATIONS] });
248
+ return approximationResult({ profile, model: DIFFRACTION_LIMITED_PSF_PROFILE_MODEL, pupilDiameterMm, pupilToImageDistanceMm: distanceMm, workingFNumber,
249
+ kernelRadiusSamples: radius, samplePitchMicrometers: pitch, wavelengths: records, maximumTruncatedEnergyFraction: maximumTruncated,
250
+ quadrature: { method: "polar-frequency-domain-trapezoid-gauss-legendre", maximumRadialNodes, maximumAngularNodes } }, DIFFRACTION_LIMITED_PSF_PROFILE_MODEL.modelId, DIFFRACTION_LIMITED_PSF_PROFILE_MODEL.modelVersion, [...LIMITATIONS]);
251
+ }
252
+ //# sourceMappingURL=diffraction-psf-profile.js.map