/* * sidereal_time.c -- Greenwich sidereal time (mean and apparent) * * Clean-room implementation from published standards: * * Mean sidereal time: * Capitaine, Guinot & McCarthy (2000), A&A 355, 398-405. * IERS Conventions (2010), IERS Technical Note 36, Ch. 5, * Eq. 5.29 (GMST as polynomial in UT1). * * The polynomial form is: * GMST(UT1) = theta_0 + theta_1*T + theta_2*T^2 + theta_3*T^3 * where T is Julian centuries of UT1 from J2000.0, and the * result is in seconds of time. Coefficients from Capitaine * et al. (2000), Eq. (42), which are the values adopted by * the IERS for consistency with IAU 2000/2006 precession. * * Apparent sidereal time: * GAST = GMST + equation_of_equinoxes * EqEq = delta_psi * cos(epsilon_A) * IERS Conventions (2010), Eq. 5.30. */ #include "sidereal_time.h" #include "precession.h" #include #ifndef M_PI #define M_PI 3.14159265358979323846 #endif /* Arcseconds to radians */ #define ARCSEC_TO_RAD (M_PI / (180.0 * 3600.0)) /* * get_mean_sidereal_time * * GMST in radians from the classical polynomial expression. * * The polynomial (Capitaine et al. 2000, Eq. 42): * GMST = 67310.54841 * + (876600h + 8640184.812866) * T * + 0.093104 * T^2 * - 6.2e-6 * T^3 * * where T = (JD_UT1 - 2451545.0) / 36525.0 * and the result is in seconds of sidereal time. * * The constant 876600h = 876600 * 3600 = 3155760000 seconds * accounts for complete rotations. * * To convert seconds of time to radians: * 1 day = 86400 seconds of time = 2*pi radians * 1 second of time = 2*pi/86400 = pi/43200 radians * * JDE is accepted for interface consistency but unused here; * GMST is fundamentally a UT1 quantity. */ double get_mean_sidereal_time(double JD, double JDE) { double T, T2, T3; double gmst_sec; double gmst_rad; (void)JDE; /* GMST depends on UT1, not TDB */ T = (JD - 2451545.0) / 36525.0; T2 = T * T; T3 = T2 * T; /* * Polynomial in seconds of sidereal time. * The large linear coefficient includes whole rotations * accumulated since J2000.0. */ gmst_sec = 67310.54841 + (876600.0 * 3600.0 + 8640184.812866) * T + 0.093104 * T2 - 6.2e-6 * T3; /* Seconds of time -> radians, then normalize to [0, 2*pi) */ gmst_rad = fmod(gmst_sec * (M_PI / 43200.0), 2.0 * M_PI); if (gmst_rad < 0.0) gmst_rad += 2.0 * M_PI; return gmst_rad; } /* * get_apparent_sidereal_time * * GAST = GMST + equation of the equinoxes. * * The equation of the equinoxes (IERS 2010, Eq. 5.30): * EqEq = delta_psi * cos(epsilon_A) * * where delta_psi is nutation in longitude and epsilon_A is * the mean obliquity of the ecliptic, both in arcseconds. * * For the full IAU 2000A model, there is an additional * "complementary terms" correction to EqEq (Eq. 5.31), * but it is at the 0.1 mas level and negligible for our * accuracy requirements. */ double get_apparent_sidereal_time(double JD, double JDE) { double gmst; double epsilon_A, chi_A, omega_A, psi_A; double delta_psi, delta_epsilon; double eq_eq; double gast; gmst = get_mean_sidereal_time(JD, JDE); /* Get mean obliquity from precession (in arcseconds) */ get_precession_angles_vondrak(JDE, &epsilon_A, &chi_A, &omega_A, &psi_A); /* Get nutation in longitude (in arcseconds) */ get_nutation_angles_iau2000b(JDE, &delta_psi, &delta_epsilon); /* * Equation of the equinoxes: * delta_psi is in arcseconds, epsilon_A is in arcseconds. * Convert delta_psi to radians, multiply by cos(epsilon_A in radians), * result is in radians. */ eq_eq = (delta_psi * ARCSEC_TO_RAD) * cos(epsilon_A * ARCSEC_TO_RAD); gast = gmst + eq_eq; /* Normalize to [0, 2*pi) */ gast = fmod(gast, 2.0 * M_PI); if (gast < 0.0) gast += 2.0 * M_PI; return gast; }