def _calc_value(self, conditions, indx=None):
        to_mask = np.where((int_rounded(conditions.az) > self.az_min)
                           & (int_rounded(conditions.az) < self.az_max))[0]
        result = self.result.copy()
        result[to_mask] = self.out_of_bounds_val

        return result
    def __init__(self,
                 nside=None,
                 min_alt=20.,
                 max_alt=82.,
                 shadow_minutes=40.,
                 penalty=np.nan,
                 site='LSST'):
        super(Zenith_shadow_mask_basis_function, self).__init__(nside=nside)
        self.update_on_newobs = False

        self.penalty = penalty

        self.min_alt = np.radians(min_alt)
        self.max_alt = np.radians(max_alt)
        self.ra, self.dec = _hpid2RaDec(nside, np.arange(hp.nside2npix(nside)))
        self.shadow_minutes = np.radians(shadow_minutes / 60. * 360. / 24.)
        # Compute the declination band where things could drift into zenith
        self.decband = np.zeros(self.dec.size, dtype=float)
        self.zenith_radius = np.radians(90. - max_alt) / 2.
        site = Site(name=site)
        self.lat_rad = site.latitude_rad
        self.lon_rad = site.longitude_rad
        self.decband[np.where(
            (int_rounded(self.dec) < int_rounded(self.lat_rad +
                                                 self.zenith_radius))
            & (int_rounded(self.dec) > int_rounded(self.lat_rad -
                                                   self.zenith_radius)))] = 1

        self.result = np.empty(hp.nside2npix(self.nside), dtype=float)
        self.result.fill(self.penalty)
    def _calc_value(self, conditions, indx=None):

        result = self.result.copy()
        alt_limit = np.where(
            (int_rounded(conditions.alt) > int_rounded(self.min_alt))
            & (int_rounded(conditions.alt) < int_rounded(self.max_alt)))[0]
        result[alt_limit] = 1
        return result
 def __init__(self,
              nside=None,
              out_of_bounds_val=np.nan,
              az_min=0.,
              az_max=180.):
     super(Mask_azimuth_basis_function, self).__init__(nside=nside)
     self.az_min = int_rounded(np.radians(az_min))
     self.az_max = int_rounded(np.radians(az_max))
     self.out_of_bounds_val = out_of_bounds_val
     self.result = np.ones(hp.nside2npix(self.nside))
 def _check_queue_mjd_only(self, mjd):
     """
     Check if there are things in the queue that can be executed using only MJD and not full conditions.
     This is primarly used by sim_runner to reduce calls calculating updated conditions when they are not
     needed.
     """
     result = False
     if len(self.queue) > 0:
         if (int_rounded(mjd) < int_rounded(self.queue[0]['flush_by_mjd'])
             ) | (self.queue[0]['flush_by_mjd'] == 0):
             result = True
     return result
Ejemplo n.º 6
0
 def __init__(self, filtername='r', nside=None, FWHMeff_limit=100.):
     if nside is None:
         nside = utils.set_default_nside()
     self.filtername = filtername
     self.FWHMeff_limit = int_rounded(FWHMeff_limit)
     # Starting at limiting mag of zero should be fine.
     self.feature = np.zeros(hp.nside2npix(nside), dtype=float)
    def _calc_value(self, conditions, indx=None):
        result = self.result.copy()

        angular_distance = _angularSeparation(conditions.az, conditions.alt,
                                              conditions.moonAz,
                                              conditions.moonAlt)

        result[int_rounded(angular_distance) < self.moon_distance] = np.nan

        return result
