def set_fake_mjd(target_mjd): import obsbot # How many ways do we get the time? global ephem_offset ephem_offset = 0. nownow = ephem.now() ephem_offset = obsbot.mjd_to_ephem_date(target_mjd) - nownow obsbot.mjdnow_offset = 0 nownow = obsbot.mjdnow() obsbot.mjdnow_offset = target_mjd - nownow
def test_recent(self): from obsbot import mjdnow from copilot import (get_recent_ccds, get_recent_exposures, recent_gr_seeing) import obsbot # Fake the current time... target_mjd = 57603.1 set_fake_mjd(target_mjd) now = mjdnow() self.assertLess(np.abs(now - target_mjd), 0.001) ccds = get_recent_ccds(recent = 0.1 * 24 * 60) self.assertEqual(len(ccds), 73) ccds = get_recent_ccds(recent = 30.) self.assertEqual(len(ccds), 15) exps = get_recent_exposures(recent = 30.) self.assertEqual(len(exps), 15) exps = get_recent_exposures(recent = 30., bands=['g','r']) self.assertEqual(len(exps), 15) gexps = get_recent_exposures(recent = 30., bands=['g']) self.assertEqual(len(gexps), 6) rexps = get_recent_exposures(recent = 30., bands=['r']) self.assertEqual(len(rexps), 9) xexps = get_recent_exposures(recent = 30., bands=[]) self.assertEqual(xexps, None) gsee, rsee, G, R = recent_gr_seeing() print('gsee', gsee) print('rsee', rsee) print('G', G) print('R', R) self.assertLess(np.abs(gsee - 1.360), 0.001) self.assertLess(np.abs(rsee - 1.374), 0.001) self.assertEqual(len(G), 5) self.assertEqual(len(R), 5)
def __init__(self, J1, J2, J3, opt, nom, obs, tiles): super(Mosbot, self).__init__(opt.rawdata, backlog=False, only_process_newest=True) # How many exposures ahead should we write? self.Nahead = 10 self.timeout = None self.J1 = J1 self.J2 = J2 self.J3 = J3 self.opt = opt self.nom = nom self.obs = obs self.tiles = tiles self.scriptdir = os.path.dirname(opt.scriptfn) # Create scriptdir (one path component only), if necessary if len(self.scriptdir) and not os.path.exists(self.scriptdir): os.mkdir(self.scriptdir) self.seqnumfn = 'seqnum.txt' self.seqnumpath = os.path.join(self.scriptdir, self.seqnumfn) self.expscriptpattern = 'expose-%i.sh' self.slewscriptpattern = 'slewread-%i.sh' self.planned_tiles = OrderedDict() if opt.write_script: # Default to Pass 2! J = [J1,J2,J3][opt.passnum - 1] self.write_initial_script(J, opt.passnum, opt.exptime, opt.scriptfn, self.seqnumfn) self.n_exposures = len(J) else: self.n_exposures = 0 self.bot_runtime = mjdnow() self.latest_meas = None self.last_forced = None self.sequence_offset = 0
def test_longtime(self): from copilot import main, Copilot from astrometry.util.fits import fits_table from astrometry.util.starutil_numpy import mjdtodate from obsdb.models import MeasuredCCD from obsbot import mjdnow import tempfile dirname = tempfile.mkdtemp() os.environ['MOS3_DATA'] = dirname args = self.mos_args + ['--n-fwhm', '10'] args += ['--plot-filename', 'longtime.png'] copilot = main(cmdlineargs=args, get_copilot=True) #copilot.exp T = fits_table(os.path.join(self.testdatadir, 'mosaic-db.fits')) # Move all the exposures' times so that the latest one is now-longtime mjdoffset = (mjdnow() - (copilot.longtime + 5.) / 86400.) - max(T.mjd_obs) T.mjd_obs += mjdoffset for t in T: m, created = MeasuredCCD.objects.get_or_create( filename=t.filename, extension=t.extension) for c in T.get_columns(): setattr(m, c, t.get(c)) m.object = m.object.strip() m.obstype = m.obstype.strip() m.save() copilot.lastNewFile = mjdtodate(max(T.mjd_obs)) copilot.plot_recent() # Change the mjd_obs times so that it's *not* longtime. copilot.opt.plot_filename = 'longtime2.png' copilot.lastNewFile += datetime.timedelta(0, 10.) copilot.plot_recent() print('Longtime:', copilot.longtime)
def main(cmdlineargs=None, get_copilot=False): global gSFD import optparse parser = optparse.OptionParser(usage='%prog') # Mosaic or Decam? from camera import (nominal_cal, ephem_observer, default_extension, tile_path) nom = nominal_cal obs = ephem_observer() plotfn_default = 'recent.png' parser.add_option('--ext', default=default_extension, help='Extension to read for computing observing conditions: default %default') parser.add_option('--extnum', type=int, help='Integer extension to read') parser.add_option('--rawdata', help='Directory to monitor for new images: default $MOS3_DATA if set, else "rawdata"', default=None) parser.add_option('--n-fwhm', default=None, type=int, help='Number of stars on which to measure FWHM') parser.add_option('--no-db', dest='db', default=True, action='store_false', help='Do not append results to database') parser.add_option('--no-focus', dest='focus', default=True, action='store_false', help='Do not analyze focus frames') parser.add_option('--fits', help='Write database to given FITS table') parser.add_option('--plot', action='store_true', help='Plot recent data and quit') parser.add_option('--plot-filename', default=None, help='Save plot to given file, default %s' % plotfn_default) parser.add_option('--nightplot', '--night', action='store_true', help="Plot tonight's data and quit") parser.add_option('--qa-plots', dest='doplots', default=False, action='store_true', help='Create QA plots') parser.add_option('--keep-plots', action='store_true', help='Do not remove PNG-format plots (normally merged into PDF)') parser.add_option('--mjdstart', type=float, default=None, help='MJD (UTC) at which to start plot') now = mjdnow() parser.add_option('--mjdend', type=float, default=None, help='MJD (UTC) at which to end plot (default: now, which is %.3f)' % now) parser.add_option('--skip', action='store_true', help='Skip images that already exist in the database') parser.add_option('--threads', type=int, default=None, help='Run multi-threaded when processing list of files on command-line') parser.add_option('--fix-db', action='store_true') parser.add_option('--tiles', default=tile_path, help='Tiles table, default %default') parser.add_option('--no-show', dest='show', default=True, action='store_false', help='Do not show plot window, just save it.') if cmdlineargs is None: opt,args = parser.parse_args() else: opt,args = parser.parse_args(cmdlineargs) if not opt.show: import matplotlib matplotlib.use('Agg') imagedir = opt.rawdata if imagedir is None: imagedir = os.environ.get('MOS3_DATA', 'rawdata') rawext = opt.ext if opt.extnum is not None: rawext = opt.extnum assert(rawext is not None) from astrometry.util.fits import fits_table tiles = fits_table(opt.tiles) from django.conf import settings import obsdb import pylab as plt plt.figure(figsize=(8,10)) markmjds = [] if opt.nightplot: opt.plot = True if opt.plot_filename is None: opt.plot_filename = 'night.png' # Are we at Tololo or Kitt Peak? Look for latest image. o = obsdb.MeasuredCCD.objects.all().order_by('-mjd_obs') cam = o[0].camera print('Camera:', cam) if opt.mjdstart is not None: sdate = ephem.Date(mjdtodate(opt.mjdend)) else: sdate = ephem.Date(datenow()) (sunset, eve12, eve18, morn18, morn12, sunrise) = get_twilight( cam, sdate) if opt.mjdstart is None: opt.mjdstart = ephemdate_to_mjd(sunset) print('Set mjd start to sunset:', sunset, opt.mjdstart) if opt.mjdend is None: opt.mjdend = ephemdate_to_mjd(sunrise) print('Set mjd end to sunrise', sunrise, opt.mjdend) markmjds.append((ephemdate_to_mjd(eve18),'b')) print('Evening twi18:', eve18, markmjds[-1]) markmjds.append((ephemdate_to_mjd(morn18),'b')) print('Morning twi18:', morn18, markmjds[-1]) markmjds.append((ephemdate_to_mjd(eve12),'g')) print('Evening twi12:', eve12, markmjds[-1]) markmjds.append((ephemdate_to_mjd(morn12),'g')) print('Morning twi12:', morn12, markmjds[-1]) if opt.plot_filename is None: opt.plot_filename = plotfn_default if opt.fits: ccds = obsdb.MeasuredCCD.objects.all() print(ccds.count(), 'measured CCDs') T = db_to_fits(ccds) T.writeto(opt.fits) print('Wrote', opt.fits) return 0 if opt.fix_db: from astrometry.util.fits import fits_table tiles = fits_table('obstatus/mosaic-tiles_obstatus.fits') now = mjdnow() #ccds = obsdb.MeasuredCCD.objects.all() #ccds = obsdb.MeasuredCCD.objects.all().filter(mjd_obs__gt=now - 0.25) ccds = obsdb.MeasuredCCD.objects.all().filter(mjd_obs__gt=57434) print(ccds.count(), 'measured CCDs') for ccd in ccds: try: hdr = fitsio.read_header(ccd.filename, ext=0) # band = hdr['FILTER'] # band = band.split()[0] # ccd.band = band set_tile_fields(ccd, hdr, tiles) ccd.save() print('Fixed', ccd.filename) except: import traceback traceback.print_exc() return 0 if opt.plot: plot_recent(opt, nom, tiles=tiles, markmjds=markmjds, show_plot=False) return 0 print('Loading SFD maps...') sfd = SFDMap() if len(args) > 0: mp = None if opt.threads > 1: gSFD = sfd from astrometry.util.multiproc import multiproc mp = multiproc(opt.threads) if opt.skip: fns = skip_existing_files(args, rawext) else: fns = args if mp is None: for fn in fns: process_image(fn, rawext, nom, sfd, opt, obs, tiles) else: sfd = None mp.map(bounce_process_image, [(fn, rawext, nom, sfd, opt, obs, tiles) for fn in fns]) plot_recent(opt, nom, tiles=tiles, markmjds=markmjds, show_plot=False) return 0 copilot = Copilot(imagedir, rawext, opt, nom, sfd, obs, tiles) # for testability if get_copilot: return copilot copilot.run() return 0
def plot_recent(opt, nom, tiles=None, markmjds=[], **kwargs): import obsdb if opt.mjdend is None: # Now mjd_end = mjdnow() else: mjd_end = opt.mjdend if opt.mjdstart is None: # an hour ago mjd_start = mjd_end - 3600. / (24*3600.) else: mjd_start = opt.mjdstart # mjd_start <= mjd_obs <= mjd_end mm = obsdb.MeasuredCCD.objects.filter(mjd_obs__gte=mjd_start, mjd_obs__lte=mjd_end) if not len(mm): print('No measurements in MJD range', mjd_start, mjd_end) return camera = mm[0].camera allobs = obsdb.MeasuredCCD.objects.filter(camera=camera) plotfn = opt.plot_filename (sunset, eve12, eve18, morn18, morn12, sunrise) = get_twilight( camera, ephem.Date(mjdtodate(mjd_end))) markmjds.append((ephemdate_to_mjd(eve18),'b')) #print('Evening twi18:', eve18, markmjds[-1]) markmjds.append((ephemdate_to_mjd(morn18),'b')) #print('Morning twi18:', morn18, markmjds[-1]) markmjds.append((ephemdate_to_mjd(eve12),'g')) #print('Evening twi12:', eve12, markmjds[-1]) markmjds.append((ephemdate_to_mjd(morn12),'g')) #print('Morning twi12:', morn12, markmjds[-1]) plot_measurements(mm, plotfn, nom, allobs=allobs, mjdrange=(mjd_start, mjd_end), markmjds=markmjds, **kwargs) planfn = 'mosbot-plan.fits' if not os.path.exists(planfn) or tiles is None: return import pylab as plt from astrometry.util.fits import fits_table P = fits_table(planfn) mlast = mm.order_by('mjd_obs').last() mrecent = mm.order_by('-mjd_obs')[:10] plt.clf() I = (tiles.in_desi == 1) * (tiles.z_done == 0) plt.plot(tiles.ra[I], tiles.dec[I], 'k.', alpha=0.05) I = (tiles.in_desi == 1) * (tiles.z_done > 0) plt.plot(tiles.ra[I], tiles.dec[I], 'k.', alpha=0.5) plt.plot([m.rabore for m in mm], [m.decbore for m in mm], 'm.') I = np.flatnonzero(P.type == '1') I = I[:10] plt.plot(P[I].ra, P[I].dec, 'k^', alpha=0.3) I = np.flatnonzero(P.type == '2') I = I[:10] plt.plot(P[I].ra, P[I].dec, 'ks', alpha=0.3) I = np.flatnonzero(P.type == '3') I = I[:10] plt.plot(P[I].ra, P[I].dec, 'kp', alpha=0.3) plt.plot(mlast.rabore, mlast.decbore, 'mo') I = np.flatnonzero(P.type == 'P') plt.plot(P[I].ra, P[I].dec, 'm*-', ms=12) plt.xlabel('RA (deg)') plt.ylabel('Dec (deg)') #plt.axis([360,0,-20,90]) ralo = min(P.ra.min(), min([m.rabore for m in mrecent])) rahi = max(P.ra.max(), max([m.rabore for m in mrecent])) declo = min(P.dec.min(), min([m.decbore for m in mrecent])) dechi = max(P.dec.max(), max([m.decbore for m in mrecent])) dr = rahi - ralo dd = dechi - declo plt.axis([ralo-0.1*dr, rahi+0.1*dr, declo-0.1*dd, dechi+0.1*dd]) fn = 'radec.png' plt.savefig(fn) print('Wrote', fn)