Example #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)
Example #2
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
Example #3
0
        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
Example #4
0
    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
Example #5
0
    def updateLastObs(self,obsnum):
        """ If the last observation was a success, this function updates the file storing the last observation number and the hit_list which is required by the dynamic scheduler."""
        if obsnum['populated']:
            if self.ucam('OUTFILE').read() == 'ucsc':
                APFLib.write(self.robot["MASTER_LAST_OBS_UCSC"], obsnum)
#            else:
#                apflog("UCAM Observer name is not ucsc, so the lastObs value will not be updated.")
#                apflog("Number of last observation is %s" % self.obsnum.read())
        return
Example #6
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)
Example #7
0
def apflog(msg, level='Notice', echo=True):
    """Wraps the APF.log function. Messages are logged as 'master'."""

    APF.log(str(msg), level=level, echo=echo)
    
    if level in ['error']:
        subject = "[APF] An Error has occured"
        sendmail(subject, msg, to=['*****@*****.**'])
    if level in ['Crit', 'Alert', 'Emerg']:
        subject = "[APF] An Error has occured"
        sendmail(subject, msg, to=['*****@*****.**','*****@*****.**'])
Example #8
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", timout=1200)
     apflog("Killing Robot.")
     ripd, running = self.findRobot()
     if running:
         APFLib.write(self.robot['scriptobs_control'], "abort")
Example #9
0
def sendmail(subject, body, to=['*****@*****.**']):
    APF.log("Sending error message to" + str(to))
    
    me = "APF <*****@*****.**>"

    msg = MIMEMultipart()
    msg["Subject"] = subject
    msg["From"] = me
    msg["To"] = ', '.join(to)
    msg.attach(MIMEText(body))
    user_msg = "Script was being run by user %s" % getpass.getuser()
    msg.attach(MIMEText(user_msg))

    s = smtplib.SMTP('localhost')
    s.sendmail(me, to, msg.as_string())
    s.quit()
Example #10
0
def apflog(msg, level='Notice', echo=True):
    """Wraps the APF.log function. Messages are logged as 'master'."""

    APF.log(str(msg), level=level, echo=echo)

    if level in ['error']:
        subject = "[APF] An Error has occured"
        sendmail(subject, msg, to=['*****@*****.**'])
    if level in ['Crit', 'Alert', 'Emerg']:
        subject = "[APF] An Error has occured"
        sendmail(subject,
                 msg,
                 to=[
                     '*****@*****.**', '[email protected] ',
                     '*****@*****.**'
                 ])
Example #11
0
def sendmail(subject, body, to=['*****@*****.**']):
    APF.log("Sending error message to" + str(to))

    me = "APF <*****@*****.**>"

    msg = MIMEMultipart()
    msg["Subject"] = subject
    msg["From"] = me
    msg["To"] = ', '.join(to)
    msg.attach(MIMEText(body + "\n"))
    user_msg = "Script was being run by user %s" % getpass.getuser()
    msg.attach(MIMEText(user_msg))

    s = smtplib.SMTP('localhost')
    s.sendmail(me, to, msg.as_string())
    s.quit()
Example #12
0
    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
Example #13
0
 def updateWindshield(self, state):
     """Checks the current windshielding mode, and depending on the input and wind speed measurements makes sure it is set properly."""
     currState = self.robot["SCRIPTOBS_WINDSHIELD"].read().strip().lower()
     if state == 'on':
         if currState != 'enable':
             APFLib.write(self.robot["SCRIPTOBS_WINDSHIELD"], "Enable")
     elif state == 'off':
         if currState != 'disable':
             APFLib.write(self.robot["SCRIPTOBS_WINDSHIELD"], "Disable")
     else:
         # State must be auto, so check wind
         if currState == 'enable' and self.wvel <= WINDSHIELD_LIMIT:
             APFLib.write(self.robot["SCRIPTOBS_WINDSHIELD"], "Disable")
         if currState == 'disable' and self.wvel > WINDSHIELD_LIMIT:
             APFLib.write(self.robot["SCRIPTOBS_WINDSHIELD"], "Enable")
Example #14
0
    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)
