Example #1
0
def nu2000k(jd_high, jd_low):
    """
    Computes the forced nutation of the non-rigid Earth: Model NU2000K.
    This model is a modified version of IAU 2000A, which has been
    truncated for speed of execution, and uses Simon et al. (1994)
    fundamental arguments throughout.NU2000K agrees with IAU 2000A at
    the 0.1 milliarcsecond level from 1700 to 2300.

    Parameters
    ----------
    jd_high : float
        High-order part of TT Julian date.
    jd_low : float
        Low-order part of TT Julian date.

    Returns
    -------
    (dpsi, deps) : tuple of floats
        Nutation (luni-solar + planetary) in (longitude, obliquity)
        in radians.

    Notes
    -----
    .. [N1] NU2000K was compared to IAU 2000A over six centuries
        (1700-2300). The average error in dpsi is 20
        microarcseconds, with 98% of the errors < 60
        microarcseconds;the average error in deleps is 8
        microarcseconds, with 100% of the errors < 60
        microarcseconds.
    .. [N2] NU2000K was developed by G. Kaplan (USNO) in March 2004.

    References
    ----------
    .. [R1] IERS Conventions (2003), Chapter 5.
    .. [R2] Simon et al. (1994) Astronomy and Astrophysics 282,
        663-683, esp. Sections 3.4-3.5.

    """

    if jd_high + jd_low < 0.0:
        raise ValueError(_neg_err.format(name="jd_high+jd_low"))

    _nu2000k = novaslib.nu2000k
    _nu2000k.argtypes = (
        ctypes.c_double,
        ctypes.c_double,
        ctypes.POINTER(ctypes.c_double),
        ctypes.POINTER(ctypes.c_double),
    )
    _nu2000k.restype = None

    dpsi = ctypes.c_double()
    deps = ctypes.c_double()

    _nu2000k(jd_high, jd_low, ctypes.byref(dpsi), ctypes.byref(deps))

    return (dpsi.value, deps.value)
Example #2
0
def nu2000k(jd_high, jd_low):
    """
    Computes the forced nutation of the non-rigid Earth: Model NU2000K.
    This model is a modified version of IAU 2000A, which has been
    truncated for speed of execution, and uses Simon et al. (1994)
    fundamental arguments throughout.NU2000K agrees with IAU 2000A at
    the 0.1 milliarcsecond level from 1700 to 2300.

    Parameters
    ----------
    jd_high : float
        High-order part of TT Julian date.
    jd_low : float
        Low-order part of TT Julian date.

    Returns
    -------
    (dpsi, deps) : tuple of floats
        Nutation (luni-solar + planetary) in (longitude, obliquity)
        in radians.

    Notes
    -----
    .. [N1] NU2000K was compared to IAU 2000A over six centuries
        (1700-2300). The average error in dpsi is 20
        microarcseconds, with 98% of the errors < 60
        microarcseconds;the average error in deleps is 8
        microarcseconds, with 100% of the errors < 60
        microarcseconds.
    .. [N2] NU2000K was developed by G. Kaplan (USNO) in March 2004.

    References
    ----------
    .. [R1] IERS Conventions (2003), Chapter 5.
    .. [R2] Simon et al. (1994) Astronomy and Astrophysics 282,
        663-683, esp. Sections 3.4-3.5.

    """

    if jd_high + jd_low < 0.0:
        raise ValueError(_neg_err.format(name='jd_high+jd_low'))

    _nu2000k = novaslib.nu2000k
    _nu2000k.argtypes = (ctypes.c_double, ctypes.c_double,
                         ctypes.POINTER(ctypes.c_double),
                         ctypes.POINTER(ctypes.c_double))
    _nu2000k.restype = None

    dpsi = ctypes.c_double()
    deps = ctypes.c_double()

    _nu2000k(jd_high, jd_low, ctypes.byref(dpsi), ctypes.byref(deps))

    return (dpsi.value, deps.value)
