开发者

pyephem: can't calculate sunrise/set for polar regions

i'm trying to calculate sunrises and sunsets using pyephem, but the algorithm never seems to converge for polar regions?

observe the sample code below. it iterates through an entire ye开发者_运维百科ar in 10-minute increments asking for the next sunrise and sunset. pyephem always returns with an AlwaysUpError or NeverUpError, but surely the sun must rise and set at least once during the year?

import ephem
from datetime import datetime, timedelta

obs = ephem.Observer()
obs.lat = '89:30'
obs.long = '0'

start = datetime(2011, 1, 1)
end = datetime(2012, 1, 1)
step = timedelta(minutes=10)

sun = ephem.Sun()

timestamp = start
while timestamp < end:
    obs.date = timestamp

    try:
        print obs.next_rising(sun)
    except (ephem.AlwaysUpError, ephem.NeverUpError):
        pass

    try:
        print obs.next_setting(sun)
    except (ephem.AlwaysUpError, ephem.NeverUpError):
        pass

    try:
        print obs.previous_rising(sun)
    except (ephem.AlwaysUpError, ephem.NeverUpError):
        pass

    try:
        print obs.previous_setting(sun)
    except (ephem.AlwaysUpError, ephem.NeverUpError):
        pass

    timestamp += step

either i'm using the api incorrectly, there's a bug in pyephem, or i'm misunderstanding something fundamental. any help?


I suspect some sort of improper caching. Consider:

import ephem 
atlanta = ephem.Observer() 
atlanta.pressure = 0 
atlanta.horizon = '-0:34' 
atlanta.lat, atlanta.lon = '89:30', '0' 
atlanta.date = '2011/03/18 12:00' 
print atlanta.previous_rising(ephem.Sun()) 
print atlanta.next_setting(ephem.Sun()) 
atlanta.date = '2011/03/19 12:00' 
print atlanta.previous_rising(ephem.Sun()) 
print atlanta.next_setting(ephem.Sun()) 
atlanta.date = '2011/03/20 12:00' 
print atlanta.previous_rising(ephem.Sun()) 
# print atlanta.next_setting(ephem.Sun()) 
atlanta.date = '2011/09/24 12:00' 
# print atlanta.previous_rising(ephem.Sun()) 
print atlanta.next_setting(ephem.Sun()) 
atlanta.date = '2011/09/25 12:00' 
print atlanta.previous_rising(ephem.Sun()) 
print atlanta.next_setting(ephem.Sun()) 
atlanta.date = '2011/09/26 12:00' 
print atlanta.previous_rising(ephem.Sun()) 
print atlanta.next_setting(ephem.Sun()) 

which yields:

2011/3/18 07:49:34 
2011/3/18 17:44:50 
2011/3/19 05:04:49 
2011/3/19 21:49:23 
2011/3/20 01:26:02 
2011/9/24 19:59:09 
2011/9/25 04:57:21 
2011/9/25 17:14:10 
2011/9/26 08:37:25 
2011/9/26 14:03:20 

which matches to the minute with USNO results:

https://raw.github.com/barrycarter/bcapps/master/db/srss-895.txt

See also my related whiny complain in linked question.


I just ran your program and got this output (piped to "sort | uniq -c"):

260 2011/3/17 11:32:31
469 2011/3/17 13:42:56
184 2011/3/18 07:25:56
350 2011/3/18 18:13:15
191 2011/3/19 04:41:42
346 2011/9/24 20:25:13
337 2011/9/25 04:27:45
214 2011/9/25 17:36:10
166 2011/9/26 08:00:59
254 2011/9/26 14:37:06

Are you sure you have the indentations right? Here's my raw code:

https://raw.github.com/barrycarter/bcapps/master/playground4.py

(the output doesn't match my other answer above, but we're using different horizons (-34 minutes vs -50 minutes).


i've found using the start parameter to obs.next_rising(), etc., yield better results. however it still sometimes seems to miss certain crossings; the rises it finds don't always pair off with a corresponding set.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