class Lookup:

    vectors = None
    elements = None

    def __init__(self, id, idType, relativeTo, time=Time.now()):
        self.obj = Horizons(id=id, id_type=idType, location=relativeTo, epochs=time.jd)

    def mass(self):
        if self.elements is None:
            self.elements = self.obj.elements(get_raw_response=True)

        match = _massPattern.search(self.elements)
        if match:
            n, m = match.group(1), match.group(2)
            kg = float(f'{m}e{n}')
            return kg * units.kilogram
        return None

    def vectorData(self, columnName):
        if self.vectors is None:
            self.vectors = self.obj.vectors()
        return self.vectors[columnName].quantity[0]
    
    def position(self):
        return CartesianRepresentation(self.vectorData('x'), self.vectorData('y'), self.vectorData('z'))

    def velocity(self):
        return CartesianRepresentation(self.vectorData('vx'), self.vectorData('vy'), self.vectorData('vz'))
    
    def assignTo(self, celestialTurtle):
        celestialTurtle.mass = self.mass()
        celestialTurtle.setposition(self.position())
        celestialTurtle.setvelocity(self.velocity())
Exemple #2
0
    def get_horizons_positioning(self, entity_id, observer_id):
        obj = Horizons(id=entity_id,
                       location='@{}'.format(observer_id),
                       epochs=Time(self.date).jd,
                       id_type='id')

        if not entity_id == observer_id:
            vectors = obj.vectors()
            elements = obj.elements()

            # get the eccentricity (e) and semimajor axis (a)
            e = elements['e'].data[0]
            a = elements['a'].data[0]
            name = elements['targetname'].data[0].replace('Barycenter ', '')

            # get the components of position and velocity from JPL SSD
            x, y = vectors['x'], vectors['y']
            vx, vy = vectors['vx'], vectors['vy']
            speed = math.hypot(vx, vy)

            # calculate angle of velocity by finding the tangent to the orbit
            # pygame specific: horizontally reflect the angle due to reversed y-axis
            angle = math.pi - ((2 * math.pi) - math.atan2(y, x))

            return x, y, speed, angle, e, a, name
        else:
            # special case for the central body of a system (e.g. the sun)
            # obj.elements() does not work for when entity_id and observer_id are the same
            name = obj.vectors()['targetname'].data[0].replace(
                'Barycenter ', '')
            return 0, 0, 0, 0, 0, 0, name
Exemple #3
0
 def query(self, term, location=None, start=None, end=None, step=None):
     if all((start, end, step)):
         epochs = {'start': start, 'end': end, 'step': step}
     else:
         epochs = None
     try:
         obj = Horizons(id=term, location=location, epochs=epochs)
         self.catalog_data = obj.elements()
     except (ValueError, IOError):
         self.catalog_data = {}
Exemple #4
0
def getHorizonsElements(
        obj_ids, 
        times, 
        location="@sun", 
        id_type="smallbody"
    ):
    """
    Query JPL Horizons (through astroquery) for an object's
    elements at the given times.
    
    Parameters
    ----------
    obj_ids : `~numpy.ndarray` (N)
        Object IDs / designations recognizable by HORIZONS. 
    times : `~astropy.core.time.Time`
        Astropy time object at which to gather state vectors.
    location : str, optional
        Location of the origin typically a NAIF code.
        ('0' or '@ssb' for solar system barycenter, '10' or '@sun' for heliocenter)
        [Default = '@sun']
    id_type : {'majorbody', 'smallbody', 'designation', 
               'name', 'asteroid_name', 'comet_name', 'id'}
        ID type, Horizons will find closest match under any given type.
        
    Returns
    -------
    elements : `~pandas.DataFrame`
        Dataframe containing the full cartesian state, r, r_rate, delta, delta_rate and light time 
        of the object at each time. 
    """
    _checkTime(times, "times")
    dfs = []
    for obj_id in obj_ids:
        obj = Horizons(
            id=obj_id, 
            epochs=times.tdb.mjd,
            location=location,
            id_type=id_type,
        )
        elements = obj.elements(
            refsystem="J2000",
            refplane="ecliptic",
            tp_type="absolute",
            cache=False
        ).to_pandas()
        dfs.append(elements)

    elements = pd.concat(dfs)
    elements.reset_index(
        inplace=True,
        drop=True
    )
    return elements