Example #3
0
def iau2000b(jd_high, jd_low):
    """
    Computes the forced nutation of the non-rigid Earth based on the
    IAU 2000B precession/nutation model.

    Parameters
    ----------
    jd_high : float
        High-order part of TT Julian date.
    jd_low : float
        Low-order part of TT Julian date.

    Returns
    -------
    (dpsi, deps) : tuple of floats
        Nutation (luni-solar + planetary) in (longitude, obliquity)
        in radians.

    Notes
    -----
    .. [N1] IAU 2000B reproduces the IAU 2000A model to a precision
        of 1 milliarcsecond in the interval 1995-2020.

    References
    ----------
    .. [R1] McCarthy, D. and Luzum, B. (2003). "An Abridged Model of
        the Precession & Nutation of the Celestial Pole," Celestial
        Mechanics and Dynamical Astronomy, Volume 85, Issue 1,
        Jan. 2003, p. 37. (IAU 2000B)
    .. [R2] IERS Conventions (2003), Chapter 5.

    """

    if jd_high + jd_low < 0.0:
        raise ValueError(_neg_err.format(name="jd_high+jd_low"))

    _iau2000b = novaslib.iau2000b
    _iau2000b.argtypes = (
        ctypes.c_double,
        ctypes.c_double,
        ctypes.POINTER(ctypes.c_double),
        ctypes.POINTER(ctypes.c_double),
    )
    _iau2000b.restype = None

    dpsi = ctypes.c_double()
    deps = ctypes.c_double()

    _iau2000b(jd_high, jd_low, ctypes.byref(dpsi), ctypes.byref(deps))

    return (dpsi.value, deps.value)
Example #4
0
def iau2000a(jd_high, jd_low):
    """
    Computes the forced nutation of the non-rigid Earth based on the
    IAU 2000A nutation model.

    Parameters
    ----------
    jd_high : float
        High-order part of TT Julian date.
    jd_low : float
        Low-order part of TT Julian date.

    Returns
    -------
    (dpsi, deps) : tuple of floats
        Nutation (luni-solar + planetary) in (longitude, obliquity)
        in radians.

    Notes
    -----
    .. [N1] The IAU 2000A nutation model is MHB_2000 without the
        free core nutation and without the corrections to Lieske
        precession.

    References
    ----------
    .. [R1] IERS Conventions (2003), Chapter 5.
    .. [R2] Simon et al. (1994) Astronomy and Astrophysics 282,
        663-683, esp. Sections 3.4-3.5.

    """

    if jd_high + jd_low < 0.0:
        raise ValueError(_neg_err.format(name="jd_high+jd_low"))

    _iau2000a = novaslib.iau2000a
    _iau2000a.argtypes = (
        ctypes.c_double,
        ctypes.c_double,
        ctypes.POINTER(ctypes.c_double),
        ctypes.POINTER(ctypes.c_double),
    )
    _iau2000a.restype = None

    dpsi = ctypes.c_double()
    deps = ctypes.c_double()

    _iau2000a(jd_high, jd_low, ctypes.byref(dpsi), ctypes.byref(deps))

    return (dpsi.value, deps.value)
Example #5
0
def iau2000b(jd_high, jd_low):
    """
    Computes the forced nutation of the non-rigid Earth based on the
    IAU 2000B precession/nutation model.

    Parameters
    ----------
    jd_high : float
        High-order part of TT Julian date.
    jd_low : float
        Low-order part of TT Julian date.

    Returns
    -------
    (dpsi, deps) : tuple of floats
        Nutation (luni-solar + planetary) in (longitude, obliquity)
        in radians.

    Notes
    -----
    .. [N1] IAU 2000B reproduces the IAU 2000A model to a precision
        of 1 milliarcsecond in the interval 1995-2020.

    References
    ----------
    .. [R1] McCarthy, D. and Luzum, B. (2003). "An Abridged Model of
        the Precession & Nutation of the Celestial Pole," Celestial
        Mechanics and Dynamical Astronomy, Volume 85, Issue 1,
        Jan. 2003, p. 37. (IAU 2000B)
    .. [R2] IERS Conventions (2003), Chapter 5.

    """

    if jd_high + jd_low < 0.0:
        raise ValueError(_neg_err.format(name='jd_high+jd_low'))

    _iau2000b = novaslib.iau2000b
    _iau2000b.argtypes = (ctypes.c_double, ctypes.c_double,
                          ctypes.POINTER(ctypes.c_double),
                          ctypes.POINTER(ctypes.c_double))
    _iau2000b.restype = None

    dpsi = ctypes.c_double()
    deps = ctypes.c_double()

    _iau2000b(jd_high, jd_low, ctypes.byref(dpsi), ctypes.byref(deps))

    return (dpsi.value, deps.value)
