def __init__(self, filtername='r', nside=None, FWHMeff_limit=100.): if nside is None: nside = utils.set_default_nside() self.filtername = filtername self.FWHMeff_limit = int_rounded(FWHMeff_limit) # Starting at limiting mag of zero should be fine. self.feature = np.zeros(hp.nside2npix(nside), dtype=float)
def __init__(self, basis_functions, reward=1e6, ignore_obs='dummy', nside=None, min_alt=30., max_alt=85.): """ min_alt : float (30.) The minimum altitude to attempt to chace a pair to (degrees). Default of 30 = airmass of 2. max_alt : float(85.) The maximum altitude to attempt to chase a pair to (degrees). """ if nside is None: nside = set_default_nside() self.extra_features = {} self.min_alt = np.radians(min_alt) self.max_alt = np.radians(max_alt) self.nside = nside self.reward_val = reward self.reward = -reward super(Scripted_survey, self).__init__(basis_functions=basis_functions, ignore_obs=ignore_obs, nside=nside)
def __init__(self, filtername='r', nside=None): if nside is None: nside = utils.set_default_nside() self.filtername = filtername self.feature = np.zeros(hp.nside2npix(nside), dtype=int) self.night = None
def __init__(self, m5_limit, nside=None, filtername='r', survey_features=None, condition_features=None, **kwargs): """ Parameters ---------- m5_limit : healpy array The faintest acceptable percentile 5-sigma depth to consider for observing. Anything below the limit will be masked. """ if nside is None: nside = utils.set_default_nside() if hp.npix2nside(np.size(m5_limit)) != nside: raise ValueError( 'm5_limit map nside does not match basis function nside') self.filtername = filtername self.m5_limit = m5_limit self.condition_features = condition_features self.survey_features = survey_features if self.condition_features is None: self.condition_features = {} self.condition_features['m5depth'] = fs.M5Depth( filtername=filtername, nside=nside) if self.survey_features is None: self.survey_features = {} self.result_map = np.zeros(hp.nside2npix(nside))
def __init__(self, percentile_limit=60., nside=None, filtername='r', survey_features=None, condition_features=None, **kwargs): """ Parameters ---------- percentile_limit : float (60.) The lowest acceptable percentile 5-sigma depth to consider for observing. Anything below the limit will be masked. """ if nside is None: nside = utils.set_default_nside() self.filtername = filtername self.percentile_limit = percentile_limit / 100. # Saved percentiles are between 0-1 self.m5p = M5percentiles() self.condition_features = condition_features self.survey_features = survey_features if self.condition_features is None: self.condition_features = {} self.condition_features['m5depth'] = fs.M5Depth( filtername=filtername) if self.survey_features is None: self.survey_features = {} self.result_map = np.zeros(hp.nside2npix(nside))
def __init__(self, nside=None, filtername='r', n_limit=3, seeing_limit=1.2, time_lag=0.45, m5_limit_map=None, survey_features=None, condition_features=None, **kwargs): """ """ if nside is None: nside = utils.set_default_nside() self.filtername = filtername self.n_limit = n_limit self.condition_features = condition_features self.survey_features = survey_features if self.survey_features is None: self.survey_features = {} self.survey_features['N_good'] = N_obs_good_conditions_feature( filtername=filtername, nside=nside, seeing_limit=seeing_limit, time_lag=time_lag, m5_limit_map=m5_limit_map, **kwargs) if self.condition_features is None: self.condition_features = {} self.result = np.zeros(hp.nside2npix(nside), dtype=float)
def __init__(self, filtername='r', binsize=10., nside=None): """ """ if nside is None: nside = utils.set_default_nside() self.filtername = filtername # Actually keep a histogram at each healpixel self.feature = np.zeros((hp.nside2npix(nside), 360. / binsize), dtype=float) self.bins = np.arange(0, 360 + binsize, binsize)
def __init__(self, filtername=None, nside=None, mask_indx=None, survey_name=None): if nside is None: nside = utils.set_default_nside() self.feature = np.zeros(hp.nside2npix(nside), dtype=float) self.filtername = filtername self.mask_indx = mask_indx self.survey_name = survey_name
def __init__(self, basis_functions, filt_to_pair='griz', dt=40., ttol=10., reward_val=101., note='scripted', ignore_obs='ack', min_alt=30., max_alt=85., lat=-30.2444, moon_distance=30., max_slew_to_pair=15., nside=None): """ Parameters ---------- filt_to_pair : str (griz) Which filters to try and get pairs of dt : float (40.) The ideal gap between pairs (minutes) ttol : float (10.) The time tolerance when gathering a pair (minutes) """ if nside is None: nside = set_default_nside() super(Pairs_survey_scripted, self).__init__(basis_functions=basis_functions, ignore_obs=ignore_obs, min_alt=min_alt, max_alt=max_alt, nside=nside) self.lat = np.radians(lat) self.note = note self.ttol = ttol / 60. / 24. self.dt = dt / 60. / 24. # To days self.max_slew_to_pair = max_slew_to_pair # in seconds self._moon_distance = np.radians(moon_distance) self.extra_features = {} self.extra_features['Pair_map'] = features.Pair_in_night( filtername=filt_to_pair) self.reward_val = reward_val self.filt_to_pair = filt_to_pair # list to hold observations self.observing_queue = [] # make ignore_obs a list if type(self.ignore_obs) is str: self.ignore_obs = [self.ignore_obs]
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 __init__(self, filtername='r', nside=default_nside, target_map=None, survey_features=None, condition_features=None, norm_factor=0.00010519, out_of_bounds_val=-10., mod_year=2, offset=0, mjd0=59580.035): """ Parameters ---------- filtername: (string 'r') The name of the filter for this target map. nside: int (default_nside) The healpix resolution. target_map : numpy array (None) A healpix map showing the ratio of observations desired for all points on the sky norm_factor : float (0.00010519) for converting target map to number of observations. Should be the area of the camera divided by the area of a healpixel divided by the sum of all your goal maps. Default value assumes LSST foV has 1.75 degree radius and the standard goal maps. out_of_bounds_val : float (-10.) Point value to give regions where there are no observations requested """ if nside is None: nside = utils.set_default_nside() self.norm_factor = norm_factor if survey_features is None: survey_features = {} # Map of the number of observations in filter survey_features['N_obs'] = N_observations_mod(filtername=filtername, mod_year=mod_year, offset=offset, mjd0=mjd0, nside=nside) # Count of all the observations survey_features['N_obs_count_all'] = N_obs_count_mod(filtername=None, mod_year=mod_year, offset=offset, mjd0=mjd0) if condition_features is None: condition_features = {} condition_features['Current_mjd'] = features.Current_mjd() super(Target_map_modulo_basis_function, self).__init__(survey_features=survey_features, condition_features=condition_features) self.nside = nside if target_map is None: self.target_map = utils.generate_goal_map(filtername=filtername) else: self.target_map = target_map self.out_of_bounds_area = np.where(self.target_map == 0)[0] self.out_of_bounds_val = out_of_bounds_val self.mjd0 = mjd0 self.mod_year = mod_year self.offset = offset
def __init__(self, filtername='r', nside=None, gap_min=25., gap_max=45.): if nside is None: nside = utils.set_default_nside() self.filtername = filtername self.feature = np.zeros(hp.nside2npix(nside), dtype=float) self.indx = np.arange(self.feature.size) self.last_observed = Last_observed(filtername=filtername) self.gap_min = gap_min / (24. * 60) # Days self.gap_max = gap_max / (24. * 60) # Days self.night = 0 # Need to keep a full record of times and healpixels observed in a night. self.mjd_log = [] self.hpid_log = []
def __init__(self, basis_functions, extra_features=None, extra_basis_functions=None, ignore_obs=None, survey_name='', nside=None, detailers=None, scheduled_obs=None): if nside is None: nside = set_default_nside() if ignore_obs is None: ignore_obs = [] if isinstance(ignore_obs, str): ignore_obs = [ignore_obs] self.nside = nside self.survey_name = survey_name self.ignore_obs = ignore_obs self.reward = None self.survey_index = None self.basis_functions = basis_functions if extra_features is None: self.extra_features = {} else: self.extra_features = extra_features if extra_basis_functions is None: self.extra_basis_functions = {} else: self.extra_basis_functions = extra_basis_functions self.reward_checked = False # Attribute to track if the reward function is up-to-date. self.reward_checked = False # If there's no detailers, add one to set rotation to near zero if detailers is None: self.detailers = [Zero_rot_detailer(nside=nside)] else: self.detailers = detailers # Scheduled observations self.scheduled_obs = scheduled_obs
def __init__(self, filtername=None, nside=None, offset=0, season_length=365.25): self.filtername = filtername if nside is None: nside = utils.set_default_nside() if offset is None: offset = np.zeros(hp.nside2npix(nside), dtype=int) self.offset = offset self.season_length = season_length self.season_map = utils.season_calc(0., offset=self.offset, season_length=season_length) self.feature = np.zeros(hp.nside2npix(nside), dtype=float)
def __init__(self, basis_functions, reward=1e6, ignore_obs='dummy', nside=None): """ """ if nside is None: nside = set_default_nside() self.extra_features = {} self.nside = nside self.reward_val = reward self.reward = -np.inf super(Scripted_survey, self).__init__(basis_functions=basis_functions, ignore_obs=ignore_obs, nside=nside)
def __init__(self, filtername='r', seeing_limit=1.2, time_lag=0.45, nside=None, m5_limit_map=None, mask_indx=None): """ Parameters ---------- filtername : str ('r') String or list that has all the filters that can count. seeing_limit : float (1.2) Only count an observation if the seeing is less than seeing_limit (arcsec). Uses the FWHMeff to compare. time_lag : float (0.45) Only count an observation if at least time_lag has elapsed (days). nside : int (32) The nside of the healpixel map to use m5_limit_map : healpix array (None) The 5-sigma limiting depth the observation must have to count as "good". mask_indx : list of ints (None) List of healpixel indices to mask and interpolate over """ if nside is None: nside = utils.set_default_nside() self.feature = np.zeros(hp.nside2npix(nside), dtype=float) self.filtername = filtername self.mask_indx = mask_indx self.time_lag = time_lag self.seeing_limit = seeing_limit if m5_limit_map is None: self.m5_limit_map = np.zeros(hp.nside2npix(nside), dtype=float) else: self.m5_limit_map = m5_limit_map self.extra_features = {} # Note, this will only count last_observed in good conditions. self.extra_features['last_observed'] = fs.Last_observed( filtername=filtername, nside=nside)
def __init__(self, season, filtername=None, nside=None, offset=0, modulo=None, max_season=None, season_length=365.25): if offset is None: offset = np.zeros(hp.nside2npix(nside), dtype=int) if nside is None: nside = utils.set_default_nside() self.feature = np.zeros(hp.nside2npix(nside), dtype=float) self.filtername = filtername self.offset = offset self.modulo = modulo self.season = season self.max_season = max_season self.season_length = season_length
def __init__(self, filtername=None, nside=default_nside, mask_indx=None, mjd0=59580.035, mod_year=2, offset=0): """ Parameters ---------- filtername : str ('r') String or list that has all the filters that can count. nside : int (32) The nside of the healpixel map to use mjd0 : float The start of the survey mod_year : int Only record observations on these years. offset : int The offset to apply when calculating mod """ if nside is None: nside = utils.set_default_nside() self.feature = np.zeros(hp.nside2npix(nside), dtype=float) self.filtername = filtername self.mjd0 = mjd0 self.offset = offset self.mod_year = mod_year
from lsst.sims.utils import _hpid2RaDec, _raDec2Hpid, Site, calcLmstLast import lsst.sims.skybrightness_pre as sb import healpy as hp import lsst.sims.featureScheduler.utils as utils import ephem from lsst.sims.speedObservatory.slew_pre import Slewtime_pre from lsst.sims.ocs.downtime import ScheduledDowntime, UnscheduledDowntime from lsst.sims.ocs.environment import SeeingModel, CloudModel from lsst.sims.ocs.configuration import Environment from lsst.sims.ocs.configuration.instrument import Filters from lsst.sims.utils import m5_flat_sed __all__ = ['Speed_observatory'] sec2days = 1. / (3600. * 24.) default_nside = utils.set_default_nside() doff = ephem.Date(0) - ephem.Date('1858/11/17') class SeeingModel_no_time(SeeingModel): """Eliminate the need to use a time_handler object """ def __init__(self, offset=0.): """ Parameters ---------- offset : float XXX-I don't even know the units on this. Days maybe? """ self.seeing_db = None self.seeing_dates = None
def __init__(self, filtername='r', nside=None, fill=np.nan): if nside is None: nside = utils.set_default_nside() self.filtername = filtername self.feature = np.zeros(hp.nside2npix(nside), dtype=float) + fill
import numpy as np import lsst.sims.featureScheduler as fs from lsst.sims.featureScheduler.utils import (sim_runner, set_default_nside, standard_goals, calc_norm_factor, generate_goal_map) import lsst.sims.featureScheduler.surveys as survey import lsst.sims.featureScheduler.basis_functions as basis_functions from lsst.sims.speedObservatory import Speed_observatory import matplotlib.pylab as plt import healpy as hp import time t0 = time.time() survey_length = 365.25 * 1.05 #365.25*10 # days nside = set_default_nside(nside=32) # Define what we want the final visit ratio map to look like years = np.round(survey_length / 365.25) # get rid of silly northern strip. target_map = standard_goals(nside=nside) norm_factor = calc_norm_factor(target_map) # set up a cloud map cloud_map = target_map['r'] * 0 + 0.7 # 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]
def __init__(self, filtername=None, n_obs=3, nside=None): self.filtername = filtername self.n_obs = n_obs if nside is None: nside = utils.set_default_nside() self.feature = np.zeros((n_obs, hp.nside2npix(nside)), dtype=float)
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=None, mjd_start=59853.5, seed=42, quickTest=True, alt_min=5., lax_dome=True, cloud_limit=0.3, sim_ToO=None, seeing_db=None, cloud_db=None, cloud_offset_year=0): """ Parameters ---------- nside : int (None) The healpix nside resolution mjd_start : float (59853.5) The MJD to start the observatory up at alt_min : float (5.) The minimum altitude to compute models at (degrees). lax_dome : bool (True) Passed to observatory model. If true, allows dome creep. cloud_limit : float (0.3) The limit to stop taking observations if the cloud model returns something equal or higher sim_ToO : sim_targetoO object (None) If one would like to inject simulated ToOs into the telemetry stream. seeing_db : filename of the seeing data database (None) If one would like to use an alternate seeing database cloud_offset_year : float, opt Offset into the cloud database by 'offset_year' years. Default 0. cloud_db : filename of the cloud data database (None) If one would like to use an alternate seeing database """ if nside is None: nside = set_default_nside() self.nside = nside self.cloud_limit = cloud_limit self.alt_min = np.radians(alt_min) self.lax_dome = lax_dome self.mjd_start = mjd_start # Conditions object to update and return on request self.conditions = Conditions(nside=self.nside) self.sim_ToO = sim_ToO # Create an astropy location self.site = Site('LSST') self.location = EarthLocation(lat=self.site.latitude, lon=self.site.longitude, height=self.site.height) # Load up all the models we need mjd_start_time = Time(self.mjd_start, format='mjd') # Downtime self.down_nights = [] self.sched_downtime_data = ScheduledDowntimeData(mjd_start_time) self.unsched_downtime_data = UnscheduledDowntimeData(mjd_start_time) sched_downtimes = self.sched_downtime_data() unsched_downtimes = self.unsched_downtime_data() down_starts = [] down_ends = [] for dt in sched_downtimes: down_starts.append(dt['start'].mjd) down_ends.append(dt['end'].mjd) for dt in unsched_downtimes: down_starts.append(dt['start'].mjd) down_ends.append(dt['end'].mjd) self.downtimes = np.array(list(zip(down_starts, down_ends)), dtype=list( zip(['start', 'end'], [float, float]))) self.downtimes.sort(order='start') # Make sure there aren't any overlapping downtimes diff = self.downtimes['start'][1:] - self.downtimes['end'][0:-1] while np.min(diff) < 0: # Should be able to do this wihtout a loop, but this works for i, dt in enumerate(self.downtimes[0:-1]): if self.downtimes['start'][i + 1] < dt['end']: new_end = np.max([dt['end'], self.downtimes['end'][i + 1]]) self.downtimes[i]['end'] = new_end self.downtimes[i + 1]['end'] = new_end good = np.where( self.downtimes['end'] - np.roll(self.downtimes['end'], 1) != 0) self.downtimes = self.downtimes[good] diff = self.downtimes['start'][1:] - self.downtimes['end'][0:-1] self.seeing_data = SeeingData(mjd_start_time, seeing_db=seeing_db) self.seeing_model = SeeingModel() self.seeing_indx_dict = {} for i, filtername in enumerate(self.seeing_model.filter_list): self.seeing_indx_dict[filtername] = i self.cloud_data = CloudData(mjd_start_time, cloud_db=cloud_db, offset_year=cloud_offset_year) sched_logger.info( f"Using {self.cloud_data.cloud_db} as cloud database with start year {self.cloud_data.start_time.iso}" ) self.sky_model = sb.SkyModelPre(speedLoad=quickTest) self.observatory = ExtendedObservatoryModel() self.observatory.configure_from_module() # Make it so it respects my requested rotator angles self.observatory.params.rotator_followsky = True self.filterlist = ['u', 'g', 'r', 'i', 'z', 'y'] self.seeing_FWHMeff = {} for key in self.filterlist: self.seeing_FWHMeff[key] = np.zeros(hp.nside2npix(self.nside), dtype=float) self.almanac = Almanac(mjd_start=mjd_start) # Let's make sure we're at an openable MJD good_mjd = False to_set_mjd = mjd_start while not good_mjd: good_mjd, to_set_mjd = self.check_mjd(to_set_mjd) self.mjd = to_set_mjd self.obsID_counter = 0
def __init__(self, nside=None, site='LSST', exptime=30., mjd_start=59853.5, season_offset=None, sun_RA_start=None): """ Parameters ---------- nside : int The healpixel nside to set the resolution of attributes. site : str ('LSST') A site name used to create a sims.utils.Site object. For looking up observatory paramteres like latitude and longitude. expTime : float (30) The exposure time to assume when computing the 5-sigma limiting depth mjd_start : float (59853.5) The starting MJD of the survey. season_offset : np.array A HEALpix array that specifies the day offset when computing the season for each HEALpix. sun_RA_start : float (None) Attributes (Set on init) ----------- nside : int Healpix resolution. All maps are set to this reslution. site : lsst.sims.Site object ('LSST') Contains static site-specific data (lat, lon, altitude, etc). Defaults to 'LSST'. ra : np.array A healpix array with the RA of each healpixel center (radians). Automatically generated. dec : np.array A healpix array with the Dec of each healpixel center (radians). Automatically generated. Attributes (to be set by user/telemetry stream/scheduler) ------------------------------------------- mjd : float Modified Julian Date (days). bulk_cloud : float The fraction of sky covered by clouds. (In the future might update to transparency map) cloud_map : np.array XXX--to be done. HEALpix array with cloudy pixels set to NaN. slewtime : np.array Healpix showing the slewtime to each healpixel center (seconds) current_filter : str The name of the current filter. (expect one of u, g, r, i, z, y). mounted_filters : list of str The filters that are currently mounted and thu available (expect 5 of u, g, r, i, z, y) night : int The current night number (days). Probably starts at 1. skybrightness : dict of np.array Dictionary keyed by filtername. Values are healpix arrays with the sky brightness at each healpix center (mag/acsec^2) FWHMeff : dict of np.array Dictionary keyed by filtername. Values are the effective seeing FWHM at each healpix center (arcseconds) moonAlt : float The altitude of the Moon (radians) moonAz : float The Azimuth of the moon (radians) moonRA : float RA of the moon (radians) moonDec : float Declination of the moon (radians) moonPhase : float The Phase of the moon. (percent, 0=new moon, 100=full moon) sunAlt : float The altitude of the sun (radians). sunAz : float The Azimuth of the sun (radians). sunRA : float The RA of the sun (radians). sunDec : float The Dec of the sun (radians). telRA : float The current telescope RA pointing (radians). telDec : float The current telescope Declination (radians). telAlt : float The current telescope altitude (radians). telAz : float The current telescope azimuth (radians). cumulative_azimuth_rad : float The cummulative telescope azimuth (radians). For tracking cable wrap cloud_map : np.array A healpix map with the cloud coverage. XXX-expand, is this bool map? Transparency map? airmass : np.array A healpix map with the airmass value of each healpixel. (unitless) sunset : float The MJD of sunset that starts the current night. Note MJDs of sunset, moonset, twilight times, etc are from interpolations. This means the sun may actually be slightly above/below the horizon at the given sunset time. sun_n12_setting : float The MJD of when the sun is at -12 degees altitude and setting during the current night. From interpolation. sun_n18_setting : float The MJD when the sun is at -18 degrees altitude and setting during the current night. From interpolation. sun_n18_rising : float The MJD when the sun is at -18 degrees altitude and rising during the current night. From interpolation. sun_n12_rising : float The MJD when the sun is at -12 degrees altitude and rising during the current night. From interpolation. sunrise : float The MJD of sunrise during the current night. From interpolation moonrise : float The MJD of moonrise during the current night. From interpolation. moonset : float The MJD of moonset during the current night. From interpolation. targets_of_opportunity : list of lsst.sims.featureScheduler.targetoO object(s) targetoO objects. planet_positions : dict Dictionary of planet name and coordinate e.g., 'venus_RA', 'mars_dec' scheduled_observations : np.array A list of MJD times when there are scheduled observations. Defaults to empty array. Attributes (calculated on demand and cached) ------------------------------------------ alt : np.array Altitude of each healpixel (radians). Recaclulated if mjd is updated. Uses fast approximate equation for converting RA,Dec to alt,az. az : np.array Azimuth of each healpixel (radians). Recaclulated if mjd is updated. Uses fast approximate equation for converting RA,Dec to alt,az. pa : np.array The parallactic angle of each healpixel (radians). Recaclulated if mjd is updated. Based on the fast approximate alt,az values. lmst : float The local mean sidearal time (hours). Updates is mjd is changed. M5Depth : dict of np.array the 5-sigma limiting depth healpix maps, keyed by filtername (mags). Will be recalculated if the skybrightness, seeing, or airmass are updated. HA : np.array Healpix map of the hour angle of each healpixel (radians). Runs from 0 to 2pi. az_to_sun : np.array Healpix map of the azimuthal distance to the sun for each healpixel (radians) az_to_anitsun : np.array Healpix map of the azimuthal distance to the anit-sun for each healpixel (radians) solar_elongation : np.array Healpix map of the solar elongation (angular distance to the sun) for each healpixel (radians) Attributes (set by the scheduler) ------------------------------- queue : list of observation objects The current queue of observations core_scheduler is waiting to execute. """ if nside is None: nside = set_default_nside() self.nside = nside self.site = Site(site) self.exptime = exptime self.mjd_start = mjd_start hpids = np.arange(hp.nside2npix(nside)) self.season_offset = season_offset self.sun_RA_start = sun_RA_start # Generate an empty map so we can copy when we need a new map self.zeros_map = np.zeros(hp.nside2npix(nside), dtype=float) self.nan_map = np.zeros(hp.nside2npix(nside), dtype=float) self.nan_map.fill(np.nan) # The RA, Dec grid we are using self.ra, self.dec = _hpid2RaDec(nside, hpids) # Modified Julian Date (day) self._mjd = None # Altitude and azimuth. Dict with degrees and radians self._alt = None self._az = None self._pa = None # The cloud level. Fraction, but could upgrade to transparency map self.clouds = None self._slewtime = None self.current_filter = None self.mounted_filters = None self.night = None self._lmst = None # Should be a dict with filtername keys self._skybrightness = {} self._FWHMeff = {} self._M5Depth = None self._airmass = None # Upcomming scheduled observations self.scheduled_observations = np.array([], dtype=float) # Attribute to hold the current observing queue self.queue = None # Moon self.moonAlt = None self.moonAz = None self.moonRA = None self.moonDec = None self.moonPhase = None # Sun self.sunAlt = None self.sunAz = None self.sunRA = None self.sunDec = None # Almanac information self.sunset = None self.sun_n12_setting = None self.sun_n18_setting = None self.sun_n18_rising = None self.sun_n12_rising = None self.sunrise = None self.moonrise = None self.moonset = None self.planet_positions = None # Current telescope pointing self.telRA = None self.telDec = None self.telAlt = None self.telAz = None # Full sky cloud map self._cloud_map = None self._HA = None # XXX--document self.bulk_cloud = None self.rotTelPos = None self.targets_of_opportunity = None self._season = None self.season_modulo = None self.season_max_season = None self.season_length = 365.25 self.season_floor = True