Skip to content

RuntimeWarning from almanac.py line 339 (divide by zero?) #1114

@aendie

Description

@aendie

Using Skyfield 1.54 I came across a somewhat rare warning:

Image

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):

    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)

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)
  • almanac.find_settings() or almanac.find_risings() outputs a TIME value that dt0.utc_iso(' ') cannot convert and crashes with the message ValueError: cannot convert float NaN to integer.

Initially I believed that the ValueError is a consequence of the RuntimeWarning. Now I tend to think the reverse is true. I adapted the program below that scans all planets for a given range of latitudes for several years so that the ValueError is trapped: it prints rise ----- NaN error ----- or set ----- NaN error ----- usually without any RuntimeWarning, however runing the program above for the given year/planet/latitude will always print the RuntimeWarning first (on the date on which it fails).

I would REALLY APPRECIATE it if the RuntimeWarning and associated ValueError 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:

Image

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:

Image

By comparison, here is correct data from Skyfield 1.49:

Image

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:

Image

Initially I thought that something broke in Skyfield 1.54
Using Windows 11, numpy 2.4.1, and Skyfield 1.54, here are some random test cases using where I detected this issue occurs:

2000-09-17 50.0N Jupiter
2000-12-12 50.0N Neptune
2000-11-17 50.5N Uranus
2000-07-27 50.7N Jupter
2000-04-29 54.9N Neptune
2000-10-26 55.6N Neptune
2000-05-20 56.1N Uranus
2000-10-24 56.8N Neptune
2000-05-29 59.3N Neptune
2000-06-26 60.4N Neptune
2000-05-03 61.1N Neptune
2000-05-03 62.1N Uranus
2000-05-06 63.0N Neptune
2000-04-22 63.8N Uranus
2000-10-10 64.2N Uranus
2000-03-24 64.4N Neptune
2000-05-27 65.6N Uranus
2000-06-08 67.0N Neptune
2000-03-18 68.7N Neptune
2000-10-06 69.3N Neptune
2000-05-13 71.6N Uranus
2001-08-18 50.4N Mars
2001-01-15 51.2N Neptune
2001-10-29 52.3N Uranus
2001-04-29 56.0N Uranus
2001-07-05 56.1N Neptune
2001-11-22 57.3N Jupiter
2001-10-10 57.6N Saturn
2001-11-21 58.1N Jupiter
2001-05-13 58.5N Neptune
2001-01-16 58.8N Jupiter
2001-09-12 58.9M Meptune
2001-06-06 60.6N Neptune
2001-04-13 61.2N Neptune
2001-07-12 63.4N Jupiter
2001-01-02 64.0N Saturn
2001-10-31 64.2N Jupiter
2001-08-31 64.7N Neptune
2001-05-22 65.8N Uranus
2001-05-26 66.0N Neptune
2001-05-14 66.1N Uranus
2001-10-14 67.0N Neptune
2001-06-23 68.1N Uranus
2001-09-20 70.0N Neptune
2001-07-05 70.2N Uranus
2001-10-14 67.0N Neptune
2001-06-23 68.1N Uranus
2001-09-20 70.0N Neptune
2001-07-05 70.2N Uranus
2020-05-23 68.4N Uranus
2021-06-03 67.3N Saturn
2021-06-30 68.7N Uranus
2023-12-31 70.9N Uranus
2025-02-09 69.8N Uranus
2026-02-08 50.7N Uranus
2027-07-16 60.2N Uranus
2028-04-04 56.9N Uranus
2028-07-23 69.3N Saturn
2029-11-04 52.0N Mars
2029-04-23 54.0N Uranus
2029-01-26 62.2N Jupiter
2029-12-23 65.9N Uranus

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 (and numpy 2.4.1 in Windows 11):
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]

Using Windows 11, numpy 2.4.1, and Skyfield 1.53, I found these cases where it 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).
(TBD: look at Skyfield 1.49, which I think is 100% free of this problem.)

I switched to another hardware platform: an old ASUS Zenbook with Intel i7-8565U CPU.
Using Windows 11, numpy 2.4.2, and Skyfield 1.54 I got exactly the same four failures for the year 2029 between 50.0°N and 72.0°N as above.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions