gnss-js 2.13.0 → 2.14.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/dist/analysis.cjs +525 -0
- package/dist/analysis.d.cts +135 -1
- package/dist/analysis.d.ts +135 -1
- package/dist/analysis.js +9 -1
- package/dist/{chunk-MFCPYUEI.js → chunk-GGWK7XLZ.js} +496 -1
- package/dist/{chunk-RWFJEVLJ.js → chunk-TETPRPZ2.js} +149 -6
- package/dist/index.cjs +647 -6
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +14 -2
- package/dist/positioning.cjs +152 -6
- package/dist/positioning.d.cts +47 -1
- package/dist/positioning.d.ts +47 -1
- package/dist/positioning.js +7 -1
- package/dist/troposphere.cjs +5056 -0
- package/dist/troposphere.d.cts +78 -0
- package/dist/troposphere.d.ts +78 -0
- package/dist/troposphere.js +5025 -0
- package/package.json +6 -1
package/dist/index.cjs
CHANGED
|
@@ -24,6 +24,7 @@ __export(src_exports, {
|
|
|
24
24
|
BAND_LABELS: () => BAND_LABELS,
|
|
25
25
|
BAND_PRESETS: () => BAND_PRESETS,
|
|
26
26
|
BDS_SATELLITES: () => BDS_SATELLITES,
|
|
27
|
+
BLQ_CONSTITUENTS: () => BLQ_CONSTITUENTS,
|
|
27
28
|
BitReader: () => BitReader,
|
|
28
29
|
CONSTELLATIONS: () => CONSTELLATIONS,
|
|
29
30
|
C_LIGHT: () => C_LIGHT,
|
|
@@ -121,6 +122,7 @@ __export(src_exports, {
|
|
|
121
122
|
analyzeQuality: () => analyzeQuality,
|
|
122
123
|
antexFreqOfGroup: () => antexFreqOfGroup,
|
|
123
124
|
applyHelmert: () => applyHelmert,
|
|
125
|
+
applyHelmertFit: () => applyHelmertFit,
|
|
124
126
|
applyIonoDcb: () => applyIonoDcb,
|
|
125
127
|
applyOrbitClock: () => applyOrbitClock,
|
|
126
128
|
biasMetres: () => biasMetres,
|
|
@@ -168,6 +170,7 @@ __export(src_exports, {
|
|
|
168
170
|
ecefToAzEl: () => ecefToAzEl,
|
|
169
171
|
ecefToGeodetic: () => ecefToGeodetic,
|
|
170
172
|
ephInfoToEphemeris: () => ephInfoToEphemeris,
|
|
173
|
+
estimateHelmert: () => estimateHelmert,
|
|
171
174
|
estimateNarrowlaneFcb: () => estimateNarrowlaneFcb,
|
|
172
175
|
estimateNetworkFcbs: () => estimateNetworkFcbs,
|
|
173
176
|
estimateWidelaneFcb: () => estimateWidelaneFcb,
|
|
@@ -179,6 +182,7 @@ __export(src_exports, {
|
|
|
179
182
|
feedNavicBlock: () => feedNavicBlock,
|
|
180
183
|
fetchSourcetable: () => fetchSourcetable,
|
|
181
184
|
findSatBias: () => findSatBias,
|
|
185
|
+
fitCoordinateSeries: () => fitCoordinateSeries,
|
|
182
186
|
fixPppPosition: () => fixPppPosition,
|
|
183
187
|
fmtD: () => fmtD,
|
|
184
188
|
fmtF: () => fmtF,
|
|
@@ -273,12 +277,14 @@ __export(src_exports, {
|
|
|
273
277
|
nlWavelength: () => nlWavelength,
|
|
274
278
|
nmeaCoordToDecimal: () => nmeaCoordToDecimal,
|
|
275
279
|
obsEpochToDate: () => obsEpochToDate,
|
|
280
|
+
oceanLoadingEnu: () => oceanLoadingEnu,
|
|
276
281
|
oem4Frames: () => oem4Frames,
|
|
277
282
|
padL: () => padL,
|
|
278
283
|
padR: () => padR,
|
|
279
284
|
parseAntex: () => parseAntex,
|
|
280
285
|
parseBiasSinex: () => parseBiasSinex,
|
|
281
286
|
parseBinex: () => parseBinex,
|
|
287
|
+
parseBlq: () => parseBlq,
|
|
282
288
|
parseClk: () => parseClk,
|
|
283
289
|
parseCrxDataLine: () => parseCrxDataLine,
|
|
284
290
|
parseIonex: () => parseIonex,
|
|
@@ -16804,6 +16810,103 @@ function solidEarthTide(rcv, sun, moon) {
|
|
|
16804
16810
|
return disp;
|
|
16805
16811
|
}
|
|
16806
16812
|
|
|
16813
|
+
// src/positioning/ocean-loading.ts
|
|
16814
|
+
var BLQ_CONSTITUENTS = [
|
|
16815
|
+
"M2",
|
|
16816
|
+
"S2",
|
|
16817
|
+
"N2",
|
|
16818
|
+
"K2",
|
|
16819
|
+
"K1",
|
|
16820
|
+
"O1",
|
|
16821
|
+
"P1",
|
|
16822
|
+
"Q1",
|
|
16823
|
+
"Mf",
|
|
16824
|
+
"Mm",
|
|
16825
|
+
"Ssa"
|
|
16826
|
+
];
|
|
16827
|
+
var ARGS = [
|
|
16828
|
+
[140519e-9, 2, -2, 0, 0],
|
|
16829
|
+
// M2
|
|
16830
|
+
[145444e-9, 0, 0, 0, 0],
|
|
16831
|
+
// S2
|
|
16832
|
+
[13788e-8, 2, -3, 1, 0],
|
|
16833
|
+
// N2
|
|
16834
|
+
[145842e-9, 2, 0, 0, 0],
|
|
16835
|
+
// K2
|
|
16836
|
+
[72921e-9, 1, 0, 0, 0.25],
|
|
16837
|
+
// K1
|
|
16838
|
+
[67598e-9, 1, -2, 0, -0.25],
|
|
16839
|
+
// O1
|
|
16840
|
+
[72523e-9, -1, 0, 0, -0.25],
|
|
16841
|
+
// P1
|
|
16842
|
+
[64959e-9, 1, -3, 1, -0.25],
|
|
16843
|
+
// Q1
|
|
16844
|
+
[53234e-10, 0, 2, 0, 0],
|
|
16845
|
+
// Mf
|
|
16846
|
+
[26392e-10, 0, 1, -1, 0],
|
|
16847
|
+
// Mm
|
|
16848
|
+
[3982e-10, 2, 0, 0, 0]
|
|
16849
|
+
// Ssa
|
|
16850
|
+
];
|
|
16851
|
+
var D2R2 = Math.PI / 180;
|
|
16852
|
+
function oceanLoadingEnu(c, utcMs) {
|
|
16853
|
+
const day = Math.floor(utcMs / 864e5);
|
|
16854
|
+
const fday = (utcMs - day * 864e5) / 1e3;
|
|
16855
|
+
const days = day - Date.UTC(1975, 0, 1) / 864e5 + 1;
|
|
16856
|
+
const t = (27392.500528 + 1.000000035 * days) / 36525;
|
|
16857
|
+
const t2 = t * t;
|
|
16858
|
+
const t3 = t2 * t;
|
|
16859
|
+
const a = [
|
|
16860
|
+
fday,
|
|
16861
|
+
(279.69668 + 36000.768930485 * t + 303e-6 * t2) * D2R2,
|
|
16862
|
+
// H0
|
|
16863
|
+
(270.434358 + 481267.88314137 * t - 1133e-6 * t2 + 19e-7 * t3) * D2R2,
|
|
16864
|
+
// S0
|
|
16865
|
+
(334.329653 + 4069.0340329577 * t - 0.010325 * t2 - 12e-6 * t3) * D2R2,
|
|
16866
|
+
// P0
|
|
16867
|
+
2 * Math.PI
|
|
16868
|
+
];
|
|
16869
|
+
const dp = [0, 0, 0];
|
|
16870
|
+
for (let i = 0; i < ARGS.length; i++) {
|
|
16871
|
+
let ang = 0;
|
|
16872
|
+
for (let j = 0; j < 5; j++) ang += a[j] * ARGS[i][j];
|
|
16873
|
+
for (let k = 0; k < 3; k++)
|
|
16874
|
+
dp[k] += c.amplitude[i][k] * Math.cos(ang - c.phase[i][k] * D2R2);
|
|
16875
|
+
}
|
|
16876
|
+
return [-dp[1], -dp[2], dp[0]];
|
|
16877
|
+
}
|
|
16878
|
+
function parseBlq(text) {
|
|
16879
|
+
const out = /* @__PURE__ */ new Map();
|
|
16880
|
+
const lines = text.split(/\r?\n/);
|
|
16881
|
+
for (let i = 0; i < lines.length; i++) {
|
|
16882
|
+
const l = lines[i];
|
|
16883
|
+
if (!l.trim() || l.startsWith("$$")) continue;
|
|
16884
|
+
const name = l.trim().split(/\s+/)[0].toUpperCase();
|
|
16885
|
+
const rows = [];
|
|
16886
|
+
let j = i + 1;
|
|
16887
|
+
while (j < lines.length && rows.length < 6) {
|
|
16888
|
+
const r = lines[j];
|
|
16889
|
+
j++;
|
|
16890
|
+
if (r.startsWith("$$") || !r.trim()) continue;
|
|
16891
|
+
const v = r.trim().split(/\s+/).map(Number);
|
|
16892
|
+
if (v.length !== 11 || v.some((x) => !Number.isFinite(x))) break;
|
|
16893
|
+
rows.push(v);
|
|
16894
|
+
}
|
|
16895
|
+
if (rows.length === 6) {
|
|
16896
|
+
out.set(name, {
|
|
16897
|
+
amplitude: BLQ_CONSTITUENTS.map(
|
|
16898
|
+
(_, k) => [rows[0][k], rows[1][k], rows[2][k]]
|
|
16899
|
+
),
|
|
16900
|
+
phase: BLQ_CONSTITUENTS.map(
|
|
16901
|
+
(_, k) => [rows[3][k], rows[4][k], rows[5][k]]
|
|
16902
|
+
)
|
|
16903
|
+
});
|
|
16904
|
+
i = j - 1;
|
|
16905
|
+
}
|
|
16906
|
+
}
|
|
16907
|
+
return out;
|
|
16908
|
+
}
|
|
16909
|
+
|
|
16807
16910
|
// src/positioning/ppp-corrections.ts
|
|
16808
16911
|
function applyCorrections(corrections, geom, ctx) {
|
|
16809
16912
|
if (corrections.evaluate) return corrections.evaluate(geom, ctx);
|
|
@@ -16821,6 +16924,14 @@ function createPppCorrections(cfg) {
|
|
|
16821
16924
|
const sun = sunEcef(timeMs);
|
|
16822
16925
|
const moon = moonEcef(timeMs);
|
|
16823
16926
|
const tideDisp = useTides ? solidEarthTide(rcvEcef, sun, moon) : [0, 0, 0];
|
|
16927
|
+
if (cfg.oceanLoading) {
|
|
16928
|
+
const [e, n, u] = oceanLoadingEnu(cfg.oceanLoading, timeMs);
|
|
16929
|
+
const [lat, lon] = ecefToGeodetic(rcvEcef[0], rcvEcef[1], rcvEcef[2]);
|
|
16930
|
+
const d = enuToEcef([e, n, u], lat, lon);
|
|
16931
|
+
tideDisp[0] += d[0];
|
|
16932
|
+
tideDisp[1] += d[1];
|
|
16933
|
+
tideDisp[2] += d[2];
|
|
16934
|
+
}
|
|
16824
16935
|
return { timeMs, sun, moon, tideDisp };
|
|
16825
16936
|
},
|
|
16826
16937
|
evaluate(geom, ctx) {
|
|
@@ -16875,7 +16986,7 @@ function createPppCorrections(cfg) {
|
|
|
16875
16986
|
rangeM += interpPcv(off, zenithDeg);
|
|
16876
16987
|
}
|
|
16877
16988
|
}
|
|
16878
|
-
if (
|
|
16989
|
+
if (ctx) {
|
|
16879
16990
|
rangeM -= dot(e, ctx.tideDisp);
|
|
16880
16991
|
}
|
|
16881
16992
|
if (useWindup && frame) {
|
|
@@ -17013,7 +17124,32 @@ function sagnacRotate(x, y, z, travelS) {
|
|
|
17013
17124
|
const s = Math.sin(theta);
|
|
17014
17125
|
return [x * c + y * s, -x * s + y * c, z];
|
|
17015
17126
|
}
|
|
17016
|
-
function satStateAtEmission(source, prn, recvTimeMs, rcv) {
|
|
17127
|
+
function satStateAtEmission(source, prn, recvTimeMs, rcv, pseudorangeM) {
|
|
17128
|
+
if (pseudorangeM !== void 0 && pseudorangeM > 1e6) {
|
|
17129
|
+
let tEmit = recvTimeMs - pseudorangeM / C_LIGHT * 1e3;
|
|
17130
|
+
const s0 = source.satState(prn, tEmit);
|
|
17131
|
+
if (!s0) return null;
|
|
17132
|
+
tEmit -= s0.clkS * 1e3;
|
|
17133
|
+
const s = source.satState(prn, tEmit);
|
|
17134
|
+
if (!s) return null;
|
|
17135
|
+
let travelS2 = 0.075;
|
|
17136
|
+
let pos = [s.x, s.y, s.z];
|
|
17137
|
+
for (let iter = 0; iter < 3; iter++) {
|
|
17138
|
+
pos = sagnacRotate(s.x, s.y, s.z, travelS2);
|
|
17139
|
+
travelS2 = Math.hypot(pos[0] - rcv[0], pos[1] - rcv[1], pos[2] - rcv[2]) / C_LIGHT;
|
|
17140
|
+
}
|
|
17141
|
+
const velDotPos2 = s.x * s.vx + s.y * s.vy + s.z * s.vz;
|
|
17142
|
+
const relS2 = -2 * velDotPos2 / (C_LIGHT * C_LIGHT);
|
|
17143
|
+
return {
|
|
17144
|
+
state: {
|
|
17145
|
+
x: pos[0],
|
|
17146
|
+
y: pos[1],
|
|
17147
|
+
z: pos[2],
|
|
17148
|
+
clkM: C_LIGHT * (s.clkS + relS2)
|
|
17149
|
+
},
|
|
17150
|
+
travelS: travelS2
|
|
17151
|
+
};
|
|
17152
|
+
}
|
|
17017
17153
|
let travelS = 0.075;
|
|
17018
17154
|
let sx = 0;
|
|
17019
17155
|
let sy = 0;
|
|
@@ -17236,7 +17372,7 @@ var PppEngine = class {
|
|
|
17236
17372
|
for (const ci of clkIdx.values()) P[ci][ci] = CLK_VAR;
|
|
17237
17373
|
P[IDX_ZWD][IDX_ZWD] += ztdQ * (ei > 0 ? 1 : 0);
|
|
17238
17374
|
const rcv = [x[IDX_X], x[IDX_Y], x[IDX_Z]];
|
|
17239
|
-
const [latRad, , heightM] = ecefToGeodetic(rcv[0], rcv[1], rcv[2]);
|
|
17375
|
+
const [latRad, lonRad, heightM] = ecefToGeodetic(rcv[0], rcv[1], rcv[2]);
|
|
17240
17376
|
const epochCtx = corrections?.epochContext?.(epoch.timeMs, rcv) ?? null;
|
|
17241
17377
|
const vis = [];
|
|
17242
17378
|
let epochZhd = 0;
|
|
@@ -17246,7 +17382,7 @@ var PppEngine = class {
|
|
|
17246
17382
|
const o = applySatBiases(source, raw, epoch.timeMs);
|
|
17247
17383
|
if (!o) continue;
|
|
17248
17384
|
const slip = detectSlip(o, ei);
|
|
17249
|
-
const sat = satStateAtEmission(source, o.prn, epoch.timeMs, rcv);
|
|
17385
|
+
const sat = satStateAtEmission(source, o.prn, epoch.timeMs, rcv, o.c1);
|
|
17250
17386
|
if (!sat) continue;
|
|
17251
17387
|
const [elRad, azRad] = getAer(
|
|
17252
17388
|
sat.state.x,
|
|
@@ -17269,7 +17405,17 @@ var PppEngine = class {
|
|
|
17269
17405
|
const pIf = g * o.c1 - (g - 1) * o.c2;
|
|
17270
17406
|
const lIf = g * (o.l1 * lam1) - (g - 1) * (o.l2 * lam2);
|
|
17271
17407
|
if (!Number.isFinite(pIf) || !Number.isFinite(lIf)) continue;
|
|
17272
|
-
const trop = opts.troposphere ?? true ?
|
|
17408
|
+
const trop = opts.troposphere ?? true ? opts.troposphereModel ? opts.troposphereModel.delays(
|
|
17409
|
+
epoch.timeMs,
|
|
17410
|
+
latRad,
|
|
17411
|
+
lonRad,
|
|
17412
|
+
heightM,
|
|
17413
|
+
elRad,
|
|
17414
|
+
azRad
|
|
17415
|
+
) : {
|
|
17416
|
+
...niellMapping(elRad, latRad, heightM, epoch.timeMs),
|
|
17417
|
+
gradient: 0
|
|
17418
|
+
} : { zhd: 0, mh: 0, mw: 0, gradient: 0 };
|
|
17273
17419
|
const { zhd, mh, mw } = trop;
|
|
17274
17420
|
epochZhd = zhd;
|
|
17275
17421
|
const geom = {
|
|
@@ -17294,7 +17440,7 @@ var PppEngine = class {
|
|
|
17294
17440
|
lIf,
|
|
17295
17441
|
satClkM: sat.state.clkM,
|
|
17296
17442
|
range,
|
|
17297
|
-
tropoFixed: zhd * mh + corr.rangeM,
|
|
17443
|
+
tropoFixed: zhd * mh + trop.gradient + corr.rangeM,
|
|
17298
17444
|
mw,
|
|
17299
17445
|
windupM: corr.phaseWindupM,
|
|
17300
17446
|
slip,
|
|
@@ -19289,6 +19435,495 @@ async function analyzeQuality(file, header, onProgress, signal) {
|
|
|
19289
19435
|
};
|
|
19290
19436
|
}
|
|
19291
19437
|
|
|
19438
|
+
// src/analysis/noise-model.ts
|
|
19439
|
+
function cholesky(M, n) {
|
|
19440
|
+
for (let j = 0; j < n; j++) {
|
|
19441
|
+
let d = M[j * n + j];
|
|
19442
|
+
for (let k = 0; k < j; k++) d -= M[j * n + k] ** 2;
|
|
19443
|
+
if (d <= 0) return false;
|
|
19444
|
+
d = Math.sqrt(d);
|
|
19445
|
+
M[j * n + j] = d;
|
|
19446
|
+
for (let i = j + 1; i < n; i++) {
|
|
19447
|
+
let s = M[i * n + j];
|
|
19448
|
+
for (let k = 0; k < j; k++) s -= M[i * n + k] * M[j * n + k];
|
|
19449
|
+
M[i * n + j] = s / d;
|
|
19450
|
+
}
|
|
19451
|
+
}
|
|
19452
|
+
return true;
|
|
19453
|
+
}
|
|
19454
|
+
function forward(L, n, b) {
|
|
19455
|
+
for (let i = 0; i < n; i++) {
|
|
19456
|
+
let s = b[i];
|
|
19457
|
+
for (let k = 0; k < i; k++) s -= L[i * n + k] * b[k];
|
|
19458
|
+
b[i] = s / L[i * n + i];
|
|
19459
|
+
}
|
|
19460
|
+
}
|
|
19461
|
+
function flickerCovariance(idx) {
|
|
19462
|
+
const N = idx[idx.length - 1] + 1;
|
|
19463
|
+
const h = new Float64Array(N);
|
|
19464
|
+
h[0] = 1;
|
|
19465
|
+
for (let i = 1; i < N; i++) h[i] = h[i - 1] * (i - 1 + 0.5) / i;
|
|
19466
|
+
const n = idx.length;
|
|
19467
|
+
const F = new Float64Array(n * n);
|
|
19468
|
+
for (let a = 0; a < n; a++)
|
|
19469
|
+
for (let b = 0; b <= a; b++) {
|
|
19470
|
+
const ia = idx[a];
|
|
19471
|
+
const ib = idx[b];
|
|
19472
|
+
let s = 0;
|
|
19473
|
+
for (let k = 0; k <= ib; k++) s += h[ia - k] * h[ib - k];
|
|
19474
|
+
F[a * n + b] = s;
|
|
19475
|
+
F[b * n + a] = s;
|
|
19476
|
+
}
|
|
19477
|
+
let tr = 0;
|
|
19478
|
+
for (let a = 0; a < n; a++) tr += F[a * n + a];
|
|
19479
|
+
const scale = n / tr;
|
|
19480
|
+
for (let i = 0; i < F.length; i++) F[i] *= scale;
|
|
19481
|
+
return F;
|
|
19482
|
+
}
|
|
19483
|
+
var MAX_SAMPLES = 360;
|
|
19484
|
+
function fitWhiteFlicker(A, y, tYears) {
|
|
19485
|
+
let rows = A.map((_, i) => i);
|
|
19486
|
+
if (rows.length > MAX_SAMPLES) {
|
|
19487
|
+
const step = rows.length / MAX_SAMPLES;
|
|
19488
|
+
rows = Array.from({ length: MAX_SAMPLES }, (_, k) => Math.floor(k * step));
|
|
19489
|
+
}
|
|
19490
|
+
const n = rows.length;
|
|
19491
|
+
const p = A[0]?.length ?? 0;
|
|
19492
|
+
if (n < p + 5) return null;
|
|
19493
|
+
const dts = rows.slice(1).map((r, k) => tYears[r] - tYears[rows[k]]).filter((d) => d > 0).sort((a, b) => a - b);
|
|
19494
|
+
const dt = dts[dts.length >> 1] ?? 1 / 365.25;
|
|
19495
|
+
const t0 = tYears[rows[0]];
|
|
19496
|
+
const idx = rows.map((r) => Math.round((tYears[r] - t0) / dt));
|
|
19497
|
+
for (let k = 1; k < n; k++)
|
|
19498
|
+
if (idx[k] <= idx[k - 1]) idx[k] = idx[k - 1] + 1;
|
|
19499
|
+
const F = flickerCovariance(idx);
|
|
19500
|
+
const evaluate = (phi) => {
|
|
19501
|
+
const C2 = new Float64Array(n * n);
|
|
19502
|
+
for (let i = 0; i < n * n; i++) C2[i] = phi * F[i];
|
|
19503
|
+
for (let i = 0; i < n; i++) C2[i * n + i] += 1 - phi;
|
|
19504
|
+
if (!cholesky(C2, n)) return null;
|
|
19505
|
+
const Aw = Array.from({ length: p }, (_, j) => {
|
|
19506
|
+
const col = Float64Array.from(rows, (r) => A[r][j]);
|
|
19507
|
+
forward(C2, n, col);
|
|
19508
|
+
return col;
|
|
19509
|
+
});
|
|
19510
|
+
const yw = Float64Array.from(rows, (r) => y[r]);
|
|
19511
|
+
forward(C2, n, yw);
|
|
19512
|
+
const N = Array.from(
|
|
19513
|
+
{ length: p },
|
|
19514
|
+
(_, a) => Array.from({ length: p }, (_2, b) => {
|
|
19515
|
+
let s = 0;
|
|
19516
|
+
for (let i = 0; i < n; i++) s += Aw[a][i] * Aw[b][i];
|
|
19517
|
+
return s;
|
|
19518
|
+
})
|
|
19519
|
+
);
|
|
19520
|
+
const rhs = Array.from({ length: p }, (_, a) => {
|
|
19521
|
+
let s = 0;
|
|
19522
|
+
for (let i = 0; i < n; i++) s += Aw[a][i] * yw[i];
|
|
19523
|
+
return s;
|
|
19524
|
+
});
|
|
19525
|
+
const Ninv = invert(N);
|
|
19526
|
+
if (!Ninv) return null;
|
|
19527
|
+
const beta = Ninv.map((row) => row.reduce((s, v, k) => s + v * rhs[k], 0));
|
|
19528
|
+
let rss = 0;
|
|
19529
|
+
for (let i = 0; i < n; i++) {
|
|
19530
|
+
let m = 0;
|
|
19531
|
+
for (let j = 0; j < p; j++) m += Aw[j][i] * beta[j];
|
|
19532
|
+
rss += (yw[i] - m) ** 2;
|
|
19533
|
+
}
|
|
19534
|
+
const sigma2 = rss / n;
|
|
19535
|
+
let logdet = 0;
|
|
19536
|
+
for (let i = 0; i < n; i++) logdet += 2 * Math.log(C2[i * n + i]);
|
|
19537
|
+
const logL = -0.5 * (n * Math.log(sigma2) + logdet + n);
|
|
19538
|
+
return {
|
|
19539
|
+
logL,
|
|
19540
|
+
velocity: beta[1],
|
|
19541
|
+
velocitySigma: Math.sqrt(sigma2 * Ninv[1][1])
|
|
19542
|
+
};
|
|
19543
|
+
};
|
|
19544
|
+
let best = null;
|
|
19545
|
+
for (let k = 0; k <= 20; k++) {
|
|
19546
|
+
const phi = Math.min(k / 20, 0.995);
|
|
19547
|
+
const r = evaluate(phi);
|
|
19548
|
+
if (r && (!best || r.logL > best.r.logL)) best = { phi, r };
|
|
19549
|
+
}
|
|
19550
|
+
if (!best) return null;
|
|
19551
|
+
let lo = Math.max(0, best.phi - 0.05);
|
|
19552
|
+
let hi = Math.min(0.995, best.phi + 0.05);
|
|
19553
|
+
const g = (Math.sqrt(5) - 1) / 2;
|
|
19554
|
+
for (let it = 0; it < 12; it++) {
|
|
19555
|
+
const a = hi - g * (hi - lo);
|
|
19556
|
+
const b = lo + g * (hi - lo);
|
|
19557
|
+
const ra = evaluate(a);
|
|
19558
|
+
const rb = evaluate(b);
|
|
19559
|
+
if (!ra || !rb) break;
|
|
19560
|
+
if (ra.logL > rb.logL) {
|
|
19561
|
+
hi = b;
|
|
19562
|
+
if (ra.logL > best.r.logL) best = { phi: a, r: ra };
|
|
19563
|
+
} else {
|
|
19564
|
+
lo = a;
|
|
19565
|
+
if (rb.logL > best.r.logL) best = { phi: b, r: rb };
|
|
19566
|
+
}
|
|
19567
|
+
}
|
|
19568
|
+
return {
|
|
19569
|
+
flickerShare: best.phi,
|
|
19570
|
+
velocitySigma: best.r.velocitySigma,
|
|
19571
|
+
velocity: best.r.velocity
|
|
19572
|
+
};
|
|
19573
|
+
}
|
|
19574
|
+
function invert(N) {
|
|
19575
|
+
const p = N.length;
|
|
19576
|
+
const M = N.map((row, i) => [
|
|
19577
|
+
...row,
|
|
19578
|
+
...Array.from({ length: p }, (_, j) => i === j ? 1 : 0)
|
|
19579
|
+
]);
|
|
19580
|
+
for (let c = 0; c < p; c++) {
|
|
19581
|
+
let piv = c;
|
|
19582
|
+
for (let r = c + 1; r < p; r++)
|
|
19583
|
+
if (Math.abs(M[r][c]) > Math.abs(M[piv][c])) piv = r;
|
|
19584
|
+
if (Math.abs(M[piv][c]) < 1e-14) return null;
|
|
19585
|
+
[M[c], M[piv]] = [M[piv], M[c]];
|
|
19586
|
+
const d = M[c][c];
|
|
19587
|
+
for (let k = 0; k < 2 * p; k++) M[c][k] /= d;
|
|
19588
|
+
for (let r = 0; r < p; r++) {
|
|
19589
|
+
if (r === c) continue;
|
|
19590
|
+
const f = M[r][c];
|
|
19591
|
+
if (f === 0) continue;
|
|
19592
|
+
for (let k = 0; k < 2 * p; k++) M[r][k] -= f * M[c][k];
|
|
19593
|
+
}
|
|
19594
|
+
}
|
|
19595
|
+
return M.map((row) => row.slice(p));
|
|
19596
|
+
}
|
|
19597
|
+
|
|
19598
|
+
// src/analysis/coordinate-series.ts
|
|
19599
|
+
var MS_PER_YEAR = 365.25 * 864e5;
|
|
19600
|
+
var TWO_PI2 = 2 * Math.PI;
|
|
19601
|
+
var MIN_SIGMA_M = 5e-4;
|
|
19602
|
+
function lsq(A, y, w) {
|
|
19603
|
+
const p = A[0]?.length ?? 0;
|
|
19604
|
+
const N = Array.from({ length: p }, () => new Array(p).fill(0));
|
|
19605
|
+
const b = new Array(p).fill(0);
|
|
19606
|
+
for (let i = 0; i < A.length; i++) {
|
|
19607
|
+
const a = A[i];
|
|
19608
|
+
for (let j = 0; j < p; j++) {
|
|
19609
|
+
b[j] += w[i] * a[j] * y[i];
|
|
19610
|
+
for (let k = 0; k < p; k++) N[j][k] += w[i] * a[j] * a[k];
|
|
19611
|
+
}
|
|
19612
|
+
}
|
|
19613
|
+
const M = N.map((row, i) => [
|
|
19614
|
+
...row,
|
|
19615
|
+
...Array.from({ length: p }, (_, j) => i === j ? 1 : 0)
|
|
19616
|
+
]);
|
|
19617
|
+
for (let c = 0; c < p; c++) {
|
|
19618
|
+
let piv = c;
|
|
19619
|
+
for (let r = c + 1; r < p; r++)
|
|
19620
|
+
if (Math.abs(M[r][c]) > Math.abs(M[piv][c])) piv = r;
|
|
19621
|
+
if (Math.abs(M[piv][c]) < 1e-12) return null;
|
|
19622
|
+
[M[c], M[piv]] = [M[piv], M[c]];
|
|
19623
|
+
const d = M[c][c];
|
|
19624
|
+
for (let k = 0; k < 2 * p; k++) M[c][k] /= d;
|
|
19625
|
+
for (let r = 0; r < p; r++) {
|
|
19626
|
+
if (r === c) continue;
|
|
19627
|
+
const f = M[r][c];
|
|
19628
|
+
if (f === 0) continue;
|
|
19629
|
+
for (let k = 0; k < 2 * p; k++) M[r][k] -= f * M[c][k];
|
|
19630
|
+
}
|
|
19631
|
+
}
|
|
19632
|
+
const Ninv = M.map((row) => row.slice(p));
|
|
19633
|
+
const x = Ninv.map((row) => row.reduce((s, v, k) => s + v * b[k], 0));
|
|
19634
|
+
return { x, Ninv };
|
|
19635
|
+
}
|
|
19636
|
+
function median3(xs) {
|
|
19637
|
+
const s = [...xs].sort((a, b) => a - b);
|
|
19638
|
+
const m = s.length >> 1;
|
|
19639
|
+
return s.length % 2 ? s[m] : (s[m - 1] + s[m]) / 2;
|
|
19640
|
+
}
|
|
19641
|
+
function robustSigma(xs) {
|
|
19642
|
+
if (xs.length < 2) return 0;
|
|
19643
|
+
const m = median3(xs);
|
|
19644
|
+
return 1.4826 * median3(xs.map((x) => Math.abs(x - m)));
|
|
19645
|
+
}
|
|
19646
|
+
function designRow(tMs, d) {
|
|
19647
|
+
const dt = (tMs - d.refEpochMs) / MS_PER_YEAR;
|
|
19648
|
+
const row = [1, dt];
|
|
19649
|
+
for (const j of d.jumps) row.push(tMs >= j ? 1 : 0);
|
|
19650
|
+
if (d.seasonal) {
|
|
19651
|
+
const ph = TWO_PI2 * (tMs / MS_PER_YEAR);
|
|
19652
|
+
row.push(Math.sin(ph), Math.cos(ph), Math.sin(2 * ph), Math.cos(2 * ph));
|
|
19653
|
+
}
|
|
19654
|
+
return row;
|
|
19655
|
+
}
|
|
19656
|
+
function fitComponent(t, y, w, used, d) {
|
|
19657
|
+
const A = [];
|
|
19658
|
+
const yy = [];
|
|
19659
|
+
const ww = [];
|
|
19660
|
+
for (let i = 0; i < t.length; i++) {
|
|
19661
|
+
if (!used[i]) continue;
|
|
19662
|
+
A.push(designRow(t[i], d));
|
|
19663
|
+
yy.push(y[i]);
|
|
19664
|
+
ww.push(w[i]);
|
|
19665
|
+
}
|
|
19666
|
+
if (A.length <= (A[0]?.length ?? 0)) return null;
|
|
19667
|
+
const s = lsq(A, yy, ww);
|
|
19668
|
+
if (!s) return null;
|
|
19669
|
+
const residuals = t.map(
|
|
19670
|
+
(ti, i) => y[i] - designRow(ti, d).reduce((acc, a, k) => acc + a * s.x[k], 0)
|
|
19671
|
+
);
|
|
19672
|
+
let wrss = 0;
|
|
19673
|
+
let sumW = 0;
|
|
19674
|
+
for (let i = 0; i < t.length; i++) {
|
|
19675
|
+
if (!used[i]) continue;
|
|
19676
|
+
wrss += w[i] * residuals[i] ** 2;
|
|
19677
|
+
sumW += w[i];
|
|
19678
|
+
}
|
|
19679
|
+
return { ...s, wrss, sumW, residuals };
|
|
19680
|
+
}
|
|
19681
|
+
function fitCoordinateSeries(samples, opts = {}) {
|
|
19682
|
+
const pts = [...samples].sort((a, b) => a.tMs - b.tMs);
|
|
19683
|
+
if (pts.length < 5) return null;
|
|
19684
|
+
const t = pts.map((p) => p.tMs);
|
|
19685
|
+
const spanYears = (t[t.length - 1] - t[0]) / MS_PER_YEAR;
|
|
19686
|
+
if (spanYears <= 0) return null;
|
|
19687
|
+
const ref = [0, 1, 2].map(
|
|
19688
|
+
(k2) => median3(pts.map((p) => p.ecef[k2]))
|
|
19689
|
+
);
|
|
19690
|
+
const [lat, lon] = ecefToGeodetic(ref[0], ref[1], ref[2]);
|
|
19691
|
+
const sl = Math.sin(lat);
|
|
19692
|
+
const cl = Math.cos(lat);
|
|
19693
|
+
const so = Math.sin(lon);
|
|
19694
|
+
const co = Math.cos(lon);
|
|
19695
|
+
const enu = pts.map((p) => {
|
|
19696
|
+
const dx = p.ecef[0] - ref[0];
|
|
19697
|
+
const dy = p.ecef[1] - ref[1];
|
|
19698
|
+
const dz = p.ecef[2] - ref[2];
|
|
19699
|
+
return [
|
|
19700
|
+
-so * dx + co * dy,
|
|
19701
|
+
-sl * co * dx - sl * so * dy + cl * dz,
|
|
19702
|
+
cl * co * dx + cl * so * dy + sl * dz
|
|
19703
|
+
];
|
|
19704
|
+
});
|
|
19705
|
+
const weights = [0, 1, 2].map(
|
|
19706
|
+
(k2) => pts.map((p) => {
|
|
19707
|
+
const s = p.sigmaEnu?.[k2];
|
|
19708
|
+
return s && s > 0 ? 1 / Math.max(s, MIN_SIGMA_M) ** 2 : 1;
|
|
19709
|
+
})
|
|
19710
|
+
);
|
|
19711
|
+
const series = [0, 1, 2].map((k2) => enu.map((v) => v[k2]));
|
|
19712
|
+
const seasonal = opts.seasonal === "auto" || opts.seasonal === void 0 ? spanYears >= 2 : opts.seasonal;
|
|
19713
|
+
const design = {
|
|
19714
|
+
refEpochMs: opts.refEpochMs ?? (t[0] + t[t.length - 1]) / 2,
|
|
19715
|
+
jumps: [...opts.jumps ?? []].filter((j) => j > t[0] && j <= t[t.length - 1]).sort((a, b) => a - b),
|
|
19716
|
+
seasonal
|
|
19717
|
+
};
|
|
19718
|
+
const detected = /* @__PURE__ */ new Set();
|
|
19719
|
+
const k = opts.outlierK ?? 4;
|
|
19720
|
+
const used = pts.map(() => true);
|
|
19721
|
+
const fitAll = () => [0, 1, 2].map(
|
|
19722
|
+
(c) => fitComponent(t, series[c], weights[c], used, design)
|
|
19723
|
+
);
|
|
19724
|
+
const robustPass = () => {
|
|
19725
|
+
for (let iter = 0; iter < 10; iter++) {
|
|
19726
|
+
const sol2 = fitAll();
|
|
19727
|
+
if (sol2.some((s) => !s)) return null;
|
|
19728
|
+
const scales = sol2.map(
|
|
19729
|
+
(s) => Math.max(robustSigma(s.residuals.filter((_, i) => used[i])), 1e-4)
|
|
19730
|
+
);
|
|
19731
|
+
let changed = false;
|
|
19732
|
+
for (let i = 0; i < t.length; i++) {
|
|
19733
|
+
const bad = sol2.some(
|
|
19734
|
+
(s, c) => Math.abs(s.residuals[i]) > k * scales[c]
|
|
19735
|
+
);
|
|
19736
|
+
if (bad === used[i]) {
|
|
19737
|
+
used[i] = !bad;
|
|
19738
|
+
changed = true;
|
|
19739
|
+
}
|
|
19740
|
+
}
|
|
19741
|
+
if (!changed) return sol2;
|
|
19742
|
+
}
|
|
19743
|
+
return fitAll();
|
|
19744
|
+
};
|
|
19745
|
+
let sol = robustPass();
|
|
19746
|
+
if (!sol) return null;
|
|
19747
|
+
if (opts.detectJumps ?? true) {
|
|
19748
|
+
const minSide = opts.minSamplesPerSide ?? 5;
|
|
19749
|
+
for (let added = 0; added < (opts.maxJumps ?? 3); added++) {
|
|
19750
|
+
const idx = t.map((_, i) => i).filter((i) => used[i]);
|
|
19751
|
+
const nUsed = idx.length;
|
|
19752
|
+
const bicOf = (s, p) => s.reduce((acc, c) => acc + nUsed * Math.log(c.wrss / c.sumW), 0) + 3 * p * Math.log(nUsed);
|
|
19753
|
+
const p0 = designRow(t[0], design).length;
|
|
19754
|
+
const bic0 = bicOf(sol, p0);
|
|
19755
|
+
let best = null;
|
|
19756
|
+
for (let j = minSide; j <= nUsed - minSide; j++) {
|
|
19757
|
+
const tj = (t[idx[j - 1]] + t[idx[j]]) / 2;
|
|
19758
|
+
if (design.jumps.some((x) => Math.abs(x - tj) < 7 * 864e5))
|
|
19759
|
+
continue;
|
|
19760
|
+
const trial = {
|
|
19761
|
+
...design,
|
|
19762
|
+
jumps: [...design.jumps, tj].sort((a, b) => a - b)
|
|
19763
|
+
};
|
|
19764
|
+
const s = [0, 1, 2].map(
|
|
19765
|
+
(c) => fitComponent(t, series[c], weights[c], used, trial)
|
|
19766
|
+
);
|
|
19767
|
+
if (s.some((x) => !x)) continue;
|
|
19768
|
+
const bic = bicOf(s, p0 + 1);
|
|
19769
|
+
if (!best || bic < best.bic)
|
|
19770
|
+
best = { tMs: tj, bic, sol: s };
|
|
19771
|
+
}
|
|
19772
|
+
if (!best || bic0 - best.bic <= 10) break;
|
|
19773
|
+
design.jumps = [...design.jumps, best.tMs].sort((a, b) => a - b);
|
|
19774
|
+
detected.add(best.tMs);
|
|
19775
|
+
sol = robustPass();
|
|
19776
|
+
if (!sol) return null;
|
|
19777
|
+
}
|
|
19778
|
+
}
|
|
19779
|
+
const nJ = design.jumps.length;
|
|
19780
|
+
const component = (c) => {
|
|
19781
|
+
const s = sol[c];
|
|
19782
|
+
const nUsed = used.filter(Boolean).length;
|
|
19783
|
+
const p = s.x.length;
|
|
19784
|
+
const vf = nUsed > p ? s.wrss / (nUsed - p) : 1;
|
|
19785
|
+
const amp = (i) => seasonal ? Math.hypot(s.x[i], s.x[i + 1]) : null;
|
|
19786
|
+
const noise = opts.noiseModel ?? true ? fitWhiteFlicker(
|
|
19787
|
+
t.flatMap((ti, i) => used[i] ? [designRow(ti, design)] : []),
|
|
19788
|
+
series[c].filter((_, i) => used[i]),
|
|
19789
|
+
t.flatMap((ti, i) => used[i] ? [ti / MS_PER_YEAR] : [])
|
|
19790
|
+
) : null;
|
|
19791
|
+
return {
|
|
19792
|
+
offset: s.x[0],
|
|
19793
|
+
velocity: s.x[1],
|
|
19794
|
+
velocitySigma: Math.sqrt(s.Ninv[1][1] * vf),
|
|
19795
|
+
velocitySigmaRealistic: noise?.velocitySigma ?? null,
|
|
19796
|
+
flickerShare: noise?.flickerShare ?? null,
|
|
19797
|
+
steps: s.x.slice(2, 2 + nJ),
|
|
19798
|
+
annualAmplitude: amp(2 + nJ),
|
|
19799
|
+
semiannualAmplitude: amp(4 + nJ),
|
|
19800
|
+
wrms: Math.sqrt(s.wrss / s.sumW)
|
|
19801
|
+
};
|
|
19802
|
+
};
|
|
19803
|
+
const points = pts.map((p, i) => ({
|
|
19804
|
+
tMs: p.tMs,
|
|
19805
|
+
enu: enu[i],
|
|
19806
|
+
model: [0, 1, 2].map((c) => series[c][i] - sol[c].residuals[i]),
|
|
19807
|
+
outlier: !used[i]
|
|
19808
|
+
}));
|
|
19809
|
+
return {
|
|
19810
|
+
refEcef: ref,
|
|
19811
|
+
refEpochMs: design.refEpochMs,
|
|
19812
|
+
e: component(0),
|
|
19813
|
+
n: component(1),
|
|
19814
|
+
u: component(2),
|
|
19815
|
+
jumps: design.jumps.map((tMs) => ({ tMs, detected: detected.has(tMs) })),
|
|
19816
|
+
points,
|
|
19817
|
+
spanYears,
|
|
19818
|
+
used: used.filter(Boolean).length,
|
|
19819
|
+
outliers: used.filter((u) => !u).length,
|
|
19820
|
+
seasonal
|
|
19821
|
+
};
|
|
19822
|
+
}
|
|
19823
|
+
|
|
19824
|
+
// src/analysis/network-alignment.ts
|
|
19825
|
+
function applyHelmertFit(x, f) {
|
|
19826
|
+
const [r1, r2, r3] = f.r;
|
|
19827
|
+
return [
|
|
19828
|
+
x[0] + f.t[0] + f.d * x[0] - r3 * x[1] + r2 * x[2],
|
|
19829
|
+
x[1] + f.t[1] + r3 * x[0] + f.d * x[1] - r1 * x[2],
|
|
19830
|
+
x[2] + f.t[2] - r2 * x[0] + r1 * x[1] + f.d * x[2]
|
|
19831
|
+
];
|
|
19832
|
+
}
|
|
19833
|
+
function solve(N, b) {
|
|
19834
|
+
const n = b.length;
|
|
19835
|
+
const M = N.map((row, i) => [...row, b[i]]);
|
|
19836
|
+
for (let c = 0; c < n; c++) {
|
|
19837
|
+
let p = c;
|
|
19838
|
+
for (let r = c + 1; r < n; r++)
|
|
19839
|
+
if (Math.abs(M[r][c]) > Math.abs(M[p][c])) p = r;
|
|
19840
|
+
if (Math.abs(M[p][c]) < 1e-6) return null;
|
|
19841
|
+
[M[c], M[p]] = [M[p], M[c]];
|
|
19842
|
+
for (let r = 0; r < n; r++) {
|
|
19843
|
+
if (r === c) continue;
|
|
19844
|
+
const f = M[r][c] / M[c][c];
|
|
19845
|
+
for (let k = c; k <= n; k++) M[r][k] -= f * M[c][k];
|
|
19846
|
+
}
|
|
19847
|
+
}
|
|
19848
|
+
return M.map((row, i) => row[n] / row[i]);
|
|
19849
|
+
}
|
|
19850
|
+
function estimateHelmert(from, to, opts = {}) {
|
|
19851
|
+
const model = opts.model ?? "translation";
|
|
19852
|
+
const nPar = model === "translation" ? 3 : 7;
|
|
19853
|
+
const minRefs = opts.minRefs ?? (model === "translation" ? 3 : 4);
|
|
19854
|
+
const maxRes = opts.maxResidualM ?? 0.015;
|
|
19855
|
+
if (from.length !== to.length) return null;
|
|
19856
|
+
const used = from.map(() => true);
|
|
19857
|
+
const c = [0, 1, 2].map(
|
|
19858
|
+
(k) => from.reduce((s, p) => s + p[k], 0) / Math.max(from.length, 1)
|
|
19859
|
+
);
|
|
19860
|
+
for (; ; ) {
|
|
19861
|
+
const idx = used.flatMap((u, i) => u ? [i] : []);
|
|
19862
|
+
if (idx.length < minRefs || idx.length * 3 <= nPar) return null;
|
|
19863
|
+
const N = Array.from(
|
|
19864
|
+
{ length: nPar },
|
|
19865
|
+
() => new Array(nPar).fill(0)
|
|
19866
|
+
);
|
|
19867
|
+
const b = new Array(nPar).fill(0);
|
|
19868
|
+
for (const i of idx) {
|
|
19869
|
+
const x = [from[i][0] - c[0], from[i][1] - c[1], from[i][2] - c[2]];
|
|
19870
|
+
for (let k = 0; k < 3; k++) {
|
|
19871
|
+
const row = new Array(nPar).fill(0);
|
|
19872
|
+
row[k] = 1;
|
|
19873
|
+
if (nPar === 7) {
|
|
19874
|
+
if (k === 0) {
|
|
19875
|
+
row[4] = x[2];
|
|
19876
|
+
row[5] = -x[1];
|
|
19877
|
+
} else if (k === 1) {
|
|
19878
|
+
row[3] = -x[2];
|
|
19879
|
+
row[5] = x[0];
|
|
19880
|
+
} else {
|
|
19881
|
+
row[3] = x[1];
|
|
19882
|
+
row[4] = -x[0];
|
|
19883
|
+
}
|
|
19884
|
+
row[6] = x[k];
|
|
19885
|
+
}
|
|
19886
|
+
const y = to[i][k] - from[i][k];
|
|
19887
|
+
for (let a = 0; a < nPar; a++) {
|
|
19888
|
+
b[a] += row[a] * y;
|
|
19889
|
+
for (let bb = 0; bb < nPar; bb++) N[a][bb] += row[a] * row[bb];
|
|
19890
|
+
}
|
|
19891
|
+
}
|
|
19892
|
+
}
|
|
19893
|
+
const p = solve(N, b);
|
|
19894
|
+
if (!p) return null;
|
|
19895
|
+
const r = nPar === 7 ? [p[3], p[4], p[5]] : [0, 0, 0];
|
|
19896
|
+
const d = nPar === 7 ? p[6] : 0;
|
|
19897
|
+
const t = [
|
|
19898
|
+
p[0] - (d * c[0] - r[2] * c[1] + r[1] * c[2]),
|
|
19899
|
+
p[1] - (r[2] * c[0] + d * c[1] - r[0] * c[2]),
|
|
19900
|
+
p[2] - (-r[1] * c[0] + r[0] * c[1] + d * c[2])
|
|
19901
|
+
];
|
|
19902
|
+
const fit = { model, t, r, d, residuals: [], used, rms: 0 };
|
|
19903
|
+
fit.residuals = from.map((x, i) => {
|
|
19904
|
+
const y = applyHelmertFit(x, fit);
|
|
19905
|
+
return [to[i][0] - y[0], to[i][1] - y[1], to[i][2] - y[2]];
|
|
19906
|
+
});
|
|
19907
|
+
let worst = -1;
|
|
19908
|
+
let worstNorm = maxRes;
|
|
19909
|
+
let ss = 0;
|
|
19910
|
+
for (const i of idx) {
|
|
19911
|
+
const n = Math.hypot(...fit.residuals[i]);
|
|
19912
|
+
ss += n * n;
|
|
19913
|
+
if (n > worstNorm) {
|
|
19914
|
+
worstNorm = n;
|
|
19915
|
+
worst = i;
|
|
19916
|
+
}
|
|
19917
|
+
}
|
|
19918
|
+
fit.rms = Math.sqrt(ss / (3 * idx.length));
|
|
19919
|
+
if (worst < 0 || idx.length <= minRefs) {
|
|
19920
|
+
fit.used = [...used];
|
|
19921
|
+
return fit;
|
|
19922
|
+
}
|
|
19923
|
+
used[worst] = false;
|
|
19924
|
+
}
|
|
19925
|
+
}
|
|
19926
|
+
|
|
19292
19927
|
// src/antex/index.ts
|
|
19293
19928
|
function label(line) {
|
|
19294
19929
|
return (line.length >= 80 ? line.substring(60, 80) : line.substring(60)).trimEnd();
|
|
@@ -20484,6 +21119,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
20484
21119
|
BAND_LABELS,
|
|
20485
21120
|
BAND_PRESETS,
|
|
20486
21121
|
BDS_SATELLITES,
|
|
21122
|
+
BLQ_CONSTITUENTS,
|
|
20487
21123
|
BitReader,
|
|
20488
21124
|
CONSTELLATIONS,
|
|
20489
21125
|
C_LIGHT,
|
|
@@ -20581,6 +21217,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
20581
21217
|
analyzeQuality,
|
|
20582
21218
|
antexFreqOfGroup,
|
|
20583
21219
|
applyHelmert,
|
|
21220
|
+
applyHelmertFit,
|
|
20584
21221
|
applyIonoDcb,
|
|
20585
21222
|
applyOrbitClock,
|
|
20586
21223
|
biasMetres,
|
|
@@ -20628,6 +21265,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
20628
21265
|
ecefToAzEl,
|
|
20629
21266
|
ecefToGeodetic,
|
|
20630
21267
|
ephInfoToEphemeris,
|
|
21268
|
+
estimateHelmert,
|
|
20631
21269
|
estimateNarrowlaneFcb,
|
|
20632
21270
|
estimateNetworkFcbs,
|
|
20633
21271
|
estimateWidelaneFcb,
|
|
@@ -20639,6 +21277,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
20639
21277
|
feedNavicBlock,
|
|
20640
21278
|
fetchSourcetable,
|
|
20641
21279
|
findSatBias,
|
|
21280
|
+
fitCoordinateSeries,
|
|
20642
21281
|
fixPppPosition,
|
|
20643
21282
|
fmtD,
|
|
20644
21283
|
fmtF,
|
|
@@ -20733,12 +21372,14 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
20733
21372
|
nlWavelength,
|
|
20734
21373
|
nmeaCoordToDecimal,
|
|
20735
21374
|
obsEpochToDate,
|
|
21375
|
+
oceanLoadingEnu,
|
|
20736
21376
|
oem4Frames,
|
|
20737
21377
|
padL,
|
|
20738
21378
|
padR,
|
|
20739
21379
|
parseAntex,
|
|
20740
21380
|
parseBiasSinex,
|
|
20741
21381
|
parseBinex,
|
|
21382
|
+
parseBlq,
|
|
20742
21383
|
parseClk,
|
|
20743
21384
|
parseCrxDataLine,
|
|
20744
21385
|
parseIonex,
|