The PyEphem Manual

Version 2007.July.5, for PyEphem version 3.7.2a.

The PyEphem Tutorial
Computing With Angles
Computing With Dates
Computations for Particular Observers
Loading Bodies From Catalogues
Fixed Objects, Precession, and Epochs
The PyEphem Reference
1. Module Contents: Astronomical Objects.
2. Module Contents: Angles and Times
3. Module Contents: Functions
4. Observer Objects
5. Body Methods
6. Body Attributes
7. Orbital Elements

The PyEphem library provides Python programmers with access to the scientific-grade astronomical routines used by the XEphem interactive astronomical ephemeris application; its author Elwood Charles Downey generously granted permission for the PyEphem source package to include his routines. After installing the module (see the INSTALL file in the distribution), you should be able to start using it with:

import ephem
and then trying out the examples below.

This documentation begins with a tutorial and ends with a comprehensive reference to the objects and variables accessible through the ephem module. The tutorial assumes that you are familiar with astronomy but not all of the issues surrounding astronomical calculation; those who find its discussions tedious will probably just want to read over its examples to quickly familiarize themselves with how PyEphem works.


The PyEphem Tutorial

PyEphem will compute the positions of celestial bodies on particular dates, and can determine where in the sky they appear from any location on earth.

When using PyEphem you will usually create instances of the bodies that interest you, compute their position for various dates and perhaps geographic locations, and finally print or display the result. For example, to determine the location and brightness of Uranus on the night it was discovered we simply create a Uranus object and ask where it was on the 13th of March 1781:

>>> u = ephem.Uranus()
>>> u.compute('1871/3/13')
>>> print u.ra, u.dec, u.mag
7:45:45.15 21:46:15.66 5.46
>>> print ephem.constellation(u)
('Gem', 'Gemini')
Calling compute() sets many attributes of a body, beyond the right ascension, declination, and magnitude printed here; see Body Attributes in the reference below for other attributes that compute() sets. You see that measurements are formatted as an astronomer would expect: dates are expressed as year, month, and day delimited by slashes; right ascension as hours of arc around the celestial equator; and declination as degrees north of the equator. The colons between the components of an angle are a compromise — the more traditional 21°46′15.66′′ is not possible with the symbols on a standard computer keyboard.

This example used one body, but you can also have several going at once. To determine how close Neptune and Jupiter lay as Galileo famously observed them — he was busy watching the Jovian moons he had discovered two years earlier and, though Neptune had moved overnight, he dismissed it as a background star and left its discovery to wait another two hundred years — we create one instance of each planet and compare their positions:

>>> j = ephem.Jupiter('1612/12/28')
>>> n = ephem.Neptune('1612/12/28')
>>> print j.ra, j.dec, j.mag
12:08:09.94 0:31:49.61 -1.96
>>> print n.ra, n.dec, n.mag
12:09:05.15 0:27:40.37 7.92
>>> print ephem.separation(j, n)
0:14:24.72
Instead of creating the planets and then calling their compute() methods, we have taken the shortcut of providing dates as we create them; in general, any arguments you provide when creating a planet are used to compute() its initial position. The separation() function computes the angle in degrees between two bodies, as measured by their right ascension and declination. In this case, the separation of 0°14′ was small enough to place both planets in Galileo's field of view.

You can even create several instances of the same body. By comparing how far Mars moves in one day at perihelion versus aphelion, we can observe its greater speed when closer to the Sun:

>>> def hpos(body): return body.hlong, body.hlat
>>> ma0 = ephem.Mars('1976/05/21')    # ma: mars near aphelion
>>> ma1 = ephem.Mars('1976/05/22')
>>> print ephem.separation(hpos(ma0), hpos(ma1))
0:26:11.36
>>> mp0 = ephem.Mars('1975/06/13')    # mp: mars near perihelion
>>> mp1 = ephem.Mars('1975/06/14')
>>> print ephem.separation(hpos(mp0), hpos(mp1))
0:38:05.25
Here we wanted to measure the motion of Mars around the Sun, but separation() normally compares the right ascension and declination of two bodies — which would measure the motion of Mars across the sky of the moving platform of our earth. So instead of giving separation() the Mars instances themselves, we specifically provided the heliocentric longitude and latitude of each instance, revealing how far Mars moved around the Sun regardless of how this motion appeared from earth.

In general separation() can measure the angle between any pair of spherical coordinates, so long as the elements of each coordinate are spherical longitude (angle around the sphere) followed by spherical latitude (angle above or below its equator). Each pair should be provided as a two-item sequence like a tuple or list. Appropriate coordinate pairs include right ascension and declination; heliocentric longitude and latitude; azimuth and altitude; and even the geographic longitude and latitude of two locations on earth.

