Пример #1
0
def visibility(ra, dec, observatory, time):

    source = SkyCoord(ra=Angle(ra * u.deg), dec=(dec * u.deg))
    location = observatory.position

    time = Time(time)

    altaz = source.transform_to(AltAz(obstime=time, location=location))
    altaz_sun = get_sun(time).transform_to(
        AltAz(obstime=time, location=location))
    altaz_moon = get_moon(time).transform_to(
        AltAz(obstime=time, location=location))

    delta_time = np.linspace(0, 24, 200) * u.hour

    frame = AltAz(obstime=time + delta_time, location=location)
    frame_night = source.transform_to(frame)
    frame_sun_night = get_sun(time + delta_time).transform_to(frame)
    frame_moon_night = get_moon(time + delta_time).transform_to(frame)
    moon_distance = np.mean(
        source.separation(
            SkyCoord(
                get_moon(time + delta_time).ra,
                get_moon(time + delta_time).dec)))
    sun_distance = np.mean(
        source.separation(
            SkyCoord(
                get_sun(time + delta_time).ra,
                get_sun(time + delta_time).dec)))
    date = ephem.Date(time.value)
    moon_phase = (date - ephem.previous_new_moon(date)) / (
        ephem.next_new_moon(date) - ephem.previous_new_moon(date))

    return altaz, delta_time, frame_night, frame_sun_night, moon_distance, sun_distance, moon_phase
Пример #2
0
    def is_visible(self,
                   orbit,
                   time,
                   limb_angle=None,
                   sun_angle=None,
                   moon_angle=None):
        """
        checks if the GRB is visible above the Earth limb
        for the given times

        :param orbit: 
        :param time: 
        :returns: 
        :rtype: 

        """

        horizon_angle = 90 - np.rad2deg(
            np.arccos((a_e / orbit.a).to(u.dimensionless_unscaled).value))

        # add Earth limb restraint

        if limb_angle is not None:

            horizon_angle += limb_angle  # deg

        pos = orbit.r_eci(time).to("km")

        sun_pos = None

        if sun_angle is not None:

            sun_pos = get_moon(time).cartesian.xyz.to("km").value.T

        moon_pos = None

        if moon_angle is not None:

            moon_pos = get_moon(time).cartesian.xyz.to("km").value.T

        return _is_visibile(
            pos.T,
            self.cart_position,
            horizon_angle,
            sun_angle,
            sun_pos,
            moon_angle,
            moon_pos,
            len(time),
        )
Пример #3
0
def plot_altitude(target_list={}, observatory=None, utc_offset=0, obs_time=None, show_sun=True, show_moon=True):
    """plot the position of science target during observation
    """
    
    # define the observation time
    delta_hours = np.linspace(-12, 12, 100)*u.hour
    obstimes = obs_time + delta_hours - utc_offset
    # observertory
    altaz_frames = AltAz(location=observatory, obstime=obstimes)

    target_altaz_list = {}
    for name, skcoord in target_list.items():
        target_altaz_list[name] = skcoord.transform_to(altaz_frames)


    fig = plt.figure(figsize=(12, 4))
    ax = fig.add_subplot(121)
    for name, pos in target_altaz_list.items():
        ax.scatter(delta_hours, pos.alt, label=name, s=8)
    ax.set_title("Observed on {}".format(obs_time.fits))
    # get position of sun and moon
    sun = get_sun(obstimes).transform_to(altaz_frames)
    if show_sun:
        ax.plot(delta_hours, sun.alt, 'r', label='sun')
    if show_moon:
        moon = get_moon(obstimes).transform_to(altaz_frames)
        ax.plot(delta_hours, moon.alt, 'k--', label='moon')

    ax.fill_between(delta_hours.to('hr').value, -90, 90, sun.alt < -0*u.deg, 
                     color='0.5', zorder=0, alpha=0.5)
    ax.fill_between(delta_hours.to('hr').value, -90, 90, sun.alt < -18*u.deg, 
                     color='k', zorder=0, alpha=0.5)
    ax.set_xlabel('LST offset')
    ax.set_ylabel('Altitude')
    # ax.set_ylim(-10, 90)
    ax.legend(loc='upper right')
    # plt.tight_layout()
    
    ax = fig.add_subplot(122, projection='polar')
    for name, pos in target_altaz_list.items():
        ax.plot(pos.az/180*np.pi, np.cos(pos.alt), label=name, marker='.', ms=8)
    if show_sun:
        ax.plot(sun.az/180*np.pi, np.cos(sun.alt), 'r.', label='sun')
    if show_moon:
        moon = get_moon(obstimes).transform_to(altaz_frames)
        ax.plot(moon.az/180*np.pi, np.cos(moon.alt), 'k--', label='moon')
    ax.set_ylim(0, 1)

    plt.show()
Пример #4
0
 def moon_position_icrs(self):
     """                                                                                                                                                                                                                                                                   
     :return: moon position as SkyCood object in icrs frame                                                                                                                                                                                                                
     """
     tmp_moon = get_moon(self._time)
     #in ICRS                                                                                                                 
     return SkyCoord(tmp_moon.ra.deg, tmp_moon.dec.deg, unit='deg', frame='gcrs',obstime=self._time).icrs
Пример #5
0
    def get(self, source_coord, frame):
        """Evaluate the constraint for given targets, a specific location and
        time.

        Parameters
        -----
        source_coord : astropy.SkyCoord
            Coordinates of the target sources.
        frame : astropy.coordinates.builtin_frames.altaz.AltAz
            A coordinate or frame in the Altitude-Azimuth system.

        Returns
        -----
        out : numpy.ndarray
            Array of boolean values. One entry for each input coordinate.
            The entry is True, if the source is observable according to the
            constrains, and False otherwise.
        """

        # if frame is the same as before re-use Moon positions:
        if self._same_frame(frame):
            moon_altaz = self.moon_altaz
        # otherwise calculate new Moon positions:
        else:
            moon_altaz = get_moon(frame.obstime).transform_to(frame)
            self.moon_altaz = moon_altaz
            self.last_frame = frame

        source_altaz = source_coord.transform_to(frame)
        separation = source_altaz.separation(moon_altaz)
        observable = np.logical_or(separation <= self.limit_lo,
                                   separation >= self.limit_hi)
        #observable = np.array(observable, dtype=float)

        return observable
Пример #6
0
def get_planet_info():
    planet_info = []

    with solar_system_ephemeris.set('de432s'):
        for planet_name in planets:
            planet = get_body(planet_name, current_time, location)

            planet_info.append({
                "name":
                planet_name,
                "lightMinutes":
                to_light_minutes(planet.distance),
                "xyz":
                get_xyz(planet)
            })

        sun = get_sun(current_time)
        planet_info.append({
            "name": "The Sun",
            "lightMinutes": to_light_minutes(sun.distance),
            "xyz": get_xyz(sun)
        })

        moon = get_moon(current_time)
        planet_info.append({
            "name": "The Moon",
            "lightMinutes": to_light_minutes(moon.distance),
            "xyz": get_xyz(moon)
        })

    return json.dumps(planet_info)
Пример #7
0
def moon_distance(loc, t2, t3):
    # Get the distance to the moon via the umbra diameter estimate

    if isinstance(loc, type(u'')) or isinstance(loc, type('')):
        loc = EarthLocation.of_address(loc)

    # Location of Sun & Moon
    sun = get_sun(t2)
    moon = get_moon(t2, loc)

    # Umbra size, from time and location
    su = estimate_umbra(loc, t2, t3)

    # Constants in km
    re = R_earth.to(u.km).value
    ds = sun.distance.to(u.km).value
    rs = R_sun.to(u.km).value
    rm = 1738.1

    dm = (2 * rm - su) * ds / (2 * (rs - rm)) + re
    print(
        'Distance estimate: {:.7} km (Actual: {:.7}). Ratio: {:.2}. Difference: {:.7}'
        .format(dm, moon.distance, moon.distance / (dm * u.km),
                dm * u.km - moon.distance))
    # moon.distance is from surface, not center
    return dm, moon.distance.to(u.km).value + re
