示例#1
0
 def __init__(self,
              mjd_start,
              sun_RA_start=0,
              nside=32,
              filters={
                  'u': 0,
                  'g': 1,
                  'r': 2,
                  'i': 3,
                  'z': 4,
                  'y': 5
              },
              period=365.25,
              step_func=None):
     self.period = period
     self.nside = nside
     if step_func is None:
         step_func = Step_line()
     self.step_func = step_func
     self.mjd_start = mjd_start
     self.sun_RA_start = sun_RA_start
     self.npix = hp.nside2npix(nside)
     self.filters = filters
     self.ra, self.dec = _hpid2RaDec(self.nside, np.arange(self.npix))
     # Set the phase of each healpixel. If RA to sun is zero, we are at phase np.pi/2.
     self.phase = (-self.ra + self.sun_RA_start + np.pi / 2) % (2. * np.pi)
     self.phase = self.phase * (self.period / 2. / np.pi)
     # Empty footprints to start
     self.out_dtype = list(zip(filters, [float] * len(filters)))
     self.footprints = np.zeros((len(filters), self.npix), dtype=float)
     self.estimate = np.zeros((len(filters), self.npix), dtype=float)
     self.current_footprints = np.zeros((len(filters), self.npix),
                                        dtype=float)
     self.zero = self.step_func(0., self.phase)
     self.mjd_current = None
    def __init__(self, surveys, nside=default_nside, camera='LSST'):
        """
        Parameters
        ----------
        surveys : list of survey objects
            A list of surveys to consider. If multiple surveys retrurn the same highest
            reward value, the survey at the earliest position in the list will be selected.
        nside : int
            A HEALpix nside value.
        camera : str ('LSST')
            Which camera to use for computing overlapping HEALpixels for an observation.
            Can be 'LSST' or 'comcam'
        """
        if nside is None:
            nside = set_default_nside()

        # initialize a queue of observations to request
        self.queue = []
        self.surveys = surveys
        self.nside = nside
        hpid = np.arange(hp.nside2npix(nside))
        self.ra_grid_rad, self.dec_grid_rad = _hpid2RaDec(nside, hpid)
        self.conditions = None
        # Should just make camera a class that takes a pointing and returns healpix indices
        if camera == 'LSST':
            self.pointing2hpindx = hp_in_lsst_fov(nside=nside)
        elif camera == 'comcam':
            self.pointing2hpindx = hp_in_comcam_fov(nside=nside)
        else:
            raise ValueError('camera %s not implamented' % camera)
示例#3
0
    def test_rad(self):
        nside = 64
        hpids = np.arange(hp.nside2npix(nside))
        ra, dec = utils._hpid2RaDec(nside, hpids)
        mjd = 59852.
        obs = utils.ObservationMetaData(mjd=mjd)

        alt1, az1, pa1 = utils._altAzPaFromRaDec(ra, dec, obs)

        alt2, az2 = utils._approx_RaDec2AltAz(ra, dec, obs.site.latitude_rad,
                                              obs.site.longitude_rad, mjd)

        # Check that the fast is similar to the more precice transform
        tol = np.radians(2)
        tol_mean = np.radians(1.)
        separations = utils._angularSeparation(az1, alt1, az2, alt2)

        self.assertLess(np.max(separations), tol)
        self.assertLess(np.mean(separations), tol_mean)

        # Check that the fast can nearly round-trip
        ra_back, dec_back = utils._approx_altAz2RaDec(alt2, az2, obs.site.latitude_rad,
                                                      obs.site.longitude_rad, mjd)
        separations = utils._angularSeparation(ra, dec, ra_back, dec_back)
        self.assertLess(np.max(separations), tol)
        self.assertLess(np.mean(separations), tol_mean)
示例#4
0
def hp2screen(inmap,
              mjd,
              height=500,
              alt_limit=10.,
              npts=600,
              grid_x=None,
              grid_y=None):
    """
    Convert a healpy map to a flat screen at height h
    """
    nside = hp.npix2nside(inmap.size)
    unmasked = np.where(inmap != hp.UNSEEN)[0]
    ra, dec = _hpid2RaDec(nside, unmasked)
    alt, az = stupidFast_RaDec2AltAz(ra, dec, lat, lon, mjd)
    good = np.where(np.degrees(alt) > alt_limit)
    r = height / np.tan(alt[good])
    x = r * np.cos(az[good])
    y = r * np.sin(az[good])
    z = inmap[unmasked][good]

    if grid_x is None:
        grid_x, grid_y = np.mgrid[x.min():x.max():600j, y.min():y.max():600j]
    screen_grid = interpolate.griddata(np.vstack((x, y)).T,
                                       z, (grid_x, grid_y),
                                       method='nearest')

    # Maybe compute the alt-az of the grid_x, grid_y so that it'll be fast to convert back to ra, dec?
    # Pretty clear this should be a class rather than a bunch of functions.

    return grid_x, grid_y, screen_grid
def ra_dec_hp_map(nside=64):
    """
    Return all the RA,dec points for the centers of a healpix map
    """
    ra, dec = _hpid2RaDec(nside, np.arange(hp.nside2npix(nside)))

    return ra, dec
示例#6
0
    def __init__(self, nside=default_nside, alt_min=20.):
        """
        Parameters
        ----------
        alt_min : float
            The minimum altitude one can point the telescope (degrees)
        """
        if nside is None:
            nside = utils.set_default_nside()

        self.ra, self.dec = _hpid2RaDec(nside, np.arange(hp.nside2npix(nside)))
        self.min_alt = np.radians(alt_min)

        self.sin_dec = np.sin(self.dec)
        self.cos_dec = np.cos(self.dec)

        site = Site('LSST')
        self.sin_lat = np.sin(site.latitude_rad)
        self.cos_lat = np.cos(site.latitude_rad)
        self.lon = site.longitude_rad

        # Compute hour angle when field hits the alt_min
        ha_alt_min = -np.arccos(
            (np.sin(self.min_alt) - self.sin_dec * self.sin_lat) /
            (self.cos_dec * self.cos_lat))
        self.ha_alt_min = ha_alt_min
        lmst_alt_min = ha_alt_min + self.ra
        lmst_alt_min[np.where(lmst_alt_min < 0)] += 2. * np.pi
        self.lmst_min = lmst_alt_min

        self.nans = np.isnan(self.lmst_min)
    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)
示例#8
0
    def __init__(self, nside=default_nside, alt_max=86.5):
        """
        Parameters
        ----------
        alt_max : float
            The maximum altitude one can point the telescope (degrees)
        """
        if nside is None:
            nside = utils.set_default_nside()

        self.ra, self.dec = _hpid2RaDec(nside, np.arange(hp.nside2npix(nside)))
        self.max_alt = np.radians(alt_max)

        self.sin_dec = np.sin(self.dec)
        self.cos_dec = np.cos(self.dec)

        site = Site('LSST')
        self.sin_lat = np.sin(site.latitude_rad)
        self.cos_lat = np.cos(site.latitude_rad)
        self.lon = site.longitude_rad

        # compute the hour angle when a point hits the alt_max
        cos_ha = (np.sin(self.max_alt) -
                  self.sin_dec * self.sin_lat) / (self.cos_dec * self.cos_lat)
        self.lmst_max = np.arccos(cos_ha) + self.ra
        self.nans = np.isnan(self.lmst_max)
示例#9
0
    def test_rad(self):
        nside = 64
        hpids = np.arange(hp.nside2npix(nside))
        ra, dec = utils._hpid2RaDec(nside, hpids)
        mjd = 59852.
        obs = utils.ObservationMetaData(mjd=mjd)

        alt1, az1, pa1 = utils._altAzPaFromRaDec(ra, dec, obs)

        alt2, az2 = utils._approx_RaDec2AltAz(ra, dec, obs.site.latitude_rad,
                                              obs.site.longitude_rad, mjd)

        # Check that the fast is similar to the more precice transform
        tol = np.radians(2)
        tol_mean = np.radians(1.)
        separations = utils._angularSeparation(az1, alt1, az2, alt2)

        self.assertLess(np.max(separations), tol)
        self.assertLess(np.mean(separations), tol_mean)

        # Check that the fast can nearly round-trip
        ra_back, dec_back = utils._approx_altAz2RaDec(alt2, az2,
                                                      obs.site.latitude_rad,
                                                      obs.site.longitude_rad,
                                                      mjd)
        separations = utils._angularSeparation(ra, dec, ra_back, dec_back)
        self.assertLess(np.max(separations), tol)
        self.assertLess(np.mean(separations), tol_mean)
    def __init__(self, nside=default_nside, max_airmass=2.5, polar_limit=-80.):
        """
        Parameters
        ----------
        max_airmass : float (2.5)
            The maximum airmass to consider a point visible
        polar_limit : float (-80.)
            Consider anything below dec polar_limit to always be visible. (degrees)
        """
        # most fields should have a min and max lmst where they are less than max_airmass

        self.ra, self.dec = _hpid2RaDec(nside, np.arange(hp.nside2npix(nside)))

        alt_limit = np.pi/2. - np.arccos(1./max_airmass)
        site = Site('LSST')
        lat = site.latitude_rad
        self.lon = site.longitude_rad

        sinalt = np.sin(alt_limit)
        sindec = np.sin(self.dec)
        sinlat = np.sin(lat)
        cosdec = np.cos(self.dec)
        coslat = np.cos(lat)

        cosha = (sinalt - sindec*sinlat)/(cosdec*coslat)
        # Here's the hour angle (plus or minus) for each healpixel
        self.ha_limit = np.arccos(cosha)*12/np.pi

        # Consider some regions circumpolar
        self.ha_limit[np.where(self.dec < np.radians(polar_limit))] = 12.

        self.polar_limit = polar_limit

        self.feature = self.ra * 0.
示例#11
0
def ra_dec_hp_map(nside=None):
    """
    Return all the RA,dec points for the centers of a healpix map, in radians.
    """
    if nside is None:
        nside = set_default_nside()
    ra, dec = _hpid2RaDec(nside, np.arange(hp.nside2npix(nside)))
    return ra, dec
示例#12
0
def bulge_pix(nside=32):
    result = np.zeros(hp.nside2npix(nside))
    ra, dec = _hpid2RaDec(nside, np.arange(hp.nside2npix(nside)))
    coord = SkyCoord(ra=ra*u.rad, dec=dec*u.rad)
    g_long, g_lat = coord.galactic.l.deg, coord.galactic.b.deg
    bulge_pix = np.where((g_long > -20) & (g_long < 20.) & (g_lat > -10) & (g_lat < 10.))
    result[bulge_pix] = 1
    return result
示例#13
0
def ss_footprints(nside=32, dist_to_eclip=25.):
    fp = standard_goals(nside=nside)
    et = ecliptic_target(nside=nside, dist_to_eclip=dist_to_eclip)
    ra, dec = _hpid2RaDec(nside, np.arange(hp.nside2npix(nside)))
    bridge = np.where((et > 0) & (dec < 0) & (fp['r'] != 1))
    for key in fp:
        fp[key][bridge] = np.max(fp[key])
    return fp
示例#14
0
def create_season_offset(nside, sun_RA_rad):
    """
    Make an offset map so seasons roll properly
    """
    hpindx = np.arange(hp.nside2npix(nside))
    ra, dec = _hpid2RaDec(nside, hpindx)
    offset = ra - sun_RA_rad + 2.*np.pi
    offset = offset % (np.pi*2)
    offset = offset * 365.25/(np.pi*2)
    offset = -offset - 365.25
    return offset
示例#15
0
    def _readMap(self):
        filename = 'TRIstarDensity_%s_nside_%i.npz' % (self.filtername, self.nside)
        starMap = np.load(os.path.join(self.mapDir, filename))
        self.starMap = starMap['starDensity'].copy()
        self.starMapBins = starMap['bins'].copy()
        self.starmapNside = hp.npix2nside(np.size(self.starMap[:, 0]))
        # note, the trilegal maps are in galactic coordinates, and nested healpix.
        gal_l, gal_b = _hpid2RaDec(self.nside, np.arange(hp.nside2npix(self.nside)), nest=True)

        # Convert that to RA,dec. Then do nearest neighbor lookup.
        ra, dec = _equatorialFromGalactic(gal_l, gal_b)
        self.tree = _buildTree(ra, dec)
示例#16
0
    def testRaDecsRad(self):
        """
        Test that the Ra Dec conversions round-trip
        """

        nside = 64
        hpids = np.arange(hp.nside2npix(nside))
        ra, dec = utils._hpid2RaDec(nside, hpids)

        hpids_return = utils._raDec2Hpid(nside, ra, dec)

        np.testing.assert_array_equal(hpids, hpids_return)
    def __init__(self,
                 surveys,
                 nside=None,
                 camera='LSST',
                 rotator_limits=[85., 275.],
                 log=None):
        """
        Parameters
        ----------
        surveys : list (or list of lists) of lsst.sims.featureScheduler.survey objects
            A list of surveys to consider. If multiple surveys return the same highest
            reward value, the survey at the earliest position in the list will be selected.
            Can also be a list of lists to make heirarchical priorities.
        nside : int
            A HEALpix nside value.
        camera : str ('LSST')
            Which camera to use for computing overlapping HEALpixels for an observation.
            Can be 'LSST' or 'comcam'
        rotator_limits : sequence of floats
        """
        if nside is None:
            nside = set_default_nside()

        if log is None:
            self.log = logging.getLogger(type(self).__name__)
        else:
            self.log = log.getChild(type(self).__name__)

        # initialize a queue of observations to request
        self.queue = []
        # The indices of self.survey_lists that provided the last addition(s) to the queue
        self.survey_index = [None, None]

        # If we have a list of survey objects, convert to list-of-lists
        if isinstance(surveys[0], list):
            self.survey_lists = surveys
        else:
            self.survey_lists = [surveys]
        self.nside = nside
        hpid = np.arange(hp.nside2npix(nside))
        self.ra_grid_rad, self.dec_grid_rad = _hpid2RaDec(nside, hpid)
        # Should just make camera a class that takes a pointing and returns healpix indices
        if camera == 'LSST':
            self.pointing2hpindx = hp_in_lsst_fov(nside=nside)
        elif camera == 'comcam':
            self.pointing2hpindx = hp_in_comcam_fov(nside=nside)
        else:
            raise ValueError('camera %s not implamented' % camera)

        # keep track of how many observations get flushed from the queue
        self.flushed = 0
        self.rotator_limits = np.sort(np.radians(rotator_limits))
def ecliptic_target(nside=32, dist_to_eclip=40., dec_max=30.):
    """Generate a target_map for the area around the ecliptic
    """

    ra, dec = _hpid2RaDec(nside, np.arange(hp.nside2npix(nside)))
    result = np.zeros(ra.size)
    coord = SkyCoord(ra=ra * u.rad, dec=dec * u.rad)
    eclip_lat = coord.barycentrictrueecliptic.lat.radian
    good = np.where((np.abs(eclip_lat) < np.radians(dist_to_eclip))
                    & (dec < np.radians(dec_max)))
    result[good] += 1

    return result
    def __init__(self,
                 nside=default_nside,
                 condition_features=None,
                 minAlt=20.,
                 maxAlt=82.,
                 azWidth=15.,
                 survey_features=None,
                 lat=-30.2444,
                 zenith_pad=15.,
                 zenith_min_alt=40.):
        """
        Parameters
        ----------
        minAlt : float (20.)
            The minimum altitude to consider (degrees)
        maxAlt : float (82.)
            The maximum altitude to leave unmasked (degrees)
        azWidth : float (15.)
            The full-width azimuth to leave unmasked (degrees)
        """
        if nside is None:
            nside = utils.set_default_nside()

        self.lat = np.radians(lat)

        if survey_features is None:
            self.survey_features = {}
        if condition_features is None:
            self.condition_features = {}
            self.condition_features['altaz'] = features.AltAzFeature(
                nside=nside)
        self.minAlt = np.radians(minAlt)
        self.maxAlt = np.radians(maxAlt)
        # Convert to half-width for convienence
        self.azWidth = np.radians(azWidth / 2.)
        self.nside = nside

        self.zenith_map = np.empty(hp.nside2npix(self.nside), dtype=float)
        self.zenith_map.fill(hp.UNSEEN)
        hpids = np.arange(self.zenith_map.size)
        ra, dec = _hpid2RaDec(nside, hpids)
        close_dec = np.where(
            np.abs(dec - np.radians(lat)) < np.radians(zenith_pad))
        self.zenith_min_alt = np.radians(zenith_min_alt)
        self.zenith_map[close_dec] = 1