Computing With Angles

Sometimes you may want to perform computations with times and angles. Strings like '7:45:45.15' are attractive when printed, but cumbersome to add and multiply; so PyEphem also makes times and angles available as floating point numbers for more convenient use in mathematical formulae.

All angles returned by PyEphem are actually measured in radians. Let us return to our first example above, and examine the results in more detail:

>>> u = ephem.Uranus('1871/3/13')
>>> print str(u.dec)
21:46:15.66
>>> print float(u.dec)
0.379975914955
>>> print u.dec + 1
1.37997591496
The rule is that angles become strings when printed or given to str(), but otherwise act like Python floating point numbers. Note that the format operator % can return either value, depending on whether you use %s or one of the numeric formats:
>>> print "as a string: %s, as a float: %f" % (u.dec, u.dec)
as a string: 21:46:15.66, as a float: 0.379976
As an example computation, we can verify Kepler's Second Law of planetary motion — that a line drawn from a planet to the sun will sweep out equal areas over equal periods of time. We have already computed two positions for Mars near its aphelion that are one day apart (and defined a helpful hpos() function; see above). We can estimate the actual distance it moved in space that day by multiplying its angular motion in radians by its distance from the Sun:
>>> aph_angle = ephem.separation(hpos(ma0), hpos(ma1))
>>> aph_distance = aph_angle * ma0.sun_distance
>>> print aph_distance
0.0126911122281
So it moved nearly 0.013 AU in a single day (about 1.9 million kilometers). A line drawn between it and the sun would have, roughly, filled in a triangle whose base is 0.013 AU, whose height is the distance to the Sun, and whose area is therefore:
>>> aph_area = aph_distance * ma0.sun_distance / 2.
>>> print aph_area
0.0105710807908
According to Kepler our results should be the same for any other one-day period for which we compute this; we can try using the two Mars positions from near perihelion:
>>> peri_angle = ephem.separation(hpos(mp0), hpos(mp1))
>>> peri_distance = peri_angle * mp0.sun_distance
>>> peri_area = peri_distance * mp0.sun_distance / 2.
>>> print peri_area      # the area, to high precision, is the same!
0.0105712665517
Despite the fact that Mars moves twenty percent faster at perihelion, the area swept out — to quite high precision — is identical, just as Kepler predicted. Some of the tiny difference shown here results from our having approximated sectors of its orbit as triangles; the rest comes from the pertubations of other planets and other small sources of irregularity in its motion.

When you use an angle in mathematical operations, Python will return normal floats that lack the special power of printing themselves as degrees or hours or arc. To turn radian measures back into printable angles, PyEphem supplies both a degrees() and an hours() function. For example:

>>> print peri_angle * 2
0.0221584026149
>>> print ephem.degrees(peri_angle * 2)
1:16:10.50
You may find that your angle arithmetic often returns angles that are less than zero or that exceed twice pi. You can access the norm attribute of an angle to force it into this range:
>>> deg = ephem.degrees
>>> print deg(deg('270') + deg('180'))
450:00:00.00
>>> print deg(deg('270') + deg('180')).norm
90:00:00.00

Computing With Dates

PyEphem stores dates as the number of days since noon on 1899 December 31. While you will probably not find the absolute value of this number very interesting, the fact that it is counted in days means you can move one day forward or backward by adding or subtracting one. The rules described above for angles hold for floats as well: you can create them with ephem.Date(), but after doing arithmetic on them you must pass them back through ephem.Date() to turn them back into dates:
>>> d = ephem.date('1950/2/28')
>>> print d + 1
18321.5
>>> print ephem.date(d + 1)
1950/3/1 00:00:00
The ephem module provides three constants hour, minute, and second, which can be added or subtracted from dates to increment or decrement them by the desired amount.

You can specify dates in several formats; not only can the strings that specify them use either floating point days or provide hours, minutes, and seconds, but you can also provide the components of the date in a tuple. Note that PyEphem does not deal with time zones — use the standard time module to convert between your local time and the Universal time used by PyEphem, which you can generate by calling gmtime() and give the first six elements it returns to PyEphem. The following assignments are all equivalent:

>>> d = ephem.date(34530.34375)
>>> d = ephem.date('1994/7/16.84375')
>>> d = ephem.date('1994/7/16 20:15')
>>> d = ephem.date((1994, 7, 16.84375))
>>> d = ephem.date((1994, 7, 16, 20, 15, 0))
And to complement the fact that you can specify dates as a tuple, two methods are provided for extracting the date as a tuple: triple() returns a year, month, and floating point day, while tuple() provides everything down to floating point seconds. After any of the above calls, the date can be examined as:
>>> print 'as a float: %f\nas a string: "%s"' % (d, d)
as a float: 34530.343750
as a string: "1994/7/16 20:15:00"
>>> print d.triple()
(1994, 7, 16.84375)
>>> print d.tuple()
(1994, 7, 16, 20, 15, 0.0)
Any PyEphem function argument that requires an angle or date will accept any of the representations shown above; so you could, for instance, give a three-element tuple directly to compute() for the date, rather than having to pass the tuple through the date() function before using it (though the latter approach would also work).