Пример #8
0
def evaluateDay(thisDate):
    delta_midnight = np.linspace(-12, 12, 96) * u.hour
    tomorrow = thisDate + dt.timedelta(days=1)
    midnight = Time("{}-{}-{} 00:00:00".format(tomorrow.year, tomorrow.month,
                                               tomorrow.day)) - utcoffset
    moonIllum = moon_illumination(
        midnight)  # assume constant illumination throughout the day
    #    if (moonIllum > MAX_MOON_ILLUMINATION):
    #        return 0
    allDay = midnight + delta_midnight
    allDayFrame = AltAz(obstime=allDay, location=observerLocation)
    objectAltAziAllDay = objectToObserve.transform_to(allDayFrame)
    objectAltAllDay = objectAltAziAllDay.alt
    sunAltAllDay = get_sun(allDay).transform_to(allDayFrame).alt
    moonAltAziAllDay = get_moon(allDay).transform_to(allDayFrame)
    moonAltAllDay = moonAltAziAllDay.alt
    #moonIllumAllDay = moon.moon_illumination(allDay)
    objectVisible = objectAltAllDay > (OBJECT_MIN_ALT * u.deg)
    nightTime = sunAltAllDay < (MAX_SUN_ALT * u.deg)
    moonLess = moonAltAllDay < (MAX_MOON_ALT * u.deg)
    goodHours = np.sum(objectVisible & nightTime & moonLess) * 0.25
    #deltaAngles = np.rad2deg(angleBetweenPolarVectors(objectAltAziAllDay,moonAltAziAllDay)) # Great circle angle between the moon and the object
    #    fig1 = plt.figure(num=None, figsize=(10, 6), dpi=80, facecolor='w', edgecolor='k')
    #    ax1 = fig1.add_subplot(1,1,1)
    #    ax1.plot(delta_midnight,objectAltAllDay,color='blue')
    #    ax1.plot(delta_midnight,sunAltAllDay,color='red')
    #    ax1.plot(delta_midnight,moonAltAllDay,color='black')
    #    ax1.plot(delta_midnight,np.rad2deg(deltaAngles),color='green')
    return goodHours
Пример #9
0
    def onclick(event):
        #if not event.inaxes:
        if event.inaxes != ax1:
            return
        xint = np.floor(event.xdata + 0.5)
        yint = np.floor(event.ydata + 0.5)
        delta_midnight = np.linspace(-12, 12, 96) * u.hour
        tomorrow = firstSunday + dt.timedelta(
            days=yint + (xint * 7)) + dt.timedelta(days=1)
        midnight = Time("{}-{}-{} 00:00:00".format(
            tomorrow.year, tomorrow.month, tomorrow.day)) - utcoffset

        allDay = midnight + delta_midnight
        allDayFrame = AltAz(obstime=allDay, location=observerLocation)
        objectAltAziAllDay = objectToObserve.transform_to(allDayFrame)
        objectAltAllDay = objectAltAziAllDay.alt
        sunAltAllDay = get_sun(allDay).transform_to(allDayFrame).alt
        moonAltAziAllDay = get_moon(allDay).transform_to(allDayFrame)
        moonAltAllDay = moonAltAziAllDay.alt
        deltaAngles = np.rad2deg(
            angleBetweenPolarVectors(objectAltAziAllDay, moonAltAziAllDay)
        )  # Great circle angle between the moon and the object
        ax3.clear()
        ax3.plot(delta_midnight, objectAltAllDay, color='blue')
        ax3.plot(delta_midnight, sunAltAllDay, color='red')
        ax3.plot(delta_midnight, moonAltAllDay, color='black')
        ax3.plot(delta_midnight, deltaAngles, color='green')
        ax3.set_title(
            (firstSunday + dt.timedelta(days=yint +
                                        (xint * 7))).strftime("%B %d, %Y"),
            fontsize=8)
        ax3.set_ylabel('degrees', fontsize=8)
        ax3.set_xlabel('hours around midnight', fontsize=8)
        ax3.set_ylim(0, np.max([90, np.max(deltaAngles)]))
Пример #10
0
def moon_and_sun(time, RA, DEC):
    """
    Input: astropy.time.Time object
    Uses astropy get_moon and get_sun for lat and lon, then transforms to AltAz frame
    """
    moon = get_moon(time, location=APACHE)
    sun = get_sun(time)
    target = SkyCoord(RA, DEC, unit=u.deg, frame=moon.frame)

    #separations
    moon_dist = moon.distance.value
    moon_sep = moon.separation(target).degree
    sun_moon_sep = moon.separation(sun.transform_to(moon.frame)).degree
    sun_elong = target.separation(sun.transform_to(moon.frame)).degree

    #geocentric latitude and longitude
    moon_lat, moon_lon = (moon.geocentrictrueecliptic.lat.value,
                          moon.geocentrictrueecliptic.lon.value)
    sun_lat, sun_lon = (sun.geocentrictrueecliptic.lat.value,
                        sun.geocentrictrueecliptic.lon.value)

    #change to altaz frame
    moon_altaz = moon.transform_to(AltAz(obstime=time, location=APACHE))
    sun_altaz = sun.transform_to(AltAz(obstime=time, location=APACHE))
    moon_alt, moon_az = (moon_altaz.alt.value, moon_altaz.az.value)
    sun_alt, sun_az = (sun_altaz.alt.value, sun_altaz.az.value)

    return [
        moon_lat, moon_lon, sun_lat, sun_lon, moon_alt, moon_az, sun_alt,
        sun_az, moon_dist, moon_sep, sun_moon_sep, sun_elong
    ]
Пример #11
0
    def next_tile(self, date=None, ra_current=None, dec_current=None, weather=None, bright_time=False, limiting_magnitude=None):
        """
        Find the next tile to be observed. This is what Jeeves is going to call each time.
        Add ra_current and dec_current (and weather). This is how Jeeves is going to call this method.
        """

        # TODO: Now or in 10 minutes?
        if date:
            self.utc = Time(date, format='iso', scale='utc')
        else:
            self.utc = Time(Time.now(), format='iso', scale='utc')
        
        self.local_sidereal_time = self.utc.sidereal_time('mean', longitude=params.params['LON']).value

        self.moon = get_moon(self.utc)

        # ONLY BRIGHT TIME
        if bright_time:
            is_bright_time = self.check_if_moon_is_above_horizon(moon=self.moon, time=self.utc)
            if is_bright_time:
                pass
            else:
                print 'Dark time, Taipan is observing.'
                return None, None
        #~ self.weather_conditions()
        #~ if weather_data_filename:
            #~ self.weather_data=np.loadtxt(weather_data_filename) # STRING!!
        #~ else:
            #~ self.weather_data=None

        # Telescope position from Jeeves
        self.ra_current=ra_current
        self.dec_current=dec_current
        if ra_current is None:
            self.ra_current=self.local_sidereal_time
        if dec_current is None:
            self.dec_current=-30.0 # TODO

        self.limiting_magnitude=limiting_magnitude


        best_tile=self.find_best_tile()
        
        if best_tile is None:
            return None, None

        # Update list of observed tiles
        manage_list_of_observed_tiles.add_tile_id_internal_to_the_list({best_tile.TaipanTile.field_id})

        json_filename = create_obs_config_json.create_ObsConfig_json(tile=best_tile, utc=self.utc)
 
        self.observed_tiles.add(best_tile.TaipanTile.field_id)
 
        #~ # PLOT
        #~ telescope_positions=[best_tile.TaipanTile.ra, best_tile.TaipanTile.dec, self.moon.ra.value, self.moon.dec.value, best_tile.angular_moon_distance]
        #~ visualization.plot_selected_tile_with_neighbourhood(moon=self.moon, lst=self.local_sidereal_time, best_tiles=self.best_tiles_to_observe_now, tiles=self.tiles, best_tile=best_tile, i=1, ra_current=self.ra_current, dec_current=self.dec_current, telescope_positions=telescope_positions, observed_tile_ids=self.observed_tiles) 
 
        
        # TODO: what should be a format for Jeeves?
        return best_tile, json_filename
Пример #12
0
def check_moon(file, avoid=30. * u.degree):
    if not isinstance(avoid, u.Quantity):
        avoid = float(avoid) * u.degree
    else:
        avoid = avoid.to(u.degree)

    header = fits.getheader(file)

    mlo = EarthLocation.of_site('Keck Observatory')  # Update later
    obstime = Time(header['DATE-OBS'],
                   format='isot',
                   scale='utc',
                   location=mlo)
    moon = get_moon(obstime, mlo)

    if 'RA' in header.keys() and 'DEC' in header.keys():
        coord_string = '{} {}'.format(header['RA'], header['DEC'])
        target = SkyCoord(coord_string, unit=(u.hourangle, u.deg))
    else:
        ## Assume zenith
        target = SkyCoord(obstime.sidereal_time('apparent'), mlo.latitude)

    moon_alt = moon.transform_to(AltAz(obstime=obstime,
                                       location=mlo)).alt.to(u.deg)
    if moon_alt < 0 * u.degree:
        print('Moon is down')
        return True
    else:
        sep = target.separation(moon)
        print('Moon is up. Separation = {:.1f} deg'.format(
            sep.to(u.degree).value))
        return (sep > avoid)
