def standard_goals(nside=None): """ A quick function to generate the "standard" goal maps. """ # Find the number of healpixels we expect to observe per observation if nside is None: nside = fs.set_default_nside() result = {} result['u'] = fs.generate_goal_map(nside=nside, NES_fraction=0., WFD_fraction=0.31, SCP_fraction=0.15, GP_fraction=0.15, WFD_upper_edge_fraction=0.) result['g'] = fs.generate_goal_map(nside=nside, NES_fraction=0.2, WFD_fraction=0.44, SCP_fraction=0.15, GP_fraction=0.15, WFD_upper_edge_fraction=0.) result['r'] = fs.generate_goal_map(nside=nside, NES_fraction=0.46, WFD_fraction=1.0, SCP_fraction=0.15, GP_fraction=0.15, WFD_upper_edge_fraction=0.) result['i'] = fs.generate_goal_map(nside=nside, NES_fraction=0.46, WFD_fraction=1.0, SCP_fraction=0.15, GP_fraction=0.15, WFD_upper_edge_fraction=0.) result['z'] = fs.generate_goal_map(nside=nside, NES_fraction=0.4, WFD_fraction=0.9, SCP_fraction=0.15, GP_fraction=0.15, WFD_upper_edge_fraction=0.) result['y'] = fs.generate_goal_map(nside=nside, NES_fraction=0., WFD_fraction=0.9, SCP_fraction=0.15, GP_fraction=0.15, WFD_upper_edge_fraction=0.) return result
def __init__(self, mjd_target, mjd_tol, extra_features=None, smoothing_kernel=None, reward=1e6, ignore_obs='dummy', nside=default_nside): """ Parameters ---------- mjd_target : float The MJD that the script should be executed at (days). It is up to the user to make sure the target is visible at that time. mjd_tol : float The tolerance on the MJD (minutes). reward : float (1e6) The reward to report if the current MJD is within mjd_tol of mjd_target. """ if nside is None: nside = set_default_nside() self.mjd_target = mjd_target self.mjd_tol = mjd_tol/60./24. self.nside = nside self.reward_val = reward self.reward = -reward if extra_features is None: extra_features = {'mjd': features.Current_mjd()} extra_features['altaz'] = features.AltAzFeature(nside=nside) super(Scripted_survey, self).__init__(basis_functions=[], basis_weights=[], extra_features=extra_features, smoothing_kernel=smoothing_kernel, ignore_obs=ignore_obs, nside=nside)
def testBaseline(self): """ Set up a baseline survey and run for a few days. A crude way to touch lots of code. """ nside = fs.set_default_nside(nside=32) survey_length = 2.1 # days # Define what we want the final visit ratio map to look like target_map = fs.standard_goals(nside=nside) filters = ['u', 'g', 'r', 'i', 'z', 'y'] surveys = [] for filtername in filters: bfs = [] bfs.append(fs.M5_diff_basis_function(filtername=filtername, nside=nside)) bfs.append(fs.Target_map_basis_function(filtername=filtername, target_map=target_map[filtername], out_of_bounds_val=hp.UNSEEN, nside=nside)) bfs.append(fs.North_south_patch_basis_function(zenith_min_alt=50., nside=nside)) bfs.append(fs.Slewtime_basis_function(filtername=filtername, nside=nside)) bfs.append(fs.Strict_filter_basis_function(filtername=filtername)) weights = np.array([3.0, 0.3, 1., 3., 3.]) surveys.append(fs.Greedy_survey_fields(bfs, weights, block_size=1, filtername=filtername, dither=True, nside=nside)) surveys.append(fs.Pairs_survey_scripted([], [], ignore_obs='DD')) # Set up the DD dd_surveys = fs.generate_dd_surveys() surveys.extend(dd_surveys) scheduler = fs.Core_scheduler(surveys, nside=nside) observatory = Speed_observatory(nside=nside) observatory, scheduler, observations = fs.sim_runner(observatory, scheduler, survey_length=survey_length, filename=None) # Check that a second part of a pair was taken assert('scripted' in observations['note']) # Check that the COSMOS DD was observed assert('DD:COSMOS' in observations['note']) # And the u-band assert('DD:u,COSMOS' in observations['note']) # Make sure a few different filters were observed assert(len(np.unique(observations['filter'])) > 3) # Make sure lots of observations executed assert(observations.size > 1000)
import numpy as np import lsst.sims.featureScheduler as fs from lsst.sims.speedObservatory import Speed_observatory import matplotlib.pylab as plt import healpy as hp # Try to run rolling cadence # Make a rolling mask that takes out two-thirds of the WFD at a time. if __name__ == '__main__': nside = fs.set_default_nside(nside=32) survey_length = 365.25*10 # days dec_limits = np.radians([-16.852, -35.545]) # Define the mask I want to use wfd = fs.WFD_healpixels(nside=nside) ra, dec = fs.ra_dec_hp_map(nside=nside) rolling_mask1 = np.zeros(ra.size, dtype=bool) rolling_mask1[np.where((wfd == 1) & (dec > dec_limits[0]))] = True rolling_mask2 = np.zeros(ra.size, dtype=bool) rolling_mask2[np.where((dec < dec_limits[0]) & (dec > dec_limits[1]))] = True rolling_mask3 = np.zeros(ra.size, dtype=bool) rolling_mask3[np.where((dec < dec_limits[1]) & (wfd == 1))] = True
from lsst.sims.speedObservatory import Speed_observatory import lsst.sims.featureScheduler as fs import numpy as np from blob_same_zmask import generate_slair_scheduler import time t0 = time.time() survey_length = 1. years = np.round(survey_length/365.25) nside = fs.set_default_nside(nside=32) scheduler = generate_slair_scheduler() observatory = Speed_observatory(nside=nside, quickTest=False) observatory, scheduler, observations = fs.sim_runner(observatory, scheduler, survey_length=survey_length, filename='blobs_same_zmask%iyrs.db' % years, delete_past=True) trun = time.time() - t0 print('ran in %i, %i minutes=%i hours' % (trun, trun/60., trun/3600.))
def generate_slair_scheduler(): nside = fs.set_default_nside(nside=32) # get rid of silly northern strip. target_map = fs.standard_goals(nside=nside) norm_factor = fs.calc_norm_factor(target_map) # List to hold all the surveys (for easy plotting later) surveys = [] # Set up observations to be taken in blocks filter1s = ['u', 'g', 'r', 'i', 'z', 'y'] filter2s = [None, 'g', 'r', 'i', None, None] pair_surveys = [] for filtername, filtername2 in zip(filter1s, filter2s): bfs = [] bfs.append( fs.M5_diff_basis_function(filtername=filtername, nside=nside)) if filtername2 is not None: bfs.append( fs.M5_diff_basis_function(filtername=filtername2, nside=nside)) bfs.append( fs.Target_map_basis_function(filtername=filtername, target_map=target_map[filtername], out_of_bounds_val=hp.UNSEEN, nside=nside, norm_factor=norm_factor)) if filtername2 is not None: bfs.append( fs.Target_map_basis_function( filtername=filtername2, target_map=target_map[filtername2], out_of_bounds_val=hp.UNSEEN, nside=nside, norm_factor=norm_factor)) bfs.append( fs.Slewtime_basis_function(filtername=filtername, nside=nside)) bfs.append(fs.Strict_filter_basis_function(filtername=filtername)) bfs.append( fs.Zenith_shadow_mask_basis_function(nside=nside, shadow_minutes=60., max_alt=76.)) weights = np.array([3.0, 3.0, .3, .3, 3., 3., 0.]) if filtername2 is None: # Need to scale weights up so filter balancing still works properly. weights = np.array([6.0, 0.6, 3., 3., 0.]) # XXX- # This is where we could add a look-ahead basis function to include m5_diff in the future. # Actually, having a near-future m5 would also help prevent switching to u or g right at twilight? # Maybe just need a "filter future" basis function? if filtername2 is None: survey_name = 'blob, %s' % filtername else: survey_name = 'blob, %s%s' % (filtername, filtername2) surveys.append( fs.Blob_survey(bfs, weights, filtername=filtername, filter2=filtername2, survey_note=survey_name)) pair_surveys.append(surveys[-1]) # Let's set up some standard surveys as well to fill in the gaps. This is my old silly masked version. # It would be good to put in Tiago's verion and lift nearly all the masking. That way this can also # chase sucker holes. filters = ['u', 'g', 'r', 'i', 'z', 'y'] #filters = ['i', 'z', 'y'] greedy_surveys = [] for filtername in filters: bfs = [] bfs.append( fs.M5_diff_basis_function(filtername=filtername, nside=nside)) bfs.append( fs.Target_map_basis_function(filtername=filtername, target_map=target_map[filtername], out_of_bounds_val=hp.UNSEEN, nside=nside, norm_factor=norm_factor)) bfs.append( fs.North_south_patch_basis_function(zenith_min_alt=50., nside=nside)) bfs.append( fs.Slewtime_basis_function(filtername=filtername, nside=nside)) bfs.append(fs.Strict_filter_basis_function(filtername=filtername)) bfs.append( fs.Zenith_shadow_mask_basis_function(nside=nside, shadow_minutes=60., max_alt=76.)) weights = np.array([3.0, 0.3, 1., 3., 3., 0.]) # Might want to try ignoring DD observations here, so the DD area gets covered normally--DONE surveys.append( fs.Greedy_survey_fields(bfs, weights, block_size=1, filtername=filtername, dither=True, nside=nside, ignore_obs='DD')) greedy_surveys.append(surveys[-1]) # Set up the DD surveys dd_surveys = fs.generate_dd_surveys() surveys.extend(dd_surveys) survey_list_o_lists = [dd_surveys, pair_surveys, greedy_surveys] # put in as list-of-lists so pairs get evaluated first. scheduler = fs.Core_scheduler(survey_list_o_lists, nside=nside) return scheduler
import numpy as np import healpy as hp import lsst.sims.featureScheduler as fs target_maps = {} nside = fs.set_default_nside(nside=32) # Required target_maps['u'] = fs.generate_goal_map(NES_fraction=0., WFD_fraction=0.31, SCP_fraction=0.15, GP_fraction=0.15, nside=nside, generate_id_map=True) target_maps['g'] = fs.generate_goal_map(NES_fraction=0.2, WFD_fraction=0.44, SCP_fraction=0.15, GP_fraction=0.15, nside=nside, generate_id_map=True) target_maps['r'] = fs.generate_goal_map(NES_fraction=0.46, WFD_fraction=1.0, SCP_fraction=0.15, GP_fraction=0.15, nside=nside, generate_id_map=True) target_maps['i'] = fs.generate_goal_map(NES_fraction=0.46, WFD_fraction=1.0, SCP_fraction=0.15, GP_fraction=0.15, nside=nside, generate_id_map=True) target_maps['z'] = fs.generate_goal_map(NES_fraction=0.4, WFD_fraction=0.9, SCP_fraction=0.15, GP_fraction=0.15, nside=nside, generate_id_map=True) target_maps['y'] = fs.generate_goal_map(NES_fraction=0., WFD_fraction=0.9, SCP_fraction=0.15, GP_fraction=0.15, nside=nside,
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