def nutation(cls, tee): """Return the longitudinal nutation at moment, tee.""" c = cls.julian_centuries(tee) cap_A = poly(c, [mpf(124.90), mpf(-1934.134), mpf(0.002063)]) cap_B = poly(c, [mpf(201.11), mpf(72001.5377), mpf(0.00057)]) return (mpf(-0.004778) * sin_degrees(cap_A) + mpf(-0.0003667) * sin_degrees(cap_B))
def precession(cls, tee): """Return the precession at moment tee using 0,0 as J2000 coordinates. Adapted from "Astronomical Algorithms" by Jean Meeus, Willmann-Bell, Inc., 1991.""" c = cls.julian_centuries(tee) eta = mod(poly(c, [0, secs(mpf(47.0029)), secs(mpf(-0.03302)), secs(mpf(0.000060))]), 360) cap_P = mod(poly(c, [mpf(174.876384), secs(mpf(-869.8089)), secs(mpf(0.03536))]), 360) p = mod(poly(c, [0, secs(mpf(5029.0966)), secs(mpf(1.11113)), secs(mpf(0.000006))]), 360) cap_A = cos_degrees(eta) * sin_degrees(cap_P) cap_B = cos_degrees(cap_P) arg = arctan_degrees(cap_A, cap_B) return mod(p + cap_P - arg, 360)
def lunar_perigee(cls, tee): """Return Angular distance of the perigee from the equinoctal point at moment, tee. Adapted from eq. 47.7 in "Astronomical Algorithms" by Jean Meeus, Willmann_Bell, Inc., 2nd ed., 1998 with corrections June 2005.""" return normalized_degrees(poly(cls.julian_centuries(tee), [mpf(83.3532465), mpf(4069.0137287), mpf(-0.0103200), mpf(-1.0/80053.0), mpf(1.0/18999000.0)]))
def alt_lunar_node(cls, tee): """Return Angular distance of the node from the equinoctal point at fixed moment, tee. Adapted from eq. 47.7 in "Astronomical Algorithms" by Jean Meeus, Willmann_Bell, Inc., 2nd ed., 1998 with corrections June 2005.""" return normalized_degrees(poly(cls.julian_centuries(tee), [mpf(125.0445479), mpf(-1934.1362891), mpf(0.0020754), mpf(1.0/467441.0), mpf(-1.0/60616000.0)]))
def lunar_elongation(cls, c): """Return elongation of moon (in degrees) at moment given in Julian centuries c. Adapted from eq. 47.2 in "Astronomical Algorithms" by Jean Meeus, Willmann_Bell, Inc., 2nd ed. with corrections, 2005.""" return normalized_degrees(poly(c, [mpf(297.8501921), mpf(445267.1114034), mpf(-0.0018819), mpf(1/545868), mpf(-1/113065000)]))
def obliquity(cls, tee): """Return (mean) obliquity of ecliptic at moment tee.""" c = cls.julian_centuries(tee) return (angle(23, 26, mpf(21.448)) + poly(c, [mpf(0), angle(0, 0, mpf(-46.8150)), angle(0, 0, mpf(-0.00059)), angle(0, 0, mpf(0.001813))]))
def lunar_latitude(cls, tee): """Return the latitude of moon (in degrees) at moment, tee. Adapted from "Astronomical Algorithms" by Jean Meeus, Willmann_Bell, Inc., 1998.""" c = cls.julian_centuries(tee) cap_L_prime = cls.mean_lunar_longitude(c) cap_D = cls.lunar_elongation(c) cap_M = Solar.solar_anomaly(c) cap_M_prime = cls.lunar_anomaly(c) cap_F = cls.moon_node(c) cap_E = poly(c, [1, mpf(-0.002516), mpf(-0.0000074)]) args_lunar_elongation = \ [0, 0, 0, 2, 2, 2, 2, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4, 4, 0, 4, 2, 2, 2, 2, 0, 2, 2, 2, 2, 4, 2, 2, 0, 2, 1, 1, 0, 2, 1, 2, 0, 4, 4, 1, 4, 1, 4, 2] args_solar_anomaly = \ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, -1, -1, -1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 1, 0, -1, -2, 0, 1, 1, 1, 1, 1, 0, -1, 1, 0, -1, 0, 0, 0, -1, -2] args_lunar_anomaly = \ [0, 1, 1, 0, -1, -1, 0, 2, 1, 2, 0, -2, 1, 0, -1, 0, -1, -1, -1, 0, 0, -1, 0, 1, 1, 0, 0, 3, 0, -1, 1, -2, 0, 2, 1, -2, 3, 2, -3, -1, 0, 0, 1, 0, 1, 1, 0, 0, -2, -1, 1, -2, 2, -2, -1, 1, 1, -2, 0, 0] args_moon_node = \ [1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 3, 1, 1, 1, -1, -1, -1, 1, -1, 1, -3, 1, -3, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 3, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1] sine_coefficients = \ [5128122, 280602, 277693, 173237, 55413, 46271, 32573, 17198, 9266, 8822, 8216, 4324, 4200, -3359, 2463, 2211, 2065, -1870, 1828, -1794, -1749, -1565, -1491, -1475, -1410, -1344, -1335, 1107, 1021, 833, 777, 671, 607, 596, 491, -451, 439, 422, 421, -366, -351, 331, 315, 302, -283, -229, 223, 223, -220, -220, -185, 181, -177, 176, 166, -164, 132, -119, 115, 107] beta = ((1.0/1000000.0) * sigma([sine_coefficients, args_lunar_elongation, args_solar_anomaly, args_lunar_anomaly, args_moon_node], lambda v, w, x, y, z: (v * pow(cap_E, abs(x)) * sin_degrees((w * cap_D) + (x * cap_M) + (y * cap_M_prime) + (z * cap_F))))) venus = ((175/1000000) * (sin_degrees(mpf(119.75) + c * mpf(131.849) + cap_F) + sin_degrees(mpf(119.75) + c * mpf(131.849) - cap_F))) flat_earth = ((-2235/1000000) * sin_degrees(cap_L_prime) + (127/1000000) * sin_degrees(cap_L_prime - cap_M_prime) + (-115/1000000) * sin_degrees(cap_L_prime + cap_M_prime)) extra = ((382/1000000) * sin_degrees(mpf(313.45) + c * mpf(481266.484))) return beta + venus + flat_earth + extra
def equation_of_time(cls, tee): """Return the equation of time (as fraction of day) for moment, tee. Adapted from "Astronomical Algorithms" by Jean Meeus, Willmann_Bell, Inc., 1991.""" c = cls.julian_centuries(tee) lamb = poly(c, [mpf(280.46645), mpf(36000.76983), mpf(0.0003032)]) anomaly = poly(c, [mpf(357.52910), mpf(35999.05030), mpf(-0.0001559), mpf(-0.00000048)]) eccentricity = poly(c, [mpf(0.016708617), mpf(-0.000042037), mpf(-0.0000001236)]) varepsilon = cls.obliquity(tee) y = pow(tan_degrees(varepsilon / 2), 2) equation = ((1/2 / pi) * (y * sin_degrees(2 * lamb) + -2 * eccentricity * sin_degrees(anomaly) + (4 * eccentricity * y * sin_degrees(anomaly) * cos_degrees(2 * lamb)) + -0.5 * y * y * sin_degrees(4 * lamb) + -1.25 * eccentricity * eccentricity * sin_degrees(2 * anomaly))) return signum(equation) * min(abs(equation), Clock.days_from_hours(mpf(12)))
def mean_lunar_longitude(cls, c): """Return mean longitude of moon (in degrees) at moment given in Julian centuries c (including the constant term of the effect of the light-time (-0".70). Adapted from eq. 47.1 in "Astronomical Algorithms" by Jean Meeus, Willmann_Bell, Inc., 2nd ed. with corrections, 2005.""" return normalized_degrees(poly(c, [mpf(218.3164477), mpf(481267.88123421), mpf(-0.0015786), mpf(1 / 538841.0), mpf(-1.0 / 65194000.0)]))
def lunar_longitude(cls, tee): """Return longitude of moon (in degrees) at moment tee. Adapted from "Astronomical Algorithms" by Jean Meeus, Willmann_Bell, Inc., 2nd ed., 1998.""" c = cls.julian_centuries(tee) cap_L_prime = cls.mean_lunar_longitude(c) cap_D = cls.lunar_elongation(c) cap_M = Solar.solar_anomaly(c) cap_M_prime = cls.lunar_anomaly(c) cap_F = cls.moon_node(c) # see eq. 47.6 in Meeus cap_E = poly(c, [1, mpf(-0.002516), mpf(-0.0000074)]) args_lunar_elongation = \ [0, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 1, 0, 2, 0, 0, 4, 0, 4, 2, 2, 1, 1, 2, 2, 4, 2, 0, 2, 2, 1, 2, 0, 0, 2, 2, 2, 4, 0, 3, 2, 4, 0, 2, 2, 2, 4, 0, 4, 1, 2, 0, 1, 3, 4, 2, 0, 1, 2] args_solar_anomaly = \ [0, 0, 0, 0, 1, 0, 0, -1, 0, -1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, -1, 0, 0, 0, 1, 0, -1, 0, -2, 1, 2, -2, 0, 0, -1, 0, 0, 1, -1, 2, 2, 1, -1, 0, 0, -1, 0, 1, 0, 1, 0, 0, -1, 2, 1, 0] args_lunar_anomaly = \ [1, -1, 0, 2, 0, 0, -2, -1, 1, 0, -1, 0, 1, 0, 1, 1, -1, 3, -2, -1, 0, -1, 0, 1, 2, 0, -3, -2, -1, -2, 1, 0, 2, 0, -1, 1, 0, -1, 2, -1, 1, -2, -1, -1, -2, 0, 1, 4, 0, -2, 0, 2, 1, -2, -3, 2, 1, -1, 3] args_moon_node = \ [0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -2, 2, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, -2, 2, 0, 2, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, -2, -2, 0, 0, 0, 0, 0, 0, 0] sine_coefficients = \ [6288774,1274027,658314,213618,-185116,-114332, 58793,57066,53322,45758,-40923,-34720,-30383, 15327,-12528,10980,10675,10034,8548,-7888, -6766,-5163,4987,4036,3994,3861,3665,-2689, -2602, 2390,-2348,2236,-2120,-2069,2048,-1773, -1595,1215,-1110,-892,-810,759,-713,-700,691, 596,549,537,520,-487,-399,-381,351,-340,330, 327,-323,299,294] correction = ((1.0/1000000.0) * sigma([sine_coefficients, args_lunar_elongation, args_solar_anomaly, args_lunar_anomaly, args_moon_node], lambda v, w, x, y, z: v * pow(cap_E, abs(x)) * sin_degrees((w * cap_D) + (x * cap_M) + (y * cap_M_prime) + (z * cap_F)))) A1 = mpf(119.75) + (c * mpf(131.849)) venus = ((3958/1000000) * sin_degrees(A1)) A2 = mpf(53.09) + c * mpf(479264.29) jupiter = ((318/1000000) * sin_degrees(A2)) flat_earth = ((1962/1000000) * sin_degrees(cap_L_prime - cap_F)) return mod(cap_L_prime + correction + venus + jupiter + flat_earth + cls.nutation(tee), 360)
def ephemeris_correction(cls, tee): """Return Dynamical Time minus Universal Time (in days) for moment, tee. Adapted from "Astronomical Algorithms" by Jean Meeus, Willmann_Bell, Inc., 1991.""" year = GregorianDate.to_year(ifloor(tee)) c = GregorianDate.date_difference(GregorianDate(1900, JulianMonth.January, 1), GregorianDate(year, JulianMonth.July, 1)) / mpf(36525) if 1988 <= year <= 2019: return 1/86400 * (year - 1933) elif 1900 <= year <= 1987: return poly(c, [mpf(-0.00002), mpf(0.000297), mpf(0.025184), mpf(-0.181133), mpf(0.553040), mpf(-0.861938), mpf(0.677066), mpf(-0.212591)]) elif 1800 <= year <= 1899: return poly(c, [mpf(-0.000009), mpf(0.003844), mpf(0.083563), mpf(0.865736), mpf(4.867575), mpf(15.845535), mpf(31.332267), mpf(38.291999), mpf(28.316289), mpf(11.636204), mpf(2.043794)]) elif 1700 <= year <= 1799: return 1/86400 * poly(year - 1700, [8.118780842, -0.005092142, 0.003336121, -0.0000266484]) elif 1620 <= year <= 1699: return 1/86400 * poly(year - 1600, [mpf(196.58333), mpf(-4.0675), mpf(0.0219167)]) else: x = Clock.days_from_hours(mpf(12)) + GregorianDate.date_difference(GregorianDate(1810, JulianMonth.January, 1), GregorianDate(year, JulianMonth.January, 1)) return 1/86400 * (((x * x) / mpf(41048480)) - 15)
def lunar_distance(cls, tee): """Return the distance to moon (in meters) at moment, tee. Adapted from "Astronomical Algorithms" by Jean Meeus, Willmann_Bell, Inc., 2nd ed.""" c = cls.julian_centuries(tee) cap_D = cls.lunar_elongation(c) cap_M = cls.solar_anomaly(c) cap_M_prime = cls.lunar_anomaly(c) cap_F = cls.moon_node(c) cap_E = poly(c, [1, mpf(-0.002516), mpf(-0.0000074)]) args_lunar_elongation = \ [0, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 1, 0, 2, 0, 0, 4, 0, 4, 2, 2, 1, 1, 2, 2, 4, 2, 0, 2, 2, 1, 2, 0, 0, 2, 2, 2, 4, 0, 3, 2, 4, 0, 2, 2, 2, 4, 0, 4, 1, 2, 0, 1, 3, 4, 2, 0, 1, 2, 2,] args_solar_anomaly = \ [0, 0, 0, 0, 1, 0, 0, -1, 0, -1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, -1, 0, 0, 0, 1, 0, -1, 0, -2, 1, 2, -2, 0, 0, -1, 0, 0, 1, -1, 2, 2, 1, -1, 0, 0, -1, 0, 1, 0, 1, 0, 0, -1, 2, 1, 0, 0] args_lunar_anomaly = \ [1, -1, 0, 2, 0, 0, -2, -1, 1, 0, -1, 0, 1, 0, 1, 1, -1, 3, -2, -1, 0, -1, 0, 1, 2, 0, -3, -2, -1, -2, 1, 0, 2, 0, -1, 1, 0, -1, 2, -1, 1, -2, -1, -1, -2, 0, 1, 4, 0, -2, 0, 2, 1, -2, -3, 2, 1, -1, 3, -1] args_moon_node = \ [0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -2, 2, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, -2, 2, 0, 2, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, -2, -2, 0, 0, 0, 0, 0, 0, 0, -2] cosine_coefficients = \ [-20905355, -3699111, -2955968, -569925, 48888, -3149, 246158, -152138, -170733, -204586, -129620, 108743, 104755, 10321, 0, 79661, -34782, -23210, -21636, 24208, 30824, -8379, -16675, -12831, -10445, -11650, 14403, -7003, 0, 10056, 6322, -9884, 5751, 0, -4950, 4130, 0, -3958, 0, 3258, 2616, -1897, -2117, 2354, 0, 0, -1423, -1117, -1571, -1739, 0, -4421, 0, 0, 0, 0, 1165, 0, 0, 8752] correction = sigma ([cosine_coefficients, args_lunar_elongation, args_solar_anomaly, args_lunar_anomaly, args_moon_node], lambda v, w, x, y, z: (v * pow(cap_E, abs(x)) * cos_degrees((w * cap_D) + (x * cap_M) + (y * cap_M_prime) + (z * cap_F)))) return 385000560 + correction
def precise_obliquity(cls, tee): """Return precise (mean) obliquity of ecliptic at moment tee.""" u = cls.julian_centuries(tee) / 100 #assert(abs(u) < 1, # 'Error! This formula is valid for +/-10000 years around J2000.0') return (poly(u, [angle(23, 26, mpf(21.448)), angle(0, 0, mpf(-4680.93)), angle(0, 0, mpf(- 1.55)), angle(0, 0, mpf(+1999.25)), angle(0, 0, mpf(- 51.38)), angle(0, 0, mpf(- 249.67)), angle(0, 0, mpf(- 39.05)), angle(0, 0, mpf(+ 7.12)), angle(0, 0, mpf(+ 27.87)), angle(0, 0, mpf(+ 5.79)), angle(0, 0, mpf(+ 2.45))]))
def nth_new_moon(cls, n): """Return the moment of n-th new moon after (or before) the new moon of January 11, 1. Adapted from "Astronomical Algorithms" by Jean Meeus, Willmann_Bell, Inc., 2nd ed., 1998.""" n0 = 24724 k = n - n0 c = k / mpf(1236.85) approx = (cls.J2000 + poly(c, [mpf(5.09766), cls.MEAN_SYNODIC_MONTH * mpf(1236.85), mpf(0.0001437), mpf(-0.000000150), mpf(0.00000000073)])) cap_E = poly(c, [1, mpf(-0.002516), mpf(-0.0000074)]) solar_anomaly = poly(c, [mpf(2.5534), (mpf(1236.85) * mpf(29.10535669)), mpf(-0.0000014), mpf(-0.00000011)]) lunar_anomaly = poly(c, [mpf(201.5643), (mpf(385.81693528) * mpf(1236.85)), mpf(0.0107582), mpf(0.00001238), mpf(-0.000000058)]) moon_argument = poly(c, [mpf(160.7108), (mpf(390.67050284) * mpf(1236.85)), mpf(-0.0016118), mpf(-0.00000227), mpf(0.000000011)]) cap_omega = poly(c, [mpf(124.7746), (mpf(-1.56375588) * mpf(1236.85)), mpf(0.0020672), mpf(0.00000215)]) E_factor = [0, 1, 0, 0, 1, 1, 2, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] solar_coeff = [0, 1, 0, 0, -1, 1, 2, 0, 0, 1, 0, 1, 1, -1, 2, 0, 3, 1, 0, 1, -1, -1, 1, 0] lunar_coeff = [1, 0, 2, 0, 1, 1, 0, 1, 1, 2, 3, 0, 0, 2, 1, 2, 0, 1, 2, 1, 1, 1, 3, 4] moon_coeff = [0, 0, 0, 2, 0, 0, 0, -2, 2, 0, 0, 2, -2, 0, 0, -2, 0, -2, 2, 2, 2, -2, 0, 0] sine_coeff = [mpf(-0.40720), mpf(0.17241), mpf(0.01608), mpf(0.01039), mpf(0.00739), mpf(-0.00514), mpf(0.00208), mpf(-0.00111), mpf(-0.00057), mpf(0.00056), mpf(-0.00042), mpf(0.00042), mpf(0.00038), mpf(-0.00024), mpf(-0.00007), mpf(0.00004), mpf(0.00004), mpf(0.00003), mpf(0.00003), mpf(-0.00003), mpf(0.00003), mpf(-0.00002), mpf(-0.00002), mpf(0.00002)] correction = ((mpf(-0.00017) * sin_degrees(cap_omega)) + sigma([sine_coeff, E_factor, solar_coeff, lunar_coeff, moon_coeff], lambda v, w, x, y, z: (v * pow(cap_E, w) * sin_degrees((x * solar_anomaly) + (y * lunar_anomaly) + (z * moon_argument))))) add_const = [mpf(251.88), mpf(251.83), mpf(349.42), mpf(84.66), mpf(141.74), mpf(207.14), mpf(154.84), mpf(34.52), mpf(207.19), mpf(291.34), mpf(161.72), mpf(239.56), mpf(331.55)] add_coeff = [mpf(0.016321), mpf(26.651886), mpf(36.412478), mpf(18.206239), mpf(53.303771), mpf(2.453732), mpf(7.306860), mpf(27.261239), mpf(0.121824), mpf(1.844379), mpf(24.198154), mpf(25.513099), mpf(3.592518)] add_factor = [mpf(0.000165), mpf(0.000164), mpf(0.000126), mpf(0.000110), mpf(0.000062), mpf(0.000060), mpf(0.000056), mpf(0.000047), mpf(0.000042), mpf(0.000040), mpf(0.000037), mpf(0.000035), mpf(0.000023)] extra = (mpf(0.000325) * sin_degrees(poly(c, [mpf(299.77), mpf(132.8475848), mpf(-0.009173)]))) additional = sigma([add_const, add_coeff, add_factor], lambda i, j, l: l * sin_degrees(i + j * k)) return cls.universal_from_dynamical(approx + correction + extra + additional)
def moon_node(cls, c): """Return Moon's argument of latitude (in degrees) at moment given in Julian centuries 'c'. Adapted from eq. 47.5 in "Astronomical Algorithms" by Jean Meeus, Willmann_Bell, Inc., 2nd ed. with corrections, 2005.""" return normalized_degrees(poly(c, [mpf(93.2720950), mpf(483202.0175233), mpf(-0.0036539), mpf(-1.0/3526000.0), mpf(1.0/863310000.0)]))
def solar_anomaly(cls, c): """Return mean anomaly of sun (in degrees) at moment given in Julian centuries c. Adapted from eq. 47.3 in "Astronomical Algorithms" by Jean Meeus, Willmann_Bell, Inc., 2nd ed. with corrections, 2005.""" return normalized_degrees(poly(c, [mpf(357.5291092), mpf(35999.0502909), mpf(-0.0001536), mpf(1.0/24490000.0)]))
def sidereal_from_moment(cls, tee): """Return the mean sidereal time of day from moment tee expressed as hour angle. Adapted from "Astronomical Algorithms" by Jean Meeus, Willmann_Bell, Inc., 1991.""" c = (tee - cls.J2000) / mpf(36525) return mod(poly(c, [mpf(280.46061837), mpf(36525) * mpf(360.98564736629), mpf(0.000387933), mpf(-1)/mpf(38710000)]), 360)
def lunar_anomaly(cls, c): """Return mean anomaly of moon (in degrees) at moment given in Julian centuries c. Adapted from eq. 47.4 in "Astronomical Algorithms" by Jean Meeus, Willmann_Bell, Inc., 2nd ed. with corrections, 2005.""" return normalized_degrees(poly(c, [mpf(134.9633964), mpf(477198.8675055), mpf(0.0087414), mpf(1.0/69699.0), mpf(-1.0/14712000.0)]))
def geometric_solar_mean_longitude(cls, tee): """Return the geometric mean longitude of the Sun at moment, tee, referred to mean equinox of the date.""" c = cls.julian_centuries(tee) return poly(c, [mpf(280.46646), mpf(36000.76983), mpf(0.0003032)])