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
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())
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
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']])
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)
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]))
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
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
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
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
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
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
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
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
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)
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
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)
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())
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]))
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
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'])
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'])
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
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)