-
-
Notifications
You must be signed in to change notification settings - Fork 242
Description
Using Skyfield 1.54 I came across a somewhat rare warning:
I have reduced the code to an MWE as best I could. I get no information where this fails in my code.
Here is my simplified code to reproduce the error:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from datetime import date, datetime, timedelta
from skyfield import VERSION
from skyfield.api import Loader, wgs84, N, S, E, W
from skyfield import almanac
d = date(2000, 1, 1) # select DATE year, month, day
lat = 67.0 # select latitude
obj = 6 # select PLANET 0, 1, 2, 3, 4, 5, 6
print("\nSkyfield version = ",VERSION)
load = Loader("./")
ts = load.timescale()
eph = load('de421.bsp')
mercury = eph['mercury']
venus = eph['venus']
earth = eph['earth']
mars = eph['mars']
jupiter = eph['jupiter barycenter']
saturn = eph['saturn barycenter']
uranus = eph['uranus barycenter']
neptune = eph['neptune barycenter']
pl_name = ['Mercury', 'Venus', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']
pl_name2 = ['Mercury', 'Venus ', 'Mars ', 'Jupiter', 'Saturn ', 'Uranus ', 'Neptune']
pl_eph = [mercury, venus, mars, jupiter, saturn, uranus, neptune]
planet = pl_eph[obj]
dt = datetime(d.year, d.month, d.day, 0, 0, 0)
dt_start = dt
daysinyear = (date(d.year+1, 1, 1) - date(d.year, 1, 1)).days
latns = 'N' if lat >= 0.0 else 'S'
print("year {}: {} at latitude {:.1f}°{}".format(d.year,pl_name2[obj],abs(lat),latns))
#---------------------------------------------------------------------------
topos = wgs84.latlon(lat, 0.0 * E, elevation_m=0.0)
observer = earth + topos
print("... raw data from almanac.find_settings and almanac.find_risings:")
for i in range(daysinyear):
#for i in range(5):
t0 = ts.ut1(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second)
t1 = ts.ut1(dt.year, dt.month, dt.day+1, dt.hour, dt.minute, dt.second)
planetset, iS = almanac.find_settings(observer, planet, t0, t1)
planetrise, iR = almanac.find_risings(observer, planet, t0, t1)
for ndx, dt0 in enumerate(planetset):
print(" set ",dt0.utc_iso(' ') ," ",iS[ndx])
for ndx, dt0 in enumerate(planetrise):
print(" rise",dt0.utc_iso(' ')," ",iR[ndx])
dt += timedelta(days = 1)
dt = dt_start
print("... ditto in chronological order and filtered for True events only:")
for i in range(daysinyear):
#for i in range(5):
t0 = ts.ut1(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second)
t1 = ts.ut1(dt.year, dt.month, dt.day+1, dt.hour, dt.minute, dt.second)
planetset, iS = almanac.find_settings(observer, planet, t0, t1)
planetrise, iR = almanac.find_risings(observer, planet, t0, t1)
# assemble TRUE events in chronological order
nR = len(planetrise); nS = len(planetset)
ndxR = ndxS = 0
riseset_time = []; isrise = []
while ndxR < nR or ndxS < nS:
if ndxR < nR and ndxS < nS:
if iR[ndxR] and iS[ndxS]:
if planetrise[ndxR] < planetset[ndxS]:
riseset_time.append(planetrise[ndxR]); isrise.append(True)
riseset_time.append(planetset[ndxS]); isrise.append(False)
else:
riseset_time.append(planetset[ndxS]); isrise.append(False)
riseset_time.append(planetrise[ndxR]); isrise.append(True)
elif iR[ndxR]:
riseset_time.append(planetrise[ndxR]); isrise.append(True)
elif iS[ndxS]:
riseset_time.append(planetset[ndxS]); isrise.append(False)
ndxR += 1; ndxS += 1
elif ndxR < nR:
if iR[ndxR]:
riseset_time.append(planetrise[ndxR]); isrise.append(True)
ndxR += 1
elif ndxS < nS:
if iS[ndxS]:
riseset_time.append(planetset[ndxS]); isrise.append(False)
ndxS += 1
dt += timedelta(days = 1)
I am using Python 3.13.9. My code works perfectly, i.e. as expected, in 99.999% of cases and I have since enhanced the code to over double the length above. As far as I can tell, there are TWO ISSUES here:
- the RuntimeWarning from almanc.py in line 339 (Skyfield 1.54)
- and most likely as a consequence of the RuntimeWarning:
almanac.find_settings()oralmanac.find_risings()can output NaN instead of an event TIME in the first output parameter, which should never be the case - this causes my code to crash
I would REALLY APPRECIATE it if this abrupt warning could be eliminated.
As always.... sincere thanks for all assistance!
UPDATES:
It occurs on 2031-04-18 and you can set for i in range(1): in the last for loop.
It then fails also with a second RuntimeWarning, this time in timelib.py at line 673:
I have now switched to incrementing the latitude in tenths of a degree as an integer, e.g. from 670 to 720, increment 1, and I divide by 10 to get the latitude (degrees) as a float. This way I avoid accumulating the error using a float increment of 0.1 repetitively.
Next failure point I noticed (using a later program version) is with Neptune on 2000-03-18 at 68.7°N:
By comparison, here is correct data from Skyfield 1.49:
Nothing unusual happens on 2000-03-18 ,,,,,,,,
Take a look at my chart for Neptune in 2000 at 68.7°N with Skyfield 1.49:
Initially I thought that something broke in Skyfield 1.54
Here are some random test cases using Skyfield 1.54 where I detected this issue occurs:
2000-06-08 Neptune 67.0N
2000-03-18 Neptune 68.7N
2000-10-06 Neptune 69.3N
2000-05-13 Uranus 71.6N
2001-10-14 Neptune 67.0N
2001-06-23 Uranus 68.1N
2001-09-20 Neptune 70.0N
2001-07-05 Uranus 70.2N
2020-05-23 Uranus 68.4N
2021-06-03 Saturn 67.3N
2021-06-30 Uranus 68.7N
2023-12-31 Uranus 70.9N
2025-02-09 Uranus 69.8N
2026-02-08 Uranus 50.7N
2027-07-16 Uranus 60.2N
2028-04-04 Uranus 56.9N
2028-07-23 Saturn 69.3N
2029-11-04 Mars 52.0N
2029-04-23 Uranus 54.0N
2029-01-26 Jupiter 62.2N
2029-12-23 Uranus 65.9N
Initially I suspected this issue is caused by Skyfield 1.54 alone, though I saw no reason for it.
So I decided to test using Skyfield 1.53.
I tested the years 2027, 2028 and 2029 for latitudes between 50.0°N and 72.0°N in 0.1 degree steps [using integer steps because it is impossible to represent 0.1 (decimal) precisely in binary with a finite number of digits]
I found these cases where Skyfield 1.53 fails with the same symptoms:
2027-08-11 Neptune 50.0N
2028-01-20 Jupiter 55.7N
2029-07-14 Saturn 56.8N
So I see that this issue is not limited to Skyfield 1.54 (though 1.54 is more error-prone than 1.53).
I now want to look at Skyfield 1.49, which I thought was 100% free of this problem.