Example #6
0
def iau2000a(jd_high, jd_low):
    """
    Computes the forced nutation of the non-rigid Earth based on the
    IAU 2000A nutation model.

    Parameters
    ----------
    jd_high : float
        High-order part of TT Julian date.
    jd_low : float
        Low-order part of TT Julian date.

    Returns
    -------
    (dpsi, deps) : tuple of floats
        Nutation (luni-solar + planetary) in (longitude, obliquity)
        in radians.

    Notes
    -----
    .. [N1] The IAU 2000A nutation model is MHB_2000 without the
        free core nutation and without the corrections to Lieske
        precession.

    References
    ----------
    .. [R1] IERS Conventions (2003), Chapter 5.
    .. [R2] Simon et al. (1994) Astronomy and Astrophysics 282,
        663-683, esp. Sections 3.4-3.5.

    """

    if jd_high + jd_low < 0.0:
        raise ValueError(_neg_err.format(name='jd_high+jd_low'))

    _iau2000a = novaslib.iau2000a
    _iau2000a.argtypes = (ctypes.c_double, ctypes.c_double,
                          ctypes.POINTER(ctypes.c_double),
                          ctypes.POINTER(ctypes.c_double))
    _iau2000a.restype = None

    dpsi = ctypes.c_double()
    deps = ctypes.c_double()

    _iau2000a(jd_high, jd_low, ctypes.byref(dpsi), ctypes.byref(deps))

    return (dpsi.value, deps.value)
Example #7
0
def solarsystem_hp(tjd, body, origin):
    """
    Provides an interface between the JPL direct-access solar system
    ephemerides and NOVAS-C for highest precision applications.

    Parameters
    ----------
    tjd : tuple of floats, of length 2
        Two-element tuple containing the Julian date, which may be
        split any way (although the first element is usually the
        "integer" part, and the second element is the "fractional"
        part). Julian date is on the TDB or "T_eph" time scale.
    body : integer
        Body identification number for the solar system object of
        interest; Mercury = 1, ..., Pluto = 9, Sun = 10, Moon = 11.
    origin : integer
        Origin code
            = 0 ... solar system barycenter
            = 1 ... center of mass of the Sun
            = 2 ... center of Earth

    Returns
    -------
    position : tuple of floats, of length 3
        Position vector of 'body' at 'tjd'; equatorial rectangular
        coordinates in AU referred to the ICRS.
    velocity : tuple of floats, of length 3
        Velocity vector of 'body' at 'tjd'; equatorial rectangular
        system referred to the ICRS, in AU/day.

    Notes
    -----
    .. [N1] This function and function 'planet_ephemeris' were
        designed to work with the 1997 version of the JPL
        ephemerides, as noted in the references.
    .. [N2] The user must have a JPL binary ephemeris file (see
        package README) and open the file using function
        'ephem_open' prior to calling this function.
    .. [N3] This function supports the "split" Julian date feature
        of function 'planet_ephemeris' for highest precision. For
        usual applications, use function 'solarsystem'.

    References
    ----------
    .. [R1] JPL. 2007, "JPL Planetary and Lunar Ephemerides: Export
        Information," (Pasadena, CA: JPL)
        http://ssd.jpl.nasa.gov/?planet_eph_export.
    .. [R2] Kaplan, G. H. "NOVAS: Naval Observatory Vector
        Astrometry Subroutines"; USNO internal document dated 20 Oct
        1988; revised 15 Mar 1990.

    """

    if tjd < 0.0:
        raise ValueError(_neg_err.format(name='tjd'))
    if body not in list(range(1, 12)):
        raise ValueError(
            _option_err.format(name='body', allowed=list(range(1, 12))))
    if origin not in [0, 1, 2]:
        raise ValueError(_option_err.format(name='origin', allowed=[0, 1, 2]))

    _solarsystem_hp = novaslib.solarsystem_hp
    _solarsystem_hp.argtypes = (ctypes.c_double * 2, ctypes.c_short,
                                ctypes.c_short,
                                ctypes.POINTER(ctypes.c_double * 3),
                                ctypes.POINTER(ctypes.c_double * 3))
    _solarsystem_hp.restype = ctypes.c_short
    _solarsystem_hp.errcheck = _check_c_errors
    _solarsystem_hp.c_errors = {
        1:
        (ValueError,
         "from C function 'solarsystem_hp': Invalid value of body or origin."),
        2:
        (RuntimeError,
         "from C function 'solarsystem_hp': Error detected by JPL software.")
    }

    position = (ctypes.c_double * 3)()
    velocity = (ctypes.c_double * 3)()

    _solarsystem_hp((ctypes.c_double * 2)(*tjd), body, origin,
                    ctypes.byref(position), ctypes.byref(velocity))

    return tuple([i for i in position]), tuple([j for j in velocity])
