Esempio n. 1
0
 def DMZero(self):
     try:
         if self.checkapf['DMTIME'].read(binary=True) < 1:
             APFLib.write(self.checkapf['DMTIME'], -1,timeout=10)
     except Exception, e:
         ostr = "Error: cannot touch DM Timer: %s " %( e)
         apflog(ostr,level='error',echo=True)
Esempio n. 2
0
def getObserved(filename):
    """ getObserved parses a file to find the object names and times
    names, times = getObserved(filename)
    names - list of names, must be first column of file called filename
    times - times either as a timestamp in second column or a (hour,minute) tuple from a scriptobs line

    """
    obs = []
    times = []
    nobs = dict()
    try:
        f = open(filename, 'r')
    except IOError:
        apflog( "Couldn't open %s" % filename,level="warn",echo=True)
        return obs, times
    else: 
        for line in f:
            line = line.strip()
            if len(line) > 0:
                if line[0] == '#' or line == "":
                    pass
                else:
                    ls = line.split()
                    obs.append(ls[0])
                    if len(ls) > 15:
                        times.append( (int(ls[14].split('=')[1]), int(ls[15].split('=')[1])) )
                    else:
                        times.append(float(ls[1]))
            
    obs.reverse()
    times.reverse()
    return obs, times
Esempio n. 3
0
 def calibrate(self, script, time):
     s_calibrate = os.path.join(ScriptDir,"calibrate")
     if self.test: 
         print "Test Mode: calibrate %s %s." % (script, time)
         APFTask.waitFor(self.task, True, timeout=10)
         return True
     if time == 'pre' or 'post':
         try:
             APFLib.write("apfmot.DEWARFOCRAW",ktl.read("apftask","FOCUSINSTR_LASTFOCUS",binary=True))
         except:
             apflog("Cannot read the last best fitting focus value or write the dewar focus value", level='error')
         if self.dewarfoc > 8600 or self.dewarfoc < 8400:
             apflog("Warning: The dewar focus is currently %d. This is outside the typical range of acceptable values." % (self.dewarfoc), level = "error", echo=True)
             return False
         apflog("Running calibrate %s %s" % (script, time), level = 'info')
         owner = self.apfschedule('OWNRHINT').read()        
         self.apfschedule('OWNRHINT').write('public')        
         
         cmd = '%s %s %s' % (s_calibrate,script, time)
         result, code = cmdexec(cmd,debug=True,cwd=os.getcwd())
         if not result:
             apflog("%s %s failed with return code %d" % (s_calibrate, script, code),echo=True)
         expression="($apftask.CALIBRATE_STATUS != 0) and ($apftask.CALIBRATE_STATUS != 1) "
         if not APFTask.waitFor(self.task,True,expression=expression,timeout=30):
             apflog("%s %s failed to exit" % (s_calibrate,script),echo=True)
         self.apfschedule('OWNRHINT').write(owner)        
             
         return result
     else:
         print "Couldn't understand argument %s, nothing was done." % time
Esempio n. 4
0
    def run_focustel(self):
        """Runs the telescope focus routine."""
        el = self.tel['EL'].read(binary=True)
        cfspos = self.fspos.read(binary=True)
        crspos = self.rspos.read(binary=True)

        if abs(el - cfspos) < 2.5 or abs(el - crspos) < 2.5:
            apflog("Cannot focus, telescope too close to shutter", level="warn", echo=True)
            return False
           
        if self.test: 
            APFTask.waitFor(self.task, True, timeout=10)
            apflog("Test Mode: Would be running focus_telescope.",echo=True)
            return True
        else:
            apflog("Running focus_telescope routine.",echo=True)
            cmdpath = '/usr/local/lick/bin/robot/'
            cmd = os.path.join(cmdpath,'focus_telescope')
            result, code = cmdexec(cmd,cwd=os.path.curdir)
            if not result:
                apflog("focustel failed with code %d" % code, echo=True)
                expression="($apftask.FOCUSINSTR_STATUS != 0) and ($apftask.FOCUSINSTR_STATUS != 1) "
                if not APFTask.waitFor(self.task,True,expression=expression,timeout=30):
                    apflog("focus_telescope failed to exit" ,echo=True)
                return result
            return True
Esempio n. 5
0
def findColumns(col_names, req_cols, opt_cols=[]):
    """findColumns finds the indices for the column names in the list of

    required columns indices = findColumns(col_names, req_cols)

    indices - a dictionary of indices, each index maps to where in
    col_names the column is found

    col_names - list of column names to be searched
    req_cols - list of names that should be in the first list
    """
    idx = []
    didx = dict()

    for r in req_cols:
        if r in col_names:
            didx[r] = col_names.index(r)
        else:
            apflog("%s Not found in column names from google spreadsheet" %
                   (r),
                   level="Warn",
                   echo=True)

    for r in opt_cols:
        if r in col_names:
            didx[r] = col_names.index(r)

    # hack to handle an error
    if req_cols[0] == "Star Name" and req_cols[0] not in didx.keys():
        didx[req_cols[0]] = 0
        apflog("Pasting 'Star Name' into column 0 of google spreadsheet",
               level="Warn",
               echo=True)

    return didx
Esempio n. 6
0
def enoughTimeTemplates(star_table, stars, idx, apf_obs, dt):

    count = numTemplateExp(star_table['Vmag'][idx])

    tot_time = count * 1200

    tot_time += 210 + (
        2 * 40 + 40 * (star_table['nexp'][idx] - 1)
    ) + 2400  # two B star exposures + three 70 second acquisitions and the actual observation readout times
    vis, star_elevations, fin_els, scaled_els = Visible.visible(
        apf_obs, [stars[idx]], [tot_time])
    time_left_before_sunrise = computeSunrise(dt, horizon='-9')

    try:
        apflog(
            "enoughTimeTemplates(): time for obs= %.1f  time until sunrise= %.1f "
            % (tot_time, time_left_before_sunrise),
            echo=True)
    except:
        apflog("enoughTimeTemplates(): cannot log times!?!", echo=True)

    if tot_time < time_left_before_sunrise and vis and time_left_before_sunrise < 14 * 3600.:
        return True
    else:
        return False
Esempio n. 7
0
 def run_centerup(self):
     cmdpath = '/usr/local/lick/bin/robot/'
     cmd = os.path.join(cmdpath,'centerup')
     result, code = cmdexec(cmd,cwd=os.path.curdir)
     if not result:
         apflog("centerup failed with code %d" % code, echo=True)
     return result
Esempio n. 8
0
def parseStarlist(starlist):
    """ Parse a scriptobs-compatible starlist for the scheduler.

    names, star_table, lines, stars = parseStarlist(starlist)
    starlist - a filename

    names - a list of stars in the starlist
    star_table - a numpy array
    lines - a list of strings that can be used for scriptobs input
    stars - a list of pyEphem objects 
    """
    names = []
    lines = []
    stars = []
    star_table = []
    try:
        f = open(starlist, 'r')
    except IOError:
        apflog("Warning: Could not open %s. No target can be selected." %
               starlist,
               echo=True)
        return None
    else:
        for line in f:
            if not re.search("\A\#", line):
                ls = line.split()
                names.append(ls[0])
                row = []
                # RA value in radians
                row.append(getRARad(ls[1], ls[2], ls[3]))
                # Dec value in radians
                row.append(getDECRad(ls[4], ls[5], ls[6]))
                # PM RA
                row.append(float(ls[8].split('=')[-1]))
                # PM Dec
                row.append(float(ls[9].split('=')[-1]))
                # V mag
                row.append(float(ls[10].split('=')[-1]))
                # Exposure time
                row.append(float(ls[11].split('=')[-1]))
                # Desired Counts
                row.append(float(ls[16].split('=')[-1]))
                # Filler not used here
                row.append(0.)
                row.append(0.)
                # Number of exposures
                row.append(int(ls[19].split('=')[-1]))

                star_table.append(row)

                # Save the scriptobs line for later
                lines.append(line)

                # Generate a pyEphem object for this target
                star = ephem.FixedBody()
                star._ra = ephem.hours(":".join([ls[1], ls[2], ls[3]]))
                star._dec = ephem.degrees(":".join([ls[4], ls[5], ls[6]]))
                stars.append(star)

    return names, np.array(star_table), lines, stars
Esempio n. 9
0
 def evening_star(self):
     """Aim the APF at the desired target. This calls prep-obs, slewlock, and focus-telescope. A workaround to relying on scriptobs."""
     if self.isOpen()[0] == False:
         apflog("APF is not open. Can't target a star while closed.",level='error',echo=True)
         return
     self.DMReset()
     # Call prep-obs
     apflog("Calling prep-obs.",echo=True)
     result, ret_code = cmdexec('prep-obs')
     if result == False:
         apflog("Prep-obs returned error code %d. Targeting object has failed." % (ret_code),level='error',echo=True)
         return
     self.DMReset()
     apflog("Slewing to lower el",echo=True)
     result, ret_code = cmdexec('slew -e 75')
     if result == False:
         apflog("Slew returned error code %d. Targeting object has failed." % (ret_code),level='error',echo=True)
         return
     # Slew to the specified RA and DEC, set guide camera settings, and centerup( Slewlock )
     # Focus the telescope?
     self.DMReset()
     if self.focusTel():
         return True
     else:
         return False
Esempio n. 10
0
def findColumns(col_names,req_cols,opt_cols=[]):
    """ findColumns finds the indices for the column names in the list of required columns
    indices = findColumns(col_names, req_cols)
    
    indices - a list of indices, each index maps to where in col_names the column is found and in the order of req_cols
    col_names - list of column names to be searched
    req_cols - list of names that should be in the first list
    """
    idx = []
    didx = dict()

    for r in req_cols:
        if r in col_names:
            didx[r] = col_names.index(r)
        else:
            apflog("%s Not found in column names from google spreadsheet" % (r) , level="Alert",echo=True)

    for r in opt_cols:
        if r in col_names:
            didx[r] = col_names.index(r)
            
    # hack to handle an error
    if req_cols[0] == "Star Name" and req_cols[0] not in didx.keys():
        didx[req_cols[0]] = 0
        apflog("Pasting 'Star Name' into column 0 of google spreadsheet" , level="Error",echo=True)

    return didx
Esempio n. 11
0
def getObserved(filename):
    """ getObserved parses a file to find the object names and times
    names, times = getObserved(filename)
    names - list of names, must be first column of file called filename
    times - times either as a timestamp in second column or a (hour,minute) tuple from a scriptobs line

    """
    obs = []
    times = []
    try:
        f = open(filename, 'r')
    except IOError:
        apflog("Couldn't open %s" % filename, level="warn", echo=True)
        return obs, times
    else:
        for line in f:
            line = line.strip()
            if len(line) > 0:
                if line[0] == '#' or line == "":
                    pass
                else:
                    ls = line.split()
                    obs.append(ls[0])
                    if len(ls) > 15:
                        times.append((int(ls[14].split('=')[1]),
                                      int(ls[15].split('=')[1])))
                    else:
                        times.append(float(ls[1]))

    obs.reverse()
    times.reverse()
    return obs, times
Esempio n. 12
0
def parseRankTable(sheet_table_name='2021B_ranks',
                   certificate='UCSC_Dynamic_Scheduler-4f4f8d64827e.json'):

    apflog("Starting parse of %s" % (sheet_table_name), echo=True)

    sheetns = []
    rank = []

    worksheet = getSpreadsheet(sheetn=sheet_table_name,
                               certificate=certificate)
    if worksheet:
        cur_codex = worksheet.get_all_values()
        if len(cur_codex) <= 0:
            apflog("Worksheet %s exists but is empty, skipping" %
                   (sheet_table_name),
                   level='error',
                   echo=True)
            return None, None
        for row in cur_codex[1:]:
            sheetns.append(row[0])
            crank = floatDefault(row[1])
            crank = int(round(crank))
            rank.append(crank)

    time_left = timeLeft()
    if time_left is not None:
        for ky in time_left.keys():
            if time_left[ky] <= 0:
                if ky in sheetns:
                    sindx = sheetns.index(ky)
                    rank[sindx] = -1000

    return sheetns, rank
Esempio n. 13
0
def templateConditions(moon, seeing, slowdown):
    """ istrue = conditionCuts(moon, seeing, slowdown)

    Checks to see if moon, seeing and slowdown factor are within template conditions

    istrue - a simple Boolean

    moon - phase value from pyephem, ranges from 0 to 100 (a percentage)
    seeing - size in pixels
    slowdown - relative to clear

    """

    if seeing < SEEING_TEMP and slowdown < SLOWDOWN_TEMP:
        apflog("moon.phase=%.2f moon.alt=%.2f" % (moon.phase, moon.alt),
               echo=True,
               level='debug')
        if moon.phase < 50 and float(moon.alt) < 0:
            return True
        elif moon.phase < 25 and float(moon.alt) < 0.7:
            return True
        else:
            return False
    else:
        return False
Esempio n. 14
0
def dmtimemon(dmtime):
    if dmtime['populated'] == False:
        return
    try:
        APF.dmtime = dmtime
    except Exception, e:
        apflog("Exception in dmtimemon: %s" % (e), level='error')
Esempio n. 15
0
def makeRankTable(sheet_table_name, outfn='rank_table', outdir=None):

    if not outdir:
        outdir = os.getcwd()

    outfn = os.path.join(outdir, outfn)
    if os.path.exists(outfn):
        rank_table = astropy.table.Table.read(outfn, format='ascii')
    else:
        sheetns, ranks = ParseUCOSched.parseRankTable(
            sheet_table_name=sheet_table_name)

        if sheetns is None or len(sheetns) == 0:
            return None

        rank_table = astropy.table.Table([sheetns, ranks],
                                         names=['sheetn', 'rank'])
        try:
            rank_table.write(outfn, format='ascii')
        except Exception as e:
            apflog("Cannot write table %s: %s" % (outfn, e),
                   level='error',
                   echo=True)

    return rank_table
Esempio n. 16
0
def parseStarlist(starlist):
    """ Parse a scriptobs-compatible starlist for the scheduler.

    names, star_table, lines, stars = parseStarlist(starlist)
    starlist - a filename

    names - a list of stars in the starlist
    star_table - a numpy array
    lines - a list of strings that can be used for scriptobs input
    stars - a list of pyEphem objects 
    """
    names = []
    lines = []
    stars = []
    star_table = []
    try:
        f = open(starlist,'r')
    except IOError:
        apflog("Warning: Could not open %s. No target can be selected." % starlist,echo=True)
        return None
    else:
        for line in f:
            if not re.search("\A\#",line):
                ls = line.split()
                names.append(ls[0])
                row = []
                # RA value in radians
                row.append(getRARad(ls[1], ls[2], ls[3]))
                # Dec value in radians
                row.append(getDECRad(ls[4], ls[5], ls[6]))
                # PM RA
                row.append(float(ls[8].split('=')[-1]))
                # PM Dec
                row.append(float(ls[9].split('=')[-1]))
                # V mag
                row.append(float(ls[10].split('=')[-1]))
                # Exposure time
                row.append(float(ls[11].split('=')[-1]))
                # Desired Counts
                row.append(float(ls[16].split('=')[-1]))
                # Filler not used here
                row.append(0.)
                row.append(0.)
                # Number of exposures
                row.append(int(ls[19].split('=')[-1]))

                star_table.append(row)

                # Save the scriptobs line for later
                lines.append(line)

                # Generate a pyEphem object for this target
                star = ephem.FixedBody()
                star.name = ls[0]
                star._ra = ephem.hours(":".join([ls[1], ls[2], ls[3]]))
                star._dec = ephem.degrees(":".join([ls[4], ls[5], ls[6]]))
                stars.append(star)
            
    return names, np.array(star_table), lines, stars
Esempio n. 17
0
def windmon(wx):
    if wx['populated'] == False:
        return
    try:
        wvel = float(wx)
    except Exception, e:
        apflog("Exception in windmon: %s" % (e), level='error')
        return
Esempio n. 18
0
def altwindmon(wx):
    if wx['populated'] == False:
        return
    try:
        downval = APF.down.read(binary=True)
    except Exception, e:
        apflog("Exception in altwindmon: %s" % (e), level='error')
        return
Esempio n. 19
0
def okmon(ok2open):
    if ok2open['populated'] == False:
        return
    try:
        ok = ok2open # historical
    except Exception, e:
        apflog("Exception in okmon for checkapf.OPEN_OK: %s" % (e), level='error')
        return
Esempio n. 20
0
def okmon(ok2open):
    ok = ok2open.read(binary=True)
    if not checkapf['MOVE_PERM'].read(binary=False):
        ok = False
    if APF.wvel > windlim:
        apflog("Too windy!")
        ok = False
    # Also need to check for cloud cover. This could require moving this call below the condition checking code.
    APF.openOK = ok
Esempio n. 21
0
def write_as_table(full_codex, outfn):
    hdr = full_codex[0]
    success = False
    try:
        ascii.write(full_codex[1:], outfn, names=full_codex[0], delimiter=",")
        success = True
    except:
        apflog("Cannot write %s" % (outfn), level="warn")
    return success
Esempio n. 22
0
def behindMoon(moon, ras, decs):
    md = TARGET_MOON_DIST_MAX - TARGET_MOON_DIST_MIN
    minMoonDist = ((moon.phase / 100.) * md) + TARGET_MOON_DIST_MIN
    moonDist = np.degrees(np.sqrt((moon.ra - ras)**2 + (moon.dec - decs)**2))

    apflog("behindMoon(): Culling stars behind the moon", echo=True)
    moon_check = moonDist > minMoonDist

    return moon_check
Esempio n. 23
0
 def setTeqMode(self, mode):
     apflog("Setting TEQMode to %s" % mode)
     if self.test: 
         print "Would be setting TEQMode to %s" % mode
         return
     self.teqmode.write(mode,wait=False)
     result = self.teqmode.waitfor('== %s' % mode, timeout=60)
     if not result:
         apflog("Error setting the TEQMODE.")
         raise RuntimeError, "Couldn't set TEQ mode"
Esempio n. 24
0
 def DMReset(self):
     try:
         APFLib.write(self.checkapf['ROBOSTATE'], "master operating",timeout=10)
     except Exception, e:
         try:
             ukind = self.checkapf['USERKIND'].read()
         except:
             ukind = "Unknown"
         ostr = "Error: Cannot write to ROBOSTATE, USERKIND = %s, reason: %s" % (ukind,e)
         apflog(ostr,level='error',echo=True)