Пример #13
0
    def _perform(self):
        """
        Returns an Argument() with the parameters that depends on this operation.
        """
        self.log.info(f"Running {self.__class__.__name__} action")

        lat=c.Latitude(self.action.args.kd.get('SITELAT'), unit=u.degree)
        lon=c.Longitude(self.action.args.kd.get('SITELONG'), unit=u.degree)
        height=float(self.action.args.kd.get('ALT-OBS')) * u.meter
        loc = c.EarthLocation(lon, lat, height)
        temperature=float(self.action.args.kd.get('AMBTEMP'))*u.Celsius
        pressure=self.cfg['Telescope'].getfloat('pressure', 700)*u.mbar
        altazframe = c.AltAz(location=loc, obstime=self.action.args.kd.obstime(),
                             temperature=temperature,
                             pressure=pressure)
        moon = c.get_moon(Time(self.action.args.kd.obstime()), location=loc)
        sun = c.get_sun(Time(self.action.args.kd.obstime()))

        moon_alt = ((moon.transform_to(altazframe).alt).to(u.degree)).value
        moon_separation = (moon.separation(self.action.args.header_pointing).to(u.degree)).value\
                    if self.action.args.header_pointing is not None else None

        # Moon illumination formula from Meeus, ÒAstronomical 
        # Algorithms". Formulae 46.1 and 46.2 in the 1991 edition, 
        # using the approximation cos(psi) \approx -cos(i). Error 
        # should be no more than 0.0014 (p. 316). 
        moon_illum = 50*(1 - np.sin(sun.dec.radian)*np.sin(moon.dec.radian)\
                     - np.cos(sun.dec.radian)*np.cos(moon.dec.radian)\
                     * np.cos(sun.ra.radian-moon.ra.radian))

        self.action.args.moon_alt = moon_alt
        self.action.args.moon_separation = moon_separation
        self.action.args.moon_illum = moon_illum

        return self.action.args
Пример #14
0
def moon_phase_angle(time, ephemeris=None):
    """
    Calculate lunar orbital phase in radians.

    Parameters
    ----------
    time : `~astropy.time.Time`
        Time of observation

    ephemeris : str, optional
        Ephemeris to use.  If not given, use the one set with
        `~astropy.coordinates.solar_system_ephemeris` (which is
        set to 'builtin' by default).

    Returns
    -------
    i : float
        Phase angle of the moon [radians]
    """
    # TODO: cache these sun/moon SkyCoord objects

    sun = get_sun(time)
    moon = get_moon(time, ephemeris=ephemeris)
    elongation = sun.separation(moon)
    return np.arctan2(sun.distance*np.sin(elongation),
                      moon.distance - sun.distance*np.cos(elongation))
Пример #15
0
def draw_moon(ax, input_time, input_loc):
    moon = get_moon(time=input_time, location=input_loc)
    moon = SkyCoord(moon.ra, moon.dec, frame='gcrs').transform_to('icrs')
    ax.plot([moon.ra.radian], [-moon.dec.value + 45],
            color='yellow',
            linestyle='',
            marker='o')
Пример #16
0
def test_moon_separation():
    time = Time('2003-04-05 06:07:08')
    apo = Observer.at_site("APO")
    altaz_frame = apo.altaz(time)
    moon = get_moon(time, apo.location).transform_to(altaz_frame)
    one_deg_away = SkyCoord(az=moon.az,
                            alt=moon.alt + 1 * u.deg,
                            frame=altaz_frame)
    five_deg_away = SkyCoord(az=moon.az + 5 * u.deg,
                             alt=moon.alt,
                             frame=altaz_frame)
    twenty_deg_away = SkyCoord(az=moon.az + 20 * u.deg,
                               alt=moon.alt,
                               frame=altaz_frame)

    constraint = MoonSeparationConstraint(min=2 * u.deg, max=10 * u.deg)
    is_constraint_met = constraint(
        apo, [one_deg_away, five_deg_away, twenty_deg_away], times=time)

    assert np.all(is_constraint_met == [False, True, False])

    constraint = MoonSeparationConstraint(max=10 * u.deg)
    is_constraint_met = constraint(
        apo, [one_deg_away, five_deg_away, twenty_deg_away], times=time)
    assert np.all(is_constraint_met == [True, True, False])

    constraint = MoonSeparationConstraint(min=2 * u.deg)
    is_constraint_met = constraint(
        apo, [one_deg_away, five_deg_away, twenty_deg_away], times=time)
    assert np.all(is_constraint_met == [False, True, True])
Пример #17
0
    def calculate_az_el(self, name, time, alt_az_frame):
        """Calculates Azimuth and Elevation of the Specified Object at the Specified Time

        Parameters
        ----------
        name : str
            Name of the Object being Tracked
        time : Time
            Current Time (only necessary for Sun/Moon Ephemeris)
        alt_az_frame : AltAz
            AltAz Frame Object

        Returns
        -------
        (float, float)
            (az, el) Tuple
        """
        if name == "Sun":
            alt_az = get_sun(time).transform_to(alt_az_frame)
        elif name == "Moon":
            alt_az = get_moon(time, self.location).transform_to(alt_az_frame)
        else:
            alt_az = self.sky_coords[self.sky_coord_names[name]].transform_to(
                alt_az_frame)
        return alt_az.az.degree, alt_az.alt.degree
Пример #18
0
def get_info_of_target(target, *args, **kwargs):
    ra = target.ra
    dec = target.dec
    coords = SkyCoord(ra=ra, dec=dec, unit=(u.degree, u.degree))
    hanle = EarthLocation(lat=32.77889 * u.degree,
                          lon=78.96472 * u.degree,
                          height=4500 * u.m)
    iao = Observer(location=hanle, name="GIT", timezone="Asia/Kolkata")
    twilight_prime = iao.sun_rise_time(
        Time(datetime.utcnow()),
        which="next",
        horizon=sunrise_horizon * u.degree) - 12 * u.hour
    targets_rise_time = iao.target_rise_time(twilight_prime,
                                             coords,
                                             which="nearest",
                                             horizon=horizon * u.degree)
    targets_set_time = iao.target_set_time(targets_rise_time,
                                           coords,
                                           which="next",
                                           horizon=horizon * u.degree)
    rise_time_IST = (targets_rise_time + 5.5 * u.hour).isot
    set_time_IST = (targets_set_time + 5.5 * u.hour).isot
    tend = targets_set_time
    mooncoords = get_moon(tend, hanle)
    sep = mooncoords.separation(coords)
    print(target.name, rise_time_IST, set_time_IST, sep)
Пример #19
0
    def moon_altaz(self, time, ephemeris=None):
        
        if not isinstance(time, Time):
            time = Time(time)

        moon = get_moon(time, location=self.location, ephemeris=ephemeris)
        return self.altaz(time, moon, grid=False)
Пример #20
0
def _get_obs_param(ra, dec, mjd):
    ''' get observing condition given tileid and time of observation 
    '''
    from astropy.time import Time
    from astropy.coordinates import EarthLocation, SkyCoord, AltAz, get_sun, get_moon
    kpno = EarthLocation.of_site('kitt peak')

    # get observing conditions
    coord = SkyCoord(ra=ra * u.deg, dec=dec * u.deg)
    utc_time = Time(mjd, format='mjd')  # observed time (UTC)

    kpno_altaz = AltAz(obstime=utc_time, location=kpno)
    coord_altaz = coord.transform_to(kpno_altaz)

    airmass = coord_altaz.secz

    # sun
    sun = get_sun(utc_time)
    sun_altaz = sun.transform_to(kpno_altaz)
    sun_alt = sun_altaz.alt.deg
    sun_sep = sun.separation(coord).deg  # sun separation
    # moon
    moon = get_moon(utc_time)
    moon_altaz = moon.transform_to(kpno_altaz)
    moon_alt = moon_altaz.alt.deg
    moon_sep = moon.separation(coord).deg  #coord.separation(self.moon).deg

    elongation = sun.separation(moon)
    phase = np.arctan2(sun.distance * np.sin(elongation),
                       moon.distance - sun.distance * np.cos(elongation))
    moon_phase = phase.value
    moon_ill = (1. + np.cos(phase)) / 2.
    return airmass, moon_ill.value, moon_alt, moon_sep, sun_alt, sun_sep
Пример #21
0
    def moonlight_veto(self, dt, debug=False):
        """
        Check if the Moon period defined by the rise and set time correspond
        to a situation where the moon is too bright or too close from the
        source.
        If this is the case (too bright or too close), returns True
        (the veto is confirmed).

        """
        too_bright = False
        too_close = False

        # Check moon illumination
        for t in dt:
            moonlight = moon_illumination(Df(t))
            if (moonlight >= self.moon_maxlight):
                too_bright = True
                if (debug):
                    print("Moonlight :", moonlight,
                          " too bright ! -> confirmed")
                break

        # Check distance to source at rise and set
        for t in dt:
            moon_radec = get_moon(Df(t), self.site)
            dist = moon_radec.separation(self.target.coord)
            if dist <= self.moon_mindist:
                too_close = True
                if (debug): print(" Moon Distance : ", dist, "too close !")
                break

        return (too_bright, too_close)
Пример #22
0
    def compute_sun_moon(self, trange, which='sun', dt_min=5):
        """
		compute the position of the sun/moon from the location of the observatory
		between the specified time interval.
			
		:param iterable trange: list of 2 elements specifying the time range (UTC). 
		Each of them can be either a `str` or `astropy.time.Time`.
		:param str which: celestial body to 'move'. Either 'sun' or 'moon'
		:param float dt_min: time resolution in minues.
		:returns: position of the sun/moon as observed from this location at the given time.
		:rtype astropy.coordinates.SkyCoord:
		"""
        start = time.time()

        # create the time object
        times = get_times(trange, dt_min)

        # define the observatory reference frame and move the sun
        obs_altaz = self.get_alt_az()
        if which.lower() == 'sun':
            skypos = get_sun(times).transform_to(obs_altaz)
        elif which.lower() == 'moon':
            skypos = get_moon(times).transform_to(obs_altaz)
        else:
            raise ValueError(
                "compute_sun_moon accepts either 'sun' or 'moon'. Got %s" %
                (which))
        end = time.time()
        self.logger.debug(
            "Computing %s motion from %s to %s (res: %.2f min, %d steps). Took %.2f sec"
            % (which, times.min().iso, times.max().iso, dt_min, len(times),
               (end - start)))
        return skypos
Пример #23
0
def moon_phase_angle(time, ephemeris=None):
    """
    Calculate lunar orbital phase in radians.

    Parameters
    ----------
    time : `~astropy.time.Time`
        Time of observation

    location : `~astropy.coordinates.EarthLocation`
        Location of observer

    ephemeris : str, optional
        Ephemeris to use.  If not given, use the one set with
        `~astropy.coordinates.solar_system_ephemeris` (which is
        set to 'builtin' by default).

    Returns
    -------
    i : float
        Phase angle of the moon [radians]
    """
    # TODO: cache these sun/moon SkyCoord objects

    sun = get_sun(time)
    moon = get_moon(time, ephemeris=ephemeris)
    elongation = sun.separation(moon)
    return np.arctan2(sun.distance * np.sin(elongation),
                      moon.distance - sun.distance * np.cos(elongation))
Пример #24
0
    def __init__(self, telLat, telLon, telElv, time, steps, sig1=.11, m1=1.7, t1=800, xlen=500, ylen=500,
                 mag_range=(-3, 3), dec_range=(-20, 90), ra_range=(0,0), max_sun_alt = -15, timestep=.5):

        self.Bews = []
        self.Bnss = []
        self.Buds = []

        self.xlen = xlen
        self.ylen = ylen
        self.mag_range = mag_range
        self.dec_range = dec_range

        self.telLat = telLat * u.deg
        self.telLon = telLon * u.deg
        self.telElv = telElv * u.m
        self.tel_loc = EarthLocation(lat=telLat * u.deg, lon=telLon * u.deg, height=telElv * u.m)

        self.err_sig = sig1
        self.err_mag = m1
        self.err_t1 = t1

        self.time_info = None

        self.time_info = Time(time, location=self.tel_loc)
        self.delta_time = np.linspace(-12, 12, steps) * u.hour

        self.time_delt = self.delta_time[1]-self.delta_time[0]
        self.telFrame = AltAz(obstime=self.time_info + self.delta_time, location=self.tel_loc)


        #get indicies for when sky is dark
        self.sunaltazs = get_sun(self.delta_time+self.time_info).transform_to(self.telFrame)
        self.moonaltazs = get_moon(self.delta_time+self.time_info).transform_to(self.telFrame)
        dark_times = np.where((self.sunaltazs.alt < max_sun_alt * u.deg))
        self.dark_times = self.telFrame.obstime.sidereal_time('apparent')[dark_times]
        self.max_sun_alt = max_sun_alt


        self.int_delta_time = np.append(np.arange(-12,12,timestep),12)*u.hour
        self.intTelFrame = AltAz(obstime=self.time_info + self.int_delta_time, location=self.tel_loc)
        self.intsunaltazs = get_sun(self.int_delta_time+self.time_info).transform_to(self.intTelFrame)

        int_dark_times = np.where((self.intsunaltazs.alt < max_sun_alt * u.deg))
        self.int_dark_times = self.intTelFrame.obstime.sidereal_time('apparent')[int_dark_times]


        #the hour_correction is to shift the sky to include stars that have just barely risen
        hour_correction = 4 * u.hourangle
        #calculate the possible ra range of the telescope for the given night
        if ra_range:
            self.ra_range = ra_range
        else:
            self.ra_range = ((self.dark_times[0] - hour_correction).to('deg').value, (self.dark_times[-1] + hour_correction).to('deg').value)
        if self.ra_range[0] > self.ra_range[1]:
            self.ra_range = self.ra_range[::-1]

        self.catalogs = []
        self.cat_names = []

        self.star_dict = {}
Пример #25
0
 def compute_constraint(self, times, observer, targets):
     """
     Computes the observability of the moon given a minimum distance to the moon between self.min_dist (for
     illumination = 0) and self.max_dist (for illumination = 1) by interpolating an intermediate distance from those
     two values following a linear regression.
     @param times: the times to compute the constraint for
     @param observer: the observer to compute the constraint for
     @param targets: the list of targets to compute the constraint for
     @return: the positive mask for target being observable for the given times and observer given the constraint
     is matched
     """
     # removed the location argument here, which causes small <1 deg
     # inaccuracies, but it is needed until astropy PR #5897 is released
     # which should be astropy 1.3.2
     moon = get_moon(times)
     # note to future editors - the order matters here
     # moon.separation(targets) is NOT the same as targets.separation(moon)
     # the former calculates the separation in the frame of the moon coord
     # which is GCRS, and that is what we want.
     moon_separation = moon.separation(targets)
     illumination = moon_illumination(times)
     min_dist = self.min_dist.value + (self.max_dist.value -
                                       self.min_dist.value) * illumination
     mask = min_dist <= moon_separation.degree
     return mask
Пример #26
0
def test_moon_separation():
    time = Time('2003-04-05 06:07:08')
    apo = Observer.at_site("APO")
    altaz_frame = apo.altaz(time)
    moon = get_moon(time, apo.location).transform_to(altaz_frame)
    one_deg_away = SkyCoord(az=moon.az, alt=moon.alt+1*u.deg, frame=altaz_frame)
    five_deg_away = SkyCoord(az=moon.az+5*u.deg, alt=moon.alt,
                             frame=altaz_frame)
    twenty_deg_away = SkyCoord(az=moon.az+20*u.deg, alt=moon.alt,
                               frame=altaz_frame)

    constraint = MoonSeparationConstraint(min=2*u.deg, max=10*u.deg)
    is_constraint_met = constraint(apo, [one_deg_away, five_deg_away,
                                         twenty_deg_away], times=time)

    assert np.all(is_constraint_met == [False, True, False])

    constraint = MoonSeparationConstraint(max=10*u.deg)
    is_constraint_met = constraint(apo, [one_deg_away, five_deg_away,
                                         twenty_deg_away], times=time)
    assert np.all(is_constraint_met == [True, True, False])

    constraint = MoonSeparationConstraint(min=2*u.deg)
    is_constraint_met = constraint(apo, [one_deg_away, five_deg_away,
                                         twenty_deg_away], times=time)
    assert np.all(is_constraint_met == [False, True, True])
Пример #27
0
def check_moon(file, avoid=30.*u.degree):
    if not isinstance(avoid, u.Quantity):
        avoid = float(avoid)*u.degree
    else:
        avoid = avoid.to(u.degree)

    header = fits.getheader(file)

    mlo = EarthLocation.of_site('Keck Observatory') # Update later
    obstime = Time(header['DATE-OBS'], format='isot', scale='utc', location=mlo)
    moon = get_moon(obstime, mlo)

    if 'RA' in header.keys() and 'DEC' in header.keys():
        coord_string = '{} {}'.format(header['RA'], header['DEC'])
        target = SkyCoord(coord_string, unit=(u.hourangle, u.deg))
    else:
        ## Assume zenith
        target = SkyCoord(obstime.sidereal_time('apparent'), mlo.latitude)

    moon_alt = moon.transform_to(AltAz(obstime=obstime, location=mlo)).alt.to(u.deg)
    if moon_alt < 0*u.degree:
        print('Moon is down')
        return True
    else:
        sep = target.separation(moon)
        print('Moon is up. Separation = {:.1f} deg'.format(sep.to(u.degree).value))
        return (sep > avoid)
Пример #28
0
def visibility_table(observer, target, obstime, dt=1 * u.hour, dt_number=24):
    """Given a target and a date for observation returns....
    Inputs:
        target:
        date:
        observer (optional):
        dt (optional):
        dt_number (optional:
    Outpus
        table
    """
    utcoffset = observer.timezone.utcoffset(obstime.datetime).seconds * u.s
    delta_midnight = np.linspace(0, dt_number, dt_number + 1) * u.hour
    times = obstime + delta_midnight
    frame = AltAz(obstime=times, location=observer.location)
    moon_altazs = get_moon(times).transform_to(frame)
    sun_altazs = get_sun(times).transform_to(frame)
    target_altazs = target.coord.transform_to(frame)
    night = observer.is_night(times)
    up = observer.target_is_up(times, target)
    table = QTable()
    table['date'] = times
    # table['night'] = night
    table['target'] = target_altazs
    table['visible'] = up & night
    table['airmass'] = target_altazs.secz
    table['moon_separation'] = np.sqrt((target_altazs.alt -
                                        moon_altazs.alt)**2 +
                                       (target_altazs.az - moon_altazs.az)**2)
    table['moon_iluminationn'] = observer.moon_illumination(times)
    import pdb
    pdb.set_trace()
    return (table)
Пример #29
0
def moon_distance(ra=DEF__RA, dec=DEF__DEC, date=DEF__DATE, from_now=False):

    # check input(s)
    ra = DEF__RA if not isinstance(ra, float) else ra
    ra = MIN__RA if ra < MIN__RA else ra
    ra = MAX__RA if ra > MAX__RA else ra
    dec = DEF__DEC if not isinstance(dec, float) else dec
    dec = MIN__DEC if dec < MIN__DEC else dec
    dec = MAX__DEC if dec > MAX__DEC else dec
    date = DEF__DATE if (not isinstance(date, str) or date.strip() == '' or not re.search(ISO__PATTERN, date)) else date
    from_now = False if not isinstance(from_now, bool) else from_now

    # set default(s)
    _sep = None
    _time = Time(date) if from_now else Time(date.split()[0])
    _time = Time(_time.iso)
    _time = Time(_time) + (1.0 * u.day * np.linspace(0.0, 1.0, AST__5_MINUTES))

    # noinspection PyBroadException
    try:
        _moon_coord = get_moon(_time, location=KUIPER_OBSERVATORY)
        _obj_radec = SkyCoord(ra=ra*u.deg, dec=dec*u.deg)
        _sep = _obj_radec.separation(_moon_coord).deg
    except Exception:
        _sep = np.linspace(math.nan, math.nan, AST__5_MINUTES)

    # return array
    return _sep
Пример #30
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
Пример #31
0
def separateap():
    for ctime in times:
        t = start + ctime
        frame = AltAz(obstime=t, location=berlin)
        sunaltaz = get_sun(t).transform_to(frame)
        if sunaltaz.alt < astronight:
            #sunaltazs.append(sunaltaz.alt)
            #print(sunaltaz)
            #print(sunaltaz.alt)
            #print('Moon phase angle:', moon_phase_angle(t, berlin))
            lum = moon_illumination(t, berlin)
            #print('Moon illumination:', moon_illumination(t, berlin))

            if lum < maxillum:
                delta.append(ctime)
                illum.append(lum)
                moon = get_moon(t, berlin)
                moonaltaz = moon.transform_to(frame)
                #print("Moon's Altitude = {0.alt:.2}".format(moonaltaz))
                moonaltazs.append(moonaltaz.alt)
                # print(moonaltaz.alt)
                if mod == 'graph':
                    pass
                elif mod == 'text' or mod == 'both':
                    if moonaltaz.alt > Latitude(minalt * u.deg):

                        dtxt.write('Date and time: ' + str(t) + '\n' +
                                   'Altitude: ' + str(moonaltaz.alt) + '\n' +
                                   'Illumination: ' + str(lum) + '\n \n')

    if mod == 'text':
        pass
    elif mod == 'graph' or mod == 'both':
        chobj(delta, illum, moonaltazs)
Пример #32
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
Пример #33
0
def moon_angle(obsnight, coords):

    obstime = Time(str(obsnight.obs_date).split()[0], scale='utc')

    mooncoord = get_moon(obstime)
    cs = SkyCoord('%s %s' % (coords[0], coords[1]), unit=(u.hourangle, u.deg))
    return ('%.1f' % cs.separation(mooncoord).deg)
Пример #34
0
def get_moon_j2000(epoch, line1, line2, position=None):
    '''
    
    Code to determine the apparent J2000 position for a given
    time and at a given position for the observatory.
    
    epoch needs to be a datetime or Time object.
    
    position is a list/tuple of X/Y/Z positions
    
    '''

    from astropy.time import Time
    from astropy.coordinates import get_moon, EarthLocation
    import astropy.units as u
    import sys
    from datetime import datetime

    if type(epoch) is Time:
        epoch = epoch.datetime

    if position is None:
        position = get_nustar_location(epoch, line1,
                                       line2)  # position in ECI coords

    t = Time(epoch)

    loc = eci2el(*position * u.km, t)

    moon_coords = get_moon(t, loc)

    # Get just the coordinates in degrees

    ra_moon, dec_moon = moon_coords.ra.degree * u.deg, moon_coords.dec.degree * u.deg
    return ra_moon, dec_moon
Пример #35
0
def get_moon_angle(file_name, number_of_files=100):
    df_SKY=pd.read_csv(file_name)
    new_SKY = df_SKY.query('OBJTYPE=="SKY".ljust(16)')
    DEC = np.array(new_SKY['DEC'].tolist())
    FIBERID = np.array(new_SKY['FIBERID'].tolist())
    MJD = np.array(new_SKY['MJD'].tolist())
    RA = np.array(new_SKY['RA'].tolist())
    plates   = list(new_SKY['PLATE'][:number_of_files].values)
    mjds   = list(new_SKY['MJD'][:number_of_files].values)
    fiberids   = list(new_SKY['FIBERID'][:number_of_files].values)
    files = ['spec-%s-%s-%s.fits'%(plate,mjd,str(fiberid).zfill(4)) for plate,mjd,fiberid in zip(plates,mjds,fiberids)]
    #FINDING INTERPLATE SKY TIME
    fin_mean=[] #time for each moon sky observation interplate, used for moon angle
    for r in range(len(files)): #mechanization of ubiquitious exposure count
        sampling=fitsio.read_header(files[r],0) #finding number of exposures
        h_beg=[]
        h_end=[]
        mean_per=[] #time for each moon sky observation intraplate
        for k in range(4, sampling['NEXP']+4): #4 is constant for everything
            h=fitsio.read_header(files[3],k)
            h_beg.append(h['TAI-BEG']) #ONLY VARIES WITH PLATE NUMBER, different for k's
            h_end.append(h['TAI-END']) #ONLY VARIES WITH PLATE NUMBER, different for k's
            mean_times=(h['TAI-BEG']+h['TAI-END'])/2
            mean_per.append(mean_times)
        tot=np.mean(mean_per)
        fin_mean.append(tot)
    #TAI TO MJD
    new_time=np.array(fin_mean)
    time_MJD=new_time/(86400)
    moon_coords1=[]
    moon_coords=[]
    for i in range (len(time_MJD)):
        t=Time(time_MJD[i], format='mjd')
        moon_coords1.append(get_moon(t))
        moon_coords.append(moon_coords1[i].spherical)
    moon_coords=list(moon_coords)
    #print(moon_coords)
    moon_coords2=[]
    for i in range(len(moon_coords)):
        moon_coords2.append(moon_coords[i]._values)
    moon_coords2=np.array(moon_coords2)
    sky_coords=np.vstack((RA,DEC)).T
    #SPLITTING ARRAY
    new_sky_coords=sky_coords[:number_of_files]
    new_sky_RA = [item[0] for item in new_sky_coords]
    new_sky_DEC = [item[1] for item in new_sky_coords]
    moon_RA = [item[0] for item in moon_coords2]
    moon_DEC = [item[1] for item in moon_coords2]
    new_sky_RA=np.array(new_sky_RA)*(np.pi/180)
    new_sky_DEC=np.array(new_sky_DEC)*(np.pi/180)
    moon_RA=np.array(moon_RA)*(np.pi/180)
    moon_DEC=np.array(moon_DEC)*(np.pi/180)
    #MOON-SKY ANGLE CALCULATIONS
    moon_sky_angle=[]
    for i in range(len(new_sky_coords)):
        moon_sky_angle.append(np.arccos((np.sin(new_sky_RA[i])*np.sin(moon_RA[i]))+np.cos(new_sky_RA[i])*np.cos(moon_RA[i])*(np.cos(new_sky_DEC[i]-moon_DEC[i])))*(180/np.pi))
    #list(moon_sky_angle)
    return (np.array(moon_sky_angle))