Exemple #5
0
    def _query_horizons(self) -> None:
        """Takes the object name from the text box, queries Horizons, and fills the RA/Dec inputs with the result."""
        from astroquery.jplhorizons import Horizons

        # query
        try:
            obj = Horizons(id=self.textHorizonsName.text(),
                           location=None,
                           epochs=Time.now().jd)
            # result = MPC.get_ephemeris(, location=self.observer.location)
        except InvalidQueryError:
            QtWidgets.QMessageBox.critical(self, "MPC", "No result found")
            return

        print(obj)
        print(obj.uri)
        try:
            eph = obj.elements()
        except ValueError:
            pass
        print(eph)
        print(eph.columns)
        print(obj.uri)

        self.spinOrbitElementsEcc.setValue(eph["e"][0])
        self.spinOrbitElementsIncl.setValue(eph["incl"][0])
        self.spinOrbitElementsSemiMajorAxis.setValue(eph["a"][0])
        self.spinOrbitElementsMA.setValue(eph["M"][0])
        self.spinOrbitElementsOmega.setValue(eph["Omega"][0])
        self.spinOrbitElementsPerifocus.setValue(eph["w"][0])
        self.spinOrbitElementsEpoch.setValue(eph["datetime_jd"][0])
        return

        # to coordinates
        coord = SkyCoord.guess_from_table(result)[0]

        # set it
        self.textTrackRA.setText(coord.ra.to_string(u.hour, sep=":"))
        self.textTrackDec.setText(coord.dec.to_string(sep=":"))
Exemple #6
0
def get_elems(obj_id, start):
    '''
    Parameters
    ----------
    obj_id : `str`
        Number of asteroid, defined by MPC.
    start : `str`
        Beginning time of integration, UTC.
        
    Returns
    -------
    el_jpl : `~numpy.ndarray` (N, 12)
        Orbital elements as returned by jpl, first column is obj_id.   
    '''

    epochs = ap.time.Time(start).jd

    el_obj = Horizons(id=obj_id, location='500@10', epochs=epochs)
    el_jpl = el_obj.elements()

    el_jpl['targetname'] = obj_id

    return el_jpl
Exemple #7
0
    def get_planet(self, n):
        """
        Nth planet info.

        Parameters:
            n: planet number (Mercury is 1, etc.)
        
        Returns:
            Tuple consisting of the
            r0: current coordinates (AU)
            orbit: calculated orbit
            name: name of the planet
        """
        obj = Horizons(id=n, location="@sun", epochs=self.__t0, id_type='id')
        r0 = np.array([float(obj.vectors()[xn]) for xn in ['x', 'y', 'z']])
        v = np.array([float(obj.vectors()[xn]) for xn in ['vx', 'vy', 'vz']])
        r = np.copy(r0)
        tmax = np.double(obj.elements()['P'])  # orbital period (days)
        dt = tmax / 400  # seems like an OK compromise between accuracy and performance
        orbit = compute_orbit(r, v, dt, tmax)
        name = obj.vectors()['targetname'].data[0].split()[
            0]  # extracts the name of planet
        return r0, orbit, name
