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
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
def close(self): """Checks that we have the proper permission, then runs the closeup script.""" if self.test: return True if self.mv_perm.binary == False: if self.chk_close.binary == True: apflog("Waiting for checkapf to close up") else: apflog("Waiting for permission to move") chk_mv = '$checkapf.MOVE_PERM == true' result = APFTask.waitFor(self.task, False, chk_mv, timeout=300) if not result: apflog("Didn't have move permission after 5 minutes. Going ahead with closeup.", echo=True) cmd = "/usr/local/lick/bin/robot/closeup" apflog("Running closeup script") attempts = 0 close_start = datetime.now() while (datetime.now() - close_start).seconds < 1800: attempts += 1 result, code = cmdexec(cmd) if not result: apflog("Closeup failed with exit code %d" % code, echo=True) if attempts == 3: apflog("Closeup has failed 3 times consecutively. Human intervention likely required.", level='error', echo=True) APFTask.waitFor(self.task, True, timeout=30) else: break if result: return True else: apflog("After 30 minutes of trying, closeup could not successfully complete.") sys.exit("Closeup Failed")
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
def closing(force=False): if running: self.apf.killRobot(now=True) APFTask.set(self.task, suffix="LAST_OBS_UCSC", value=self.apf.ucam["OBSNUM"].read()) rv = self.apf.disableInst() rv = self.apf.close(force=force) if rv: return rv = self.apf.servoFailure() if rv: apflog("Servo Failure, cannot close and power off telescope ", level="alert", echo=True) rv = self.apf.powerDownTelescope() if rv: apflog("Power cycled telescope", echo=True) else: apflog("Failure power cycling telescope", echo=True, level="alert") return
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
def openat(self, sunset=False): """Function to ready the APF for observing. Calls either openatsunset or openatnight. This function will attempt to open successfully twice. If both attempts fail, then it will return false, allowing the master to register the error and behave accodingly. Otherwise it will return True. """ # If this is a test run, just return True if self.test: return True if not self.ok2open: # This should really never happen. In case of a temporary condition, we give # a short waitfor rather than immediatly exiting. chk_open = "$checkapf.OPEN_OK == true" result = APFLib.waitFor(self.task, False, chk_open, timeout=30) if not result: apflog("Tried calling openat with OPEN_OK = False. Can't open.", echo=True) apflog(self.checkapf["OPREASON"].read(), echo=True) return False if float(self.sunel) > SUNEL_HOR: apflog("Sun is still up. Current sunel = %4.2f. Can't open." % self.sunel, echo=True) return False 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 if self.states_set(): apflog("An unusal emergency state is set.", level="error",echo=True) return False # Everything seems acceptable, so lets try opening if sunset: cmd = '/usr/local/lick/bin/robot/openatsunset' else: cmd = '/usr/local/lick/bin/robot/openatnight' # Make two tries at opening. If they both fail return False so the caller can act # accordingly. result, code = cmdexec(cmd) if not result: apflog("First openup attempt has failed. Exit code = %d. After a pause, will make one more attempt." % code,echo=True) APFTask.waitFor(self.task, True, timeout=10) result, code = cmdexec(cmd) if not result: apflog("Second openup attempt also failed. Exit code %d. Giving up." % code,echo=True) return False rv = self.checkhome() if rv == False: return False try: APFLib.write("eostele.FOCUS",ktl.read("apftask","FOCUSTEL_LASTFOCUS",binary=True)) except: apflog("Cannot move secondary focus.",level="error") return False return True
def closing(): if running: APF.killRobot(now=True) APF.close() if apf.ucam['OUTFILE'].read() == 'ucsc': APFTask.set(parent,suffix="LAST_OBS_UCSC", value=apf.ucam["OBSNUM"].read()) return
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
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
def set_autofocval(self): """ Master.set_autofocval() tests when the last time the telescope was focused, if more than FOCUSTIME enable focus check """ APF = self.APF # check last telescope focus lastfoc = APF.robot['FOCUSTEL_LAST_SUCCESS'].read(binary=True) if time.time() - lastfoc > FOCUSTIME : APF.autofoc.write("robot_autofocus_enable") APFTask.set(parent,suffix="MESSAGE",value="More than %.1f hours since telescope focus, now focusing" % (FOCUSTIME/3600.),wait=False) else: APF.autofoc.write("robot_autofocus_disable")
def checkClouds(self, target): """ This function will take a test exposure of a B-Star. By using scriptobs to take this exposure, the avg_fwhm and countrate keywords will be updated. The resulting file will be stored as Heimdallr1.fits? :return: """ apflog("checkClouds(): starting transparency check", echo=True) # Things to reset after this apflog("checkClouds(): Storing current UCAM keywords for later...", echo=True) # UCAM outfile obs_file = self.ucam["OUTFILE"].read() # UCAM Obsnumber obs_num = self.ucam["OBSNUM"].read() robot['MASTER_VAR_2'].write(obs_num) # scriptobs_lines_done lines_done = int(self.robot["SCRIPTOBS_LINES_DONE"]) APFLib.write(self.autofoc, "robot_autofocus_enable") apflog("checkClouds(): File name=%s - Number=%d - Lines Done=%d" % (obs_file, int(obs_num), lines_done) ) APFLib.write(self.ucam["OUTFILE"], "heimdallr") APFLib.write(self.ucam["OBSNUM"], self.cloudObsNum) APFLib.write(self.ucam["RECORD"], "No") cmdexec('/usr/local/lick/bin/robot/prep-obs') args = ['/usr/local/lick/bin/robot/scriptobs', '-dir', os.path.join(self.cwd,'checkClouds/')] apflog("checkClouds(): Observing %s as a test star to check the clouds/seeing/transparency" % target["NAME"], echo=True) outfile = open('robot.log', 'a') p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=outfile, stderr=outfile) foo, bar = p.communicate(target["SCRIPTOBS"]) outfile.close() ret = p.returncode if ret != 0: apflog("checkClouds(): The cloud cover test exposure has failed.", echo=True) else: apflog("checkClouds(): Cloud check was successful", echo=True) self.cloudObsNum += 2 apflog("checkClouds(): Resetting UCAM keywords to previous values.", echo=True) APFLib.write(self.ucam["RECORD"], "Yes") APFLib.write(self.ucam["OUTFILE"], obs_file) APFLib.write(self.ucam["OBSNUM"], obs_num) APFLib.write(self.robot["SCRIPTOBS_LINES_DONE"], lines_done) APFTask.waitFor(self.task, True, timeout=5) apflog("checkClouds(): Keywords successfully written.", echo=True) apflog("checkClouds(): New values") apflog("checkClouds(): File=%s - Num=%d - LinesDone=%d" % (self.ucam["OUTFILE"].read(), int(self.ucam["OBSNUM"].read()), int(self.robot["SCRIPTOBS_LINES_DONE"].read()) ) ) return
def shutdown(): if success == True: status = 'Exited/Success' else: status = 'Exited/Failure' try: APFTask.set(parent, 'STATUS', status) except: print 'Exited/Failure' else: print status
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
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
def checkServos(self): ripd, running = self.apf.findRobot() if running: self.apf.killRobot(now=True) chk_done = "$checkapf.MOVE_PERM == true" result = APFTask.waitFor(self.task, True, expression=chk_done, timeout=600) if result: rv = self.apf.servoFailure() if rv: rv = self.apf.powerDownTelescope() if rv: apflog("Power cycled telescope", echo=True) else: apflog("Failure power cycling telescope", echo=True, level="alert") return rv else: apflog("No current servo faults", echo=True) elif result is False and "DomeShutter" in self.apf.isOpen()[1]: apflog( "Error: After 10 min move permission did not return, and the dome is still open.", level='error', echo=True) closing(force=True) return False
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
def start_ucam_software(self): if self.ucam_status.read(binary=True) == 0: self.ucam_command.write(1) rv = APFTask.waitfor(self.task, True, expression="$apftask.UCAMLAUNCHER_UCAM_STATUS == 'Running'", timeout=3) return rv else: return False
def close(self, force=False): """Checks that we have the proper permission, then runs the closeup script.""" if self.test: return True cmd = "/usr/local/lick/bin/robot/closeup" if force: apflog("Calling a single instance of closeup. Will return regardless of result.", echo=True) result, code = cmdexec(cmd) return result if self.mv_perm.binary == False: if self.chk_close.binary == True: apflog("Waiting for checkapf to close up") else: apflog("Waiting for permission to move") chk_mv = '$checkapf.MOVE_PERM == true' result = APFTask.waitFor(self.task, False, chk_mv, timeout=300) if not result: apflog("Didn't have move permission after 5 minutes. Going ahead with closeup.", echo=True) apflog("Running closeup script") attempts = 0 close_start = datetime.now() while (datetime.now() - close_start).seconds < 1800: attempts += 1 result, code = cmdexec(cmd) if not result: apflog("Closeup failed with exit code %d" % code, echo=True) if attempts == 2: if self.servo_failure(): apflog("Servo amplifier failure, power cycled telescope",echo=True) if attempts == 3: lstr = "Closeup has failed 3 times consecutively. Human intervention likely required." areopen, whatsopen = self.isOpen() if areopen == True: # truly dire, the telescope is open apflog(lstr, level='Alert', echo=True) else: # telescope powered on, and possibly in the wrong place, but not open apflog(lstr, level='error', echo=True) APFTask.waitFor(self.task, True, timeout=30) else: break if result: return True else: apflog("After 30 minutes of trying, closeup could not successfully complete.")
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")
def startRobot(self): """Start an instance of scriptobs. Returns the result from subprocess.Popen().""" # For running in test mode if self.test: apflog("Would be taking observation in starlist %s" % observation) APFTask.waitFor(self.task, True, timeout=300) return # Make sure the telescope autofocus is enabled APFLib.write(self.autofoc, "robot_autofocus_enable") chk_foc = '$apftask.SCRIPTOBS_AUTOFOC == robot_autofocus_enable' result = APFTask.waitFor(self.task, False, chk_foc, timeout=60) if not result: apflog("Error setting scriptobs_autofoc", echo=True) return # Make sure APFTEQ is in night mode for observations if self.teqmode.read() != 'Night': self.setTeqMode('Night') # Check the instrument focus for a reasonable value if self.dewarfoc > DEWARMAX or self.dewarfoc < DEWARMIN: lastfit_dewarfoc = ktl.read("apftask","FOCUSINSTR_LASTFOCUS",binary=True) apflog("Warning: The dewar focus is currently %d. This is outside the typical range of acceptable values. Resetting to last derived value %d" % (self.dewarfoc,lastfit_dewarfoc), level = "error", echo=True) APFLib.write("apfmot.DEWARFOCRAW",lastfit_dewarfoc) robotdir = "/usr/local/lick/bin/robot/" telstate = tel['TELSTATE'].read() if telstate == 'Disabled': rv, retc = cmdexec(os.path.join(robotdir,"slew --hold")) if not rv: return rv rv, retc = cmdexec(os.path.join(robotdir,"prep-obs")) if not rv: return rv # Start scriptobs outfile = open("robot.log", 'a') args = ['/usr/local/lick/bin/robot/scriptobs', '-dir', os.getcwd()] p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=outfile, stderr=outfile) return p
def control_watch(keyword,parent): if keyword['populated'] == False: return try: value = keyword['ascii'] global paused if value == "Abort": APFTask.set(parent,suffix='STATUS',value='Exited/Failure') APF.log("Aborted by APFTask") os.kill(os.getpid(),signal.SIGINT) elif value == "Pause": try: APFTask.set(parent,suffix='STATUS',value='PAUSED') paused = True except: APF.log("Failure to set STATUS in APFTask",level=error) os.kill(os.getpid(),signal.SIGINT) else: try: APFTask.set(parent,suffix='STATUS',value='Running') paused = False except: APF.log("Failure to set STATUS in APFTask",level=error) os.kill(os.getpid(),signal.SIGINT) except: return
def observe(self, observation, skip=0): """ Currently: Takes a string which is the filename of a properly formatted star list. """ if self.test: apflog("Would be taking observation in starlist %s" % observation) APFTask.waitFor(self.task, True, timeout=300) return self.robot['SCRIPTOBS_AUTOFOC'].write('robot_autofocus_enable') result = self.robot['SCRIPTOBS_AUTOFOC'].waitfor('== robot_autofocus_enable', timeout=60) if not result: apflog("Error setting scriptobs_autofoc", echo=True) return if self.teqmode.read() != 'Night': self.setTeqMode('Night') # Check Focus robotdir = "/u/user/devel_scripts/robot/" infile = open(observation,'r') outfile = open('robot.log', 'a') if skip != 0: args = ['./robot.csh', '-dir', '/u/rjhanson/master/','-skip', str(skip)] else: args = ['./robot.csh', '-dir', '/u/rjhanson/master/'] p = subprocess.Popen(args,stdin=infile, stdout=outfile,stderr = subprocess.PIPE, cwd=robotdir)
def power_down_telescope(self): """Checks that we have the proper permission and dome is closed, then resets telescope power.""" if self.test: return True cmd = "/usr/local/lick/bin/robot/power_down_telescope" self.DMReset() if self.mv_perm.binary == False: apflog("Waiting for permission to move") chk_mv = '$checkapf.MOVE_PERM == true' result = APFTask.waitFor(self.task, False, chk_mv, timeout=300) if not result: apflog("Didn't have move permission after 5 minutes.", echo=True) return False apflog("Running power_down_telescope script") result, code = cmdexec(cmd) if not result: apflog("power_down_telescope has failed. Human intervention likely required.", level='error', echo=True) APFTask.waitFor(self.task, True, timeout=30) else: pass if result: return True else: return False
def focusloop(): apflog("Current focus value = %s" % dewfoc) focmul = np.array(range(numsteps)) - np.median(range(numsteps)) focsteps = stepsize*focmul + normfoc apflog("Focus trials = %s" % repr(focsteps)) imfiles = [] for foc in focsteps: apflog("Setting dewar focus to %d" % foc) dewfoc.write(foc) time.sleep(2) while abs(dewfoc.binary - foc) > 10: time.sleep(2) apflog("Actual dewar focus value %d" % dewfoc.binary) APFTask.set('focusinstr','MESSAGE',"Actual dewar focus value %d" % dewfoc.binary) fname = os.path.join(ucam('OUTDIR').read(), ucam('OUTFILE').read() + ucam('OBSNUM').read() + '.fits') imfiles.append(fname) exposure('Focus', tharexp, readwait=False) apflog("Returning focus to starting position...") dewfoc.write(startfoc, wait=False) APFTask.set('focusinstr','MESSAGE','Returning focus to starting position...') return imfiles
def observe(self, observation,skip=False): """ Currently: Takes a string which is the filename of a properly formatted star list. """ if self.test: apflog("Would be taking observation in starlist %s" % observation) APFTask.waitFor(self.task, True, timeout=300) return # Make sure the telescope autofocus is enabled APFLib.write(self.autofoc, "robot_autofocus_enable") APFLib.write(self.ucam["RECORD"], "Yes") chk_foc = '$apftask.SCRIPTOBS_AUTOFOC == robot_autofocus_enable' result = APFTask.waitFor(self.task, False, chk_foc, timeout=60) if not result: apflog("Error setting scriptobs_autofoc", echo=True) return # Make sure APFTEQ is in night mode for observations if self.teqmode.read() != 'Night': self.setTeqMode('Night') # Check the instrument focus for a reasonable value if self.dewarfoc > 8600 or self.dewarfoc < 8400: lastfit_dewarfoc = ktl.read("apftask","FOCUSINSTR_LASTFOCUS",binary=True) apflog("Error: The dewar focus is currently %d. This is outside the typical range of acceptable values. Resetting to last derived value %d" % (self.dewarfoc,lastfit_dewarfoc), level = "error", echo=True) APFLib.write("apfmot.DEWARFOCRAW",lastfit_dewarfoc) # Check Telescope M2 Focus robotdir = "/usr/local/lick/bin/robot/" infile = open(observation,'r') outfile = open("robot.log", 'a') if skip: args = ['/usr/local/lick/bin/robot/scriptobs', '-dir', os.getcwd(),'-skip'] else: args = ['/usr/local/lick/bin/robot/scriptobs', '-dir', os.getcwd()] p = subprocess.Popen(args,stdin=infile, stdout=outfile,stderr = subprocess.PIPE, cwd=robotdir)
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
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
def opening(sunel,sunset=False): when = "night" if sunset: when = "sunset" apflog("Running open at %s as sunel = %4.2f" % (when, float(sunel))) (apfopen,what) =APF.isOpen() if apfopen: APF.DMReset() else: APF.DMZero() result = APF.openat(sunset=sunset) apflog("openatsunset completed with result %s" % (result), echo=True) if result == False: apflog("openatsunset hasn't successfully opened. Current sunel = %4.2f" % ( float(sunel)), level='warn', echo=True) if ( float(sunel) < SUNEL_ENDLIM): result = APF.openat(sunset=sunset) if not result: apflog("Error: openatsunset has failed twice.", level='error', echo=True) APF.close() if datetime.now().strftime("%p") == 'PM': setting = True else: setting = False APF.DMReset() if setting and sunset: rv = APF.evening_star() if not rv: apflog("evening star targeting and telescope focus did not work",level='warn', echo=True) chk_done = "$eostele.SUNEL < %f" % (SUNEL_STARTLIM*np.pi/180.0) result = False while float(sunel.read()) > SUNEL_STARTLIM and setting: outstr = "Sun setting is %s and sun at elevation of %.3f" % (setting, float(sunel.read())) apflog(outstr,level='info', echo=True) result = APFTask.waitFor(self.task, True, expression=chk_done, timeout=60) APF.DMReset() return
def focusloop(): apflog("Current focus value = %s" % dewfoc) focmul = np.array(range(numsteps)) - np.median(range(numsteps)) focsteps = stepsize * focmul + normfoc apflog("Focus trials = %s" % repr(focsteps)) imfiles = [] for foc in focsteps: apflog("Setting dewar focus to %d" % foc) dewfoc.write(foc) lfoc = foc - 10 hfoc = foc + 10 expr = 'apfmot.DEWARFOCRAW > %.0f & apfmot.DEWARFOCRAW > %.0f' % (lfoc, hfoc) success = APFTask.waitFor(parent, True, expression=expr, timeout=60) if success: apflog("Actual dewar focus value %d" % dewfoc.binary) APFTask.set('focusinstr', 'MESSAGE', "Actual dewar focus value %d" % dewfoc.binary) return [] else: apflog("Deware focus move failed, Actual dewar focus value %d" % dewfoc.binary, level='error') APFTask.set( 'focusinstr', 'MESSAGE', "Dewar focus move failed. Actual dewar focus value %d" % dewfoc.binary) fname = os.path.join( ucam('OUTDIR').read(), ucam('OUTFILE').read() + ucam('OBSNUM').read() + '.fits') imfiles.append(fname) exposure('Focus', tharexp, readwait=False) apflog("Returning focus to starting position...") dewfoc.write(startfoc, wait=False) APFTask.set('focusinstr', 'MESSAGE', 'Returning focus to starting position...') return imfiles
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
def run(self): """ Observe.run() - runs the observing """ def calcSlowdown(): if self.blank: return self.apf.robot["MASTER_SLOWDOWN"].read() if self.BV is None: apflog( "Warning!: Ended up in getTarget() with no B Magnitude value, slowdown can't be computed.", echo=True) self.BV = 0.6 # use a default average if self.VMAG is None: apflog( "Warning!: Ended up in getTarget() with no V Magnitude value, slowdown can't be computed.", echo=True) return 5 if self.apf.avg_fwhm < 1.0: apflog( "Warning!: AVG_FWHM = %4.2f. By Odin's beard that seems low." % self.apf.avg_fwhm, echo=True) return SchedulerConsts.SLOWDOWN_MAX slowdown = 1 apflog("Calculating expected counts") apflog( "self.VMAG [%4.2f] - self.BV [%4.2f] - self.apf.ael [%4.2f]" % (self.VMAG, self.BV, self.apf.ael)) exp_cnts_sec = ExposureCalculations.getEXPMeter_Rate( self.VMAG, self.BV, self.apf.ael, self.apf.avg_fwhm, self.decker) try: if self.apf.countrate <= 0: try: self.apf.countrate = self.apf.ccountrate except: self.apf.countrate = -1.0 if self.apf.countrate * 10 < self.apf.ccountrate: self.apf.countrate = self.apf.ccountrate slowdown = exp_cnts_sec / self.apf.countrate if slowdown < 0: slowdown = 1 apflog("Countrate non-sensical %g" % (self.apf.countrate), echo=True, level='warn') self.apf.counts.monitor(start=False) self.apf.counts.monitor(start=True) self.apf.counts.callback(APFControl.countmon) # yes this happened. if slowdown < SchedulerConsts.SLOWDOWN_MIN: slowdown = SchedulerConsts.SLOWDOWN_MIN apflog("slowdown too low, countrate= %g" % (self.apf.countrate), echo=True, level='debug') # yes this happened. if slowdown > SchedulerConsts.SLOWDOWN_MAX: slowdown = SchedulerConsts.SLOWDOWN_MAX apflog("slowdown too high, countrate= %g" % (self.apf.countrate), echo=True, level='debug') except ZeroDivisionError: apflog("Current countrate was 0. Slowdown will be set to 1.", echo=True) slowdown = 1 apflog("countrate = %.2f, ccountrate = %.2f" % (self.apf.countrate, self.apf.ccountrate)) apflog("slowdown factor = %4.2f" % slowdown, echo=True) APFLib.write(self.apf.robot["MASTER_SLOWDOWN"], slowdown) return slowdown def popNext(): curstr = None if self.target is not None and 'SCRIPTOBS' in self.target.keys(): tlist = self.target["SCRIPTOBS"] if len(tlist) > 0: apflog( "getTarget(): Going through remaining target queue.", echo=True) curstr = tlist.pop() + '\n' return curstr if self.fixedtarget is not None and 'SCRIPTOBS' in self.fixedtarget.keys( ): tlist = self.fixedtarget["SCRIPTOBS"] if len(tlist) > 0: apflog("getTarget(): Going through fixed starlist.", echo=True) curstr = tlist.pop() + '\n' else: apflog("getTarget(): Finished fixed starlist.", echo=True) self.fixedtarget = None return curstr # This is called when an observation finishes, and selects the next target def getTarget(): APFLib.write(self.apf.ucam["RECORD"], "Yes") # safe / sorry if self.apf.nerase != 2: self.apf.nerase.write(2, binary=True) if self.checkObsFinished(): apflog( "getTarget(): Scriptobs phase is input, determining next target.", echo=True) else: apflog("getTarget(): Not at end of block but out of targets.", echo=True) try: self.obsBstar = ktl.read("apftask", "MASTER_OBSBSTAR", binary=True) apflog("getTarget(): Setting obsBstar to %s" % (str(self.obsBstar)), echo=True) except Exception, e: apflog("getTarget(): Cannot read apftask.MASTER_OBSBSTAR: %s" % (e), level='error', echo=True) self.obsBstar = True if self.scriptobs is None: apflog( "Called getTarget, but there is not instance of scriptobs associated with %s. This is an error condition." % (self.name), level='error', echo=True) ripd, running = self.apf.findRobot() if running: apflog("Attempting to kill the existing robot, %d" % (ripd), level='error', echo=True) self.apf.killRobot() return # setup a B star observation if needed # if not B star observation, look at current stack of observations and see if anything is left if self.obsBstar: self.apf.autofoc.write("robot_autofocus_enable") else: curstr = popNext() if curstr: self.scriptobs.stdin.write(curstr) return # Calculate the slowdown factor. slowdown = calcSlowdown() # Check for a valid seeing measurment. If there isn't one, use a default if self.apf.avg_fwhm == 0.: apflog( "getTarget(): Warning AVG_FWHM is 0. A default value of 15 will be used in its place.", echo=True) seeing = 15 else: seeing = float(self.apf.avg_fwhm) apflog("getTarget(): Current AVG_FWHM = %4.2f" % seeing) self.apf.initGuideCam() self.apf.updateWindshield(self.windshield_mode) self.focval = self.apf.setAutofocVal() self.target = ds.getNext(time.time(), seeing, slowdown, bstar=self.obsBstar, sheetns=self.sheetn, owner=self.owner, template=self.doTemp, focval=self.focval, rank_sheetn=self.rank_tablen, frac_sheet=self.frac_tablen) if self.target is None: apflog( "No acceptable target was found. Since there does not seem to be anything to observe, %s will now shut down." % (self.name), echo=True) # Send scriptobs EOF to finish execution - wouldn't want to leave a zombie scriptobs running self.scriptobs.stdin.close() self.apf.close() if self.fixedList is None: APFLib.write(self.apf.ldone, 0) self.apf.countrate = -1.0 # sleep for a half hour to see if the clouds blow by APFTask.waitfor(self.task, True, timeout=60 * 30) return else: apflog("Observing target: %s" % self.target['NAME'], echo=True) APFTask.set(self.task, suffix="MESSAGE", value="Observing target: %s" % self.target['NAME'], wait=False) try: self.scriptobs.stdin.write(self.target["SCRIPTOBS"].pop() + '\n') except IOError as e: apflog("Cannot observe target %s: IOError: %s" % (self.target['NAME'], e), echo=True, level='error') return # Set the Vmag and B-V mag of the latest target self.VMAG = self.target["VMAG"] self.BV = self.target["BV"] self.decker = self.target["DECKER"] istemp = str(self.target['isTemp']) if self.target["mode"] == 'B' or self.target["mode"] == 'A': self.blank = True else: self.blank = False apflog("getTarget(): V=%.2f B-V=%.2f Pri=%.2f " % (self.VMAG, self.BV, self.target["PRI"])) apflog("getTarget(): FWHM=%.2f Slowdown=%.2f Countrate=%.2f" % (self.apf.avg_fwhm, slowdown, self.apf.countrate)) apflog("getTarget(): Target= %s Temp=%s" % (self.target["NAME"], istemp)) apflog("getTarget(): Counts=%.2f EXPTime=%.2f Nexp=%d" % (self.target["COUNTS"], self.target["EXP_TIME"], self.target["NEXP"])) if self.target['isTemp']: self.nTemps += 1 if self.nTemps >= self.totTemps: self.doTemp = False return
def startScriptobs(): # Update the last obs file and hitlist if needed if apf.ucam['OUTFILE'].read() == 'ucsc' and apf.test == False: APFTask.set(parent,suffix="LAST_OBS_UCSC", value=apf.ucam["OBSNUM"].read()) APF.updateWindshield(self.windshield) apflog("Starting an instance of scriptobs",echo=True) ripd, running = APF.findRobot() if running: apflog("Scriptobs is already running yet startScriptobs was called",level="warn",echo=True) return if self.fixedList is not None and self.shouldStartList(): # We wish to observe a fixed target list, in it's original order if not os.path.exists(self.fixedList): apflog("Error: starlist %s does not exist" % (self.fixedList), level="error") self.fixedList=None return tot = getTotalLines(self.fixedList) apflog("%d total starlist lines and %d lines done." % (tot, APF.ldone)) if APF.ldone == tot and APF.user != "ucsc": APF.close() if apf.ucam['OUTFILE'].read() == 'ucsc': APFTask.set(parent,suffix="LAST_OBS_UCSC", value=apf.ucam["OBSNUM"].read()) self.exitMessage = "Fixed list is finished. Exiting the watcher." self.stop() # The fixed list has been completely observed so nothing left to do elif APF.ldone == tot and APF.user == "ucsc": self.fixedList = None self.starttime = None if not APF.test: APFTask.set(self.task,suffix="STARLIST",value="") ripd, running = APF.findRobot() if running: APF.killRobot(now=True) apflog("Finished fixed list on line %d, will start dynamic scheduler" % int(APF.ldone), echo=True) expression="($apftask.SCRIPTOBS_STATUS != 0) and ($apftask.SCRIPTOBS_STATUS != 1) " if APFTask.waitFor(self.task,True,expression=expression,timeout=30): apflog("Starting an instance of scriptobs for dynamic observing.",echo=True) self.scriptobs = APF.startRobot() else: apflog("Found Fixed list %s" % self.fixedList, echo=True) apflog("Starting fixed list on line %d" % int(APF.ldone), echo=True) APF.observe(str(self.fixedList),skip=True) APFTask.waitFor(self.task, True, timeout=10) else: if self.BV is None: apflog("No B-V value at the moment", echo=True) #self.BV = 0.028 if self.VMAG is None: apflog("No VMag value at the moment", echo=True) #self.VMAG = None # We wish to observe either a starlist with intelligent ordering, or the dynamic scheduler apflog("Starting an instance of scriptobs for dynamic observing.",echo=True) self.scriptobs = APF.startRobot() # Don't let the watcher run over the robot starting up APFTask.waitFor(self.task, True, timeout=10) return
def opening(sunel, sunset=False): if self.canOpen is False: apflog("We cannot open, so not trying", level='Error', echo=True) return False when = "night" if sunset: when = "sunset" mstr = "Open at %s" % (when) APFTask.set(self.task, suffix="MESSAGE", value=mstr, wait=False) result = self.apf.ucamStatus() if result is False: apflog("Failure in UCAM status and restart!", level='Alert', echo=True) else: apflog("UCAM OK", echo=True) result = self.apf.enableObsInst() if result == False: apflog("Cannot enable instrument", level='warn', echo=True) result = self.apf.enableObsInst() if not result: apflog("Error: cannot enable instrument twice.", level='alert', echo=True) return result else: apflog("Instrument OK", echo=True) apflog("Running open at %s as sunel = %4.2f" % (when, float(sunel)), echo=True) (apfopen, what) = self.apf.isOpen() if apfopen: self.apf.DMReset() else: self.apf.DMZero() result = self.apf.openat(sunset=sunset) apflog("opening completed with result %s" % (result), echo=True) if result == False: apflog( "opening hasn't successfully opened. Current sunel = %4.2f" % (float(sunel)), level='warn', echo=True) if (float(sunel) < SchedulerConsts.SUNEL_ENDLIM): result = self.apf.openat(sunset=sunset) if not result and self.apf.openOK['binary']: apflog( "Error: opening has failed twice, likely needs intervention.", level='Alert', echo=True) self.apf.close() self.canOpen = False if datetime.now().strftime("%p") == 'PM': setting = True else: setting = False self.apf.DMReset() return result
else: apflog("Phase %s failed" % cur_phase, echo=True) return self.stop() return def stop(self): self.signal = False threading.Thread._Thread__stop(self) if __name__ == "__main__": task = 'example' APFTask.establish(task, os.getpid()) apf = APFControl.APF(task=task, test=True) # Give the monitors some time to start up APFTask.waitFor(task, True, timeout=2) print(str(apf)) stime = time.time() + 5 calibrate = Calibrate(apf, 'public', stime, task=task, test=True) while calibrate.signal: try: APFTask.wait(task, True, timeout=1) except KeyboardInterrupt: apflog("%s has been killed by user." % (calibrate.name), echo=True) calibrate.stop() sys.exit() except:
def getTarget(): apflog("getTarget(): Scriptobs phase is input, determining next target.",echo=True) APFLib.write(APF.ucam["RECORD"], "Yes") # safe / sorry try: self.obsBstar = bool(ktl.read("apftask","master_var_3")) except: self.obsBstar = True if self.scriptobs is None: apflog("Called getTarget, but there is not instance of scriptobs associated with Heimdallr. This is an error condition.", echo=True) return None # Calculate the slowdown factor. if self.BV is None: apflog("Warning!: Ended up in getTarget() with no B Magnitude value, slowdown can't be computed.", echo=True) self.BV = 0.6 # use a default average if self.VMAG is None: apflog("Warning!: Ended up in getTarget() with no V Magnitude value, slowdown can't be computed.", echo=True) slowdown = 5 elif APF.avg_fwhm < 1.0: apflog("Warning!: AVG_FWHM = %4.2f. By Odin's beard that seems low." % APF.avg_fwhm, echo=True) slowdown = 5 else: apflog("Calculating expected counts") apflog("self.VMAG [%4.2f] - self.BV [%4.2f] - APF.ael [%4.2f]" % (self.VMAG, self.BV, APF.ael)) exp_cnts_sec = ExposureCalculations.getEXPMeter_Rate(self.VMAG, self.BV, APF.ael,APF.avg_fwhm, self.decker) try: if APF.countrate <= 0: try: APF.countrate = APF.ccountrate except: APF.countrate = -1.0 slowdown = exp_cnts_sec / APF.countrate if APF.countrate*10 < APF.ccountrate: APF.countrate = APF.ccountrate if slowdown < 0: slowdown = 1 apflog("Countrate non-sensical %g" % (APF.countrate), echo=True, level='warn') APF.counts.monitor(start=False) APF.counts.monitor(start=True) APF.counts.callback(ad.countmon) # yes this happened. if slowdown < SchedulerConsts.SLOWDOWN_MIN: slowdown = SchedulerConsts.SLOWDOWN_MIN apflog("slowdown too low, countrate= %g" % (APF.countrate), echo=True, level='debug') # yes this happened. if slowdown > SchedulerConsts.SLOWDOWN_MAX: slowdown = SchedulerConsts.SLOWDOWN_MAX apflog("slowdown too high, countrate= %g" % (APF.countrate), echo=True, level='debug') except ZeroDivisionError: apflog("Current countrate was 0. Slowdown will be set to 1.", echo=True) slowdown = 1 apflog("getTarget(): slowdown factor = %4.2f" % slowdown, echo=True) APFLib.write(apf.robot["MASTER_VAR_1"], slowdown) apflog("getTarget(): countrate = %.2f, ccountrate = %.2f" % (APF.countrate,APF.ccountrate)) # Check for a valid seeing measurment. If there isn't one, use a default if APF.avg_fwhm == 0.: apflog("getTarget(): Warning AVG_FWHM is 0. A default value of 15 will be used in its place.",echo=True) seeing = 15 else: seeing = float(APF.avg_fwhm) apflog("getTarget(): Current AVG_FWHM = %4.2f" % seeing) target = ds.getNext(time.time(), seeing, slowdown, bstar=self.obsBstar, verbose=True, sheetns=self.sheetn, owner=self.owner) self.set_autofocval() if target is None: apflog("No acceptable target was found. Since there does not seem to be anything to observe, Heimdallr will now shut down.", echo=True) # Send scriptobs EOF to finish execution - wouldn't want to leave a zombie scriptobs running self.scriptobs.stdin.close() APF.close() apf.countrate = -1.0 # sleep for a half hour to see if the clouds blow by APFTask.waitfor(self.task, True, timeout=60*45) return else: apflog("Observing target: %s" % target['NAME'], echo=True) self.scriptobs.stdin.write(target["SCRIPTOBS"] + '\n') # Set the Vmag and B-V mag of the latest target self.VMAG = target["VMAG"] self.BV = target["BV"] self.decker = target["DECKER"] apflog("getTarget(): V=%.2f B-V=%.2f Pri=%.2f " % (self.VMAG, self.BV, target["PRI"])) apflog("getTarget(): FWHM=%.2f Slowdown=%.2f Countrate=%.2f" % (APF.avg_fwhm, slowdown, APF.countrate)) apflog("getTarget(): Target= %s" % target["NAME"]) apflog("getTarget(): Counts=%.2f EXPTime=%.2f Nexp=%d" % (target["COUNTS"], target["EXP_TIME"], target["NEXP"]))
def run(self): """ Master.run() - runs the observing """ APF = self.APF # This is called when an observation finishes, and selects the next target def getTarget(): apflog("getTarget(): Scriptobs phase is input, determining next target.",echo=True) APFLib.write(APF.ucam["RECORD"], "Yes") # safe / sorry try: self.obsBstar = bool(ktl.read("apftask","master_var_3")) except: self.obsBstar = True if self.scriptobs is None: apflog("Called getTarget, but there is not instance of scriptobs associated with Heimdallr. This is an error condition.", echo=True) return None # Calculate the slowdown factor. if self.BV is None: apflog("Warning!: Ended up in getTarget() with no B Magnitude value, slowdown can't be computed.", echo=True) self.BV = 0.6 # use a default average if self.VMAG is None: apflog("Warning!: Ended up in getTarget() with no V Magnitude value, slowdown can't be computed.", echo=True) slowdown = 5 elif APF.avg_fwhm < 1.0: apflog("Warning!: AVG_FWHM = %4.2f. By Odin's beard that seems low." % APF.avg_fwhm, echo=True) slowdown = 5 else: apflog("Calculating expected counts") apflog("self.VMAG [%4.2f] - self.BV [%4.2f] - APF.ael [%4.2f]" % (self.VMAG, self.BV, APF.ael)) exp_cnts_sec = ExposureCalculations.getEXPMeter_Rate(self.VMAG, self.BV, APF.ael,APF.avg_fwhm, self.decker) try: if APF.countrate <= 0: try: APF.countrate = APF.ccountrate except: APF.countrate = -1.0 slowdown = exp_cnts_sec / APF.countrate if APF.countrate*10 < APF.ccountrate: APF.countrate = APF.ccountrate if slowdown < 0: slowdown = 1 apflog("Countrate non-sensical %g" % (APF.countrate), echo=True, level='warn') APF.counts.monitor(start=False) APF.counts.monitor(start=True) APF.counts.callback(ad.countmon) # yes this happened. if slowdown < SchedulerConsts.SLOWDOWN_MIN: slowdown = SchedulerConsts.SLOWDOWN_MIN apflog("slowdown too low, countrate= %g" % (APF.countrate), echo=True, level='debug') # yes this happened. if slowdown > SchedulerConsts.SLOWDOWN_MAX: slowdown = SchedulerConsts.SLOWDOWN_MAX apflog("slowdown too high, countrate= %g" % (APF.countrate), echo=True, level='debug') except ZeroDivisionError: apflog("Current countrate was 0. Slowdown will be set to 1.", echo=True) slowdown = 1 apflog("getTarget(): slowdown factor = %4.2f" % slowdown, echo=True) APFLib.write(apf.robot["MASTER_VAR_1"], slowdown) apflog("getTarget(): countrate = %.2f, ccountrate = %.2f" % (APF.countrate,APF.ccountrate)) # Check for a valid seeing measurment. If there isn't one, use a default if APF.avg_fwhm == 0.: apflog("getTarget(): Warning AVG_FWHM is 0. A default value of 15 will be used in its place.",echo=True) seeing = 15 else: seeing = float(APF.avg_fwhm) apflog("getTarget(): Current AVG_FWHM = %4.2f" % seeing) target = ds.getNext(time.time(), seeing, slowdown, bstar=self.obsBstar, verbose=True, sheetns=self.sheetn, owner=self.owner) self.set_autofocval() if target is None: apflog("No acceptable target was found. Since there does not seem to be anything to observe, Heimdallr will now shut down.", echo=True) # Send scriptobs EOF to finish execution - wouldn't want to leave a zombie scriptobs running self.scriptobs.stdin.close() APF.close() apf.countrate = -1.0 # sleep for a half hour to see if the clouds blow by APFTask.waitfor(self.task, True, timeout=60*45) return else: apflog("Observing target: %s" % target['NAME'], echo=True) self.scriptobs.stdin.write(target["SCRIPTOBS"] + '\n') # Set the Vmag and B-V mag of the latest target self.VMAG = target["VMAG"] self.BV = target["BV"] self.decker = target["DECKER"] apflog("getTarget(): V=%.2f B-V=%.2f Pri=%.2f " % (self.VMAG, self.BV, target["PRI"])) apflog("getTarget(): FWHM=%.2f Slowdown=%.2f Countrate=%.2f" % (APF.avg_fwhm, slowdown, APF.countrate)) apflog("getTarget(): Target= %s" % target["NAME"]) apflog("getTarget(): Counts=%.2f EXPTime=%.2f Nexp=%d" % (target["COUNTS"], target["EXP_TIME"], target["NEXP"])) # opens the dome & telescope, if sunset is True calls open at sunset, else open at night def opening(sunel,sunset=False): when = "night" if sunset: when = "sunset" apflog("Running open at %s as sunel = %4.2f" % (when, float(sunel))) (apfopen,what) =APF.isOpen() if apfopen: APF.DMReset() else: APF.DMZero() result = APF.openat(sunset=sunset) apflog("openatsunset completed with result %s" % (result), echo=True) if result == False: apflog("openatsunset hasn't successfully opened. Current sunel = %4.2f" % ( float(sunel)), level='warn', echo=True) if ( float(sunel) < SUNEL_ENDLIM): result = APF.openat(sunset=sunset) if not result: apflog("Error: openatsunset has failed twice.", level='error', echo=True) APF.close() if datetime.now().strftime("%p") == 'PM': setting = True else: setting = False APF.DMReset() if setting and sunset: rv = APF.evening_star() if not rv: apflog("evening star targeting and telescope focus did not work",level='warn', echo=True) chk_done = "$eostele.SUNEL < %f" % (SUNEL_STARTLIM*np.pi/180.0) result = False while float(sunel.read()) > SUNEL_STARTLIM and setting: outstr = "Sun setting is %s and sun at elevation of %.3f" % (setting, float(sunel.read())) apflog(outstr,level='info', echo=True) result = APFTask.waitFor(self.task, True, expression=chk_done, timeout=60) APF.DMReset() return # closing def closing(): if running: APF.killRobot(now=True) APF.close() if apf.ucam['OUTFILE'].read() == 'ucsc': APFTask.set(parent,suffix="LAST_OBS_UCSC", value=apf.ucam["OBSNUM"].read()) return # starts an instance of scriptobs def startScriptobs(): # Update the last obs file and hitlist if needed if apf.ucam['OUTFILE'].read() == 'ucsc' and apf.test == False: APFTask.set(parent,suffix="LAST_OBS_UCSC", value=apf.ucam["OBSNUM"].read()) APF.updateWindshield(self.windshield) apflog("Starting an instance of scriptobs",echo=True) ripd, running = APF.findRobot() if running: apflog("Scriptobs is already running yet startScriptobs was called",level="warn",echo=True) return if self.fixedList is not None and self.shouldStartList(): # We wish to observe a fixed target list, in it's original order if not os.path.exists(self.fixedList): apflog("Error: starlist %s does not exist" % (self.fixedList), level="error") self.fixedList=None return tot = getTotalLines(self.fixedList) apflog("%d total starlist lines and %d lines done." % (tot, APF.ldone)) if APF.ldone == tot and APF.user != "ucsc": APF.close() if apf.ucam['OUTFILE'].read() == 'ucsc': APFTask.set(parent,suffix="LAST_OBS_UCSC", value=apf.ucam["OBSNUM"].read()) self.exitMessage = "Fixed list is finished. Exiting the watcher." self.stop() # The fixed list has been completely observed so nothing left to do elif APF.ldone == tot and APF.user == "ucsc": self.fixedList = None self.starttime = None if not APF.test: APFTask.set(self.task,suffix="STARLIST",value="") ripd, running = APF.findRobot() if running: APF.killRobot(now=True) apflog("Finished fixed list on line %d, will start dynamic scheduler" % int(APF.ldone), echo=True) expression="($apftask.SCRIPTOBS_STATUS != 0) and ($apftask.SCRIPTOBS_STATUS != 1) " if APFTask.waitFor(self.task,True,expression=expression,timeout=30): apflog("Starting an instance of scriptobs for dynamic observing.",echo=True) self.scriptobs = APF.startRobot() else: apflog("Found Fixed list %s" % self.fixedList, echo=True) apflog("Starting fixed list on line %d" % int(APF.ldone), echo=True) APF.observe(str(self.fixedList),skip=True) APFTask.waitFor(self.task, True, timeout=10) else: if self.BV is None: apflog("No B-V value at the moment", echo=True) #self.BV = 0.028 if self.VMAG is None: apflog("No VMag value at the moment", echo=True) #self.VMAG = None # We wish to observe either a starlist with intelligent ordering, or the dynamic scheduler apflog("Starting an instance of scriptobs for dynamic observing.",echo=True) self.scriptobs = APF.startRobot() # Don't let the watcher run over the robot starting up APFTask.waitFor(self.task, True, timeout=10) return ############################### # Actual Watching loop apflog("Beginning observing process....",echo=True) APF.DMZero() haveobserved = False failstart = 0 while self.signal: # Check on everything if datetime.now().strftime("%p") == 'AM': rising = True sunel_lim = SUNEL_ENDLIM else: rising = False sunel_lim = sunel_startlim() wind_vel = APF.wvel ripd, running = APF.findRobot() sunel = APF.sunel sunel.monitor() # if paused: # apflog("Pausing because of apftask request",level='warn',echo=True) # APFTask.waitfor(self.task, True, timeout=60) # Check and close for weather if APF.isOpen()[0] and not APF.openOK: closetime = datetime.now() APFTask.set(parent,suffix="MESSAGE",value="Closing for weather",wait=False) apflog("No longer ok to open.", echo=True) apflog("OPREASON: " + APF.checkapf["OPREASON"].read(), echo=True) apflog("WEATHER: " + APF.checkapf['WEATHER'].read(), echo=True) closing() # Check the slowdown factor to close for clouds if self.VMAG is not None and self.BV is not None and False: exp_cntrate = ExposureCalculations.getEXPMeter_Rate(self.VMAG, self.BV, APF.ael,APF.avg_fwhm) try: slow = exp_cntrate / APF.countrate if slow < 0: slow = 5 apflog("Countrate non-sensical %g" % APF.countrate, echo=True) except ZeroDivisionError: apflog("No current countrate", echo=True) slow = 5 APFTask.set(parent,suffix="MESSAGE",value="FWHM = %.2f and slowdown %.2f" % (APF.avg_fwhm,slow),wait=False) if slow > 16: # The slowdown is too high, we should close up and wait. APFTask.set(parent,suffix="MESSAGE",value="Closing for clouds",wait=False) apflog("Slowdown factor of %.2f is too high. Waiting 30 min to check again." % slow, echo=True) closing() APFTask.waitfor(self.task, True, timeout=60*30) self.VMAG=None self.BV=None APF.countrate = 0 # If scriptobs is running and waiting for input, give it a target if running == True and float(sunel) < sunel_lim and APF.sop.read().strip() == 'Input': if self.fixedList is None or self.shouldStartList() == False: self.lastObsSuccess = self.checkObsSuccess() self.obsBstar = self.checkBstar(haveobserved) APFTask.set(parent,suffix="MESSAGE",value="Calling getTarget",wait=False) apflog("Scriptobs phase is input ( dynamic scheduler ), calling getTarget.") getTarget() apflog("Observing target") APFTask.set(parent,suffix="MESSAGE",value="Observing Target",wait=False) APFTask.waitfor(self.task, True, timeout=15) haveobserved = True elif self.starttime != None and self.shouldStartList() : APF.killRobot() # check last telescope focus if running and float(sunel) <= sunel_lim : self.set_autofocval() # If the sun is rising and we are finishing an observation # Send scriptobs EOF. This will shut it down after the observation if float(sunel) >= sunel_lim and running == True: APFTask.set(parent,suffix="MESSAGE",value="Last call",wait=False) if self.scriptobs is None: apflog("Robot claims to be running, but no self.scriptobs instance can be found. Instead calling killRobot().", echo=True) APF.killRobot() else: self.scriptobs.stdin.close() APF.killRobot() # If the sun is rising and scriptobs has stopped, run closeup if float(sunel) > sunel_lim and running == False and rising == True: apflog("Closing due to sun elevation. Sunel = % 4.2f" % float(sunel), echo=True) APFTask.set(parent,suffix="MESSAGE",value="Closing, sun is rising",wait=False) if APF.isOpen()[0]: msg = "APF is open, closing due to sun elevation = %4.2f" % float(sunel) closing() else: msg = "Telescope was already closed when sun got to %4.2f" % float(sunel) if APF.isOpen()[0]: apflog("Error: Closeup did not succeed", level='error', echo=True) self.exitMessage = msg self.stop() # If we can open, try to set stuff up so the vent doors can be controlled by apfteq if APF.openOK and not rising and not APF.isOpen()[0]: APFTask.set(parent,suffix="MESSAGE",value="Powering up for APFTeq",wait=False) if APF.clearestop(): try: APFLib.write(APF.dome['AZENABLE'],'enable',timeout=10) except: apflog("Error: Cannot enable AZ drive, exiting",level="error") return apf.setTeqMode('Evening') else: apflog("Error: Cannot clear emergency stop, sleeping for 600 seconds",level="error") APFTask.waitFor(parent,True,timeout=600) # Open if not APF.isReadyForObserving()[0] and float(sunel) < SUNEL_HOR and APF.openOK : if float(sunel) > sunel_lim and not rising : APFTask.set(parent,suffix="MESSAGE",value="Open at sunset",wait=False) success = opening( sunel, sunset=True) elif not rising or (rising and float(sunel) < (sunel_lim - 5)): APFTask.set(parent,suffix="MESSAGE",value="Open at night",wait=False) success = opening( sunel) else: success = True if success == False: apflog("Error: Cannot open the dome",echo=True,level='error') APF.close() os._exit() # Check for servo errors if APF.isOpen()[0] and APF.slew_allowed == False: APFTask.set(parent,suffix="MESSAGE",value="Servo failure.",wait=False) apflog("Error: APF is open, and slew_allowed is false. Likely an amplifier fault.", level="error", echo=True) # apflog("Forcing checkapf to close the dome. Heimdallr will then exit.", echo=True) chk_done = "$checkapf.MOVE_PERM == true" # APFLib.write(APF.dmtimer, 0) result = APFTask.waitFor(self.task, True, expression=chk_done, timeout=600) if not result and "DomeShutter" in APF.isOpen()[1]: apflog("Error: After 10 min move permission did not return, and the dome is still open.", level='error', echo=True) APF.close(force=True) if not APF.power_down_telescope(): apflog("Error: Cannot reset telescope after servo failure",level="error", echo=True) os._exit(1) # If we are open and scriptobs isn't running, start it up if APF.isReadyForObserving()[0] and not running and float(sunel) <= sunel_lim: APFTask.set(parent,suffix="MESSAGE",value="Starting scriptobs",wait=False) startScriptobs() if not APFTask.waitFor(self.task,True,expression="$apftask.SCRIPTOBS_STATUS == 'Running'",timeout=10): if failstart % 11 == 0 and failstart > 0: lvl = "error" else: lvl = "warn" apflog("scriptobs is not running just after being started!", level=lvl, echo=True) APFTask.set(parent,suffix="MESSAGE",value="scriptobs is not running just after being started!",wait=False) # Keep an eye on the deadman timer if we are open if APF.isOpen()[0] and APF.dmtime <= DMLIM: APFTask.set(parent,suffix="MESSAGE",value="Reseting DM timer",wait=False) APF.DMReset() # apflog("The APF is open, the DM timer is clicking down, and scriptobs is %s." % ( str(running)),level="debug") if not APF.isOpen()[0] and not rising: APFTask.set(parent,suffix="MESSAGE",value="Waiting for sunset",wait=False) APFTask.waitFor(self.task, True, timeout=5) if APF.isOpen()[0] and float(sunel) > sunel_lim: APFTask.set(parent,suffix="MESSAGE",value="Waiting for the end of twilight",wait=False) APFTask.waitFor(self.task, True, timeout=5)
def startScriptobs(): # Update the last obs file and hitlist if needed APFTask.set(self.task, suffix="LAST_OBS_UCSC", value=self.apf.ucam["OBSNUM"].read()) self.apf.updateWindshield(self.windshield_mode) ripd, running = self.apf.findRobot() if running: apflog( "Scriptobs is already running yet startScriptobs was called", level="warn", echo=True) return rv = self.checkScriptobsMessages() if rv is False: return expr = "$checkapf.MOVE_PERM = True and $checkapf.INSTR_PERM = True" perms = APFTask.waitFor(self.task, True, expression=expr, timeout=1200) if perms is False: apflog( "Cannot start an instance of scriptobs because do not have permission", echo=True, level='error') return apflog("Starting an instance of scriptobs", echo=True) if self.fixedList is not None and self.shouldStartList(): # We wish to observe a fixed target list, in it's original order if not os.path.exists(self.fixedList): apflog("Error: starlist %s does not exist" % (self.fixedList), level="error") self.fixedList = None self.starttime = None APFLib.write(self.apf.robot["MASTER_STARLIST"], "") APFLib.write(self.apf.robot["MASTER_UTSTARTLIST"], "") # this reads in the list and appends it to self.target tot = readStarlistFile() if self.apf.ldone == tot: APFLib.write(self.apf.robot["MASTER_STARLIST"], "") APFLib.write(self.apf.robot["MASTER_UTSTARTLIST"], "") self.fixedList = None self.starttime = None self.target = None if not self.apf.test: APFTask.set(self.task, suffix="STARLIST", value="") apflog( "Finished fixed list on line %d, will start dynamic scheduler" % int(self.apf.ldone), echo=True) else: apflog("Found Fixed list %s" % self.fixedList, echo=True) apflog("Starting fixed list on line %d" % int(self.apf.ldone), echo=True) self.fixedList = None else: if self.BV is None: apflog("No B-V value at the moment", echo=True) #self.BV = 0.028 if self.VMAG is None: apflog("No VMag value at the moment", echo=True) #self.VMAG = None # We wish to observe with the dynamic scheduler ripd, running = self.apf.findRobot() if running is False: apflog( "Starting an instance of scriptobs for dynamic observing.", echo=True) self.scriptobs = self.apf.startRobot() # Don't let the watcher run over the robot starting up APFTask.waitFor(self.task, True, timeout=10) return
rv = self.ucam_powercycle(fake=fake) return rv if comb.read(binary=True) > 0: # brains! rv = self.ucam_restart(comb,fake=fake) return rv return True if __name__ == '__main__': print "Testing telescope monitors, grabbing and printing out current state." task = 'example' APFTask.establish(task, os.getpid()) apf = APF(task=task,test=False) # Give the monitors some time to start up APFTask.waitFor(task, True,timeout=2) print str(apf) while True: print str(apf) time.sleep(10)
apflog("Beginning observing process....", echo=True) self.apf.DMZero() haveobserved = False failstart = 0 while self.signal: # Check on everything if self.apf.sunRising(): rising = True sunel_lim = SchedulerConsts.SUNEL_ENDLIM else: rising = False sunel_lim = SchedulerConsts.SUNEL_STARTLIM ripd, running = self.apf.findRobot() cursunel = self.apf.sunel current_msg = APFTask.get("master", ["MESSAGE"]) # Check and close for weather self.badweather = self.apf.dewTooClose or not self.apf.openOK if self.apf.isOpen()[0] and self.badweather: closetime = datetime.now() APFTask.set(self.task, suffix="MESSAGE", value="Closing for weather", wait=False) apflog("No longer ok to open.", echo=True) apflog("OPREASON: " + self.apf.checkapf["OPREASON"].read(), echo=True) apflog("WEATHER: " + self.apf.checkapf['WEATHER'].read(), echo=True)
def run(self): APF = self.APF apflog("Beginning observing process....",echo=True) while self.signal: # Check on everything if datetime.now().strftime("%p") == 'AM': rising = True else: rising = False wind_vel = APF.wvel ripd, running = APF.findRobot() el = float(APF.sunel) # Check and close for weather if APF.isOpen()[0] and not APF.openOK: closetime = datetime.now() apflog("No longer ok to open.", echo=True) apflog("OPREASON:" + APF.checkapf["OPREASON"].read(), echo=True) apflog("WEATHER:" + APF.checkapf['WEATHER'].read(), echo=True) if running: APF.killRobot(now=True) APF.close() APF.updateLastObs() # If we are open and the sun rises, closeup if el > -8.9 and not running and rising: apflog("Closing due to the sun.", echo=True) if APF.isOpen()[0]: msg = "APF is open, closing due to sun elevation = %4.2f" % el else: msg = "Telescope was already closed when sun got to %4.2f" % el APF.close() if APF.isOpen()[0]: apflog("Closeup did not succeed", level='Error', echo=True) APF.updateLastObs() self.exitMessage = msg self.stop() # Open at sunset if not APF.isOpen()[0] and el < -3.2 and el > -8 and APF.openOK and not rising: apflog("Running open at sunset as sunel = %4.2f" % el) result = APF.openat(sunset=True) if not result: apflog("After two tries openatsunset hasn't successfully opened. \ Emailing for help and exiting.", level='error', echo=True) APF.close() sys.exit(1) # If we are closed, and the sun is down, openatnight if not APF.isOpen()[0] and el < -8.9 and APF.openOK: apflog("Running open at night at sunel =%4.2f" % el) result = APF.openat(sunset=False) if not result: apflog("After two tried openatnight couldn't succeed. \ Emailing for help and exiting.", level='error', echo=True) APF.close() sys.exit(1) # If we are open at night and the robot isn't running # take an obs if APF.isOpen()[0] and not running and el <= -8.9: # Update the last obs file and hitlist if needed APF.updateLastObs() APF.updateWindshield(self.windshield) apflog("Looking for a valid target",echo=True) tooFound = False try: f = open("TOO.txt",'r') except IOError: pass else: f.close() apflog("Found a target of opportunity. Observing that.", echo=True) apflog("After starting Observation file will be renamed 'TOO_done.txt'", echo=True) APF.observe("TOO.txt") tooFound = True if self.fixedList is not None and not tooFound: tot = getTotalLines(self.fixedList) if apf.ldone == tot: APF.close() APF.updateLastObs() self.exitMessage = "Fixed list is finished. Exiting the watcher." self.stop() # The fixed list has been completely observed so nothing left to do else: apflog("Found Fixed list %s" % self.fixedList, echo=True) apflog("Starting fixed list on line %s" % str(apf.ldone), echo=True) APF.observe(str(self.fixedList), skip=int(apf.ldone)) elif not tooFound: infile = sh.getObs() if infile is None: apflog("Couldn't get a valid target from sh.getObs().",echo=True) else: # Make sure we don't pass an empty starlist to scriptobs lines = getTotalLines(infile) apflog("Observing valid target list with %d line(s)" % (lines),echo=True) if lines > 0: APF.observe(infile, skip=0) # Don't let the watcher run over the robot starting up APFTask.waitFor(self.task, True, timeout=5) # Keep an eye on the deadman timer if we are open if APF.isOpen()[0] and APF.dmtime <= 120: APF.DMReset()
opt = args() if opt.test: debug = True parent = 'example' else: debug = False parent = 'master' print "Starting Nights Run..." # Establish this as the only running master script try: APFTask.establish(parent, os.getpid()) except Exception as e: print e apflog("Task is already running with name %s." % parent, echo=True) sys.exit("Couldn't establish APFTask %s" % parent) else: # Set up monitoring of the current master phase apftask = ktl.Service("apftask") phase = apftask("%s_PHASE" % parent) phase.monitor() # Set preliminary signal and tripwire conditions APFTask.set(parent, "SIGNAL", "TERM") APFTask.set(parent, "TRIPWIRE", "TASK_ABORT")
apflog("Offset from previous value = %+4.0f" % offset) import mailer msgbody = """Focused the Levy spectograph at %s Pacific local time. Found best focus (including offset) at DEWARFOCRAW=%d Change from previous focus = %4.0f FHWM = %4.3f pixels Max peak counts = %4.0f ADU\n """ % (datetime.strftime(datetime.now(), format="%Y-%m-%d %H:%M"), int(round(bestfoc)), int(round(offset)), np.min(yfit), bestflux) mailer.sendmail(msgbody, 'Levy Focus', toaddr=mailer.contacts.ucbgroup, attachments=['dewar_focus.png']) return int(round(bestfoc)) if __name__ == '__main__': APFTask.establish('focusinstr',os.getpid()) try: waitwrite(ucam['AUTOSHUT'], True) APFTask.set('focusinstr','PHASE','Configuring instrument for pinhole ThAr Focus') stagesetup(focuspos) APFTask.set('focusinstr','PHASE','Focus loop') focimages = focusloop() APFTask.set('focusinstr','PHASE','Finding Best Focus Value') bestfoc = findfoc(focimages) if abs(bestfoc - normfoc) < 2500: apflog("Setting dewar focus to %d" % bestfoc) # Disabled updating to best focus, use UCSC value instead apfmot['DEWARFOCRAW'].write(bestfoc) APFTask.set('focusinstr','LASTFOCUS',bestfoc) #pass else: apflog("ERROR: Best focus value (%d) is very far from nominal!" % bestfoc, level="error")
if opt.test: debug = True parent = 'example' apflog("Heimdallr starting in test mode.") else: debug = False parent = 'master' apftask = ktl.Service("apftask") # Establish this as the only running master script ( Or example task in test mode ) try: apflog("Attempting to establish apftask as %s" % parent) APFTask.establish(parent, os.getpid()) except Exception as e: print e apflog("Task is already running with name %s." % parent, echo=True) sys.exit("Couldn't establish APFTask %s" % parent) else: # Set up monitoring of the current master phase phase = apftask("%s_PHASE" % parent) phase.monitor() # Set preliminary signal and tripwire conditions apflog("Setting APFTask signal and tripwire.") APFTask.set(parent, "SIGNAL", "TERM") APFTask.set(parent, "TRIPWIRE", "TASK_ABORT") control = apftask[parent + '_CONTROL']
Change from previous focus = %4.0f FHWM = %4.3f pixels Max peak counts = %4.0f ADU\n """ % (datetime.strftime(datetime.now(), format="%Y-%m-%d %H:%M"), int(round(bestfoc)), int(round(offset)), np.min(yfit), bestflux) mailer.sendmail(msgbody, 'Levy Focus', toaddr=mailer.contacts.ucbgroup, attachments=['dewar_focus.png']) return int(round(bestfoc)) if __name__ == '__main__': APFTask.establish(parent, os.getpid()) try: waitwrite(ucam['AUTOSHUT'], True) APFTask.set('focusinstr', 'PHASE', 'Configuring instrument for pinhole ThAr Focus') stagesetup(focuspos) APFTask.set('focusinstr', 'PHASE', 'Focus loop') focimages = focusloop() if len(focimages) == 0: sys.exit() APFTask.set('focusinstr', 'PHASE', 'Finding Best Focus Value') bestfoc = findfoc(focimages) if abs(bestfoc - normfoc) < 2500: apflog("Setting dewar focus to %d" % bestfoc ) # Disabled updating to best focus, use UCSC value instead apfmot['DEWARFOCRAW'].write(bestfoc)
outdir=os.getcwd(), prilim=self.prilim, certificate=self.certificate) except Exception as e: apflog("Error: Cannot download %s: %s" % (self.too, e), level="error") self.reading = False self.stop() return if __name__ == "__main__": class Opt: pass task = 'example' APFTask.establish(task, os.getpid()) opt = Opt() opt.test = True opt.too = None opt.time_left = "/home/holden/time_left.csv" opt.rank_table = '2021B_ranks' opt.frac_table = '2021B_frac' opt.sheet = "RECUR_A100,2021B_A000,2021B_A001,2021B_A002,2021B_A003,2021B_A005,2021B_A006,2021B_A007,2021B_A008,2021B_A010,2021B_A011,2021B_A012,2021B_A013,2021B_A014".split( ",") get_targs = getUCOTargets(opt, task=task)
def run(self): APFTask.wait(self.task, True, timeout=self.wait_time) if self.signal: if self.debug: print("Would have downloaded %s" % (self.sheets)) else: try: star_table, stars = ParseUCOSched.parseUCOSched( sheetns=self.sheets, outfn='googledex.dat', outdir=os.getcwd(), prilim=self.prilim, certificate=self.certificate) except Exception as e: apflog("Error: Cannot download googledex?! %s" % (e), level="error") # goto backup if os.path.exists("googledex.dat.1"): shutil.copyfile("googledex.dat.1", "googledex.dat") if self.debug: print("Would have downloaded %s" % (self.rank_table)) else: try: rank_table = ds.makeRankTable( sheet_table_name=self.rank_table, outdir=os.getcwd(), certificate=self.certificate) except Exception as e: apflog("Error: Cannot download rank_table?! %s" % (e), level="error") # goto backup if os.path.exists("rank_table.1"): shutil.copyfile("rank_table.1", "rank_table") if self.time_left is None: hour_constraints = None else: if os.path.exists(self.time_left): try: hour_constraints = astropy.io.ascii.read( self.time_left) except Exception as e: hour_constraints = None apflog("Error: Cannot read file of time left %s : %s" % (opt.time_left, e)) else: hour_constraints = None if self.debug: print("Would have downloaded %s" % (self.frac_table)) else: try: hour_table = ds.makeHourTable( self.frac_table, datetime.now(), outdir=os.getcwd(), hour_constraints=hour_constraints, certificate=self.certificate) except Exception as e: apflog("Error: Cannot download frac_table?! %s" % (e), level="error") while self.signal and self.too is not None: if APFTask.waitfor(self.task, False, expression='apftask.SCRIPTOBS_PHASE==Observing', timeout=self.timeout): self.reading = True try: ParseUCOSched.parseTOO(too_sheetns=self.too, outfn='googledex.dat', outdir=os.getcwd(), prilim=self.prilim, certificate=self.certificate) except Exception as e: apflog("Error: Cannot download %s: %s" % (self.too, e), level="error") self.reading = False self.stop() return