示例#20
0
    def __call__(self, ra, dec, rotSkyPos):
        """
        Parameters
        ----------
        ra : float
            RA in radians
        dec : float
            Dec in radians
        rotSkyPos : float
            The rotation angle of the camera in radians
        Returns
        -------
        indx : numpy array
            The healpixels that are within the FoV
        """
        x, y, z = _xyz_from_ra_dec(np.max(ra), np.max(dec))
        # Healpixels within the inner circle
        indices = self.tree.query_ball_point((x, y, z), self.inner_radius)
        # Healpixels withing the outer circle
        indices_all = np.array(self.tree.query_ball_point((x, y, z), self.outter_radius))
        indices_to_check = indices_all[np.in1d(indices_all, indices, invert=True)]

        cos_rot = np.cos(rotSkyPos)
        sin_rot = np.sin(rotSkyPos)
        x_rotated = self.corners_x*cos_rot - self.corners_y*sin_rot
        y_rotated = self.corners_x*sin_rot + self.corners_y*cos_rot

        # Draw the square that we want to check if points are in.
        bbPath = mplPath.Path(np.array([[x_rotated[0], y_rotated[0]],
                                       [x_rotated[1], y_rotated[1]],
                                       [x_rotated[2], y_rotated[2]],
                                       [x_rotated[3], y_rotated[3]],
                                       [x_rotated[0], y_rotated[0]]]))

        ra_to_check, dec_to_check = _hpid2RaDec(self.nside, indices_to_check)

        # Project the indices to check to the tangent plane, see if they fall inside the polygon
        x, y = gnomonic_project_toxy(ra_to_check, dec_to_check, ra, dec)
        for i, xcheck in enumerate(x):
            # I wonder if I can do this all at once rather than a loop?
            if bbPath.contains_point((x[i], y[i])):
                indices.append(indices_to_check[i])

        return np.array(indices)
def big_sky(
    nside=32,
    weights={
        'u': [0.31, 0.15, False],
        'g': [0.44, 0.15],
        'r': [1., 0.3],
        'i': [1., 0.3],
        'z': [0.9, 0.3],
        'y': [0.9, 0.3, False]
    }):
    """
    Based on the Olsen et al Cadence White Paper
    """

    # wfd covers -72.25 < dec < 12.4. Avoid galactic plane |b| > 15 deg
    wfd_north = np.radians(12.4)
    wfd_south = np.radians(-72.25)
    full_north = np.radians(30.)
    g_lat_limit = np.radians(8.)

    ra, dec = _hpid2RaDec(nside, np.arange(hp.nside2npix(nside)))
    total_map = np.zeros(ra.size)
    coord = SkyCoord(ra=ra * u.rad, dec=dec * u.rad)
    g_long, g_lat = coord.galactic.l.radian, coord.galactic.b.radian

    # let's make a first pass here

    total_map[np.where(dec < full_north)] = 1e-6
    total_map[np.where((dec > wfd_south) & (dec < wfd_north)
                       & (np.abs(g_lat) > g_lat_limit))] = 1.

    # Now let's break it down by filter
    result = {}

    for key in weights:
        result[key] = total_map + 0.
        result[key][np.where(result[key] == 1)] = weights[key][0]
        result[key][np.where(result[key] == 1e-6)] = weights[key][1]
        if len(weights[key]) == 3:
            result[key][np.where(dec > wfd_north)] = 0.

    return result
示例#22
0
def hp_kd_tree(nside=set_default_nside(), leafsize=100):
    """
    Generate a KD-tree of healpixel locations

    Parameters
    ----------
    nside : int
        A valid healpix nside
    leafsize : int (100)
        Leafsize of the kdtree

    Returns
    -------
    tree : scipy kdtree
    """
    hpid = np.arange(hp.nside2npix(nside))
    ra, dec = _hpid2RaDec(nside, hpid)
    x, y, z = treexyz(ra, dec)
    tree = kdtree(list(zip(x, y, z)), leafsize=leafsize, balanced_tree=False, compact_nodes=False)
    return tree
def generate_events(nside=32,
                    mjd0=59853.5,
                    radius=15.,
                    survey_length=365.25 * 10,
                    rate=10.,
                    expires=3.,
                    seed=42):
    """
    Parameters
    ----------

    """

    np.random.seed(seed=seed)
    ra, dec = _hpid2RaDec(nside, np.arange(hp.nside2npix(nside)))
    radius = np.radians(radius)
    # Use a ceil here so we get at least 1 event even if doing a short run.
    n_events = np.int(np.ceil(survey_length / 365.25 * rate))
    names = ['mjd_start', 'ra', 'dec', 'expires']
    types = [float] * 4
    event_table = np.zeros(n_events, dtype=list(zip(names, types)))

    event_table['mjd_start'] = np.sort(
        np.random.random(n_events)) * survey_length + mjd0
    event_table['expires'] = event_table['mjd_start'] + expires
    # Make sure latitude points spread correctly
    # http://mathworld.wolfram.com/SpherePointPicking.html
    event_table['ra'] = np.random.rand(n_events) * np.pi * 2
    event_table['dec'] = np.arccos(2. * np.random.rand(n_events) -
                                   1.) - np.pi / 2.

    events = []
    for i, event_time in enumerate(event_table['mjd_start']):
        dist = _angularSeparation(ra, dec, event_table['ra'][i],
                                  event_table['dec'][i])
        good = np.where(dist <= radius)
        footprint = np.zeros(ra.size, dtype=float)
        footprint[good] = 1
        events.append(TargetoO(i, footprint, event_time, expires))
    events = Sim_targetoO_server(events)
    return events, event_table
示例#24
0
 def __call__(self):
     """
     Just point at the highest reward healpix
     """
     if not self.reward_checked:
         self.reward = self.calc_reward_function()
     # Just find the best one
     highest_reward = self.reward[np.where(~self.reward.mask)].max()
     best = [np.min(np.where(self.reward == highest_reward)[0])]
     # Could move this up to be a lookup rather than call every time.
     ra, dec = _hpid2RaDec(default_nside, best)
     observations = []
     for i, indx in enumerate(best):
         obs = empty_observation()
         obs['RA'] = ra[i]
         obs['dec'] = dec[i]
         obs['filter'] = self.filtername
         obs['nexp'] = 2.
         obs['exptime'] = 30.
         observations.append(obs)
     return observations