Esempio n. 25
0
def instr_permit():
    instr_perm = ktl.read("checkapf","INSTR_PERM",binary=True)
    userkind = ktl.read("checkapf","USERKIND",binary=True)
    while not instr_perm or userkind != 3:
        apflog("Waiting for instrument permission to be true and userkind to be robotic")
        APFTask.waitfor(parent,True,expression="$checkapf.INSTR_PERM = true",timeout=600)
        APFTask.waitfor(parent,True,expression="$checkapf.USERKIND = robotic",timeout=600)
        instr_perm = ktl.read("checkapf","INSTR_PERM",binary=True)
        userkind = ktl.read("checkapf","USERKIND",binary=True)

    return True
Esempio n. 26
0
    def run_autoexposure(self,ind=5):
        cmdpath = '/usr/local/lick/bin/robot/'
        cmd = os.path.join(cmdpath,'autoexposure')
        istr = "%d" % (ind)
        cmdargs = cmd
#       cmdargs = cmd + " -i " + istr
        result, code = cmdexec(cmdargs,cwd=os.path.curdir)

#        result, code = cmdexec([cmd,istr],cwd=os.path.curdir)
        if not result:
            apflog("autoexposure failed with code %d" % code, echo=True)
        return result
Esempio n. 27
0
def templateConditions(moon, seeing, slowdown):

    if seeing < 20 and slowdown < 0.7:
        apflog("moon.phase=%.2f moon.alt=%.2f" % (moon.phase, moon.alt),
               echo=True,
               level='debug')
        if moon.phase < 50 and float(moon.alt) < 0.7:
            return True
        else:
            return False
    else:
        return False
Esempio n. 28
0
 def focusTel(self):
     star = self.find_star()
     if not star:
         apflog("Cannot find star near current position!?",level='error',echo=True)
         return False
     apflog("Targeting telescope on %s" % star[0], echo=True)
     
     if self.slew(star):
         if self.run_autoexposure(ind=1):
             if self.run_centerup():
                 return self.run_focustel()
     return False
Esempio n. 29
0
def update_googledex_lastobs(filename, sheetns=["2018B"],ctime=None,certificate='UCSC Dynamic Scheduler-5b98d1283a95.json'):
    """
        Update the online googledex lastobs column assuming things in filename have been observed.
        update_googledex_lastobs(filename, sheetn="The Googledex",time=None,certificate='UCSC Dynamic Scheduler-5b98d1283a95.json')

        filename - where the observations are logged
    """
    names, times = ObservedLog.getObserved(filename)
    if len(names) == 0:
        return
    if ctime is None:
        ctime = datetime.utcfromtimestamp(int(time.time()))
    

    for sheetn in sheetns:
        ws = get_spreadsheet(sheetn=sheetn,certificate=certificate)
        if ws:
            vals = ws.get_all_values()
        else:
            next
        col = vals[0].index("lastobs") 
        nobscol = vals[0].index("Nobs")
    
        for i, v in enumerate(vals):
            # Did we observe this target tonight?
            if v[0] in names:
                # We observed this target, so update the cell in the worksheet
                # update_cell(row, col, val) - col and row are 1 indexed
                otime = times[names.index(v[0])]
                if isinstance(otime,float):
                    t = datetime.utcfromtimestamp(otime)
                else:
                    hr, mn = otime
                    t = datetime(ctime.year, ctime.month, ctime.day, hr, mn)
                jd = float(ephem.julian_date(t))
                try:
                    pastdate = float(v[col])
                    try:
                        n = int(v[nobscol])
                    except:
                        n = 0
                    if jd > pastdate:
                        ws.update_cell(i+1, col+1, round(jd, 2) )
                        ws.update_cell(i+1, nobscol+1, n + 1 )

                except:
                    print (v[0], v[col])
                    ws.update_cell(i+1, col+1, round(jd,2) )
                
            apflog( "Updated %s" % (sheetn),echo=True)

    return
Esempio n. 30
0
def countratemon(kcountrate):
     if kcountrate['populated'] == False:
         return

     try:
         ctr = float(kcountrate['binary'])
     except:
         apflog("Cannot read apfguide.countrate",level='warn',echo=True)
         return
     APF.countrate *=  (1.0*APF.ncountrate)/(APF.ncountrate+1)
     APF.countrate += ctr/(APF.ncountrate+1)
     APF.ncountrate += 1
     return
Esempio n. 31
0
def update_local_googledex(intime,googledex_file="googledex.dat", observed_file="observed_targets"):
    """
        Update the local copy of the googledex with the last observed star time.
        update_local_googledex(time,googledex_file="googledex.dat", observed_file="observed_targets")

        opens googledex_file and inputs date of last observation from observed_file
        in principle can use timestamps as well as scriptobs uth and utm values
    """
    names, times = getObserved(observed_file)

    try:
        g = open(googledex_file, 'r')
    except IOError:
        apflog("googledex file did not exist, so can't be updated",echo=True)
        return names,times

    full_codex = pickle.load(g)
    g.close()

    codex_cols = full_codex[0]

    starNameIdx = codex_cols.index("Star Name")
    lastObsIdx = codex_cols.index("lastobs")
    
    for i in range(1, len(full_codex)):
        row = full_codex[i]
        if row[starNameIdx] in names:
            # We have observed this star, so lets update the last obs field
            obstime = times[names.index(row[starNameIdx])]
            if isinstance(obstime,float):
                t = datetime.utcfromtimestamp(obstime)
            else:
                hr, min = obstime
                if type(intime) != datetime:
                    ctime = datetime.now()
                    td = timedelta(0,3600.*7)
                    intime = ctime + td
                t = datetime(intime.year, intime.month, intime.day, hr, min)

            # This keeps the JD precision to one decimal point. There is no real reason for this other than
            # the googledex currently only stores the lastObs field to one decimal precision. Legacy styles FTW.
            jd = round(float(ephem.julian_date(t)), 2) 
            apflog( "Updating local googledex star %s from time %s to %s" % (row[starNameIdx], row[lastObsIdx], str(jd)),echo=True)
            row[lastObsIdx] = str(jd)
            full_codex[i] = row

    with open(googledex_file, 'w') as f:
        pickle.dump(full_codex, f)
    f.close()
    
    return names, times
Esempio n. 32
0
    def ucam_powercycle(self, fake=False):

        if fake:
            apflog("would have executed @LROOT/bin/robot/robot_power_cycle_ucam")
            return True
        else:
            val = subprocess.call("/usr/local/lick/bin/robot/robot_power_cycle_ucam")
            if val > 0:
                apflog("power cycle of UCAM failed",level='alert')
                return False

            return True

        return True
Esempio n. 33
0
    def testBias(self):

        if self.test:
            apflog(
                "Would have taken a single bias frame using APFControl.testBias()",
                echo=True)
        else:
            result = self.apf.testBias()
            if result == None:
                apflog("Focusinstr or calibrate or scriptobs are running?!",
                       level='Error',
                       echo=True)
            if result == False:
                # this is a UCAM problem
                rv = self.apf.ucamRestart()
                if rv == False:
                    apflog("Failure in UCAM status and restart!",
                           level='Alert',
                           echo=True)

        result = self.apf.ucamStatus()
        if result is False:
            apflog("Failure in UCAM status and restart!",
                   level='Alert',
                   echo=True)

        return result
Esempio n. 34
0
    def run(self):

        now = time.time()
        timeout = int(self.stime - now)
        if now < self.stime:
            apflog("Waiting until %s to begin" % datetime.fromtimestamp(now),
                   echo=True)
            APFTask.wait(self.task, True, timeout=timeout)

        if self.phase_index == 1:
            bias_result = self.testBias()

        if bias_result is False:
            return

        start = self.phase_index
        end = self.phase_index + 1
        for pi in (start, end):
            self.phase_index = pi
            cur_phase = self.possible_phases[pi]
            APFTask.phase(self.task, self.possible_phases[pi])
            apflog("Phase now %s %d" % (cur_phase, pi), echo=True)
            if cur_phase[0:3] == 'Cal':
                result = self.calibrate(cur_phase)
            else:
                result = self.focusInstr()

            if result:
                apflog("Phase %s is complete" % cur_phase, echo=True)
            else:
                apflog("Phase %s failed" % cur_phase, echo=True)
                return

        self.stop()
        return
Esempio n. 35
0
    def focus(self,flags="-b"):
        """Runs the focus routine appropriate for the user."""

        if self.test: 
            APFTask.waitFor(self.task, True, timeout=10)
            print "Test Mode: Would be running focusinstr."
            return True
        else:
            supplies = ('PS1_48V_ENA', 'PS2_48V_ENA')
            for keyword in supplies:
                value = motor[keyword].read(binary=True)
                if value != 1:
                    motor[keyword].write('Enabled', wait=False)
                    
            apflog("Running focusinstr routine.",echo=True)
            cmdpath = '/usr/local/lick/bin/robot/'
            execstr = " ".join(['focusinstr',flags])
            cmd = os.path.join(cmdpath,execstr)
            result, code = cmdexec(cmd,debug=True,cwd=os.getcwd())
            if not result:
                apflog("focusinstr failed with code %d" % code, echo=True)
                result = False
                
            expression="($apftask.FOCUSINSTR_STATUS == 3)"
            if not APFTask.waitFor(self.task,True,expression=expression,timeout=30):
                apflog("focusinstr failed" ,echo=True, level="error")
                result = False
            expression="($apftask.FOCUSINSTR_LASTFOCUS > 0)"
            if not APFTask.waitFor(self.task,True,expression=expression,timeout=30):
                apflog("focusinstr failed to find an adequate focus" ,echo=True, level="error")
                result = False
            return result