Computations for Particular Observers

The examples so far have determined the position of bodies against the background of stars, and their location in the solar system. But to observe a body we need to know more — whether it is visible from our latitude, when it rises and sets, and the height it achieves above our horizon. In return for this more detailed information, PyEphem quite reasonably demands to know our position on the earth's surface; we can provide this through an object called an Observer:
>>> gatech = ephem.Observer()
>>> gatech.long, gatech.lat = '-84.39733', '33.775867'
When the Observer is provided to compute() instead of a date and epoch, PyEphem has enough information to determine where in the sky the body appears. Fill in the date and epoch fields of the Observer with the values you would otherwise provide to compute(); the epoch defaults to the year 2000 if you do not set it yourself. As an example, we can examine the 1984 eclipse of the sun from Atlanta:
>>> gatech.date = '1984/5/30 16:22:56'   # 12:22:56 EDT
>>> sun, moon = ephem.Sun(), ephem.Moon()
>>> sun.compute(gatech), moon.compute(gatech)
>>> print sun.alt, sun.az
70:08:39.19 122:11:26.44
>>> print moon.alt, moon.az
70:08:39.46 122:11:26.04
For those unfamiliar with azimuth and altitude: they describe position in the sky by measuring angle around the horizon, then angle above the horizon. To locate the Sun and Moon in this instance, you would begin by facing north and then turn right 122°, bringing you almost around to the southeast (which lies 125° around the sky from north); and by looking 70° above that point on the horizon — fairly high, given that 90° is directly overhead — you would find the Sun and Moon.

Eclipses are classified as partial when the Moon merely takes a bite out of the Sun; annular when the Moon passes inside the disc of the sun to leave only a brilliant ring (Latin annulus) visible; and total when the moon is large enough to cover the Sun completely. To classify this eclipse we must compare the size of the Sun and Moon to the distance between them. Since each argument to separation() can be an arbitrary measure of spherical longitude and latitude, we can provide azimuth and altitude:

>>> print ephem.separation((sun.az, sun.alt), (moon.az, moon.alt))
0:00:00.30
>>> print sun.size, moon.size, sun.size - moon.size
1892.91210938 1891.85778809 1.05432128906
The Sun's diameter is larger by 1.05′′, so placing the Moon at its center would leave an annulus of width 1.05′′ / 2 = 0.52′′ visible around the Moon's edge. But in fact the center of the Moon lies 0.48 arc seconds towards one edge of the sun — not enough to move its edge outside the sun and make a partial eclipse, but enough to make a quite lopsided annular eclipse, whose annulus is 0.52′′ + 0.48 = 1.00′′ wide on one side and a scant 0.52′′ - 0.48 = 0.04′′ on the other.

The sky positions computed by PyEphem take into account the refraction of the atmosphere, which bends upwards the images of bodies near the horizon. During sunset, for example, the descent of the sun appears to slow because the atmosphere bends its image upwards as it approaches the horizon:

>>> gatech.date = '1984/5/31 00:00'   # 20:00 EDT
>>> sun.compute(gatech)
>>> for i in range(8):
...     old_az, old_alt = sun.az, sun.alt
...     gatech.date += ephem.minute * 5.
...     sun.compute(gatech)
...     sep = ephem.separation((old_az, old_alt), (sun.az, sun.alt))
...     print gatech.date, sun.alt, sep
1984/5/31 00:05:00 6:17:36.84 1:08:48.09
1984/5/31 00:10:00 5:21:15.64 1:08:36.29
1984/5/31 00:15:00 4:25:31.56 1:08:19.95
1984/5/31 00:20:00 3:30:34.23 1:07:56.53
1984/5/31 00:25:00 2:36:37.80 1:07:22.73
1984/5/31 00:30:00 1:44:04.64 1:06:32.20
1984/5/31 00:35:00 0:53:28.73 1:05:17.01
1984/5/31 00:40:00 0:05:37.82 1:03:28.31
We see that the Sun's apparent angular speed indeed decreased as it approached the horizon, from around 1°08′ to barely 1°03′ each five minutes.