Example #15
0
    # If a command line phase was specified, use that.
    if opt.phase != None:
        APFTask.phase(parent, opt.phase)
        phase.poll()
        
    # If the phase isn't a valid option, (say the watchdog was run last)
    # then assume we are starting a fresh night and start from setting the observer information.
    apflog("Phase at start is: %s" % phase, echo=True)
    if str(phase).strip() not in possible_phases:
        apflog("Starting phase is not valid. Phase being set to ObsInfo", echo=True)
        APFTask.phase(parent, "ObsInfo")

    # Make sure that the command line arguments are respected.
    # Regardless of phase, if a name, obsnum, or reset was commanded, make sure we perform these operations.
    apflog("Setting scriptobs_lines_done=0")
    APFLib.write(apf.robot["SCRIPTOBS_LINES_DONE"], 0)
    if opt.fixed:
        if not os.path.exists(opt.fixed):
            errmsg = "starlist %s does not exist" % (opt.fixed)
            apflog(errmsg,level="error",echo=True)
            sys.exit(errmsg)
        if not debug:
            APFTask.set(parent,"STARLIST",opt.fixed)
    else:
        if not debug:
            APFTask.set(parent,"STARLIST","")

    if str(phase).strip() != "ObsInfo":
        if opt.name:
            apflog("option -n specified. Setting UCAM Observer to %s." % opt.name)
            APFLib.write(apf.ucam["OBSERVER"], opt.name)
Example #16
0
    # If a command line phase was specified, use that.
    if opt.phase != None:
        APFTask.phase(parent, opt.phase)
        phase.poll()
        
    # If the phase isn't a valid option, (say the watchdog was run last)
    # then assume we are starting a fresh night and start from setting the observer information.
    apflog("Phase at start is: %s" % phase, echo=True)
    if str(phase).strip() not in possible_phases:
        apflog("Starting phase is not valid. Phase being set to ObsInfo", echo=True)
        APFTask.phase(parent, "ObsInfo")

    # Make sure that the command line arguments are respected.
    # Regardless of phase, if a name, obsnum, or reset was commanded, make sure we perform these operations.
    if opt.restart:
        APFLib.write(apf.robot["SCRIPTOBS_LINES_DONE"], 0)
    if str(phase).strip() != "ObsInfo":
        if opt.obsnum:
            APFLib.write(apf.ucam["OBSNUM"], int(opt.obsnum))

    # Start the actual operations
    # Goes through 5 steps:
    # 1) Set the observer information
    # 2) Run focuscube
    # 3) Run calibrate ucsc pre
    # 4) Start the main watcher
    # 5) Run calibrate ucsc post
    # Specifying a phase jumps straight to that point, and continues from there.


    # 1) Setting the observer information.
Example #17
0
    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
Example #18
0
                                   level='error')
                        else:
                            apflog("Error: Lost permission during opening",
                                   echo=True)

                # If we can open, try to set stuff up so the vent doors can be controlled by apfteq
                if not rising and not self.apf.isOpen()[0] and float(
                        cursunel) > SchedulerConsts.SUNEL_HOR:
                    APFTask.set(self.task,
                                suffix="MESSAGE",
                                value="Powering up for APFTeq",
                                wait=False)
                    if self.apf.clearestop():
                        try:
                            APFLib.write(self.apf.dome['AZENABLE'],
                                         'enable',
                                         timeout=10)
                        except:
                            apflog("Error: Cannot enable AZ drive",
                                   level="error")

                        self.apf.setTeqMode('Evening')
                        vent_open = "$eosdome.VD4STATE = VENT_OPENED"
                        result = APFTask.waitfor(self.task,
                                                 True,
                                                 expression=vent_open,
                                                 timeout=180)
                        if result:
                            try:
                                Apflib.write(self.apf.dome['AZENABLE'],
                                             'disable',
Example #19
0
    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
Example #20
0
        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
Example #21
0
        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
Example #22
0
 def DMReset(self):
     APFLib.write(self.checkapf['ROBOSTATE'], "master operating")
Example #23
0
    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)
Example #24
0
from __future__ import print_function

import getpass
import os
import smtplib

import ktl
import APF

from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

# Possible logging levels:
# 'Info' 'Notice' 'Warn' 'Error'

APF.logident("master")


def logpush(filename, keep=4):
    """Takes the filename, and gives it the extension filename.1
       If there is alread a filename.1, it will become filename.2
       This continues untill filename.4, which will be deleted if it exists."""
    # First check that the initial file exists
    try:
        open(filename, 'r')
    except IOError:
        apflog("logpush: File %s could not be located." % filename,
               level="warn",
               echo=True)
        return
    # Try removing the oldest logged file. (currently number 4)
Example #25
0
        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"]))
Example #26
0
from __future__ import print_function

import getpass
import os
import smtplib

import ktl
import APF

from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

# Possible logging levels:
# 'Info' 'Notice' 'Warn' 'Error'

APF.logident("master")


def logpush(filename, keep=4):
    """Takes the filename, and gives it the extension filename.1
       If there is alread a filename.1, it will become filename.2
       This continues untill filename.4, which will be deleted if it exists."""
    # First check that the initial file exists
    try:
        open(filename,'r')
    except IOError:
        apflog("logpush: File %s could not be located." % filename,level="warn",echo=True)
        return
    # Try removing the oldest logged file. (currently number 4)
    try:
        os.remove(filename + ".4")