Instrument Neutral Distributed Interface INDI 2.2.5
test_libnova_nutation.cpp
Go to the documentation of this file.
1/*******************************************************************************
2 * Test: libnova nutation correctness
3 *
4 * Validates INDI::ln_get_equ_nut (and by extension J2000toObserved) against
5 * two independent checks:
6 *
7 * 1. Sign check: the nutation correction in Dec for Deneb at JD 2459019.8
8 * must be negative. The DEG_TO_RAD macro bug
9 * (nut_ecliptic computed as ~23.4 instead of ~0.409 radians) flips
10 * sin/cos of the ecliptic and reverses the sign, turning a -4" Dec
11 * correction into a +11" one.
12 *
13 * 2. Absolute accuracy: J2000toObserved for Deneb must agree with IMCCE
14 * Miriade (INPOP19) truth to < 1 arcsecond. The macro bug causes ~15"
15 * error, dominated by the flipped Dec nutation term.
16 *
17 * Truth source: IMCCE Miriade, query:
18 * https://ssp.imcce.fr/webservices/miriade/api/ephemcc.php
19 * -name=HIP102098 -type=star -ep=2459019.833333 -tcoor=1 -mime=json
20 * Deneb (HIP 102098) at JD 2459019.833333 (2020-06-19 08:00 UTC)
21 *******************************************************************************/
22
23#include <gtest/gtest.h>
24#include <libastro.h>
25#include <libnova/nutation.h>
26#include <cmath>
27
28static constexpr double JD_TEST = 2459019.833333;
29static constexpr double RA_J2000_H = 20.69053168;
30static constexpr double DEC_J2000_DEG = 45.28033881;
31static constexpr double RA_TRUTH_H = 20.70237028;
32static constexpr double DEC_TRUTH_DEG = 45.35036333;
33
34// ---------------------------------------------------------------------------
35// Structural: the Dec nutation correction for Deneb at this epoch must be
36// negative. With the correct nut_ecliptic (~0.409 rad) sin_ecliptic>0,
37// giving delta_dec ≈ -4". The DEG_TO_RAD bug yields nut_ecliptic ~23.4 rad
38// where sin(23.4) < 0, flipping the sign to +11".
39// ---------------------------------------------------------------------------
40TEST(LibnovaNutation, DecCorrectionSign)
41{
42 ln_equ_posn pos_before = { RA_J2000_H * 15.0, DEC_J2000_DEG };
43 ln_equ_posn pos_after = pos_before;
44
45 INDI::ln_get_equ_nut(&pos_after, JD_TEST, false);
46
47 double delta_dec_arcsec = (pos_after.dec - pos_before.dec) * 3600.0;
48
49 GTEST_LOG_(INFO) << "Nutation Dec correction: " << delta_dec_arcsec << "\"";
50 GTEST_LOG_(INFO) << "Nutation RA correction: " << (pos_after.ra - pos_before.ra) * 3600.0 << "\"";
51
52 // The correct Dec nutation for this star/epoch is negative (~-4").
53 // The DEG_TO_RAD bug produces +11", so testing the sign is sufficient
54 // to distinguish correct from buggy without hard-coding the exact value.
55 EXPECT_LT(delta_dec_arcsec, 0.0)
56 << "Dec nutation correction is positive (" << delta_dec_arcsec
57 << "\") — expected negative for Deneb at this epoch. "
58 "Likely DEG_TO_RAD macro bug in ln_get_equ_nut.";
59}
60
61// ---------------------------------------------------------------------------
62// Absolute accuracy: J2000toObserved for Deneb must agree with IMCCE truth
63// to < 1 arcsecond. The DEG_TO_RAD bug causes ~15" error.
64// ---------------------------------------------------------------------------
65TEST(LibnovaNutation, J2000toObservedAccuracy)
66{
67 INDI::IEquatorialCoordinates j2000 = { RA_J2000_H, DEC_J2000_DEG };
69
70 INDI::J2000toObserved(&j2000, JD_TEST, &jnow);
71
72 double cos_dec = std::cos(DEC_TRUTH_DEG * M_PI / 180.0);
73 double err_ra = std::abs(jnow.rightascension - RA_TRUTH_H) * 15.0 * 3600.0 * cos_dec;
74 double err_dec = std::abs(jnow.declination - DEC_TRUTH_DEG) * 3600.0;
75 double err_total = std::hypot(err_ra, err_dec);
76
77 GTEST_LOG_(INFO) << "Deneb J2000toObserved: ra=" << jnow.rightascension
78 << "h dec=" << jnow.declination << "d";
79 GTEST_LOG_(INFO) << "Error vs IMCCE: RA=" << err_ra << "\" Dec=" << err_dec
80 << "\" total=" << err_total << "\"";
81
82 EXPECT_LT(err_total, 1.0)
83 << "J2000toObserved error=" << err_total
84 << "\" exceeds 1\" vs IMCCE truth — likely DEG_TO_RAD macro bug";
85}
86
87int main(int argc, char **argv)
88{
89 ::testing::InitGoogleTest(&argc, argv);
90 return RUN_ALL_TESTS();
91}
#define M_PI
Definition dsp.h:52
int main()
void ln_get_equ_nut(ln_equ_posn *posn, double jd, bool reverse)
apply or remove nutation
Definition libastro.cpp:103
void J2000toObserved(IEquatorialCoordinates *J2000pos, double jd, IEquatorialCoordinates *observed)
*J2000toObserved converts catalogue to observed
Definition libastro.cpp:81
TEST(LibnovaNutation, DecCorrectionSign)