Example #8
0
def state(jed, target):
    """
    This function reads and interpolates the JPL planetary ephemeris
    file.

    Parameters
    ----------
    jed : tuple of floats, of length 2
        Julian date (TDB) at which interpolation is wanted. Any
        combination of jed[0]+jed[1] which falls within the time
        span on the file is a permissible epoch. See Note [N1]_
        below.
    target : {0, ..., 10}
        The requested body to get data for from the ephemeris file.
        The designation of the astronomical bodies is:
            = 0 ... Mercury
            = 1 ... Venus
            = 2 ... Earth-Moon barycenter
            = 3 ... Mars
            = 4 ... Jupiter
            = 5 ... Saturn
            = 6 ... Uranus
            = 7 ... Neptune
            = 8 ... Pluto
            = 9 ... geocentric Moon
            = 10 ... Sun

    Returns
    -------
    target_pos : tuple of floats, of length 3
        The barycentric position vector array of the requested
        object, in AU.
    target_vel : tuple of floats, of length 3
        The barycentric velocity vector array of the requested
        object, in AU/Day.

        Both vectors are referenced to the Earth mean equator and
        equinox of epoch.

    Notes
    -----
    .. [N1] For ease in programming, the user may put the entire
        epoch in jed[0] and set jed[1] = 0. For maximum
        interpolation accuracy set jed[0] = the most recent midnight
        at or before interpolation epoch, and set jed[1] =
        fractional part of a day elapsed between jed[0] and epoch.
        As an alternative, it may prove convenient to set jed[0] =
        some fixed epoch, such as start of the integration and
        jed[1] = elapsed interval between then and epoch.

    References
    ----------
    .. [R1] Standish, E.M. and Newhall, X X (1988). "The JPL Export
        Planetary Ephemeris"; JPL document dated 17 June 1988.

    """

    if jed[0] + jed[1] < 0:
        raise ValueError(_neg_err.format(name='jed[0]+jed[1]'))
    if target not in list(range(0, 11)):
        raise ValueError(
            _option_err.format(name='target', allowed=list(range(0, 11))))

    _state = novaslib.state
    _state.argtypes = (ctypes.POINTER(ctypes.c_double * 2), ctypes.c_short,
                       ctypes.POINTER(ctypes.c_double * 3),
                       ctypes.POINTER(ctypes.c_double * 3))
    _state.restype = ctypes.c_short
    _state.errcheck = _check_c_errors
    _state.c_errors = {
        1: (IOError, "from C function 'state': error reading ephemeris file."),
        2: (ValueError, "from C function 'state': epoch out of range.")
    }

    target_pos = (ctypes.c_double * 3)()
    target_vel = (ctypes.c_double * 3)()

    _state(ctypes.byref((ctypes.c_double * 2)(*jed)), target,
           ctypes.byref(target_pos), ctypes.byref(target_vel))

    return tuple([i for i in target_pos]), tuple([j for j in target_vel])
