@photivra/engine 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/CITATION.cff +1 -1
- package/README.md +37 -3
- package/dist/index.d.ts +15 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/motion/camera-rotation.d.ts +60 -0
- package/dist/motion/camera-rotation.d.ts.map +1 -1
- package/dist/motion/camera-rotation.js +95 -0
- package/dist/motion/camera-rotation.js.map +1 -1
- package/dist/motion/capture-rotation-inverse-mapping.d.ts +100 -0
- package/dist/motion/capture-rotation-inverse-mapping.d.ts.map +1 -0
- package/dist/motion/capture-rotation-inverse-mapping.js +171 -0
- package/dist/motion/capture-rotation-inverse-mapping.js.map +1 -0
- package/dist/motion/capture-rotation-temporal-quadrature.d.ts +89 -0
- package/dist/motion/capture-rotation-temporal-quadrature.d.ts.map +1 -0
- package/dist/motion/capture-rotation-temporal-quadrature.js +116 -0
- package/dist/motion/capture-rotation-temporal-quadrature.js.map +1 -0
- package/dist/motion/capture-rotation-trajectory.d.ts +98 -0
- package/dist/motion/capture-rotation-trajectory.d.ts.map +1 -0
- package/dist/motion/capture-rotation-trajectory.js +153 -0
- package/dist/motion/capture-rotation-trajectory.js.map +1 -0
- package/dist/optics/lateral-chromatic-aberration.d.ts.map +1 -1
- package/dist/optics/lateral-chromatic-aberration.js +12 -4
- package/dist/optics/lateral-chromatic-aberration.js.map +1 -1
- package/dist/optics/radial-distortion.d.ts +4 -2
- package/dist/optics/radial-distortion.d.ts.map +1 -1
- package/dist/optics/radial-distortion.js +83 -23
- package/dist/optics/radial-distortion.js.map +1 -1
- package/dist/output/capture-geometry.d.ts.map +1 -1
- package/dist/output/capture-geometry.js +24 -11
- package/dist/output/capture-geometry.js.map +1 -1
- package/dist/sensor/capture-color-sampling-binding.d.ts +211 -0
- package/dist/sensor/capture-color-sampling-binding.d.ts.map +1 -0
- package/dist/sensor/capture-color-sampling-binding.js +423 -0
- package/dist/sensor/capture-color-sampling-binding.js.map +1 -0
- package/dist/sensor/capture-mode.d.ts +157 -0
- package/dist/sensor/capture-mode.d.ts.map +1 -0
- package/dist/sensor/capture-mode.js +434 -0
- package/dist/sensor/capture-mode.js.map +1 -0
- package/dist/sensor/color-sampling.d.ts +133 -0
- package/dist/sensor/color-sampling.d.ts.map +1 -0
- package/dist/sensor/color-sampling.js +226 -0
- package/dist/sensor/color-sampling.js.map +1 -0
- package/dist/sensor/exposure-window.d.ts +103 -0
- package/dist/sensor/exposure-window.d.ts.map +1 -0
- package/dist/sensor/exposure-window.js +291 -0
- package/dist/sensor/exposure-window.js.map +1 -0
- package/dist/sensor/optical-stack.d.ts +132 -0
- package/dist/sensor/optical-stack.d.ts.map +1 -0
- package/dist/sensor/optical-stack.js +286 -0
- package/dist/sensor/optical-stack.js.map +1 -0
- package/dist/sensor/readout-exposure-linkage.d.ts +111 -0
- package/dist/sensor/readout-exposure-linkage.d.ts.map +1 -0
- package/dist/sensor/readout-exposure-linkage.js +210 -0
- package/dist/sensor/readout-exposure-linkage.js.map +1 -0
- package/dist/sensor/readout-timing.d.ts +124 -0
- package/dist/sensor/readout-timing.d.ts.map +1 -0
- package/dist/sensor/readout-timing.js +230 -0
- package/dist/sensor/readout-timing.js.map +1 -0
- package/dist/sensor/sampling-aperture.d.ts +154 -0
- package/dist/sensor/sampling-aperture.d.ts.map +1 -0
- package/dist/sensor/sampling-aperture.js +374 -0
- package/dist/sensor/sampling-aperture.js.map +1 -0
- package/dist/sensor/spatial-sample-reduction.d.ts +128 -0
- package/dist/sensor/spatial-sample-reduction.d.ts.map +1 -0
- package/dist/sensor/spatial-sample-reduction.js +299 -0
- package/dist/sensor/spatial-sample-reduction.js.map +1 -0
- package/dist/sensor/spatial-sampling-quadrature.d.ts +155 -0
- package/dist/sensor/spatial-sampling-quadrature.d.ts.map +1 -0
- package/dist/sensor/spatial-sampling-quadrature.js +197 -0
- package/dist/sensor/spatial-sampling-quadrature.js.map +1 -0
- package/docs/ARCHITECTURE.md +17 -0
- package/docs/AUTOMATION_COORDINATION.md +188 -0
- package/docs/IMAGE_FORMATION.md +26 -0
- package/docs/MOTION_AND_SIGNAL.md +142 -0
- package/docs/USAGE.md +1273 -3
- package/package.json +5 -3
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { type EvidenceProvenance } from "../core/evidence-provenance.js";
|
|
2
|
+
export type NativeColorSamplingSiteCoordinateSystem = "native-sensor-color-sampling-site-index";
|
|
3
|
+
export type SensorColorSamplingProfileCoordinateSystem = NativeColorSamplingSiteCoordinateSystem | "native-sensor-layered-spatial-relationship-not-resolved";
|
|
4
|
+
export interface NativeColorSamplingSiteIndex {
|
|
5
|
+
/**
|
|
6
|
+
* Zero-based integer site index from the native sensor's left edge.
|
|
7
|
+
*
|
|
8
|
+
* This is an abstract color-sampling-site lattice index. It is not a
|
|
9
|
+
* NativeImageRaster coordinate and does not assert one site = one physical
|
|
10
|
+
* photodiode.
|
|
11
|
+
*/
|
|
12
|
+
x: number;
|
|
13
|
+
/**
|
|
14
|
+
* Zero-based integer site index from the native sensor's top edge.
|
|
15
|
+
*
|
|
16
|
+
* +Y points downward in native sensor-facing coordinates.
|
|
17
|
+
*/
|
|
18
|
+
y: number;
|
|
19
|
+
}
|
|
20
|
+
export interface MonochromeColorSamplingLayout {
|
|
21
|
+
kind: "monochrome";
|
|
22
|
+
/**
|
|
23
|
+
* Semantic measurement-channel identifier only. It is not a spectral
|
|
24
|
+
* response curve, wavelength, colorimetric primary, or calibration.
|
|
25
|
+
*/
|
|
26
|
+
channelId: string;
|
|
27
|
+
}
|
|
28
|
+
export interface PeriodicMosaicColorSamplingLayout {
|
|
29
|
+
kind: "periodic-mosaic";
|
|
30
|
+
/**
|
|
31
|
+
* Number of color-sampling sites in one horizontal repeat period.
|
|
32
|
+
*/
|
|
33
|
+
repeatWidthSites: number;
|
|
34
|
+
/**
|
|
35
|
+
* Number of color-sampling sites in one vertical repeat period.
|
|
36
|
+
*/
|
|
37
|
+
repeatHeightSites: number;
|
|
38
|
+
/**
|
|
39
|
+
* Row-major semantic channel IDs for one repeating tile.
|
|
40
|
+
*
|
|
41
|
+
* Length must equal repeatWidthSites × repeatHeightSites.
|
|
42
|
+
*/
|
|
43
|
+
siteChannelIds: readonly string[];
|
|
44
|
+
/**
|
|
45
|
+
* The repeat tile is anchored at native sensor sampling-site index (0, 0).
|
|
46
|
+
*
|
|
47
|
+
* Active crops and physical orientation must not silently reset this phase.
|
|
48
|
+
*/
|
|
49
|
+
anchor: "native-sensor-top-left-site";
|
|
50
|
+
}
|
|
51
|
+
export interface LayeredColorSamplingLayout {
|
|
52
|
+
kind: "layered";
|
|
53
|
+
/**
|
|
54
|
+
* Semantic layer/channel identifiers only. They do not define spectral
|
|
55
|
+
* response, depth ordering, spatial sampling density, or registration.
|
|
56
|
+
*/
|
|
57
|
+
layerChannelIds: readonly string[];
|
|
58
|
+
/**
|
|
59
|
+
* The first layered representation is deliberately structural only because
|
|
60
|
+
* real layered sensors may use unequal per-layer spatial sampling.
|
|
61
|
+
*/
|
|
62
|
+
spatialSamplingRelationship: "not-resolved";
|
|
63
|
+
}
|
|
64
|
+
export type SensorColorSamplingLayout = MonochromeColorSamplingLayout | PeriodicMosaicColorSamplingLayout | LayeredColorSamplingLayout;
|
|
65
|
+
export interface SensorColorSamplingProfile {
|
|
66
|
+
schemaVersion: "0.1.0";
|
|
67
|
+
profileId: string;
|
|
68
|
+
/**
|
|
69
|
+
* Evidence supporting this exact topology declaration.
|
|
70
|
+
*
|
|
71
|
+
* Descriptive architecture-family metadata remains a separate contract.
|
|
72
|
+
*/
|
|
73
|
+
evidence: readonly EvidenceProvenance[];
|
|
74
|
+
coordinateSystem: SensorColorSamplingProfileCoordinateSystem;
|
|
75
|
+
layout: SensorColorSamplingLayout;
|
|
76
|
+
}
|
|
77
|
+
export interface ResolveColorSamplingSiteInput {
|
|
78
|
+
profile: SensorColorSamplingProfile;
|
|
79
|
+
site: NativeColorSamplingSiteIndex;
|
|
80
|
+
}
|
|
81
|
+
export interface ResolvedColorSamplingSite {
|
|
82
|
+
profileId: string;
|
|
83
|
+
coordinateSystem: NativeColorSamplingSiteCoordinateSystem;
|
|
84
|
+
site: NativeColorSamplingSiteIndex;
|
|
85
|
+
mapping: {
|
|
86
|
+
kind: "monochrome";
|
|
87
|
+
channelId: string;
|
|
88
|
+
} | {
|
|
89
|
+
kind: "periodic-mosaic";
|
|
90
|
+
channelId: string;
|
|
91
|
+
repeatCoordinate: {
|
|
92
|
+
x: number;
|
|
93
|
+
y: number;
|
|
94
|
+
};
|
|
95
|
+
repeatWidthSites: number;
|
|
96
|
+
repeatHeightSites: number;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Explicit scientific boundaries for downstream consumers.
|
|
100
|
+
*/
|
|
101
|
+
spectralResponseEstablished: false;
|
|
102
|
+
nativeImageRasterBindingEstablished: false;
|
|
103
|
+
physicalPhotodiodeBindingEstablished: false;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Parses an exact color-sampling topology declaration without binding it to
|
|
107
|
+
* NativeImageRaster, physical photodiodes, spectral response, or a
|
|
108
|
+
* manufacturer-specific family enum.
|
|
109
|
+
*
|
|
110
|
+
* Periodic mosaics use an abstract native sensor color-sampling-site lattice
|
|
111
|
+
* with zero-based integer indices, top-left origin, +X right and +Y down.
|
|
112
|
+
* The repeat phase is anchored to the sensor lattice, so later active crops or
|
|
113
|
+
* orientation transforms must preserve the original native site indices.
|
|
114
|
+
*
|
|
115
|
+
* Layered layouts are structural-only in this first contract because real
|
|
116
|
+
* layered sensors may use unequal spatial sampling density/registration across
|
|
117
|
+
* layers. No per-site layered resolver is exposed until that relationship is
|
|
118
|
+
* modeled explicitly.
|
|
119
|
+
*/
|
|
120
|
+
export declare function parseSensorColorSamplingProfile(value: unknown): SensorColorSamplingProfile;
|
|
121
|
+
/**
|
|
122
|
+
* Resolves the semantic measurement-channel assignment at one abstract native
|
|
123
|
+
* sensor color-sampling-site index for monochrome or periodic-mosaic layouts.
|
|
124
|
+
*
|
|
125
|
+
* This API intentionally has no NativeImageRaster input. A later explicit
|
|
126
|
+
* binding must establish how a selected capture mode's effective raster maps
|
|
127
|
+
* to this color-sampling-site lattice before RAW/CFA sampling can be simulated.
|
|
128
|
+
*
|
|
129
|
+
* Layered layouts fail closed because their per-layer spatial relationship is
|
|
130
|
+
* not resolved by the first structural contract.
|
|
131
|
+
*/
|
|
132
|
+
export declare function resolveColorSamplingSite(input: ResolveColorSamplingSiteInput): ResolvedColorSamplingSite;
|
|
133
|
+
//# sourceMappingURL=color-sampling.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-sampling.d.ts","sourceRoot":"","sources":["../../src/sensor/color-sampling.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,gCAAgC,CAAC;AAKxC,MAAM,MAAM,uCAAuC,GACjD,yCAAyC,CAAC;AAE5C,MAAM,MAAM,0CAA0C,GAClD,uCAAuC,GACvC,yDAAyD,CAAC;AAE9D,MAAM,WAAW,4BAA4B;IAC3C;;;;;;OAMG;IACH,CAAC,EAAE,MAAM,CAAC;IACV;;;;OAIG;IACH,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,YAAY,CAAC;IACnB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iCAAiC;IAChD,IAAI,EAAE,iBAAiB,CAAC;IACxB;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC;;;;OAIG;IACH,MAAM,EAAE,6BAA6B,CAAC;CACvC;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,SAAS,CAAC;IAChB;;;OAGG;IACH,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;;;OAGG;IACH,2BAA2B,EAAE,cAAc,CAAC;CAC7C;AAED,MAAM,MAAM,yBAAyB,GACjC,6BAA6B,GAC7B,iCAAiC,GACjC,0BAA0B,CAAC;AAE/B,MAAM,WAAW,0BAA0B;IACzC,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,QAAQ,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACxC,gBAAgB,EAAE,0CAA0C,CAAC;IAC7D,MAAM,EAAE,yBAAyB,CAAC;CACnC;AAED,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,0BAA0B,CAAC;IACpC,IAAI,EAAE,4BAA4B,CAAC;CACpC;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,uCAAuC,CAAC;IAC1D,IAAI,EAAE,4BAA4B,CAAC;IACnC,OAAO,EACH;QACE,IAAI,EAAE,YAAY,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,GACD;QACE,IAAI,EAAE,iBAAiB,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,gBAAgB,EAAE;YAChB,CAAC,EAAE,MAAM,CAAC;YACV,CAAC,EAAE,MAAM,CAAC;SACX,CAAC;QACF,gBAAgB,EAAE,MAAM,CAAC;QACzB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;IACN;;OAEG;IACH,2BAA2B,EAAE,KAAK,CAAC;IACnC,mCAAmC,EAAE,KAAK,CAAC;IAC3C,oCAAoC,EAAE,KAAK,CAAC;CAC7C;AA2ND;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,OAAO,GACb,0BAA0B,CA4C5B;AAmBD;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,6BAA6B,GACnC,yBAAyB,CAwF3B"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
3
|
+
import { parseEvidenceList } from "../core/evidence-provenance.js";
|
|
4
|
+
import { InvalidScientificInputError } from "../core/validation.js";
|
|
5
|
+
function requireRecord(value, path) {
|
|
6
|
+
if (typeof value !== "object" ||
|
|
7
|
+
value === null ||
|
|
8
|
+
Array.isArray(value)) {
|
|
9
|
+
throw new InvalidConfigurationError(path + " must be an object.");
|
|
10
|
+
}
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
function requireNonEmptyString(value, path) {
|
|
14
|
+
if (typeof value !== "string" ||
|
|
15
|
+
value.trim().length === 0) {
|
|
16
|
+
throw new InvalidConfigurationError(path + " must be a non-empty string.");
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
function requirePositiveSafeInteger(value, path) {
|
|
21
|
+
if (typeof value !== "number" ||
|
|
22
|
+
!Number.isSafeInteger(value) ||
|
|
23
|
+
value <= 0) {
|
|
24
|
+
throw new InvalidConfigurationError(path + " must be a positive safe integer.");
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
function parseChannelIds(value, path, options) {
|
|
29
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
30
|
+
throw new InvalidConfigurationError(path + " must be a non-empty array.");
|
|
31
|
+
}
|
|
32
|
+
if (options.exactLength !== undefined &&
|
|
33
|
+
value.length !== options.exactLength) {
|
|
34
|
+
throw new InvalidConfigurationError(path +
|
|
35
|
+
" length must equal the declared repeating-tile site count.");
|
|
36
|
+
}
|
|
37
|
+
const ids = value.map((entry, index) => requireNonEmptyString(entry, path + "[" + index + "]"));
|
|
38
|
+
if (!options.allowDuplicates &&
|
|
39
|
+
new Set(ids).size !== ids.length) {
|
|
40
|
+
throw new InvalidConfigurationError(path + " must not contain duplicate channel IDs.");
|
|
41
|
+
}
|
|
42
|
+
return ids;
|
|
43
|
+
}
|
|
44
|
+
function parseLayout(value, path) {
|
|
45
|
+
const record = requireRecord(value, path);
|
|
46
|
+
if (record.kind === "monochrome") {
|
|
47
|
+
if (record.repeatWidthSites !== undefined ||
|
|
48
|
+
record.repeatHeightSites !== undefined ||
|
|
49
|
+
record.siteChannelIds !== undefined ||
|
|
50
|
+
record.anchor !== undefined ||
|
|
51
|
+
record.layerChannelIds !== undefined ||
|
|
52
|
+
record.spatialSamplingRelationship !== undefined) {
|
|
53
|
+
throw new InvalidConfigurationError(path +
|
|
54
|
+
" monochrome layout must omit mosaic/layered fields.");
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
kind: "monochrome",
|
|
58
|
+
channelId: requireNonEmptyString(record.channelId, path + ".channelId")
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
if (record.kind === "periodic-mosaic") {
|
|
62
|
+
if (record.channelId !== undefined ||
|
|
63
|
+
record.layerChannelIds !== undefined ||
|
|
64
|
+
record.spatialSamplingRelationship !== undefined) {
|
|
65
|
+
throw new InvalidConfigurationError(path +
|
|
66
|
+
" periodic-mosaic layout must omit monochrome/layered fields.");
|
|
67
|
+
}
|
|
68
|
+
const repeatWidthSites = requirePositiveSafeInteger(record.repeatWidthSites, path + ".repeatWidthSites");
|
|
69
|
+
const repeatHeightSites = requirePositiveSafeInteger(record.repeatHeightSites, path + ".repeatHeightSites");
|
|
70
|
+
const repeatSiteCount = repeatWidthSites * repeatHeightSites;
|
|
71
|
+
if (!Number.isSafeInteger(repeatSiteCount)) {
|
|
72
|
+
throw new InvalidConfigurationError(path +
|
|
73
|
+
" repeating-tile site count must be a safe integer.");
|
|
74
|
+
}
|
|
75
|
+
if (record.anchor !== "native-sensor-top-left-site") {
|
|
76
|
+
throw new InvalidConfigurationError(path +
|
|
77
|
+
'.anchor must be "native-sensor-top-left-site".');
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
kind: "periodic-mosaic",
|
|
81
|
+
repeatWidthSites,
|
|
82
|
+
repeatHeightSites,
|
|
83
|
+
siteChannelIds: parseChannelIds(record.siteChannelIds, path + ".siteChannelIds", {
|
|
84
|
+
allowDuplicates: true,
|
|
85
|
+
exactLength: repeatSiteCount
|
|
86
|
+
}),
|
|
87
|
+
anchor: "native-sensor-top-left-site"
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (record.kind === "layered") {
|
|
91
|
+
if (record.channelId !== undefined ||
|
|
92
|
+
record.repeatWidthSites !== undefined ||
|
|
93
|
+
record.repeatHeightSites !== undefined ||
|
|
94
|
+
record.siteChannelIds !== undefined ||
|
|
95
|
+
record.anchor !== undefined) {
|
|
96
|
+
throw new InvalidConfigurationError(path +
|
|
97
|
+
" layered layout must omit monochrome/mosaic fields.");
|
|
98
|
+
}
|
|
99
|
+
if (record.spatialSamplingRelationship !==
|
|
100
|
+
"not-resolved") {
|
|
101
|
+
throw new InvalidConfigurationError(path +
|
|
102
|
+
'.spatialSamplingRelationship must be "not-resolved" for the first layered contract.');
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
kind: "layered",
|
|
106
|
+
layerChannelIds: parseChannelIds(record.layerChannelIds, path + ".layerChannelIds", {
|
|
107
|
+
allowDuplicates: false
|
|
108
|
+
}),
|
|
109
|
+
spatialSamplingRelationship: "not-resolved"
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
throw new InvalidConfigurationError(path + ".kind is invalid.");
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Parses an exact color-sampling topology declaration without binding it to
|
|
116
|
+
* NativeImageRaster, physical photodiodes, spectral response, or a
|
|
117
|
+
* manufacturer-specific family enum.
|
|
118
|
+
*
|
|
119
|
+
* Periodic mosaics use an abstract native sensor color-sampling-site lattice
|
|
120
|
+
* with zero-based integer indices, top-left origin, +X right and +Y down.
|
|
121
|
+
* The repeat phase is anchored to the sensor lattice, so later active crops or
|
|
122
|
+
* orientation transforms must preserve the original native site indices.
|
|
123
|
+
*
|
|
124
|
+
* Layered layouts are structural-only in this first contract because real
|
|
125
|
+
* layered sensors may use unequal spatial sampling density/registration across
|
|
126
|
+
* layers. No per-site layered resolver is exposed until that relationship is
|
|
127
|
+
* modeled explicitly.
|
|
128
|
+
*/
|
|
129
|
+
export function parseSensorColorSamplingProfile(value) {
|
|
130
|
+
const profile = requireRecord(value, "sensorColorSampling");
|
|
131
|
+
if (profile.schemaVersion !== "0.1.0") {
|
|
132
|
+
throw new InvalidConfigurationError('sensorColorSampling.schemaVersion must be "0.1.0".');
|
|
133
|
+
}
|
|
134
|
+
const layout = parseLayout(profile.layout, "sensorColorSampling.layout");
|
|
135
|
+
const expectedCoordinateSystem = layout.kind === "layered"
|
|
136
|
+
? "native-sensor-layered-spatial-relationship-not-resolved"
|
|
137
|
+
: "native-sensor-color-sampling-site-index";
|
|
138
|
+
if (profile.coordinateSystem !==
|
|
139
|
+
expectedCoordinateSystem) {
|
|
140
|
+
throw new InvalidConfigurationError("sensorColorSampling.coordinateSystem does not match the declared layout kind.");
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
schemaVersion: "0.1.0",
|
|
144
|
+
profileId: requireNonEmptyString(profile.profileId, "sensorColorSampling.profileId"),
|
|
145
|
+
evidence: parseEvidenceList(profile.evidence, "sensorColorSampling.evidence"),
|
|
146
|
+
coordinateSystem: expectedCoordinateSystem,
|
|
147
|
+
layout
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function requireNativeSiteIndex(value, path) {
|
|
151
|
+
if (typeof value !== "number" ||
|
|
152
|
+
!Number.isSafeInteger(value) ||
|
|
153
|
+
value < 0) {
|
|
154
|
+
throw new InvalidScientificInputError(path +
|
|
155
|
+
" must be a non-negative safe integer native color-sampling-site index.");
|
|
156
|
+
}
|
|
157
|
+
return value;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Resolves the semantic measurement-channel assignment at one abstract native
|
|
161
|
+
* sensor color-sampling-site index for monochrome or periodic-mosaic layouts.
|
|
162
|
+
*
|
|
163
|
+
* This API intentionally has no NativeImageRaster input. A later explicit
|
|
164
|
+
* binding must establish how a selected capture mode's effective raster maps
|
|
165
|
+
* to this color-sampling-site lattice before RAW/CFA sampling can be simulated.
|
|
166
|
+
*
|
|
167
|
+
* Layered layouts fail closed because their per-layer spatial relationship is
|
|
168
|
+
* not resolved by the first structural contract.
|
|
169
|
+
*/
|
|
170
|
+
export function resolveColorSamplingSite(input) {
|
|
171
|
+
const profile = parseSensorColorSamplingProfile(input.profile);
|
|
172
|
+
if (typeof input.site !== "object" ||
|
|
173
|
+
input.site === null) {
|
|
174
|
+
throw new InvalidScientificInputError("site must be an object.");
|
|
175
|
+
}
|
|
176
|
+
const x = requireNativeSiteIndex(input.site.x, "site.x");
|
|
177
|
+
const y = requireNativeSiteIndex(input.site.y, "site.y");
|
|
178
|
+
if (profile.layout.kind === "layered") {
|
|
179
|
+
throw new InvalidScientificInputError("Layered color sampling is structural-only in schema 0.1.0; per-site resolution requires an explicit per-layer spatial sampling relationship.");
|
|
180
|
+
}
|
|
181
|
+
if (profile.coordinateSystem !==
|
|
182
|
+
"native-sensor-color-sampling-site-index") {
|
|
183
|
+
throw new InvalidScientificInputError("Resolvable color sampling requires the native sensor color-sampling-site coordinate system.");
|
|
184
|
+
}
|
|
185
|
+
if (profile.layout.kind === "monochrome") {
|
|
186
|
+
return {
|
|
187
|
+
profileId: profile.profileId,
|
|
188
|
+
coordinateSystem: profile.coordinateSystem,
|
|
189
|
+
site: { x, y },
|
|
190
|
+
mapping: {
|
|
191
|
+
kind: "monochrome",
|
|
192
|
+
channelId: profile.layout.channelId
|
|
193
|
+
},
|
|
194
|
+
spectralResponseEstablished: false,
|
|
195
|
+
nativeImageRasterBindingEstablished: false,
|
|
196
|
+
physicalPhotodiodeBindingEstablished: false
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
const repeatX = x % profile.layout.repeatWidthSites;
|
|
200
|
+
const repeatY = y % profile.layout.repeatHeightSites;
|
|
201
|
+
const index = repeatY * profile.layout.repeatWidthSites +
|
|
202
|
+
repeatX;
|
|
203
|
+
const channelId = profile.layout.siteChannelIds[index];
|
|
204
|
+
if (channelId === undefined) {
|
|
205
|
+
throw new InvalidScientificInputError("Periodic color-sampling tile resolution failed.");
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
profileId: profile.profileId,
|
|
209
|
+
coordinateSystem: profile.coordinateSystem,
|
|
210
|
+
site: { x, y },
|
|
211
|
+
mapping: {
|
|
212
|
+
kind: "periodic-mosaic",
|
|
213
|
+
channelId,
|
|
214
|
+
repeatCoordinate: {
|
|
215
|
+
x: repeatX,
|
|
216
|
+
y: repeatY
|
|
217
|
+
},
|
|
218
|
+
repeatWidthSites: profile.layout.repeatWidthSites,
|
|
219
|
+
repeatHeightSites: profile.layout.repeatHeightSites
|
|
220
|
+
},
|
|
221
|
+
spectralResponseEstablished: false,
|
|
222
|
+
nativeImageRasterBindingEstablished: false,
|
|
223
|
+
physicalPhotodiodeBindingEstablished: false
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=color-sampling.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-sampling.js","sourceRoot":"","sources":["../../src/sensor/color-sampling.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { type CalculationResult } from "../core/calculation-result.js";
|
|
2
|
+
import { type EvidenceBackedFact } from "../core/evidence-provenance.js";
|
|
3
|
+
import type { RasterPoint, RasterRect, RasterVector } from "../output/capture-geometry.js";
|
|
4
|
+
import type { NativeImageRaster } from "./sensor-geometry.js";
|
|
5
|
+
import type { CaptureShutterMechanism, NativeSensorReadoutScanDirection, SourcedSensorTimingSeconds } from "./readout-timing.js";
|
|
6
|
+
export type CaptureExposureBoundaryActuator = "mechanical" | "electronic";
|
|
7
|
+
export type SourcedCaptureTimingSeconds = SourcedSensorTimingSeconds;
|
|
8
|
+
export type SourcedCaptureBoundaryDirection = EvidenceBackedFact<NativeSensorReadoutScanDirection>;
|
|
9
|
+
export interface SimultaneousExposureBoundarySchedule {
|
|
10
|
+
kind: "simultaneous";
|
|
11
|
+
directionNative?: never;
|
|
12
|
+
traversalDurationSeconds?: never;
|
|
13
|
+
}
|
|
14
|
+
export interface UniformLinearExposureBoundarySchedule {
|
|
15
|
+
kind: "uniform-linear-native-scan";
|
|
16
|
+
directionNative: SourcedCaptureBoundaryDirection;
|
|
17
|
+
traversalDurationSeconds: SourcedCaptureTimingSeconds;
|
|
18
|
+
}
|
|
19
|
+
export type ExposureBoundarySchedule = SimultaneousExposureBoundarySchedule | UniformLinearExposureBoundarySchedule;
|
|
20
|
+
export interface CalculateCaptureExposureWindowsInput {
|
|
21
|
+
nativeRaster: NativeImageRaster;
|
|
22
|
+
/**
|
|
23
|
+
* Active capture rectangle in invariant native-raster coordinates.
|
|
24
|
+
*
|
|
25
|
+
* Defaults to the complete native raster. Boundary traversal timing is never
|
|
26
|
+
* inferred by scaling a full-frame timing value to this rectangle.
|
|
27
|
+
*/
|
|
28
|
+
activeCaptureRect?: RasterRect;
|
|
29
|
+
shutterMechanism: CaptureShutterMechanism;
|
|
30
|
+
/**
|
|
31
|
+
* Nominal interval between the zero-phase opening and closing references.
|
|
32
|
+
*
|
|
33
|
+
* Local exposure duration may differ from this value when opening and closing
|
|
34
|
+
* boundary schedules have different spatial phase behavior.
|
|
35
|
+
*/
|
|
36
|
+
nominalExposureDurationSeconds: SourcedCaptureTimingSeconds;
|
|
37
|
+
opening: ExposureBoundarySchedule;
|
|
38
|
+
closing: ExposureBoundarySchedule;
|
|
39
|
+
/**
|
|
40
|
+
* Optional continuous native raster edge-coordinate points for diagnostics.
|
|
41
|
+
* Pixel centers may be represented with +0.5 offsets.
|
|
42
|
+
*/
|
|
43
|
+
samplePointsNative?: readonly RasterPoint[];
|
|
44
|
+
}
|
|
45
|
+
export interface ResolvedCaptureExposureBoundary {
|
|
46
|
+
actuator: CaptureExposureBoundaryActuator;
|
|
47
|
+
schedule: {
|
|
48
|
+
kind: "simultaneous";
|
|
49
|
+
} | {
|
|
50
|
+
kind: "uniform-linear-native-scan";
|
|
51
|
+
directionNative: SourcedCaptureBoundaryDirection;
|
|
52
|
+
unitVectorNative: RasterVector;
|
|
53
|
+
traversalDurationSeconds: SourcedCaptureTimingSeconds;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export interface CaptureExposureWindowSample {
|
|
57
|
+
pointNative: RasterPoint;
|
|
58
|
+
openingNormalizedScanPosition: number | null;
|
|
59
|
+
closingNormalizedScanPosition: number | null;
|
|
60
|
+
/**
|
|
61
|
+
* Seconds from the first opening-boundary phase.
|
|
62
|
+
*/
|
|
63
|
+
startOffsetSecondsFromOpeningReference: number;
|
|
64
|
+
/**
|
|
65
|
+
* Seconds from the first opening-boundary phase.
|
|
66
|
+
*/
|
|
67
|
+
endOffsetSecondsFromOpeningReference: number;
|
|
68
|
+
localExposureDurationSeconds: number;
|
|
69
|
+
}
|
|
70
|
+
export interface CaptureExposureWindows {
|
|
71
|
+
shutterMechanism: CaptureShutterMechanism;
|
|
72
|
+
timeReference: "first-opening-boundary-phase";
|
|
73
|
+
nativeRaster: NativeImageRaster;
|
|
74
|
+
activeCaptureRect: RasterRect;
|
|
75
|
+
nominalExposureDurationSeconds: SourcedCaptureTimingSeconds;
|
|
76
|
+
opening: ResolvedCaptureExposureBoundary;
|
|
77
|
+
closing: ResolvedCaptureExposureBoundary;
|
|
78
|
+
localExposureDurationRangeSeconds: {
|
|
79
|
+
minimum: number;
|
|
80
|
+
maximum: number;
|
|
81
|
+
};
|
|
82
|
+
samples: readonly CaptureExposureWindowSample[];
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Resolves local capture exposure windows from independent opening and closing
|
|
86
|
+
* boundary schedules.
|
|
87
|
+
*
|
|
88
|
+
* The returned time basis is seconds from the first opening-boundary phase.
|
|
89
|
+
* This is intentionally not the existing camera-rotation API's global
|
|
90
|
+
* "exposure start" semantic; a later integration layer must bind those time
|
|
91
|
+
* bases explicitly.
|
|
92
|
+
*
|
|
93
|
+
* The mechanism identifies whether each boundary is mechanical or electronic,
|
|
94
|
+
* but does not supply any traversal duration or direction. Every non-simultaneous
|
|
95
|
+
* timing value and direction is caller-declared with evidence.
|
|
96
|
+
*
|
|
97
|
+
* The first model supports simultaneous boundaries and uniform-linear
|
|
98
|
+
* single-axis native-sensor scans only. It does not model curtain acceleration,
|
|
99
|
+
* segmented/nonlinear electronic schedules, flash/flicker, rolling-shutter
|
|
100
|
+
* image distortion, shutter shock, or EFCS-specific pupil/bokeh behavior.
|
|
101
|
+
*/
|
|
102
|
+
export declare function calculateCaptureExposureWindows(input: CalculateCaptureExposureWindowsInput): CalculationResult<CaptureExposureWindows>;
|
|
103
|
+
//# sourceMappingURL=exposure-window.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exposure-window.d.ts","sourceRoot":"","sources":["../../src/sensor/exposure-window.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,gCAAgC,CAAC;AAKxC,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,YAAY,EACb,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EACV,uBAAuB,EACvB,gCAAgC,EAChC,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;AAE7B,MAAM,MAAM,+BAA+B,GAAG,YAAY,GAAG,YAAY,CAAC;AAE1E,MAAM,MAAM,2BAA2B,GAAG,0BAA0B,CAAC;AAErE,MAAM,MAAM,+BAA+B,GACzC,kBAAkB,CAAC,gCAAgC,CAAC,CAAC;AAEvD,MAAM,WAAW,oCAAoC;IACnD,IAAI,EAAE,cAAc,CAAC;IACrB,eAAe,CAAC,EAAE,KAAK,CAAC;IACxB,wBAAwB,CAAC,EAAE,KAAK,CAAC;CAClC;AAED,MAAM,WAAW,qCAAqC;IACpD,IAAI,EAAE,4BAA4B,CAAC;IACnC,eAAe,EAAE,+BAA+B,CAAC;IACjD,wBAAwB,EAAE,2BAA2B,CAAC;CACvD;AAED,MAAM,MAAM,wBAAwB,GAChC,oCAAoC,GACpC,qCAAqC,CAAC;AAE1C,MAAM,WAAW,oCAAoC;IACnD,YAAY,EAAE,iBAAiB,CAAC;IAChC;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,UAAU,CAAC;IAC/B,gBAAgB,EAAE,uBAAuB,CAAC;IAC1C;;;;;OAKG;IACH,8BAA8B,EAAE,2BAA2B,CAAC;IAC5D,OAAO,EAAE,wBAAwB,CAAC;IAClC,OAAO,EAAE,wBAAwB,CAAC;IAClC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;CAC7C;AAED,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,EAAE,+BAA+B,CAAC;IAC1C,QAAQ,EACJ;QACE,IAAI,EAAE,cAAc,CAAC;KACtB,GACD;QACE,IAAI,EAAE,4BAA4B,CAAC;QACnC,eAAe,EAAE,+BAA+B,CAAC;QACjD,gBAAgB,EAAE,YAAY,CAAC;QAC/B,wBAAwB,EAAE,2BAA2B,CAAC;KACvD,CAAC;CACP;AAED,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,WAAW,CAAC;IACzB,6BAA6B,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,6BAA6B,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C;;OAEG;IACH,sCAAsC,EAAE,MAAM,CAAC;IAC/C;;OAEG;IACH,oCAAoC,EAAE,MAAM,CAAC;IAC7C,4BAA4B,EAAE,MAAM,CAAC;CACtC;AAED,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,EAAE,uBAAuB,CAAC;IAC1C,aAAa,EAAE,8BAA8B,CAAC;IAC9C,YAAY,EAAE,iBAAiB,CAAC;IAChC,iBAAiB,EAAE,UAAU,CAAC;IAC9B,8BAA8B,EAAE,2BAA2B,CAAC;IAC5D,OAAO,EAAE,+BAA+B,CAAC;IACzC,OAAO,EAAE,+BAA+B,CAAC;IACzC,iCAAiC,EAAE;QACjC,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,OAAO,EAAE,SAAS,2BAA2B,EAAE,CAAC;CACjD;AAoVD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,oCAAoC,GAC1C,iBAAiB,CAAC,sBAAsB,CAAC,CAkG3C"}
|