From 52d77e34ed7b6bccf7514eb91119831743a634ca Mon Sep 17 00:00:00 2001 From: Don Cross Date: Sat, 29 Jun 2019 14:31:37 -0400 Subject: [PATCH] Python: more work in progress, translating functions. Also fixed incorrect comment in C code. --- generate/template/astronomy.c | 2 +- generate/template/astronomy.py | 37 ++++++++++++++++++++++++++++++++-- source/c/astronomy.c | 2 +- source/python/astronomy.py | 37 ++++++++++++++++++++++++++++++++-- 4 files changed, 72 insertions(+), 6 deletions(-) diff --git a/generate/template/astronomy.c b/generate/template/astronomy.c index 7ca4aa67..fddd1093 100644 --- a/generate/template/astronomy.c +++ b/generate/template/astronomy.c @@ -3044,7 +3044,7 @@ astro_search_result_t Astronomy_SearchMoonPhase(double targetLon, astro_time_t s I have seen up to 0.826 days away from the simple prediction. To be safe, we take the predicted time of the event and search +/-0.9 days around it (a 1.8-day wide window). - But we must return null if the final result goes beyond limitDays after startTime. + Return ASTRO_NO_MOON_QUARTER if the final result goes beyond limitDays after startTime. */ const double uncertainty = 0.9; astro_func_result_t funcres; diff --git a/generate/template/astronomy.py b/generate/template/astronomy.py index 658d65b7..296c9abd 100644 --- a/generate/template/astronomy.py +++ b/generate/template/astronomy.py @@ -1493,6 +1493,38 @@ def SearchSunLongitude(targetLon, startTime, limitDays): t2 = startTime.Add(limitDays) return Search(_sun_offset, targetLon, startTime, t2, 1.0) +def MoonPhase(time): + return LongitudeFromSun(BODY_MOON, time) + +def _moon_offset(targetLon, time): + angle = MoonPhase(time) + return _LongitudeOffset(angle - targetLon) + +def SearchMoonPhase(targetLon, startTime, limitDays): + # To avoid discontinuities in the _moon_offset function causing problems, + # we need to approximate when that function will next return 0. + # We probe it with the start time and take advantage of the fact + # that every lunar phase repeats roughly every 29.5 days. + # There is a surprising uncertainty in the quarter timing, + # due to the eccentricity of the moon's orbit. + # I have seen up to 0.826 days away from the simple prediction. + # To be safe, we take the predicted time of the event and search + # +/-0.9 days around it (a 1.8-day wide window). + # But we must return None if the final result goes beyond limitDays after startTime. + uncertainty = 0.9 + ya = _moon_offset(targetLon, startTime) + if ya > 0.0: + ya -= 360.0 # force searching forward in time, not backward + est_dt = -(_MEAN_SYNODIC_MONTH * ya) / 360.0 + dt1 = est_dt - uncertainty + if dt1 > limitDays: + return None # not possible for moon phase to occur within the specified window + dt2 = min(limitDays, est_dt + uncertainty) + t1 = startTime.AddDays(dt1) + t2 = startTime.AddDays(dt2) + return Search(_moon_offset, targetLon, t1, t2, 1.0) + + #================================================================================================== # + SearchSunLongitude # + _sun_offset @@ -1506,8 +1538,9 @@ def SearchSunLongitude(targetLon, startTime, limitDays): # + SearchRelativeLongitude # + Elongation # + LongitudeFromSun -# - MoonPhase -# - SearchMoonPhase +# + MoonPhase +# + SearchMoonPhase +# + _moon_offset # - SearchMoonQuarter # - NextMoonQuarter # - SearchHourAngle diff --git a/source/c/astronomy.c b/source/c/astronomy.c index ca7f08e1..92b995d3 100644 --- a/source/c/astronomy.c +++ b/source/c/astronomy.c @@ -4100,7 +4100,7 @@ astro_search_result_t Astronomy_SearchMoonPhase(double targetLon, astro_time_t s I have seen up to 0.826 days away from the simple prediction. To be safe, we take the predicted time of the event and search +/-0.9 days around it (a 1.8-day wide window). - But we must return null if the final result goes beyond limitDays after startTime. + Return ASTRO_NO_MOON_QUARTER if the final result goes beyond limitDays after startTime. */ const double uncertainty = 0.9; astro_func_result_t funcres; diff --git a/source/python/astronomy.py b/source/python/astronomy.py index f17727ce..24e1bff6 100644 --- a/source/python/astronomy.py +++ b/source/python/astronomy.py @@ -2331,6 +2331,38 @@ def SearchSunLongitude(targetLon, startTime, limitDays): t2 = startTime.Add(limitDays) return Search(_sun_offset, targetLon, startTime, t2, 1.0) +def MoonPhase(time): + return LongitudeFromSun(BODY_MOON, time) + +def _moon_offset(targetLon, time): + angle = MoonPhase(time) + return _LongitudeOffset(angle - targetLon) + +def SearchMoonPhase(targetLon, startTime, limitDays): + # To avoid discontinuities in the _moon_offset function causing problems, + # we need to approximate when that function will next return 0. + # We probe it with the start time and take advantage of the fact + # that every lunar phase repeats roughly every 29.5 days. + # There is a surprising uncertainty in the quarter timing, + # due to the eccentricity of the moon's orbit. + # I have seen up to 0.826 days away from the simple prediction. + # To be safe, we take the predicted time of the event and search + # +/-0.9 days around it (a 1.8-day wide window). + # But we must return None if the final result goes beyond limitDays after startTime. + uncertainty = 0.9 + ya = _moon_offset(targetLon, startTime) + if ya > 0.0: + ya -= 360.0 # force searching forward in time, not backward + est_dt = -(_MEAN_SYNODIC_MONTH * ya) / 360.0 + dt1 = est_dt - uncertainty + if dt1 > limitDays: + return None # not possible for moon phase to occur within the specified window + dt2 = min(limitDays, est_dt + uncertainty) + t1 = startTime.AddDays(dt1) + t2 = startTime.AddDays(dt2) + return Search(_moon_offset, targetLon, t1, t2, 1.0) + + #================================================================================================== # + SearchSunLongitude # + _sun_offset @@ -2344,8 +2376,9 @@ def SearchSunLongitude(targetLon, startTime, limitDays): # + SearchRelativeLongitude # + Elongation # + LongitudeFromSun -# - MoonPhase -# - SearchMoonPhase +# + MoonPhase +# + SearchMoonPhase +# + _moon_offset # - SearchMoonQuarter # - NextMoonQuarter # - SearchHourAngle