Exemple #8
0
    def from_horizons(cls, targetids, id_type='smallbody',
                      epochs=None, center='500@10',
                      **kwargs):
        """Load target orbital elements from
        `JPL Horizons <https://ssd.jpl.nasa.gov/horizons.cgi>`_ using
        `astroquery.jplhorizons.HorizonsClass.elements`

        Parameters
        ----------
        targetids : str or iterable of str
            Target identifier, i.e., a number, name, designation, or JPL
            Horizons record number, for one or more targets.
        id_type : str, optional
            The nature of ``targetids`` provided; possible values are
            ``'smallbody'`` (asteroid or comet), ``'majorbody'`` (planet or
            satellite), ``'designation'`` (asteroid or comet designation),
            ``'name'`` (asteroid or comet name), ``'asteroid_name'``,
            ``'comet_name'``, ``'id'`` (Horizons id).
            Default: ``'smallbody'``
        epochs : `~astropy.time.Time` or dict, optional
            Epochs of elements to be queried; requires a
            `~astropy.time.Time` object with a single or multiple epochs. A
            dictionary including keywords ``start`` and ``stop``, as well
            as either ``step`` or ``number``, can be used to generate a range
            of epochs. ``start`` and ``stop`` have to be
            `~astropy.time.Time` objects (see :ref:`epochs`).
            If ``step`` is provided, a range
            of epochs will be queries starting at ``start`` and ending at
            ``stop`` in steps of ``step``; ``step`` has to be provided as
            a `~astropy.units.Quantity` object with integer value and a
            unit of either minutes, hours, days, or years. If
            ``number`` is provided as an integer, the
            interval defined by
            ``start`` and ``stop`` is split into ``number`` equidistant
            intervals. If ``None`` is
            provided, current date and time are
            used. All epochs should be provided in TDB; if not, they will be
            converted to TDB and a `~sbpy.data.TimeScaleWarning` will be
            raised.  Default: ``None``
        center : str, optional, default ``'500@10'`` (center of the Sun)
            Elements will be provided relative to this position.
        **kwargs : optional
            Arguments that will be provided to
            `astroquery.jplhorizons.HorizonsClass.elements`.

        Notes
        -----
        * For detailed explanations of the queried fields, refer to
          `astroquery.jplhorizons.HorizonsClass.elements` and the
          `JPL Horizons documentation <https://ssd.jpl.nasa.gov/?horizons_doc>`_.
        * By default, elements are provided in the J2000.0 reference
          system and relative to the ecliptic and mean equinox of the
          reference epoch. Different settings can be chosen using
          additional keyword arguments as used by
          `astroquery.jplhorizons.HorizonsClass.elements`.

        Returns
        -------
        `~Orbit` object

        Examples
        --------
        >>> from sbpy.data import Orbit
        >>> from astropy.time import Time
        >>> epoch = Time('2018-05-14', scale='tdb')  # doctest: +REMOTE_DATA
        >>> eph = Orbit.from_horizons('Ceres', epochs=epoch)  # doctest: +REMOTE_DATA
        """

        # modify epoch input to make it work with astroquery.jplhorizons
        # maybe this stuff should really go into that module....
        if epochs is None:
            epochs = [Time.now().tdb.jd]
        elif isinstance(epochs, Time):
            if epochs.scale != 'tdb':
                warn(('converting {} epochs to tdb for use in '
                      'astroquery.jplhorizons').format(epochs.scale),
                     TimeScaleWarning)
            epochs = epochs.tdb.jd
        elif isinstance(epochs, dict):
            if 'start' in epochs and 'stop' in epochs and 'number' in epochs:
                epochs['step'] = epochs['number']*u.dimensionless_unscaled
            # convert to tdb and iso for astroquery.jplhorizons
            epochs['start'] = epochs['start'].tdb.iso
            epochs['stop'] = epochs['stop'].tdb.iso
            if 'step' in epochs:
                if epochs['step'].unit is not u.dimensionless_unscaled:
                    epochs['step'] = '{:d}{:s}'.format(
                        int(epochs['step'].value),
                        {u.minute: 'm', u.hour: 'h', u.d: 'd',
                         u.year: 'y'}[epochs['step'].unit])
                else:
                    epochs['step'] = '{:d}'.format(
                        int(epochs['step'].value-1))

        # if targetids is a list, run separate Horizons queries and append
        if not isinstance(targetids, (list, ndarray, tuple)):
            targetids = [targetids]

        # append elements table for each targetid
        all_elem = None
        for targetid in targetids:

            # load elements using astroquery.jplhorizons
            obj = Horizons(id=targetid, id_type=id_type,
                           location=center, epochs=epochs)
            try:
                elem = obj.elements(**kwargs)
            except ValueError as e:
                raise QueryError(
                    ('Error raised by astroquery.jplhorizons: {:s}\n'
                     'The following query was attempted: {:s}').format(
                         str(e), obj.uri))

            # workaround for current version of astroquery to make
            # column units compatible with astropy.table.QTable
            # should really change '---' units to None in
            # astroquery.jplhorizons.__init__.py
            for column_name in elem.columns:
                if elem[column_name].unit == '---':
                    elem[column_name].unit = None

            if all_elem is None:
                all_elem = elem
            else:
                all_elem = vstack([all_elem, elem])

        # turn epochs into astropy.time.Time and apply timescale
        # https://ssd.jpl.nasa.gov/?horizons_doc
        all_elem['epoch'] = Time(all_elem['datetime_jd'], format='jd',
                                 scale='tdb')
        all_elem['Tp'] = Time(all_elem['Tp_jd'], format='jd',
                              scale='tdb')

        all_elem.remove_column('datetime_jd')
        all_elem.remove_column('datetime_str')
        all_elem.remove_column('Tp_jd')

        return cls.from_table(all_elem)