Since atmospheric refraction varies with temperature and pressure, you can improve the accuracy of PyEphem by providing these values from a local forecast, or at least from average values for your location and season. By default an Observer uses 15°C and 1010 mB, the values for these parameters at sea level in the standard atmosphere model used in aviation. Setting the pressure to zero directs PyEphem to simply ignore atmospheric refraction.

Once PyEphem knows your location it can also work out when bodies rise, cross your meridian, and set each day. These computations can be fairly involved, since planets continue their journey among the stars even as the rotation of the earth brings them across the sky; PyEphem has to internally re-compute their position several times before it finds the exact circumstances of rising or setting. But this is taken care of automatically, leaving you to simply ask:

>>> print sun.set_time, sun.set_az
1984/5/31 00:40:36 297:05:57.36
This agrees with the list of altitudes we generated above, which placed the sun at nearly zero degrees altitude at 8:40 pm; the azimuth tells us exactly where on the horizon the sun set. You can similarly determine when and where a body rose by checking its rise_time and rise_az variables, and for the time and height of its transit across your meridian with transit_time and transit_alt.

Note that these risings and settings are those for the date you have specified in the Observer for which you asked the body to compute its position. If between midnight and midnight on that day a body happens not to rise, set, or transit, the corresponding events will simply return None for their values:

>>> print moon.rise_time, moon.transit_time, moon.set_time
1984/5/30 10:23:13 1984/5/30 17:36:40 None
Remember that PyEphem counts days from one midnight UTC to the next. If you are in another time zone you will probably want to retrieve the risings and settings from two adjacent UTC days and use the ones that fall around the period when you will be observing.

Loading Bodies From Catalogues

So far we have dealt with the planets, the Sun, and the Moon — major bodies whose orbits PyEphem already knows in great detail. But for minor bodies, like comets and asteroids, you must aquire and load the orbital parameters yourself.

Understand that because the major planets constantly perturb the other bodies in the solar system, including each other, it requires great effort — years of observation yielding formulae with dozens or hundreds of terms — to predict the position of a body accurately over decades or centuries. For a comet or asteroid, astronomers find it more convenient to describe its orbit as perfect ellipse, parabola, or hyperbola, and then issue new orbital parameters as its orbit changes.

The PyEphem home page provides links to several online catalogues of orbital elements. Once you have obtained elements for a particular body, simply provide them to PyEphem's readdb() function in ephem database format and the resulting object is ready to use:

>>> yh = ephem.readdb("C/2002 Y1 (Juels-Holvorcem),e,103.7816," +
...    "166.2194,128.8232,242.5695,0.0002609,0.99705756,0.0000," +
...    "04/13.2508/2003,2000,g  6.5,4.0")
>>> yh.compute('2003/4/11')
>>> print yh.name
C/2002 Y1 (Juels-Holvorcem)
>>> print yh.ra, yh.dec
0:22:36.80 26:48:57.52
>>> print ephem.constellation(yh), yh.mag
('And', 'Andromeda') 5.96
(Unfortunately the library upon which PyEphem is build truncates object names to twenty characters, as you can see.) Each call to readdb() returns an object appropriate for the orbit specified in the database entry; in this case it has returned an EllipticalBody:
>>> print yh
<ephem.EllipticalBody 'C/2002 Y1 (Juels-Holvorcem)' at 0x81ae358>
For objects for which you cannot find an entry in ephem database format, you can always create the appropriate kind of object and then fill in its orbital parameters yourself; see below for their names and meanings. By calling the writedb() function of a PyEphem object, you can even get it to generate its own database entry for archiving or distribution.

There is one other database format with which PyEphem is familiar: the NORAD Two-Line Element format (TLE) used for earth satellites. Here are some recent elements for the International Space Station.

>>> iss = ephem.readtle("ISS (ZARYA)",
...  "1 25544U 98067A   03097.78853147  .00021906  00000-0  28403-3 0  8652",
...  "2 25544  51.6361  13.7980 0004256  35.6671  59.2566 15.58778559250029")
>>> gatech.date = '2003/3/23'
>>> iss.compute(gatech)
>>> print iss.rise_time, iss.transit_time, iss.set_time
2003/3/23 00:00:44 2003/3/23 00:03:22 2003/3/23 00:06:00
Note that earth satellites are fast movers — in this case rising and setting in less than six minutes! They can therefore have multiple risings and settings each day, and the particular ones you get from rise_time and set_time depend on the particular time of day for which you ask. Repeating the above query eight hours later gives complete different results:
>>> gatech.date = '2003/3/23 8:00'
>>> iss.compute(gatech)
>>> print iss.rise_time, iss.transit_time, iss.set_time
2003/3/23 08:03:41 2003/3/23 08:08:29 2003/3/23 08:13:16
When calling compute() for an earth satellite you should provide an Observer, and not simply a date and epoch, since its location is entirely dependent upon the location from which you are observing. PyEphem provides extra information about earth satellites, beyond the ones available for other objects; see below for details.

