@photivra/engine 0.2.0 → 0.4.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 (89) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/CITATION.cff +1 -1
  3. package/README.md +58 -10
  4. package/dist/camera/equivalent-focal-length.d.ts +34 -0
  5. package/dist/camera/equivalent-focal-length.d.ts.map +1 -0
  6. package/dist/camera/equivalent-focal-length.js +33 -0
  7. package/dist/camera/equivalent-focal-length.js.map +1 -0
  8. package/dist/camera/field-of-view.d.ts +40 -3
  9. package/dist/camera/field-of-view.d.ts.map +1 -1
  10. package/dist/camera/field-of-view.js +66 -24
  11. package/dist/camera/field-of-view.js.map +1 -1
  12. package/dist/core/calculation-result.d.ts.map +1 -1
  13. package/dist/core/calculation-result.js +14 -2
  14. package/dist/core/calculation-result.js.map +1 -1
  15. package/dist/core/configuration-error.d.ts +9 -0
  16. package/dist/core/configuration-error.d.ts.map +1 -0
  17. package/dist/core/configuration-error.js +13 -0
  18. package/dist/core/configuration-error.js.map +1 -0
  19. package/dist/core/evidence-provenance.d.ts +40 -0
  20. package/dist/core/evidence-provenance.d.ts.map +1 -0
  21. package/dist/core/evidence-provenance.js +79 -0
  22. package/dist/core/evidence-provenance.js.map +1 -0
  23. package/dist/core/image-formation.d.ts +70 -0
  24. package/dist/core/image-formation.d.ts.map +1 -0
  25. package/dist/core/image-formation.js +335 -0
  26. package/dist/core/image-formation.js.map +1 -0
  27. package/dist/index.d.ts +15 -3
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +15 -3
  30. package/dist/index.js.map +1 -1
  31. package/dist/motion/camera-rotation.d.ts +91 -0
  32. package/dist/motion/camera-rotation.d.ts.map +1 -0
  33. package/dist/motion/camera-rotation.js +157 -0
  34. package/dist/motion/camera-rotation.js.map +1 -0
  35. package/dist/optics/focus-breathing.d.ts +73 -0
  36. package/dist/optics/focus-breathing.d.ts.map +1 -0
  37. package/dist/optics/focus-breathing.js +77 -0
  38. package/dist/optics/focus-breathing.js.map +1 -0
  39. package/dist/optics/illumination-vignetting.d.ts +59 -0
  40. package/dist/optics/illumination-vignetting.d.ts.map +1 -0
  41. package/dist/optics/illumination-vignetting.js +107 -0
  42. package/dist/optics/illumination-vignetting.js.map +1 -0
  43. package/dist/optics/lateral-chromatic-aberration.d.ts +93 -0
  44. package/dist/optics/lateral-chromatic-aberration.d.ts.map +1 -0
  45. package/dist/optics/lateral-chromatic-aberration.js +174 -0
  46. package/dist/optics/lateral-chromatic-aberration.js.map +1 -0
  47. package/dist/optics/psf-foundation.d.ts +102 -0
  48. package/dist/optics/psf-foundation.d.ts.map +1 -0
  49. package/dist/optics/psf-foundation.js +164 -0
  50. package/dist/optics/psf-foundation.js.map +1 -0
  51. package/dist/optics/radial-distortion.d.ts +91 -0
  52. package/dist/optics/radial-distortion.d.ts.map +1 -0
  53. package/dist/optics/radial-distortion.js +198 -0
  54. package/dist/optics/radial-distortion.js.map +1 -0
  55. package/dist/output/capture-geometry.d.ts +225 -0
  56. package/dist/output/capture-geometry.d.ts.map +1 -0
  57. package/dist/output/capture-geometry.js +478 -0
  58. package/dist/output/capture-geometry.js.map +1 -0
  59. package/dist/schema/validation.d.ts +1 -8
  60. package/dist/schema/validation.d.ts.map +1 -1
  61. package/dist/schema/validation.js +2 -11
  62. package/dist/schema/validation.js.map +1 -1
  63. package/dist/sensor/architecture.d.ts +40 -0
  64. package/dist/sensor/architecture.d.ts.map +1 -0
  65. package/dist/sensor/architecture.js +98 -0
  66. package/dist/sensor/architecture.js.map +1 -0
  67. package/dist/sensor/radiometry-readiness.d.ts +111 -0
  68. package/dist/sensor/radiometry-readiness.d.ts.map +1 -0
  69. package/dist/sensor/radiometry-readiness.js +294 -0
  70. package/dist/sensor/radiometry-readiness.js.map +1 -0
  71. package/dist/sensor/sensor-geometry.d.ts +99 -0
  72. package/dist/sensor/sensor-geometry.d.ts.map +1 -0
  73. package/dist/sensor/sensor-geometry.js +71 -0
  74. package/dist/sensor/sensor-geometry.js.map +1 -0
  75. package/dist/simulation/poc-simulation.d.ts +93 -1
  76. package/dist/simulation/poc-simulation.d.ts.map +1 -1
  77. package/dist/simulation/poc-simulation.js +308 -24
  78. package/dist/simulation/poc-simulation.js.map +1 -1
  79. package/docs/API_STYLE.md +35 -2
  80. package/docs/ARCHITECTURE.md +179 -1
  81. package/docs/IMAGE_FORMATION.md +142 -0
  82. package/docs/MOTION_AND_SIGNAL.md +52 -1
  83. package/docs/PHYSICS_FOUNDATION.md +190 -3
  84. package/docs/POC_API.md +73 -7
  85. package/docs/PROVENANCE.md +24 -0
  86. package/docs/PSF_FOUNDATION.md +133 -0
  87. package/docs/STABILIZATION.md +17 -4
  88. package/docs/USAGE.md +657 -3
  89. package/package.json +1 -1