Esempio n. 36
0
 def calibrate(self, script, time):
     if self.test: 
         print "Test Mode: calibrate %s %s." % (script, time)
         APFTask.waitFor(self.task, True, timeout=10)
         return True
     if time == 'pre' or 'post':
         apflog("Running calibrate %s %s" % (script, time), level = 'info')
         cmd = '/usr/local/lick/bin/robot/calibrate %s %s' % (script, time)
         result, code = cmdexec(cmd)
         if not result:
             apflog("Calibrate %s %s failed with return code %d" % (script, time, code),echo=True)
         return result
     else:
         print "Couldn't understand argument %s, nothing was done." % time
Esempio n. 37
0
 def isOpen(self):
     """Returns the state of checkapf.WHATSOPN as a tuple (bool, str)."""
     try:
         whatstr = str(self.whatsopn)
         what = whatstr.split()
     except:
         apflog("checkapf.WHATSOPN returned a value that str.split cannot split",level='warn',echo=True)
         return False, ''
     if hasattr(what,'__iter__'):
         if "DomeShutter" in what or "MirrorCover" in what or "Vents" in what:
             return True, what
         else:
             return False, ''
     else:
         return False, ''
Esempio n. 38
0
    def focusInstr(self):

        if self.test:
            apflog("Would have run APFControl.focusinstr", echo=True)
            result = True
        else:

            result = self.apf.focusinstr()
            apflog("Focus has finished.", echo=True)

        if not self.test:
            APFTask.set(self.task,
                        suffix="LAST_OBS_UCSC",
                        value=self.apf.ucam["OBSNUM"].read())

        return result
Esempio n. 39
0
 def focus(self, user='******'):
     """Runs the focus routine appropriate for the style string."""
     if user == 'ucsc':
         if self.test: 
             APFTask.waitFor(self.task, True, timeout=10)
             print "Test Mode: Would be running Focus cube."
             return True
         else:
             apflog("Running FocusCube routine.",echo=True)
             cmd = '/u/user/devel_scripts/ucscapf/auto_focuscube.sh pre t'
             result, code = cmdexec(cmd,cwd='/u/user/devel_scripts/ucscapf')
             if not result:
                 apflog("Focuscube failed with code %d" % code, echo=True)
             return result
     else:
         print "Don't recognize user %s. Nothing was done." % style
Esempio n. 40
0
    def clearestop(self):
        if self.test: return True
        if self.mv_perm.binary == False:
            apflog("Waiting for permission to move...", echo=True)
            chk_move = "$checkapf.MOVE_PERM == true"
            result = APFTask.waitFor(self.task, False, chk_move, timeout=600)
            if not result:
                apflog("Can't open. No move permission.",echo=True)
                return False

        cmd = '/usr/local/lick/bin/robot/clear_estop'
        result, code = cmdexec(cmd,debug=True,cwd=os.getcwd())
        if result:
            return True
        else:
            return False
Esempio n. 41
0
def lastAttempted(observed):

    failed_obs = None

    try:
        lastresult = ktl.read("apftask", "SCRIPTOBS_LINE")
        lastobj = lastresult.split()[0]
    except:
        return None

    if lastobj not in observed.names:
        apflog("lastAttempted(): Last objects attempted %s" % (lastobj),
               echo=True)
        failed_obs = lastobj

    return failed_obs
Esempio n. 42
0
def updateHourTable(hour_table, observed, dt, outfn='hour_table', outdir=None):
    '''
    updateHourTableobserved_logs,outfn='hour_table')

    Updates hour_table with history of observations.

    '''

    if not outdir:
        outdir = os.getcwd()

    outfn = os.path.join(outdir, outfn)

    hours = dict()

    # observed objects have lists as attributes
    # in reverse time order, so most recent target observed is first.
    nobj = len(observed.names)
    for i in range(0, nobj):
        own = observed.owners[i]
        if own not in hours.keys():
            hours[own] = 0.0

    cur = dt
    for i in range(0, nobj):
        hr, mn = observed.times[i]
        prev = datetime(dt.year, dt.month, dt.day, hr, mn)
        diff = cur - prev
        hourdiff = (diff.days * 24 + diff.seconds / 3600.)
        if hourdiff > 0:
            hours[observed.owners[i]] += hourdiff
        cur = prev

    for ky in hours.keys():
        if ky == 'public':
            hour_table['cur'][hour_table['sheetn'] == 'RECUR_A100'] = hours[ky]
        else:
            hour_table['cur'][hour_table['sheetn'] == ky] = hours[ky]

    try:
        hour_table.write(outfn, format='ascii', overwrite=True)
    except Exception as e:
        apflog("Cannot write table %s: %s" % (outfn, e),
               level='error',
               echo=True)

    return hour_table
Esempio n. 43
0
 def killRobot(self, now=False):
     """ In case during an exposure there is a need to stop the robot and close up."""
     apflog("Terminating Robot.csh")
     if now:
         apflog("Abort exposure, terminating robot now.")
     else:
         if not ucam['EVENT_STR'].read() == "ControllerReady":
             apflog("Waiting for current exposure to finish.")
             ucam['EVENT_STR'].waitfor(" = ReadoutBegin", timeout=1200)
     apflog("Killing Robot.")
     ripd, running = self.findRobot()
     if running:
         try:
             APFLib.write(self.robot['scriptobs_control'], "abort")
         except Exception, e:
             errstr = "Cannot abort scriptobs: %s" % (e)
             apflog(errstr,level="Warn",echo=True)
Esempio n. 44
0
    def power_cycle_fousb(self):

        self.apfmot['FOUSB_POWER'].write(0)
        rv = APFTask.waitfor(self.task, True, expression="$apfmot.FOUSB_POWER == Off", timeout=10)
        if rv:
            APFTask.wait(self.task,True,timeout=1)
        else:
            apflog("Cannot power cycle FOUSB",level='error',echo=True)
            return False
        self.apfmot['FOUSB_POWER'].write(1)
        rv = APFTask.waitfor(self.task, True, expression="$apfmot.FOUSB_POWER == On",timeout=10)
        if rv:
            APFTask.wait(self.task,True,timeout=1)
        else:
            apflog("Cannot power cycle FOUSB",level='error',echo=True)
            return False
        return rv
Esempio n. 45
0
def computePriorities(star_table,
                      cur_dt,
                      observed=None,
                      hour_table=None,
                      rank_table=None):
    # make this a function, have it return the current priorities, than change references to the star_table below into references to the current priority list
    new_pri = np.zeros_like(star_table['pri'])

    # new priorities will be
    new_pri[star_table['pri'] == 1] += 0
    new_pri[star_table['pri'] == 2] -= 20
    new_pri[star_table['pri'] == 3] -= 40

    cadence_check = (ephem.julian_date(cur_dt) - star_table['lastobs'])
    good_cadence = cadence_check > star_table['cad']
    bad_cadence = np.logical_not(good_cadence)

    cadence_check /= star_table['cad']

    if hour_table is not None:
        too_much = hour_table['cur'] > hour_table['tot']
        done_sheets = hour_table['sheetn'][too_much]
    else:
        done_sheets = []

    if done_sheets != []:
        apflog("The following sheets are finished for the night: %s" %
               (" ".join(done_sheets)),
               echo=True)

    bad_pri = np.floor(cadence_check * 100)
    bad_pri = np.int_(bad_pri)

    if rank_table is not None:
        for sheetn in rank_table['sheetn']:
            if sheetn not in done_sheets:
                cur = star_table['sheetn'] == sheetn
                new_pri[cur & good_cadence] += rank_table['rank'][
                    rank_table['sheetn'] == sheetn]
                new_pri[cur & bad_cadence] += bad_pri[cur & bad_cadence]
            else:
                cur = star_table['sheetn'] == sheetn
                new_pri[cur & good_cadence] += 100
                new_pri[cur & bad_cadence] += bad_pri[cur & bad_cadence]

    return new_pri
Esempio n. 46
0
def set_obs_defaults(opt):
    if opt.name is None or opt.name == "ucsc":
        opt.owner = 'Vogt'
        opt.name = 'ucsc'
        if opt.obsnum == None:
            apflog("Figuring out what the observation number should be.",echo=False)
            opt.obsnum = findObsNum(apf)
        else:
            opt.obsnum = int(opt.obsnum)
    elif opt.name == "ucb":
        apflog("Figuring out what the observation name should be.",echo=False)
        opt.owner = 'Howard'
        opt.name = "ucb-" + getnightcode()
        opt.obsnum=100
    else:
        if opt.owner == None:
            opt.owner = opt.name

    return opt
Esempio n. 47
0
    def reboot_warsaw(self):

        if self.ucam_status.read(binary=True) == 1:
            rv = self.stop_ucam_software()
            if rv is False:
                apflog("UCAM software did not stop running, rebooting anyway",level='Error',echo=True)
            
        self.ucam_command.write(2)
        rv = APFTask.waitfor(self.task, True, expression="$apftask.UCAMLAUNCHER_STATUS == Running", timeout=120)
        if rv:
                # yay!
            self.ucam_command.write(1)
            rv = self.power_cycle_fousb()
            return rv
        else:
            # this is bad
            apflog("UCAM host not re-booted",level='Alert',echo=True)

        return False