Fixed Objects, Precession, and Epochs

We will start with the simplest: those for which a fixed right ascension and declination are specified. These include stars, nebulae, global clusters, and galaxies. One example is Polaris, the North Star, which lies at the end of Ursa Minor's tail:
>>> polaris = ephem.readdb("Polaris,f|M|F7,2:31:48.704,89:15:50.72,2.02,2000")
>>> print polaris.dec
RuntimeError: field dec undefined until first compute()
We are able to create the object successfully — why should asking its position raise a runtime error? The reason is that fixed objects, like planets, have an undefined position and magnitude until you call their compute() method to determine their position for a particular date or Observer:
>>> polaris.compute()    # uses the current time by default
>>> print polaris.dec
89:15:50.73
>>> print ephem.degrees(ephem.degrees('90') - polaris.dec)
0:44:09.27
Much better; we see that the ‘North Star’ lies less than forty-five arc minutes from the pole. But why should we have to call compute() for something fixed — something whose position is considered permanent, and which should not move between one date and another?

The reason is that, while ‘fixed’ stars and nebulae are indeed nearly motionless over the span of human civilization, the coordinate system by which we designate their positions changes more rapidly. Right ascension and declination are based upon the orientation of the earth's pole — but it turns out that the pole slowly revolves (around the axis of the ecliptic plane) like the axis of a whirling top, completing each revolution in roughly 25,800 years. This motion is called precession. Because this makes the entire coordinate system shift slightly every year, is not sufficient to state that Polaris lies at 2h31m right ascension and 89:15° declination; you have to say in which year.

That is why the Polaris entry above ends with 2000 — this gives the year for which the coordinates are correct, called the epoch of the coordinates. Because the year 2000 is currently a very popular epoch for quoting positions and orbital parameters, compute() uses it by default; but we can provide an epoch= keyword parameter to have the coordinates translated into those for another year:

>>> polaris.compute(epoch='2100')
>>> print polaris.dec
89:32:26.08
Thus we see that in another hundred years Polaris will actually lie closer to the pole that it does today. (The '2100' is the same year/month/day format you have seen already, missing both its month and day because we are not bothering to be that specific.) If you enter subsequent years you will find that 2100 is very nearly the closest approach of the pole to Polaris, and that soon afterwards they move apart. For much of the twenty-five thousand year journey the pole makes, there are no stars very near; we may have been lucky to have held the Age of Exploration as the pole was approaching as convenient a star as Polaris.

Today a dim star in Draco named Thuban lies more than twenty degrees from the pole:

>>> thuban = ephem.readdb("Thuban,f|V|A0,14:4:23.3,64:22:33,3.65,2000")
>>> thuban.compute()
>>> print thuban.dec
64:22:32.99
But in 2801 BC as the Egyptians built the pyramids, Thuban served as their pole star, while Polaris lay further from their pole than Thuban lies from ours today:
>>> thuban.compute(epoch='-2800')
>>> print thuban.dec
89:54:34.97
>>> polaris.compute(epoch='-2800')
>>> print polaris.dec
63:33:17.63
Realize that in these examples I have been lazy by giving compute() an epoch without an actual date, which requests the current position of each star in the coordinates of another epoch. This makes no difference for these fixed objects, since their positions never change; but when dealing with moving objects one must always keep in mind the difference between the date for which you want their position computed, and the epoch in which you want those coordinates expressed. Here are some example compute() calls, beginning with one like the above but for a moving object: When planning to observe with an equatorial telescope, you may want to use the current date as your epoch, because the rotation of the sky above your telescope is determined by where the pole points today, not where it pointed in 2000 or some other convenient epoch. Computing positions in the epoch of their date is accomplished by simply providing the same argument for both date and epoch:
>>> j = ephem.Jupiter()
>>> j.compute(epoch=ephem.now())   # so both date and epoch are now
>>> print j.ra, j.dec
8:44:29.49 19:00:10.23
>>> j.compute('2003/3/25', epoch='2003/3/25')
>>> print j.ra, j.dec
8:43:32.82 19:03:32.46
Be careful when computing distances; comparing two positions in the coordinates of their own epochs will give slightly different results than if the two were based on the same epoch:
>>> j1, j2 = ephem.Jupiter(), ephem.Jupiter()
>>> j1.compute('2003/3/1')
>>> j2.compute('2003/4/1')
>>> print ephem.separation(j1, j2)    # coordinates are both epoch 2000
1:46:35.90
>>> j1.compute('2003/3/1', '2003/3/1')
>>> j2.compute('2003/4/1', '2003/4/1')
>>> print ephem.separation(j1, j2)    # coordinates are both epoch-of-date
1:46:31.56
Comparing coordinates of the same epoch, as in the first call above, measures motion against the background of stars; comparing coordinates from different epochs, as in the second call, measures motion against the slowly shifting coordinate system of the earth. Users are most often interested in the first kind of measurement, and stick with a single epoch the whole way through a computation.