@@ -0,0 +1,71 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { calculatedResult } from "../core/calculation-result.js";
3
+ import { InvalidScientificInputError, requirePositiveFinite, requirePositiveInteger } from "../core/validation.js";
4
+ const REFERENCE_35MM_WIDTH_MM = 36;
5
+ const REFERENCE_35MM_HEIGHT_MM = 24;
6
+ const REFERENCE_35MM_DIAGONAL_MM = Math.hypot(REFERENCE_35MM_WIDTH_MM, REFERENCE_35MM_HEIGHT_MM);
7
+ /**
8
+ * Calculates physical imaging-area metrics independently from native raster
9
+ * density.
10
+ *
11
+ * Crop factor uses the diagonal ratio to a 36 × 24 mm reference frame.
12
+ * Digital/output crops are not part of this physical imaging-area quantity.
13
+ *
14
+ * @param imagingArea Physical photosensitive imaging area.
15
+ * @returns Physical diagonal, aspect ratio, and diagonal 35 mm crop factor.
16
+ */
17
+ export function calculateImagingAreaMetrics(imagingArea) {
18
+ requirePositiveFinite("imagingArea.widthMm", imagingArea.widthMm);
19
+ requirePositiveFinite("imagingArea.heightMm", imagingArea.heightMm);
20
+ const diagonalMm = Math.hypot(imagingArea.widthMm, imagingArea.heightMm);
21
+ return calculatedResult({
22
+ diagonalMm,
23
+ aspectRatio: imagingArea.widthMm / imagingArea.heightMm,
24
+ cropFactor35Mm: REFERENCE_35MM_DIAGONAL_MM / diagonalMm
25
+ }, "sensor-imaging-area", "1.0.0", [
26
+ "35 mm reference frame is 36 × 24 mm and crop factor is diagonal-based.",
27
+ "Digital/output cropping is excluded from physical imaging-area crop factor."
28
+ ]);
29
+ }
30
+ /**
31
+ * Calculates physical imaging-area, native-raster, and geometric sampling
32
+ * metrics without coupling sensor size to resolution.
33
+ *
34
+ * The supplied raster is assumed to span the supplied imaging area. Derived
35
+ * sampling pitch is geometric sample spacing only and must not be interpreted
36
+ * as photosite fill factor or photon-collection area.
37
+ *
38
+ * @param input Physical imaging area and native effective image raster.
39
+ * @returns Derived imaging-area, raster, and sampling metrics.
40
+ */
41
+ export function calculateSensorGeometryMetrics(input) {
42
+ requirePositiveFinite("imagingArea.widthMm", input.imagingArea.widthMm);
43
+ requirePositiveFinite("imagingArea.heightMm", input.imagingArea.heightMm);
44
+ requirePositiveInteger("nativeRaster.pixelWidth", input.nativeRaster.pixelWidth);
45
+ requirePositiveInteger("nativeRaster.pixelHeight", input.nativeRaster.pixelHeight);
46
+ const totalImageSamples = input.nativeRaster.pixelWidth * input.nativeRaster.pixelHeight;
47
+ if (!Number.isSafeInteger(totalImageSamples)) {
48
+ throw new InvalidScientificInputError("nativeRaster total image-sample count must be a positive safe integer.");
49
+ }
50
+ const imagingAreaMetrics = calculateImagingAreaMetrics(input.imagingArea).value;
51
+ const pitchXMicrometers = (input.imagingArea.widthMm / input.nativeRaster.pixelWidth) * 1000;
52
+ const pitchYMicrometers = (input.imagingArea.heightMm / input.nativeRaster.pixelHeight) * 1000;
53
+ return calculatedResult({
54
+ imagingArea: imagingAreaMetrics,
55
+ nativeRaster: {
56
+ totalImageSamples,
57
+ megapixels: totalImageSamples / 1_000_000,
58
+ aspectRatio: input.nativeRaster.pixelWidth / input.nativeRaster.pixelHeight
59
+ },
60
+ sampling: {
61
+ pitchXMicrometers,
62
+ pitchYMicrometers,
63
+ pitchAspectRatio: pitchXMicrometers / pitchYMicrometers
64
+ }
65
+ }, "sensor-imaging-area-native-raster", "1.0.0", [
66
+ "35 mm reference frame is 36 × 24 mm and crop factor is diagonal-based.",
67
+ "The native effective image raster is assumed to span the supplied physical imaging area.",
68
+ "Derived sampling pitch is geometric image-sample spacing, not physical photodiode active area or fill factor."
69
+ ]);
70
+ }
71
+ //# sourceMappingURL=sensor-geometry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sensor-geometry.js","sourceRoot":"","sources":["../../src/sensor/sensor-geometry.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC,OAAO,EACL,gBAAgB,EAEjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,uBAAuB,GAAG,EAAE,CAAC;AACnC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AACpC,MAAM,0BAA0B,GAAG,IAAI,CAAC,KAAK,CAC3C,uBAAuB,EACvB,wBAAwB,CACzB,CAAC;AAkFF;;;;;;;;;GASG;AACH,MAAM,UAAU,2BAA2B,CACzC,WAA8B;IAE9B,qBAAqB,CAAC,qBAAqB,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAClE,qBAAqB,CAAC,sBAAsB,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAEpE,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAEzE,OAAO,gBAAgB,CACrB;QACE,UAAU;QACV,WAAW,EAAE,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,QAAQ;QACvD,cAAc,EAAE,0BAA0B,GAAG,UAAU;KACxD,EACD,qBAAqB,EACrB,OAAO,EACP;QACE,wEAAwE;QACxE,6EAA6E;KAC9E,CACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,8BAA8B,CAC5C,KAA0C;IAE1C,qBAAqB,CAAC,qBAAqB,EAAE,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACxE,qBAAqB,CAAC,sBAAsB,EAAE,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC1E,sBAAsB,CACpB,yBAAyB,EACzB,KAAK,CAAC,YAAY,CAAC,UAAU,CAC9B,CAAC;IACF,sBAAsB,CACpB,0BAA0B,EAC1B,KAAK,CAAC,YAAY,CAAC,WAAW,CAC/B,CAAC;IAEF,MAAM,iBAAiB,GACrB,KAAK,CAAC,YAAY,CAAC,UAAU,GAAG,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC;IACjE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,2BAA2B,CACnC,wEAAwE,CACzE,CAAC;IACJ,CAAC;IAED,MAAM,kBAAkB,GAAG,2BAA2B,CACpD,KAAK,CAAC,WAAW,CAClB,CAAC,KAAK,CAAC;IACR,MAAM,iBAAiB,GACrB,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,GAAG,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;IACrE,MAAM,iBAAiB,GACrB,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,GAAG,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;IAEvE,OAAO,gBAAgB,CACrB;QACE,WAAW,EAAE,kBAAkB;QAC/B,YAAY,EAAE;YACZ,iBAAiB;YACjB,UAAU,EAAE,iBAAiB,GAAG,SAAS;YACzC,WAAW,EACT,KAAK,CAAC,YAAY,CAAC,UAAU,GAAG,KAAK,CAAC,YAAY,CAAC,WAAW;SACjE;QACD,QAAQ,EAAE;YACR,iBAAiB;YACjB,iBAAiB;YACjB,gBAAgB,EAAE,iBAAiB,GAAG,iBAAiB;SACxD;KACF,EACD,mCAAmC,EACnC,OAAO,EACP;QACE,wEAAwE;QACxE,0FAA0F;QAC1F,+GAA+G;KAChH,CACF,CAAC;AACJ,CAAC"}
@@ -1,5 +1,8 @@
1
1
  import type { CalculationProvenance } from "../core/calculation-result.js";
