@photivra/engine 0.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 (97) hide show
  1. package/CITATION.cff +23 -0
  2. package/LICENSE +201 -0
  3. package/NOTICE +9 -0
  4. package/README.md +235 -0
  5. package/dist/camera/field-of-view.d.ts +37 -0
  6. package/dist/camera/field-of-view.d.ts.map +1 -0
  7. package/dist/camera/field-of-view.js +47 -0
  8. package/dist/camera/field-of-view.js.map +1 -0
  9. package/dist/camera/projected-object-size.d.ts +34 -0
  10. package/dist/camera/projected-object-size.d.ts.map +1 -0
  11. package/dist/camera/projected-object-size.js +57 -0
  12. package/dist/camera/projected-object-size.js.map +1 -0
  13. package/dist/core/calculation-result.d.ts +125 -0
  14. package/dist/core/calculation-result.d.ts.map +1 -0
  15. package/dist/core/calculation-result.js +175 -0
  16. package/dist/core/calculation-result.js.map +1 -0
  17. package/dist/core/validation.d.ts +30 -0
  18. package/dist/core/validation.d.ts.map +1 -0
  19. package/dist/core/validation.js +45 -0
  20. package/dist/core/validation.js.map +1 -0
  21. package/dist/exposure/exposure.d.ts +50 -0
  22. package/dist/exposure/exposure.d.ts.map +1 -0
  23. package/dist/exposure/exposure.js +62 -0
  24. package/dist/exposure/exposure.js.map +1 -0
  25. package/dist/index.d.ts +28 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +27 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/motion/projected-motion.d.ts +41 -0
  30. package/dist/motion/projected-motion.d.ts.map +1 -0
  31. package/dist/motion/projected-motion.js +84 -0
  32. package/dist/motion/projected-motion.js.map +1 -0
  33. package/dist/optics/aperture.d.ts +39 -0
  34. package/dist/optics/aperture.d.ts.map +1 -0
  35. package/dist/optics/aperture.js +62 -0
  36. package/dist/optics/aperture.js.map +1 -0
  37. package/dist/optics/circle-of-confusion.d.ts +23 -0
  38. package/dist/optics/circle-of-confusion.d.ts.map +1 -0
  39. package/dist/optics/circle-of-confusion.js +32 -0
  40. package/dist/optics/circle-of-confusion.js.map +1 -0
  41. package/dist/optics/depth-of-field.d.ts +53 -0
  42. package/dist/optics/depth-of-field.d.ts.map +1 -0
  43. package/dist/optics/depth-of-field.js +81 -0
  44. package/dist/optics/depth-of-field.js.map +1 -0
  45. package/dist/optics/diffraction.d.ts +26 -0
  46. package/dist/optics/diffraction.d.ts.map +1 -0
  47. package/dist/optics/diffraction.js +21 -0
  48. package/dist/optics/diffraction.js.map +1 -0
  49. package/dist/optics/thin-lens.d.ts +30 -0
  50. package/dist/optics/thin-lens.d.ts.map +1 -0
  51. package/dist/optics/thin-lens.js +33 -0
  52. package/dist/optics/thin-lens.js.map +1 -0
  53. package/dist/output/crop.d.ts +27 -0
  54. package/dist/output/crop.d.ts.map +1 -0
  55. package/dist/output/crop.js +26 -0
  56. package/dist/output/crop.js.map +1 -0
  57. package/dist/output/subject-framing-crop.d.ts +36 -0
  58. package/dist/output/subject-framing-crop.d.ts.map +1 -0
  59. package/dist/output/subject-framing-crop.js +42 -0
  60. package/dist/output/subject-framing-crop.js.map +1 -0
  61. package/dist/schema/camera.d.ts +34 -0
  62. package/dist/schema/camera.d.ts.map +1 -0
  63. package/dist/schema/camera.js +3 -0
  64. package/dist/schema/camera.js.map +1 -0
  65. package/dist/schema/scene.d.ts +69 -0
  66. package/dist/schema/scene.d.ts.map +1 -0
  67. package/dist/schema/scene.js +3 -0
  68. package/dist/schema/scene.js.map +1 -0
  69. package/dist/schema/validation.d.ts +25 -0
  70. package/dist/schema/validation.d.ts.map +1 -0
  71. package/dist/schema/validation.js +180 -0
  72. package/dist/schema/validation.js.map +1 -0
  73. package/dist/sensor/pixel-pitch.d.ts +21 -0
  74. package/dist/sensor/pixel-pitch.d.ts.map +1 -0
  75. package/dist/sensor/pixel-pitch.js +19 -0
  76. package/dist/sensor/pixel-pitch.js.map +1 -0
  77. package/dist/sensor/signal-noise.d.ts +37 -0
  78. package/dist/sensor/signal-noise.d.ts.map +1 -0
  79. package/dist/sensor/signal-noise.js +53 -0
  80. package/dist/sensor/signal-noise.js.map +1 -0
  81. package/dist/simulation/poc-simulation.d.ts +264 -0
  82. package/dist/simulation/poc-simulation.d.ts.map +1 -0
  83. package/dist/simulation/poc-simulation.js +449 -0
  84. package/dist/simulation/poc-simulation.js.map +1 -0
  85. package/dist/stabilization/camera-shake.d.ts +41 -0
  86. package/dist/stabilization/camera-shake.d.ts.map +1 -0
  87. package/dist/stabilization/camera-shake.js +79 -0
  88. package/dist/stabilization/camera-shake.js.map +1 -0
  89. package/docs/API_STYLE.md +65 -0
  90. package/docs/ARCHITECTURE.md +51 -0
  91. package/docs/MOTION_AND_SIGNAL.md +53 -0
  92. package/docs/PHYSICS_FOUNDATION.md +92 -0
  93. package/docs/POC_API.md +210 -0
  94. package/docs/PROVENANCE.md +87 -0
  95. package/docs/STABILIZATION.md +78 -0
  96. package/docs/USAGE.md +538 -0
  97. package/package.json +91 -0