Example #9
0
def planet_ephemeris(tjd, target, center):
    """
    This function accesses the JPL planetary ephemeris to give the
    position and velocity of the target object with respect to the
    center object.

    Parameters
    ----------
    tjd : tuple of floats, of length 2
        Julian date split into two parts. 'tjd' may be split any way
        (although the first element is usually the "integer" part,
        and the second element is the "fractional" part).  Julian
        date is in the TDB or "T_eph" time scale.
    target : {0, ..., 13}
        Number of 'target' point.
    center : {0, ..., 13}
        Number of 'center' (origin) point.

        The numbering convention for 'target' and'center' is:
            = 0 ... Mercury
            = 1 ... Venus
            = 2 ... Earth
            = 3 ... Mars
            = 4 ... Jupiter
            = 5 ... Saturn
            = 6 ... Uranus
            = 7 ... Neptune
            = 8 ... Pluto
            = 9 ... Moon
            = 10 ... Sun
            = 11 ... Solar system bary.
            = 12 ... Earth-Moon bary.
            = 13 ... Nutations (long int. and obliq.)
            (If nutations are desired, set 'target' = 13;
             'center' will be ignored on that call.)

    Returns
    -------
    position : tuple of floats, of length 3
        Position vector array of target relative to center, measured
        in AU.
    velocity : tuple of floats, of length 3
        Velocity vector array of target relative to center, measured
        in AU/day.

    References
    ----------
    .. [R1] Standish, E.M. and Newhall, X X (1988). "The JPL Export
        Planetary Ephemeris"; JPL document dated 17 June 1988.

    """

    if tjd[0] + tjd[1] < 0:
        raise ValueError(_neg_err.format(name='tjd[0]+tjd[1]'))
    if target not in list(range(0, 14)):
        raise ValueError(
            _option_err.format(name='target', allowed=list(range(0, 14))))
    if center not in list(range(0, 14)):
        raise ValueError(
            _option_err.format(name='center', allowed=list(range(0, 14))))

    _planet_ephemeris = novaslib.planet_ephemeris
    _planet_ephemeris.argtypes = (ctypes.c_double * 2, ctypes.c_short,
                                  ctypes.c_short,
                                  ctypes.POINTER(ctypes.c_double * 3),
                                  ctypes.POINTER(ctypes.c_double * 3))
    _planet_ephemeris.restype = ctypes.c_short
    _planet_ephemeris.errcheck = _check_c_errors
    _planet_ephemeris.c_errors = {
        1: (IOError, "from C function 'state': error reading ephemeris file."),
        2: (ValueError, "from C function 'state': epoch out of range.")
    }

    position = (ctypes.c_double * 3)()
    velocity = (ctypes.c_double * 3)()

    _planet_ephemeris((ctypes.c_double * 2)(*tjd), target, center,
                      ctypes.byref(position), ctypes.byref(velocity))

    return tuple([i for i in position]), tuple([j for j in velocity])