Exemple #9
0
def ephemeris(desg, epochs, orbit=True):
    """Ephemeris and orbital parameters.

    Parameters
    ----------
    desg : string
      Object designation.
    epochs : array-like or dictionary
      `epochs` parameter for `astroquery.jplhorizons.Horizons`.
    orbit : bool, optional
      Set to `False` to exclude orbital parameters.

    Returns
    -------
    eph : astropy.table.Table
      All jplhorizons ephemeris and orbital quantities, plus 'T-Tp'.

    """

    import re
    from astropy.time import Time
    from astropy.table import Column, join, vstack
    from astroquery.jplhorizons import Horizons
    from .exceptions import EphemerisError

    # limit Horizons requests to 200 individual epochs (530 is
    # definitely too many)
    if not isinstance(epochs, dict):
        if len(epochs) > 200:
            eph = ephemeris(desg, epochs[:200], orbit=orbit)
            for i in range(200, len(epochs), 200):
                j = min(i + 200, len(epochs))
                eph = vstack((eph, ephemeris(desg, epochs[i:j], orbit=orbit)))
            return eph

    opts = {}
    if re.match('^([CPID]/|[0-9]+P)', desg) is not None:
        id_type = 'designation'
        opts['closest_apparition'] = True
        opts['no_fragments'] = True
    else:
        id_type = 'smallbody'

    try:
        q = Horizons(id=desg, id_type=id_type, location='I41', epochs=epochs)
        eph = q.ephemerides(cache=False, **opts)
    except Exception as e:
        raise EphemerisError('{}: {}'.format(desg, str(e)))

    if len(eph) == 0:
        raise EphemerisError('{}'.format(desg))

    # combine Tmag and Nmag into V
    if 'Tmag' in eph.colnames:
        V = eph['Tmag']
        try:
            i = eph['Tmag'].mask
            V[i] = eph['Nmag'][i]
        except AttributeError as e:
            pass
        eph.add_column(V, name='V')

    V = eph['V'].data.astype(float)
    eph['V'] = Column(V, name='V')

    if orbit:
        q = Horizons(id=desg, id_type=id_type, location='0', epochs=epochs)
        orb = q.elements(cache=False, **opts)
        if len(orb) == 0:
            raise EphemerisError('{}'.format(desg))

        Tp = Time(orb['Tp_jd'], format='jd', scale='tdb')
        T = Time(orb['datetime_jd'], format='jd', scale='utc')
        tmtp = (T - Tp).jd
        orb.add_column(Column(tmtp, name='T-Tp'))

        # remove repeated columns
        repeated = [
            c for c in orb.colnames
            if (c in eph.colnames) and (c != 'datetime_jd')
        ]
        orb.remove_columns(repeated)

        # cheat to avoid float errors
        orb['datetime_jd'] = eph['datetime_jd']

        eph = join(eph, orb)

    return eph
Exemple #10
0
        save_massive_states=True,
        epoch_scale='tdb',
    ),
)

epoch = Time('2029-04-09T00:00:00', format='isot', scale='tdb')

# 99942 Apophis
# SPK ID = 2099942
# MINOR BODY ID = 2004 MN4
jpl_obj = Horizons(
    id='2004 MN4',
    location='500@10',
    epochs=epoch.jd,
)
jpl_el = jpl_obj.elements()
print(jpl_obj)
print(jpl_el)
for key in jpl_el.keys():
    print(f'{key}:{jpl_el[key].data[0]}')

