kylebarron / suncalc-py

A Python port of suncalc.js for calculating sun position and sunlight phases
MIT License
60 stars 8 forks source link

arccos errors in 0.1.2 #7

Closed tedder closed 2 years ago

tedder commented 2 years ago

This seems to be related or similar to #4. (note I manually wordwrapped these for readability)

$ python3
Python 3.8.10 (default, Nov 26 2021, 20:14:08) 
[GCC 9.3.0] on linux
>>> suncalc.__version__
'0.1.2'
>>> import datetime,suncalc
>>> datetime.datetime.strptime('20211220', '%Y%m%d')
datetime.datetime(2021, 12, 20, 0, 0)
>>> suncalc.get_times( datetime.datetime.strptime('2021220', '%Y%m%d'), 51, -114)
/usr/local/lib/python3.8/dist-packages/suncalc/suncalc.py:202:
RuntimeWarning: invalid value encountered in arccos
  return acos((sin(h) - sin(phi) * sin(d)) / (cos(phi) * cos(d)))
{'solar_noon': datetime.datetime(2021, 2, 20, 8, 51, 12, 961660),
'nadir': datetime.datetime(2021, 2, 19, 20, 51, 12, 961660),
'sunrise': datetime.datetime(2021, 2, 20, 4, 43, 14, 252018),
'sunset': datetime.datetime(2021, 2, 20, 12, 59, 11, 671301),
'sunrise_end': datetime.datetime(2021, 2, 20, 4, 37, 13, 961476),
'sunset_start': datetime.datetime(2021, 2, 20, 13, 5, 11, 961843),
'dawn': datetime.datetime(2021, 2, 20, 5, 47, 17, 217253),
'dusk': datetime.datetime(2021, 2, 20, 11, 55, 8, 706066),
'nautical_dawn': datetime.datetime(2021, 2, 20, 7, 41, 14, 97490),
'nautical_dusk': datetime.datetime(2021, 2, 20, 10, 1, 11, 825829),
'night_end': numpy.datetime64('NaT'),
'night': numpy.datetime64('NaT'),
'golden_hour_end': datetime.datetime(2021, 2, 20, 3, 30, 41, 914049),
'golden_hour': datetime.datetime(2021, 2, 20, 14, 11, 44, 9271)}

>>> suncalc.get_times( datetime.datetime.strptime('2021120', '%Y%m%d'), 51, -114)
{'solar_noon': datetime.datetime(2021, 1, 20, 8, 48, 6, 897451), 
'nadir': datetime.datetime(2021, 1, 19, 20, 48, 6, 897451),
'sunrise': datetime.datetime(2021, 1, 20, 6, 45, 44, 506256),
'sunset': datetime.datetime(2021, 1, 20, 10, 50, 29, 288645),
'sunrise_end': datetime.datetime(2021, 1, 20, 6, 35, 10, 891669),
'sunset_start': datetime.datetime(2021, 1, 20, 11, 1, 2, 903233),
'dawn': numpy.datetime64('NaT'), 
'dusk': numpy.datetime64('NaT'),
'nautical_dawn': numpy.datetime64('NaT'),
'nautical_dusk': numpy.datetime64('NaT'),
'night_end': numpy.datetime64('NaT'),
'night': numpy.datetime64('NaT'),
'golden_hour_end': datetime.datetime(2021, 1, 20, 5, 1, 19, 241467),
'golden_hour': datetime.datetime(2021, 1, 20, 12, 34, 54, 553435)}

>>> suncalc.get_times( datetime.datetime.utcnow(), 31, -114)
{'solar_noon': datetime.datetime(2021, 12, 21, 9, 55, 20, 995867),
'nadir': datetime.datetime(2021, 12, 20, 21, 55, 20, 995867),
'sunrise': numpy.datetime64('NaT'),
'sunset': numpy.datetime64('NaT'),
'sunrise_end': datetime.datetime(2021, 12, 21, 9, 19, 27, 169529),
'sunset_start': datetime.datetime(2021, 12, 21, 10, 31, 14, 822205),
'dawn': numpy.datetime64('NaT'),
'dusk': numpy.datetime64('NaT'),
'nautical_dawn': numpy.datetime64('NaT'),
'nautical_dusk': numpy.datetime64('NaT'),
'night_end': numpy.datetime64('NaT'),
'night': numpy.datetime64('NaT'),
'golden_hour_end': datetime.datetime(2021, 12, 21, 6, 51, 1, 218479),
'golden_hour': datetime.datetime(2021, 12, 21, 12, 59, 40, 773255)}

Note it only gives the warning once, but it happens in each- presumably numpy just suppresses the warnings after the first time. Here's an example- and note it isn't near the winter solstice.

>>> import datetime,suncalc
>>> suncalc.get_times( datetime.datetime(2021, 10, 21, 9, 55, 20, 995867), 51, -114)
/usr/local/lib/python3.8/dist-packages/suncalc/suncalc.py:202:
RuntimeWarning: invalid value encountered in arccos
  return acos((sin(h) - sin(phi) * sin(d)) / (cos(phi) * cos(d)))
{'solar_noon': datetime.datetime(2021, 10, 21, 8, 21, 47, 239111),
'nadir': datetime.datetime(2021, 10, 20, 20, 21, 47, 239111),
'sunrise': datetime.datetime(2021, 10, 21, 4, 11, 27, 472661),
'sunset': datetime.datetime(2021, 10, 21, 12, 32, 7, 5561),
'sunrise_end': datetime.datetime(2021, 10, 21, 4, 5, 29, 309365),
'sunset_start': datetime.datetime(2021, 10, 21, 12, 38, 5, 168856),
'dawn': datetime.datetime(2021, 10, 21, 5, 14, 55, 726919),
'dusk': datetime.datetime(2021, 10, 21, 11, 28, 38, 751302),
'nautical_dawn': datetime.datetime(2021, 10, 21, 7, 4, 56, 97234),
'nautical_dusk': datetime.datetime(2021, 10, 21, 9, 38, 38, 380988),
'night_end': numpy.datetime64('NaT'),
'night': numpy.datetime64('NaT'),
'golden_hour_end': datetime.datetime(2021, 10, 21, 2, 59, 12, 620696),
'golden_hour': datetime.datetime(2021, 10, 21, 13, 44, 21, 857526)}

Some of the problems seem to be solstice-related:

>>> suncalc.get_times( datetime.datetime(2021, 12, 20, 20, 21, 47, 239111), 31, -114)['dawn']
numpy.datetime64('NaT')
>>> suncalc.get_times( datetime.datetime(2021, 10, 20, 20, 21, 47, 239111), 31, -114)['dawn']
datetime.datetime(2021, 10, 21, 6, 35, 10, 705027)
tedder commented 2 years ago

Ha. It's LON/LAT not LAT/LON.

So it's hard to calculate a proper sun time for 32 degrees past the pole.