Beispiel #1
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
Beispiel #2
0
def test_ecliptic_to_equatorial(target, jd_tdb, id_type, centre):
    '''
    Test that heliocentric cartesian coordinates taken from Horizons
    are converted to barycentric cartesian and still agree with Horizons.
    jd_tdb isn't actually used for this, but it seemed useful to record it.
    
    MJP : The ecliptic_to_equatorial will now transform CoV Matrix as well
            This is tested in *test_ecliptic_to_equatorial_covariance* below
    '''
    # Query horizons
    hor_table = Horizons(target, centre, epochs=jd_tdb, id_type=id_type)
    hor_in_table = hor_table.vectors(refplane='ecliptic')['x', 'y', 'z', 'vx',
                                                          'vy', 'vz']
    hor_out_table = hor_table.vectors(refplane='earth')['x', 'y', 'z', 'vx',
                                                        'vy', 'vz']
    input_xyz = list(hor_in_table.as_array()[0])
    expected_output_xyz = np.array(list(hor_out_table.as_array()[0]))

    # Call the function we want to test
    output_xyz = parse_input.ecliptic_to_equatorial(input_xyz)

    # Each element should be within 15mm or 1.5mm/day
    error = np.abs(expected_output_xyz - output_xyz)
    assert np.all(error[:3] < 1e-13)  # XYZ accurate to 15 milli-metres
    assert np.all(error[3:6] < 1e-14)  # V accurate to 1.5 milli-metres/day
    print('test_ecliptic_to_equatorial successful!')
def get_data(id_list, referenceFrame="500@10"):  # defaut @ sun center of mass

    initpos = np.zeros([len(id_list), 3], dtype=np.float64)
    initvel = np.zeros([len(id_list), 3], dtype=np.float64)

    for i in xrange(len(id_list)):
        obj = Horizons(id=id_list[i],
                       id_type='id',
                       epochs={
                           'start': '2018-10-16',
                           'stop': '2018-11-15',
                           'step': '1d'
                       },
                       location=referenceFrame)
        vec = obj.vectors()
        x = vec['x'][0]
        y = vec['y'][0]
        z = vec['z'][0]
        vx = vec['vx'][0]
        vy = vec['vy'][0]
        vz = vec['vz'][0]

        initpos[i] = [x, y, z]  # [AU]
        initvel[i] = [vx, vy, vz]  # [AU/Day]

    initvel *= 365.25  # [AU/Day] -> [AU/Year]

    return initpos, initvel
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())
Beispiel #5
0
def get_earth_ephemerides(epoch_start, epoch_stop, step_size, type_elements):

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

    obj = Horizons(id='Geocenter',
                   location='500@10',
                   epochs={
                       'start': epoch_start,
                       'stop': epoch_stop,
                       'step': step_size
                   },
                   id_type='majorbody')

    if type_elements.lower() == 'vectors':
        data_output = obj.vectors()  # vectorial elements
    elif type_elements.lower() == 'ephemerides':
        data_output = obj.ephemerides()

    len_rows = len(data_output)
    len_cols = 6  # 3 positions 'x','y','z', and 3 velocities 'vx', 'vy', 'vz'
    idx_x = 3  # 'x' is at position 3 in the table
    data = 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 3rd col, going up till the 9th that is 'vz'
            data[row, col] = data_output[row][idx_col_in_table]

    return data
    def get_target_xyz(t):
        """
        Returns the vectors of the Horizons body at a certain time t.
        
        Arguments:
        
        t: days
        
        Julian date of observation
        
        Returns:
    
        xyz: numpy array
        
        A position vector of the observed object
    
        uvw: numpy array
        
        An instantaneous velocity vector of the observed object
        """

        obj = Horizons(id=name, location=loc, epochs=t, id_type='majorbody')
        obj1 = obj.vectors(aberrations=cor, refplane='earth')
        xyz = np.array([float(obj1['x']), float(obj1['y']), float(obj1['z'])])
        uvw = np.array(
            [float(obj1['vx']),
             float(obj1['vy']),
             float(obj1['vz'])])
        obj2 = obj.ephemerides(refsystem='J2000', extra_precision=True)
        radec = np.array(
            [float(obj2['RA']),
             float(obj2['DEC']),
             float(obj1['range'])])
        return xyz, uvw, radec
