Пример #1
0
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)
Пример #2
0
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]
Пример #3
0
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)
Пример #4
0
    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
Пример #5
0
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]
Пример #6
0
    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()
Пример #7
0
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)
Пример #8
0
    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()
Пример #9
0
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
Пример #10
0
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
Пример #12
0
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
Пример #13
0
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
Пример #14
0
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
Пример #16
0
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)
Пример #17
0
    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')
Пример #18
0
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
Пример #19
0
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))
Пример #20
0
    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"
Пример #21
0
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)
Пример #22
0
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))
Пример #23
0
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)
Пример #24
0
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)
Пример #25
0
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
Пример #26
0
    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()
Пример #27
0
    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)
Пример #28
0
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')
Пример #29
0
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)
Пример #30
0
    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"
Пример #31
0
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)
Пример #32
0
    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)
Пример #33
0
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)
Пример #34
0
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)
Пример #35
0
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)
Пример #36
0
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)
Пример #37
0
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
Пример #38
0
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')
Пример #39
0
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))
Пример #40
0
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
Пример #41
0
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
Пример #42
0
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)
Пример #43
0
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)
Пример #44
0
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)
Пример #45
0
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)
Пример #46
0
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))
Пример #47
0
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)
Пример #48
0
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))
Пример #49
0
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])
Пример #50
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)
Пример #51
0
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
Пример #52
0
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"
Пример #53
0
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
Пример #54
0
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')
Пример #55
0
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
Пример #56
0
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]))
Пример #57
0
    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)
Пример #58
0
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
Пример #59
0
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