Esempio n. 48
0
def update_googledex_lastobs(
        filename,
        sheetn="FakeGoogledex",
        time=None,
        certificate='UCSC Dynamic Scheduler-5b98d1283a95.json'):
    """
        Update the online googledex lastobs column assuming things in filename have been observed.
        update_googledex_lastobs(filename, sheetn="FakeGoogledex",time=None,certificate='UCSC Dynamic Scheduler-5b98d1283a95.json')

        filename - where the observations are logged
    """
    names, times = getObserved(filename)
    if len(names) == 0:
        return
    if time is None:
        time = datetime.utcnow()

    ws = get_spreadsheet(sheetn=sheetn, certificate=certificate)
    vals = ws.get_all_values()

    col = vals[0].index("lastobs")

    for i, v in enumerate(vals):
        # Did we observe this target tonight?
        if v[0] in names:
            # We observed this target, so update the cell in the worksheet
            # update_cell(row, col, val) - col and row are 1 indexed
            otime = times[names.index(v[0])]
            if isinstance(otime, float):
                t = datetime.fromtimestamp(otime)
            else:
                hr, min = otime
                t = datetime(time.year, time.month, time.day, hr, min)
            jd = float(ephem.julian_date(t))
            try:
                pastdate = float(v[col])
                if jd > pastdate:
                    ws.update_cell(i + 1, col + 1, round(jd, 2))
            except:
                print(v[0], v[col])

    apflog("Updated Googledex", echo=True)
Esempio n. 49
0
 def checkBstar(self,haveobserved):
     """ Master.obsBstar(haveobserved) 
         if observing has begun, and the last observation was a success, set Master.obsBstar to false, writes master_var_3 to
         the current value of obsBstar
         The variable VAR_3 still overrides
     """
     vals = APFTask.get("master",["VAR_3"])
     if vals['VAR_3'] == 'True':
         self.obsBstar = True
     else:
         self.obsBstar = False
     if haveobserved and self.lastObsSuccess:
         self.obsBstar = False
     try:
         s=""
         if self.obsBstar:
             s="True"
         APFTask.set(parent,suffix="VAR_3",value=s,wait=False)
     except:
         apflog("Error: Cannot communicate with apftask",level="error")
Esempio n. 50
0
def enoughTime(star_table, stars, idx, row, apf_obs, dt):
    tot_time = row[DS_NSHOTS] * row[DS_EXPT]
    tot_time += 210 + (
        2 * 40 + 40 * (row[DS_NSHOTS] - 1)
    )  # two B star exposures + three 70 second acquisitions and the actual observation readout times
    vis, star_elevations, fin_els = Visible.is_visible(apf_obs, [stars[idx]],
                                                       [tot_time])
    time_left_before_sunrise = compute_sunrise(dt, horizon='-9')

    try:
        apflog("enoughTime(): time for obs= %.1f  time until sunrise= %.1f " %
               (tot_time, time_left_before_sunrise),
               echo=True)
    except:
        apflog("enoughTime(): cannot log times!?!", echo=True)

    if tot_time < time_left_before_sunrise and vis and time_left_before_sunrise < 14 * 3600.:
        return True
    else:
        return False
Esempio n. 51
0
def parseFracTable(sheet_table_name='2021B_frac',
                   certificate='UCSC_Dynamic_Scheduler-4f4f8d64827e.json',
                   outfn=None,
                   outdir=None):

    apflog("Starting parse of %s" % (sheet_table_name), echo=True)
    if not outdir:
        outdir = os.getcwd()
    if outfn is not None and os.path.exists(os.path.join(outdir, outfn)):
        sheetns = []
        frac = []
        with open(os.path.join(outdir, outfn)) as fp:
            lines = fp.readlines()
            for ln in lines:
                row = ln.strip().split()
                if row[0] == 'sheetn':
                    continue
                sheetns.append(row[0])
                try:
                    frac.append(float(row[0]))
                except:
                    frac.append(0)
        return sheetns, frac

    sheetns = []
    frac = []

    worksheet = getSpreadsheet(sheetn=sheet_table_name,
                               certificate=certificate)
    if worksheet:
        cur_codex = worksheet.get_all_values()
        if len(cur_codex) <= 0:
            apflog("Worksheet %s exists but is empty, skipping" %
                   (sheet_table_name),
                   level='error',
                   echo=True)
            return None, None
        for row in cur_codex:
            if row[0] == 'sheetn':
                continue
            sheetns.append(row[0])
            frac.append(floatDefault(row[1]))

    wait_time = len(frac)
    apflog("Sleeping %.1f seconds to keep Google happy" % (wait_time),
           level="info",
           echo=True)
    time.sleep(wait_time)

    return sheetns, frac
Esempio n. 52
0
def get_spreadsheet(sheetn="FakeGoogledex",
                    certificate='UCSC Dynamic Scheduler-5b98d1283a95.json'):
    """ Get the spreadsheet from google

    worksheet = get_spreadsheet(sheetn="FakeGoogledex",certificate='UCSC Dynamic Scheduler-5b98d1283a95.json')
    worksheet - the worksheet object returned by the gspread module

    sheetn - name of the google sheet, defaults to "FakeGoogledex"
    certificate - certificate used to control access to the google sheet
    
    """
    # this downloads the googledex from the Google Drive
    # the certificate must be available
    # these certificates are generated through the Google Developer Interface
    # the developer must select the correct API for access

    # the certificate has an email associated with it, that email must
    # have the document shared with it to allow access

    certificate_path = os.path.dirname(__file__)

    json_key = json.load(open(os.path.join(certificate_path, certificate)))
    scope = [
        'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.me https://spreadsheets.google.com/feeds'
    ]

    credentials = SignedJwtAssertionCredentials(json_key['client_email'],
                                                json_key['private_key'], scope)
    gs = gspread.authorize(credentials)

    apflog("Successfully logged in.", echo=True)
    spreadsheet = gs.open(sheetn)
    apflog("Loaded Main %s" % (sheetn), echo=True)
    worksheet = spreadsheet.sheet1
    apflog("Got spreadsheet", echo=True)

    return worksheet
Esempio n. 53
0
def updateSheetLastobs(observed_file,
                       sheetns=["Bstar"],
                       ctime=None,
                       certificate='UCSC_Dynamic_Scheduler-4f4f8d64827e.json',
                       outfn='parsesched.dat',
                       outdir=None):
    """
        Update the online googledex lastobs column assuming things in filename have been observed.
        updateSheetLastobs(filename, sheetn="The Googledex",time=None,certificate='UCSC_Dynamic_Scheduler-4f4f8d64827e.json')

        filename - where the observations are logged
        sheetns - list of sheets that will be updated
        ctime - current time as a time stamp
        certificate - required for authentication
        outfn - the local copy of the star list
        outdir - directory of data files
        returns the number of cells updated
    """

    if not outdir:
        outdir = os.getcwd()

    obslog = ObservedLog.ObservedLog(
        filename=os.path.join(outdir, observed_file))
    if len(obslog.names) == 0:
        return
    if ctime is None:
        ctime = datetime.utcfromtimestamp(int(time.time()))

    outfn = os.path.join(outdir, outfn)
    star_table = readStarTable(outfn)

    # OK the following code is going to rely on the fact that owner
    # is the sheet name
    # this will need to be updated when we start using coverid
    needed_sheetns = list(set(obslog.owners))

    if 'public' in needed_sheetns:
        needed_sheetns.remove('public')
        needed_sheetns.append('RECUR_A100')

    nupdates = 0
    for sheetn in needed_sheetns:
        ws = getSpreadsheet(sheetn=sheetn, certificate=certificate)

        if ws:
            vals = ws.get_all_values()
        else:
            continue

        # The top of the sheet is a list of column names
        nmcol = vals[0].index('Star Name')
        col = vals[0].index("lastobs")
        nobscol = vals[0].index("Nobs")
        tempcol = vals[0].index("Template")

        wait_time = len(vals)
        time.sleep(wait_time)

        for i, v in enumerate(vals):
            # Starting at the top of vals is important.
            # the i is the row in the list of lists.
            # v is the current row in the list.
            # The columns that are updated are assigned above
            # By starting at 0 in vals, we will be indexed to the same row as in the sheet

            # Did we observe this target tonight?
            local_name = parseStarname(v[nmcol])

            if local_name in obslog.names:
                # We observed this target, so update the cell in the worksheet
                # update_cell(row, col, val) - col and row are 1 indexed
                nameidx = obslog.names.index(local_name)
                otime = obslog.times[nameidx]
                taketemp = obslog.temps[nameidx]
                curowner = obslog.owners[nameidx]
                if curowner == 'public':
                    curowner = 'RECUR_A100'
                jd = None
                try:
                    star_table_row = star_table[
                        (star_table['name'] == local_name)
                        & (star_table['sheetn'] == sheetn)]
                except:
                    star_table_row = None

                # idealy get JD from the local table
                if star_table_row is not None:
                    if len(star_table_row['lastobs']) > 0:
                        jd = float(star_table_row['lastobs'][0])

                # if the above fails, we should be able to use the observing log
                # but this is JUST the UT hour and minute, not the day so we have to use the otime
                # value to calculate the full JD
                if jd is None:
                    if isinstance(otime, float):
                        t = datetime.utcfromtimestamp(otime)
                    else:
                        hr, mn = otime
                        t = datetime(ctime.year, ctime.month, ctime.day, hr,
                                     mn)
                    jd = float(ephem.julian_date(t))
                try:
                    pastdate = float(v[col])
                except:
                    pastdate = 0.0
                try:
                    n = int(v[nobscol])
                except:
                    n = 0
                try:
                    if round(jd, 3) > pastdate and curowner == sheetn:
                        ws.update_cell(i + 1, col + 1, round(jd, 3))
                        ws.update_cell(
                            i + 1, nobscol + 1, n + 1
                        )  # sheets are indexed at 1 not at 0 like python lists
                        nupdates += 2
                        apflog("Updated %s from %.4f to %.4f and %d in %s" %
                               (v[0], pastdate, round(jd, 3), n + 1, sheetn),
                               echo=True)
                except:
                    apflog("Updated %s to %.4f and %d in %s" %
                           (v[0], round(jd, 3), 1, sheetn),
                           echo=True)
                    ws.update_cell(i + 1, col + 1, round(jd, 3))
                    ws.update_cell(i + 1, nobscol + 1, 1)
                    nupdates += 2
                try:
                    have_temp = v[tempcol]
                    if taketemp == "Y" and have_temp == "N" and curowner == sheetn:
                        ws.update_cell(i + 1, tempcol + 1, "Y")
                        nupdates += 1
                        apflog("Updated %s to having a template in %s" %
                               (v[0], sheetn),
                               echo=True)
                except:
                    apflog("Error logging template obs for %s" % (v[0]),
                           echo=True,
                           level='error')

    return nupdates