Пример #36
0
def test_regression_5889_5890():
    # ensure we can represent all Representations and transform to ND frames
    greenwich = EarthLocation(
        *u.Quantity([3980608.90246817, -102.47522911, 4966861.27310067],
        unit=u.m))
    times = Time("2017-03-20T12:00:00") + np.linspace(-2, 2, 3)*u.hour
    moon = get_moon(times, location=greenwich)
    targets = SkyCoord([350.7*u.deg, 260.7*u.deg], [18.4*u.deg, 22.4*u.deg])
    targs2d = targets[:, np.newaxis]
    targs2d.transform_to(moon)
Пример #37
0
def test_regression_4926():
    times = Time('2010-01-1') + np.arange(20)*u.day
    green = get_builtin_sites()['greenwich']
    # this is the regression test
    moon = get_moon(times, green)

    # this is an additional test to make sure the GCRS->ICRS transform works for complex shapes
    moon.transform_to(ICRS())

    # and some others to increase coverage of transforms
    moon.transform_to(HCRS(obstime="J2000"))
    moon.transform_to(HCRS(obstime=times))
Пример #38
0
def test_moon_veto(observer):
    mac = MoonAvoidance()

    time = Time('2016-08-13 10:00:00')

    moon = get_moon(time, observer.location)

    observation1 = Observation(Field('Sabik', '17h10m23s -15d43m30s'))  # Sabik

    veto1, score1 = mac.get_score(time, observer, observation1, moon=moon)

    assert veto1 is True
Пример #39
0
    def __init__(self, date=None, site='sutherland', targets=None, tz=2*u.h, **options): #res
        
        self.sitename = site.title()
        self.siteloc = EarthLocation.of_site(self.sitename)
        #TODO from time import timezone
        self.tz = tz                         #can you get this from the site location??
        #obs = Observer(self.siteloc)
        self.targets = {}
        self.trajectories = {}
        self.plots = OrderedDict()
        
        if not date:
            now = datetime.now()        #current local time
            #default behaviour of this function changes depending on the time of day.
            #if calling during early morning hours (at telescope) - let midnight refer to previous midnight
            #if calling during afternoon hours - let midnight refer to coming midnight
            d = now.day# + (now.hour > 7)    #FIXME =32??
            date = datetime(now.year, now.month, d, 0, 0, 0)
        else:
            raise NotImplementedError
        self.date = date
        
        self.midnight = midnight = Time(date) - tz    #midnight UTC in local time
        #TODO: efficiency here.  Dont need to plot everything over 
        self.hours = h = np.linspace(-12, 12, 250) * u.h      #variable time 
        self.t = t = midnight + h
        self.tp = t.plot_date
        self.frames = AltAz(obstime=t, location=self.siteloc)
        #self.tmoon
        
        #collect name, coordinates in dict

        if not targets is None:
            self.add_coordinates(targets)
        
        #Get sun, moon coordinates
        sun = get_sun(t)
        self.sun = sun.transform_to(self.frames)    #WARNING: slow!!!!
        #TODO: other bright stars / planets
        
        #get dawn / dusk times
        self.dusk, self.dawn = self.get_daylight()
        self.sunset, self.sunrise = self.dusk['sunset'], self.dawn['sunrise']
        
        #get moon rise/set times, phase, illumination etc...
        self.moon = get_moon(t).transform_to(self.frames)
        self.mooning = self.get_moonlight()
        self.moon_phase, self.moon_ill  = self.get_moon_phase()
        
        self.setup_figure()
        #HACK
        self.cid = self.figure.canvas.mpl_connect('draw_event', self._on_first_draw)
Пример #40
0
def test_moon_avoidance(observer):
    mac = MoonAvoidance()

    time = Time('2016-08-13 10:00:00')

    moon = get_moon(time, observer.location)

    observation1 = Observation(Field('HD189733', '20h00m43.7135s +22d42m39.0645s'))  # HD189733
    observation2 = Observation(Field('Hat-P-16', '00h38m17.59s +42d27m47.2s'))  # Hat-P-16

    veto1, score1 = mac.get_score(time, observer, observation1, moon=moon)
    veto2, score2 = mac.get_score(time, observer, observation2, moon=moon)

    assert veto1 is False and veto2 is False
    assert score2 > score1
Пример #41
0
    def get_moon_phase(self):
        '''calculate moon phase and illumination at local midnight'''
        midnight = self.midnight
        altaz = AltAz(location=self.siteloc, obstime=midnight)

        moon = get_moon(midnight)
        moon = moon.transform_to(altaz)
        sun = get_sun(midnight)
        sun = sun.transform_to(altaz)

        #
        elongation = sun.separation(moon)
        #phase angle at midnight 
        phase = np.arctan2(sun.distance * np.sin(elongation),
                            moon.distance - sun.distance * np.cos(elongation))

        ill = (1 + np.cos(phase)) / 2.0
        return phase.value, ill.value
Пример #42
0
    def compute_constraint(self, times, observer, targets):
        # removed the location argument here, which causes small <1 deg
        # innacuracies, but it is needed until astropy PR #5897 is released
        # which should be astropy 1.3.2
        moon = get_moon(times,
                        ephemeris=self.ephemeris)
        # note to future editors - the order matters here
        # moon.separation(targets) is NOT the same as targets.separation(moon)
        # the former calculates the separation in the frame of the moon coord
        # which is GCRS, and that is what we want.
        moon_separation = moon.separation(targets)

        if self.min is None and self.max is not None:
            mask = self.max >= moon_separation
        elif self.max is None and self.min is not None:
            mask = self.min <= moon_separation
        elif self.min is not None and self.max is not None:
            mask = ((self.min <= moon_separation) &
                    (moon_separation <= self.max))
        else:
            raise ValueError("No max and/or min specified in "
                             "MoonSeparationConstraint.")
        return mask
