def test_itrs_vals_5133(): time = Time('2010-1-1') el = EarthLocation.from_geodetic(lon=20*u.deg, lat=45*u.deg, height=0*u.km) lons = [20, 30, 20]*u.deg lats = [44, 45, 45]*u.deg alts = [0, 0, 10]*u.km coos = [EarthLocation.from_geodetic(lon, lat, height=alt).get_itrs(time) for lon, lat, alt in zip(lons, lats, alts)] aaf = AltAz(obstime=time, location=el) aacs = [coo.transform_to(aaf) for coo in coos] assert all([coo.isscalar for coo in aacs]) # the ~1 arcsec tolerance is b/c aberration makes it not exact assert_quantity_allclose(aacs[0].az, 180*u.deg, atol=1*u.arcsec) assert aacs[0].alt < 0*u.deg assert aacs[0].distance > 50*u.km # it should *not* actually be 90 degrees, b/c constant latitude is not # straight east anywhere except the equator... but should be close-ish assert_quantity_allclose(aacs[1].az, 90*u.deg, atol=5*u.deg) assert aacs[1].alt < 0*u.deg assert aacs[1].distance > 50*u.km assert_quantity_allclose(aacs[2].alt, 90*u.deg, atol=1*u.arcsec) assert_quantity_allclose(aacs[2].distance, 10*u.km)
def compute_sun_time_offset(LONG, LAT): EL = el.from_geodetic(LONG, LAT) sidingSpringEL = el.from_geodetic(149.071111, -31.273333) ### calculate time offset: time_offsets = np.linspace(0, 24, num=24 * 6) full_night_times = time.Time.now() + time_offsets * u.hour full_night_aa_frames = AltAz(location=EL, obstime=full_night_times) sun = ((coor.get_sun(full_night_times).transform_to(full_night_aa_frames) ).alt.deg) s = 0 if sun[0] < -18: start = 0 else: while sun[s] > -18: s = s + 1 start = time_offsets[s] e = s + 1 while sun[e] < -18: e = e + 1 end = time_offsets[e] mid = time_offsets[s + (e - s) // 2] return [start, mid, end]
def test_itrs_vals_5133(): time = Time('2010-1-1') el = EarthLocation.from_geodetic(lon=20*u.deg, lat=45*u.deg, height=0*u.km) lons = [20, 30, 20]*u.deg lats = [44, 45, 45]*u.deg alts = [0, 0, 10]*u.km coos = [EarthLocation.from_geodetic(lon, lat, height=alt).get_itrs(time) for lon, lat, alt in zip(lons, lats, alts)] aaf = AltAz(obstime=time, location=el) aacs = [coo.transform_to(aaf) for coo in coos] assert all([coo.isscalar for coo in aacs]) # the ~1 arcsec tolerance is b/c aberration makes it not exact assert_quantity_allclose(aacs[0].az, 180*u.deg, atol=1*u.arcsec) assert aacs[0].alt < 0*u.deg assert aacs[0].distance > 50*u.km # it should *not* actually be 90 degrees, b/c constant latitude is not # straight east anywhere except the equator... but should be close-ish assert_quantity_allclose(aacs[1].az, 90*u.deg, atol=5*u.deg) assert aacs[1].alt < 0*u.deg assert aacs[1].distance > 50*u.km assert_quantity_allclose(aacs[2].alt, 90*u.deg, atol=1*u.arcsec) assert_quantity_allclose(aacs[2].distance, 10*u.km)
def visibility_altaz(self, source_radec, site, hardcoded=True): """ To each time grid point associates AltAz coordinates. :param source_radec: source coordinates (astropy SkyCoord object) :param site: (str) :return: """ if not hasattr(self, 'vis_points'): raise AttributeError( 'Must invoke visibility_points() before using this method') if not hardcoded: site_coords = EarthLocation.of_site(site) else: if site.lower() in ('north', 'roque de los muchachos'): site_coords = EarthLocation.from_geodetic( '342.1184', '28.7606', 2326. * u.meter) #site_coords = EarthLocation.from_geocentric(5327285.09211954, -1718777.11250295, 3051786.7327476, unit="m") elif site.lower() in ('south', 'paranal'): site_coords = EarthLocation.from_geodetic( '289.5972', '-24.6253', 2635. * u.meter) #site_coords = EarthLocation.from_geocentric(1946635.7979987, -5467633.94561753, -2642498.5212285, unit="m") else: raise Warning(f"{site} is not a valid site choice") self.altaz = source_radec.transform_to( AltAz(obstime=self.vis_points, location=site_coords)) return self
def compute_sun_time_offset(LONG,LAT): EL = el.from_geodetic( LONG , LAT ) sidingSpringEL = el.from_geodetic(149.071111, -31.273333) ### calculate time offset: time_offsets = np.linspace(0, 24, num=24 * 6) full_night_times = time.Time.now() + time_offsets * u.hour full_night_aa_frames = AltAz(location=EL, obstime=full_night_times) sun = ((coor.get_sun(full_night_times).transform_to(full_night_aa_frames)).alt.deg) s = 0 if sun[0] < -18: start = 0 else: while sun[s] > -18: s = s + 1 start = time_offsets[s] e = s + 1 while sun[e] < -18: e = e + 1 end = time_offsets[e] mid = time_offsets[s + (e - s) // 2] return [start, mid, end]
def find_parallax(self, date): '''Find the maximum parallax of self.planet on the given date from self.observer's location -- in other words, the difference in Mars' position between the observer's position and an observer at the same latitude but opposite longitude: this tells you you how much difference you would see from your position if Mars didn't move between your sunrise and sunset. ''' # To calculate from a point on the equator, set lat to 0. observer_loc = EarthLocation.from_geodetic(self.location.lon, self.location.lat, self.location.height) # Specify the anti-point. # This isn't really an antipode unless lat == 0. antipode_loc = EarthLocation.from_geodetic(-observer.lon, observer.lat, observer.height) # XXX Oops, astropy doesn't offer next_rising etc. # so we'll need a function to find that before this # function can be implemented since it only works # when the planet is on the horizon so both the observer # and the anti-observer can see it. risetime = find_next_rising(planetname, date) obs_planet = get_body(planetname, risetime, observer_loc) ant_planet = get_body(planetname, risetime, antipode_loc) # First, calculate it the straightforward way using the arctan: print() mars_dist_miles = mars.distance.km / 1.609344 print("Miles to Mars:", mars_dist_miles) earth_mean_radius = 3958.8 # in miles half_dist = earth_mean_radius * math.cos(observer_loc.lat) print("Distance between observers:", 2. * half_dist) par = 2. * math.atan(half_dist / mars_dist_miles) \ * 180. / math.pi * 3600. print("Calculated parallax (arcsec):", par) # See what astropy calculates as the difference between observations: print() print("parallax on %s: RA %f, dec %f" % (antipode.date, obs_planet.ra - ant_planet.ra, obs_planet.dec - ant_planet.dec)) total_par = (math.sqrt((obs_planet.ra.radians - ant_planet.ra.radians)**2 + (obs_planet.dec.radians - ant_planet.dec.radians)**2) * 180. * 3600. / math.pi) print("Total parallax (sum of squares): %f arcseconds" % total_par) print()
def barycorr(header, instrument='nirspec'): """ Calculate the barycentric correction using Astropy. Input: header (fits header): using the keywords UT, RA, and DEC Output: barycentric correction (float*u(km/s)) """ if instrument == 'nirspec': longitude = 360 - (155 + 28.7/60 ) # degrees latitude = 19 + 49.7/60 #degrees altitude = 4160. keck = EarthLocation.from_geodetic(lat=latitude*u.deg, lon=longitude*u.deg, height=altitude*u.m) date = Time(header['DATE-OBS'], scale='utc') jd = date.jd if jd >= 2458401.500000: # upgraded NIRSPEC ut = header['DATE-OBS'] + 'T' + header['UT'] ra = header['RA'] dec = header['DEC'] sc = SkyCoord('%s %s'%(ra, dec), unit=(u.hourangle, u.deg), equinox='J2000', frame='fk5') else: ut = header['DATE-OBS'] + 'T' + header['UTC'] ra = header['RA'] dec = header['DEC'] sc = SkyCoord(ra=ra*u.deg, dec=dec*u.deg, equinox='J2000', frame='fk5') barycorr = sc.radial_velocity_correction(obstime=Time(ut, scale='utc'), location=keck) elif instrument == 'apogee': longitude = 360 - (105 + 49.2/60 ) # degrees latitude = 32 + 46.8/60 #degrees altitude = 2798. apogee = EarthLocation.from_geodetic(lat=latitude*u.deg, lon=longitude*u.deg, height=altitude*u.m) ut = header['UT-MID'] ra = header['RA'] dec = header['DEC'] sc = SkyCoord(ra=ra*u.deg, dec=dec*u.deg, equinox='J2000', frame='fk5') #apogee = EarthLocation.of_site('Apache Point Observatory') barycorr = sc.radial_velocity_correction(obstime=Time(ut, scale='utc'), location=apogee) return barycorr.to(u.km/u.s)
def find_parallax(self, date): '''Find the maximum parallax of self.planet on the given date from self.observer's location -- in other words, the difference in Mars' position between the observer's position and an observer at the same latitude but opposite longitude: this tells you you how much difference you would see from your position if Mars didn't move between your sunrise and sunset. ''' # To calculate from a point on the equator, set lat to 0. observer_loc = EarthLocation.from_geodetic(self.location.lon, self.location.lat, self.location.height) # Specify the anti-point. # This isn't really an antipode unless lat == 0. antipode_loc = EarthLocation.from_geodetic(-observer.lon, observer.lat, observer.height) # XXX Oops, astropy doesn't offer next_rising etc. # so we'll need a function to find that before this # function can be implemented since it only works # when the planet is on the horizon so both the observer # and the anti-observer can see it. risetime = find_next_rising(planetname, date) obs_planet = get_body(planetname, risetime, observer_loc) ant_planet = get_body(planetname, risetime, antipode_loc) # First, calculate it the straightforward way using the arctan: print() mars_dist_miles = mars.distance.km / 1.609344 print("Miles to Mars:", mars_dist_miles) earth_mean_radius = 3958.8 # in miles half_dist = earth_mean_radius * math.cos(observer_loc.lat) print("Distance between observers:", 2. * half_dist) par = 2. * math.atan(half_dist / mars_dist_miles) \ * 180. / math.pi * 3600. print("Calculated parallax (arcsec):", par) # See what astropy calculates as the difference between observations: print() print("parallax on %s: RA %f, dec %f" % (antipode.date, obs_planet.ra - ant_planet.ra, obs_planet.dec - ant_planet.dec)) total_par = ( math.sqrt((obs_planet.ra.radians - ant_planet.ra.radians)**2 + (obs_planet.dec.radians - ant_planet.dec.radians)**2) * 180. * 3600. / math.pi) print("Total parallax (sum of squares): %f arcseconds" % total_par) print()
def vlsr_correction(obs_timestamp, ra, dec): # hcro loc = EarthLocation.from_geodetic(lat=40.8172439*u.deg, \ lon=-121.4698327*u.deg, \ height=986.0*u.m) # Correction for the Sun's motion in our own Galaxy sun = get_sun(Time(obs_timestamp)).icrs psun = SkyCoord(ra="18:03:50.29", \ dec="+30:00:16.8", \ frame="icrs", unit=(u.hourangle, u.deg)) vsun = -20.0 * u.km / u.s #Calculate the correction: T = Time('2010-03-26T15:16:33') # Source (Antenna) Direction. Make sure to transform to icrs SD = SkyCoord(ra=ra*u.hourangle, dec=dec*u.deg, frame='icrs', \ location = loc, obstime = T) # Calculate radial velocity and correct for Solar motion v = SD.cartesian.dot( psun.cartesian) * vsun - SD.radial_velocity_correction() return v.value
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 lla2ECEF(lat, lon, alt): """This function takes a position geodetic position (lon,lat,alt above ellipsiod) and converts into ECEF coodinates [m].""" # # Input # lon = geodetic latitude (WGS-84) # lat = geodetic latitude (WGS-84) # alt = altitude above ellipsoid (m) # Output # x = Position in ECEF (m) # y = Position in ECEF (m) # z = Position in ECEF (m) # FIXME: check if obstime is needed el = EarthLocation.from_geodetic(lon, lat, alt) ecef = el.get_itrs() x = ecef.cartesian.x.value y = ecef.cartesian.y.value z = ecef.cartesian.z.value return x, y, z
def moonEQC(time, loc): ''' ################################################################# # Desc: Return RA, DEC of the moon at utc isot time, location. # # ------------------------------------------------------------- # # Imports: astropy.time.Time # # astropy.coordinates.(Earthlocation, AltAz, get_moon) # # ------------------------------------------------------------- # # Input # # ------------------------------------------------------------- # # time: str time format in ISOT, UTC # # loc: iterable floats position coordinate in [long, lat, alt] # # ------------------------------------------------------------- # # Output # # ------------------------------------------------------------- # # RA, DEC: float equatorial coordinate position in degree # ################################################################# ''' from astropy.time import Time from astropy.coordinates import EarthLocation, AltAz, get_moon t = Time(time, format='isot', scale='utc') l = EarthLocation.from_geodetic(*loc) eq = get_moon(t, l, 'de440') aa = eq.transform_to(AltAz(obstime=t, location=l)) RA, DEC = eq.ra.degree, eq.dec.degree return RA, DEC
def date2dict_times(date): day = Time(date, format='iso') longitude = '78d57m53s' latitude = '32d46m44s' elevation = 4500 * u.m location = EarthLocation.from_geodetic(longitude, latitude, elevation) iaohanle = Observer(location=location, name="IAO", timezone='Asia/Kolkata', description="GROWTH-India 70cm telescope") sunset_iao = iaohanle.sun_set_time(day, which='next') sunrise_iao = iaohanle.sun_rise_time(day, which='next') twelve_twil_eve_iao = iaohanle.twilight_evening_nautical(day, which='next') eighteen_twil_eve_iao = iaohanle.twilight_evening_astronomical( day, which='next') twelve_twil_morn_iao = iaohanle.twilight_morning_nautical(day, which='next') eighteen_twil_morn_iao = iaohanle.twilight_morning_astronomical( day, which='next') dict_times = OrderedDict() dict_times['Sunset '] = time2utc_ist(sunset_iao) dict_times['Sunrise '] = time2utc_ist(sunrise_iao) dict_times['Twelve degree Evening Twilight '] = time2utc_ist( twelve_twil_eve_iao) dict_times['Eighteen degree Evening Twilight '] = time2utc_ist( eighteen_twil_eve_iao) dict_times['Twelve degree Morning Twilight '] = time2utc_ist( twelve_twil_morn_iao) dict_times['Eighteen degree Morning Twilight '] = time2utc_ist( eighteen_twil_morn_iao) return dict_times
def test_new_site_info_to_json(): lon_str = "-155d28m34s" lat_str = "+19d49m32s" elevation = 4139*u.m location = EarthLocation.from_geodetic(lon_str, lat_str, elevation) short_name = "New telescope (subaru)" aliases = ["example new telescope with subaru's coordinates"] source = "the tests module" new_site_json = new_site_info_to_json(short_name, location, aliases, source) new_site = json.loads(new_site_json) ns = new_site[short_name] assert_quantity_allclose(Longitude(lon_str), Longitude(ns["longitude"]*u.Unit(ns["longitude_unit"])), atol=0.001*u.deg) assert_quantity_allclose(Latitude(lat_str), Latitude(ns["latitude"]*u.Unit(ns["latitude_unit"])), atol=0.001*u.deg) assert_quantity_allclose(elevation, new_site[short_name]["elevation"]*u.Unit(ns["elevation_unit"]), atol=1*u.m) assert short_name == new_site[short_name]['name'] assert aliases == new_site[short_name]['aliases'] with pytest.raises(ValueError): # This name already exists new_site_info_to_json("Keck", location, aliases, source)
def culmination_time_utc_astroplan(source_name, date, print_or_not): """ Calculates culmination time in UTC with astroplan library """ # Coordinates of UTR-2 radio telescope longitude = '36d56m27.560s' latitude = '+49d38m10.310s' elevation = 156 * u.m observatory = 'UTR-2, Ukraine' utr2_location = EarthLocation.from_geodetic(longitude, latitude, elevation) if print_or_not == 1: print('\n Observatory:', observatory, '\n') print(' Coordinates: \n * Longitude: ', str(utr2_location.lon).replace("d", "\u00b0 ").replace("m", "\' ").replace("s", "\'\' "), ' \n * Latitude: ' + str(utr2_location.lat).replace("d", "\u00b0 ").replace("m", "\' ").replace("s", "\'\' ") + '\n') print(' Source:', source_name, '\n') observer = Observer(location=utr2_location, name='Volokhiv Yar', timezone='UTC') alt, az = catalogue_sources(source_name) coordinates = SkyCoord(alt, az, frame='icrs') target = FixedTarget(coord=coordinates, name="target") date_of_obs = Time(date, scale='utc') culmination = observer.target_meridian_transit_time(date_of_obs, target, which='next') culm_time = culmination.to_datetime().time() culm_time = date + ' ' + str(culm_time)[0:8] if print_or_not == 1: print(' Culmination time:', culm_time, ' UTC \n') return culm_time
def observatory_location(): "Returns the observatory location as an astropy EarthLocation object" # These values should be edited to match the observatory location longitude = -2.1544 latitude = 53.7111 elevation = 316 return EarthLocation.from_geodetic(longitude, latitude, elevation)
def __init__(self, spsname): spstab = Table.read(spsname,hdu=1) # Apply TIMEZERO if needed if 'TIMEZERO' in spstab.meta: log.info('Applying TIMEZERO of {0} to spstab'.format(spstab.meta['TIMEZERO'])) spstab['TIME'] += spstab.meta['TIMEZERO'] spstab.meta['TIMEZERO'] = 0.0 idx = np.where(np.logical_not(np.logical_and(spstab['GPS_SPS_LAT']==0.0, spstab['GPS_SPS_LON']==0.0)))[0] spstab = spstab[idx] spstab.sort('TIME') self.met = spstab['TIME'] log.info('SPS Range {0} to {1}'.format(self.met.min(),self.met.max())) # Read lat and lon. These come with units (rad) provided by the FITS file self.spslat = spstab['GPS_SPS_LAT'] self.spslon = spstab['GPS_SPS_LON'] self.earthloc = EarthLocation.from_geodetic(lon=self.spslon,lat=self.spslat) # Convert to cartesian for smooth interpolation, since the wrapping # of latitude gives interpolators fits. self.ecef_x = InterpolatedUnivariateSpline(self.met,self.earthloc.x,ext='const') self.ecef_y = InterpolatedUnivariateSpline(self.met,self.earthloc.y,ext='const') self.ecef_z = InterpolatedUnivariateSpline(self.met,self.earthloc.z,ext='const')
def moonLC(time, loc): ''' ################################################################# # Desc: Return ALT, AZ of the moon at utc isot time, location. # # ------------------------------------------------------------- # # Imports: astropy.time.Time # # astropy.coordinates.(Earthlocation, AltAz, get_moon) # # ------------------------------------------------------------- # # Input # # ------------------------------------------------------------- # # time: str time format in ISOT, UTC # # loc: iterable floats position coordinate in [long, lat, alt] # # ------------------------------------------------------------- # # Output # # ------------------------------------------------------------- # # ALT, AZ: float alt-az coordinate position in degree # ################################################################# ''' from astropy.time import Time from astropy.coordinates import EarthLocation, AltAz, get_moon t = Time(time, format='isot', scale='utc') l = EarthLocation.from_geodetic(*loc) eq = get_moon(t, l, 'de440') lc = eq.transform_to(AltAz(obstime=t, location=l)) ALT, AZ = lc.alt.degree, lc.az.degree return ALT, AZ
def test_moon_rise_set(): pyephem_next_rise = datetime.datetime(2017, 10, 7, 23, 50, 24, 407018) pyephem_next_set = datetime.datetime(2017, 10, 7, 12, 30, 30, 787116) pyephem_prev_rise = datetime.datetime(2017, 10, 6, 23, 13, 43, 644455) pyephem_prev_set = datetime.datetime(2017, 10, 6, 11, 20, 9, 340009) time = Time('2017-10-07 12:00:00') lat = '42:00:00' lon = '-70:00:00' elevation = 0.0 * u.m pressure = 0 * u.bar location = EarthLocation.from_geodetic(lon, lat, elevation) obs = Observer(location=location) astroplan_next_rise = obs.moon_rise_time(time, which='next') astroplan_next_set = obs.moon_set_time(time, which='next') astroplan_prev_rise = obs.moon_rise_time(time, which='previous') astroplan_prev_set = obs.moon_set_time(time, which='previous') threshold_minutes = 2 assert (abs(pyephem_next_rise - astroplan_next_rise.datetime) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(pyephem_next_set - astroplan_next_set.datetime) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(pyephem_prev_rise - astroplan_prev_rise.datetime) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(pyephem_prev_set - astroplan_prev_set.datetime) < datetime.timedelta(minutes=threshold_minutes))
def __init__( self, location: EarthLocation = EarthLocation.from_geodetic(lon=14.974609, lat=37.693267, height=1730), cam_config: target_calib.CameraConfiguration = None, focal_length: float = 2.15, ): super().__init__("Telescope") self.location = location self.cam_config = (cam_config if cam_config is not None else target_calib.CameraConfiguration("1.1.0")) self.focal_length = focal_length self._mapping = self.cam_config.GetMapping() self.pix_posx = np.array(self._mapping.GetXPixVector()) * 1e3 # mm self.pix_posy = np.array(self._mapping.GetYPixVector()) * 1e3 # mm self.pix_pos = np.array(list(zip(self.pix_posx, self.pix_posy))) self.par_pointingra = FitParameter("pointingra", 0.0, [-10.0, 370.0]) self.par_pointingdec = FitParameter("pointingdec", 0.0, [-90.0, 90.0]) self.out_horizon_frames = "horizon_frames" self.out_pointings = "pointings" self.out_cam_frames = "cam_frames" self.cout_pix_pos = "pix_pos" self.cout_fov = "fov" self.cout_altazframes = "horiz_frames"
def test_sunrise_sunset_equator_civil_twilight(): """ Check that time of sunrise/set for an observer on the equator is consistent with PyEphem results (for no atmosphere/pressure=0) """ lat = "00:00:00" lon = "00:00:00" elevation = 0.0 * u.m pressure = 0 * u.bar location = EarthLocation.from_geodetic(lon, lat, elevation) time = Time("2000-01-01 12:00:00") obs = Observer(location=location, pressure=pressure) # Manually impose horizon equivalent to civil twilight horizon = -6 * u.degree astroplan_next_sunrise = obs.sun_rise_time(time, which="next", horizon=horizon).datetime astroplan_next_sunset = obs.sun_set_time(time, which="next", horizon=horizon).datetime astroplan_prev_sunrise = obs.sun_rise_time(time, which="previous", horizon=horizon).datetime astroplan_prev_sunset = obs.sun_set_time(time, which="previous", horizon=horizon).datetime # Run print_pyephem_sunrise_sunset_equator_civil_twilight() to compute # analogous result from PyEphem: pyephem_next_rise = datetime.datetime(2000, 1, 2, 5, 37, 34, 83328) pyephem_next_set = datetime.datetime(2000, 1, 1, 18, 29, 29, 195908) pyephem_prev_rise = datetime.datetime(2000, 1, 1, 5, 37, 4, 701708) pyephem_prev_set = datetime.datetime(1999, 12, 31, 18, 29, 1, 530987) threshold_minutes = 8 assert abs(pyephem_next_rise - astroplan_next_sunrise) < datetime.timedelta(minutes=threshold_minutes) assert abs(pyephem_next_set - astroplan_next_sunset) < datetime.timedelta(minutes=threshold_minutes) assert abs(pyephem_prev_rise - astroplan_prev_sunrise) < datetime.timedelta(minutes=threshold_minutes) assert abs(pyephem_prev_set - astroplan_prev_sunset) < datetime.timedelta(minutes=threshold_minutes)
def test_solar_transit_convenience_methods(): """ Test that astroplan's noon and midnight convenience methods agree with PyEphem's solar transit/antitransit time. """ lat = '00:00:00' lon = '00:00:00' elevation = 0.0 * u.m pressure = 0 * u.bar location = EarthLocation.from_geodetic(lon, lat, elevation) time = Time('2000-01-01 12:00:00') from astropy.coordinates import get_sun obs = Observer(location=location, pressure=pressure) # Compute next/previous noon/midnight using generic calc_transit methods astroplan_next_noon = obs.noon(time, which='next').datetime astroplan_next_midnight = obs.midnight(time, which='next').datetime astroplan_prev_noon = obs.noon(time, which='previous').datetime astroplan_prev_midnight = obs.midnight(time, which='previous').datetime # Computed in print_pyephem_solar_transit_noon() pyephem_next_transit = datetime.datetime(2000, 1, 1, 12, 3, 17, 207300) pyephem_next_antitransit = datetime.datetime(2000, 1, 2, 0, 3, 31, 423333) pyephem_prev_transit = datetime.datetime(1999, 12, 31, 12, 2, 48, 562755) pyephem_prev_antitransit = datetime.datetime(2000, 1, 1, 0, 3, 2, 918943) threshold_minutes = 8 assert (abs(astroplan_next_noon - pyephem_next_transit) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(astroplan_next_midnight - pyephem_next_antitransit) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(astroplan_prev_noon - pyephem_prev_transit) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(astroplan_prev_midnight - pyephem_prev_antitransit) < datetime.timedelta(minutes=threshold_minutes))
def test_sunrise_sunset_equator(): """ Check that time of sunrise/set for an observer on the equator is consistent with PyEphem results (for no atmosphere/pressure=0) """ lat = "00:00:00" lon = "00:00:00" elevation = 0.0 * u.m pressure = 0 * u.bar location = EarthLocation.from_geodetic(lon, lat, elevation) time = Time("2000-01-01 12:00:00") obs = Observer(location=location, pressure=pressure) astroplan_next_sunrise = obs.sun_rise_time(time, which="next").datetime astroplan_next_sunset = obs.sun_set_time(time, which="next").datetime astroplan_prev_sunrise = obs.sun_rise_time(time, which="previous").datetime astroplan_prev_sunset = obs.sun_set_time(time, which="previous").datetime # Run print_pyephem_sunrise_sunset() to compute analogous # result from PyEphem: pyephem_next_sunrise = datetime.datetime(2000, 1, 2, 6, 3, 39, 150790) pyephem_next_sunset = datetime.datetime(2000, 1, 1, 18, 3, 23, 676686) pyephem_prev_sunrise = datetime.datetime(2000, 1, 1, 6, 3, 10, 720052) pyephem_prev_sunset = datetime.datetime(1999, 12, 31, 18, 2, 55, 100786) # Typical difference in this example between PyEphem and astroplan # with an atmosphere is <2 min threshold_minutes = 8 assert abs(pyephem_next_sunrise - astroplan_next_sunrise) < datetime.timedelta(minutes=threshold_minutes) assert abs(pyephem_next_sunset - astroplan_next_sunset) < datetime.timedelta(minutes=threshold_minutes) assert abs(pyephem_prev_sunrise - astroplan_prev_sunrise) < datetime.timedelta(minutes=threshold_minutes) assert abs(pyephem_prev_sunset - astroplan_prev_sunset) < datetime.timedelta(minutes=threshold_minutes)
def test_new_site_info_to_json(): lon_str = "-155d28m34s" lat_str = "+19d49m32s" elevation = 4139 * u.m location = EarthLocation.from_geodetic(lon_str, lat_str, elevation) short_name = "New telescope (subaru)" aliases = ["example new telescope with subaru's coordinates"] source = "the tests module" new_site_json = new_site_info_to_json(short_name, location, aliases, source) new_site = json.loads(new_site_json) ns = new_site[short_name] assert_quantity_allclose(Longitude(lon_str), Longitude(ns["longitude"] * u.Unit(ns["longitude_unit"])), atol=0.001 * u.deg) assert_quantity_allclose(Latitude(lat_str), Latitude(ns["latitude"] * u.Unit(ns["latitude_unit"])), atol=0.001 * u.deg) assert_quantity_allclose(elevation, new_site[short_name]["elevation"] * u.Unit(ns["elevation_unit"]), atol=1 * u.m) assert short_name == new_site[short_name]['name'] assert aliases == new_site[short_name]['aliases'] with pytest.raises(ValueError): # This name already exists new_site_info_to_json("Keck", location, aliases, source)
def test_vega_sirius_transit_seattle(): """ Check that time of transit of Vega for an observer in Seattle is consistent with PyEphem results (for no atmosphere/pressure=0) """ lat = "47d36m34.92s" lon = "122d19m59.16s" elevation = 0.0 * u.m pressure = 0 * u.bar location = EarthLocation.from_geodetic(lon, lat, elevation) time = Time("1990-01-01 12:00:00") vega = SkyCoord(279.23473479 * u.degree, 38.78368896 * u.degree) sirius = SkyCoord(101.28715533 * u.degree, -16.71611586 * u.degree) obs = Observer(location=location, pressure=pressure) astroplan_vega_transit = obs.target_meridian_transit_time(time, vega, which="next").datetime astroplan_sirius_transit = obs.target_meridian_transit_time(time, sirius, which="next").datetime astroplan_vector_transit = obs.target_meridian_transit_time(time, [vega, sirius], which="next").datetime # Run print_pyephem_vega_sirius_transit() to compute analogous # result from PyEphem: pyephem_vega_transit = datetime.datetime(1990, 1, 2, 3, 41, 9, 244067) pyephem_sirius_transit = datetime.datetime(1990, 1, 1, 15, 51, 15, 135167) # Typical difference in this example between PyEphem and astroplan # with an atmosphere is <2 min threshold_minutes = 8 assert abs(pyephem_vega_transit - astroplan_vega_transit) < datetime.timedelta(minutes=threshold_minutes) assert abs(pyephem_sirius_transit - astroplan_sirius_transit) < datetime.timedelta(minutes=threshold_minutes) # Now check vectorized solutions against scalar: assert astroplan_vector_transit[0] == astroplan_vega_transit assert astroplan_vector_transit[1] == astroplan_sirius_transit
def __init__(self, targets, tzinfo='Australia/Sydney', portal_htmls=[]): ### target and calibrators if not isinstance(targets, Sequence): targets = [targets] self.targets = targets self.calibrator = [FixedTarget(name='1934-638', coord=SkyCoord('19h39m25.026s -63d42m45.63s')), FixedTarget(name='0823-500', coord=SkyCoord('08h25m26.869s -50d10m38.49s'))] ### observer ATCA_loc = (149.5501388*u.deg,-30.3128846*u.deg,237*u.m) location = EarthLocation.from_geodetic(*ATCA_loc) self.observer = Observer(name='ATCA', location=location, timezone=timezone('Australia/Sydney')) time_now = datetime.now(timezone(tzinfo)) self.utcoffset = time_now.utcoffset() self.tzinfo = tzinfo if len(portal_htmls) == 0: self.portal_tz = None self.portal_sched = None else: atca_scheds = ATCA_sched(portal_htmls) self.portal_tz = atca_scheds.timezone self.portal_sched = atca_scheds.schedules ### portal utcoffset portal_now = datetime.now(timezone(self.portal_tz)) self.portal_utcoffset = portal_now.utcoffset()
def test_topo_position_vs_pycraf(self): from astropy.coordinates import EarthLocation from astropy import time from pycraf import satellite tle_string = '\n'.join(self.tle_tup) location = EarthLocation.from_geodetic(*self.effbg_tup_m, 'WGS72') sat_obs = satellite.SatelliteObserver(location) dt = datetime.datetime(*self.dt_tup) obstime = time.Time(dt) gmst = obstime.sidereal_time('mean', 'greenwich').rad lmst = gmst + location.lon.rad print(obstime) print(gmst, lmst) az, el, dist = sat_obs.azel_from_sat(tle_string, obstime) az, el, dist = az.value, el.value, dist.value az %= 360. print(az, el, dist) sat = Satellite(self.tle, self.effbg_observer, self.pydt) # sat.mjd = self.mjd # print(sat.pydt) eci_pos = sat.eci_pos() topo_pos = sat.topo_pos() print(eci_pos.pydt) print(eci_pos.pydt.gmst(), eci_pos.pydt.lmst(self.effbg_tup[0])) print(topo_pos.az, topo_pos.el, topo_pos.dist) assert_allclose(topo_pos.az, az, atol=1e-3) assert_allclose(topo_pos.el, el, atol=1e-3) assert_allclose(topo_pos.dist, dist, atol=2e-2)
def test_Observer_constructor_location(): """ Show that location defined by latitude/longitude/elevation is parsed identically to passing in an `~astropy.coordinates.EarthLocation` directly. """ lat = '+19:00:00' lon = '-155:00:00' elevation = 0.0 * u.m location = EarthLocation.from_geodetic(lon, lat, elevation) environment_kwargs = dict(pressure=1 * u.bar, relative_humidity=0.1, temperature=10 * u.deg_C) obs1 = Observer(name='Observatory', latitude=lat, longitude=lon, elevation=elevation, **environment_kwargs) obs2 = Observer(name='Observatory', location=location, **environment_kwargs) assert obs1.location == obs2.location, ('using latitude/longitude/' 'elevation keywords gave a ' 'different answer from passing in ' 'an EarthLocation directly')
def set_time(request, transient_id, obs_id): import time tstart = time.time() transient = Transient.objects.filter(id=transient_id)[0] coords = transient.CoordString() obsnight = ClassicalObservingDate.objects.get(pk=obs_id) tme = Time(str(obsnight.obs_date).split()[0]) sc = SkyCoord('%s %s' % (coords[0], coords[1]), unit=(u.hourangle, u.deg)) location = EarthLocation.from_geodetic( obsnight.resource.telescope.longitude * u.deg, obsnight.resource.telescope.latitude * u.deg, obsnight.resource.telescope.elevation * u.m) tel = Observer(location=location, timezone="UTC") target_set_time = tel.target_set_time(tme, sc, horizon=18 * u.deg, which="previous") if target_set_time: settime = target_set_time.isot.split('T')[-1] else: settime = None print(time.time() - tstart) setdict = {'set_time': settime} return JsonResponse(setdict)
def __init__(self, longitude: Optional[float] = None, latitude: Optional[float] = None, datetime: Optional[dt] = None): super().__init__(longitude=longitude, latitude=latitude, datetime=datetime) self.height = 1500 self.location = EarthLocation.from_geodetic(lon=self.longitude * u.degree, lat=self.latitude * u.degree, height=self.height * u.meter) if self.datetime is None: self.datetime = dt.now() self.datetime = str(self.datetime)[:10] + ' 23:00:00' self.time = Time(self.datetime) else: self.time = Time(str(self.datetime)[:10]+' 23:00:00') self.alt, self.az = np.meshgrid(np.arange(5, 85, 5), np.arange(5, 355, 5)) self.alt = self.alt.ravel() self.az = self.az.ravel() self.dome = SkyCoord(az=self.az * u.degree, alt=self.alt * u.degree, frame=AltAz(obstime=self.time, location=self.location)) self.constellations = None self.name = "TONIGHT'S CONSTELLATIONS" self.dict_name = "consts"
def tonight_set_time(request, transient_id, too_id): transient = Transient.objects.filter(id=transient_id)[0] coords = transient.CoordString() obsnight = ToOResource.objects.filter(id=too_id)[0] time = Time(datetime.datetime.now()) sc = SkyCoord('%s %s' % (coords[0], coords[1]), unit=(u.hourangle, u.deg)) location = EarthLocation.from_geodetic( obsnight.telescope.longitude * u.deg, obsnight.telescope.latitude * u.deg, obsnight.telescope.elevation * u.m) tel = Observer(location=location, timezone="UTC") target_set_time = tel.target_set_time(time, sc, horizon=18 * u.deg, which="previous") if target_set_time: returnstarttime = target_set_time.isot.split('T')[-1] else: returnstarttime = None setdict = {'set_time': returnstarttime} return JsonResponse(setdict)
def new_with_astropy(cls, starttime, stoptime, obsid=None): """ Add an observation to the M&C database, using Astropy to compute the LST. Parameters: ------------ starttime: astropy time object observation starttime stoptime: astropy time object observation stoptime obsid: long integer observation identification number. If not provided, will be set to the gps second corresponding to the starttime using floor. """ t_start = starttime.utc t_stop = stoptime.utc # t_start.delta_ut1_utc = iers_a.ut1_utc(t_start) # t_stop.delta_ut1_utc = iers_a.ut1_utc(t_stop) if obsid is None: from math import floor obsid = floor(t_start.gps) t_start.location = EarthLocation.from_geodetic(HERA_LON, HERA_LAT) return cls(obsid=obsid, start_time_jd=t_start.jd, stop_time_jd=t_stop.jd, lst_start_hr=t_start.sidereal_time('apparent').hour)
def test_exceptions(): lat = '00:00:00' lon = '00:00:00' elevation = 0.0 * u.m location = EarthLocation.from_geodetic(lon, lat, elevation) time = Time('2000-01-01 12:00:00') vega_coords = SkyCoord('18h36m56.33635s', '+38d47m01.2802s') obs = Observer(location=location) with pytest.raises(ValueError): obs.target_rise_time(time, vega_coords, which='oops').datetime with pytest.raises(ValueError): obs.target_set_time(time, vega_coords, which='oops').datetime with pytest.raises(ValueError): obs.target_meridian_transit_time(time, vega_coords, which='oops').datetime with pytest.raises(ValueError): obs.target_meridian_antitransit_time(time, vega_coords, which='oops').datetime with pytest.raises(TypeError): FixedTarget(['00:00:00', '00:00:00'], name='VE') with pytest.raises(TypeError): Observer(location='Greenwich') with pytest.raises(TypeError): Observer(location=EarthLocation(0, 0, 0), timezone=-6)
def test_exceptions(): lat = "00:00:00" lon = "00:00:00" elevation = 0.0 * u.m location = EarthLocation.from_geodetic(lon, lat, elevation) time = Time("2000-01-01 12:00:00") vega_coords = SkyCoord("18h36m56.33635s", "+38d47m01.2802s") obs = Observer(location=location) with pytest.raises(ValueError): obs.target_rise_time(time, vega_coords, which="oops").datetime with pytest.raises(ValueError): obs.target_set_time(time, vega_coords, which="oops").datetime with pytest.raises(ValueError): obs.target_meridian_transit_time(time, vega_coords, which="oops").datetime with pytest.raises(ValueError): obs.target_meridian_antitransit_time(time, vega_coords, which="oops").datetime with pytest.raises(TypeError): FixedTarget(["00:00:00", "00:00:00"], name="VE") with pytest.raises(TypeError): Observer(location="Greenwich") with pytest.raises(TypeError): Observer(location=EarthLocation(0, 0, 0), timezone=-6)
def test_sample_radec( aperture_plane_model: primary_beam.PrimaryBeamAperturePlane, lat: u.Quantity) -> None: model = aperture_plane_model location = EarthLocation.from_geodetic(18 * u.deg, lat=lat, height=100 * u.m) obstime = Time('2021-04-22T13:00:00Z') frequency = 1 * u.GHz altaz_frame = AltAz(obstime=obstime, location=location) target_altaz = SkyCoord(alt=70 * u.deg, az=150 * u.deg, frame=altaz_frame) l_altaz = [-0.002, 0.001, 0.0, 0.0, 0.0] m_altaz = [0.0, 0.02, 0.0, -0.03, 0.01] coords_altaz = _lm_to_coords(l_altaz, m_altaz, target_altaz) target_icrs = target_altaz.icrs coords_icrs = coords_altaz.icrs l_icrs, m_icrs = _coords_to_lm(coords_icrs, target_icrs) out_radec = model.sample( l_icrs, m_icrs, frequency, primary_beam.RADecFrame.from_sky_coord(target_icrs), primary_beam.OutputType.JONES_HV) out_altaz = model.sample(l_altaz, m_altaz, frequency, primary_beam.AltAzFrame(), primary_beam.OutputType.JONES_HV) # Tolerance is high because RADecFrame doesn't account for aberration np.testing.assert_allclose(out_radec, out_altaz, atol=1e-4)
def test_exceptions(): lat = '00:00:00' lon = '00:00:00' elevation = 0.0 * u.m location = EarthLocation.from_geodetic(lon, lat, elevation) time = Time('2000-01-01 12:00:00') vega_coords = SkyCoord('18h36m56.33635s', '+38d47m01.2802s') obs = Observer(location=location) with pytest.raises(ValueError): obs.target_rise_time(time, vega_coords, which='oops').datetime with pytest.raises(ValueError): obs.target_set_time(time, vega_coords, which='oops').datetime with pytest.raises(ValueError): obs.target_meridian_transit_time(time, vega_coords, which='oops').datetime with pytest.raises(ValueError): obs.target_meridian_antitransit_time(time, vega_coords, which='oops').datetime with pytest.raises(TypeError): FixedTarget(['00:00:00', '00:00:00'], name='VE') with pytest.raises(TypeError): Observer(location='Greenwich') with pytest.raises(TypeError): Observer(location=EarthLocation(0, 0, 0), timezone=-6)
def velocity_at_point(omega_cartesian, location, mode): if mode == 'geocentric': lat, lon, r = location pos_cartesian = spherical_to_cartesian(r, lat, lon) else: if mode == 'geodetic': lat_geode, lon, h = location pos_cartesian = EarthLocation.from_geodetic(lon, lat_geode, h) x, y, z = pos_cartesian.x, pos_cartesian.y, pos_cartesian.z pos_cartesian = (x, y, z) elif mode == 'cartesian': x, y, z = location pos_cartesian = location r, lat_rad, lon_rad = cartesian_to_spherical(x, y, z) lat, lon = lat_rad.to(u.deg), lon_rad.to(u.deg) velocity_en = euler_matrix(lat, lon, r) @ omega_cartesian velocity_cartesian = np.cross(omega_cartesian, pos_cartesian) velocity_xyz = vel_unit_conver(velocity_cartesian) velocity_en = vel_unit_conver(velocity_en) speed = norm(velocity_xyz) azimuth = np.arctan2(velocity_en[0], velocity_en[1]).to(u.deg) return velocity_xyz, velocity_en, speed, azimuth
def test_Observer_constructor_location(): """ Show that location defined by latitude/longitude/elevation is parsed identically to passing in an `~astropy.coordinates.EarthLocation` directly. """ lat = '+19:00:00' lon = '-155:00:00' elevation = 0.0 * u.m location = EarthLocation.from_geodetic(lon, lat, elevation) environment_kwargs = dict(pressure=1*u.bar, relative_humidity=0.1, temperature=10*u.deg_C) obs1 = Observer(name='Observatory', latitude=lat, longitude=lon, elevation=elevation, **environment_kwargs) obs2 = Observer(name='Observatory', location=location, **environment_kwargs) assert obs1.location == obs2.location, ('using latitude/longitude/' 'elevation keywords gave a ' 'different answer from passing in ' 'an EarthLocation directly')
def test_solar_transit_convenience_methods(): """ Test that astroplan's noon and midnight convenience methods agree with PyEphem's solar transit/antitransit time. """ lat = '00:00:00' lon = '00:00:00' elevation = 0.0 * u.m pressure = 0 * u.bar location = EarthLocation.from_geodetic(lon, lat, elevation) time = Time('2000-01-01 12:00:00') from astropy.coordinates import get_sun obs = Observer(location=location, pressure=pressure) # Compute next/previous noon/midnight using generic calc_transit methods astroplan_next_noon = obs.noon(time, which='next').datetime astroplan_next_midnight = obs.midnight(time, which='next').datetime astroplan_prev_noon = obs.noon(time, which='previous').datetime astroplan_prev_midnight = obs.midnight(time, which='previous').datetime # Computed in print_pyephem_solar_transit_noon() pyephem_next_transit = datetime.datetime(2000, 1, 1, 12, 3, 17, 207300) pyephem_next_antitransit = datetime.datetime(2000, 1, 2, 0, 3, 31, 423333) pyephem_prev_transit = datetime.datetime(1999, 12, 31, 12, 2, 48, 562755) pyephem_prev_antitransit = datetime.datetime(2000, 1, 1, 0, 3, 2, 918943) threshold_minutes = 8 assert (abs(astroplan_next_noon - pyephem_next_transit) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(astroplan_next_midnight - pyephem_next_antitransit) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(astroplan_prev_noon - pyephem_prev_transit) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(astroplan_prev_midnight - pyephem_prev_antitransit) < datetime.timedelta(minutes=threshold_minutes))
def get_projected_velocity(ra, dec, jd, obs_lat=nch.lat, obs_lon=nch.lon, obs_alt=nch.alt, epoch=2451545.): '''Compute the projected velocity of the telescope wrt the Local Standard of Rest. Parameters ---------- ra, dec : float degrees, the RA/DEC of target jd : float, julian date (UTC) of the observation obs_lat : float degrees, latitude of observatory, default=nch.lat obs_lon : float degrees, longitude of observatory, default=nch.lon obs_alt : float meters, altitude of observatory, default=nch.alt epoch : float, julian date epoch of ra/dec coordinates default=2451545 is J2000 Returns ------- v : float m/s, barycenter-corrected radial velocity ''' location = EarthLocation.from_geodetic(lat=obs_lat * u.deg, lon=obs_lon * u.deg, height=obs_alt * u.m) sc = SkyCoord(ra=ra * u.deg, dec=dec * u.deg) barycorr = sc.radial_velocity_correction(obstime=Time(jd, format="jd"), location=location) v = barycorr.to(u.m / u.s) return v
def tel_move(RA, DEC, n, COLOR, s): #initialize and update position coordinates location = EarthLocation.from_geodetic(lon=-111.5947 * u.deg, lat=31.95844 * u.deg, height=2097.024 * u.m) kittpeak = Observer(location=location, name='kitt peak') coord = SkyCoord(ra=RA * u.deg, dec=DEC * u.deg, unit='deg', frame='icrs') time = thetime('2018-4-6 00:00:00') times = time + (n * u.second) lst = kittpeak.local_sidereal_time(times) ha = (lst.hour - (RA / 15.0) ) # given in hours, converted to degrees later for PA calc frame = AltAz(obstime=times, location=location) new_coord = coord.transform_to(frame) alt = new_coord.alt.degree az = new_coord.az.degree # parallactic angle calculation ----------------------------------------------------------------------------------- sina = np.sin(np.radians(ha * 15.0)) cosa = (np.tan(np.radians(31.95844)) * np.cos(np.radians(DEC))) - ( np.sin(np.radians(DEC)) * np.cos(np.radians(ha * 15.0))) pa = np.degrees(np.arctan2(sina, cosa)) #s.send(message.encode('utf-8')) packer = struct.Struct('d d d d d d d') data = packer.pack(pa, slew_flag, alt, az, ra, dec, othertime.time()) s.send(data) return s
def rise_time(obsnight, coords, tel=None): import time tstart = time.time() tme = Time(str(obsnight.obs_date).split()[0]) sc = SkyCoord('%s %s' % (coords[0], coords[1]), unit=(u.hourangle, u.deg)) location = EarthLocation.from_geodetic( obsnight.resource.telescope.longitude * u.deg, obsnight.resource.telescope.latitude * u.deg, obsnight.resource.telescope.elevation * u.m) tel = Observer(location=location, timezone="UTC") target_rise_time = tel.target_rise_time(tme, sc, horizon=18 * u.deg, which="previous") if target_rise_time: returnstarttime = target_rise_time.isot.split('T')[-1] else: returnstarttime = None print(time.time() - tstart) return (returnstarttime)
def test_hour_angle(): # TODO: Add tests for different targets/times with tools other than PyEphem time = Time('2005-02-03 00:00:00') location = EarthLocation.from_geodetic(10*u.deg, 40*u.deg, 0*u.m) obs = Observer(location=location) vernal_eq = FixedTarget(SkyCoord(ra=0*u.deg, dec=0*u.deg)) hour_angle = obs.target_hour_angle(time, vernal_eq) lst = obs.local_sidereal_time(time) assert_quantity_allclose(hour_angle, lst, atol=0.001*u.deg)
def test_local_sidereal_time(): time = Time('2005-02-03 00:00:00') location = EarthLocation.from_geodetic(10*u.deg, 40*u.deg, 0*u.m) obs = Observer(location=location) # test sidereal time astroplan_lst = obs.local_sidereal_time(time) # Compute this with print_pyephem_lst() pyephem_lst = 2.5005375428099104*u.rad assert_quantity_allclose(astroplan_lst, pyephem_lst, atol=0.01*u.deg)
def test_moon_altaz(): time = Time('2012-06-21 03:00:00') location = EarthLocation.from_geodetic(-155*u.deg, 19*u.deg, 0*u.m) obs = Observer(location=location, pressure=0*u.bar) altaz = obs.moon_altaz(time) astroplan_altaz = [altaz.alt.radian, altaz.az.radian] # Get this from print_pyephem_moon_altaz(): pyephem_altaz = [0.7092548608779907, 4.865438938140869] assert_allclose(astroplan_altaz, pyephem_altaz, atol=0.1)
def test_twilight_convenience_funcs(): """ Check that the convenience functions for evening astronomical/nautical/civil twilight correspond to their PyEphem equivalents """ lat = '00:00:00' lon = '00:00:00' elevation = 0.0 * u.m pressure = 0 * u.bar location = EarthLocation.from_geodetic(lon, lat, elevation) time = Time('2000-01-01 12:00:00') obs = Observer(location=location, pressure=pressure) # Compute morning twilights with astroplan astroplan_morning_civil = obs.twilight_morning_civil( time, which='previous').datetime astroplan_morning_nautical = obs.twilight_morning_nautical( time, which='previous').datetime astroplan_morning_astro = obs.twilight_morning_astronomical( time, which='previous').datetime # Compute evening twilights with astroplan astroplan_evening_civil = obs.twilight_evening_civil( time, which='next').datetime astroplan_evening_nautical = obs.twilight_evening_nautical( time, which='next').datetime astroplan_evening_astro = obs.twilight_evening_astronomical( time, which='next').datetime # Compute morning and evening twilights with PyEphem from # the function print_pyephem_twilight_convenience_funcs() pyephem_morning_civil, pyephem_morning_nautical, pyephem_morning_astronomical, = ( datetime.datetime(2000, 1, 1, 5, 37, 4, 701708), datetime.datetime(2000, 1, 1, 5, 10, 55, 450939), datetime.datetime(2000, 1, 1, 4, 44, 39, 415865)) pyephem_evening_civil, pyephem_evening_nautical, pyephem_evening_astronomical = ( datetime.datetime(2000, 1, 1, 18, 29, 29, 195908), datetime.datetime(2000, 1, 1, 18, 55, 37, 864882), datetime.datetime(2000, 1, 1, 19, 21, 53, 213768)) threshold_minutes = 2 # Compare morning twilights assert (abs(astroplan_morning_civil - pyephem_morning_civil) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(astroplan_morning_nautical - pyephem_morning_nautical) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(astroplan_morning_astro - pyephem_morning_astronomical) < datetime.timedelta(minutes=threshold_minutes)) # Compare evening twilights assert (abs(astroplan_evening_civil - pyephem_evening_civil) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(astroplan_evening_nautical - pyephem_evening_nautical) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(astroplan_evening_astro - pyephem_evening_astronomical) < datetime.timedelta(minutes=threshold_minutes))
def test_vega_sirius_rise_set_seattle(): """ Check that time of rise/set of Vega for an observer in Seattle is consistent with PyEphem results (for no atmosphere/pressure=0) """ lat = '47d36m34.92s' lon = '122d19m59.16s' elevation = 0.0 * u.m pressure = 0 * u.bar location = EarthLocation.from_geodetic(lon, lat, elevation) time = Time('1990-01-01 12:00:00') vega = SkyCoord(279.23473479*u.degree, 38.78368896*u.degree) sirius = SkyCoord(101.28715533*u.degree, -16.71611586*u.degree) obs = Observer(location=location, pressure=pressure) astroplan_vega_rise = obs.target_rise_time(time, vega, which='next').datetime astroplan_sirius_rise = obs.target_rise_time(time, sirius, which='next').datetime astroplan_vector_rise = obs.target_rise_time(time, [vega, sirius], which='next').datetime astroplan_vega_set = obs.target_set_time(time, vega, which='next').datetime astroplan_sirius_set = obs.target_set_time(time, sirius, which='next').datetime astroplan_vector_set = obs.target_set_time(time, [vega, sirius], which='next').datetime # Run print_pyephem_vega_sirius_rise_set() to compute analogous # result from PyEphem: pyephem_vega_rise = datetime.datetime(1990, 1, 1, 17, 36, 15, 615484) pyephem_sirius_rise = datetime.datetime(1990, 1, 2, 11, 4, 52, 35375) pyephem_vega_set = datetime.datetime(1990, 1, 1, 13, 49, 58, 788327) pyephem_sirius_set = datetime.datetime(1990, 1, 1, 20, 33, 42, 342885) # Typical difference in this example between PyEphem and astroplan # with an atmosphere is <8 min threshold_minutes = 8 assert (abs(pyephem_vega_rise - astroplan_vega_rise) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(pyephem_sirius_rise - astroplan_sirius_rise) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(pyephem_vega_set - astroplan_vega_set) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(pyephem_sirius_set - astroplan_sirius_set) < datetime.timedelta(minutes=threshold_minutes)) # Now check vectorized solutions against scalar: assert (astroplan_vector_rise[0] == astroplan_vega_rise) assert (astroplan_vector_rise[1] == astroplan_sirius_rise) assert (astroplan_vector_set[0] == astroplan_vega_set) assert (astroplan_vector_set[1] == astroplan_sirius_set)
def test_target_is_up(): """ Test that Polaris is/isn't observable from north/south pole """ elevation = 0.0 * u.m pressure = 0 * u.bar north = EarthLocation.from_geodetic("00:00:00", "90:00:00", elevation) south = EarthLocation.from_geodetic("00:00:00", "-90:00:00", elevation) time = Time("2000-01-01 12:00:00") polaris = SkyCoord(37.95456067 * u.degree, 89.26410897 * u.degree) polaris_B = SkyCoord(37.639725 * u.degree, 89.26080556 * u.degree) polaris_binary = [polaris, polaris_B] north_pole = Observer(location=north, pressure=pressure) south_pole = Observer(location=south, pressure=pressure) assert north_pole.target_is_up(time, polaris) assert not south_pole.target_is_up(time, polaris) assert all(north_pole.target_is_up(time, polaris_binary)) assert not any(south_pole.target_is_up(time, polaris_binary))
def test_regression_5133(): N = 1000 np.random.seed(12345) lon = np.random.uniform(-10, 10, N) * u.deg lat = np.random.uniform(50, 52, N) * u.deg alt = np.random.uniform(0, 10., N) * u.km time = Time('2010-1-1') objects = EarthLocation.from_geodetic(lon, lat, height=alt) itrs_coo = objects.get_itrs(time) homes = [EarthLocation.from_geodetic(lon=-1 * u.deg, lat=52 * u.deg, height=h) for h in (0, 1000, 10000)*u.km] altaz_frames = [AltAz(obstime=time, location=h) for h in homes] altaz_coos = [itrs_coo.transform_to(f) for f in altaz_frames] # they should all be different for coo in altaz_coos[1:]: assert not quantity_allclose(coo.az, coo.az[0]) assert not quantity_allclose(coo.alt, coo.alt[0])
def test_illumination(): time = Time(['1990-01-01 00:00:00', '1990-03-01 06:00:00', '1990-06-01 12:00:00', '1990-11-01 18:00:00']) location = EarthLocation.from_geodetic(-155*u.deg, 19*u.deg, 0*u.m) obs = Observer(location) # Get illumination via time illumination1 = obs.moon_illumination(time) # Run print_pyephem_illumination() for PyEphem's solution pyephem_illumination = [0.15475513880925418, 0.19484233284757257, 0.6170840254669668, 0.9780219372563843] assert_allclose(illumination1, pyephem_illumination, atol=0.05)
def test_TargetAlwaysUpWarning(recwarn): lat = '90:00:00' lon = '00:00:00' elevation = 0.0 * u.m location = EarthLocation.from_geodetic(lon, lat, elevation) time = Time('2000-01-01 12:00:00') polaris = SkyCoord(37.95456067*u.degree, 89.26410897*u.degree) obs = Observer(location=location) no_time = obs.target_rise_time(time, polaris, which='next') w = recwarn.pop(TargetAlwaysUpWarning) assert issubclass(w.category, TargetAlwaysUpWarning) assert no_time == MAGIC_TIME
def test_Observer_timezone_parser(): lat = "+19:00:00" lon = "-155:00:00" elevation = 0.0 * u.m location = EarthLocation.from_geodetic(lon, lat, elevation) obs1 = Observer(name="Observatory", location=location, timezone=pytz.timezone("UTC")) obs2 = Observer(name="Observatory", location=location, timezone="UTC") obs3 = Observer(name="Observatory", location=location) assert obs1.timezone == obs2.timezone, ( "Accept both strings to pass to " "the pytz.timezone() constructor " "and instances of pytz.timezone" ) assert obs2.timezone == obs3.timezone, "Default timezone should be UTC"
def test_registry(): reg = SiteRegistry() assert len(reg.names) == 0 names = ['sitea', 'site A'] loc = EarthLocation.from_geodetic(lat=1*u.deg, lon=2*u.deg, height=3*u.km) reg.add_site(names, loc) assert len(reg.names) == 2 loc1 = reg['SIteA'] assert loc1 is loc loc2 = reg['sIte a'] assert loc2 is loc
def test_Observer_timezone_parser(): lat = '+19:00:00' lon = '-155:00:00' elevation = 0.0 * u.m location = EarthLocation.from_geodetic(lon, lat, elevation) obs1 = Observer(name='Observatory', location=location, timezone=pytz.timezone('UTC')) obs2 = Observer(name='Observatory', location=location, timezone='UTC') obs3 = Observer(name='Observatory', location=location) assert obs1.timezone == obs2.timezone, ('Accept both strings to pass to ' 'the pytz.timezone() constructor ' 'and instances of pytz.timezone') assert obs2.timezone == obs3.timezone, ('Default timezone should be UTC')
def test_string_times(): """ Test that strings passed to time argument get successfully passed to Time constructor. Analogous test to test_vega_rise_set_equator(), just with a string for a time. """ lat = '00:00:00' lon = '00:00:00' elevation = 0.0 * u.m pressure = 0 * u.bar location = EarthLocation.from_geodetic(lon, lat, elevation) time = '2000-01-01 12:00:00' vega_ra, vega_dec = (279.23473479*u.degree, 38.78368896*u.degree) vega = SkyCoord(vega_ra, vega_dec) obs = Observer(location=location, pressure=pressure) astroplan_next_rise = obs.target_rise_time(time, vega, which='next').datetime astroplan_next_set = obs.target_set_time(time, vega, which='next').datetime astroplan_prev_rise = obs.target_rise_time(time, vega, which='previous').datetime astroplan_prev_set = obs.target_set_time(time, vega, which='previous').datetime astroplan_nearest_rise = obs.target_rise_time(time, vega, which='nearest').datetime astroplan_nearest_set = obs.target_set_time(time, vega, which='nearest').datetime # Run print_pyephem_vega_rise_set() to compute analogous # result from PyEphem: pyephem_next_rise = datetime.datetime(2000, 1, 2, 5, 52, 8, 257401) pyephem_next_set = datetime.datetime(2000, 1, 1, 17, 54, 6, 211705) pyephem_prev_rise = datetime.datetime(2000, 1, 1, 5, 56, 4, 165852) pyephem_prev_set = datetime.datetime(1999, 12, 31, 17, 58, 2, 120088) # Typical difference in this example between PyEphem and astroplan # with an atmosphere is <2 min threshold_minutes = 8 assert (abs(pyephem_next_rise - astroplan_next_rise) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(pyephem_next_set - astroplan_next_set) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(pyephem_prev_rise - astroplan_prev_rise) < datetime.timedelta(minutes=threshold_minutes)) assert (abs(pyephem_prev_set - astroplan_prev_set) < datetime.timedelta(minutes=threshold_minutes)) # Check that the 'nearest' option selects the nearest rise/set assert astroplan_nearest_rise == astroplan_prev_rise assert astroplan_nearest_set == astroplan_next_set
def print_pyephem_moon_altaz(): """ To run: python -c 'from astroplan.tests.test_observer import print_pyephem_moon_altaz as f; f()' """ time = Time('2012-06-21 03:00:00') location = EarthLocation.from_geodetic(-155*u.deg, 19*u.deg, 0*u.m) moon = ephem.Moon() pe_obs = ephem.Observer() pe_obs.lat = location.latitude.to(u.degree).to_string(sep=':') pe_obs.lon = location.longitude.to(u.degree).to_string(sep=':') pe_obs.elevation = location.height.to(u.m).value pe_obs.date = time.datetime pe_obs.pressure = 0 moon.compute(pe_obs) print(map(float, [moon.alt, moon.az]))
def test_add_obs(self): t1 = Time('2016-01-10 01:15:23', scale='utc') t2 = t1 + TimeDelta(120.0, format='sec') # t1.delta_ut1_utc = mc.iers_a.ut1_utc(t1) # t2.delta_ut1_utc = mc.iers_a.ut1_utc(t2) from math import floor obsid = floor(t1.gps) t1.location = EarthLocation.from_geodetic(observations.HERA_LON, observations.HERA_LAT) expected = [observations.Observation(obsid=obsid, start_time_jd=t1.jd, stop_time_jd=t2.jd, lst_start_hr=t1.sidereal_time('apparent').hour)] self.test_session.add(observations.Observation.new_with_astropy(t1, t2)) result = self.test_session.get_obs() self.assertEqual(result, expected)
def _load_sites(): """ Load observatory database from astroplan/data/observatories.json """ global _site_db, _site_names _site_db = dict() db = json.loads(get_pkg_data_contents('data/observatories.json')) for site in db: location = EarthLocation.from_geodetic(db[site]['longitude'], db[site]['latitude'], db[site]['elevation_meters']) _site_names.append(db[site]['name']) _site_names.append(site) _site_db[site.lower()] = location _site_db[db[site]['name'].lower()] = location for alias in db[site]['aliases']: _site_db[alias.lower()] = location
def test_vega_rise_set_equator(): """ Check that time of rise/set of Vega for an observer on the equator is consistent with PyEphem results (for no atmosphere/pressure=0) """ lat = "00:00:00" lon = "00:00:00" elevation = 0.0 * u.m pressure = 0 * u.bar location = EarthLocation.from_geodetic(lon, lat, elevation) time = Time("2000-01-01 12:00:00") vega_ra, vega_dec = (279.23473479 * u.degree, 38.78368896 * u.degree) vega = SkyCoord(vega_ra, vega_dec) obs = Observer(location=location, pressure=pressure) astroplan_next_rise = obs.target_rise_time(time, vega, which="next").datetime astroplan_next_set = obs.target_set_time(time, vega, which="next").datetime astroplan_prev_rise = obs.target_rise_time(time, vega, which="previous").datetime astroplan_prev_set = obs.target_set_time(time, vega, which="previous").datetime astroplan_nearest_rise = obs.target_rise_time(time, vega, which="nearest").datetime astroplan_nearest_set = obs.target_set_time(time, vega, which="nearest").datetime # Run print_pyephem_vega_rise_set() to compute analogous # result from PyEphem: pyephem_next_rise = datetime.datetime(2000, 1, 2, 5, 52, 8, 257401) pyephem_next_set = datetime.datetime(2000, 1, 1, 17, 54, 6, 211705) pyephem_prev_rise = datetime.datetime(2000, 1, 1, 5, 56, 4, 165852) pyephem_prev_set = datetime.datetime(1999, 12, 31, 17, 58, 2, 120088) # Typical difference in this example between PyEphem and astroplan # with an atmosphere is <2 min threshold_minutes = 8 assert abs(pyephem_next_rise - astroplan_next_rise) < datetime.timedelta(minutes=threshold_minutes) assert abs(pyephem_next_set - astroplan_next_set) < datetime.timedelta(minutes=threshold_minutes) assert abs(pyephem_prev_rise - astroplan_prev_rise) < datetime.timedelta(minutes=threshold_minutes) assert abs(pyephem_prev_set - astroplan_prev_set) < datetime.timedelta(minutes=threshold_minutes) # Check that the 'nearest' option selects the nearest rise/set assert astroplan_nearest_rise == astroplan_prev_rise assert astroplan_nearest_set == astroplan_next_set