def state(jed, target):
    """
    This function reads and interpolates the JPL planetary ephemeris
    file.

    Parameters
    ----------
    jed : tuple of floats, of length 2
        Julian date (TDB) at which interpolation is wanted. Any
        combination of jed[0]+jed[1] which falls within the time
        span on the file is a permissible epoch. See Note [N1]_
        below.
    target : {0, ..., 10}
        The requested body to get data for from the ephemeris file.
        The designation of the astronomical bodies is:
            = 0 ... Mercury
            = 1 ... Venus
            = 2 ... Earth-Moon barycenter
            = 3 ... Mars
            = 4 ... Jupiter
            = 5 ... Saturn
            = 6 ... Uranus
            = 7 ... Neptune
            = 8 ... Pluto
            = 9 ... geocentric Moon
            = 10 ... Sun

    Returns
    -------
    target_pos : tuple of floats, of length 3
        The barycentric position vector array of the requested
        object, in AU.
    target_vel : tuple of floats, of length 3
        The barycentric velocity vector array of the requested
        object, in AU/Day.

        Both vectors are referenced to the Earth mean equator and
        equinox of epoch.

    Notes
    -----
    .. [N1] For ease in programming, the user may put the entire
        epoch in jed[0] and set jed[1] = 0. For maximum
        interpolation accuracy set jed[0] = the most recent midnight
        at or before interpolation epoch, and set jed[1] =
        fractional part of a day elapsed between jed[0] and epoch.
        As an alternative, it may prove convenient to set jed[0] =
        some fixed epoch, such as start of the integration and
        jed[1] = elapsed interval between then and epoch.

    References
    ----------
    .. [R1] Standish, E.M. and Newhall, X X (1988). "The JPL Export
        Planetary Ephemeris"; JPL document dated 17 June 1988.

    """

    if jed[0] + jed[1] < 0:
        raise ValueError(_neg_err.format(name='jed[0]+jed[1]'))
    if target not in list(range(0, 11)):
        raise ValueError(_option_err.format(name='target',
                                            allowed=list(range(0, 11))))

    _state = novaslib.state
    _state.argtypes = (ctypes.POINTER(ctypes.c_double*2), ctypes.c_short,
                       ctypes.POINTER(ctypes.c_double*3),
                       ctypes.POINTER(ctypes.c_double*3))
    _state.restype = ctypes.c_short
    _state.errcheck = _check_c_errors
    _state.c_errors = {
        1: (IOError, "from C function 'state': error reading ephemeris file."),
        2: (ValueError, "from C function 'state': epoch out of range.")
        }

    target_pos = (ctypes.c_double*3)()
    target_vel = (ctypes.c_double*3)()

    _state(ctypes.byref((ctypes.c_double*2)(*jed)), target,
           ctypes.byref(target_pos), ctypes.byref(target_vel))

    return tuple([i for i in target_pos]), tuple([j for j in target_vel])
def planet_ephemeris(tjd, target, center):
    """
    This function accesses the JPL planetary ephemeris to give the
    position and velocity of the target object with respect to the
    center object.

    Parameters
    ----------
    tjd : tuple of floats, of length 2
        Julian date split into two parts. 'tjd' may be split any way
        (although the first element is usually the "integer" part,
        and the second element is the "fractional" part).  Julian
        date is in the TDB or "T_eph" time scale.
    target : {0, ..., 13}
        Number of 'target' point.
    center : {0, ..., 13}
        Number of 'center' (origin) point.

        The numbering convention for 'target' and'center' is:
            = 0 ... Mercury
            = 1 ... Venus
            = 2 ... Earth
            = 3 ... Mars
            = 4 ... Jupiter
            = 5 ... Saturn
            = 6 ... Uranus
            = 7 ... Neptune
            = 8 ... Pluto
            = 9 ... Moon
            = 10 ... Sun
            = 11 ... Solar system bary.
            = 12 ... Earth-Moon bary.
            = 13 ... Nutations (long int. and obliq.)
            (If nutations are desired, set 'target' = 13;
             'center' will be ignored on that call.)

    Returns
    -------
    position : tuple of floats, of length 3
        Position vector array of target relative to center, measured
        in AU.
    velocity : tuple of floats, of length 3
        Velocity vector array of target relative to center, measured
        in AU/day.

    References
    ----------
    .. [R1] Standish, E.M. and Newhall, X X (1988). "The JPL Export
        Planetary Ephemeris"; JPL document dated 17 June 1988.

    """

    if tjd[0] + tjd[1] < 0:
        raise ValueError(_neg_err.format(name='tjd[0]+tjd[1]'))
    if target not in list(range(0, 14)):
        raise ValueError(_option_err.format(name='target',
                                            allowed=list(range(0, 14))))
    if center not in list(range(0, 14)):
        raise ValueError(_option_err.format(name='center',
                                            allowed=list(range(0, 14))))

    _planet_ephemeris = novaslib.planet_ephemeris
    _planet_ephemeris.argtypes = (ctypes.c_double*2, ctypes.c_short,
                                  ctypes.c_short,
                                  ctypes.POINTER(ctypes.c_double*3),
                                  ctypes.POINTER(ctypes.c_double*3))
    _planet_ephemeris.restype = ctypes.c_short
    _planet_ephemeris.errcheck = _check_c_errors
    _planet_ephemeris.c_errors = {
        1: (IOError, "from C function 'state': error reading ephemeris file."),
        2: (ValueError, "from C function 'state': epoch out of range.")
        }

    position = (ctypes.c_double*3)()
    velocity = (ctypes.c_double*3)()

    _planet_ephemeris((ctypes.c_double*2)(*tjd), target, center,
                      ctypes.byref(position), ctypes.byref(velocity))

    return tuple([i for i in position]), tuple([j for j in velocity])