Beispiel #7
0
 def _get_object_XYZ_from_horizons(self,
                                   object_name,
                                   times,
                                   object_type='smallbody',
                                   plane='earth'):
     '''
     Query horizons for the BARYCENTRIC VECTOR of a
     *known object* at a sequence of times.
     input:
     object_name - string
     times       - array
     object_type - string
                 - Usually the default "smallbody" is fine, 
                   but for some objects, like natsats, it's neccessary.
     plane       - string
                 - 'earth' = equatorial
                 - 'ecliptic' = ecliptic
     '''
     horizons_query = Horizons(id=object_name,
                               location='500@0',
                               epochs=times,
                               id_type=object_type)
     horizons_vector = horizons_query.vectors(refplane=plane)
     self.XYZ = np.array(
         [horizons_vector['x'], horizons_vector['y'], horizons_vector['z']])
Beispiel #8
0
def query_vectors(cfg):
    print("Querying Vectors")
    #create query object
    if 'id' in cfg['horizons'].keys(): id = cfg['horizons']['id']
    else: id = cfg['horizons']['name']
    obj = Horizons(id=id,
                   location=cfg['horizons']['coord_origin'],
                   id_type=cfg['horizons']['id_type'],
                   epochs=cfg['horizons']['epochs'])
    eph = obj.vectors()
    #print(eph)
    print(eph.columns)
    #return eph
    keys = ['datetime_str', 'datetime_jd', 'x', 'y', 'z', 'vx', 'vy', 'vz']
    df = pd.DataFrame(np.array(eph[keys]), columns=keys)
    df['x'] = df['x'] * au2km
    df['y'] = df['y'] * au2km
    df['z'] = df['z'] * au2km
    df['vx'] = df['vx'] * au2km / day2sec
    df['vy'] = df['vy'] * au2km / day2sec
    df['vz'] = df['vz'] * au2km / day2sec
    column_map = {
        'datetime_str': 'datetime_str [UTC]',
        'datetime_jd': 'datetime_jd [UTC]',
        'x': 'x [km]',
        'y': 'y [km]',
        'z': 'z [km]',
        'vx': 'x_dot [km/sec]',
        'vy': 'y_dot [km/sec]',
        'vz': 'z_dot [km/sec]'
    }
    df = df.rename(columns=column_map)
    df['datetime [ISO UTC]'] = pd.to_datetime(
        df['datetime_str [UTC]'], format="A.D. %Y-%b-%d %H:%M:%S.%f")
    return df
def test_Ephemerides_Vectors_Astrometric():
    strstartdate = '2021-1-1 12:00:00'
    strenddate = '2021-1-2 12:00:00'
    start_time = Time(strstartdate)
    start_time_tdb = start_time.tdb
    end_time = Time(strenddate)
    end_time_tdb = end_time.tdb
    # print(start_time.value, start_time_tdb.value)
    mars_by_earth_obs = Horizons(id='499',
                                 id_type='majorbody',
                                 location='500',
                                 epochs={
                                     'start': start_time.value,
                                     'stop': end_time.value,
                                     'step': '1'
                                 })
    mars_by_earth_vec = Horizons(id='499',
                                 id_type='majorbody',
                                 location='500',
                                 epochs={
                                     'start': start_time_tdb.value,
                                     'stop': end_time_tdb.value,
                                     'step': '1'
                                 })
    mars_by_earth_obs_data = mars_by_earth_obs.ephemerides(
        quantities='1,2,4,20,31')
    mars_by_earth_vec_astrometric = mars_by_earth_vec.vectors(
        refplane='earth', aberrations='astrometric', delta_T=True)
    mars_by_earth_vec_apparent = mars_by_earth_vec.vectors(
        refplane='earth', aberrations='apparent', delta_T=True)
    mars_by_earth_vec_geometric = mars_by_earth_vec.vectors(refplane='earth',
                                                            delta_T=True)
    print(
        "比較 Horizons 中,用 Observer 模式查得的 RA/DEC與用Vectors模式(aberrations='astrometric')查得的是否相同?是相同!"
    )
    print(mars_by_earth_obs_data['datetime_str', 'RA', 'DEC', 'RA_app',
                                 'DEC_app', 'delta'])
    # print(mars_by_earth_vec_astrometric['x','y','z','lighttime'])
    astrometric_position = SkyCoord(
        x=mars_by_earth_vec_astrometric['x'].tolist() * u.au,
        y=mars_by_earth_vec_astrometric['y'].tolist() * u.au,
        z=mars_by_earth_vec_astrometric['z'].tolist() * u.au,
        representation_type='cartesian',
        frame='gcrs')
    astrometric_position.representation_type = 'spherical'
    print(astrometric_position)
