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)
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 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
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)
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)
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.
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
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
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
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
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)
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
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
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
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
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
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)))
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)
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)
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
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)