It was for the sake of simplicity that all of the examples in this section simply provided dates as arguments to the compute() function. If you are instead using an Observer argument, then you specify the epoch through the observer's epoch variable, not through the epoch= argument. Observers use epoch 2000 by default.

Finally, make sure you understand that your choice of epoch only affects absolute position — the right ascension and declination returned for objects — not the azimuth and altitude of an object above an observer. This is because the sun will hang in the same position over Atlanta whether the star atlas with which you plot its position has epoch 2000, or 1950, or even 1066 coordinates; the epoch only affects how you name locations in the sky, not how they are positioned with respect to you.


The PyEphem Reference

1. Module Contents: Astronomical Objects.

Sun() Moon() Mercury() Venus() Mars() Jupiter() Saturn() Uranus() Neptune() Pluto()
Phobos() Deimos()
Io() Europa() Ganymede() Callisto()
Mimas() Enceladus() Tethys() Dione() Rhea() Titan() Hyperion() Iapetus()
Ariel() Umbriel() Titania() Oberon() Miranda()
These calls each create and return an instance of a major solar-system body, whose position PyEphem knows how to compute using high accuracy formulae and series. Any of these functions can be given arguments, which will be used to call the compute() method of the new object before it is returned to you. (Only Saturn and the Moon are actual type objects; the others return instances of either the Planet or PlanetMoon types.)
FixedBody() EllipticalBody() ParabolicBody() HyperbolicBody() EarthSatellite()
Calling one of these type objects creates a blank and uninitialized body whose orbital elements must be filled in before use; see below for the orbital elements required for each type of body.
readdb(line)
Parse an entry from an XEphem database file and return an instance of the object it describes. If an error is encountered parsing the database line, ValueError is raised. The type of the returned object will be one of the five listed above, with all of its orbital elements already set.
readtle(name, line1, line2)
This function parses an earth satellite description that is in the Two-Line Element format used by NORAD, and returns the result as an EarthSatellite.
Observer()
This returns an Observer object with which the user can describe a position on the Earth's surface together with the atmospheric conditions. See below for the fields supported by these objects, which can be passed to the compute() method of any body.

2. Module Contents: Angles and Times

Every ephem object and method that returns an angle will return a floating point number giving the angle in radians, but which if subjected to either str() or to printing will format itself as traditional degrees or hours of right ascension like '7:45:45.15'. But since any mathematics performed upon an angle will return a normal Python float, the following functions are useful:
degrees(radians_float)
degrees(degrees_string)
Returns an angle as a floating point number of radians which formats itself as degrees of arc when printed or subjected to str(). It can be initialized directly with a float in radians, or with a string expressing degrees in sexigesimal format like '33:44:56' or as a decimal like '33.7489'. Strings produced by the angle are always sexigesimal.
hours(radians_float)
hours(hours_string)
Like the above function except that the string taken as input, returned by str(), or printed, uses hours of arc (of which there are twenty-four in a circle).
Angle arithmetic may result in angles less than zero or greater than twice pi; if you want your result normalized to within this range, access the norm attribute:
angle.norm — Returns the angle normalized to the interval [0, 2π).
Dates are stored as the number of days since noon on 1899 December 31, and like angles yield simple floats when used in computations. Dates can be created in several ways:
now()
date(raw_float)
date('yyyy.y')
date('yyyy/mm/dd.d')
date('yyyy/mm/dd hh.h')
date('yyyy/mm/dd hh/mm.m')
date('yyyy/mm/dd hh/mm/ss.s')
date((yyyy,))
date((yyyy, mm))
date((yyyy, mm, dd.d))
date((yyyy, mm, dd, hh.h))
date((yyyy, mm, dd, hh, mm.m))
date((yyyy, mm, dd, hh, mm, ss.s))
In addition to using dates as floats, and as strings through str() and print, they can be extracted in two other forms:
date.triple() — Returns the date as (year, month, day.fraction).
date.tuple() — Returns the date as (year, month, day, hour, minute, second.fraction).
Three constants are provided to help increment and decrement dates:
hour = one twenty-fourth of a day
minute = one sixtieth of an hour
second = one sixtieth of a minute

3. Module Contents: Functions