@@ -0,0 +1,449 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { calculateFieldOfView } from "../camera/field-of-view.js";
3
+ import { calculateProjectedObjectSize } from "../camera/projected-object-size.js";
4
+ import { InvalidScientificInputError, requirePositiveFinite } from "../core/validation.js";
5
+ import { calculateExposureValue100 } from "../exposure/exposure.js";
6
+ import { calculateProjectedMotionBlur } from "../motion/projected-motion.js";
7
+ import { calculateIdealApertureGeometry } from "../optics/aperture.js";
8
+ import { estimateEquivalentViewingCircleOfConfusion } from "../optics/circle-of-confusion.js";
9
+ import { calculateAiryDisk } from "../optics/diffraction.js";
10
+ import { calculateThinLensImageDistance } from "../optics/thin-lens.js";
11
+ import { calculateDefocusCircle, calculateDepthOfField } from "../optics/depth-of-field.js";
12
+ import { calculateCenteredCrop } from "../output/crop.js";
13
+ import { calculateSubjectFramingCrop } from "../output/subject-framing-crop.js";
14
+ import { calculatePixelPitch } from "../sensor/pixel-pitch.js";
15
+ import { estimateCameraShakeBlur } from "../stabilization/camera-shake.js";
16
+ function calculateCroppedFieldOfView(sensorWidthMm, sensorHeightMm, focalLengthMm, focusDistanceM, cropFactor) {
17
+ const diagonalMm = Math.hypot(sensorWidthMm, sensorHeightMm);
18
+ return {
19
+ horizontalDegrees: calculateFieldOfView({
20
+ focalLengthMm,
21
+ sensorDimensionMm: sensorWidthMm / cropFactor,
22
+ focusDistanceM
23
+ }).value.degrees,
24
+ verticalDegrees: calculateFieldOfView({
25
+ focalLengthMm,
26
+ sensorDimensionMm: sensorHeightMm / cropFactor,
27
+ focusDistanceM
28
+ }).value.degrees,
29
+ diagonalDegrees: calculateFieldOfView({
30
+ focalLengthMm,
31
+ sensorDimensionMm: diagonalMm / cropFactor,
32
+ focusDistanceM
33
+ }).value.degrees
34
+ };
35
+ }
36
+ function requireUniqueSampleIds(label, samples) {
37
+ if (samples === undefined) {
38
+ return;
39
+ }
40
+ const seen = new Set();
41
+ for (const sample of samples) {
42
+ const normalizedId = sample.id.trim();
43
+ if (normalizedId.length === 0) {
44
+ throw new InvalidScientificInputError(`${label}[].id must not be empty.`);
45
+ }
46
+ if (seen.has(normalizedId)) {
47
+ throw new InvalidScientificInputError(`${label}[].id values must be unique; duplicate: ${normalizedId}`);
48
+ }
49
+ seen.add(normalizedId);
50
+ }
51
+ }
52
+ /**
53
+ * Composes the validated POC calculations into a single renderer/agent-facing
54
+ * response without introducing any new photographic model.
55
+ *
56
+ * @param request Complete POC simulation request with explicit physical units.
57
+ * @returns Serializable POC metrics for one camera/scene configuration.
58
+ */
59
+ export function simulatePocCamera(request) {
60
+ requirePositiveFinite("sensor.widthMm", request.sensor.widthMm);
61
+ requirePositiveFinite("sensor.heightMm", request.sensor.heightMm);
62
+ requirePositiveFinite("lens.focalLengthMm", request.lens.focalLengthMm);
63
+ requirePositiveFinite("lens.aperture", request.lens.aperture);
64
+ requirePositiveFinite("exposure.shutterSeconds", request.exposure.shutterSeconds);
65
+ requirePositiveFinite("exposure.iso", request.exposure.iso);
66
+ requirePositiveFinite("focus.focusDistanceM", request.focus.focusDistanceM);
67
+ const hasExplicitCircleOfConfusion = request.focus.circleOfConfusionMm !== undefined;
68
+ const hasEquivalentViewingCriterion = request.focus.equivalentViewingCircleOfConfusion !== undefined;
69
+ if (hasExplicitCircleOfConfusion === hasEquivalentViewingCriterion) {
70
+ throw new InvalidScientificInputError("Provide exactly one focus circle-of-confusion criterion.");
71
+ }
72
+ const equivalentViewingCircleOfConfusion = request.focus.equivalentViewingCircleOfConfusion === undefined
73
+ ? undefined
74
+ : estimateEquivalentViewingCircleOfConfusion({
75
+ sensorWidthMm: request.sensor.widthMm,
76
+ sensorHeightMm: request.sensor.heightMm,
77
+ ...request.focus.equivalentViewingCircleOfConfusion
78
+ });
79
+ const circleOfConfusionMm = equivalentViewingCircleOfConfusion?.value.circleOfConfusionMm ??
80
+ request.focus.circleOfConfusionMm;
81
+ if (circleOfConfusionMm === undefined) {
82
+ throw new InvalidScientificInputError("A focus circle-of-confusion criterion is required.");
83
+ }
84
+ requirePositiveFinite("focus.circleOfConfusionMm", circleOfConfusionMm);
85
+ requirePositiveFinite("crop.factor", request.crop.factor);
86
+ requirePositiveFinite("diffraction.wavelengthNm", request.diffraction.wavelengthNm);
87
+ requireUniqueSampleIds("defocusSamples", request.defocusSamples);
88
+ requireUniqueSampleIds("samplingSamples", request.samplingSamples);
89
+ requireUniqueSampleIds("motionSamples", request.motionSamples);
90
+ const projection = calculateThinLensImageDistance({
91
+ focalLengthMm: request.lens.focalLengthMm,
92
+ objectDistanceM: request.focus.focusDistanceM
93
+ });
94
+ const diagonalMm = Math.hypot(request.sensor.widthMm, request.sensor.heightMm);
95
+ const horizontalFov = calculateFieldOfView({
96
+ focalLengthMm: request.lens.focalLengthMm,
97
+ sensorDimensionMm: request.sensor.widthMm,
98
+ focusDistanceM: request.focus.focusDistanceM
99
+ });
100
+ const verticalFov = calculateFieldOfView({
101
+ focalLengthMm: request.lens.focalLengthMm,
102
+ sensorDimensionMm: request.sensor.heightMm,
103
+ focusDistanceM: request.focus.focusDistanceM
104
+ });
105
+ const diagonalFov = calculateFieldOfView({
106
+ focalLengthMm: request.lens.focalLengthMm,
107
+ sensorDimensionMm: diagonalMm,
108
+ focusDistanceM: request.focus.focusDistanceM
109
+ });
110
+ const pixelPitch = calculatePixelPitch({
111
+ sensorWidthMm: request.sensor.widthMm,
112
+ pixelWidth: request.sensor.pixelWidth
113
+ });
114
+ const crop = calculateCenteredCrop({
115
+ pixelWidth: request.sensor.pixelWidth,
116
+ pixelHeight: request.sensor.pixelHeight,
117
+ cropFactor: request.crop.factor
118
+ });
119
+ const cropFieldOfView = calculateCroppedFieldOfView(request.sensor.widthMm, request.sensor.heightMm, request.lens.focalLengthMm, request.focus.focusDistanceM, request.crop.factor);
120
+ const depthOfField = calculateDepthOfField({
121
+ focalLengthMm: request.lens.focalLengthMm,
122
+ aperture: request.lens.aperture,
123
+ focusDistanceM: request.focus.focusDistanceM,
124
+ circleOfConfusionMm
125
+ });
126
+ const diffraction = calculateAiryDisk({
127
+ aperture: request.lens.aperture,
128
+ wavelengthNm: request.diffraction.wavelengthNm
129
+ });
130
+ const motion = calculateProjectedMotionBlur({
131
+ focalLengthMm: request.lens.focalLengthMm,
132
+ shutterSeconds: request.exposure.shutterSeconds,
133
+ positionM: request.motion.positionM,
134
+ velocityMps: request.motion.velocityMps,
135
+ focusDistanceM: request.focus.focusDistanceM,
136
+ pixelPitchMicrometers: pixelPitch.value.micrometers
137
+ });
138
+ const exposureValue = calculateExposureValue100({
139
+ aperture: request.lens.aperture,
140
+ shutterSeconds: request.exposure.shutterSeconds
141
+ });
142
+ const subjectSampling = request.subject === undefined
143
+ ? undefined
144
+ : calculateProjectedObjectSize({
145
+ focalLengthMm: request.lens.focalLengthMm,
146
+ objectWidthM: request.subject.widthM,
147
+ objectHeightM: request.subject.heightM,
148
+ distanceM: request.subject.distanceM,
149
+ focusDistanceM: request.focus.focusDistanceM,
150
+ pixelPitchMicrometers: pixelPitch.value.micrometers
151
+ }).value;
152
+ const samplingSamples = request.samplingSamples === undefined
153
+ ? undefined
154
+ : request.samplingSamples.map((sample) => {
155
+ const projected = calculateProjectedObjectSize({
156
+ focalLengthMm: request.lens.focalLengthMm,
157
+ objectWidthM: sample.widthM,
158
+ objectHeightM: sample.heightM,
159
+ distanceM: sample.distanceM,
160
+ focusDistanceM: request.focus.focusDistanceM,
161
+ pixelPitchMicrometers: pixelPitch.value.micrometers
162
+ }).value;
163
+ return {
164
+ id: sample.id,
165
+ widthMm: projected.widthMm,
166
+ heightMm: projected.heightMm,
167
+ widthPixels: projected.widthPixels ?? 0,
168
+ heightPixels: projected.heightPixels ?? 0
169
+ };
170
+ });
171
+ const motionSamples = request.motionSamples === undefined
172
+ ? undefined
173
+ : request.motionSamples.map((sample) => {
174
+ const projected = calculateProjectedMotionBlur({
175
+ focalLengthMm: request.lens.focalLengthMm,
176
+ shutterSeconds: request.exposure.shutterSeconds,
177
+ positionM: sample.positionM,
178
+ velocityMps: sample.velocityMps,
179
+ focusDistanceM: request.focus.focusDistanceM,
180
+ pixelPitchMicrometers: pixelPitch.value.micrometers
181
+ });
182
+ return {
183
+ id: sample.id,
184
+ distanceMm: projected.value.distanceMm,
185
+ distancePixels: projected.value.distancePixels ?? 0,
186
+ deltaXMm: projected.value.deltaXMm,
187
+ deltaYMm: projected.value.deltaYMm,
188
+ deltaXPixels: projected.value.deltaXMm /
189
+ (pixelPitch.value.micrometers / 1000),
190
+ deltaYPixels: projected.value.deltaYMm /
191
+ (pixelPitch.value.micrometers / 1000)
192
+ };
193
+ });
194
+ const subjectCrop = request.subjectCrop === undefined || subjectSampling === undefined
195
+ ? undefined
196
+ : calculateSubjectFramingCrop({
197
+ pixelWidth: crop.value.pixelWidth,
198
+ pixelHeight: crop.value.pixelHeight,
199
+ subjectHeightPixels: subjectSampling.heightPixels ?? 0,
200
+ targetSubjectHeightFraction: request.subjectCrop.targetSubjectHeightFraction
201
+ }).value;
202
+ const totalSubjectCropFactor = subjectCrop === undefined
203
+ ? undefined
204
+ : request.crop.factor * subjectCrop.cropFactor;
205
+ const subjectCropFieldOfView = totalSubjectCropFactor === undefined
206
+ ? undefined
207
+ : calculateCroppedFieldOfView(request.sensor.widthMm, request.sensor.heightMm, request.lens.focalLengthMm, request.focus.focusDistanceM, totalSubjectCropFactor);
208
+ const cameraShake = request.cameraShake === undefined
209
+ ? undefined
210
+ : estimateCameraShakeBlur({
211
+ focalLengthMm: request.lens.focalLengthMm,
212
+ shutterSeconds: request.exposure.shutterSeconds,
213
+ angularVelocityRadPerSec: request.cameraShake.angularVelocityRadPerSec,
214
+ stabilizationStopsEquivalent: request.cameraShake.stabilizationStopsEquivalent,
215
+ focusDistanceM: request.focus.focusDistanceM,
216
+ pixelPitchMicrometers: pixelPitch.value.micrometers
217
+ });
218
+ const apertureShape = request.apertureShape === undefined
219
+ ? undefined
220
+ : calculateIdealApertureGeometry(request.apertureShape);
221
+ const diagnosticSubjectMotion = request.diagnostics?.subjectMotionSampleId === undefined
222
+ ? undefined
223
+ : motionSamples?.find((sample) => sample.id === request.diagnostics?.subjectMotionSampleId);
224
+ if (request.diagnostics?.subjectMotionSampleId !== undefined &&
225
+ diagnosticSubjectMotion === undefined) {
226
+ throw new InvalidScientificInputError(`Unknown diagnostics subjectMotionSampleId: ${request.diagnostics.subjectMotionSampleId}`);
227
+ }
228
+ const subjectDefocus = request.subject === undefined
229
+ ? undefined
230
+ : calculateDefocusCircle({
231
+ focalLengthMm: request.lens.focalLengthMm,
232
+ aperture: request.lens.aperture,
233
+ focusDistanceM: request.focus.focusDistanceM,
234
+ subjectDistanceM: request.subject.distanceM
235
+ }).value;
236
+ const primarySubjectDiagnostics = request.subject === undefined ||
237
+ subjectSampling === undefined ||
238
+ subjectDefocus === undefined
239
+ ? undefined
240
+ : {
241
+ subjectDistanceM: request.subject.distanceM,
242
+ samplingHeightPixels: subjectSampling.heightPixels ?? 0,
243
+ defocusDiameterPixels: subjectDefocus.diameterMm /
244
+ (pixelPitch.value.micrometers / 1000),
245
+ diffractionFirstZeroDiameterPixels: diffraction.value.firstZeroDiameterMicrometers /
246
+ pixelPitch.value.micrometers,
247
+ diffractionModel: diffraction.provenance.model,
248
+ ...(diagnosticSubjectMotion === undefined
249
+ ? {}
250
+ : {
251
+ subjectMotion: {
252
+ id: diagnosticSubjectMotion.id,
253
+ distancePixels: diagnosticSubjectMotion.distancePixels
254
+ }
255
+ }),
256
+ ...(cameraShake === undefined
257
+ ? {}
258
+ : {
259
+ cameraShake: {
260
+ stabilizedDistancePixels: cameraShake.value.stabilized.distancePixels ?? 0,
261
+ provenanceKind: "approximation"
262
+ }
263
+ }),
264
+ comparisonCaution: "Sampling, defocus diameter, diffraction diameter, motion path, and camera-shake path are different physical indicators and must not be directly summed into a sharpness score."
265
+ };
266
+ const defocusSamples = request.defocusSamples === undefined
267
+ ? undefined
268
+ : request.defocusSamples.map((sample) => {
269
+ requirePositiveFinite("defocusSamples[].distanceM", sample.distanceM);
270
+ const defocus = calculateDefocusCircle({
271
+ focalLengthMm: request.lens.focalLengthMm,
272
+ aperture: request.lens.aperture,
273
+ focusDistanceM: request.focus.focusDistanceM,
274
+ subjectDistanceM: sample.distanceM
275
+ });
276
+ return {
277
+ id: sample.id,
278
+ distanceM: sample.distanceM,
279
+ diameterMm: defocus.value.diameterMm,
280
+ diameterPixels: defocus.value.diameterMm /
281
+ (pixelPitch.value.micrometers / 1000)
282
+ };
283
+ });
284
+ return {
285
+ apiVersion: "0.17.0",
286
+ projection: {
287
+ kind: "focus-aware-thin-lens",
288
+ focusDistanceM: request.focus.focusDistanceM,
289
+ imageDistanceMm: projection.value.imageDistanceMm,
290
+ infinityProjectionScale: projection.value.infinityProjectionScale,
291
+ provenance: projection.provenance
292
+ },
293
+ fieldOfView: {
294
+ horizontalDegrees: horizontalFov.value.degrees,
295
+ verticalDegrees: verticalFov.value.degrees,
296
+ diagonalDegrees: diagonalFov.value.degrees
297
+ },
298
+ sensor: {
299
+ pixelPitchMicrometers: pixelPitch.value.micrometers
300
+ },
301
+ crop: {
302
+ cropFactor: request.crop.factor,
303
+ ...crop.value,
304
+ effectiveFieldOfView: cropFieldOfView
305
+ },
306
+ focusCriterion: equivalentViewingCircleOfConfusion === undefined
307
+ ? {
308
+ source: "explicit",
309
+ circleOfConfusionMm
310
+ }
311
+ : {
312
+ source: "equivalent-viewing-approximation",
313
+ circleOfConfusionMm,
314
+ scaleFactor: equivalentViewingCircleOfConfusion.value.scaleFactor,
315
+ provenance: {
316
+ kind: "approximation",
317
+ model: equivalentViewingCircleOfConfusion.provenance.model,
318
+ modelVersion: equivalentViewingCircleOfConfusion.provenance.modelVersion,
319
+ ...(equivalentViewingCircleOfConfusion.provenance.assumptions ===
320
+ undefined
321
+ ? {}
322
+ : {
323
+ assumptions: equivalentViewingCircleOfConfusion.provenance.assumptions
324
+ })
325
+ }
326
+ },
327
+ depthOfField: depthOfField.value,
328
+ diffraction: {
329
+ firstZeroDiameterMicrometers: diffraction.value.firstZeroDiameterMicrometers,
330
+ airyDiameterPixels: diffraction.value.firstZeroDiameterMicrometers /
331
+ pixelPitch.value.micrometers,
332
+ pupilModel: "ideal-circular",
333
+ provenance: diffraction.provenance
334
+ },
335
+ motion: {
336
+ distanceMm: motion.value.distanceMm,
337
+ distancePixels: motion.value.distancePixels ?? 0,
338
+ deltaXMm: motion.value.deltaXMm,
339
+ deltaYMm: motion.value.deltaYMm,
340
+ deltaXPixels: motion.value.deltaXMm / (pixelPitch.value.micrometers / 1000),
341
+ deltaYPixels: motion.value.deltaYMm / (pixelPitch.value.micrometers / 1000)
342
+ },
343
+ exposure: {
344
+ ev100: exposureValue.value,
345
+ iso: request.exposure.iso
346
+ },
347
+ ...(subjectSampling === undefined
348
+ ? {}
349
+ : {
350
+ subjectSampling: {
351
+ widthMm: subjectSampling.widthMm,
352
+ heightMm: subjectSampling.heightMm,
353
+ widthPixels: subjectSampling.widthPixels ?? 0,
354
+ heightPixels: subjectSampling.heightPixels ?? 0
355
+ }
356
+ }),
357
+ ...(defocusSamples === undefined ? {} : { defocusSamples }),
358
+ ...(samplingSamples === undefined ? {} : { samplingSamples }),
359
+ ...(motionSamples === undefined ? {} : { motionSamples }),
360
+ ...(subjectCrop === undefined ||
361
+ subjectCropFieldOfView === undefined ||
362
+ totalSubjectCropFactor === undefined
363
+ ? {}
364
+ : {
365
+ subjectCrop: {
366
+ additionalCropFactor: subjectCrop.cropFactor,
367
+ totalCropFactor: totalSubjectCropFactor,
368
+ pixelWidth: subjectCrop.pixelWidth,
369
+ pixelHeight: subjectCrop.pixelHeight,
370
+ megapixels: subjectCrop.megapixels,
371
+ subjectHeightFraction: subjectCrop.subjectHeightFraction,
372
+ subjectClipped: subjectCrop.subjectClipped,
373
+ additionalCropApplied: subjectCrop.cropped,
374
+ effectiveFieldOfView: subjectCropFieldOfView
375
+ }
376
+ }),
377
+ ...(apertureShape === undefined
378
+ ? {}
379
+ : {
380
+ apertureShape: {
381
+ ...apertureShape.value,
382
+ provenance: apertureShape.provenance
383
+ }
384
+ }),
385
+ ...(primarySubjectDiagnostics === undefined
386
+ ? {}
387
+ : { primarySubjectDiagnostics }),
388
+ ...(cameraShake === undefined
389
+ ? {}
390
+ : {
391
+ cameraShake: {
392
+ residualMotionFactor: cameraShake.value.residualMotionFactor,
393
+ unstabilized: {
394
+ deltaXmm: cameraShake.value.unstabilized.deltaXmm,
395
+ deltaYmm: cameraShake.value.unstabilized.deltaYmm,
396
+ distanceMm: cameraShake.value.unstabilized.distanceMm,
397
+ distancePixels: cameraShake.value.unstabilized.distancePixels ?? 0,
398
+ deltaXPixels: cameraShake.value.unstabilized.deltaXPixels ?? 0,
399
+ deltaYPixels: cameraShake.value.unstabilized.deltaYPixels ?? 0
400
+ },
401
+ stabilized: {
402
+ deltaXmm: cameraShake.value.stabilized.deltaXmm,
403
+ deltaYmm: cameraShake.value.stabilized.deltaYmm,
404
+ distanceMm: cameraShake.value.stabilized.distanceMm,
405
+ distancePixels: cameraShake.value.stabilized.distancePixels ?? 0,
406
+ deltaXPixels: cameraShake.value.stabilized.deltaXPixels ?? 0,
407
+ deltaYPixels: cameraShake.value.stabilized.deltaYPixels ?? 0
408
+ },
409
+ provenance: {
410
+ kind: "approximation",
411
+ model: cameraShake.provenance.model,
412
+ modelVersion: cameraShake.provenance.modelVersion,
413
+ ...(cameraShake.provenance.assumptions === undefined
414
+ ? {}
415
+ : { assumptions: cameraShake.provenance.assumptions })
416
+ }
417
+ }
418
+ }),
419
+ provenance: {
420
+ kind: equivalentViewingCircleOfConfusion !== undefined ||
421
+ cameraShake !== undefined
422
+ ? "mixed"
423
+ : "calculated",
424
+ components: {
425
+ projection: "calculated",
426
+ fieldOfView: "calculated",
427
+ crop: "calculated",
428
+ focusCriterion: equivalentViewingCircleOfConfusion === undefined
429
+ ? "calculated"
430
+ : "approximation",
431
+ depthOfField: "calculated",
432
+ diffraction: "calculated",
433
+ motion: "calculated",
434
+ exposure: "calculated",
435
+ ...(apertureShape === undefined
436
+ ? {}
437
+ : { apertureShape: "calculated" }),
438
+ ...(cameraShake === undefined
439
+ ? {}
440
+ : { cameraShake: "approximation" })
441
+ },
442
+ note: equivalentViewingCircleOfConfusion !== undefined ||
443
+ cameraShake !== undefined
444
+ ? "Mixed provenance: calculated analytical models plus explicitly labeled approximations."
445
+ : "Calculated from Photivra open-engine analytical models."
446
+ }
447
+ };
448
+ }
449
+ //# sourceMappingURL=poc-simulation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poc-simulation.js","sourceRoot":"","sources":["../../src/simulation/poc-simulation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { type CalculationResult } from "../core/calculation-result.js";
2
+ export interface EstimateCameraShakeBlurInput {
3
+ focalLengthMm: number;
4
+ shutterSeconds: number;
5
+ angularVelocityRadPerSec: {
6
+ yaw: number;
7
+ pitch: number;
8
+ };
9
+ stabilizationStopsEquivalent: number;
10
+ /** Optional focus distance in metres for focus-aware sensor-plane projection. */
11
+ focusDistanceM?: number;
12
+ pixelPitchMicrometers?: number;
13
+ }
14
+ export interface CameraShakeBlurSample {
15
+ deltaXmm: number;
16
+ deltaYmm: number;
17
+ distanceMm: number;
18
+ distancePixels?: number;
19
+ deltaXPixels?: number;
20
+ deltaYPixels?: number;
21
+ }
22
+ export interface CameraShakeEstimate {
23
+ residualMotionFactor: number;
24
+ projectionDistanceMm: number;
25
+ unstabilized: CameraShakeBlurSample;
26
+ stabilized: CameraShakeBlurSample;
27
+ }
28
+ /**
29
+ * Estimates sensor-plane blur from a controlled constant-angular-velocity
30
+ * handheld shake profile, with optional equivalent stabilization attenuation.
31
+ *
32
+ * With focusDistanceM supplied, angular motion is projected using the same
33
+ * ideal thin-lens sensor-plane distance as the other focus-aware projection
34
+ * primitives; otherwise nominal focal length preserves the prior approximation.
35
+ *
36
+ * The optical projection is physically calculated, but mapping a stabilization
37
+ * rating in stops to residual angular motion by 2^-stops is an educational
38
+ * approximation. It is not a CIPA DC-011 measurement or a real-camera rating.
39
+ */
40
+ export declare function estimateCameraShakeBlur(input: EstimateCameraShakeBlurInput): CalculationResult<CameraShakeEstimate>;
41
+ //# sourceMappingURL=camera-shake.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camera-shake.d.ts","sourceRoot":"","sources":["../../src/stabilization/camera-shake.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,+BAA+B,CAAC;AAOvC,MAAM,WAAW,4BAA4B;IAC3C,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,wBAAwB,EAAE;QACxB,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,4BAA4B,EAAE,MAAM,CAAC;IACrC,iFAAiF;IACjF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,EAAE,qBAAqB,CAAC;IACpC,UAAU,EAAE,qBAAqB,CAAC;CACnC;AAiCD;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,4BAA4B,GAClC,iBAAiB,CAAC,mBAAmB,CAAC,CA4ExC"}
@@ -0,0 +1,79 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { approximationResult } from "../core/calculation-result.js";
3
+ import { InvalidScientificInputError, requirePositiveFinite } from "../core/validation.js";
4
+ import { calculateThinLensImageDistance } from "../optics/thin-lens.js";
5
+ function requireFinite(name, value) {
6
+ if (!Number.isFinite(value)) {
7
+ throw new InvalidScientificInputError(`${name} must be finite.`);
8
+ }
9
+ }
10
+ function projectAngularDisplacement(projectionDistanceMm, yawRad, pitchRad, pixelPitchMicrometers) {
11
+ const deltaXmm = projectionDistanceMm * Math.tan(yawRad);
12
+ const deltaYmm = projectionDistanceMm * Math.tan(pitchRad);
13
+ const distanceMm = Math.hypot(deltaXmm, deltaYmm);
14
+ if (pixelPitchMicrometers === undefined) {
15
+ return { deltaXmm, deltaYmm, distanceMm };
16
+ }
17
+ const pitchMm = pixelPitchMicrometers / 1000;
18
+ return {
19
+ deltaXmm,
20
+ deltaYmm,
21
+ distanceMm,
22
+ distancePixels: distanceMm / pitchMm,
23
+ deltaXPixels: deltaXmm / pitchMm,
24
+ deltaYPixels: deltaYmm / pitchMm
25
+ };
26
+ }
27
+ /**
28
+ * Estimates sensor-plane blur from a controlled constant-angular-velocity
29
+ * handheld shake profile, with optional equivalent stabilization attenuation.
30
+ *
31
+ * With focusDistanceM supplied, angular motion is projected using the same
32
+ * ideal thin-lens sensor-plane distance as the other focus-aware projection
33
+ * primitives; otherwise nominal focal length preserves the prior approximation.
34
+ *
35
+ * The optical projection is physically calculated, but mapping a stabilization
36
+ * rating in stops to residual angular motion by 2^-stops is an educational
37
+ * approximation. It is not a CIPA DC-011 measurement or a real-camera rating.
38
+ */
39
+ export function estimateCameraShakeBlur(input) {
40
+ requirePositiveFinite("focalLengthMm", input.focalLengthMm);
41
+ requirePositiveFinite("shutterSeconds", input.shutterSeconds);
42
+ requireFinite("angularVelocityRadPerSec.yaw", input.angularVelocityRadPerSec.yaw);
43
+ requireFinite("angularVelocityRadPerSec.pitch", input.angularVelocityRadPerSec.pitch);
44
+ if (!Number.isFinite(input.stabilizationStopsEquivalent) ||
45
+ input.stabilizationStopsEquivalent < 0) {
46
+ throw new InvalidScientificInputError("stabilizationStopsEquivalent must be finite and greater than or equal to zero.");
47
+ }
48
+ if (input.pixelPitchMicrometers !== undefined) {
49
+ requirePositiveFinite("pixelPitchMicrometers", input.pixelPitchMicrometers);
50
+ }
51
+ const focusProjection = input.focusDistanceM === undefined
52
+ ? undefined
53
+ : calculateThinLensImageDistance({
54
+ focalLengthMm: input.focalLengthMm,
55
+ objectDistanceM: input.focusDistanceM
56
+ });
57
+ const projectionDistanceMm = focusProjection?.value.imageDistanceMm ?? input.focalLengthMm;
58
+ const yawRad = input.angularVelocityRadPerSec.yaw * input.shutterSeconds;
59
+ const pitchRad = input.angularVelocityRadPerSec.pitch * input.shutterSeconds;
60
+ const residualMotionFactor = 2 ** -input.stabilizationStopsEquivalent;
61
+ return approximationResult({
62
+ residualMotionFactor,
63
+ projectionDistanceMm,
64
+ unstabilized: projectAngularDisplacement(projectionDistanceMm, yawRad, pitchRad, input.pixelPitchMicrometers),
65
+ stabilized: projectAngularDisplacement(projectionDistanceMm, yawRad * residualMotionFactor, pitchRad * residualMotionFactor, input.pixelPitchMicrometers)
66
+ }, focusProjection === undefined
67
+ ? "constant-angular-velocity-stabilization-equivalent"
68
+ : "focus-aware-constant-angular-velocity-stabilization-equivalent", "1.0.0", [
69
+ "Camera rotation is constant during the exposure",
70
+ focusProjection === undefined
71
+ ? "Nominal focal length is used as the infinity-focus projection distance"
72
+ : "Thin-lens image distance for the selected focus plane is used as the projection distance",
73
+ "Yaw and pitch are treated independently",
74
+ "Equivalent stabilization stops attenuate angular displacement by 2^-stops",
75
+ "This is not a CIPA DC-011 compliance measurement",
76
+ "Roll, translation, subject motion, and stabilization limits are not modeled"
77
+ ]);
78
+ }
79
+ //# sourceMappingURL=camera-shake.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camera-shake.js","sourceRoot":"","sources":["../../src/stabilization/camera-shake.ts"],"names":[],"mappings":"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"}