Esempio n. 54
0
def updateLocalStarlist(intime,
                        observed_file="observed_targets",
                        outfn='parsesched.dat',
                        toofn='too.dat',
                        outdir=None):
    """
        Update the local copy of the googledex with the last observed star time.
        updateLocalStarlist(time,googledex_file="googledex.dat", observed_file="observed_targets")

    opens googledex_file and inputs date of last observation from observed_file
        in principle can use timestamps as well as scriptobs uth and utm values
    """

    if not outdir:
        outdir = os.getcwd()

    obslog = ObservedLog.ObservedLog(
        filename=os.path.join(outdir, observed_file))

    outfn = os.path.join(outdir, outfn)
    if os.path.exists(outfn):
        star_table = readStarTable(outfn)
    else:
        return obslog, None

    toofn = os.path.join(outdir, toofn)
    if os.path.exists(toofn):
        too_table = readStarTable(toofn)
    else:
        too_table = None

    for name in obslog.names:
        index = obslog.names.index(name)
        obstime = obslog.times[index]
        owner = obslog.owners[index]
        if owner == 'public':
            owner = 'RECUR_A100'

        if isinstance(obstime, float):
            t = datetime.utcfromtimestamp(obstime)
        else:
            hr, min = obstime
            if type(intime) != datetime:
                ctime = datetime.now()
                td = timedelta(0, 3600. * 7)
                intime = ctime + td
            t = datetime(intime.year, intime.month, intime.day, hr, min)

        jd = round(float(ephem.julian_date(t)), 4)

        selection = (star_table['name'] == name) & (star_table['sheetn']
                                                    == owner)
        if any(selection):
            if np.any(jd > star_table['lastobs'][selection]):
                star_table['lastobs'][selection] = jd
                star_table['nobs'][selection] += 1
                apflog(
                    "Updating local googledex star %s in program %s to %.4f" %
                    (name, owner, jd),
                    echo=True)
        elif too_table is not None:
            selection = (too_table['name'] == name) & (too_table['sheetn']
                                                       == owner)
            if any(selection) and jd > too_table['lastobs'][selection]:
                apflog("Updating ToO target %s from time %.4f to %.4f" %
                       (name, too_table['lastobs'][selection], jd),
                       echo=True)
                too_table['lastobs'][selection] = jd
                too_table['nobs'][selection] += 1

    astropy.io.ascii.write(star_table, outfn, format='ecsv', overwrite=True)
    if too_table is not None:
        astropy.io.ascii.write(too_table, toofn, format='ecsv', overwrite=True)
        star_table = astropy.table.vstack(too_table, star_table)

    return obslog, star_table
Esempio n. 55
0
def parseCodex(config,
               sheetns=["RECUR_A100"],
               certificate='UCSC_Dynamic_Scheduler-4f4f8d64827e.json',
               prilim=1,
               sleep=True,
               hour_constraints=None):
    # These are the columns we need for scheduling
    req_cols = ["Star Name", "RA hr", "RA min", "RA sec", \
                    "Dec deg", "Dec min", "Dec sec", "pmRA", "pmDEC", "Vmag", \
                    "texp", "I2", "expcount", "decker","Close Companion", "APFnshots", \
                    "owner", "APFpri", "APFcad", "lastobs", "B-V", \
                    "cad", "pri", "nexp", "count",
                    "uth","utm","duration", \
                    "Template", "Nobs", "Total Obs", \
                    "mode", "raoff", "decoff", "Bstar", "obsblock",\
                    'sheetn' \
                    ]

    negsearch = re.compile("\-(\d+\.*\d*)")

    full_codex = retrieveCodex(
        req_cols,
        sheetns=sheetns,
        certificate='UCSC_Dynamic_Scheduler-4f4f8d64827e.json',
        sleep=sleep)

    col_names = full_codex[0]
    codex = full_codex[1:]

    didx = findColumns(col_names, req_cols)
    star_table = initStarTable(req_cols)

    if hour_constraints is not None:
        done_names = hour_constraints['runname'][hour_constraints['left'] < 0]
    else:
        done_names = []

    stars = []
    # Build the star table to return to
    for ls in codex:
        row = []
        if ls[0] == '':
            continue
        if "pri" in didx and ls[didx["pri"]] is not None:
            apfpri = intDefault(ls[didx["pri"]], default=-1)
        else:
            apfpri = intDefault(ls[didx["APFpri"]], default=-1)

        nobs = intDefault(ls[didx["Nobs"]])
        totobs = intDefault(ls[didx["Total Obs"]], default=-1)
        csheetn = checkFlag("sheetn", didx, ls, "\A(.*)", 'public')

        if totobs > 0 and nobs >= totobs: continue
        if apfpri < prilim: continue
        if csheetn in done_names: continue
        if apfpri > MAX_PRI: apfpri = MAX_PRI

        name = parseStarname(ls[didx["Star Name"]])
        # Get the RA
        raval, rahr, ramin, rasec = Coords.getRARad(ls[didx["RA hr"]],
                                                    ls[didx["RA min"]],
                                                    ls[didx["RA sec"]])
        if raval is None:
            # alarm
            apflog("Error in RA coordinates for %s" % (name),
                   level='warn',
                   echo=True)
            continue

        # Get the DEC
        decval, decdeg, decmin, decsec = Coords.getDECRad(
            ls[didx["Dec deg"]], ls[didx["Dec min"]], ls[didx["Dec sec"]])
        if decval is None:
            # alarm
            apflog("Error in Dec coordinates for %s" % (name),
                   level='warn',
                   echo=True)
            continue

        # why are we doing this you may ask?
        # we use Google sheets which cannot have -0 for a value
        # but if we pass a value like 00:-16:00 to eostele, it generates
        # an incorrect declination value
        # so, we move the - to the front of the sexagesimal string
        # the radian values above are only used for the scheduler, we still
        # command the telescope in the raw units

        if name and raval and decval:
            star_table["name"].append(name)

            star_table['ra'].append(raval)
            star_table['RA hr'].append(rahr)
            star_table['RA min'].append(ramin)
            star_table['RA sec'].append(rasec)

            star_table['dec'].append(decval)
            star_table["Dec deg"].append(decdeg)
            star_table["Dec min"].append(decmin)
            star_table["Dec sec"].append(decsec)
        else:
            continue

        mode = checkFlag("mode", didx, ls, "\A(b|B|a|A|c|C)", config["mode"])
        if type(mode) == str:
            mode = mode.upper()
        star_table['mode'].append(mode)
        star_table['raoff'].append(
            checkFlag("raoff", didx, ls, "\A((\+|\-)?\d+\.?\d*)",
                      config["raoff"]))
        star_table['decoff'].append(
            checkFlag("decoff", didx, ls, "\A((\+|\-)?\d+\.?\d*)",
                      config["decoff"]))

        for coln in ("pmRA", "pmDEC"):
            star_table[coln].append(floatDefault(ls[didx[coln]]))

        star_table['Vmag'].append(floatDefault(ls[didx["Vmag"]], default=15.0))
        star_table['texp'].append(floatDefault(ls[didx["texp"]], default=1200))
        expcount = floatDefault(ls[didx["expcount"]], default=1e9)
        if expcount > EXP_LIM:
            expcount = EXP_LIM
        star_table['expcount'].append(expcount)
        if "nexp" in didx and ls[didx["nexp"]] is not None:
            star_table['nexp'].append(intDefault(ls[didx["nexp"]], default=1))
        elif "count" in didx and ls[didx['count']] is not None:
            star_table['nexp'].append(intDefault(ls[didx["count"]], default=1))
        else:
            star_table['nexp'].append(
                intDefault(ls[didx["APFnshots"]], default=1))

        # scheduler specific
        if "cad" in didx and ls[didx['cad']] is not None:
            star_table['cad'].append(floatDefault(ls[didx["cad"]],
                                                  default=0.7))
        else:
            star_table['cad'].append(
                floatDefault(ls[didx["APFcad"]], default=0.7))

        star_table['pri'].append(apfpri)
        star_table["lastobs"].append(
            floatDefault(ls[didx["lastobs"]], default=0))

        inval = floatDefault(ls[didx["B-V"]], default=0.7)
        if inval < 0:
            inval = 1.
        if coln is 'B-V' and inval > 2:
            inval = 1
        star_table['B-V'].append(inval)

        # Nobs
        star_table['nobs'].append(nobs)

        # Total Obs
        if totobs >= 0:
            star_table['totobs'].append(totobs)
        else:
            star_table['totobs'].append(0)

        check = checkFlag("Close Companion", didx, ls, "\A(y|Y)", "")
        if check == "Y" or check == "y":
            star_table['do'].append(check)
        else:
            star_table['do'].append("")

        star_table['decker'].append(
            checkFlag("decker", didx, ls, "\A(W|N|T|S|O|K|L|M|B)",
                      config["decker"]))
        i2select = checkFlag("I2", didx, ls, "\A(n|N)", config["I2"])
        star_table['I2'].append(i2select.upper())
        tempselect = checkFlag("Template", didx, ls, "\A(n|N)", 'Y')
        star_table['Template'].append(tempselect.upper())

        star_table['owner'].append(
            checkFlag("owner", didx, ls, "\A(\w?\.?\w+)", config["owner"]))
        star_table['obsblock'].append(
            checkFlag("obsblock", didx, ls, "\A(\w+)", config["obsblock"]))
        #        star_table['inst'].append(checkFlag("inst",didx,ls,"(levy|darts)",config['inst']).lower())

        # need to check raoff and decoff values and alarm on failure

        if 'Bstar' in didx:
            star_table['Bstar'].append(
                checkFlag('Bstar', didx, ls, "(Y|y)", 'N'))
            star_table['sheetn'].append(csheetn)
        else:
            if 'RECUR_A100' in csheetn:
                star_table['Bstar'].append("Y")
                star_table['sheetn'].append('RECUR_A100')
            else:
                star_table['Bstar'].append("N")
                star_table['sheetn'].append(csheetn)

    badkeylist = []
    for k in star_table.keys():
        if len(star_table[k]) == 0:
            badkeylist.append(k)
    for k in badkeylist:
        del star_table[k]

    # This just reorders the columns
    # This way the ascii table has these columns in front to make finding targets by specific programs easier
    star_table_names = list(star_table.keys())
    for n in ('Dec sec', 'Dec min', 'Dec deg', 'RA sec', 'RA min', 'RA hr',
              'APFpri', 'sheetn', 'name'):
        if n in star_table_names:
            star_table_names.remove(n)
            star_table_names = [n] + star_table_names

    star_table = astropy.table.Table(star_table, names=star_table_names)

    return star_table