Example #12
0
def solarsystem_hp(tjd, body, origin):
    """
    Provides an interface between the JPL direct-access solar system
    ephemerides and NOVAS-C for highest precision applications.

    Parameters
    ----------
    tjd : tuple of floats, of length 2
        Two-element tuple containing the Julian date, which may be
        split any way (although the first element is usually the
        "integer" part, and the second element is the "fractional"
        part). Julian date is on the TDB or "T_eph" time scale.
    body : integer
        Body identification number for the solar system object of
        interest; Mercury = 1, ..., Pluto = 9, Sun = 10, Moon = 11.
    origin : integer
        Origin code
            = 0 ... solar system barycenter
            = 1 ... center of mass of the Sun
            = 2 ... center of Earth

    Returns
    -------
    position : tuple of floats, of length 3
        Position vector of 'body' at 'tjd'; equatorial rectangular
        coordinates in AU referred to the ICRS.
    velocity : tuple of floats, of length 3
        Velocity vector of 'body' at 'tjd'; equatorial rectangular
        system referred to the ICRS, in AU/day.

    Notes
    -----
    .. [N1] This function and function 'planet_ephemeris' were
        designed to work with the 1997 version of the JPL
        ephemerides, as noted in the references.
    .. [N2] The user must have a JPL binary ephemeris file (see
        package README) and open the file using function
        'ephem_open' prior to calling this function.
    .. [N3] This function supports the "split" Julian date feature
        of function 'planet_ephemeris' for highest precision. For
        usual applications, use function 'solarsystem'.

    References
    ----------
    .. [R1] JPL. 2007, "JPL Planetary and Lunar Ephemerides: Export
        Information," (Pasadena, CA: JPL)
        http://ssd.jpl.nasa.gov/?planet_eph_export.
    .. [R2] Kaplan, G. H. "NOVAS: Naval Observatory Vector
        Astrometry Subroutines"; USNO internal document dated 20 Oct
        1988; revised 15 Mar 1990.

    """

    if tjd < 0.0:
        raise ValueError(_neg_err.format(name='tjd'))
    if body not in list(range(1, 12)):
        raise ValueError(_option_err.format(name='body',
                                            allowed=list(range(1, 12))))
    if origin not in [0, 1, 2]:
        raise ValueError(_option_err.format(name='origin',
                                            allowed=[0, 1, 2]))

    _solarsystem_hp = novaslib.solarsystem_hp
    _solarsystem_hp.argtypes = (ctypes.c_double*2, ctypes.c_short,
                                ctypes.c_short,
                                ctypes.POINTER(ctypes.c_double*3),
                                ctypes.POINTER(ctypes.c_double*3))
    _solarsystem_hp.restype = ctypes.c_short
    _solarsystem_hp.errcheck = _check_c_errors
    _solarsystem_hp.c_errors = {
        1: (ValueError, "from C function 'solarsystem_hp': Invalid value of body or origin."),
        2: (RuntimeError, "from C function 'solarsystem_hp': Error detected by JPL software.")
        }

    position = (ctypes.c_double*3)()
    velocity = (ctypes.c_double*3)()

    _solarsystem_hp((ctypes.c_double*2)(*tjd), body, origin,
                    ctypes.byref(position), ctypes.byref(velocity))

    return tuple([i for i in position]), tuple([j for j in velocity])