def load_windows(self, windows=None): """ Load the set of start and stop times for the observation windows. """ if windows is None: windows = self._defaults['windows'] logging.info("Setting default observing windows:\n %s" % windows) if isinstance(windows, basestring): windows = fileio.csv2rec(windows) self.windows = [] for start, end in windows: self.windows.append([ephem.Date(start), ephem.Date(end)]) # Sanity check that observation windows are properly sorted for ii, (start, end) in enumerate(self.windows): msg = 'Observation windows are not properly sorted\n' msg += '%s: %s -- %s' % (get_nite(start), datestr(start), datestr(end)) if (end < start): logging.warn(msg) if ii > 0 and (start < self.windows[ii - 1][1]): logging.warn(msg) logging.debug('Observation Windows:') for start, end in self.windows: logging.debug(' %s: %s UTC -- %s UTC' % (get_nite(start), datestr(start), datestr(end))) logging.debug(30 * '-')
def test_datestr(): string = '2016/02/14 01:30:00.0000' dt = dateutil.parser.parse(string) eph = ephem.Date(string) for d in [dt, eph, string]: np.testing.assert_equal(datestr(d), string[:-5]) for i, j in [(0, -5), (3, -1), (2, -2), (1, -3), (0, -5)]: np.testing.assert_equal(datestring(d, i), string[slice(j)], err_msg="i=%s, j=%s" % (i, j))
def select_field(self, date, mode=None): """ 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']) # ADW: Why do we create the tactician each time? self.tactician = self.create_tactician(mode=mode) self.tactician.set_date(date) self.tactician.set_target_fields(self.target_fields[sel]) self.tactician.set_completed_fields(self.completed_fields) self.tactician.fwhm = self.fwhm 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
def plot_nightsum(fields,nitestr,date): """ Plot the bliss night summary. Parameters: ----------- fields: the fields observed tonight nitestr: the nite in strig format Returns: -------- None """ from obztak.utils.database import Database plt.ioff() # Select the fields from the database db = Database() db.connect() query = """ select id, qc_fwhm as psf, qc_teff as teff, filter from exposure where delivered = True and propid = '%s' and flavor = 'object' and qc_teff is not NULL and qc_fwhm is not NULL and to_timestamp(utc_beg) %s """ #new = db.query2recarray(query%(fields.PROPID,'>',datestr(date))) d = datestr(date) q = query%(fields.PROPID,"between (timestamp '%s') AND (timestamp '%s' + interval '12 hours')"%(d,d)) logging.debug(q) new = db.query2recarray(q) try: q = query%(fields.PROPID,"< (timestamp '%s')"%d) logging.debug(q) old = db.query2recarray(q) except ValueError as e: print(e) old = np.recarray(0,dtype=new.dtype) for b in ['u','g','r','i','z','Y']: f = new[new['filter'] == b] print ' %s-band:'%b, len(f) if not len(new): logging.warn("No new exposures...") return ########################## plot_coverage(fields,nitestr) ########################## fig,axes = plt.subplots(1,2,figsize=(12,5)) for i,d in enumerate(['2017/02/08 07:00:00','2017/02/08 19:00:00']): plt.sca(axes[i]) bmap = DECamOrtho(date=d) for b in np.unique(fields['FILTER']): f = fields[fields['FILTER']==b] bmap.draw_focal_planes(f['RA'],f['DEC'],color=COLORS[b],alpha=0.3) bmap.draw_bliss() bmap.draw_galaxy() bmap.draw_des() plt.suptitle('Coverage (%s)'%nitestr,fontsize=16) plt.savefig('nightsum_summary_%s.png'%nitestr) new_sel = (np.array(map(utc2nite,fields['DATE'])) == nitestr) new_fields = fields[new_sel] old_fields = fields[~new_sel] ########################## fig,axes = plt.subplots(1,2,figsize=(12,5)) plt.sca(axes[0]) plt.plot(np.nan,np.nan,'-w',label='all') plot_psf(new,old) plt.title('Seeing (%s)'%nitestr) plt.sca(axes[1]) plt.plot(np.nan,np.nan,'-w',label='all') plot_teff(new,old) plt.title('Effective Depth (%s)'%nitestr) plt.savefig('nightsum_psf_teff_%s.png'%nitestr,bbox_inches='tight') fig,axes = plt.subplots(2,2,figsize=(14,10)) axes = axes.flatten() for i,b in enumerate(['g','r','i','z']): plt.sca(axes[i]) plt.plot(np.nan,np.nan,'-w',label='%s-band'%b) plot_psf(new[new['filter'] == b],old[old['filter'] == b]) plt.savefig('nightsum_psf_%s.png'%nitestr,bbox_inches='tight') fig,axes = plt.subplots(2,2,figsize=(14,10)) axes = axes.flatten() for i,b in enumerate(['g','r','i','z']): plt.sca(axes[i]) plt.plot(np.nan,np.nan,'-w',label='%s-band'%b) plot_teff(new[new['filter'] == b],old[old['filter'] == b]) plt.savefig('nightsum_teff_%s.png'%nitestr,bbox_inches='tight')