Esempio n. 56
0
    def calibrate(self, phase):

        apflog("Starting calibrate %s script." % (phase),
               level='Info',
               echo=True)
        if self.test:
            apflog(
                "Would have waited for permission (APFControl.instrPermit()) for phase %s"
                % (phase),
                echo=True)
        else:
            self.apf.instrPermit()

        if self.test:
            apflog("Would have run APFControl.ucamStatus() for phase %s" %
                   (phase),
                   echo=True)
            result = True
        else:
            result = self.apf.ucamStatus()
            if result is False:
                apflog("Failure in UCAM status and restart!",
                       level='Alert',
                       echo=True)
                return False

        time = phase[4:].lower()

        if self.test:
            apflog("Would have run APFControl.calibrate for time %s" % (time),
                   echo=True)
            result = True
        else:
            result = self.apf.calibrate(script=opt.calibrate, time=time)
            if not self.test:
                APFTask.set(self.task,
                            suffix="LAST_OBS_UCSC",
                            value=self.apf.ucam["OBSNUM"].read())

        if result == False:
            apflog("Calibrate Pre has failed. Trying again",
                   level='warn',
                   echo=True)
            self.apf.instrPermit()
            result = self.apf.calibrate(script=opt.calibrate, time='pre')
            if not result:
                apflog(
                    "Error: Calibrate Pre has failed twice. Observer is exiting.",
                    level='error',
                    echo=True)
                self.apf.turnOffLamps()

        return result
Esempio n. 57
0
def retrieveCodex(req_cols,
                  sheetns=["The Googledex"],
                  certificate='UCSC_Dynamic_Scheduler-4f4f8d64827e.json',
                  sleep=True):
    """retrieveCodex(req_cols,sheetns=["The Googledex"],certificate='UCSC_Dynamic_Scheduler-4f4f8d64827e.json')

    returns the "codex", a list of lists containing all of the columns
    in the req_cols list, source of the data are the Google sheets named
    in sheetns, needs a certificate to authenticate.

    - req_cols : a list of column names in the sheets that are required
    for the final list of lists
    - sheetns : sheets to download from
    - certificate : the thing that allows authentication
    """
    full_codex = []
    # These are the columns we need for scheduling
    full_codex.append(req_cols)
    failed = []
    for sheetn in sheetns:
        wait_time = 0
        worksheet = getSpreadsheet(sheetn=sheetn, certificate=certificate)
        if worksheet:
            cur_codex = None
            more_sleeping = 10.
            while cur_codex is None:
                try:
                    cur_codex = worksheet.get_all_values()
                except:
                    if sleep:
                        time.sleep(more_sleeping)
                    cur_codex = None

            if len(cur_codex) <= 0:
                apflog("Worksheet %s exists but is empty, skipping" % (sheetn),
                       level='error',
                       echo=True)

                continue
            didx = findColumns(cur_codex[0], req_cols)

            for row in cur_codex[1:]:
                nrow = []
                for c in req_cols:
                    if c in didx.keys():
                        nrow.append(row[didx[c]])
                    else:
                        if c is 'sheetn':
                            nrow.append(sheetn)
                        else:
                            nrow.append(None)

                full_codex.append(nrow)
                wait_time += .3
            if sleep and ((sheetns.index(sheetn) + 1) < len(sheetns)):
                apflog("Sleeping %.1f seconds to keep Google happy" %
                       (wait_time),
                       level="info",
                       echo=True)
                time.sleep(wait_time)

    return full_codex
Esempio n. 58
0
def getSpreadsheet(sheetn="The Googledex",
                   certificate='UCSC_Dynamic_Scheduler-4f4f8d64827e.json'):
    """ Get the spreadsheet from google

    worksheet = getSpreadsheet(sheetn="The Googledex",certificate='UCSC_Dynamic_Scheduler-4f4f8d64827e.json')
    worksheet - the worksheet object returned by the gspread module

    sheetn - name of the google sheet, defaults to "The Googledex"
    certificate - certificate used to control access to the google sheet

    """
    # this downloads the googledex from the Google Drive
    # the certificate must be available
    # these certificates are generated through the Google Developer Interface
    # the developer must select the correct API for access

    # the certificate has an email associated with it, that email must
    # have the document shared with it to allow access

    certificate_path = os.path.dirname("/usr/local/lick/data/apf/master/")
    if os.path.exists(certificate_path) is False:
        certificate_path = os.path.dirname(__file__)
    finpath = os.path.join(certificate_path, certificate)

    json_key = json.load(open(finpath))
    scope = [
        'https://spreadsheets.google.com/feeds',
        'https://www.googleapis.com/auth/drive'
    ]

    credentials = ServiceAccountCredentials.from_json_keyfile_name(
        os.path.join(certificate_path, certificate), scope)
    try:
        gs = gspread.authorize(credentials)
        apflog("Successfully logged in.", echo=True)
    except Exception as e:
        apflog("Cannot log into Google API.", echo=True, level='error')
        apflog(e, echo=True, level='error')
        return None
    worksheet = None
    tries = 0
    while worksheet is None and tries < 3:
        tries = tries + 1
        try:
            spreadsheet = gs.open(sheetn)
            apflog("Loaded Main %s" % (sheetn), echo=True)
            worksheet = spreadsheet.sheet1
            apflog("Got spreadsheet", echo=True)
            errlog = None
        except Exception as e:
            errlog = "Cannot Read %s: %s" % (sheetn, e)
            time.sleep(1)
    if worksheet is None and errlog is not None:
        apflog(errlog, echo=True, level='error')
    return worksheet
Esempio n. 59
0
def makeHourTable(sheet_table_name,
                  dt,
                  outfn='hour_table',
                  outdir=None,
                  frac_fn='frac_table',
                  hour_constraints=None):

    if not outdir:
        outdir = os.getcwd()

    outfn = os.path.join(outdir, outfn)

    if os.path.exists(outfn):
        hour_table = astropy.table.Table.read(outfn, format='ascii')
        return hour_table

    frac_fn = os.path.join(outdir, frac_fn)
    if os.path.exists(frac_fn):
        frac_table = astropy.table.Table.read(frac_fn, format='ascii')
    else:
        sheetns, fracs = ParseUCOSched.parseFracTable(
            sheet_table_name=sheet_table_name, outfn=frac_fn)
        frac_table = []
        for i in range(0, len(fracs)):
            frow = []
            frow.append(sheetns[i])
            frow.append(fracs[i])
            frac_table.append(frow)
        frac_table = astropy.table.Table(rows=frac_table,
                                         names=['sheetn', 'frac'])
        try:
            frac_table.write(frac_fn, format='ascii')
        except Exception as e:
            apflog("Cannot write table %s: %s" % (frac_fn, e),
                   level='error',
                   echo=True)

    hour_table = astropy.table.Table(frac_table, names=['sheetn', 'frac'])

    sunset, sunrise = computeSunsetRise(dt, horizon='-9')
    if sunrise < sunset:
        sunrise += 86400
    tot = sunrise - sunset
    tot /= 3600.

    hour_table['tot'] = np.abs(tot * hour_table['frac'])
    hour_table['cur'] = 0.0 * hour_table['frac']

    if hour_constraints is not None:
        if 'runname' in hour_constraints.keys(
        ) and 'left' in hour_constraints.keys():
            for runname in hour_constraints['runname']:
                if hour_constraints['left'][
                        hour_constraints['runname'] == runname] < hour_table[
                            'tot'][hour_table['sheetn'] == runname]:
                    hour_table['tot'][
                        hour_table['sheetn'] == runname] = hour_constraints[
                            'left'][hour_constraints['runname'] == runname]
                elif hour_constraints['left'][hour_constraints['runname'] ==
                                              runname] < 0:
                    hour_table['tot'][hour_table['sheetn'] == runname] = -1.0

    try:
        hour_table.write(outfn, format='ascii')
    except Exception as e:
        apflog("Cannot write table %s: %s" % (outfn, e),
               level='error',
               echo=True)
    return hour_table
