Skip to content

Commit 58ca94b

Browse files
Merge pull request #540 from Smithsonian/fix/nongrav-reporting
Make the non-grav placeholder negligible and the discarded refinement visible
2 parents 6f52cc9 + efe1740 commit 58ca94b

2 files changed

Lines changed: 24 additions & 5 deletions

File tree

src/layup/orbitfit.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1568,7 +1568,17 @@ def _orbitfit(
15681568
if res_ng.flag == 0:
15691569
res = res_ng
15701570
else:
1571-
logger.debug("Non-grav refinement did not converge; reporting non-grav params as NaN.")
1571+
# Not silent: the caller asked for a non-grav fit and is getting a
1572+
# gravity-only one, with the parameters reported as NaN and a flag
1573+
# of 0 that refers to the gravity fit. Name the flag the joint fit
1574+
# actually returned -- 6 is a weakly-constrained solution, not a
1575+
# failure to converge, and 2 is an acceptable-step fit rejected on
1576+
# chi-square.
1577+
logger.warning(
1578+
"Non-grav refinement returned flag %d; keeping the 6-parameter "
1579+
"solution and reporting the non-grav parameters as NaN.",
1580+
res_ng.flag,
1581+
)
15721582

15731583
# The non-grav refinement above can replace `res`, so take the check
15741584
# verdicts from whatever is actually being returned.

src/lib/orbit_fit/orbit_fit.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ namespace orbit_fit
9393
// short arcs) and the fit is reported as weakly constrained (flag = 6).
9494
static constexpr double WEAK_NONGRAV_RCOND = 1e-8;
9595

96+
// Placeholder amplitude (au/day^2) used to keep a non-grav parameter's column
97+
// non-degenerate when its seed is zero; see the seeding loop in orbit_fit.
98+
static constexpr double NONGRAV_SEED_PLACEHOLDER = 1e-20;
99+
96100
// Arcseconds per radian (180*3600/pi). Converts astrometric/rate
97101
// uncertainties from arcseconds to radians and scales residuals for display.
98102
static constexpr double ARCSEC_PER_RAD = 206265.0;
@@ -1103,8 +1107,13 @@ namespace orbit_fit
11031107
// active[] holds the param indices (0=A1,1=A2,2=A3) in column order. ASSIST
11041108
// skips the non-grav block when A1=A2=A3=0, which would zero the param
11051109
// columns; seed each active param with a tiny nonzero value so its column
1106-
// is non-degenerate (the partial is independent of the param's magnitude,
1107-
// and 1e-15 au/day^2 is dynamically negligible).
1110+
// is non-degenerate. The partial does not depend on the seed's magnitude,
1111+
// so the seed only has to be small enough to be dynamically irrelevant.
1112+
// It was 1e-15 au/day^2, which is not: real Yarkovsky amplitudes are of
1113+
// that order, so on a long arc with precise data the placeholder is a
1114+
// sizeable fraction of the signal. On (6489) Golevka it is 6% of the true
1115+
// A2 and raises the starting chi-square from 12,888 to 138,416 before the
1116+
// first iteration. 1e-20 restores the gravity-only chi-square exactly.
11081117
std::vector<int> active;
11091118
for (int i = 0; i < 3; i++)
11101119
if (nongrav_mask & (1 << i))
@@ -1129,9 +1138,9 @@ namespace orbit_fit
11291138
for (int k = 0; k < nactive; k++)
11301139
{
11311140
if (a123[active[k]] == 0.0)
1132-
a123[active[k]] = 1e-15;
1141+
a123[active[k]] = NONGRAV_SEED_PLACEHOLDER;
11331142
if (per_arc && a123b[active[k]] == 0.0)
1134-
a123b[active[k]] = 1e-15;
1143+
a123b[active[k]] = NONGRAV_SEED_PLACEHOLDER;
11351144
}
11361145

11371146
// #419 sequential update: snapshot the prior mean x0 (= the seed state)

0 commit comments

Comments
 (0)