constellation(body)
constellation((ra, dec))
constellation((ra, dec), epoch=epoch)
Determines the constellation in which the given body or coordinates lie. If you provide coordinates without an epoch, then epoch 2000 is assumed.
delta_t(date)
delta_t(observer)
delta_t()
Return for the given date the offset between Terrestrial Time and Universal Time. The former marches forward with equal-length days regardless of the behavior of the Earth, while the latter is constantly tweaked and adjusted through leap seconds to follow the Earth's actual rotation. If given an Observer object, the function uses observer.date, and if given no argument it uses now().
julian_date(date)
julian_date(observer)
julian_date()
Return the Julian Date for the given PyEphem date object. If given an Observer, the function uses observer.date, and if given no argument it uses now(). (The Julian Date is the number of days that have elapsed since noon Universal Time on Monday, January 1, 4713 BC.)
millennium_atlas(ra, dec)
uranometria(ra, dec)
uranometria2000(ra, dec)
These three functions return the page number on which a particular right ascension and declination fall in each of three star atlases:

Millennium Star Atlas by Roger W. Sinnott and Michael A. C. Perryman
Uranometria by Johannes Bayer
Uranometria 2000.0 edited by Wil Tirion

moon_phases(date)
moon_phases(observer)
moon_phases()
Given a date, returns a dictionary {'new': new_date, 'full': full_date} giving the dates of a consecutive new and full moon that are near the date you specified. If given an Observer object it uses observer.date, and if given no argument, uses now().
separation(position0, position1)
Returns the angle in degrees between two positions on a sphere. Each position should be a coordinate pair whose first element measures angle around the sphere's equator, and whose second specifies angle above or below its equator. (Common examples of such pairs are right ascension and declination, and longitude and latitude.) While each coordinate pair can simply be a sequence of two floats, you can also submit an Observer, whose longitude and latitude will be used, or a celestial body, whose right ascension and declination will be used.

4. Observer Objects

All of these values can be set by the user; default values are shown in parentheses.

observer.date — the date for which the position should be computed (current time)
observer.epoch — epoch for which coordinates should be generated (year 2000)
observer.long, observer.lat — location of the observer on the earth; longitude should be positive for east and negative west, and latitude should be positive north and negative south
observer.elev — elevation above sea level in meters (0 m)
observer.temp — temperature in degrees centigrade (15°C)
observer.pressure — atmospheric pressure in milibars (1010 mB)
observer.horizon — at what angle you consider an object to be rising or setting (0°)

The temp and pressure are used to estimate how the object's position will be distorted by the atmosphere when it is close to the horizon; setting pressure to zero makes PyEphem ignore atmospheric refraction. The horizon value sets how far above (for positive angles) or below (for negative ones) the horizon an object needs to appear for you to consider it at the point of rising or setting; normally this is set to zero, meaning that rising and setting times tell you when an object appears exactly at the horizon.

Observers support two functions:

sidereal_time()
Returns the sidereal time for the observer's date and location.
radec_of(az=azimuth, alt=altitude)
Given a point in the sky above the observer specified by its azimuth (angle east of north) and altitude (angle above the horizon), return the right ascension and declination that lie at the point.

5. Body Methods

body.compute()
body.compute(date)
body.compute(epoch=epoch)
body.compute(date, epoch=epoch)
body.compute(observer)
Computes the position of the body for a particular date and in the equatorial coordinates of a particular epoch, and stores the result in the attributes listed above. The first four forms are geocentric and determine the object's position from the center of the earth; if date is not specified, the current time is used, while an unspecified epoch defaults to year-2000. The last form is topocentric and determines the object's position above the particular location on the earth's surface specified by the observer, and for the time and epoch it specifies.
body.writedb()
This returns a string representing the object in ephem database format; you can recreate the object at any later time by submitting this string to the module's readdb() function.
body.copy()
Returns a new copy of the body.

6. Body Attributes

These attributes present the results of the most recent compute() that you have performed on a body. The units of each attribute are shown in parenthesis.
Position
body.ra — right ascension (radians that print as hours of arc)
body.dec — declination (radians that print as degrees)
body.elong — angular distance from the sun (radians that print as degrees)
body.mag — visual magnitude
body.size — visual size (arc seconds)
Position Relative to an Observer
These are only available when you provided an Observer to compute().
body.az — azimuth, measured east from true north (radians that print as degrees)
body.alt — altitude above the horizon (radians that print as degrees)

body.circumpolar — whether the body remains up all day (boolean)
body.neverup — whether the body never rises above the horizon (boolean)

body.rise_time — the time at which the body rises
body.rise_az — the position on the horizon where the body rises (radians that print as degrees)
(these are both None on days the body does not rise)

body.transit_time — the time at which the body transits
body.transit_alt — the altitude at which the body transits (radians that print as degrees)
(these are both None on days the body does not transit)

