Search code examples
pythonastronomypyephem

PyEphem Angle Clarification


I'd just like to make sure I understand what PyEphem is doing with angles.

Let's say I have an observer at 30° S, 60° W looking at the sky today at noon. So I do:

obs = ephem.Observer()
obs.lat, obs.lon = '-30', '-60'
obs.date = '2012/6/22 12:00:00'

Now I want to find which part of the celestial sphere (in RA and declination) the observer sees when looking at a certain azimuth and altitude. I can do:

obs.radec_of(az,alt)

Here is where I'm confused. From what I understand, PyEphem works with all angles as radians, so I should put az and alt in as radians. Is it the case, then, that 0° altitude is the horizon, 90° altitude is directly overhead, and -90° is pointing straight into the ground? In which case, does PyEphem consider 95° altitude to be the same as 85° or does it roll over into -85°?

Also, if the observer wants to look at the south celestial pole, is this the correct code?

az = float( ephem.degree('180') )
alt = float( ephem.degree('30') )
ra, dec = obs.radec_of(az,alt)

Or should the altitude be -30°?


Solution

  • Your understanding of altitude and azimuth sounds correct! The south celestial pole indeed lies 30° above the southern horizon for someone at 30° south latitude, exactly as you describe.

    But there are one or two fixes that we can make to your code.

    First, a misspelling. The function you are looking for that converts degrees to radians is named ephem.degrees() (note that plural) — if you try calling ephem.degree as a function, then you will get the exception:

    TypeError: 'float' object is not callable
    

    because ephem.degree is actually the floating-point number 0.0174532925199 because that is how many radians are in a degree. And you cannot call a floating-point number as though as it is a function! Fixing that, we get correct and working code for your example:

    az = float(ephem.degrees('180'))
    alt = float(ephem.degrees('30'))
    ra, dec = obs.radec_of(az,alt)
    print ra, dec
    
    → 12:30:10.05 -89:53:54.7
    

    But we can make the code even simpler!

    First, the return value of ephem.degrees() is already a floating-point number, so the float() call around it is not actually necessary; you can just say:

    az = ephem.degrees('180')
    alt = ephem.degrees('30')
    

    and those two values are just fine as the arguments to radec_of(). In fact, you can do even better: because the radec_of() function knows that azimuth and altitude are traditionally given in degrees, you can just hand the strings to the function itself and it will assume that the numbers inside of your strings are written in degrees. So we can eliminate the az and alt variables entirely if we want and just say:

    ra, dec = obs.radec_of('180', '30')
    

    Finally, you might wonder why the RA and declination we got back were not quite exactly at the south pole, even though they were close.

    The first reason is that PyEphem takes account of atmospheric refraction, which boosts the apparent altitude of an object above the horizon at low altitudes. If we tell the Observer object to ignore atmospheric effects (by telling it there is no air where we live — atmospheric pressure zero), then the return value will be even closer to the south pole:

    obs.pressure = 0
    ra, dec = obs.radec_of('180', '30')
    print ra, dec
    
    → 12:24:25.48 -89:55:15.9
    

    That, obviously, gets us closer. There are one or two issues left involving precession and perhaps even nutation, that we need to tackle to actually drive the declination down to a full –90°, but I will have to look at them in the morning when I can visualize angles better!