Пример #43
0
def get_moon_j2000(epoch, line1, line2, position = None):
    '''
    
    Code to determine the apparent J2000 position for a given
    time and at a given position for the observatory.
    
    epoch needs to be a datetime or Time object.
    
    position is a list/tuple of X/Y/Z positions
    
    '''
    
    from astropy.time import Time
    from astropy.coordinates import get_moon, EarthLocation
    import astropy.units as u
    import sys
    from datetime import datetime
    
    if type(epoch) is Time:
        epoch = epoch.datetime
    
    
    if position is None:
        position = get_nustar_location(epoch, line1, line2)  # position in ECI coords


    t=Time(epoch)
    
    loc = eci2el(*position*u.km,t)

    moon_coords = get_moon(t,loc)
    
    # Get just the coordinates in degrees
    
    ra_moon, dec_moon = moon_coords.ra.degree * u.deg, moon_coords.dec.degree*u.deg
    return ra_moon, dec_moon
    def _update_queue(self, current_state):
        """Calculate greedy weighting of requests in the Pool using current
        telescope state only"""

        # store block index for which these values were calculated
        self.queue_block = block_index(current_state['current_time'])

        # check that the pool has fields in it
        if len(self.rp.pool) == 0:
            raise QueueEmptyError("No fields in pool")

        # join with fields so we have the information we need
        # make a copy so rp.pool and self.queue are not linked
        df = self.rp.pool.join(self.fields.fields, on='field_id').copy()

        df = self._update_overhead(current_state, df=df)

        # start with conservative altitude cut;
        # airmass weighting applied naturally below
        # also make a copy because otherwise it retains knowledge of
        # (discarded) previous reference and raises SettingWithCopyWarnings
        df = df.loc[df['altitude'] > 20, :].copy()

        if len(df) == 0:
            raise QueueEmptyError("No fields in queue above altitude cut")

        # if restricting to one program per block, drop other programs
        if self.block_programs:
            current_block_program = PROGRAM_BLOCK_SEQUENCE[
                self.queue_block % LEN_BLOCK_SEQUENCE]
            df = df.loc[df['program_id'] == current_block_program, :]

        # use cadence functions to compute requests with active cadence windows
        # this is slow, so do it after our altitude cut
        in_window = {}
        for idx, row in df.iterrows():
            # this is way, way slower
            # df['in_cadence_window'].ix[idx] = \
            in_window[idx] = eval(
                '{}(row, current_state)'.format(row['cadence_func']))

        cadence_cuts = pd.Series(in_window)
        # TODO: handle if cadence cuts returns no fields
        if np.sum(cadence_cuts) == 0:
            raise QueueEmptyError("No fields with observable cadence windows")
        # also make a copy because otherwise it retains knowledge of
        # (discarded) previous reference and raises SettingWithCopyWarnings
        df = df.loc[cadence_cuts, :].copy()

        # compute airmasses by field_id
        # airmass = zenith_angle_to_airmass(90. - df_alt)
        # airmass.name = 'airmass'
        # df = pd.merge(df, pd.DataFrame(airmass),
        #              left_on='field_id', right_index=True)
        # airmass cut (or add airmass weighting to value below)
        # df = df[(df['airmass'] <= MAX_AIRMASS) & (df['airmass'] > 0)]

        # compute inputs for sky brightness
        sc = coord.SkyCoord(df['ra'], df['dec'], frame='icrs', unit='deg')
        sun = coord.get_sun(current_state['current_time'])
        sun_altaz = skycoord_to_altaz(sun, current_state['current_time'])
        moon = coord.get_moon(current_state['current_time'],
                              location=P48_loc)
        moon_altaz = skycoord_to_altaz(moon, current_state['current_time'])
        df.loc[:, 'moonillf'] = astroplan.moon.moon_illumination(
            # Don't use P48_loc to avoid astropy bug:
            # https://github.com/astropy/astroplan/pull/213
            current_state['current_time'])
        # current_state['current_time'], P48_loc)
        df.loc[:, 'moon_dist'] = sc.separation(moon).to(u.deg).value
        df.loc[:, 'moonalt'] = moon_altaz.alt.to(u.deg).value
        df.loc[:, 'sunalt'] = sun_altaz.alt.to(u.deg).value

        # compute sky brightness
        df.loc[:, 'sky_brightness'] = self.Sky.predict(df)
        #df = pd.merge(df, df_sky, left_on='field_id', right_index=True)

        # compute seeing at each pointing
        df.loc[:, 'seeing'] = seeing_at_pointing(current_state['current_zenith_seeing'],
                                                 df['altitude'])
        #df_seeing.name = 'seeing'
        #df = pd.merge(df, df_seeing, left_on='field_id', right_index=True)

        df.loc[:, 'limiting_mag'] = limiting_mag(EXPOSURE_TIME, df['seeing'],
                                                 df['sky_brightness'],
                                                 filter_id=df['filter_id'],
                                                 altitude=df['altitude'], SNR=5.)
        #df_limmag.name = 'limiting_mag'
        #df = pd.merge(df, df_limmag, left_on='field_id', right_index=True)

        df.loc[:, 'value'] = self._metric(df)

        self.queue = df
Пример #45
0
    def log_pointing(self, state, request):

        record = {}
        # don't use request_id here, but
        # let sqlite create a unique non-null key
        # record['obsHistID'] = request['request_id']
        record["sessionID"] = 0
        record["propID"] = request["target_program_id"]
        record["fieldID"] = request["target_field_id"]
        record["fieldRA"] = np.radians(request["target_ra"])
        record["fieldDec"] = np.radians(request["target_dec"])

        record["filter"] = '"' + FILTER_ID_TO_NAME[request["target_filter_id"]] + '"'
        # times are recorded at start of exposure
        exposure_start = state["current_time"] - request["target_exposure_time"]
        # see note in utils.py
        exposure_start.delta_ut1_utc = 0.0

        record["expDate"] = (exposure_start - self.survey_start_time).sec
        record["expMJD"] = exposure_start.mjd

        record["night"] = np.floor((exposure_start - self.survey_start_time).jd).astype(np.int)
        record["visitTime"] = request["target_exposure_time"].to(u.second).value
        record["visitExpTime"] = request["target_exposure_time"].to(u.second).value

        # compute some values we will need
        sc = coord.SkyCoord(record["fieldRA"] * u.radian, record["fieldDec"] * u.radian)
        altaz = skycoord_to_altaz(sc, exposure_start)

        pointing_seeing = seeing_at_pointing(state["current_zenith_seeing"].to(u.arcsec).value, altaz.alt.value)
        record["FWHMgeom"] = pointing_seeing
        record["FWHMeff"] = pointing_seeing
        # transparency

        # finRank
        record["airmass"] = altaz.secz.value
        # vSkyBright
        record["filtSkyBright"] = request["target_sky_brightness"]
        record["rotSkyPos"] = 0.0  # TODO: confirm
        record["rotTelPos"] = 0.0
        # despite the docs, it seems lst is stored as radians
        record["lst"] = np.radians(exposure_start.sidereal_time("apparent").to(u.hourangle).value / 24.0 * 360.0)
        record["altitude"] = altaz.alt.to(u.radian).value
        record["azimuth"] = altaz.az.to(u.radian).value

        sun = coord.get_sun(exposure_start)
        sun_altaz = skycoord_to_altaz(sun, exposure_start)
        moon = coord.get_moon(exposure_start, P48_loc)
        moon_altaz = skycoord_to_altaz(moon, exposure_start)
        record["dist2Moon"] = sc.separation(moon).to(u.radian).value
        record["solarElong"] = sc.separation(sun).to(u.deg).value
        record["moonRA"] = moon.ra.to(u.radian).value
        record["moonDec"] = moon.dec.to(u.radian).value
        record["moonAlt"] = moon_altaz.alt.to(u.radian).value
        record["moonAZ"] = moon_altaz.az.to(u.radian).value

        # store tonight's mjd so that we can avoid recomputing moon
        # illumination, which profiling shows is weirdly expensive
        if np.floor(exposure_start.mjd) != self.mjd_tonight:
            self.moon_illumination_tonight = (
                astroplan.moon.moon_illumination(
                    # Don't use P48_loc to avoid astropy bug:
                    # https://github.com/astropy/astroplan/pull/213
                    # exposure_start, P48_loc) * 100.
                    exposure_start
                )
                * 100.0
            )
            self.mjd_tonight = np.floor(exposure_start.mjd)

        record["moonPhase"] = self.moon_illumination_tonight

        record["sunAlt"] = sun_altaz.alt.to(u.radian).value
        record["sunAz"] = sun_altaz.az.to(u.radian).value
        # phaseAngle, rScatter, mieScatter, moonBright, darkBright
        # rawSeeing
        # wind
        # humidity
        if self.prev_obs is not None:
            sc_prev = coord.SkyCoord(self.prev_obs["fieldRA"] * u.radian, self.prev_obs["fieldDec"] * u.radian)
            record["slewDist"] = sc.separation(sc_prev).to(u.radian).value
            record["slewTime"] = record["expDate"] - (self.prev_obs["expDate"] + self.prev_obs["visitTime"])
        record["fiveSigmaDepth"] = request["target_limiting_mag"]
        record["ditheredRA"] = 0.0
        record["ditheredDec"] = 0.0

        # ztf_sim specific keywords!
        record["requestNumberTonight"] = request["target_request_number_tonight"]
        record["totalRequestsTonight"] = request["target_total_requests_tonight"]
        record["metricValue"] = request["target_metric_value"]

        # use placeholders to create the INSERT query
        columns = ", ".join(record.keys())
        placeholders = "{" + "}, {".join(record.keys()) + "}"
        query = "INSERT INTO Summary ({}) VALUES ({})".format(columns, placeholders)
        query_filled = query.format(**record)
        self.conn.execute(query_filled)

        # save record for next obs
        self.prev_obs = record

        pass