Ejemplo n.º 8
0
    def calc_reward_function(self, conditions):
        """
        """
        # Set the number of observations we are going to try and take
        self._set_block_size(conditions)
        #  Computing reward like usual with basis functions and weights
        if self._check_feasibility(conditions):
            self.reward = 0
            indx = np.arange(hp.nside2npix(self.nside))
            for bf, weight in zip(self.basis_functions, self.basis_weights):
                basis_value = bf(conditions, indx=indx)
                self.reward += basis_value * weight
                # might be faster to pull this out into the feasabiliity check?
            if self.smoothing_kernel is not None:
                self.smooth_reward()

            # Apply max altitude cut
            too_high = np.where(
                int_rounded(conditions.alt) > int_rounded(self.alt_max))
            self.reward[too_high] = np.nan

            # Select healpixels within some radius of the max
            # This is probably faster with a kd-tree.

            max_hp = np.where(self.reward == np.nanmax(self.reward))[0]
            if np.size(max_hp) > 0:
                peak_reward = np.min(max_hp)
            else:
                # Everything is masked, so get out
                return -np.inf

            # Apply radius selection
            dists = _angularSeparation(self.ra[peak_reward],
                                       self.dec[peak_reward], self.ra,
                                       self.dec)
            out_hp = np.where(
                int_rounded(dists) > int_rounded(self.search_radius))
            self.reward[out_hp] = np.nan

            # Apply az cut
            az_centered = conditions.az - conditions.az[peak_reward]
            az_centered[np.where(az_centered < 0)] += 2. * np.pi

            az_out = np.where(
                (int_rounded(az_centered) > int_rounded(self.az_range / 2.))
                & (int_rounded(az_centered) < int_rounded(2. * np.pi -
                                                          self.az_range / 2.)))
            self.reward[az_out] = np.nan
        else:
            self.reward = -np.inf
        self.reward_checked = True
        return self.reward
Ejemplo n.º 9
0
    def add_observation(self, observation, indx=None):

        if observation['filter'] == self.filtername:
            if int_rounded(observation['FWHMeff']) <= self.FWHMeff_limit:
                m5 = m5_flat_sed(observation['filter'],
                                 observation['skybrightness'],
                                 observation['FWHMeff'],
                                 observation['exptime'],
                                 observation['airmass'])

                self.feature[indx] = 1.25 * np.log10(
                    10.**(0.8 * self.feature[indx]) + 10.**(0.8 * m5))
    def _calc_value(self, conditions, indx=None):

        result = self.result.copy()
        alt_limit = np.where(
            (int_rounded(conditions.alt) > int_rounded(self.min_alt))
            & (int_rounded(conditions.alt) < int_rounded(self.max_alt)))[0]
        result[alt_limit] = 1
        to_mask = np.where((int_rounded(conditions.HA) > int_rounded(
            2. * np.pi - self.shadow_minutes - self.zenith_radius))
                           & (self.decband == 1))
        result[to_mask] = np.nan
        return result
Ejemplo n.º 11
0
    def __call__(self, observation_list, conditions):
        obs_array = np.concatenate(observation_list)
        alt, az = _approx_RaDec2AltAz(obs_array['RA'], obs_array['dec'],
                                      conditions.site.latitude_rad,
                                      conditions.site.longitude_rad,
                                      conditions.mjd)
        alt_diff = np.abs(alt - conditions.telAlt)
        in_band = np.where(int_rounded(alt_diff) <= self.alt_band)[0]
        if in_band.size == 0:
            in_band = np.arange(alt.size)

        # Find the closest in angular distance of the points that are in band
        ang_dist = _angularSeparation(az[in_band], alt[in_band],
                                      conditions.telAz, conditions.telAlt)
        good = np.min(np.where(ang_dist == ang_dist.min())[0])
        indx = in_band[good]
        result = observation_list[indx:] + observation_list[:indx]
        return result
    def request_observation(self, mjd=None):
        """
        Ask the scheduler what it wants to observe next

        Paramters
        ---------
        mjd : float (None)
            The Modified Julian Date. If None, it uses the MJD from the conditions from the last conditions update.

        Returns
        -------
        observation object (ra,dec,filter,rotangle)
        Returns None if the queue fails to fill
        """
        if mjd is None:
            mjd = self.conditions.mjd
        if len(self.queue) == 0:
            self._fill_queue()

        if len(self.queue) == 0:
            return None
        else:
            # If the queue has gone stale, flush and refill. Zero means no flush_by was set.
            if (int_rounded(mjd) > int_rounded(self.queue[0]['flush_by_mjd'])
                ) & (self.queue[0]['flush_by_mjd'] != 0):
                self.flushed += len(self.queue)
                self.flush_queue()
                self._fill_queue()
            if len(self.queue) == 0:
                return None
            observation = self.queue.pop(0)
            # If we are limiting the camera rotator
            if self.rotator_limits is not None:
                alt, az = _approx_RaDec2AltAz(
                    observation['RA'], observation['dec'],
                    self.conditions.site.latitude_rad,
                    self.conditions.site.longitude_rad, mjd)
                obs_pa = approx_altaz2pa(alt, az,
                                         self.conditions.site.latitude_rad)
                rotTelPos_expected = (obs_pa -
                                      observation['rotSkyPos']) % (2. * np.pi)
                if (int_rounded(rotTelPos_expected) > int_rounded(
                        self.rotator_limits[0])) & (
                            int_rounded(rotTelPos_expected) < int_rounded(
                                self.rotator_limits[1])):
                    diff = np.abs(self.rotator_limits - rotTelPos_expected)
                    limit_indx = np.min(np.where(diff == np.min(diff))[0])
                    observation['rotSkyPos'] = (
                        obs_pa - self.rotator_limits[limit_indx]) % (2. *
                                                                     np.pi)
            return observation