def generate_events_simple(nside=32, mjd0=59853.5, radius=15.):
    """
    Generate 3 simple ToO events
    """
    ra, dec = _hpid2RaDec(nside, np.arange(hp.nside2npix(nside)))
    radius = np.radians(radius)

    nights = [1, 3, 6]
    expires = 3
    event_ra = np.radians([0, 10, 350])
    event_dec = np.radians(-40.)

    events = []
    for i, nignt in enumerate(nights):
        dist = _angularSeparation(ra, dec, event_ra[i], event_dec)
        good = np.where(dist <= radius)
        footprint = np.zeros(ra.size, dtype=float)
        footprint[good] = 1
        events.append(TargetoO(i, footprint, mjd0 + nights[i], expires))
    events = Sim_targetoO_server(events)
    return events
示例#26
0
def hp_kd_tree(nside=None, leafsize=100, scale=1e5):
    """
    Generate a KD-tree of healpixel locations

    Parameters
    ----------
    nside : int
        A valid healpix nside
    leafsize : int (100)
        Leafsize of the kdtree

    Returns
    -------
    tree : scipy kdtree
    """
    if nside is None:
        nside = set_default_nside()

    hpid = np.arange(hp.nside2npix(nside))
    ra, dec = _hpid2RaDec(nside, hpid)
    return _buildTree(ra, dec, leafsize, scale=scale)
def hp2screen(inmap, mjd, height=500, alt_limit=10., npts=600, grid_x=None, grid_y=None):
    """
    Convert a healpy map to a flat screen at height h
    """
    nside = hp.npix2nside(inmap.size)
    unmasked = np.where(inmap != hp.UNSEEN)[0]
    ra, dec = _hpid2RaDec(nside, unmasked)
    alt, az = stupidFast_RaDec2AltAz(ra, dec, lat, lon, mjd)
    good = np.where(np.degrees(alt) > alt_limit)
    r = height/np.tan(alt[good])
    x = r*np.cos(az[good])
    y = r*np.sin(az[good])
    z = inmap[unmasked][good]

    if grid_x is None:
        grid_x, grid_y = np.mgrid[x.min():x.max():600j, y.min():y.max():600j]
    screen_grid = interpolate.griddata(np.vstack((x, y)).T, z, (grid_x, grid_y), method='nearest')

    # Maybe compute the alt-az of the grid_x, grid_y so that it'll be fast to convert back to ra, dec? 
    # Pretty clear this should be a class rather than a bunch of functions.

    return grid_x, grid_y, screen_grid
def bulge_footprint(nside=32, bulge_frac=1., ll_frac=1., i_heavy=False):
    sg = big_sky(nside=nside)
    wfd_north = np.radians(12.4)
    wfd_south = np.radians(-72.25)

    ra, dec = _hpid2RaDec(nside, np.arange(hp.nside2npix(nside)))
    wfd_pix = np.where(sg['r'] == 1)

    # Zero out the bulge as it is now
    bulge_pix = np.where((sg['r'] == 0.15) & (dec > wfd_south))
    for key in sg:
        sg[key][bulge_pix] = 0

    coord = SkyCoord(ra=ra * u.rad, dec=dec * u.rad)
    g_long, g_lat = coord.galactic.l.deg, coord.galactic.b.deg
    bulge_pix = np.where((g_long > -20) & (g_long < 20.) & (g_lat > -10)
                         & (g_lat < 10.))

    lo_lat_pix = np.where((np.abs(g_lat) < 10.) & (dec < wfd_north))

    # scale things as desired
    for key in sg:
        sg[key][lo_lat_pix] = ll_frac * np.max(sg[key][wfd_pix])
        sg[key][bulge_pix] = bulge_frac * np.max(sg[key][wfd_pix])

    if i_heavy:
        i_val = np.max(sg['i'][bulge_pix])
        total_val = 0
        for key in sg:
            total_val += np.max(sg[key][bulge_pix])
        not_i = total_val - i_val
        scale_down = (not_i - i_val) / (not_i)
        for key in sg:
            if key == 'i':
                sg[key][bulge_pix] = 2. * sg[key][bulge_pix]
            else:
                sg[key][bulge_pix] = scale_down * sg[key][bulge_pix]

    return sg
示例#29
0
    def __init__(self, nside=default_nside, radius=1.75, radius_search=1.75):
        """

        """
        self.nside = nside
        # XXX -- should I shrink the radius slightly to get rid of overlap? That would be clever!
        self.p2hp_search = pointings2hp(nside=nside, radius=radius_search)
        self.p2hp = pointings2hp(nside=nside, radius=radius)
        # Load up a list of pointings, chop them down to a small block

        # XXX--Should write code to generate a new tellelation so we know where it came from,
        # not just a random .dat file that's been floating around!
        fields = read_fields()
        good = np.where((fields['RA'] > np.radians(360. - 15.))
                        | (fields['RA'] < np.radians(15.)))
        fields = fields[good]
        good = np.where(np.abs(fields['dec']) < np.radians(15.))
        fields = fields[good]
        self.ra = fields['RA']
        self.dec = fields['dec']

        # Healpixel ra and dec
        self.hp_ra, self.hp_dec = _hpid2RaDec(nside,
                                              np.arange(hp.nside2npix(nside)))