2
+ import { type ActiveCaptureFieldOfView, type CaptureOrientation, type OutputFieldOfView, type PhysicalBoundsFromOpticalAxisMm, type RasterRect, type RasterVector, type ResolvedCaptureGeometry } from "../output/capture-geometry.js";
3
+ import { type RasterDimensions, type SensorGeometryMetrics, type SensorImagingArea } from "../sensor/sensor-geometry.js";
2
4
  import type { Vector3 } from "../schema/scene.js";
5
+ export declare const POC_SIMULATION_API_VERSION: "0.20.0";
3
6
  export interface PocSimulationRequest {
4
7
  sensor: {
5
8
  widthMm: number;
@@ -25,8 +28,24 @@ export interface PocSimulationRequest {
25
28
  };
26
29
  };
27
30
  crop: {
31
+ /**
32
+ * Legacy centered same-aspect crop factor.
33
+ *
34
+ * When capture geometry is supplied this must remain 1. New callers should
35
+ * use capture.activeCaptureRect/outputCropRect instead of stacking two
36
+ * independent crop models.
37
+ */
28
38
  factor: number;
29
39
  };
40
+ /**
41
+ * Opt-in staged capture geometry. Omit for exact legacy POC behavior.
42
+ */
43
+ capture?: {
44
+ orientation: CaptureOrientation;
45
+ activeCaptureRect?: RasterRect;
46
+ outputCropRect?: RasterRect;
47
+ outputRaster?: RasterDimensions;
48
+ };
30
49
  diffraction: {
31
50
  wavelengthNm: number;
32
51
  };
@@ -77,8 +96,20 @@ interface FieldOfViewSummary {
77
96
  verticalDegrees: number;
78
97
  diagonalDegrees: number;
79
98
  }
99
+ interface CaptureSubjectFraming {
100
+ additionalCropFactor: number;
101
+ raster: RasterDimensions;
102
+ megapixels: number;
103
+ subjectHeightFraction: number;
104
+ subjectClipped: boolean;
105
+ additionalCropApplied: boolean;
106
+ retainedImagingArea: SensorImagingArea;
107
+ physicalBoundsFromOpticalAxisMm: PhysicalBoundsFromOpticalAxisMm;
108
+ effectiveFieldOfView: FieldOfViewSummary;
109
+ basis: "centered-output-framing";
110
+ }
80
111
  export interface PocSimulationResponse {
81
- apiVersion: "0.17.0";
112
+ apiVersion: typeof POC_SIMULATION_API_VERSION;
82
113
  projection: {
83
114
  kind: "focus-aware-thin-lens";
84
115
  focusDistanceM: number;
@@ -95,7 +126,66 @@ export interface PocSimulationResponse {
95
126
  diagonalDegrees: number;
96
127
  };
97
128
  sensor: {
129
+ /** Physical imaging-area/native-raster metrics from the shared sensor foundation. */
130
+ geometry: SensorGeometryMetrics;
131
+ /**
132
+ * Backwards-compatible representative pitch used by the current composed
133
+ * POC calculations. This remains the horizontal pitch.
134
+ */
98
135
  pixelPitchMicrometers: number;
136
+ pitchXMicrometers: number;
137
+ pitchYMicrometers: number;
138
+ pitchAxisRelativeDifference: number;
139
+ };
140
+ capture?: {
141
+ geometry: ResolvedCaptureGeometry;
142
+ activeFieldOfView: ActiveCaptureFieldOfView;
143
+ outputFieldOfView: OutputFieldOfView;
144
+ focalLength: {
145
+ actualFocalLengthMm: number;
146
+ equivalentFocalLength35Mm: number;
147
+ cropFactor35Mm: number;
148
+ activeImagingAreaDiagonalMm: number;
149
+ basis: "diagonal";
150
+ };
151
+ /**
152
+ * Axis-aware pixel-domain mapping from oriented active-capture samples to
153
+ * the declared output raster. Subject framing is a later crop, not another
154
+ * resampling step.
155
+ */
156
+ outputSamplingScale: {
157
+ x: number;
158
+ y: number;
159
+ axisRelativeDifference: number;
160
+ };
161
+ /**
162
+ * Additional post-output subject framing. This does not mutate physical
163
+ * sensor identity, active capture, or active-capture focal equivalence.
164
+ */
165
+ subjectFraming?: CaptureSubjectFraming;
166
+ motion: {
167
+ nativeRasterDeltaPixels: RasterVector;
168
+ orientedCaptureDeltaPixels: RasterVector;
169
+ outputDeltaPixels: RasterVector;
170
+ };
171
+ motionSamples?: readonly {
172
+ id: string;
173
+ nativeRasterDeltaPixels: RasterVector;
174
+ orientedCaptureDeltaPixels: RasterVector;
175
+ outputDeltaPixels: RasterVector;
176
+ }[];
177
+ cameraShake?: {
178
+ unstabilized: {
179
+ nativeRasterDeltaPixels: RasterVector;
180
+ orientedCaptureDeltaPixels: RasterVector;
181
+ outputDeltaPixels: RasterVector;
182
+ };
183
+ stabilized: {
184
+ nativeRasterDeltaPixels: RasterVector;
185
+ orientedCaptureDeltaPixels: RasterVector;
186
+ outputDeltaPixels: RasterVector;
187
+ };
188
+ };
99
189
  };
100
190
  crop: {
101
191
  cropFactor: number;
@@ -112,6 +202,8 @@ export interface PocSimulationResponse {
112
202
  source: "equivalent-viewing-approximation";
113
203
  circleOfConfusionMm: number;
114
204
  scaleFactor: number;
205
+ targetBasis: "full-sensor" | "final-retained-output";
206
+ targetImagingArea: SensorImagingArea;
115
207
  provenance: {
116
208
  kind: "approximation";
117
209
  model: string;
@@ -1 +1 @@
1
- {"version":3,"file":"poc-simulation.d.ts","sourceRoot":"","sources":["../../src/simulation/poc-simulation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"poc-simulation.d.ts","sourceRoot":"","sources":["../../src/simulation/poc-simulation.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAe3E,OAAO,EAKL,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,+BAA+B,EACpC,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC7B,MAAM,+BAA+B,CAAC;AAIvC,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACvB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAGlD,eAAO,MAAM,0BAA0B,EAAG,QAAiB,CAAC;AAI5D,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,IAAI,EAAE;QACJ,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,QAAQ,EAAE;QACR,cAAc,EAAE,MAAM,CAAC;QACvB,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,KAAK,EAAE;QACL,cAAc,EAAE,MAAM,CAAC;QACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,kCAAkC,CAAC,EAAE;YACnC,sBAAsB,EAAE,MAAM,CAAC;YAC/B,uBAAuB,EAAE,MAAM,CAAC;YAChC,4BAA4B,EAAE,MAAM,CAAC;SACtC,CAAC;KACH,CAAC;IACF,IAAI,EAAE;QACJ;;;;;;WAMG;QACH,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF;;OAEG;IACH,OAAO,CAAC,EAAE;QACR,WAAW,EAAE,kBAAkB,CAAC;QAChC,iBAAiB,CAAC,EAAE,UAAU,CAAC;QAC/B,cAAc,CAAC,EAAE,UAAU,CAAC;QAC5B,YAAY,CAAC,EAAE,gBAAgB,CAAC;KACjC,CAAC;IACF,WAAW,EAAE;QACX,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,MAAM,EAAE;QACN,SAAS,EAAE,OAAO,CAAC;QACnB,WAAW,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,cAAc,CAAC,EAAE,SAAS;QACxB,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,EAAE,MAAM,CAAC;KACnB,EAAE,CAAC;IACJ,eAAe,CAAC,EAAE,SAAS;QACzB,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,EAAE,CAAC;IACJ,aAAa,CAAC,EAAE,SAAS;QACvB,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,EAAE,OAAO,CAAC;QACnB,WAAW,EAAE,OAAO,CAAC;KACtB,EAAE,CAAC;IACJ,WAAW,CAAC,EAAE;QACZ,2BAA2B,EAAE,MAAM,CAAC;KACrC,CAAC;IACF,WAAW,CAAC,EAAE;QACZ,wBAAwB,EAAE;YACxB,GAAG,EAAE,MAAM,CAAC;YACZ,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;QACF,4BAA4B,EAAE,MAAM,CAAC;KACtC,CAAC;IACF,aAAa,CAAC,EAAE;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,0BAA0B,CAAC,EAAE,MAAM,CAAC;KACrC,CAAC;IACF,WAAW,CAAC,EAAE;QACZ,qBAAqB,CAAC,EAAE,MAAM,CAAC;KAChC,CAAC;CACH;AAsDD,UAAU,kBAAkB;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,qBAAqB;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,cAAc,EAAE,OAAO,CAAC;IACxB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,mBAAmB,EAAE,iBAAiB,CAAC;IACvC,+BAA+B,EAAE,+BAA+B,CAAC;IACjE,oBAAoB,EAAE,kBAAkB,CAAC;IACzC,KAAK,EAAE,yBAAyB,CAAC;CAClC;AAyFD,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,OAAO,0BAA0B,CAAC;IAC9C,UAAU,EAAE;QACV,IAAI,EAAE,uBAAuB,CAAC;QAC9B,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;QACxB,uBAAuB,EAAE,MAAM,CAAC;QAChC,UAAU,EAAE,qBAAqB,CAAC;KACnC,CAAC;IACF;;OAEG;IACH,WAAW,EAAE;QACX,iBAAiB,EAAE,MAAM,CAAC;QAC1B,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,MAAM,EAAE;QACN,qFAAqF;QACrF,QAAQ,EAAE,qBAAqB,CAAC;QAChC;;;WAGG;QACH,qBAAqB,EAAE,MAAM,CAAC;QAC9B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,2BAA2B,EAAE,MAAM,CAAC;KACrC,CAAC;IACF,OAAO,CAAC,EAAE;QACR,QAAQ,EAAE,uBAAuB,CAAC;QAClC,iBAAiB,EAAE,wBAAwB,CAAC;QAC5C,iBAAiB,EAAE,iBAAiB,CAAC;QACrC,WAAW,EAAE;YACX,mBAAmB,EAAE,MAAM,CAAC;YAC5B,yBAAyB,EAAE,MAAM,CAAC;YAClC,cAAc,EAAE,MAAM,CAAC;YACvB,2BAA2B,EAAE,MAAM,CAAC;YACpC,KAAK,EAAE,UAAU,CAAC;SACnB,CAAC;QACF;;;;WAIG;QACH,mBAAmB,EAAE;YACnB,CAAC,EAAE,MAAM,CAAC;YACV,CAAC,EAAE,MAAM,CAAC;YACV,sBAAsB,EAAE,MAAM,CAAC;SAChC,CAAC;QACF;;;WAGG;QACH,cAAc,CAAC,EAAE,qBAAqB,CAAC;QACvC,MAAM,EAAE;YACN,uBAAuB,EAAE,YAAY,CAAC;YACtC,0BAA0B,EAAE,YAAY,CAAC;YACzC,iBAAiB,EAAE,YAAY,CAAC;SACjC,CAAC;QACF,aAAa,CAAC,EAAE,SAAS;YACvB,EAAE,EAAE,MAAM,CAAC;YACX,uBAAuB,EAAE,YAAY,CAAC;YACtC,0BAA0B,EAAE,YAAY,CAAC;YACzC,iBAAiB,EAAE,YAAY,CAAC;SACjC,EAAE,CAAC;QACJ,WAAW,CAAC,EAAE;YACZ,YAAY,EAAE;gBACZ,uBAAuB,EAAE,YAAY,CAAC;gBACtC,0BAA0B,EAAE,YAAY,CAAC;gBACzC,iBAAiB,EAAE,YAAY,CAAC;aACjC,CAAC;YACF,UAAU,EAAE;gBACV,uBAAuB,EAAE,YAAY,CAAC;gBACtC,0BAA0B,EAAE,YAAY,CAAC;gBACzC,iBAAiB,EAAE,YAAY,CAAC;aACjC,CAAC;SACH,CAAC;KACH,CAAC;IACF,IAAI,EAAE;QACJ,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,oBAAoB,EAAE,kBAAkB,CAAC;KAC1C,CAAC;IACF,cAAc,EACV;QACE,MAAM,EAAE,UAAU,CAAC;QACnB,mBAAmB,EAAE,MAAM,CAAC;KAC7B,GACD;QACE,MAAM,EAAE,kCAAkC,CAAC;QAC3C,mBAAmB,EAAE,MAAM,CAAC;QAC5B,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,aAAa,GAAG,uBAAuB,CAAC;QACrD,iBAAiB,EAAE,iBAAiB,CAAC;QACrC,UAAU,EAAE;YACV,IAAI,EAAE,eAAe,CAAC;YACtB,KAAK,EAAE,MAAM,CAAC;YACd,YAAY,EAAE,MAAM,CAAC;YACrB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;SACjC,CAAC;KACH,CAAC;IACN,YAAY,EAAE;QACZ,mBAAmB,EAAE,MAAM,CAAC;QAC5B,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;KACnC,CAAC;IACF,WAAW,EAAE;QACX,4BAA4B,EAAE,MAAM,CAAC;QACrC,kBAAkB,EAAE,MAAM,CAAC;QAC3B,UAAU,EAAE,gBAAgB,CAAC;QAC7B,UAAU,EAAE,qBAAqB,CAAC;KACnC,CAAC;IACF,MAAM,EAAE;QACN,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,eAAe,CAAC,EAAE;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,cAAc,CAAC,EAAE,SAAS;QACxB,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;KACxB,EAAE,CAAC;IACJ,eAAe,CAAC,EAAE,SAAS;QACzB,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACtB,EAAE,CAAC;IACJ,aAAa,CAAC,EAAE,SAAS;QACvB,EAAE,EAAE,MAAM,CAAC;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;KACtB,EAAE,CAAC;IACJ,WAAW,CAAC,EAAE;QACZ,oEAAoE;QACpE,oBAAoB,EAAE,MAAM,CAAC;QAC7B,qDAAqD;QACrD,eAAe,EAAE,MAAM,CAAC;QACxB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,qBAAqB,EAAE,MAAM,CAAC;QAC9B,cAAc,EAAE,OAAO,CAAC;QACxB,qBAAqB,EAAE,OAAO,CAAC;QAC/B,oBAAoB,EAAE,kBAAkB,CAAC;KAC1C,CAAC;IACF,aAAa,CAAC,EAAE;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,EAAE,MAAM,CAAC;QACxB,uBAAuB,EAAE,SAAS,MAAM,EAAE,CAAC;QAC3C,kBAAkB,EAAE,SAAS;YAC3B,CAAC,EAAE,MAAM,CAAC;YACV,CAAC,EAAE,MAAM,CAAC;SACX,EAAE,CAAC;QACJ,UAAU,EAAE,qBAAqB,CAAC;KACnC,CAAC;IACF,yBAAyB,CAAC,EAAE;QAC1B,gBAAgB,EAAE,MAAM,CAAC;QACzB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,qBAAqB,EAAE,MAAM,CAAC;QAC9B,kCAAkC,EAAE,MAAM,CAAC;QAC3C,gBAAgB,EAAE,MAAM,CAAC;QACzB,aAAa,CAAC,EAAE;YACd,EAAE,EAAE,MAAM,CAAC;YACX,cAAc,EAAE,MAAM,CAAC;SACxB,CAAC;QACF,WAAW,CAAC,EAAE;YACZ,wBAAwB,EAAE,MAAM,CAAC;YACjC,cAAc,EAAE,eAAe,CAAC;SACjC,CAAC;QACF,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,WAAW,CAAC,EAAE;QACZ,oBAAoB,EAAE,MAAM,CAAC;QAC7B,YAAY,EAAE;YACZ,QAAQ,EAAE,MAAM,CAAC;YACjB,QAAQ,EAAE,MAAM,CAAC;YACjB,UAAU,EAAE,MAAM,CAAC;YACnB,cAAc,EAAE,MAAM,CAAC;YACvB,YAAY,EAAE,MAAM,CAAC;YACrB,YAAY,EAAE,MAAM,CAAC;SACtB,CAAC;QACF,UAAU,EAAE;YACV,QAAQ,EAAE,MAAM,CAAC;YACjB,QAAQ,EAAE,MAAM,CAAC;YACjB,UAAU,EAAE,MAAM,CAAC;YACnB,cAAc,EAAE,MAAM,CAAC;YACvB,YAAY,EAAE,MAAM,CAAC;YACrB,YAAY,EAAE,MAAM,CAAC;SACtB,CAAC;QACF,UAAU,EAAE;YACV,IAAI,EAAE,eAAe,CAAC;YACtB,KAAK,EAAE,MAAM,CAAC;YACd,YAAY,EAAE,MAAM,CAAC;YACrB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;SACjC,CAAC;KACH,CAAC;IACF,UAAU,EAAE;QACV,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC;QAC7B,UAAU,EAAE;YACV,UAAU,EAAE,YAAY,CAAC;YACzB,WAAW,EAAE,YAAY,CAAC;YAC1B,IAAI,EAAE,YAAY,CAAC;YACnB,cAAc,EAAE,YAAY,GAAG,eAAe,CAAC;YAC/C,YAAY,EAAE,YAAY,CAAC;YAC3B,WAAW,EAAE,YAAY,CAAC;YAC1B,MAAM,EAAE,YAAY,CAAC;YACrB,QAAQ,EAAE,YAAY,CAAC;YACvB,aAAa,CAAC,EAAE,YAAY,CAAC;YAC7B,WAAW,CAAC,EAAE,eAAe,CAAC;SAC/B,CAAC;QACF,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAoCD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,oBAAoB,GAC5B,qBAAqB,CAwvBvB"}
@@ -1,5 +1,6 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
- import { calculateFieldOfView } from "../camera/field-of-view.js";
2
+ import { calculateEquivalentFocalLength35Mm } from "../camera/equivalent-focal-length.js";
3
+ import { calculateFieldOfView, calculateFieldOfViewBounds } from "../camera/field-of-view.js";
3
4
  import { calculateProjectedObjectSize } from "../camera/projected-object-size.js";
4
5
  import { InvalidScientificInputError, requirePositiveFinite } from "../core/validation.js";
5
6
  import { calculateExposureValue100 } from "../exposure/exposure.js";
@@ -9,10 +10,14 @@ import { estimateEquivalentViewingCircleOfConfusion } from "../optics/circle-of-
9
10
  import { calculateAiryDisk } from "../optics/diffraction.js";
10
11
  import { calculateThinLensImageDistance } from "../optics/thin-lens.js";
11
12
  import { calculateDefocusCircle, calculateDepthOfField } from "../optics/depth-of-field.js";
13
+ import { calculateActiveCaptureFieldOfView, calculateOutputFieldOfView, resolveCaptureGeometry, transformNativeRasterVectorToOriented } from "../output/capture-geometry.js";
12
14
  import { calculateCenteredCrop } from "../output/crop.js";
13
15
  import { calculateSubjectFramingCrop } from "../output/subject-framing-crop.js";
14
16
  import { calculatePixelPitch } from "../sensor/pixel-pitch.js";
17
+ import { calculateSensorGeometryMetrics } from "../sensor/sensor-geometry.js";
15
18
  import { estimateCameraShakeBlur } from "../stabilization/camera-shake.js";
19
+ export const POC_SIMULATION_API_VERSION = "0.20.0";
20
+ const POC_MAX_PITCH_AXIS_RELATIVE_DIFFERENCE = 0.01;
16
21
  function calculateCroppedFieldOfView(sensorWidthMm, sensorHeightMm, focalLengthMm, focusDistanceM, cropFactor) {
17
22
  const diagonalMm = Math.hypot(sensorWidthMm, sensorHeightMm);
18
23
  return {
@@ -49,6 +54,80 @@ function requireUniqueSampleIds(label, samples) {
49
54
  seen.add(normalizedId);
50
55
  }
51
56
  }
57
+ function centeredPhysicalCropBounds(bounds, retainedFractionX, retainedFractionY) {
58
+ const centerX = (bounds.left + bounds.right) / 2;
59
+ const centerY = (bounds.top + bounds.bottom) / 2;
60
+ const halfWidth = ((bounds.right - bounds.left) * retainedFractionX) / 2;
61
+ const halfHeight = ((bounds.bottom - bounds.top) * retainedFractionY) / 2;
62
+ return {
63
+ left: centerX - halfWidth,
64
+ right: centerX + halfWidth,
65
+ top: centerY - halfHeight,
66
+ bottom: centerY + halfHeight
67
+ };
68
+ }
69
+ function calculateFieldOfViewForPhysicalBounds(bounds, focalLengthMm, focusDistanceM) {
70
+ const horizontal = calculateFieldOfViewBounds({
71
+ focalLengthMm,
72
+ minimumSensorCoordinateMm: bounds.left,
73
+ maximumSensorCoordinateMm: bounds.right,
74
+ focusDistanceM
75
+ }).value;
76
+ const vertical = calculateFieldOfViewBounds({
77
+ focalLengthMm,
78
+ minimumSensorCoordinateMm: bounds.top,
79
+ maximumSensorCoordinateMm: bounds.bottom,
80
+ focusDistanceM
81
+ }).value;
82
+ const projectionDistanceMm = horizontal.projectionDistanceMm;
83
+ const corners = {
84
+ topLeft: { x: bounds.left, y: bounds.top },
85
+ topRight: { x: bounds.right, y: bounds.top },
86
+ bottomRight: { x: bounds.right, y: bounds.bottom },
87
+ bottomLeft: { x: bounds.left, y: bounds.bottom }
88
+ };
89
+ const angleBetween = (first, second) => {
90
+ const firstLength = Math.hypot(first.x, first.y, projectionDistanceMm);
91
+ const secondLength = Math.hypot(second.x, second.y, projectionDistanceMm);
92
+ const dot = first.x * second.x +
93
+ first.y * second.y +
94
+ projectionDistanceMm * projectionDistanceMm;
95
+ const cosine = Math.max(-1, Math.min(1, dot / (firstLength * secondLength)));
96
+ return (Math.acos(cosine) * 180) / Math.PI;
97
+ };
98
+ return {
99
+ horizontalDegrees: horizontal.degrees,
100
+ verticalDegrees: vertical.degrees,
101
+ diagonalDegrees: Math.max(angleBetween(corners.topLeft, corners.bottomRight), angleBetween(corners.topRight, corners.bottomLeft))
102
+ };
103
+ }
104
+ function isPortraitOrientation(orientation) {
105
+ return (orientation === "portrait-clockwise" ||
106
+ orientation === "portrait-counter-clockwise");
107
+ }
108
+ function resolveCaptureVector(legacyImagePlaneVector, orientation, geometry) {
109
+ // Legacy projected-motion/camera-shake components use +X right and +Y up.
110
+ // Capture raster coordinates use +X right and +Y down. Preserve the legacy
111
+ // fields unchanged and convert explicitly before applying physical rotation.
112
+ const nativeRasterDeltaPixels = {
113
+ x: legacyImagePlaneVector.x,
114
+ y: -legacyImagePlaneVector.y
115
+ };
116
+ const orientedCaptureDeltaPixels = transformNativeRasterVectorToOriented({
117
+ vector: nativeRasterDeltaPixels,
118
+ orientation
119
+ });
120
+ const scaleX = geometry.output.orientedCaptureToOutputScale.x;
121
+ const scaleY = geometry.output.orientedCaptureToOutputScale.y;
122
+ return {
123
+ nativeRasterDeltaPixels,
124
+ orientedCaptureDeltaPixels,
125
+ outputDeltaPixels: {
126
+ x: orientedCaptureDeltaPixels.x * scaleX,
127
+ y: orientedCaptureDeltaPixels.y * scaleY
128
+ }
129
+ };
130
+ }
52
131
  /**
53
132
  * Composes the validated POC calculations into a single renderer/agent-facing
54
133
  * response without introducing any new photographic model.
@@ -59,6 +138,48 @@ function requireUniqueSampleIds(label, samples) {
59
138
  export function simulatePocCamera(request) {
60
139
  requirePositiveFinite("sensor.widthMm", request.sensor.widthMm);
61
140
  requirePositiveFinite("sensor.heightMm", request.sensor.heightMm);
141
+ const sensorGeometry = calculateSensorGeometryMetrics({
142
+ imagingArea: {
143
+ widthMm: request.sensor.widthMm,
144
+ heightMm: request.sensor.heightMm
145
+ },
146
+ nativeRaster: {
147
+ pixelWidth: request.sensor.pixelWidth,
148
+ pixelHeight: request.sensor.pixelHeight
149
+ }
150
+ }).value;
151
+ const pitchXMicrometers = sensorGeometry.sampling.pitchXMicrometers;
152
+ const pitchYMicrometers = sensorGeometry.sampling.pitchYMicrometers;
153
+ const pitchAxisRelativeDifference = Math.abs(pitchXMicrometers - pitchYMicrometers) /
154
+ ((pitchXMicrometers + pitchYMicrometers) / 2);
155
+ if (pitchAxisRelativeDifference >
156
+ POC_MAX_PITCH_AXIS_RELATIVE_DIFFERENCE) {
157
+ throw new InvalidScientificInputError("The composed POC currently requires approximately square geometric sampling; X/Y pitch differ by more than 1%. Use lower-level axis-aware engine primitives until the POC contract supports separate X/Y sampling.");
158
+ }
159
+ const capture = request.capture;
160
+ const subjectCropRequest = request.subjectCrop;
161
+ const captureGeometry = capture === undefined
162
+ ? undefined
163
+ : resolveCaptureGeometry({
164
+ imagingArea: {
165
+ widthMm: request.sensor.widthMm,
166
+ heightMm: request.sensor.heightMm
167
+ },
168
+ nativeRaster: {
169
+ pixelWidth: request.sensor.pixelWidth,
170
+ pixelHeight: request.sensor.pixelHeight
171
+ },
172
+ orientation: capture.orientation,
173
+ ...(capture.activeCaptureRect === undefined
174
+ ? {}
175
+ : { activeCaptureRect: capture.activeCaptureRect }),
176
+ ...(capture.outputCropRect === undefined
177
+ ? {}
178
+ : { outputCropRect: capture.outputCropRect }),
179
+ ...(capture.outputRaster === undefined
180
+ ? {}
181
+ : { outputRaster: capture.outputRaster })
182
+ }).value;
62
183
  requirePositiveFinite("lens.focalLengthMm", request.lens.focalLengthMm);
63
184
  requirePositiveFinite("lens.aperture", request.lens.aperture);
64
185
  requirePositiveFinite("exposure.shutterSeconds", request.exposure.shutterSeconds);
@@ -69,20 +190,10 @@ export function simulatePocCamera(request) {
69
190
  if (hasExplicitCircleOfConfusion === hasEquivalentViewingCriterion) {
70
191
  throw new InvalidScientificInputError("Provide exactly one focus circle-of-confusion criterion.");
71
192
  }
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
193
  requirePositiveFinite("crop.factor", request.crop.factor);
194
+ if (capture !== undefined && request.crop.factor !== 1) {
195
+ throw new InvalidScientificInputError("capture geometry cannot be combined with legacy crop.factor other than 1.");
196
+ }
86
197
  requirePositiveFinite("diffraction.wavelengthNm", request.diffraction.wavelengthNm);
87
198
  requireUniqueSampleIds("defocusSamples", request.defocusSamples);
88
199
  requireUniqueSampleIds("samplingSamples", request.samplingSamples);
@@ -107,6 +218,51 @@ export function simulatePocCamera(request) {
107
218
  sensorDimensionMm: diagonalMm,
108
219
  focusDistanceM: request.focus.focusDistanceM
109
220
  });
221
+ const activeCaptureFieldOfView = captureGeometry === undefined || capture === undefined
222
+ ? undefined
223
+ : calculateActiveCaptureFieldOfView({
224
+ imagingArea: {
225
+ widthMm: request.sensor.widthMm,
226
+ heightMm: request.sensor.heightMm
227
+ },
228
+ nativeRaster: {
229
+ pixelWidth: request.sensor.pixelWidth,
230
+ pixelHeight: request.sensor.pixelHeight
231
+ },
232
+ orientation: capture.orientation,
233
+ ...(capture.activeCaptureRect === undefined
234
+ ? {}
235
+ : { activeCaptureRect: capture.activeCaptureRect }),
236
+ focalLengthMm: request.lens.focalLengthMm,
237
+ focusDistanceM: request.focus.focusDistanceM
238
+ }).value;
239
+ const equivalentFocalLength = captureGeometry === undefined
240
+ ? undefined
241
+ : calculateEquivalentFocalLength35Mm({
242
+ focalLengthMm: request.lens.focalLengthMm,
243
+ activeImagingArea: captureGeometry.activeCapture.imagingArea
244
+ }).value;
245
+ const outputFieldOfView = captureGeometry === undefined || capture === undefined
246
+ ? undefined
247
+ : calculateOutputFieldOfView({
248
+ imagingArea: {
249
+ widthMm: request.sensor.widthMm,
250
+ heightMm: request.sensor.heightMm
251
+ },
252
+ nativeRaster: {
253
+ pixelWidth: request.sensor.pixelWidth,
254
+ pixelHeight: request.sensor.pixelHeight
255
+ },
256
+ orientation: capture.orientation,
257
+ ...(capture.activeCaptureRect === undefined
258
+ ? {}
259
+ : { activeCaptureRect: capture.activeCaptureRect }),
260
+ ...(capture.outputCropRect === undefined
261
+ ? {}
262
+ : { outputCropRect: capture.outputCropRect }),
263
+ focalLengthMm: request.lens.focalLengthMm,
264
+ focusDistanceM: request.focus.focusDistanceM
265
+ }).value;
110
266
  const pixelPitch = calculatePixelPitch({
111
267
  sensorWidthMm: request.sensor.widthMm,
112
268
  pixelWidth: request.sensor.pixelWidth
@@ -117,12 +273,6 @@ export function simulatePocCamera(request) {
117
273
  cropFactor: request.crop.factor
118
274
  });
119
275
  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
276
  const diffraction = calculateAiryDisk({
127
277
  aperture: request.lens.aperture,
128
278
  wavelengthNm: request.diffraction.wavelengthNm
@@ -149,6 +299,70 @@ export function simulatePocCamera(request) {
149
299
  focusDistanceM: request.focus.focusDistanceM,
150
300
  pixelPitchMicrometers: pixelPitch.value.micrometers
151
301
  }).value;
302
+ const captureSubjectFraming = captureGeometry === undefined ||
303
+ capture === undefined ||
304
+ subjectCropRequest === undefined ||
305
+ subjectSampling === undefined
306
+ ? undefined
307
+ : (() => {
308
+ const orientedSubjectHeightPixels = isPortraitOrientation(capture.orientation)
309
+ ? (subjectSampling.widthPixels ?? 0)
310
+ : (subjectSampling.heightPixels ?? 0);
311
+ const outputSubjectHeightPixels = orientedSubjectHeightPixels *
312
+ captureGeometry.output.orientedCaptureToOutputScale.y;
313
+ const framing = calculateSubjectFramingCrop({
314
+ pixelWidth: captureGeometry.output.raster.pixelWidth,
315
+ pixelHeight: captureGeometry.output.raster.pixelHeight,
316
+ subjectHeightPixels: outputSubjectHeightPixels,
317
+ targetSubjectHeightFraction: subjectCropRequest.targetSubjectHeightFraction
318
+ }).value;
319
+ const retainedBounds = centeredPhysicalCropBounds(captureGeometry.output.physicalBoundsFromOpticalAxisMm, framing.pixelWidth / captureGeometry.output.raster.pixelWidth, framing.pixelHeight / captureGeometry.output.raster.pixelHeight);
320
+ const retainedImagingArea = {
321
+ widthMm: retainedBounds.right - retainedBounds.left,
322
+ heightMm: retainedBounds.bottom - retainedBounds.top
323
+ };
324
+ return {
325
+ additionalCropFactor: framing.cropFactor,
326
+ raster: {
327
+ pixelWidth: framing.pixelWidth,
328
+ pixelHeight: framing.pixelHeight
329
+ },
330
+ megapixels: framing.megapixels,
331
+ subjectHeightFraction: framing.subjectHeightFraction,
332
+ subjectClipped: framing.subjectClipped,
333
+ additionalCropApplied: framing.cropped,
334
+ retainedImagingArea,
335
+ physicalBoundsFromOpticalAxisMm: retainedBounds,
336
+ effectiveFieldOfView: calculateFieldOfViewForPhysicalBounds(retainedBounds, request.lens.focalLengthMm, request.focus.focusDistanceM),
337
+ basis: "centered-output-framing"
338
+ };
339
+ })();
340
+ const equivalentViewingTargetArea = captureGeometry === undefined
341
+ ? {
342
+ widthMm: request.sensor.widthMm,
343
+ heightMm: request.sensor.heightMm
344
+ }
345
+ : (captureSubjectFraming?.retainedImagingArea ??
346
+ captureGeometry.output.imagingArea);
347
+ const equivalentViewingCircleOfConfusion = request.focus.equivalentViewingCircleOfConfusion === undefined
348
+ ? undefined
349
+ : estimateEquivalentViewingCircleOfConfusion({
350
+ sensorWidthMm: equivalentViewingTargetArea.widthMm,
351
+ sensorHeightMm: equivalentViewingTargetArea.heightMm,
352
+ ...request.focus.equivalentViewingCircleOfConfusion
353
+ });
354
+ const circleOfConfusionMm = equivalentViewingCircleOfConfusion?.value.circleOfConfusionMm ??
355
+ request.focus.circleOfConfusionMm;
356
+ if (circleOfConfusionMm === undefined) {
357
+ throw new InvalidScientificInputError("A focus circle-of-confusion criterion is required.");
358
+ }
359
+ requirePositiveFinite("focus.circleOfConfusionMm", circleOfConfusionMm);
360
+ const depthOfField = calculateDepthOfField({
361
+ focalLengthMm: request.lens.focalLengthMm,
362
+ aperture: request.lens.aperture,
363
+ focusDistanceM: request.focus.focusDistanceM,
364
+ circleOfConfusionMm
365
+ });
152
366
  const samplingSamples = request.samplingSamples === undefined
153
367
  ? undefined
154
368
  : request.samplingSamples.map((sample) => {
@@ -191,13 +405,15 @@ export function simulatePocCamera(request) {
191
405
  (pixelPitch.value.micrometers / 1000)
192
406
  };
193
407
  });
194
- const subjectCrop = request.subjectCrop === undefined || subjectSampling === undefined
408
+ const subjectCrop = capture !== undefined ||
409
+ subjectCropRequest === undefined ||
410
+ subjectSampling === undefined
195
411
  ? undefined
196
412
  : calculateSubjectFramingCrop({
197
413
  pixelWidth: crop.value.pixelWidth,
198
414
  pixelHeight: crop.value.pixelHeight,
199
415
  subjectHeightPixels: subjectSampling.heightPixels ?? 0,
200
- targetSubjectHeightFraction: request.subjectCrop.targetSubjectHeightFraction
416
+ targetSubjectHeightFraction: subjectCropRequest.targetSubjectHeightFraction
201
417
  }).value;
202
418
  const totalSubjectCropFactor = subjectCrop === undefined
203
419
  ? undefined
@@ -281,8 +497,39 @@ export function simulatePocCamera(request) {
281
497
  (pixelPitch.value.micrometers / 1000)
282
498
  };
283
499
  });
500
+ const captureMotion = captureGeometry === undefined || capture === undefined
501
+ ? undefined
502
+ : resolveCaptureVector({
503
+ x: motion.value.deltaXMm / (pixelPitch.value.micrometers / 1000),
504
+ y: motion.value.deltaYMm / (pixelPitch.value.micrometers / 1000)
505
+ }, capture.orientation, captureGeometry);
506
+ const captureMotionSamples = captureGeometry === undefined ||
507
+ capture === undefined ||
508
+ motionSamples === undefined
509
+ ? undefined
510
+ : motionSamples.map((sample) => ({
511
+ id: sample.id,
512
+ ...resolveCaptureVector({
513
+ x: sample.deltaXPixels,
514
+ y: sample.deltaYPixels
515
+ }, capture.orientation, captureGeometry)
516
+ }));
517
+ const captureCameraShake = captureGeometry === undefined ||
518
+ capture === undefined ||
519
+ cameraShake === undefined
520
+ ? undefined
521
+ : {
522
+ unstabilized: resolveCaptureVector({
523
+ x: cameraShake.value.unstabilized.deltaXPixels ?? 0,
524
+ y: cameraShake.value.unstabilized.deltaYPixels ?? 0
525
+ }, capture.orientation, captureGeometry),
526
+ stabilized: resolveCaptureVector({
527
+ x: cameraShake.value.stabilized.deltaXPixels ?? 0,
528
+ y: cameraShake.value.stabilized.deltaYPixels ?? 0
529
+ }, capture.orientation, captureGeometry)
530
+ };
284
531
  return {
285
- apiVersion: "0.17.0",
532
+ apiVersion: POC_SIMULATION_API_VERSION,
286
533
  projection: {
287
534
  kind: "focus-aware-thin-lens",
288
535
  focusDistanceM: request.focus.focusDistanceM,
@@ -296,8 +543,39 @@ export function simulatePocCamera(request) {
296
543
  diagonalDegrees: diagonalFov.value.degrees
297
544
  },
298
545
  sensor: {
299
- pixelPitchMicrometers: pixelPitch.value.micrometers
546
+ geometry: sensorGeometry,
547
+ pixelPitchMicrometers: pixelPitch.value.micrometers,
548
+ pitchXMicrometers,
549
+ pitchYMicrometers,
550
+ pitchAxisRelativeDifference
300
551
  },
552
+ ...(captureGeometry === undefined ||
553
+ activeCaptureFieldOfView === undefined ||
554
+ outputFieldOfView === undefined ||
555
+ equivalentFocalLength === undefined ||
556
+ captureMotion === undefined
557
+ ? {}
558
+ : {
559
+ capture: {
560
+ geometry: captureGeometry,
561
+ activeFieldOfView: activeCaptureFieldOfView,
562
+ outputFieldOfView,
563
+ focalLength: equivalentFocalLength,
564
+ outputSamplingScale: {
565
+ ...captureGeometry.output.orientedCaptureToOutputScale
566
+ },
567
+ ...(captureSubjectFraming === undefined
568
+ ? {}
569
+ : { subjectFraming: captureSubjectFraming }),
570
+ motion: captureMotion,
571
+ ...(captureMotionSamples === undefined
572
+ ? {}
573
+ : { motionSamples: captureMotionSamples }),
574
+ ...(captureCameraShake === undefined
575
+ ? {}
576
+ : { cameraShake: captureCameraShake })
577
+ }
578
+ }),
301
579
  crop: {
302
580
  cropFactor: request.crop.factor,
303
581
  ...crop.value,
@@ -312,6 +590,12 @@ export function simulatePocCamera(request) {
312
590
  source: "equivalent-viewing-approximation",
313
591
  circleOfConfusionMm,
314
592
  scaleFactor: equivalentViewingCircleOfConfusion.value.scaleFactor,
593
+ targetBasis: captureGeometry === undefined
594
+ ? "full-sensor"
595
+ : "final-retained-output",
596
+ targetImagingArea: {
597
+ ...equivalentViewingTargetArea
598
+ },
315
599
  provenance: {
316
600
  kind: "approximation",
317
601
  model: equivalentViewingCircleOfConfusion.provenance.model,