Ejemplo n.º 13
0
 def __init__(self, alt_band=10.):
     super(Close_alt_detailer, self).__init__()
     self.alt_band = int_rounded(np.radians(alt_band))
    def __init__(self, nside=None, moon_distance=30.):
        super(Moon_avoidance_basis_function, self).__init__(nside=nside)
        self.update_on_newobs = False

        self.moon_distance = int_rounded(np.radians(moon_distance))
        self.result = np.ones(hp.nside2npix(self.nside), dtype=float)
Ejemplo n.º 15
0
 def check_feasibility(self, conditions):
     available_time = getattr(conditions, 'sun_n' + self.alt_limit + '_rising') - conditions.mjd
     result = int_rounded(available_time) < self.time_remaining
     return result
Ejemplo n.º 16
0
 def __init__(self, time_remaining=30., alt_limit=18):
     super(End_of_evening_basis_function, self).__init__()
     self.time_remaining = int_rounded(time_remaining/60./24.)
     self.alt_limit = str(alt_limit)
Ejemplo n.º 17
0
 def __init__(self, illum_limit=10.):
     self.illum_limit_IR = int_rounded(illum_limit)
Ejemplo n.º 18
0
    def check_feasibility(self, conditions):
        result = True
        target_HA = (conditions.lmst - self.ra_hours) % 24
        ratio = self.survey_features['N_survey'].feature / self.survey_features['Ntot'].feature
        available_time = getattr(conditions, 'sun_' + self.sun_alt_limit + '_rising') - conditions.mjd
        # If it's more that self.time_jump to hour angle zero
        # See if there will be enough time to twilight in the future
        if (int_rounded(target_HA) > int_rounded(12)) & (int_rounded(target_HA) < int_rounded(24.-self.time_jump)):
            if int_rounded(available_time) > int_rounded(self.time_needed + self.time_jump):
                result = False
                # If we paused for better conditions, but the moon will rise, turn things back on.
                if int_rounded(conditions.moonAlt) < int_rounded(0):
                    if int_rounded(conditions.moonrise) > int_rounded(conditions.mjd):
                        if int_rounded(conditions.moonrise - conditions.mjd) > int_rounded(self.time_jump):
                            result = True
        # If the moon is up and will set soon, pause
        if int_rounded(conditions.moonAlt) > int_rounded(0):
            time_after_moonset = getattr(conditions, 'sun_' + self.sun_alt_limit + '_rising') - conditions.moonset
            if int_rounded(conditions.moonset) > int_rounded(self.time_jump):
                if int_rounded(time_after_moonset) > int_rounded(self.time_needed):
                    result = False

        # If the survey has fallen far behind, be agressive and observe anytime it's up.
        if int_rounded(ratio) < int_rounded(self.aggressive_fraction):
            result = True
        return result
Ejemplo n.º 19
0
 def __call__(self, conditions):
     if int_rounded(conditions.moonPhase) > self.illum_limit_IR:
         result = ['g', 'r', 'i', 'z', 'y']
     else:
         result = ['u', 'g', 'r', 'i', 'y']
     return result