示例#30
0
def generate_taget_maps(nside=128):
    """
    Generate a suite of target depths for each filter.
    """
    npix = hp.nside2npix(nside)
    ra, dec = utils._hpid2RaDec(nside, np.arange(npix))
    coord = SkyCoord(ra=ra*u.rad, dec=dec*u.rad)
    g_long, g_lat = coord.galactic.l.radian, coord.galactic.b.radian
    eclip_long, eclip_lat = coord.barycentrictrueecliptic.lon.radian, coord.barycentrictrueecliptic.lat.radian

    # Set borders of different regions
    main_dec = 0

    south_dec = np.radians(-60.)

    nes_dec = 0.
    nes_eclip = np.radians(15.)

    gal_lat = np.radians(10.)
    gal_long_end1 = np.radians(70.)
    gal_long_end2 = np.radians(270.)

    wfd_region = np.where((dec <= main_dec) &
                          ((np.abs(g_lat) >= gal_lat) | (g_long > gal_long_end1)) &
                          (dec >= south_dec))
    south_pole_region = np.where(dec < south_dec)
    nes_region = np.where((dec > nes_dec) & (eclip_lat < nes_eclip))

    # Need to add in the galactic plane taper.
    galatic_plane_region = np.where((np.abs(g_lat) < gal_lat) &
                                    ((g_long < gal_long_end1) | (g_long > gal_long_end2)))

    wfd_depth = {'u': 26.1, 'g': 27.4, 'r': 27.5, 'i': 26.8, 'z': 26.1, 'y': 24.9}
    nes_depth = {'g': 26.9, 'r': 27.0, 'i': 26.3, 'z': 23.6}
    south_pole_depth = {'u': 25.6, 'g': 26.9, 'r': 27.0, 'i': 26.3, 'z': 23.6, 'y': 24.4}
    galactic_plane_depth = {'u': 25.6, 'g': 26.9, 'r': 27.0, 'i': 26.3, 'z': 23.6, 'y': 24.4}

    all_filters = []
    all_filters.extend(wfd_depth.keys())
    all_filters.extend(nes_depth.keys())
    all_filters.extend(south_pole_depth.keys())
    all_filters.extend(galactic_plane_depth.keys())
    all_filters = list(set(all_filters))

    all_depth = {}
    for filtername in all_filters:
        all_depth[filtername] = np.empty(npix, dtype=float)
        all_depth[filtername].fill(hp.UNSEEN)

    # Should probably throw an error if any of the regions overlap.

    for filtername in wfd_depth:
        all_depth[filtername][wfd_region] = wfd_depth[filtername]

    for filtername in south_pole_depth:
        all_depth[filtername][south_pole_region] = south_pole_depth[filtername]

    for filtername in nes_depth:
        all_depth[filtername][nes_region] = nes_depth[filtername]

    for filtername in galactic_plane_depth:
        all_depth[filtername][galatic_plane_region] = galactic_plane_depth[filtername]

    return all_depth
def gen_cloud_maps():
    sm = sb.SkyModel(mags=True)
    hpindx = np.arange(hp.nside2npix(32))
    ra, dec = utils._hpid2RaDec(32, hpindx)

    do_query = False
    dbAddress = 'sqlite:///meddata.sqlite'
    engine = sqla.create_engine(dbAddress)
    connection = engine.raw_connection()
    cursor = connection.cursor()

    # Check all the mjd values in the db
    if do_query:
        query = 'select distinct(mjd) from medskybrightness;'
        cursor.execute(query)
        data = cursor.fetchall()
        mjd_clean = [ack[0] for ack in data]
        mjd_clean = np.array(mjd_clean)

    # Let's go 57200 as a start
    mjd_start = 57200
    mjd_length = 40.

    query = 'select distinct(mjd) from medskybrightness where mjd > %f and mjd < %f;' % (mjd_start,
                                                                                         mjd_start+mjd_length)

    cursor.execute(query)
    data = cursor.fetchall()
    mjd_clean = np.array([ack[0] for ack in data])

    cloud_maps = []
    mjd_final = []

    moon_limit = np.radians(30.)
    am_limit = 2.5

    maxI = mjd_clean[1:].size
    for i, mjd in enumerate(mjd_clean[1:]):
        if (mjd_clean[i]-mjd_clean[i-1]) < (2./60./24.):
            sf = single_frame(mjd_clean[i-1])
            sf2 = single_frame(mjd_clean[i])
            if (sf.max() != hp.UNSEEN) & (sf2.max() != hp.UNSEEN):
                diff = (sf-sf2)/sf
                mask = np.where((sf == hp.UNSEEN) | (sf2 == hp.UNSEEN))
                diff[mask] = hp.UNSEEN
                if diff.max() != hp.UNSEEN:
                    cf, cloud_mask = cloudyness(diff, skyRMS_max=0.05)
                    sm.setRaDecMjd(ra, dec, mjd)
                    skymap = sm.returnMags()['r']
                    mask = np.where((skymap == hp.UNSEEN) | np.isnan(skymap))[0]
                    cloud_mask[mask] = 2
                    moon_dist = utils.haversine(ra, dec, sm.moonRA, sm.moonDec)
                    mask = np.where((moon_dist < moon_limit) | (sm.airmass < 1.) | (sm.airmass > am_limit))
                    cloud_mask[mask] = 2
                    cloud_maps.append(cloud_mask)
                    # put in some masking near the moon
                    mjd_final.append(mjd)

                    progress = i/float(maxI)*100
                    text = "\r progress = %.1f%%" % progress
                    sys.stdout.write(text)
                    sys.stdout.flush()

    cloud_maps = np.array(cloud_maps)
    map_key = {'good': 0, 'masked': 2, 'bright_in_current': -1, 'bright_in_last': 1}
    np.savez('month_o_clouds.npz', cloud_maps=cloud_maps, mjds=mjd_final, map_key=map_key)