Beispiel #10
0
def nice_Horizons(target, centre, epochs, id_type):
    '''
    Only require the inputs I actually want to vary.
    Return in the format I actually want, not an astropy table.
    '''
    horizons_table  = Horizons(target, centre, epochs=epochs, id_type=id_type)
    horizons_vector = horizons_table.vectors(refplane='earth')
    horizons_xyzv   = horizons_vector['x', 'y', 'z', 'vx', 'vy', 'vz']
    return np.array(list(horizons_xyzv.as_array()[0]))
Beispiel #11
0
def getHorizonsObserverState(observatory_codes,
                             observation_times,
                             origin="heliocenter",
                             aberrations="geometric"):
    """
    Query JPL Horizons (through astroquery) for an object's
    elements at the given times.
    
    Parameters
    ----------
    observatory_codes : list or `~numpy.ndarray`
        MPC observatory codes. 
    observation_times : `~astropy.time.core.Time`
        Epochs for which to find the observatory locations.
    origin : {'barycenter', 'heliocenter'}
        Return observer state with heliocentric or barycentric origin.
    aberrations : {'geometric', 'astrometric', 'apparent'}
        Adjust state for one of three different aberrations. 
        
    Returns
    -------
    vectors : `~pandas.DataFrame`
        Dataframe containing the full cartesian state, r, r_rate, delta, delta_rate and light time 
        of the object at each time. 
    """
    _checkTime(observation_times, "observation_times")

    if origin == "heliocenter":
        origin_horizons = "sun"
    elif origin == "barycenter":
        origin_horizons = "ssb"
    else:
        err = ("origin should be one of {'heliocenter', 'barycenter'}")
        raise ValueError(err)

    dfs = []
    for code in observatory_codes:
        obj = Horizons(
            id=origin_horizons,
            epochs=observation_times.tdb.mjd,
            location=code,
            id_type="majorbody",
        )
        vectors = obj.vectors(
            refplane="ecliptic",
            aberrations=aberrations,
        ).to_pandas()

        vectors = vectors.drop(columns="targetname")
        vectors.insert(0, "observatory_code",
                       [code for i in range(len(vectors))])
        vectors.loc[:, ["x", "y", "z", "vx", "vy", "vz"]] *= -1
        dfs.append(vectors)

    vectors = pd.concat(dfs)
    vectors.reset_index(inplace=True, drop=True)
    return vectors
Beispiel #12
0
def JPL_query(Ttot, ts):
	"""
	Querying JPL Horizons system for the state-vectors of Jupiter and 67P/C-G,
	then converting the tables to pandas dataframes.
	"""
	JD_period_end = 2415020.5 + Ttot
	
	if JD_period_end > 2667387.5:
		print('Timescale is too large for query. Using previously downloaded HORIZONS data.')
		df1 = pd.read_csv('.' + sep + 'addendum' + sep + 'Jupiter_1900_2000_1.csv', skipinitialspace = True, float_precision = 'high')
		df2 = pd.read_csv('.' + sep + 'addendum' + sep + '67P_1900_2000_1.csv', skipinitialspace = True, float_precision = 'high')
		
	else:
		try:
			# Creating the necessary date format for querying:
			endy, endm, endd = jd_to_date(JD_period_end)
			end = str(endy) + '-' + str(endm) + '-' + str(endd)
		
			print(f'Querying HORIZONS with a {ts} days timestep...')
		
			# Jupiter data:
			Jup = Horizons(id = '599', id_type = 'id', location = '500@0', epochs = {'start': '1900-01-01', 'stop': end, 'step': (str(ts)+'d')})
			vec = Jup.vectors()
		
			df1 = vec.to_pandas()
		
			# 67P/C-G data:
			CG = Horizons(id = '900681', id_type = 'id', location = '500@0', epochs = {'start': '1900-01-01', 'stop': end, 'step': (str(ts)+'d')})
			vec2 = CG.vectors()
		
			df2 = vec2.to_pandas()
			
			print('Done.')
			
		except:
			# In case there is no internet, or querying fails anyhow, use standard addendum logs:
			
			print('Something went wrong with the query. Using previously downloaded HORIZONS data.')
			
			df1 = pd.read_csv('.' + sep + 'addendum' + sep + 'Jupiter_1900_2000_1.csv', skipinitialspace = True, float_precision = 'high')
			df2 = pd.read_csv('.' + sep + 'addendum' + sep + '67P_1900_2000_1.csv', skipinitialspace = True, float_precision = 'high')
			
	return df1, df2
