def schedule_survey(self, start=None, end=None, chunk=60, plot=False, mode=None, write=False, dirname=None): """ Schedule the entire survey. Parameters: ----------- start : Start of survey (int or str) end : End of survey (int or str) chunk : The duration of a chunk of exposures (minutes) plot : Dynamically plot the progress after each night mode : Mode of scheduler tactician Returns: -------- scheduled_nites : An ordered dictionary of scheduled nites """ self.scheduled_nites = odict() for tstart, tend in self.windows: if start is not None and ephem.Date(tstart) < ephem.Date(start): continue if end is not None and ephem.Date(tend) > ephem.Date(end): continue #nite = nitestring(tstart) nite = get_nite(tstart) try: chunks = self.schedule_nite(tstart, chunk, clip=True, plot=False, mode=mode) except ValueError as error: ortho.plotField(self.completed_fields[-1:], self.target_fields, self.completed_fields) raise (error) self.scheduled_nites[nite] = chunks if write: self.write_nite(nite, chunks, dirname=dirname) if plot: ortho.plotField(self.completed_fields[-1:], self.target_fields, self.completed_fields) if (raw_input(' ...continue ([y]/n)').lower() == 'n'): import pdb pdb.set_trace() if plot: raw_input(' ...finish... ') return self.scheduled_nites
def select_field(self, date, mode='coverage'): """ Select field(s) using the survey tactician. Parameters: ----------- date : ephem.Date object mode : Type of tactician to use for selecting field Returns: -------- field : selected field(s) from tactician """ sel = ~np.in1d(self.target_fields['ID'], self.completed_fields['ID']) self.tactician = self.create_tactician(mode) self.tactician.set_date(date) self.tactician.set_target_fields(self.target_fields[sel]) self.tactician.set_completed_fields(self.completed_fields) field_select = self.tactician.select_fields() logging.debug(str(field_select)) # For diagnostic purposes if False and len(self.scheduled_fields) % 10 == 0: weight = self.tactician.weight ortho.plotWeight(field_select[-1], self.target_fields, self.tactician.weight) raw_input('WAIT') if len(field_select) == 0: logging.error("No field selected... we've got problems.") msg = "date=%s\n" % (datestr(date)) msg += "index_select=%s, index=%s\n" % (index_select, index) msg += "nselected=%s, selection=%s\n" % (cut.sum(), cut[index_select]) msg += "weights=%s" % weight logging.info(msg) #ortho.plotWeight(self.scheduled_fields[-1], self.target_fields, self.tactician.weight) ortho.plotField(self.scheduled_fields[-1], self.scheduled_fields, options_basemap=dict(date='2017/02/20 05:00:00')) raw_input('WAIT') import pdb pdb.set_trace() raise Exception() return field_select
def schedule_nite(self, date=None, start=None, chunk=60, clip=False, plot=False, mode=None): """ Schedule a night of observing. A `nite` is defined by the day (UTC) at noon local time before observing started. Parameters: ----------- date : The date of the nite to schedule chunk : The duration of a chunk of exposures (minutes) plot : Dynamically plot the progress after each chunk mode : Mode for scheduler tactician Returns: -------- chunks : A list of the chunks generated for the scheduled nite. """ # Create the nite nite = get_nite(date) # Convert chunk to MJD if chunk > 1: chunk = chunk * ephem.minute try: nites = [get_nite(w[0]) for w in self.windows] idx = nites.index(nite) winstart, finish = self.windows[idx] if start is None: start = winstart else: logging.warn("Over-writing nite start time") except (TypeError, ValueError): msg = "Requested nite (%s) not found in windows:\n" % nite msg += '[' + ', '.join([n for n in nites]) + ']' logging.warning(msg) start = date self.observatory.date = date self.observatory.horizon = self.observatory.twilight finish = self.observatory.next_rising(ephem.Sun(), use_center=True) self.observatory.horizon = '0' logging.info("Night start (UTC): %s" % datestr(start)) logging.info("Night finish (UTC): %s" % datestr(finish)) chunks = [] i = 0 while start < finish: i += 1 msg = "Scheduling %s -- Chunk %i" % (start, i) logging.debug(msg) end = start + chunk try: scheduled_fields = self.run(start, end, clip=clip, plot=False, mode=mode) except ValueError: # Write fields even if there is an error #chunks.append(self.scheduled_fields) break if plot: field_select = scheduled_fields[-1:] bmap = ortho.plotField(field_select, self.target_fields, self.completed_fields) if (raw_input(' ...continue ([y]/n)').lower() == 'n'): import pdb pdb.set_trace() chunks.append(scheduled_fields) fieldtime = chunks[-1]['EXPTIME'][ -1] * ephem.second + constants.OVERHEAD start = ephem.Date(chunks[-1]['DATE'][-1]) + fieldtime #start = end if plot: raw_input(' ...finish... ') return chunks
def run(self, tstart=None, tstop=None, clip=False, plot=False, mode=None): """ Schedule a chunk of exposures. This is the loop where date is incremented Parameters: ----------- tstart : Chunk start time tstop : Chunk end time (may be replace with chunk length) plot : Plot the chunk (may be removed) Returns: -------- fields : Scheduled fields """ # Reset the scheduled fields self.scheduled_fields = self.FieldType() # If no tstop, run for 90 minutes if tstart is None: tstart = ephem.now() if tstop is None: timedelta = 90 * ephem.minute tstop = tstart + timedelta # Convert strings into dates if isinstance(tstart, basestring): tstart = ephem.Date(tstart) if isinstance(tstop, basestring): tstop = ephem.Date(tstop) msg = "\nRun start: %s\n" % datestr(tstart, 4) msg += "Run end: %s\n" % datestr(tstop, 4) logging.debug(msg) msg = "Previously completed fields: %i" % len(self.completed_fields) logging.info(msg) # This is not safe since tactician is re-created in select_field self.tactician = self.create_tactician(mode=mode) msg = "Scheduling with '%s' in mode '%s'" % ( self.tactician.__class__.__name__, self.tactician.mode) logging.info(msg) self.seeing.set_date(datestr(tstart)) self.fwhm = self.seeing.get_fwhm(band='i', airmass=1.0) logging.info("Predicted i-band zenith fwhm: %.2f arcsec" % self.fwhm) logging.debug(self.seeing.raw) date = tstart latch = True while latch: logging.debug(' ' + datestr(date, 4)) # Check to see if in valid observation window if self.windows is not None: inside = False for window in self.windows: if date >= window[0] and date < window[-1]: inside = True break if not inside: if clip: break else: msg = 'Date outside of nominal observing windows' logging.warning(msg) # Select one (or more) fields from the tactician try: field_select = self.select_field(date, mode) except Exception as e: # Only write if error occurred outside observing window if not inside: logging.warning(str(e)) break else: raise (e) # Now update the time from the last selected field (note duplication in tactician.select_field) fieldtime = field_select[-1][ 'EXPTIME'] * ephem.second + constants.OVERHEAD date = ephem.Date(field_select[-1]['DATE']) + fieldtime self.completed_fields = self.completed_fields + field_select self.scheduled_fields = self.scheduled_fields + field_select msg = " %(DATE).19s: id=%(ID)10s, secz=%(AIRMASS).2f, slew=%(SLEW).2f" msg += ", moon=%(PHASE).0f%%,%(ALT).0fdeg" for i, f in zip(field_select.unique_id, field_select): params = dict([('ID', i)] + [(k, f[k]) for k in f.dtype.names]) params.update({ 'PHASE': self.tactician.moon.phase, "ALT": np.degrees(self.tactician.moon.alt) }) logging.info(msg % params) #if plot: self.plotField(date, field_select) if plot: ortho.plotField(field_select[:-1], self.target_fields, self.completed_fields) if date >= tstop: break msg = "Newly scheduled fields: %i" % len(self.scheduled_fields) logging.info(msg) return self.scheduled_fields
def run(self, tstart=None, tstop=None, clip=False, plot=False, mode='coverage'): """ Schedule a chunk of exposures. This is the loop where date is incremented Parameters: ----------- tstart : Chunk start time tstop : Chunk end time (may be replace with chunk length) plot : Plot the chunk (may be removed) Returns: -------- fields : Scheduled fields """ # Reset the scheduled fields self.scheduled_fields = self.FieldType() # If no tstop, run for 90 minutes timedelta = 90 * ephem.minute if tstart is None: tstart = ephem.now() if tstop is None: tstop = tstart + timedelta # Convert strings into dates if isinstance(tstart, basestring): tstart = ephem.Date(tstart) if isinstance(tstop, basestring): tstop = ephem.Date(tstop) msg = "Run start: %s\n" % datestr(tstart, 4) msg += "Run end: %s\n" % datestr(tstop, 4) msg += "Run time: %s minutes" % (timedelta / ephem.minute) logging.debug(msg) msg = "Previously completed fields: %i" % len(self.completed_fields) logging.info(msg) msg = "Scheduling with tactician: %s" % mode logging.info(msg) date = tstart latch = True while latch: logging.debug(' ' + datestr(date, 4)) # Check to see if in valid observation window if self.windows is not None: inside = False for window in self.windows: if date >= window[0] and date < window[-1]: inside = True break if not inside: if clip: break else: msg = 'Date outside of nominal observing windows' logging.warning(msg) # Select one (or more) fields from the tactician field_select = self.select_field(date, mode) # Now update the time from the selected field date = ephem.Date(field_select[-1]['DATE']) + constants.FIELDTIME self.completed_fields = self.completed_fields + field_select self.scheduled_fields = self.scheduled_fields + field_select msg = " %(DATE).19s: id=%(ID)10s, secz=%(AIRMASS).2f, slew=%(SLEW).2f" msg += ", moon=%(PHASE).0f%%,%(ALT).0fdeg" for i, f in zip(field_select.unique_id, field_select): params = dict([('ID', i)] + [(k, f[k]) for k in f.dtype.names]) params.update({ 'PHASE': self.tactician.moon.phase, "ALT": np.degrees(self.tactician.moon.alt) }) logging.info(msg % params) #if plot: self.plotField(date, field_select) if plot: ortho.plotField(field_select[:-1], self.target_fields, self.completed_fields) if date >= tstop: break msg = "Newly scheduled fields: %i" % len(self.scheduled_fields) logging.info(msg) return self.scheduled_fields