示例#32
0
    def __init__(self,
                 basis_functions,
                 basis_weights,
                 extra_features=None,
                 extra_basis_functions=None,
                 filtername='r',
                 filter2='g',
                 slew_approx=7.5,
                 filter_change_approx=140.,
                 read_approx=2.,
                 nexp=2,
                 min_exptime=15.,
                 max_exptime=60.,
                 ideal_pair_time=22.,
                 min_pair_time=15.,
                 search_radius=30.,
                 alt_max=85.,
                 az_range=90.,
                 smoothing_kernel=None,
                 nside=default_nside,
                 dither=True,
                 seed=42,
                 ignore_obs='ack',
                 tag_fields=False,
                 tag_map=None,
                 tag_names=None,
                 sun_alt_limit=-19.,
                 survey_note='blob',
                 sitename='LSST'):
        """
        Parameters
        ----------
        min_exp_time : float (15.)
            The minimum exposure time to use (seconds). This is the exposure time when
            conditions are dark time on the meridian (or better).
        max_exp_time : float (60.)
            The maximum exposure time to use (seconds)
        filtername : str ('r')
            The filter to observe in.
        filter2 : str ('g')
            The filter to pair with the first observation. If set to None, no pair
            will be observed.
        slew_approx : float (7.5)
            The approximate slewtime between neerby fields (seconds). Used to calculate
            how many observations can be taken in the desired time block.
        filter_change_approx : float (140.)
             The approximate time it takes to change filters (seconds).
        ideal_pair_time : float (22.)
            The ideal time gap wanted between observations to the same pointing (minutes)
        min_pair_time : float (15.)
            The minimum acceptable pair time (minutes)
        search_radius : float (30.)
            The radius around the reward peak to look for additional potential pointings (degrees)
        alt_max : float (85.)
            The maximum altitude to include (degrees).
        az_range : float (90.)
            The range of azimuths to consider around the peak reward value (degrees).
        sitename : str ('LSST')
            The name of the site to lookup latitude and longitude.
        """

        if nside is None:
            nside = set_default_nside()

        if extra_features is None:
            extra_features = {}
            extra_features['night'] = features.Current_night()
            extra_features['mounted_filters'] = features.Mounted_filters()
            extra_features['mjd'] = features.Current_mjd()
            extra_features[
                'night_boundaries'] = features.CurrentNightBoundaries()
            extra_features['sun_moon_alt'] = features.Sun_moon_alts()
            extra_features['lmst'] = features.Current_lmst(
            )  # Pretty sure in hours
            extra_features['current_filter'] = features.Current_filter()
            extra_features['altaz'] = features.AltAzFeature()
        if extra_basis_functions is None:
            extra_basis_functions = {}
            extra_basis_functions['filter1_m5diff'] = M5_diff_basis_function(
                filtername=filtername, nside=nside)
            if filter2 is not None:
                extra_basis_functions[
                    'filter2_m5diff'] = M5_diff_basis_function(
                        filtername=filter2, nside=nside)

        super(Vary_expt_survey,
              self).__init__(basis_functions=basis_functions,
                             basis_weights=basis_weights,
                             extra_features=extra_features,
                             extra_basis_functions=extra_basis_functions,
                             filtername=filtername,
                             block_size=0,
                             smoothing_kernel=smoothing_kernel,
                             dither=dither,
                             seed=seed,
                             ignore_obs=ignore_obs,
                             tag_fields=tag_fields,
                             tag_map=tag_map,
                             tag_names=tag_names,
                             nside=nside)
        self.nexp = nexp
        self.min_exptime = min_exptime
        self.max_exptime = max_exptime
        self.slew_approx = slew_approx
        self.read_approx = read_approx
        self.hpids = np.arange(hp.nside2npix(self.nside))
        # If we are taking pairs in same filter, no need to add filter change time.
        if filtername == filter2:
            filter_change_approx = 0
        # Compute the minimum time needed to observe a blob (or observe, then repeat.)
        if filter2 is not None:
            self.time_needed = (min_pair_time * 60. * 2. + read_approx +
                                filter_change_approx) / 24. / 3600.  # Days
        else:
            self.time_needed = (min_pair_time * 60. +
                                read_approx) / 24. / 3600.  # Days
        self.filter_set = set(filtername)
        if filter2 is None:
            self.filter2_set = self.filter_set
        else:
            self.filter2_set = set(filter2)
        self.sun_alt_limit = np.radians(sun_alt_limit)

        self.ra, self.dec = _hpid2RaDec(self.nside, self.hpids)
        # Look up latitude and longitude for alt,az conversions later
        # XXX: TODO: lat and lon should be in the Observatory feature. But that feature
        # needs documentation on what's in it!
        site = Site(name=sitename)
        self.lat = site.latitude_rad
        self.lon = site.longitude_rad
        self.survey_note = survey_note
        self.counter = 1  # start at 1, because 0 is default in empty observation
        self.filter2 = filter2
        self.search_radius = np.radians(search_radius)
        self.az_range = np.radians(az_range)
        self.alt_max = np.radians(alt_max)
        self.min_pair_time = min_pair_time
        self.ideal_pair_time = ideal_pair_time