Beispiel #13
0
 def __query_body(self, body_id):
     try:
         obj = Horizons(id=body_id,
                        epochs=self.epochs,
                        location='500@sun',
                        id_type='majorbody')
         vec = obj.vectors()
         return vec
     except ValueError as e:
         print(e)
def test_ecliptic_to_equatorial(target, jd_tdb, id_type, centre):
    '''
    Test that heliocentric cartesian coordinates taken from Horizons
    is converted to barycentric cartesian and still agrees with Horizons.
    jd_tdb isn't actually used for this, but it seemed useful to record it.
    '''
    hor_table = Horizons(target, centre, epochs=jd_tdb, id_type=id_type)
    hor_in_table = hor_table.vectors(refplane='ecliptic')['x', 'y', 'z', 'vx',
                                                          'vy', 'vz']
    hor_out_table = hor_table.vectors(refplane='earth')['x', 'y', 'z', 'vx',
                                                        'vy', 'vz']
    input_xyz = list(hor_in_table.as_array()[0])
    expected_output_xyz = np.array(list(hor_out_table.as_array()[0]))
    output_xyz = parse_input.ecliptic_to_equatorial(input_xyz)
    # Each element should be within 15mm or 1.5mm/day
    error = np.abs(expected_output_xyz - output_xyz)
    print(error)
    assert np.all(error[:3] < 1e-13)  # XYZ accurate to 15 milli-metres
    assert np.all(error[3:6] < 1e-14)  # V accurate to 1.5 milli-metres/day