Esempio n. 60
0
def getNext(ctime,
            seeing,
            slowdown,
            bstar=False,
            template=False,
            sheetns=["RECUR_A100"],
            owner='public',
            outfn="googledex.dat",
            toofn="too.dat",
            outdir=None,
            focval=0,
            inst='',
            rank_sheetn='rank_table',
            frac_sheet=None):
    """ Determine the best target for UCSC team to observe for the given input.
        Takes the time, seeing, and slowdown factor.
        Returns a dict with target RA, DEC, Total Exposure time, and scritobs line
    """

    global last_objs_attempted

    if not outdir:
        outdir = os.getcwd()

    dt = computeDatetime(ctime)

    config = configDefaults(owner)

    apflog("getNext(): Finding target for time %s" % (dt), echo=True)

    if slowdown > SLOWDOWN_MAX:
        apflog(
            "getNext(): Slowndown value of %f exceeds maximum of %f at time %s"
            % (slowdown, SLOWDOWN_MAX, dt),
            echo=True)
        return None

    try:
        apfguide = ktl.Service('apfguide')
        stamp = apfguide['midptfin'].read(binary=True)
        ptime = datetime.utcfromtimestamp(stamp)
    except:
        if type(dt) == datetime:
            ptime = dt
        else:
            ptime = datetime.utcfromtimestamp(int(time.time()))

    apflog("getNext(): Updating star list with previous observations",
           echo=True)
    observed, star_table = ParseUCOSched.updateLocalStarlist(
        ptime, outfn=outfn, toofn=toofn, observed_file="observed_targets")

    hour_table = None
    if frac_sheet is not None:
        hour_table = makeHourTable(frac_sheet, dt)
        hour_table = updateHourTable(hour_table, observed, dt)

    # Parse the Googledex
    # Note -- RA and Dec are returned in Radians

    if star_table is None:
        apflog("getNext(): Parsing the star list", echo=True)
        star_table, stars = ParseUCOSched.parseUCOSched(sheetns=sheetns,
                                                        outfn=outfn,
                                                        outdir=outdir,
                                                        config=config)
    else:
        stars = ParseUCOSched.genStars(star_table)
    targNum = len(stars)

    # List of targets already observed

    lastfailure = lastAttempted(observed)
    if lastfailure is not None:
        last_objs_attempted.append(lastfailure)
    if len(last_objs_attempted) == 5:
        apflog("getNext(): 5 failed acquisition attempts",
               level="warn",
               echo=True)

    ###
    # Need to update the googledex with the lastObserved date for observed targets
    # Scriptobs line uth utm can be used for this
    # Need to convert a uth and utm to a JD quickly.
    # timedelta = now - uth,utm : minus current JD?
    ###

    apf_obs = makeAPFObs(dt)
    # APF latitude in radians
    apf_lat = (37 + 20 / 60. + 33.1 / 3600.) * np.pi / 180.

    # Calculate the moon's location
    moon = ephem.Moon()
    moon.compute(apf_obs)

    do_templates = template and templateConditions(moon, seeing, slowdown)

    apflog("getNext(): Parsed the Googledex...", echo=True)

    apflog("getNext(): Finding B stars", echo=True)
    # Note which of these are B-Stars for later.
    bstars = (star_table['Bstar'] == 'Y') | (star_table['Bstar'] == 'y')

    # Distance to stay away from the moon

    totexptimes = np.zeros(targNum, dtype=float)
    totexptimes = star_table['texp'] * star_table['nexp'] + 40 * (
        star_table['nexp'] - 1)

    available = np.ones(targNum, dtype=bool)
    cur_elevations = np.zeros(targNum, dtype=float)
    scaled_elevations = np.zeros(targNum, dtype=float)

    # Is the target behind the moon?
    moon_check = behindMoon(moon, star_table['ra'], star_table['dec'])
    available = available & moon_check
    if len(last_objs_attempted) > 0:
        for n in last_objs_attempted:
            attempted = (star_table['name'] == n)
            available = available & np.logical_not(
                attempted)  # Available and not observed

    if bstar:
        # We just need a B star
        apflog("getNext(): Selecting B stars", echo=True)
        available = available & bstars

    else:

        apflog("getNext(): Culling B stars", echo=True)
        available = available & np.logical_not(bstars)

    # Calculate the exposure time for the target
    # Want to pass the entire list of targets to this function

    apflog("getNext(): Computing exposure times", echo=True)
    exp_counts = star_table['expcount']

    # Is the exposure time too long?
    apflog("getNext(): Removing really long exposures", echo=True)
    time_check = timeCheck(star_table, totexptimes, dt, hour_table)

    available = available & time_check
    if np.any(available) == False:
        apflog("getNext(): Not enough time left to observe any targets",
               level="error",
               echo=True)
        return None

    apflog("getNext(): Computing star elevations", echo=True)
    fstars = [s for s, _ in zip(stars, available) if _]
    vis, star_elevations, fin_star_elevations, scaled_els = Visible.visible(
        apf_obs, fstars, totexptimes[available], shiftwest=True)
    currently_available = available
    if len(star_elevations) > 0:
        currently_available[available] = currently_available[available] & vis
    else:
        apflog("getNext(): Couldn't find any suitable targets!",
               level="error",
               echo=True)
        return None

    cur_elevations[available] += star_elevations[vis]
    scaled_elevations[available] += scaled_els[vis]

    if slowdown > SLOWDOWN_THRESH or seeing > SEEING_THRESH:
        bright_enough = star_table['Vmag'] < SLOWDOWN_VMAG_LIM
        available = available & bright_enough

    # Now just sort by priority, then cadence. Return top target
    if len(star_table['name'][available]) < 1:
        apflog("getNext(): Couldn't find any suitable targets!",
               level="error",
               echo=True)
        return None

    final_priorities = computePriorities(star_table,
                                         dt,
                                         rank_table=makeRankTable(rank_sheetn),
                                         hour_table=hour_table,
                                         observed=observed)

    try:
        pri = max(final_priorities[available])
        sort_i = (final_priorities == pri) & available
    except:
        apflog("getNext(): Couldn't find any suitable targets!",
               level="error",
               echo=True)
        return None

    if bstar:
        sort_j = cur_elevations[sort_i].argsort()[::-1]
        focval = 2
    else:
        sort_j = scaled_elevations[sort_i].argsort()[::-1]

    allidx, = np.where(sort_i)
    idx = allidx[sort_j][0]

    t_n = star_table['name'][idx]
    o_n = star_table['sheetn'][idx]
    p_n = final_priorities[idx]

    apflog("getNext(): selected target %s for program %s at priority %.0f" %
           (t_n, o_n, p_n))
    nmstr = "getNext(): star names %s" % (np.asarray(
        star_table['name'][sort_i][sort_j]))
    pristr = "getNext(): star priorities %s" % (np.asarray(
        final_priorities[sort_i][sort_j]))
    mxpristr = "getNext(): max priority %d" % (pri)
    shstr = "getNext(): star sheet names %s" % (np.asarray(
        star_table['sheetn'][sort_i][sort_j]))
    if bstar:
        elstr = "getNext(): Bstar current elevations %s" % (
            cur_elevations[sort_i][sort_j])
    else:
        elstr = "getNext(): star scaled elevations %s" % (
            scaled_elevations[sort_i][sort_j])
    apflog(nmstr, echo=True)
    apflog(shstr, echo=True)
    apflog(pristr, echo=True)
    apflog(mxpristr, echo=True)
    apflog(elstr, echo=True)

    stars[idx].compute(apf_obs)

    res = makeResult(stars,
                     star_table,
                     totexptimes,
                     final_priorities,
                     dt,
                     idx,
                     focval=focval,
                     bstar=bstar,
                     mode=config['mode'])
    if do_templates and star_table['Template'][idx] == 'N' and star_table[
            'I2'][idx] == 'Y':
        bidx, bfinidx = findBstars(star_table, idx, bstars)

        if enoughTimeTemplates(star_table, stars, idx, apf_obs, dt):
            bline = makeScriptobsLine(star_table[bidx],
                                      dt,
                                      decker="N",
                                      I2="Y",
                                      owner=res['owner'],
                                      focval=2)
            line = makeScriptobsLine(star_table[idx],
                                     dt,
                                     decker="N",
                                     I2="N",
                                     owner=res['owner'],
                                     temp=True)
            bfinline = makeScriptobsLine(star_table[bfinidx],
                                         dt,
                                         decker="N",
                                         I2="Y",
                                         owner=res['owner'],
                                         focval=0)
            res['SCRIPTOBS'] = []
            res['SCRIPTOBS'].append(bfinline + " # temp=Y end")
            res['SCRIPTOBS'].append(line + " # temp=Y")
            res['SCRIPTOBS'].append(bline + " # temp=Y")
            res['isTemp'] = True
            apflog("Attempting template observation of %s" %
                   (star_table['name'][idx]),
                   echo=True)

    return res