def gen_cloud_maps():
    sm = sb.SkyModel(mags=True)
    hpindx = np.arange(hp.nside2npix(32))
    ra, dec = utils._hpid2RaDec(32, hpindx)

    do_query = False
    dbAddress = 'sqlite:///meddata.sqlite'
    engine = sqla.create_engine(dbAddress)
    connection = engine.raw_connection()
    cursor = connection.cursor()

    # Check all the mjd values in the db
    if do_query:
        query = 'select distinct(mjd) from medskybrightness;'
        cursor.execute(query)
        data = cursor.fetchall()
        mjd_clean = [ack[0] for ack in data]
        mjd_clean = np.array(mjd_clean)

    # Let's go 57200 as a start
    mjd_start = 57200
    mjd_length = 40.

    query = 'select distinct(mjd) from medskybrightness where mjd > %f and mjd < %f;' % (
        mjd_start, mjd_start + mjd_length)

    cursor.execute(query)
    data = cursor.fetchall()
    mjd_clean = np.array([ack[0] for ack in data])

    cloud_maps = []
    mjd_final = []

    moon_limit = np.radians(30.)
    am_limit = 2.5

    maxI = mjd_clean[1:].size
    for i, mjd in enumerate(mjd_clean[1:]):
        if (mjd_clean[i] - mjd_clean[i - 1]) < (2. / 60. / 24.):
            sf = single_frame(mjd_clean[i - 1])
            sf2 = single_frame(mjd_clean[i])
            if (sf.max() != hp.UNSEEN) & (sf2.max() != hp.UNSEEN):
                diff = (sf - sf2) / sf
                mask = np.where((sf == hp.UNSEEN) | (sf2 == hp.UNSEEN))
                diff[mask] = hp.UNSEEN
                if diff.max() != hp.UNSEEN:
                    cf, cloud_mask = cloudyness(diff, skyRMS_max=0.05)
                    sm.setRaDecMjd(ra, dec, mjd)
                    skymap = sm.returnMags()['r']
                    mask = np.where((skymap == hp.UNSEEN)
                                    | np.isnan(skymap))[0]
                    cloud_mask[mask] = 2
                    moon_dist = utils.haversine(ra, dec, sm.moonRA, sm.moonDec)
                    mask = np.where((moon_dist < moon_limit)
                                    | (sm.airmass < 1.)
                                    | (sm.airmass > am_limit))
                    cloud_mask[mask] = 2
                    cloud_maps.append(cloud_mask)
                    # put in some masking near the moon
                    mjd_final.append(mjd)

                    progress = i / float(maxI) * 100
                    text = "\r progress = %.1f%%" % progress
                    sys.stdout.write(text)
                    sys.stdout.flush()

    cloud_maps = np.array(cloud_maps)
    map_key = {
        'good': 0,
        'masked': 2,
        'bright_in_current': -1,
        'bright_in_last': 1
    }
    np.savez('month_o_clouds.npz',
             cloud_maps=cloud_maps,
             mjds=mjd_final,
             map_key=map_key)
示例#34
0
    def __init__(self,
                 basis_functions,
                 basis_weights,
                 filtername1='r',
                 filtername2='g',
                 slew_approx=7.5,
                 filter_change_approx=140.,
                 read_approx=2.,
                 exptime=30.,
                 nexp=2,
                 nexp_dict=None,
                 ideal_pair_time=22.,
                 min_pair_time=15.,
                 search_radius=30.,
                 alt_max=85.,
                 az_range=90.,
                 flush_time=30.,
                 smoothing_kernel=None,
                 nside=None,
                 dither=True,
                 seed=42,
                 ignore_obs=None,
                 survey_note='blob',
                 detailers=None,
                 camera='LSST',
                 twilight_scale=True,
                 in_twilight=False,
                 check_scheduled=True,
                 min_area=None,
                 grow_blob=True,
                 area_required=None):

        if nside is None:
            nside = set_default_nside()

        super(Blob_survey, self).__init__(basis_functions=basis_functions,
                                          basis_weights=basis_weights,
                                          filtername=None,
                                          block_size=0,
                                          smoothing_kernel=smoothing_kernel,
                                          dither=dither,
                                          seed=seed,
                                          ignore_obs=ignore_obs,
                                          nside=nside,
                                          detailers=detailers,
                                          camera=camera,
                                          area_required=area_required)
        self.flush_time = flush_time / 60. / 24.  # convert to days
        self.nexp = nexp
        self.nexp_dict = nexp_dict
        self.exptime = exptime
        self.slew_approx = slew_approx
        self.read_approx = read_approx
        self.hpids = np.arange(hp.nside2npix(self.nside))
        self.twilight_scale = twilight_scale
        self.in_twilight = in_twilight
        self.grow_blob = grow_blob

        if self.twilight_scale & self.in_twilight:
            warnings.warn(
                'Both twilight_scale and in_twilight are set to True. That is probably wrong.'
            )

        self.min_area = min_area
        self.check_scheduled = check_scheduled
        # If we are taking pairs in same filter, no need to add filter change time.
        if filtername1 == filtername2:
            filter_change_approx = 0
        # Compute the minimum time needed to observe a blob (or observe, then repeat.)
        if filtername2 is not None:
            self.time_needed = (min_pair_time * 60. * 2. + exptime +
                                read_approx +
                                filter_change_approx) / 24. / 3600.  # Days
        else:
            self.time_needed = (min_pair_time * 60. + exptime +
                                read_approx) / 24. / 3600.  # Days
        self.filter_set = set(filtername1)
        if filtername2 is None:
            self.filter2_set = self.filter_set
        else:
            self.filter2_set = set(filtername2)

        self.ra, self.dec = _hpid2RaDec(self.nside, self.hpids)

        self.survey_note = survey_note
        self.counter = 1  # start at 1, because 0 is default in empty observation
        self.filtername1 = filtername1
        self.filtername2 = filtername2
        self.search_radius = np.radians(search_radius)
        self.az_range = np.radians(az_range)
        self.alt_max = np.radians(alt_max)
        self.min_pair_time = min_pair_time
        self.ideal_pair_time = ideal_pair_time

        self.pixarea = hp.nside2pixarea(self.nside, degrees=True)

        # If we are only using one filter, this could be useful
        if (self.filtername2 is None) | (self.filtername1 == self.filtername2):
            self.filtername = self.filtername1
示例#35
0
    def __init__(self, nside=128, radius=1.75):
        hpindex = np.arange(hp.nside2npix(nside))
        ra, dec = _hpid2RaDec(nside, hpindex)

        self._setRad(radius=radius)
        self._buildTree(ra, dec)