Пример #46
0
# evenly spaced times between noon on July 12 and noon on July 13:

from astropy.coordinates import get_sun
delta_midnight = np.linspace(-12, 12, 1000)*u.hour
times_July12_to_13 = midnight + delta_midnight
frame_July12_to_13 = AltAz(obstime=times_July12_to_13, location=bear_mountain)
sunaltazs_July12_to_13 = get_sun(times_July12_to_13).transform_to(frame_July12_to_13)


##############################################################################
# Do the same with `~astropy.coordinates.get_moon` to find when the moon is
# up. Be aware that this will need to download a 10MB file from the internet
# to get a precise location of the moon.

from astropy.coordinates import get_moon
moon_July12_to_13 = get_moon(times_July12_to_13)
moonaltazs_July12_to_13 = moon_July12_to_13.transform_to(frame_July12_to_13)

##############################################################################
# Find the alt,az coordinates of M33 at those same times:

m33altazs_July12_to_13 = m33.transform_to(frame_July12_to_13)

##############################################################################
# Make a beautiful figure illustrating nighttime and the altitudes of M33 and
# the Sun over that time:

plt.plot(delta_midnight, sunaltazs_July12_to_13.alt, color='r', label='Sun')
plt.plot(delta_midnight, moonaltazs_July12_to_13.alt, color=[0.75]*3, ls='--', label='Moon')
plt.scatter(delta_midnight, m33altazs_July12_to_13.alt,
            c=m33altazs_July12_to_13.az, label='M33', lw=0, s=8,
Пример #47
0
def simulate_a_telescope(name, altitude, longitude, latitude, filter, time_start, time_end, sampling, event, location,
                         bad_weather_percentage=0.0, minimum_alt=20, moon_windows_avoidance=20,
                         maximum_moon_illumination=100.0):
    """ Simulate a telescope. More details in the telescopes module. The observations simulation are made for the
        full time windows, then limitation are applied :
            - Sun has to be below horizon : Sun< -18
            - Moon has to be more than the moon_windows_avoidance distance from the target
            - Observations altitude of the target have to be bigger than minimum_alt

        :param str name:  the name of the telescope.
        :param float altitude: the altitude in meters if the telescope
        :param float longitude: the longitude in degree of the telescope location
        :param float latitude: the latitude in degree of the telescope location
        :param str filter: the filter used for observations
        :param float time_start: the start of observations in JD
        :param float time_end: the end of observations in JD
        :param float sampling: the hour sampling.
        :param object event: the microlensing event you look at
        :param str location: the location of the telescope. If it is 'Space', then the observations are made
                             continuously given the observing windows and the sampling.
        :param float bad_weather_percentage: the percentage of bad nights
        :param float minimum_alt: the minimum altitude ini degrees that your telescope can go to.
        :param float moon_windows_avoidance: the minimum distance in degrees accepted between the target and the Moon
        :param float maximum_moon_illumination: the maximum Moon brightness you allow in percentage

        :return: a telescope object
        :rtype: object
    """

    # fake lightcurve
    if location != 'Space':
        earth_location = EarthLocation(lon=longitude * astropy.units.deg,
                                       lat=latitude * astropy.units.deg,
                                       height=altitude * astropy.units.m)

        target = SkyCoord(event.ra, event.dec, unit='deg')

        minimum_sampling = min(4.0, sampling)
        ratio_sampling = np.round(sampling / minimum_sampling)

        time_of_observations = time_simulation(time_start, time_end, minimum_sampling,
                                               bad_weather_percentage)

        time_convertion = Time(time_of_observations, format='jd').isot

        telescope_altaz = target.transform_to(AltAz(obstime=time_convertion, location=earth_location))
        altazframe = AltAz(obstime=time_convertion, location=earth_location)
        Sun = get_sun(Time(time_of_observations, format='jd')).transform_to(altazframe)
        Moon = get_moon(Time(time_of_observations, format='jd')).transform_to(altazframe)
        Moon_illumination = moon_illumination(Sun, Moon)
        Moon_separation = target.separation(Moon)
        observing_windows = np.where((telescope_altaz.alt > minimum_alt * astropy.units.deg)
                                     & (Sun.alt < -18 * astropy.units.deg)
                                     & (Moon_separation > moon_windows_avoidance * astropy.units.deg)
                                     & (Moon_illumination<maximum_moon_illumination)
                                     )[0]

        time_of_observations = time_of_observations[observing_windows][::ratio_sampling]

    else:

        time_of_observations = np.arange(time_start, time_end, sampling / (24.0))

    lightcurveflux = np.ones((len(time_of_observations), 3)) * 42
    lightcurveflux[:, 0] = time_of_observations

    telescope = telescopes.Telescope(name=name, camera_filter=filter, light_curve_flux=lightcurveflux)

    return telescope
Пример #48
0
def test_regression_5209():
    "check that distances are not lost on SkyCoord init"
    time = Time('2015-01-01')
    moon = get_moon(time)
    new_coord = SkyCoord([moon])
    assert_quantity_allclose(new_coord[0].distance, moon.distance)
Пример #49
0
    def get_observation(self, time=None, show_all=False, reread_fields_file=False):
        """Get a valid observation

        Args:
            time (astropy.time.Time, optional): Time at which scheduler applies,
                defaults to time called
            show_all (bool, optional): Return all valid observations along with
                merit value, defaults to False to only get top value
            reread_fields_file (bool, optional): If targets file should be reread
                before getting observation, default False.

        Returns:
            tuple or list: A tuple (or list of tuples) with name and score of ranked observations
        """
        if reread_fields_file:
            self.logger.debug("Rereading fields file")
            # The setter method on `fields_file` will force a reread
            self.fields_file = self.fields_file

        if time is None:
            time = current_time()

        valid_obs = {obs: 1.0 for obs in self.observations}
        best_obs = []

        common_properties = {
            'end_of_night': self.observer.tonight(time=time, horizon=-18 * u.degree)[-1],
            'moon': get_moon(time, self.observer.location)
        }

        for constraint in listify(self.constraints):
            self.logger.debug("Checking Constraint: {}".format(constraint))
            for obs_name, observation in self.observations.items():
                if obs_name in valid_obs:
                    self.logger.debug("\tObservation: {}".format(obs_name))

                    veto, score = constraint.get_score(
                        time, self.observer, observation, **common_properties)

                    self.logger.debug("\t\tScore: {}\tVeto: {}".format(score, veto))

                    if veto:
                        self.logger.debug("\t\t{} vetoed by {}".format(obs_name, constraint))
                        del valid_obs[obs_name]
                        continue

                    valid_obs[obs_name] += score

        for obs_name, score in valid_obs.items():
            valid_obs[obs_name] += self.observations[obs_name].priority

        if len(valid_obs) > 0:
            # Sort the list by highest score (reverse puts in correct order)
            best_obs = sorted(valid_obs.items(), key=lambda x: x[1])[::-1]

            top_obs = best_obs[0]

            # Check new best against current_observation
            if self.current_observation is not None \
                    and top_obs[0] != self.current_observation.name:

                # Favor the current observation if still available
                end_of_next_set = time + self.current_observation.set_duration
                if self.observation_available(self.current_observation, end_of_next_set):

                    # If current is better or equal to top, use it
                    if self.current_observation.merit >= top_obs[1]:
                        best_obs.insert(0, self.current_observation)

            # Set the current
            self.current_observation = self.observations[top_obs[0]]
            self.current_observation.merit = top_obs[1]
        else:
            if self.current_observation is not None:
                # Favor the current observation if still available
                end_of_next_set = time + self.current_observation.set_duration
                if end_of_next_set < common_properties['end_of_night'] and \
                        self.observation_available(self.current_observation, end_of_next_set):

                    self.logger.debug("Reusing {}".format(self.current_observation))
                    best_obs = [(self.current_observation.name, self.current_observation.merit)]
                else:
                    self.logger.warning("No valid observations found")
                    self.current_observation = None

        if not show_all and len(best_obs) > 0:
            best_obs = best_obs[0]

        return best_obs