The PyEphem page for Rising, Transit, Setting
suggests that to match the USNO's almanac data for rising of the Sun,
you can turn off refraction (by setting air pressure to zero)
and put the horizon 34 minutes of arc lower than normal:
>>> import ephem
>>> atlanta = ephem.Observer()
>>> atlanta.pressure = 0
>>> atlanta.horizon = '-0:34'
>>> atlanta.lat, atlanta.lon = '33.8', '-84.4'
>>> atlanta.date = '2009/09/06 17:00' # noon EST
>>> print(atlanta.previous_rising(ephem.Sun()))
Now if you move the horizon up by the entire apparent diameter of the Sun,
previous_rising
will tell when the top limb of the Sun reaches
this horizon (assuming no refraction), which will occur exactly when
the bottom limb of the Sun reaches 34 minutes of arc below the
normal horizon (again assuming no refraction),
which (following the USNO's practice) is the predicted time when the
bottom limb of the sun will be at the normal horizon when refraction
is taken into account.
Note that, as explained under the heading
Technical Definitions and Computational Details
on this page at the USNO site,
the USNO rise/set times for the Sun tell when the center of the sun
is 50 minutes of arc below the horizon, regardless of the actual apparent
diameter of the Sun at that time.
In effect, they assume 16 minutes of arc for the radius of the Sun
and 34 minutes of arc for refraction.
Further, under the subheading Accuracy of rise/set computations,
it is noted that "even under ideal conditions (e.g., a clear sky at sea) the times computed for rise or set may be in error by a minute or more"
due to unpredictable atmospheric conditions.
And the effect gets even worse if you are at a higher latitude.
In light of this, a reasonable procedure might be to assume
32 minutes of arc for the Sun's diameter; then to predict the end of
sunrise rather than the beginning, you would change the line
>>> atlanta.horizon = '-0:34'
in the PyEphem sample code to
>>> atlanta.horizon = '-0:02'