orb = pyorb.Orbit(
    M0=pyorb.M_sol,
    direct_update=True,
    auto_update=True,
    degrees=True,
    a=jpl_el['a'].data[0] * pyorb.AU,
    e=jpl_el['e'].data[0],
    i=jpl_el['incl'].data[0],
    omega=jpl_el['w'].data[0],
    Omega=jpl_el['Omega'].data[0],
Exemple #11
0
    dic["z"].append(row["z"])
    dic["vx"].append(row["vx"])
    dic["vy"].append(row["vy"])
    dic["vz"].append(row["vz"])

df = pd.read_csv("jfc_comets.csv")
jfc_ids = np.random.choice(np.array(df.spkid, dtype=np.int), 100)
ids_comets = [13699] + list(jfc_ids)

print(ids_comets)
for i in ids_comets:
    print(str(i))
    try:
        obj = Horizons(id=str(i), location='@sun', epochs=2458133.33546, id_type='designation')
        row = obj.vectors()[0]
        el = obj.elements()
        a = el['a']
        if a > 6:
            print("not a JFC")
            continue
    except ValueError as e:
        # print(e)
        continue
    dic["name"].append(row["targetname"])
    dic["m"].append(1/(2e30))
    dic["x"].append(row["x"])
    dic["y"].append(row["y"])
    dic["z"].append(row["z"])
    dic["vx"].append(row["vx"])
    dic["vy"].append(row["vy"])
    dic["vz"].append(row["vz"])
Exemple #12
0
def get_horizons_ephemerides(name, pov, epoch_start, epoch_stop, step_size,
                             type_elements):

    # step: step size, [10m, 1d, 1y]

    if pov.lower() == 'sun':
        loc = '500@10'  # position relative to the sun
    elif pov.lower() == 'goldstone':
        loc = '257'  # from goldstone
    elif pov.lower() == 'maunakea':
        loc = '568'  # maunakea
    else:
        print('Not Valid Location Point Of View')

    # Process to get homogeneity from main script full name '2012QD8' to a valid name for Horizon call '2012 QD8'
    if len(
            re.findall('([0-9])', name)
    ) <= 4:  # 4 is the min numbers in every name, the date year of discovery
        r = re.compile("([0-9]+)([a-zA-Z]+)").match(name)
        k1 = r.group(1)  # the date of the name
        k2 = r.group(2)  # the code of the date
        valid_name = k1 + " " + k2
    else:
        r = re.compile("([0-9]+)([a-zA-Z]+)([0-9]+)").match(name)
        k1 = r.group(1)  # the date of the name
        k2 = r.group(2)  # the code of the date
        k3 = r.group(3)  # id after the letters
        valid_name = k1 + " " + k2 + k3

    obj = Horizons(id=valid_name,
                   location=loc,
                   epochs={
                       'start': epoch_start,
                       'stop': epoch_stop,
                       'step': step_size
                   })

    if type_elements.lower() == 'vectors':
        data = obj.vectors()  # vectorial elements

        len_rows = len(data)
        len_cols = 6  # 3 positions 'x','y','z', and 3 velocities 'vx', 'vy', 'vz'
        idx_x = 5  # 'x' is at position 5 in the table (starting from 0)
        adata = np.zeros([len_rows, len_cols])
        for row in range(len_rows):
            for col in range(6):
                idx_col_in_table = idx_x + col  # because the 'x' start at 6th col, going up till the 12th that is 'vz'
                adata[row, col] = data[row][idx_col_in_table]

    elif type_elements.lower() == 'elements':
        # refsystem = 'J2000', # Element reference system for geometric and astrometric quantities
        # refplane = 'ecliptic' #ecliptic and mean equinox of reference epoch
        data = obj.elements(refsystem='J2000', refplane='ecliptic')

        len_rows = len(data)
        len_cols = 6  # (a e i OM om theta)
        adata = np.zeros([len_rows, len_cols])
        for row in range(len_rows):
            adata[row,
                  0] = data[row][14]  # 15th column of data -> semimajor axis
            adata[row, 1] = data[row][5]  # 6th column of data -> eccentricity
            adata[row, 2] = data[row][7]  # 8th column of data -> inclination
            adata[row, 3] = data[row][8]  # 9th column of data -> RAAN, (OMEGA)
            adata[row, 4] = data[row][
                9]  # 10th column of data -> argument of perigee, (omega)
            adata[row, 5] = data[row][
                13]  # 14th column of data -> True anomaly, (theta)

    return adata
Exemple #13
0
def get_horizons_ephemerides_elements(name, pov, epoch_start):

    # step: step size, [10m, 1d, 1y]

    if pov.lower() == 'sun':
        loc = '500@10'  # position relative to the sun
    elif pov.lower() == 'goldstone':
        loc = '257'  # from goldstone
    elif pov.lower() == 'maunakea':
        loc = '568'  # maunakea
    else:
        print('Not Valid Location Point Of View')

    # Process to get homogeneity from main script full name '2012QD8' to a valid name for Horizon call '2012 QD8'
    if len(
            re.findall('([0-9])', name)
    ) <= 4:  # 4 is the min numbers in every name, the date year of discovery
        r = re.compile("([0-9]+)([a-zA-Z]+)").match(name)
        k1 = r.group(1)  # the date of the name
        k2 = r.group(2)  # the code of the date
        valid_name = k1 + " " + k2
    else:
        r = re.compile("([0-9]+)([a-zA-Z]+)([0-9]+)").match(name)
        k1 = r.group(1)  # the date of the name
        k2 = r.group(2)  # the code of the date
        k3 = r.group(3)  # id after the letters
        valid_name = k1 + " " + k2 + k3

    # always a day after the input, anyway you consider the moment of input, the first of the data output extracted
    epoch_start
    chunks = epoch_start.split('-')
    chunks2 = int(chunks[2]) + 1  # add 1 day
    list_string = [chunks[0], chunks[1], str(chunks2)]
    epoch_stop = '-'.join(list_string)

    step_size = '1d'

    obj = Horizons(id=valid_name,
                   location=loc,
                   epochs={
                       'start': epoch_start,
                       'stop': epoch_stop,
                       'step': step_size
                   })

    # refsystem = 'J2000', # Element reference system for geometric and astrometric quantities
    # refplane = 'ecliptic' #ecliptic and mean equinox of reference epoch
    data = obj.elements(refsystem='J2000', refplane='ecliptic')

    len_cols = 7  # jd,ec,qr,tp,incl,OM,om
    adata = np.zeros([1, len_cols])
    # always assign the first row of output data -> the first date required!
    #for row in range(len_rows):
    adata[0, 0] = data[0][5]  # 6th column of data -> e, eccentricity (-)
    adata[0,
          1] = data[0][6]  # 7th column of data -> qr, periapsis distance (AU)
    adata[0,
          2] = data[0][10]  # 11th column of data -> tp, time of periapsis (JD)
    adata[0, 3] = data[0][7]  # 8th column of data -> incl, inclination (deg)
    adata[0, 4] = data[0][
        8]  # 10th column of data -> OM, longitude of Asc. Node (deg)
    adata[0, 5] = data[0][
        9]  # 11th column of data -> om, argument of periapsis (deg)
    adata[0, 6] = data[0][
        1]  # 2nd column of the data extracted -> jd of evaluation

    return adata
Exemple #14
0
    def from_horizons(cls,
                      targetids,
                      id_type='smallbody',
                      epochs=None,
                      center='500@10',
                      **kwargs):
        """Load target orbital elements from
        `JPL Horizons <https://ssd.jpl.nasa.gov/horizons.cgi>`_ using
        `astroquery.jplhorizons.HorizonsClass.elements`

        Parameters
        ----------
        targetids : str or iterable of str
            Target identifier, i.e., a number, name, designation, or JPL
            Horizons record number, for one or more targets.
        id_type : str, optional
            The nature of ``targetids`` provided; possible values are
            ``'smallbody'`` (asteroid or comet), ``'majorbody'`` (planet or
            satellite), ``'designation'`` (asteroid or comet designation),
            ``'name'`` (asteroid or comet name), ``'asteroid_name'``,
            ``'comet_name'``, ``'id'`` (Horizons id).
            Default: ``'smallbody'``
        epochs : `~astropy.time.Time` object or iterable thereof, or dictionary, optional
            Epochs of elements to be queried; a list, tuple or
            `~numpy.ndarray` of `~astropy.time.Time` objects or Julian
            Dates as floats should be used for a number of discrete
            epochs; a dictionary including keywords ``start``,
            ``step``, and ``stop`` can be used to generate a range of
            epochs (see
            `~astroquery.jplhorizons.HorizonsClass.Horizons.elements`
            for details); if ``None`` is provided, current date and
            time are used. Default: ``None``
        center : str, optional, default ``'500@10'`` (center of the Sun)
            Elements will be provided relative to this position.
        **kwargs : optional
            Arguments that will be provided to
            `astroquery.jplhorizons.HorizonsClass.elements`.

        Returns
        -------
        `~Orbit` object

        Examples
        --------
        >>> from sbpy.data import Orbit
        >>> from astropy.time import Time
        >>> epoch = Time('2018-05-14', scale='utc')
        >>> eph = Orbit.from_horizons('Ceres', epochs=epoch)
        """

        # modify epoch input to make it work with astroquery.jplhorizons
        # maybe this stuff should really go into that module....
        if epochs is None:
            epochs = [Time.now().jd]
        elif isinstance(epochs, Time):
            epochs = [Time(epochs).jd]
        elif isinstance(epochs, dict):
            for key, val in epochs.items():
                if isinstance(val, Time):
                    val.format = 'iso'
                    val.out_subfmt = 'date_hm'
                    epochs[key] = "'" + val.value + "'"
                else:
                    epochs[key] = "'" + epochs[key] + "'"
        elif isinstance(epochs, (list, tuple, ndarray)):
            new_epochs = [None] * len(epochs)
            for i in range(len(epochs)):
                if isinstance(epochs[i], Time):
                    new_epochs[i] = epochs[i].jd
                else:
                    new_epochs[i] = epochs[i]
            epochs = new_epochs

        # if targetids is a list, run separate Horizons queries and append
        if not isinstance(targetids, (list, ndarray, tuple)):
            targetids = [targetids]

        # append elements table for each targetid
        all_elem = None
        for targetid in targetids:

            # load elements using astroquery.jplhorizons
            obj = Horizons(id=targetid,
                           id_type=id_type,
                           location=center,
                           epochs=epochs)

            elem = obj.elements(**kwargs)

            # workaround for current version of astroquery to make
            # column units compatible with astropy.table.QTable
            # should really change '---' units to None in
            # astroquery.jplhorizons.__init__.py
            for column_name in elem.columns:
                if elem[column_name].unit == '---':
                    elem[column_name].unit = None

            if all_elem is None:
                all_elem = elem
            else:
                all_elem = vstack([all_elem, elem])

        # identify time scales returned by Horizons query
        timescales = ['TT'] * len(all_elem)
        all_elem.add_column(Column(timescales, name='timescale'))

        if bib.status() is None or bib.status():
            bib.register('sbpy.data.Orbit.from_horizons',
                         {'data service': '1996DPS....28.2504G'})

        return cls.from_table(all_elem)
Exemple #15
0
        step = epochs[2]

        print(start)
        print(stop)
        print(step)

        obj = Horizons(id=planet[1],
                       id_type=planet[2],
                       location=planet[3],
                       epochs={
                           'start': start + '-01-01',
                           'stop': stop + '-01-01',
                           'step': step + 'd'
                       })
        try:
            elem = obj.elements()
        except ValueError:
            # no data available, just continue
            continue

        print(elem['targetname'][0])

        elem['datetime_jd'] -= 2451544.5
        # 1 jan 2000 00h00:00.00
        elem['incl'].convert_unit_to('rad')
        elem['Omega'].convert_unit_to('rad')
        elem['w'].convert_unit_to('rad')
        elem['a'].convert_unit_to('m')
        elem['M'].convert_unit_to('rad')

        table = elem['datetime_jd', 'incl', 'Omega', 'w', 'e', 'a', 'M']