Beispiel #15
0
def getHorizonsVectors(
        obj_ids, 
        times, 
        location="@sun", 
        id_type="smallbody", 
        aberrations="geometric",
    ):
    """
    Query JPL Horizons (through astroquery) for an object's
    state vectors at the given times.
    
    Parameters
    ----------
    obj_ids : `~numpy.ndarray` (N)
        Object IDs / designations recognizable by HORIZONS. 
    times : `~astropy.core.time.Time` (M)
        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.
    aberrations : {'geometric', 'astrometric', 'apparent'}
        Adjust state for one of three different aberrations. 
        
    Returns
    -------
    vectors : `~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,
        )
        vectors = obj.vectors(
            refplane="ecliptic",
            aberrations=aberrations,
            cache=False
        ).to_pandas()
        dfs.append(vectors)

    vectors = pd.concat(dfs)
    vectors.reset_index(
        inplace=True,
        drop=True
    )
    return vectors
Beispiel #16
0
def fetch_data(jpl_id, referenceFrame="500@0"):
    """
    This function fetches position and velocity data from the Horizons system
    hosted by the Solar dynamics group at JPL, NASA using astroquery.
    Since i only need initial conditions, i fetch data using the default epoch
    kwarg in the Horizons() class, which yields the position and velocity vectors
    at time = runtime
    """
    NumPlanets = len(jpl_id)
    initPos = np.zeros([NumPlanets, 3])
    initVel = np.zeros([NumPlanets, 3])
    planetMass = np.zeros(NumPlanets)

    # Astroquery doesn't seemt to have masses, so i hardcode these
    # Values collected from https://en.wikipedia.org/wiki/Planetary_mass
    # in units [Solar mass]
    MASS_TABLE = {"Sun": 1, "Mercury": 0.16601E-6, "Venus": 2.4478383E-6,
                  "Earth": 3.00348959632E-6, "Mars": 0.3227151E-6, "Jupiter": 954.79194E-6,
                  "Saturn": 285.8860E-6, "Uranus": 43.66244E-6, "Neptune": 51.51389E-6,
                  "Pluto": 0.007396E-6}


    for i, pname in enumerate(jpl_id):
        print "Here", i, pname
        # Status update on a single, updating line
        print "\rFetching data from: https://ssd.jpl.nasa.gov/horizons_batch.cgi [%i/%i]" % (i, NumPlanets),
        sys.stdout.flush()
        temp_obj = Horizons(id=jpl_id[pname], id_type='id',
                            location=referenceFrame)
        """Fetches position and velocity data in order (x, y, z)
        Note: Print method in vectors() doesnt seem to play nice with list
        comprehensions Hence the ugly (but stable and functioning)
        implemetation here."""
        initPos[i] = [temp_obj.vectors()["x"], temp_obj.vectors()["y"],
                      temp_obj.vectors()["z"]]  # [AU]
        initVel[i] = [temp_obj.vectors()["vx"], temp_obj.vectors()["vy"],
                      temp_obj.vectors()["vz"]]  # [AU/day]
        initVel = initVel * (365.25)  # Convert to units [AU/yr]
        planetMass[i] = MASS_TABLE[pname]   # Fetches the mass from the hardcoded table
    print "\rFetching data from: https://ssd.jpl.nasa.gov/horizons_batch.cgi [COMPLETE]"

    return initPos, initVel, planetMass
Beispiel #17
0
def targetEphemerisFromHorizons(target_id,
                                observer_location,
                                tstart,
                                tstop,
                                ephemeris_dt='12h'):
    """Query JPL Horizons via astroquery to get sun-observer state vectors.
    
    Parameters:
    -----------
    target_id          ... Horizons identifyer target, e.g. 'Ceres'
    observer_location  ... Horizons identifyer of observer location, e.g. 'I11'
    tstart             ... start time for ephemeris in Horizons format, e.g. 'JD2456789.5'
    tstop              ... end time for ephemeris in Horizons format, e.g. 'JD2456799.5'
    ephemeris_dt       ... Time step for ephemeris query. 
                           Typically 1h since the actual times will be interpolated later.
    
    Returns:
    --------
    RA, DEC               ... Right Ascension and Declination of target wrt observer
    ephemeris_jd        ... Ephemeris epochs (JD / UTC)
    
    External Function Requirements:
    -------------------------------
    # External API's
    from astroquery.jplhorizons import Horizons
    """
    try:
        # Get observer locations (caution: choose the right plane of reference and direction of the vectors!)
        # check query by copy/pasting the output of print(observer_sun.uri) into a webbrowser if there are problems.

        #         tmin = 'JD'+str(tstart)
        #         tmax = 'JD'+str(tstop+1.)

        tmin = tstart
        tmax = tstop
        observer2target = Horizons(id=target_id,
                                   location=observer_location,
                                   epochs={
                                       'start': tmin,
                                       'stop': tmax,
                                       'step': ephemeris_dt
                                   })

        ra, dec = observer2target.ephemerides()['RA', 'DEC']
        jd = (observer2target.vectors())['datetime_jd']

    except:
        print(
            "Error in observer_state_from_horizons: potential online ephemeris query failure."
        )
        raise

    return ephemeris_jd, ra, dec
Beispiel #18
0
    def get_cartesian_states(self, obj_id, epoch, end_time):
        """
        Query database and get cartesian rv
        NOTE: id requires the Horizons name, not SPK number!

        Args:
            id (str) - object ID (Horizons name)
            epoch (datetime obj) - start time
            end_time (datetime obj) - end time

        Returns:
            rv (list of rv list) - rv in the format:
                x (km), y (km), z (km), vx (km/s), vy (km/s), vz (km/s)
        """
        # Format step size for query
        if self._step_unit == 'sec':
            # Special formatting needed
            dt = int((end_time - epoch).total_seconds() / self._step)
        else:
            # Concatenate step size and unit
            dt = str(self._step) + self._step_unit[0]

        # Make call to JPL Horizons database and get data
        try:
            obj = Horizons(id=obj_id,
                           location='@sun',
                           epochs={
                               'start': epoch.isoformat(),
                               'stop': end_time.isoformat(),
                               'step': dt
                           })
            data = obj.vectors()
        except:
            raise RuntimeError("Invalid query")

        # Get column header
        columns = data.colnames

        # Make state vectors
        rv = []
        for row in data:
            r_mult = AU  # convert AU to km
            v_mult = AU / DAY2SEC  # convert AU/day to km/s

            rv.append([
                row[columns.index("x")] * r_mult,
                row[columns.index("y")] * r_mult,
                row[columns.index("z")] * r_mult,
                row[columns.index("vx")] * v_mult,
                row[columns.index("vy")] * v_mult,
                row[columns.index("vz")] * v_mult
            ])
        return rv
Beispiel #19
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
Beispiel #20
0
def get_planet(p_id, mss):
    obj = Horizons(id=p_id,
                   id_type='majorbody',
                   epochs={
                       'start': '2018-10-20',
                       'stop': '2018-10-21',
                       'step': '1d'
                   })
    vec = obj.vectors()
    return planet(
        vec['targetname'][0], np.array([vec['x'][0], vec['y'][0],
                                        vec['z'][0]]),
        365.25 * np.array([vec['vx'][0], vec['vy'][0], vec['vz'][0]]),
        mss / 1988500e24)
Beispiel #21
0
def get_object_info(obj):
    obj = Horizons(id=obj,
                   location='500@10',
                   epochs={
                       'start': '2018-12-31',
                       'stop': '2019-01-02',
                       'step': '1d'
                   },
                   id_type='majorbody')
    table = obj.vectors()

    initial_position = np.array([table['x'][0], table['y'][0],
                                 table['z'][0]])  # AU
    initial_velocity = np.array(
        [table['vx'][0], table['vy'][0], table['vz'][0]]) * 365.25  # AU/yr

    return table['targetname'][0], initial_position, initial_velocity
Beispiel #22
0
    def _do_query(self):
        _query_kw = {'location': self._location, **self._target}

        # query in batches to avoid 2000-char URL length limit:
        tik = time.time()
        nchunks = (self._timestamps.tdb.jd.size // self._qmax) + 1
        batches = np.array_split(self._timestamps.tdb.jd, nchunks)
        results = []
        for ii, batch in enumerate(batches, 1):
            self._vlwrite(1, 99, "\rQuery batch %d of %d ... " % (ii, nchunks))
            hrz_query = Horizons(**_query_kw, epochs=batch.tolist())
            batch_eph = hrz_query.vectors(refplane=self._refplane)
            results.append(batch_eph)
        tok = time.time()
        self._vlwrite(1, 99, "done (took %.3f sec).\n" % (tok - tik))
        # combine results:
        return apt.vstack(results)
Beispiel #23
0
def getpositions(id, id_type="majorbody"):
    today = date.today()
    obj = Horizons(id_type=id_type,
                   id=id,
                   location='500@0',
                   epochs={
                       'start': today.__str__(),
                       'stop': (today + td(1)).__str__(),
                       'step': '2d'
                   })

    table = obj.vectors()

    return table["targetname"].item().rsplit(
        " ",
        1)[0], (table["x"].item(), table["y"].item(),
                table["z"].item()), (table["vx"].item(), table["vy"].item(),
                                     table["vz"].item())
Beispiel #24
0
def download_Body(name, number, time, mass=-1) -> bodies.Body:
    majorbody = (
        mass != -1
    )  #Tests if a mass value is provided, and if it is, marks body as major
    if majorbody:  #Creates actual body in astroquery
        working_body = Horizons(id=str(number),
                                epochs=time,
                                id_type='majorbody')
    else:
        working_body = Horizons(id=str(number), epochs=time)
    body_table = working_body.vectors(
    )  #Returns astropy table of position/velocity vectors
    if (mass == -1):  #Estimates mass using function in estimation_tools.py
        mass = estimation_tools.estimate_mass(body_table['H'][0], 'x')
    return bodies.Body(name, number, float(mass), float(body_table['x'][0]),
                       float(body_table['y'][0]), float(body_table['z'][0]),
                       float(body_table['vx'][0]), float(body_table['vy'][0]),
                       float(body_table['vz'][0]))
Beispiel #25
0
def grabBody(UUID, date=None):
	"""
	Takes a UUID and returns string of UUID, initial position and velocity
	
	Args: 
		UUID: 	  The unique id for a body
		date: 	  String, YYYY-MM-DD, Date for intial conditions, default is todays date

	Returns:
		init:     String of UUID and initial conditions (UUID,x,y,z,vx,vy,vz)
	"""

	obj = Horizons(id=UUID, location="500@0", epochs=date,  id_type="majorbody")
	v = obj.vectors()
	
	init = [str(v[elm][0]) for elm in ["x", "y", "z", "vx", "vy", "vz"]]
	init.insert(0, str(UUID))
	init = ",".join(init) 
	
	return init
Beispiel #26
0
    def __init__(self, id_list):
        self.id_list = id_list

        self.data_list = []

        for jpl_id in id_list:

            body = Horizons(id=jpl_id,
                            location='@ssb',
                            epochs={
                                'start': '1970-1-1',
                                'stop': '2000-1-1',
                                'step': '10d'
                            },
                            id_type="majorbody")
            vecs = body.vectors()
            self.data_list.append(vecs)
            print("\t".join([
                str(x) for x in list(vecs[0]["targetname", "x", "y", "z", "vx",
                                             "vy", "vz"])
            ]))
def compare_obj(planets, code, year, month, day, hour=0, minute=0, second=0):
    '''
    compare position between jpl query and skyfield computation

    parameters:
    ----------
    code : 1,2,3,4,5,6,7,8,9,10,199,299,399,301

    year: int,
    month: int,
    day: int,
    hour: int default 0,
    minute: int default 0,
    second float default 0,
    '''

    # print(code)
    ts = load.timescale()
    t = ts.utc(year, month, day, hour, minute, second)
    objname = planets.names()[code][0]
    # print(objname)
    obj = planets[objname]
    icrf_sf = obj.at(t)
    # print(icrf_sf.position)
    icrf_sf_np = icrf_sf.position.km

    time = Time(t.utc_iso())
    times = time.tt+np.linspace(0, 1, 2)*u.s
    objquery = Horizons(id=str(code), id_type='majorbody', location='@0',
                        epochs={'start': times.value[0], 'stop': times.value[1], 'step': '1'})
    icrf_jpl = objquery.vectors(refplane='earth')
    icrf_jpl['x'].convert_unit_to('km')
    icrf_jpl['y'].convert_unit_to('km')
    icrf_jpl['z'].convert_unit_to('km')
    icrf_jpl_np = np.array(
        [icrf_jpl['x'][0], icrf_jpl['y'][0], icrf_jpl['z'][0]])
    print(objname + ' icrf_sf_np in km', icrf_sf_np)
    print(objname + ' icrf_jpl_np in km', icrf_jpl_np)
    print(objname + ' icrf_sf_np-icrf_jpl_np in km', icrf_sf_np-icrf_jpl_np)
    print()
def get_current_pos(object_name, start_date, end_date, time_step):
    if 'COMET' in object_name:
        obj = Horizons(id=object_name[object_name.find(' ') + 1:],
                       epochs={
                           'start': start_time,
                           'stop': end_time,
                           'step': step
                       },
                       id_type='id')
    if not 'COMET' in object_name:
        obj = Horizons(id=object_name,
                       epochs={
                           'start': start_date,
                           'stop': end_date,
                           'step': time_step
                       })
    eph = obj.ephemerides()
    pos = SkyCoord(eph['RA'], eph['DEC'], unit='deg')
    vec = obj.vectors()
    times = Time(np.asarray(vec['datetime_jd']), format='jd', scale='utc')
    return np.asarray(pos.ra), np.asarray(pos.dec), times, np.asarray(
        eph['RA_rate']), np.asarray(eph['DEC_rate']), np.asarray(eph['V'])
Beispiel #29
0
def update_bodies(bodies_raw):
    for body in bodies_raw['bodies']:
        for naif_id_key, value in body.items():
            name = value['name']
            value['rgb'] = [255, 255, 255]
            obj = Horizons(
                id=naif_id_key,
                location='500@0',
                epochs={
                    'start': '2018-03-06',
                    'stop': '2018-03-07',
                    'step': '1d'
                },
                id_type='majorbody',
            )
            s_vec = obj.vectors(get_raw_response=True)
            print(name)
            # Get name
            value['name_horizons'] = __get_name(s_vec, value['name'])
            # Get mass
            value['mass'] = __get_mass(s_vec)
            # Get radius
            value['radius'] = __get_radius(s_vec)
            # Get position
            if not 'position' in value:
                value['position'] = [
                    0.0,
                    0.0,
                    0.0,
                ]
            if not 'speed' in value:
                value['speed'] = [
                    0.0,
                    0.0,
                    0.0,
                ]
            __get_position(s_vec, value['position'], value['speed'])
Beispiel #30
0
def get_heliocentric_equatorial_XYZ_from_JPL(times, obs_code='500',
                                            verbose=False):
    '''
    Query horizons for the EQUATORIAL heliocentric
    observatory position at a sequence of times.

    input:
    obs_code    - string
                - Note that Horizons uses some weird ones sometimes,
                  like "500@-95" for Tess.
    times       - array of JD times (UTC)
    '''
    from astroquery.jplhorizons import Horizons
    times_AP = Time(times, format='jd', scale='utc')
    # convert times to tdb
    times_tdb = times_AP.tdb.value
    horizons_query = Horizons(id='10', location=obs_code,
                              epochs=times_tdb, id_type='id')
    horizons_vector = horizons_query.vectors(refplane='earth')
    helio_OBS_equ = 0 - np.array([horizons_vector['x'], horizons_vector['y'],
                                  horizons_vector['z']]).T
    if verbose:
        print('No verbosity implemented yet, sorry')
    return helio_OBS_equ
Beispiel #31
0
def get_horizons_coord(body, time='now', id_type='majorbody'):
    """
    Queries JPL HORIZONS and returns a `~astropy.coordinates.SkyCoord` for the location of a
    solar-system body at a specified time.  This location is the instantaneous or "true" location,
    and is not corrected for light travel time or observer motion.  This function requires the
    Astroquery package to be installed and requires an Internet connection.

    Parameters
    ----------
    body : `str`
        The solar-system body for which to calculate positions
    id_type : `str`
        If 'majorbody', search by name for planets or satellites.  If 'id', search by ID number.
    time : various
        Time to use as `~astropy.time.Time` or in a parse_time-compatible format

    Returns
    -------
    `~astropy.coordinates.SkyCoord`
        Location of the solar-system body

    Notes
    -----
    Be aware that there can be discrepancies between the coordinates returned by JPL HORIZONS,
    the coordinates reported in mission data files, and the coordinates returned by
    `~sunpy.coordinates.get_body_heliographic_stonyhurst`.

    References
    ----------
    * `JPL HORIZONS <https://ssd.jpl.nasa.gov/?horizons>`_
    * `Astroquery <https://astroquery.readthedocs.io/en/latest/>`_

    Examples
    --------
    .. Run these tests with a temp cache dir
    .. testsetup::
        >>> from astropy.config.paths import set_temp_cache
        >>> import tempfile
        >>> c = set_temp_cache(tempfile.mkdtemp())
        >>> _ = c.__enter__()

    >>> from sunpy.coordinates import get_horizons_coord

    Query the location of Venus

    >>> get_horizons_coord('Venus barycenter', '2001-02-03 04:05:06')  # doctest: +REMOTE_DATA
    INFO: Obtained JPL HORIZONS location for Venus Barycenter (2) [sunpy.coordinates.ephemeris]
    <SkyCoord (HeliographicStonyhurst: obstime=2001-02-03T04:05:06.000): (lon, lat, radius) in (deg, deg, AU)
        (326.06844114, -1.64998481, 0.71915147)>

    Query the location of the SDO spacecraft

    >>> get_horizons_coord('SDO', '2011-11-11 11:11:11')  # doctest: +REMOTE_DATA
    INFO: Obtained JPL HORIZONS location for Solar Dynamics Observatory (spac [sunpy.coordinates.ephemeris]
    <SkyCoord (HeliographicStonyhurst: obstime=2011-11-11T11:11:11.000): (lon, lat, radius) in (deg, deg, AU)
        (0.01018888, 3.29640407, 0.99011042)>

    Query the location of the SOHO spacecraft via its ID number (-21)

    >>> get_horizons_coord(-21, '2004-05-06 11:22:33', 'id')  # doctest: +REMOTE_DATA
    INFO: Obtained JPL HORIZONS location for SOHO (spacecraft) (-21) [sunpy.coordinates.ephemeris]
    <SkyCoord (HeliographicStonyhurst: obstime=2004-05-06T11:22:33.000): (lon, lat, radius) in (deg, deg, AU)
        (0.2523461, -3.55863351, 0.99923086)>

    .. testcleanup::
        >>> _ = c.__exit__()
    """
    obstime = parse_time(time)

    # Import here so that astroquery is not a module-level dependency
    from astroquery.jplhorizons import Horizons
    query = Horizons(id=body, id_type=id_type,
                     location='500@10',      # Heliocentric (mean ecliptic)
                     epochs=obstime.tdb.jd)  # Time must be provided in JD TDB
    try:
        result = query.vectors()
    except Exception:  # Catch and re-raise all exceptions, and also provide query URL if generated
        if query.uri is not None:
            log.error(f"See the raw output from the JPL HORIZONS query at {query.uri}")
        raise
    log.info(f"Obtained JPL HORIZONS location for {result[0]['targetname']}")

    vector = CartesianRepresentation(result[0]['x', 'y', 'z'])*u.AU
    coord = SkyCoord(vector, frame=HeliocentricMeanEcliptic, obstime=obstime)

    return coord.transform_to(HGS)