def get_unnamed_object(target_ra, target_dec, tstamp, pressure=0.0, temperature=0.0, relative_humidity=0.0, obswl=1): """Give ra and dec in degrees, return the Astropy SkyCoord object target_ra, target_dec are floating point RA, DEC values as decimal degrees tstamp is a datetime or Time object""" if (target_ra is None) or (target_dec is None): return p = pressure * u.hPa t = temperature * u.deg_C rh = relative_humidity * u.dimensionless_unscaled obswl = obswl * u.micron solar_system_ephemeris.set('jpl') obsloc = observatory_location() if not isinstance(tstamp, Time): tstamp = Time(tstamp, format='datetime', scale='utc') target = SkyCoord(target_ra * u.deg, target_dec * u.deg, frame='icrs') return target.transform_to( AltAz(obstime=tstamp, location=obsloc, pressure=p, temperature=t, relative_humidity=rh, obswl=obswl))
def galactic(tstart=None, tend=None, tstep=None, time=None): if time is not None and (tstart is not None or tend is not None or tstep is not None): raise AssertionError( 'Must enter one time, or a start time, end time, and time step') elif time is not None: with solar_system_ephemeris.set('jpl'): jup_ephem = get_body('sun', time).galactic elif time is None and (tstart is None or tend is None or tstep is None): raise AssertionError('Must enter start time, end time, and time step') elif time is None and (tstart is not None and tend is not None and tstep is not None): # tstart = tstart.mjd + (tstep/2) #use this line if you want times in the center of timeranges, dont use if you want coordinates at the time intervals themselves tstart = tstart.mjd # use if you want coordinates at time intervals not at center of intervals tend = tend.mjd times = np.arange(tstart, tend, tstep, dtype=float) times_list = Time(times, format='mjd').fits times_list = Time(times_list, format='fits') jup_ephem = list() for date in times_list: with solar_system_ephemeris.set('jpl'): jup = get_body('sun', date).galactic jup_ephem.append(jup) return jup_ephem
def test_solar_pressure(): # based on example 12.9 from Howard Curtis solar_system_ephemeris.set('de432s') j_date = 2438400.5 * u.day tof = 600 * u.day sun_r = build_ephem_interpolant(Sun, 365 * u.day, (j_date, j_date + tof), rtol=1e-2) epoch = Time(j_date, format='jd', scale='tdb') drag_force_orbit = [10085.44 * u.km, 0.025422 * u.one, 88.3924 * u.deg, 45.38124 * u.deg, 227.493 * u.deg, 343.4268 * u.deg] initial = Orbit.from_classical(Earth, *drag_force_orbit, epoch=epoch) # in Curtis, the mean distance to Sun is used. In order to validate against it, we have to do the same thing sun_normalized = functools.partial(normalize_to_Curtis, sun_r=sun_r) r, v = cowell(initial, np.linspace(0, (tof).to(u.s).value, 4000), rtol=1e-8, ad=radiation_pressure, R=Earth.R.to(u.km).value, C_R=2.0, A=2e-4, m=100, Wdivc_s=Sun.Wdivc.value, star=sun_normalized) delta_as, delta_eccs, delta_incs, delta_raans, delta_argps, delta_hs = [], [], [], [], [], [] for ri, vi in zip(r, v): orbit_params = rv2coe(Earth.k.to(u.km**3 / u.s**2).value, ri, vi) delta_eccs.append(orbit_params[1] - drag_force_orbit[1].value) delta_incs.append((orbit_params[2] * u.rad).to(u.deg).value - drag_force_orbit[2].value) delta_raans.append((orbit_params[3] * u.rad).to(u.deg).value - drag_force_orbit[3].value) delta_argps.append((orbit_params[4] * u.rad).to(u.deg).value - drag_force_orbit[4].value) # averaging over 5 last values in the way Curtis does for check in solar_pressure_checks: index = int(1.0 * check['t_days'] / tof.to(u.day).value * 4000) delta_ecc, delta_inc, delta_raan, delta_argp = np.mean(delta_eccs[index - 5:index]), \ np.mean(delta_incs[index - 5:index]), np.mean(delta_raans[index - 5:index]), \ np.mean(delta_argps[index - 5:index]) assert_quantity_allclose([delta_ecc, delta_inc, delta_raan, delta_argp], check['deltas_expected'], rtol=1e-1, atol=1e-4)
def sun_position(obs_time): location = EarthLocation(lon=115.2505 * u.deg, lat=42.211833333 * u.deg, height=1365.0 * u.m) solar_system_ephemeris.set('de432s') # GCRS phasecentre = get_body('sun', obs_time, location, ephemeris='jpl') print('SUN: RA:{} Dec:{}'.format(phasecentre.ra.value, phasecentre.dec.value)) # convert phasecentre into ITRS coordinate # ITRF - Alta cAltAz = phasecentre.transform_to( AltAz(obstime=obs_time, location=location)) newAltAzcoordiantes = SkyCoord(alt=cAltAz.alt, az=cAltAz.az, obstime=obs_time, frame='altaz') new_ra_dec = newAltAzcoordiantes.transform_to('icrs') print(new_ra_dec) c_ITRS = phasecentre.transform_to(ITRS(obstime=obs_time, location=location)) local_ha = location.lon - c_ITRS.spherical.lon local_ha.wrap_at(24 * u.hourangle, inplace=True) print("UTC: {} Local Hour Angle: {}".format(obs_time, local_ha.to('deg').value)) obs_time1 = Time(obs_time, scale='utc', location=location) lst = obs_time1.sidereal_time('mean') local_ha1 = lst.to('deg').value - phasecentre.ra.value print("UTC: {} Local Hour Angle: {}".format(obs_time, local_ha1 * u.deg))
def roemer_delay(epoch, ecl_latitude, ecl_longitude, ephemeris='de432s'): """ Computes the Roemer timing delay about the Solar System Barycentre at the position the Earth, given a set of ecliptic coordinates for a given pulsar. Parameters ---------- epoch : array_like, float observation timestamp(s) where delay is evaluated, in MJD format. ecl_longitudeatitude : float ecliptic latitude, in units of degrees. ecl_longitude = : float ecliptic longitude, in units of degrees. Returns ------- delay: array_like, float time delay due to orbital motion of the Earth, in seconds. """ # before computing anythin, set the ephemeris context to be value # supplied at the function call. solar_system_ephemeris.set(ephemeris) time = Time(epoch, format='mjd') # now comoute the required position vectors. r_earth = get_body_barycentric('earth', time) s_pulsar = pulsar_position_ecliptic(ecl_latitude, ecl_longitude) # finally, compute and return the delay. delay = r_earth.dot(s_pulsar).to(u.m) / c return delay
def test_3rd_body_Curtis(test_params): # based on example 12.11 from Howard Curtis body = test_params['body'] solar_system_ephemeris.set('de432s') j_date = 2454283.0 * u.day tof = (test_params['tof']).to(u.s).value body_r = build_ephem_interpolant(body, test_params['period'], (j_date, j_date + test_params['tof']), rtol=1e-2) epoch = Time(j_date, format='jd', scale='tdb') initial = Orbit.from_classical(Earth, *test_params['orbit'], epoch=epoch) r, v = cowell(initial, np.linspace(0, tof, 400), rtol=1e-10, ad=third_body, k_third=body.k.to(u.km**3 / u.s**2).value, third_body=body_r) incs, raans, argps = [], [], [] for ri, vi in zip(r, v): angles = Angle(rv2coe(Earth.k.to(u.km**3 / u.s**2).value, ri, vi)[2:5] * u.rad) # inc, raan, argp angles = angles.wrap_at(180 * u.deg) incs.append(angles[0].value) raans.append(angles[1].value) argps.append(angles[2].value) # averaging over 5 last values in the way Curtis does inc_f, raan_f, argp_f = np.mean(incs[-5:]), np.mean(raans[-5:]), np.mean(argps[-5:]) assert_quantity_allclose([(raan_f * u.rad).to(u.deg) - test_params['orbit'][3], (inc_f * u.rad).to(u.deg) - test_params['orbit'][2], (argp_f * u.rad).to(u.deg) - test_params['orbit'][4]], [test_params['raan'], test_params['inc'], test_params['argp']], rtol=1e-1)
def calculate_trip(depart, arrive, date): t = Time(date) solar_system_ephemeris.set('builtin') start = get_body_barycentric(depart, t) end = get_body_barycentric(arrive, t) distance = ((start.x - end.x)**2 + (start.y - end.y)**2 + (start.z - end.z)**2)**(1/2) return distance.to(u.km)
def convert_azel(self, planet, times): on_coord = astropy.coordinates.get_body(location=self.nobeyama, time=times, body=planet) solar_system_ephemeris.set('de432s') #between 1950-2050 on_coord.location = self.nobeyama on_coord.pressure = self.press * u.hPa on_coord.temperature = self.temp * u.deg_C on_coord.relative_humidity = self.humid on_coord.obswl = (astropy.constants.c / (self.obswl * u.GHz)).to('micron') return on_coord.altaz
def __init__(self, bodies: list = ['moon', 'sun'], parts: list = ['zonal', 'tesseral', 'sectorial'], love: dict = iers2010.DEGREE2_LOVE_NUMBERS, gravimetric_factor: float = 1.1563, diminishing_factor: float = 0.6947, ephemeris: str = None): self.bodies = [body.lower() for body in bodies] solar_system_ephemeris.set(ephemeris) self.ephemeris = ephemeris for body in self.bodies: if body.lower() == 'pluto': raise ValueError('Pluto? Seriosly? No way. ' 'It is not even a planet!') if body.lower() in ('earth', 'earth-moon-barycenter'): raise ValueError( 'Do not include \'{0}\' for calculation of the Earth ' 'tides!'.format(body)) if body.lower() not in solar_system_ephemeris.bodies: raise ValueError('There is no ephemeris for {0}!'.format(body)) if body.lower() not in solar_system_gm.bodies: raise ValueError('There is no GM for {0}!'.format(body)) for part in parts: if part not in ('zonal', 'tesseral', 'sectorial'): raise ValueError('There are only zonal, ' 'tessseral and sectorial parts!') self.parts = parts if not all(item in love for item in ('k', 'l', 'h')): raise ValueError('All Love ("k", "l", "h") numbers should be ' 'specified!') self.love = love if gravimetric_factor is None: self.gravimetric_factor = 1 + self.love['h'] - \ 3 / 2 * self.love['k'] else: self.gravimetric_factor = gravimetric_factor if diminishing_factor is None: self.diminishing_factor = 1 + self.love['k'] - self.love['h'] else: self.diminishing_factor = diminishing_factor self.bodies_gm = self._get_bodies_gm()
def use_DE440s(): # This class is for test functions that need the Astropy ephemeris to be set to DE432s pytest.importorskip("astroquery") old_ephemeris = solar_system_ephemeris.get() try: solar_system_ephemeris.set('de440s') except ValueError: pytest.skip( "The installed version of Astropy cannot set the ephemeris to DE440s" ) yield solar_system_ephemeris.set(old_ephemeris)
def Get_Sun_Coordinates(self, cg, ctime): # # Get_Sun_Coordinates # # This method obtains the Sun Coordinates both in (Ra,Dec) and (Alt, Az) # While astropy may use very accurate calculations and corrections from # IERS, for some reason it cannot download the data. So, I decided to # work off-line with a lesser precision, although enoug for us. # # # @guiguesp - 2020-04-05 # - 2020-05-30 : Now using sunpy 1.1 #_____________________________________________________________________________ t = Time(ctime) with solar_system_ephemeris.set('builtin'): sun_radec = get_body('sun', t, cg) aa = AltAz(location=cg, obstime=t) sun_altaz = sun_radec.transform_to(aa) L0 = Sun_Coordinates.sun.L0(ctime) B0 = Sun_Coordinates.sun.B0(ctime) P = Sun_Coordinates.sun.P(ctime) R_Sun = Sun_Coordinates.sun.angular_radius(ctime) Carrington = Sun_Coordinates.sun.carrington_rotation_number(ctime) return sun_radec, sun_altaz, L0, B0, P, R_Sun, Carrington
def _select_solar_system(self, body: str) -> None: """Set RA/Dec for selected solar system body.""" from astropy.coordinates import solar_system_ephemeris, get_body # nothing? if body == "": return # clear simbad and JPL self.textSimbadName.clear() self.textJplHorizonsName.clear() QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) with solar_system_ephemeris.set("builtin"): # get coordinates body = get_body(body, Time.now(), self.observer.location) QtWidgets.QApplication.restoreOverrideCursor() # set them self.textMoveRA.setText( body.ra.to_string(unit=u.hour, sep=" ", precision=2)) self.textMoveDec.setText(body.dec.to_string(sep=" ", precision=2)) # update destination self._calc_dest_equatorial(clear=False)
def moon_coordinates(time, cam): """This function searches for the moon position at a given time. Parameters ----------- time: 'astropy.time.core.Time' Time the image was taken. cam: 'str' Camera Returns ------- moon_altitude: 'float' Altitude of the moon at the time the image was taken [radians] """ observer = cam.location object = 'moon' with solar_system_ephemeris.set('builtin'): coordinates = get_body(object, time, observer) ra = coordinates.ra dec = coordinates.dec moon_position = SkyCoord(ra=ra, dec=dec, frame='icrs', unit='deg') moon_position_altaz = moon_position.transform_to( AltAz(obstime=time, location=observer)) moon_altitude = moon_position_altaz.alt.radian print('time', type(time)) return moon_altitude
def test_3rd_body_Curtis(test_params): # based on example 12.11 from Howard Curtis body = test_params['body'] with solar_system_ephemeris.set('builtin'): j_date = 2454283.0 * u.day tof = (test_params['tof']).to(u.s).value body_r = build_ephem_interpolant(body, test_params['period'], (j_date, j_date + test_params['tof']), rtol=1e-2) epoch = Time(j_date, format='jd', scale='tdb') initial = Orbit.from_classical(Earth, *test_params['orbit'], epoch=epoch) r, v = cowell(initial, np.linspace(0, tof, 400), rtol=1e-10, ad=third_body, k_third=body.k.to(u.km**3 / u.s**2).value, third_body=body_r) incs, raans, argps = [], [], [] for ri, vi in zip(r, v): angles = Angle(rv2coe(Earth.k.to(u.km**3 / u.s**2).value, ri, vi)[2:5] * u.rad) # inc, raan, argp angles = angles.wrap_at(180 * u.deg) incs.append(angles[0].value) raans.append(angles[1].value) argps.append(angles[2].value) # averaging over 5 last values in the way Curtis does inc_f, raan_f, argp_f = np.mean(incs[-5:]), np.mean(raans[-5:]), np.mean(argps[-5:]) assert_quantity_allclose([(raan_f * u.rad).to(u.deg) - test_params['orbit'][3], (inc_f * u.rad).to(u.deg) - test_params['orbit'][2], (argp_f * u.rad).to(u.deg) - test_params['orbit'][4]], [test_params['raan'], test_params['inc'], test_params['argp']], rtol=1e-1)
def planet(body, obs_loc, t=None): if t is None: t = datetime.utcnow() body = body.lower() if not body in solar_system_ephemeris.bodies: raise Exception("Body not available!") if type(obs_loc) == str and obs_loc in cities.keys(): lon, lat = cities[obs_loc][:-1] elif isinstance(obs_loc, tuple): if len(obs_loc) == 2: lon, lat = obs_loc else: raise Exception("obs_loc should be in the format: (lon, lat)") else: raise Exception( "obs_loc should be a city name or geographic coordiantes.") loc = EarthLocation(lon=lon, lat=lat) with solar_system_ephemeris.set('jpl'): crd = get_body(body, Time(t), loc) ra = crd.ra.value dec = crd.dec.value r = crd.distance.value x, y, z = radec_to_cartesian(ra, dec, r) alt, az = radec_to_altaz(lon=lon, lat=lat, ra=ra, dec=dec, t=t) return (x, y, z), (ra, dec, r), (az, alt)
def test_ephemerides(self): bval1 = self.obstime.light_travel_time(self.star, 'barycentric') with solar_system_ephemeris.set('jpl'): bval2 = self.obstime.light_travel_time(self.star, 'barycentric', ephemeris='jpl') # should differ by less than 0.1 ms, but not be the same assert abs(bval1 - bval2) < 1. * u.ms assert abs(bval1 - bval2) > 1. * u.us
def test_solar_pressure(): # based on example 12.9 from Howard Curtis with solar_system_ephemeris.set('builtin'): j_date = 2438400.5 * u.day tof = 600 * u.day sun_r = build_ephem_interpolant(Sun, 365 * u.day, (j_date, j_date + tof), rtol=1e-2) epoch = Time(j_date, format='jd', scale='tdb') drag_force_orbit = [10085.44 * u.km, 0.025422 * u.one, 88.3924 * u.deg, 45.38124 * u.deg, 227.493 * u.deg, 343.4268 * u.deg] initial = Orbit.from_classical(Earth, *drag_force_orbit, epoch=epoch) # in Curtis, the mean distance to Sun is used. In order to validate against it, we have to do the same thing sun_normalized = functools.partial(normalize_to_Curtis, sun_r=sun_r) r, v = cowell(initial, np.linspace(0, (tof).to(u.s).value, 4000), rtol=1e-8, ad=radiation_pressure, R=Earth.R.to(u.km).value, C_R=2.0, A=2e-4, m=100, Wdivc_s=Sun.Wdivc.value, star=sun_normalized) delta_eccs, delta_incs, delta_raans, delta_argps = [], [], [], [] for ri, vi in zip(r, v): orbit_params = rv2coe(Earth.k.to(u.km**3 / u.s**2).value, ri, vi) delta_eccs.append(orbit_params[1] - drag_force_orbit[1].value) delta_incs.append((orbit_params[2] * u.rad).to(u.deg).value - drag_force_orbit[2].value) delta_raans.append((orbit_params[3] * u.rad).to(u.deg).value - drag_force_orbit[3].value) delta_argps.append((orbit_params[4] * u.rad).to(u.deg).value - drag_force_orbit[4].value) # averaging over 5 last values in the way Curtis does for check in solar_pressure_checks: index = int(1.0 * check['t_days'] / tof.to(u.day).value * 4000) delta_ecc, delta_inc, delta_raan, delta_argp = np.mean(delta_eccs[index - 5:index]), \ np.mean(delta_incs[index - 5:index]), np.mean(delta_raans[index - 5:index]), \ np.mean(delta_argps[index - 5:index]) assert_quantity_allclose([delta_ecc, delta_inc, delta_raan, delta_argp], check['deltas_expected'], rtol=1e-1, atol=1e-4)
def get_planet_info(): planet_info = [] with solar_system_ephemeris.set('de432s'): for planet_name in planets: planet = get_body(planet_name, current_time, location) planet_info.append({ "name": planet_name, "lightMinutes": to_light_minutes(planet.distance), "xyz": get_xyz(planet) }) sun = get_sun(current_time) planet_info.append({ "name": "The Sun", "lightMinutes": to_light_minutes(sun.distance), "xyz": get_xyz(sun) }) moon = get_moon(current_time) planet_info.append({ "name": "The Moon", "lightMinutes": to_light_minutes(moon.distance), "xyz": get_xyz(moon) }) return json.dumps(planet_info)
def test_aa_high_precision(): """ These tests are provided by @mkbrewer - see issue #10356. The code that produces them agrees very well (<0.5 mas) with SkyField once Polar motion is turned off, but SkyField does not include polar motion, so a comparison to Skyfield or JPL Horizons will be ~1" off. The absence of polar motion within Skyfield and the disagreement between Skyfield and Horizons make high precision comparisons to those codes difficult. """ lat = -22.959748 * u.deg lon = -67.787260 * u.deg elev = 5186 * u.m loc = EarthLocation.from_geodetic(lon, lat, elev) t = Time('2017-04-06T00:00:00.0') with solar_system_ephemeris.set('de430'): moon = get_body('moon', t, loc) moon_aa = moon.transform_to(AltAz(obstime=t, location=loc)) TARGET_AZ, TARGET_EL = 15.0326735105 * u.deg, 50.3031101339 * u.deg TARGET_DISTANCE = 376252883.2473 * u.m assert_allclose(moon_aa.az, TARGET_AZ, atol=2 * u.uas, rtol=0) assert_allclose(moon_aa.alt, TARGET_EL, atol=2 * u.uas, rtol=0) assert_allclose(moon_aa.distance, TARGET_DISTANCE, atol=2 * u.mm, rtol=0)
def annual_parallax(self, time_to_treat): """Compute the position shift due to the Earth movement. Please have a look on : "Resolution of the MACHO-LMC-5 Puzzle: The Jerk-Parallax Microlens Degeneracy" Gould, Andrew 2004. http://adsabs.harvard.edu/abs/2004ApJ...606..319G :param time_to_treat: a numpy array containing the time where you want to compute this effect. :return: the shift induce by the Earth motion around the Sun :rtype: array_like **WARNING** : this is a geocentric point of view. slalib use MJD time definition, which is MJD = JD-2400000.5 """ with solar_system_ephemeris.set('builtin'): time_jd_reference = Time(self.to_par, format='jd') Earth_position_time_reference = get_body_barycentric_posvel('Earth', time_jd_reference) Sun_position_time_reference = -Earth_position_time_reference[0] Sun_speed_time_reference = -Earth_position_time_reference[1] time_jd = Time(time_to_treat, format='jd') Earth_position = get_body_barycentric_posvel('Earth', time_jd) Sun_position = -Earth_position[0] delta_Sun = Sun_position.xyz.value.T - np.c_[ time_to_treat - self.to_par] * Sun_speed_time_reference.xyz.value \ - Sun_position_time_reference.xyz.value delta_Sun_projected = np.array( [np.dot(delta_Sun, self.North), np.dot(delta_Sun, self.East)]) return delta_Sun_projected
def test_solar_pressure(t_days, deltas_expected, sun_r): # based on example 12.9 from Howard Curtis with solar_system_ephemeris.set("builtin"): j_date = 2_438_400.5 * u.day tof = 600 * u.day epoch = Time(j_date, format="jd", scale="tdb") initial = Orbit.from_classical( Earth, 10085.44 * u.km, 0.025422 * u.one, 88.3924 * u.deg, 45.38124 * u.deg, 227.493 * u.deg, 343.4268 * u.deg, epoch=epoch, ) # in Curtis, the mean distance to Sun is used. In order to validate against it, we have to do the same thing sun_normalized = functools.partial(normalize_to_Curtis, sun_r=sun_r) rr, vv = cowell( Earth.k, initial.r, initial.v, np.linspace(0, (tof).to(u.s).value, 4000) * u.s, rtol=1e-8, ad=radiation_pressure, R=Earth.R.to(u.km).value, C_R=2.0, A_over_m=2e-4 / 100, Wdivc_s=Wdivc_sun.value, star=sun_normalized, ) delta_eccs, delta_incs, delta_raans, delta_argps = [], [], [], [] for ri, vi in zip(rr.to(u.km).value, vv.to(u.km / u.s).value): orbit_params = rv2coe(Earth.k.to(u.km**3 / u.s**2).value, ri, vi) delta_eccs.append(orbit_params[1] - initial.ecc.value) delta_incs.append((orbit_params[2] * u.rad).to(u.deg).value - initial.inc.value) delta_raans.append((orbit_params[3] * u.rad).to(u.deg).value - initial.raan.value) delta_argps.append((orbit_params[4] * u.rad).to(u.deg).value - initial.argp.value) # averaging over 5 last values in the way Curtis does index = int(1.0 * t_days / tof.to(u.day).value * 4000 # type: ignore ) delta_ecc, delta_inc, delta_raan, delta_argp = ( np.mean(delta_eccs[index - 5:index]), np.mean(delta_incs[index - 5:index]), np.mean(delta_raans[index - 5:index]), np.mean(delta_argps[index - 5:index]), ) assert_quantity_allclose( [delta_ecc, delta_inc, delta_raan, delta_argp], deltas_expected, rtol=1e0, # TODO: Excessively low, rewrite test? atol=1e-4, )
def solarbody_to_radec( body, location, timestamp, # default output in degrees as_radians=False, as_string=False): """Calculate equatorial (ra, dec) for solar body ephemerides Parameters ---------- body: Name of solar body, Astropy convention location: Telescope geocentric position, `Astropy.EarthLocaton` timestamp: Unix timestamp Returns ------- tuple: (ra, dec) equatorial coordinates in degrees """ obs_time = timestamp2datetime(timestamp) obs_time = obs_time.strftime("%Y-%m-%d %H:%M:%S") obs_time = Time(obs_time) with solar_system_ephemeris.set('builtin'): solar_gcrs = get_body(body, obs_time, location) return radec_from_pointing_object(solar_gcrs, as_radians=as_radians, as_string=as_string)
def test_ephemerides(self): bval1 = self.obstime.light_travel_time(self.star, 'barycentric') with solar_system_ephemeris.set('jpl'): bval2 = self.obstime.light_travel_time(self.star, 'barycentric', ephemeris='jpl') # should differ by less than 0.1 ms, but not be the same assert abs(bval1 - bval2) < 1. * u.ms assert abs(bval1 - bval2) > 1. * u.us
def get_mars_ephemeris(timedate): """ Get the ephemeris of Mars given a particular julian date """ t = Time(timedate) with solar_system_ephemeris.set('builtin'): mars = get_body('mars', t) return mars
def test_icrs_body_position_to_planetary_frame_yields_zeros(body, frame): with solar_system_ephemeris.set("builtin"): epoch = J2000 vector = get_body_barycentric(body.name, epoch) vector_result = ICRS(vector).transform_to(frame(obstime=epoch)).represent_as(CartesianRepresentation) assert_quantity_allclose(vector_result.xyz, [0, 0, 0] * u.km, atol=1e-7 * u.km)
def __init__(self, day): self.day = day at = AstropyTime(day, format='datetime', scale='utc') with solar_system_ephemeris.set('builtin'): sun = get_sun(at) self.sun_ecliptic = self._cartesian( sun.transform_to(GeocentricMeanEcliptic)) self.sun = self._cartesian(sun) self.moon = self._cartesian(get_moon(at))
def jupLoc(tt, dd, loc): ds = str(dd[0]) + '-' + str(dd[1]) + '-' + str(dd[2]) ts = str(tt[0]) + ':' + str(tt[1]) + ':' + str(tt[2]) t = Time(ds + ' ' + ts) # loc = EarthLocation.of_site('Kitt Peak') with solar_system_ephemeris.set('builtin'): jup_loc = get_body('jupiter', t, loc) return jup_loc.ra, jup_loc.dec
def test_planetary_icrs_frame_is_just_translation(body, frame): with solar_system_ephemeris.set("builtin"): epoch = J2000 vector = CartesianRepresentation(x=100 * u.km, y=100 * u.km, z=100 * u.km) vector_result = frame(vector, obstime=epoch).transform_to(ICRS).represent_as(CartesianRepresentation) expected_result = get_body_barycentric(body.name, epoch) + vector assert_quantity_allclose(vector_result.xyz, expected_result.xyz)
def parallax_delay(epoch, ecl_latitude, ecl_longitude, distance, ephemeris='de432s'): """ Computes the annual-parallax timing delay for the Earth, given a set of ecliptic coordinates and distance measure. Parameters ---------- epoch : array_like, float observation timestamp(s) where delay is evaluated, in MJD format. ecl_latitude : float ecliptic latitude, in units of degrees. ecl_longitude : float ecliptic longitude, in units of degrees. distance : float distance to the pulsar or pulsar-binary system, in units of kpc. Returns ------- delay : array_like, dloat time delay due to parallax motion, in seconds. """ # before computing anythin, set the ephemeris context to be value # supplied at the function call. solar_system_ephemeris.set(ephemeris) time = Time(epoch, format='mjd') distance *= u.kpc # now comoute the required position vectors. r_earth = get_body_barycentric('earth', time) s_pulsar = pulsar_position_ecliptic(ecl_latitude, ecl_longitude) r_cross_s = r_earth.cross(s_pulsar) # finally, compute and return the delay. delay = r_cross_s.dot(r_cross_s).to(u.m**2) / 2 / c / distance.to(u.m) return delay
def test_icrs_body_position_to_planetary_frame_yields_zeros(body, frame): with solar_system_ephemeris.set("builtin"): epoch = J2000 vector = get_body_barycentric(body.name, epoch) vector_result = (ICRS(vector).transform_to( frame(obstime=epoch)).represent_as(CartesianRepresentation)) assert_quantity_allclose(vector_result.xyz, [0, 0, 0] * u.km, atol=1e-7 * u.km)
def test_3rd_body_Curtis(test_params): # based on example 12.11 from Howard Curtis body = test_params["body"] with solar_system_ephemeris.set("builtin"): j_date = 2454283.0 * u.day tof = (test_params["tof"]).to(u.s).value body_r = build_ephem_interpolant( body, test_params["period"], (j_date, j_date + test_params["tof"]), rtol=1e-2, ) epoch = Time(j_date, format="jd", scale="tdb") initial = Orbit.from_classical(Earth, *test_params["orbit"], epoch=epoch) rr, vv = cowell( Earth.k, initial.r, initial.v, np.linspace(0, tof, 400) * u.s, rtol=1e-10, ad=third_body, k_third=body.k.to(u.km**3 / u.s**2).value, perturbation_body=body_r, ) incs, raans, argps = [], [], [] for ri, vi in zip(rr.to(u.km).value, vv.to(u.km / u.s).value): angles = Angle( rv2coe(Earth.k.to(u.km**3 / u.s**2).value, ri, vi)[2:5] * u.rad) # inc, raan, argp angles = angles.wrap_at(180 * u.deg) incs.append(angles[0].value) raans.append(angles[1].value) argps.append(angles[2].value) # averaging over 5 last values in the way Curtis does inc_f, raan_f, argp_f = ( np.mean(incs[-5:]), np.mean(raans[-5:]), np.mean(argps[-5:]), ) assert_quantity_allclose( [ (raan_f * u.rad).to(u.deg) - test_params["orbit"][3], (inc_f * u.rad).to(u.deg) - test_params["orbit"][2], (argp_f * u.rad).to(u.deg) - test_params["orbit"][4], ], [test_params["raan"], test_params["inc"], test_params["argp"]], rtol=1e-1, )
def test_planetary_icrs_frame_is_just_translation(body, frame): with solar_system_ephemeris.set("builtin"): epoch = J2000 vector = CartesianRepresentation(x=100 * u.km, y=100 * u.km, z=100 * u.km) vector_result = (frame(vector, obstime=epoch).transform_to( ICRS).represent_as(CartesianRepresentation)) expected_result = get_body_barycentric(body.name, epoch) + vector assert_quantity_allclose(vector_result.xyz, expected_result.xyz)
def dist_chart(asteroid, date, timespan): solar_system_ephemeris.set('jpl') EPOCH = Time(date, scale="tdb") epochs = time_range(EPOCH - TimeDelta(timespan), end=EPOCH + TimeDelta(timespan)) epochs_moon = time_range(EPOCH - TimeDelta(15 * u.day), end=EPOCH + TimeDelta(15 * u.day)) moon = Ephem.from_body(Moon, epochs_moon, attractor=Earth) aster = Ephem.from_horizons(asteroid, epochs, attractor=Earth) plotter = StaticOrbitPlotter() plotter.set_attractor(Earth) plotter.set_body_frame(Moon) plotter.plot_ephem(moon, EPOCH, label=Moon) plotter.plot_ephem(aster, EPOCH, label=asteroid) return plotter
def galactic(obj=None, frame=None, tstart=None, tend=None, tstep=None, time=None, mode=None): if mode is None: raise AssertionError('Must specify mode: either center times (c) or boundary times (b).') if time is not None and (tstart is not None or tend is not None or tstep is not None): raise AssertionError('Must enter one time, or a start time, end time, and time step') elif time is not None: with solar_system_ephemeris.set('jpl'): jup = get_body(obj, date) ra = jup.ra.value dec = jup.dec.value time = jup.obstime.value jup_ephem = SkyCoord(ra, dec, frame=frame, unit='deg', obstime=time) elif time is None and (tstart is None or tend is None or tstep is None): raise AssertionError('Must enter start time, end time, and time step') elif time is None and (tstart is not None and tend is not None and tstep is not None): if mode == 'c': tstart = tstart.mjd + (tstep/2) #use this line if you want times in the center of timeranges, dont use if you want coordinates at the time intervals themselves elif mode == 'b': tstart= tstart.mjd # use if you want coordinates at time intervals not at center of intervals tend = tend.mjd times = np.arange(tstart, tend, tstep, dtype=float) times_list = Time(times, format='mjd').fits times_list = Time(times_list, format='fits') jup_ephem = list() for date in times_list: with solar_system_ephemeris.set('jpl'): jup = get_body(obj, date) ra = jup.ra.value dec = jup.dec.value time = jup.obstime.value jup2 = SkyCoord(ra, dec, frame=frame, unit='deg', obstime=time) jup_ephem.append(jup2.galactic) return jup_ephem
def test_3rd_body_Curtis(test_params): # based on example 12.11 from Howard Curtis body = test_params["body"] with solar_system_ephemeris.set("builtin"): j_date = 2454283.0 * u.day tof = (test_params["tof"]).to(u.s).value body_r = build_ephem_interpolant( body, test_params["period"], (j_date, j_date + test_params["tof"]), rtol=1e-2, ) epoch = Time(j_date, format="jd", scale="tdb") initial = Orbit.from_classical(Earth, *test_params["orbit"], epoch=epoch) rr, vv = cowell( Earth.k, initial.r, initial.v, np.linspace(0, tof, 400) * u.s, rtol=1e-10, ad=third_body, k_third=body.k.to(u.km ** 3 / u.s ** 2).value, third_body=body_r, ) incs, raans, argps = [], [], [] for ri, vi in zip(rr.to(u.km).value, vv.to(u.km / u.s).value): angles = Angle( rv2coe(Earth.k.to(u.km ** 3 / u.s ** 2).value, ri, vi)[2:5] * u.rad ) # inc, raan, argp angles = angles.wrap_at(180 * u.deg) incs.append(angles[0].value) raans.append(angles[1].value) argps.append(angles[2].value) # averaging over 5 last values in the way Curtis does inc_f, raan_f, argp_f = ( np.mean(incs[-5:]), np.mean(raans[-5:]), np.mean(argps[-5:]), ) assert_quantity_allclose( [ (raan_f * u.rad).to(u.deg) - test_params["orbit"][3], (inc_f * u.rad).to(u.deg) - test_params["orbit"][2], (argp_f * u.rad).to(u.deg) - test_params["orbit"][4], ], [test_params["raan"], test_params["inc"], test_params["argp"]], rtol=1e-1, )
def test_planetary_inertial_fixed_conversion(body, fixed_frame, inertial_frame): with solar_system_ephemeris.set("builtin"): epoch = J2000 inertial_position = inertial_frame( 0 * u.deg, 0 * u.deg, body.R, obstime=epoch, representation_type="spherical" ) fixed_position = inertial_position.transform_to(fixed_frame(obstime=epoch)) assert_quantity_allclose( fixed_position.spherical.distance, body.R, atol=1e-7 * u.km ) assert_quantity_allclose( inertial_position.spherical.distance, body.R, atol=1e-7 * u.km )
def get_jwst_position2(times, jwstpos, use_jpl_ephemeris=False): ''' This returns the pair of relative positions from the barycenter and heliocenter to JWST in that order as a tuple of two arrays, each of shape (len(times), 3). ''' t = Time(times, format="mjd", scale="tt") if use_jpl_ephemeris: from astropy.coordinates import solar_system_ephemeris solar_system_ephemeris.set('jpl') # Vectors from the solar-system barycenter to the center of the Earth. bary_earth = acoord.get_body_barycentric("earth", t) # Vectors from the solar-system barycenter to the center of the Sun. bary_sun = acoord.get_body_barycentric("sun", t) # Vectors from the center of the Sun to the center of the Earth. sun_earth = bary_earth - bary_sun # Convert to ordinary numpy arrays of 3-element vectors, in km. barysun_centerearth_pos = np.empty((len(t), 3), dtype=np.float64) barysun_centerearth_pos[:, 0] = bary_earth.x.si.value / 1000. barysun_centerearth_pos[:, 1] = bary_earth.y.si.value / 1000. barysun_centerearth_pos[:, 2] = bary_earth.z.si.value / 1000. centersun_centerearth_pos = np.empty((len(t), 3), dtype=np.float64) centersun_centerearth_pos[:, 0] = sun_earth.x.si.value / 1000. centersun_centerearth_pos[:, 1] = sun_earth.y.si.value / 1000. centersun_centerearth_pos[:, 2] = sun_earth.z.si.value / 1000. centerearth_jwst = jwstpos return (barysun_centerearth_pos + centerearth_jwst), \ (centersun_centerearth_pos + centerearth_jwst)
def test_ephemerides(): """ We test that using different ephemerides gives very similar results for transformations """ t = Time("2014-12-25T07:00") moon = SkyCoord(GCRS(318.10579159*u.deg, -11.65281165*u.deg, 365042.64880308*u.km, obstime=t)) icrs_frame = ICRS() hcrs_frame = HCRS(obstime=t) ecl_frame = HeliocentricTrueEcliptic(equinox=t) cirs_frame = CIRS(obstime=t) moon_icrs_builtin = moon.transform_to(icrs_frame) moon_hcrs_builtin = moon.transform_to(hcrs_frame) moon_helioecl_builtin = moon.transform_to(ecl_frame) moon_cirs_builtin = moon.transform_to(cirs_frame) with solar_system_ephemeris.set('jpl'): moon_icrs_jpl = moon.transform_to(icrs_frame) moon_hcrs_jpl = moon.transform_to(hcrs_frame) moon_helioecl_jpl = moon.transform_to(ecl_frame) moon_cirs_jpl = moon.transform_to(cirs_frame) # most transformations should differ by an amount which is # non-zero but of order milliarcsecs sep_icrs = moon_icrs_builtin.separation(moon_icrs_jpl) sep_hcrs = moon_hcrs_builtin.separation(moon_hcrs_jpl) sep_helioecl = moon_helioecl_builtin.separation(moon_helioecl_jpl) sep_cirs = moon_cirs_builtin.separation(moon_cirs_jpl) assert_allclose([sep_icrs, sep_hcrs, sep_helioecl], 0.0*u.deg, atol=10*u.mas) assert all(sep > 10*u.microarcsecond for sep in (sep_icrs, sep_hcrs, sep_helioecl)) # CIRS should be the same assert_allclose(sep_cirs, 0.0*u.deg, atol=1*u.microarcsecond)
# check ephemeris is in our current list if args.ephemeris.upper() not in EPH_URLS.keys(): print("Ephemeris '{}' is not allowed, use one of: {}".format(args.ephemeris, EPH_URLS.keys())) sys.exit(1) else: ephemfile = EPH_URLS[args.ephemeris.upper()] # check that the body is in our current list if args.target.lower() not in BODIES: print("Target body '{}' is not in the allowed list: {}".format(args.target, BODIES)) sys.exit(1) else: body = args.target.lower() if args.target.lower() != 'earth-moon-barycentre' else 'earth-moon-barycenter' # set the ephemeris file solar_system_ephemeris.set(ephemfile) # set the start time if args.gpsstart is not None and args.yearstart is not None: print("Specify either '--gps-start' or '--year-start', but not both") sys.exit(1) elif args.gpsstart is not None: try: starttime = Time(args.gpsstart, format='gps', scale='utc') except ValueError: Exception("Could not parse start GPS time: {}".format(args.gpsstart)) else: try: starttime = Time(args.yearstart, format='decimalyear', scale='utc') except ValueError: Exception("Could not parse start year: {}".format(args.yearstart))
if MIDPOINT_RETRO in flags: l.append("Retrograde midpoint") return ', '.join(l) if __name__ == '__main__': # PEEC Los Alamos: # Google Maps lookups sometimes fail, # especially if you run over and over while testing. # loc = EarthLocation.of_address('2600 Canyon Road, Los Alamos, New Mexico 87544') # So instead, specify coordinates directly: loc = EarthLocation.from_geodetic('-106:18.36', '35:53.09', 2100.) # I'm not clear what this does, or what is used if you don't # specify builtin: solar_system_ephemeris.set('builtin') parser = argparse.ArgumentParser() parser.add_argument('-w', "--window", dest="window", default=False, action="store_true", help="Show a graphical window") args = parser.parse_args(sys.argv[1:]) start_date = Time('2018-06-25 00:00') oppy = OppRetro(loc) try: oppy.find_opp_and_retro(start_date) except KeyboardInterrupt: print("Interrupt")