body.set_time — the time at which the body sets
body.set_az — the position on the horizon where the body sets (radians that print as degrees)
(these are both None on days the body does not set)
Position in the Solar System
These are available for all bodies that orbit the Sun.
body.hlong — heliocentric longitude (radians that print as degrees)
body.hlat — heliocentric latitude (radians that print as degrees)
body.sun_distance — distance from the sun (AU)
body.earth_distance — distance from earth (AU)
body.phase — percent of the body illuminated when viewed from earth
Saturn Attributes
body.earth_tilt — tilt of rings toward Earth (radians that print as degrees)
body.sun_tilt — tilt of rings toward the Sun (radians that print as degrees)
(these are positive for a southward tilt and negative for northward)
Attributes of Earth's Moon
body.moon_phase — the fraction of the lunar surface that appears illuminated from the earth (this value will probably be more accurate than the phase attribute the Moon shares with other Planet objects)
body.colong — the co-longitude of (360° minus) the lunar meridian experiencing sunrise (radians that print as degrees)
body.subsolar_lat — the lunar latitude at which the Sun is overhead (radians that print as degrees)
body.libration_lat, body.libration_long — the latitude and longitude of the point on the lunar surface facing the earth (radians that print as degrees)
Attributes of other moons
body.x, body.y, body.z — where the moon lies in the sky with respect to its planet, measured in planet radii; x gives the distance east or west (east is positive), y gives the distance north or south (south is positive), and z indicates distance toward or away from the Earth relative to the distance of its planet (closer to Earth is positive)
body.earth_visible — whether the moon is visible from Earth (boolean)
body.sun_visible — whether the moon is visible from the Sun (boolean)
Earth Satellite Attributes
body.catalog_number — if the satellite was created with readtle(), this gives the integer catalog number of the source TLE entry
body.sublat, body.sublong — the point on Earth above which the satellite is positioned (radians that print as degrees)
body.elevation — height of the satellite above sea level (meters)
body.range — distance between the observer and the satellite (meters)
body.range_velocity — rate at which the distance between the observer and the satellite is changing (meters per second)
body.eclipsed — whether the satellite lies in the shadow of Earth (boolean)

7. Orbital Elements

Bodies with supplied orbital elements can be of any of the following types; you can create such bodies either by submitting an ephem database entry to ephem.readdb() or by creating one of these objects directly and filling in the properties of its orbit. Orbital elements always begin with an underscore to prevent their being confused with normal object attributes.
Fixed Object Elements (FixedBody)
body._class — a character in which to store the classification of the fixed object
body._spect — a two-character string where you can store the spectral code
body._ratio — the ratio between the major and minor diameters
body._pa — the angle at which the major axis lies in the sky, in degrees east of north
body._epoch — the epoch of the position
body._ra, body._dec — position in hours and degrees respectively
Elliptical Orbital Elements (EllipticalBody)
body._inc — inclination in degrees
body._Om — longitude of ascending node in degrees
body._om — argument of perihelion in degrees
body._a — mean distance from sun in AU
body._M — mean anomaly in degrees from perihelion at _epoch_M
body._epoch_M — epoch date for _M
body._size — angular size in arc seconds at 1 AU
body._e — eccentricity
body._epoch — equinox year for _inc, _Om, and _om
body._H, body._G — parameters for the H/G magnitude model
body._g, body._k — parameters for the g/k magnitude model
Hyperbolic Orbital Elements (HyperbolicBody)
body._epoch — equinox year for _inc, _Om, and _om
body._epoch_p — epoch of perihelion
body._inc — inclination in degrees
body._Om — longitude of ascending node in degrees
body._om — argument of perihelion in degrees
body._e — eccentricity
body._q — perihelion distance in AU
body._g, body._k — magnitude model coefficients
body._size — angular size in arcseconds at 1 AU
Parabolic Orbital Elements (ParabolicBody)
body._epoch — equinox year for _inc, _Om, and _om
body._epoch_p — epoch of perihelion
body._inc — inclination in degrees
body._Om — longitude of ascending node in degrees
body._om — argument of perihelion in degrees
body._q — perihelion distance in AU
body._g, body._k — magnitude model coefficients
body._size — angular size in arcseconds at 1 AU
Earth Satellite Orbital Elements (EarthSatellite)
body._epoch — reference epoch
body._n — mean motion in revolutions per day
body._inc — inclination in degrees
body._raan — right ascension of ascending node in degrees
body._e — eccentricity
body._ap — argument of perigee at epoch in degrees
body._M — mean anomaly in degrees from perigee at epoch
body._decay — orbit decay rate in revolutions per day, per day
body._drag — object drag coefficient in per earth radii
body._orbit — integer orbit number of epoch