def displayRealImage(self, msg):
        path = msg
        # no abort then display the image
        if self.abort:
            # add a new deffered object
            d = self.protocol.addDeferred("realSent")
            d.addCallback(self.displayRealImage_thread)
            
            
            if(self.timer.IsRunning()):
                self.timer.Stop()
            
            self.parent.parent.parent.expGauge.SetValue(self.endTimer)
            

            # get stats
            data = als.getData(path)
            stats_list = als.calcStats(data)
            # change the gui with thread safety
            wx.CallAfter(self.safePlot, data, stats_list)

            self.parent.parent.parent.expGauge.SetValue(0) 
            self.startTimer = 0

            thread.start_new_thread(self.exposeTimer, (self.timeToSend,))
    def connectionMade(self):
        """
        Executes when conncetion is made to filter.
        """
        ## Add a callback that will open up the rest of the gui when the camera is done setting up
        #gui = self.factory.gui # get gui for adding the callback method
        #d = defer.Deferred()
        #d.addCallback(gui.onConnectCallback)
        #self._deferreds["status"] = d
        
        self.gui = self.factory.gui
        self.gui.takeImage.filterInstance.protocol2 = self

        logger.info("connection made to filter")

        filterInstance = self.gui.takeImage.filterInstance

        filterInstance.filterConnection = True
        #self.filterWatchThread = threading.Thread(target=filterInstance.filterWatch, args=())
        #self.filterWatchThread.daemon = True

        filterInstance.logFunction = filterInstance.logFilter
        logString = als.getLogString('filter connect', 'pre')
        filterInstance.log(filterInstance.logFunction, logString)

        logString = als.getLogString('filter getFilter', 'pre')
        filterInstance.log(filterInstance.logFunction, logString)

        d = self.sendCommand('getFilter')
        d.addCallback(filterInstance.getFilterCallback)
Example #3
0
    def __init__(self):
        wx.Frame.__init__(self,
                          parent=None,
                          title="Data Sender",
                          size=(500, 400))

        self.protocol = None

        # main sizers
        self.vertSizer = wx.BoxSizer(wx.VERTICAL)
        self.horzSizer = wx.BoxSizer(wx.HORIZONTAL)

        # Widgets
        self.statTxt = wx.StaticText(self, id=100, label="Command Prompt")
        self.enterTxt = wx.TextCtrl(self, id=101, size=(200, -1))
        self.btn = wx.Button(self, id=102, size=(100, -1), label="OK")

        self.vertSizer.Add(self.statTxt, flag=wx.ALIGN_CENTER)
        als.AddLinearSpacer(self.vertSizer, 10)
        self.vertSizer.Add(self.enterTxt, flag=wx.ALIGN_CENTER)
        als.AddLinearSpacer(self.vertSizer, 10)
        self.vertSizer.Add(self.btn, flag=wx.ALIGN_CENTER)

        self.Bind(wx.EVT_BUTTON, self.onButton, id=102)

        self.SetSizer(self.vertSizer)
        self.vertSizer.Fit(self)
    def onExpose(self, event):
        """
        Executes when the expose button is pressed. It checks that the variable
        self.exposeToSend is a float. It it passes then this value is sent to Evora.  If it
        fails a dialog box tells the user the varible is not a number and will not send it
        to Evora.
        """
        if als.isNumber(self.timeToSend):
            print float(self.timeToSend)
        else:
            dialog = wx.MessageDialog(None, "Exposure time not a number...will not expose.",
                                      "", wx.OK|wx.ICON_ERROR)
            dialog.ShowModal()

        if self.nameToSend is "":
            dialog = wx.MessageDialog(None,"No name was given...will not expose", "",
                                      wx.OK|wx.ICON_ERROR)
            dialog.ShowModal()
        else:
            print self.nameToSend

        if als.isNumber(self.timeToSend) and self.nameToSend is not "":
            self.protocol.sendLine("Exposing with name " + str(self.nameToSend) + " and time " + str(self.timeToSend) + " s")
            line = self.getAttributesToSend()
            self.protocol.sendLine(line)
    def displaySeriesImage(self, msg):
        msg = msg.split(",")
        
        imNum = int(msg[0])
        print type(imNum)
        time = float(msg[1])
        path = msg[2]
        print "Got:", msg
        # no abort then display the image
        if(self.abort and imNum <= int(self.seriesImageNumber)):
            print "Entered to display series image"
            # add a new deffered object
            d = self.protocol.addDeferred("seriesSent")
            d.addCallback(self.displaySeriesImage_thread)
            
            
            if(self.timer.IsRunning()):
                self.timer.Stop()
            
            self.parent.parent.parent.expGauge.SetValue(self.endTimer)
            

            # get stats
            data = als.getData(path)
            stats_list = als.calcStats(data)
            # change the gui with thread safety
            wx.CallAfter(self.safePlot, data, stats_list)

            self.parent.parent.parent.expGauge.SetValue(0) 
            self.startTimer = 0

            if(self.seriesImageNumber != None):
                if(imNum < int(self.seriesImageNumber)):
                    thread.start_new_thread(self.exposeTimer, (time,))
    def displayRealImage_callback(self, msg):
        path = msg # path to image (/tmp/image_date.fits)

        if(msg != "None"):
                        # get data
            data = als.getData(path)
            stats_list = als.calcStats(data)
            # change the gui with thread safety
            wx.CallAfter(self.safePlot, data, stats_list)
    def exposeCallback(self, msg):
        ### May need to thread to a different method if to slow
        results = msg.split(",")

        # immediatly reset button
        self.abort = False
        self.expButton.Enable(True)
        if(self.stopExp.IsEnabled()):
            self.stopExp.Enable(False)

        ## complete progress bar for image acquisition
        # check to see if timer is still going and stop it (callback might come in early)
        
        if(self.timer.IsRunning()):
            self.timer.Stop()
        
        # finish out gauge and then reset it
        self.parent.parent.parent.expGauge.SetValue(self.endTimer)

        
        # get success;
        success = int(results[0]) # 1 for true 0 for false
        #print success
 
        # at the end of the callback reset the gauge (signifies a reset for exposure)
        self.parent.parent.parent.expGauge.SetValue(0)
        self.startTimer = 0

        print self.parent.parent.parent.imageOpen
        print "opened window"

        if(success == 1):
            # get name of image and path
            filePath = results[1].split("/")
            name = filePath[-1].rstrip()
            path = ""
            for i in filePath[:-1]:
                path += i + "/"
            
            print path, name

            # get data
            data = als.getData(path+name)
            stats_list = als.calcStats(data)

            # change the gui with thread safety
            wx.CallAfter(self.safePlot, data, stats_list)
        else:
            print "Successfully Aborted"
            pass
    def onCool(self, event):
        if als.isNumber(self.tempToSend):
            if(float(self.tempToSend) >= -80.0 and float(self.tempToSend) <= -10.0):
                print float(self.tempToSend)
                if self.parent.exposureInstance.abort:
                    dialog = wx.MessageDialog(None, "Do you want to changing temperature during exposure?", "", wx.OK | wx.CANCEL|wx.ICON_QUESTION)
                    answer = dialog.ShowModal()
                    dialog.Destroy()

                    if answer == wx.ID_OK:
                        d = self.protocol.sendCommand("setTEC " + str(int(self.tempToSend)))
                        d.addCallback(self.cooling_callback)
                        if(not self.stopCool.IsEnabled()):
                            self.stopCool.Enable(True)
                else:
                    d = self.protocol.sendCommand("setTEC " + str(int(self.tempToSend)))
                    d.addCallback(self.cooling_callback)
                    if(not self.stopCool.IsEnabled()):
                        self.stopCool.Enable(True)
            else:
                dialog = wx.MessageDialog(None, "Temperature is not within the bounds.", "", wx.OK|wx.ICON_ERROR)
                dialog.ShowModal()
                dialog.Destroy()
        else:
            dialog = wx.MessageDialog(None, "Temperature specified is not a number.", "", wx.OK|wx.ICON_ERROR)
            dialog.ShowModal()
            dialog.Destroy()
 def onCool(self, event):
     if als.isNumber(self.tempToSend):
         print float(self.tempToSend)
         self.protocol.sendLine("temperature " + str(self.tempToSend))
     else:
         dialog = wx.MessageDialog(None, "Temperature specified is not a number.", "", wx.OK|wx.ICON_ERROR)
         dialog.ShowModal()
 def onOpen(self, event):
     """
     Opens when user selects to load an image.  Allows user to select a load a saved fits/fit image.
     """
     logger.info("Trying to open image")
     openFileDialog = wx.FileDialog(self, "Open Image File", "", "", "Image (*.fits;*.fit)|*.fits.*;*.fits;*.fit", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
     
     if openFileDialog.ShowModal() == wx.ID_CANCEL:
         return
     
     fileName = openFileDialog.GetFilename()
     fileName = fileName.split(".")
     
     if fileName[-1] in ["fits", "fit"]:
         data = als.getData(openFileDialog.GetPath())
         stats_list = als.calcStats(data)
         self.parent.takeImage.exposureInstance.safePlot(data, stats_list)
    def clientConnectionLost(self, transport, reason):
        """
        Executes when client has lost connection normally.
        """
        filterInstance = self.gui.takeImage.filterInstance
        filterInstance.logFunction = filterInstance.logFilter
        logString = als.getLogString("filter connectLost 1", 'post')
        filterInstance.log(filterInstance.logFunction, logString)

        logger.info("connection lost normally on port 5503")
    def clientConnectionFailed(self, transport, reason):
        """
        Called when client connection is lost unexpectedly.
        """
        exposureInstance = self.gui.takeImage.exposureInstance
        exposureInstance.logFunction = exposureInstance.logExposure
        logString = als.getLogString("connectFailed 1", 'post')
        exposureInstance.log(exposureInstance.logFunction, logString)

        logger.warning("connection to E. server failed on port 5502")
    def clientConnectionLost(self, transport, reason):
        """
        Called when client connection is lost normally.
        """
        exposureInstance = self.gui.takeImage.exposureInstance
        exposureInstance.logFunction = exposureInstance.logExposure
        logString = als.getLogString("connectLost 1", 'post')
        exposureInstance.log(exposureInstance.logFunction, logString)

        logger.info("connection to E. server lost normally on port 5502")
    def clientConnectionFailed(self, transport, reason):
        """
        Executes when client has lost connection unexpectedly.
        """
        filterInstance = self.gui.takeImage.filterInstance
        filterInstance.logFunction = filterInstance.logFilter
        logString = als.getLogString("filter connectFailed 1", 'post')
        filterInstance.log(filterInstance.logFunction, logString)

        logger.warning("connection failed on port 5503")
Example #15
0
 def threadSafeLogStatus(self, string):
     """ 
     Note: This should be called with with wx.CallAfter to update a GUI element.
     Pre: Takes in a string.
     Post: Displays that string in the log status box in the log tab of the gui.
     """
     msg = als.timeStamp() + " " + string
     val = self.logBox.GetValue()
     self.logBox.SetValue(val + msg + "\n")
     self.logBox.SetInsertionPointEnd()
    def callShutdown(self, msg):
        """
        When the camera sends it has shutdown successfully then this runs and locks down the GUI.
        """
        self.logFunction = self.logMain
        logString = als.getLogString("shutdown " + msg, 'post')
        self.logMethod(self.logFunction, logString)
        
        self.takeImage.tempInstance.isConnected = False

        bitmap = wx.StaticBitmap(self.stats, -1, size=(90, 17))
        self.stats.AddWidget(bitmap, pos=0, horizontalalignment=EnhancedStatusBar.ESB_ALIGN_RIGHT)
        self.stats.SetStatusText("Current Temp:            ... C", 0)

        self.joinThreads("temp", demonized=False)
        self.connection.disconnect()
        self.connected = False
        self.enableConnections(True, False, False)
    def callStartup(self, msg):
        """
        When connect is sent to the server and is done this will set the state of the GUI.
        """
        self.logFunction = self.logMain
        logString = als.getLogString('connect ' + msg, 'post')
        self.logMethod(self.logFunction, logString)

        result = int(msg)

        self.connected = True # boolean to tell if connected to server
        self.enableConnections(False, True, True) # grey and un-grey camera menu options
        self.disableButtons("connect", False) # enable gui functionality
        self.takeImage.tempInstance.isConnected = True # setups infinite loop in watchTemp method
        t = threading.Thread(target=self.takeImage.tempInstance.watchTemp, args=(), name="temp thread")
        t.daemon = True
        t.start()
        self.active_threads["temp"] = t

        logger.info("Started up from callStartup method")
    def onConnectCallback(self, msg):
        """
        When a connection is made successfully the server sends a status which goes throught this.
        If the camera status is uninitialized then it runs the startup routine else it sets the state
        of the GUI to connect..
        """
        #msg = args[0]
        #thread = args[1]

        logger.debug(msg + " Startup callback entered")
        self.connected = True

        # get the number of clients
        status = int(msg.split(",")[0])

        self.logFunction = self.logMain
        logString = als.getLogString('status ' + str(status), 'post')
        self.logMethod(self.logFunction, logString)

        logger.debug("status from connect callback: " + str(status))

        if(status == 20075):  # camera is uninitialized
            d = self.protocol.sendCommand("connect")
            d.addCallback(self.callStartup)
            
        elif(status == 20002):  # if camera is already initialized then start server like regular
            # start temperature thread
            t = threading.Thread(target=self.takeImage.tempInstance.watchTemp, args=(), name="temp thread")
            self.takeImage.tempInstance.isConnected = True # setups infinite loop in watchTemp method
            t.daemon = True
            
            # Enable disconnect and shutdown and disable connect menu items
            self.enableConnections(False, True, True)
            self.disableButtons("connect", False)

            t.start()
            self.active_threads["temp"] = t
            
        else: # camera drivers are broken needs reinstall?
            pass
Example #19
0
    def kseriesExposure(self, protocol, imType, itime, filter="", readTime=3, numexp=1, binning=1, numAccum=1, accumCycleTime=0, kCycleTime=0):
        """
        This handles multiple image acquisition using the camera kinetic series capability.  The basic arguements are
        the passed in protocol, the image type, integration time, filter type, readout index, number of exposures, and binning type.

        In the future this function could be modified to include accumulations or add time the kinetic cycle time.  Accumulations 
        are how many images should be readout as one, and kCycleTime can add time between each exposure that is taken.
        """
        global isAborted
        isAborted = False
        retval,width,height = andor.GetDetector()
        logger.debug('GetDetector: ' + str(retval) + " " + str(width) + " " + str(height))

        logger.debug("SetAcquisitionMode: " + str(andor.SetAcquisitionMode(3)))
        logger.debug('SetReadMode: ' + str(andor.SetReadMode(4)))

        logger.debug('SetImage: ' + str(andor.SetImage(binning,binning,1,width,1,height)))
        logger.debug('GetDetector (again): ' + str(andor.GetDetector()))

        if(imType == "bias"):
            itime = 0
            andor.SetShutter(1,2,0,0) # TLL mode high, shutter mode Permanently Closed, 0 millisec open/close
            logger.debug('SetExposureTime: ' + str(andor.SetExposureTime(0)))
        else:
            if(imType in ['flat', 'object']):
                andor.SetShutter(1,0,5,5)
            else:
                andor.SetShutter(1,2,0,0)
            logger.debug('SetExposureTime: ' + str(andor.SetExposureTime(itime))) # TLL mode high, shutter mode Fully Auto, 5 millisec open/close

        logger.debug("SetNumberOfAccumulations: " + str(andor.SetNumberAccumulations(numAccum))) # number of exposures to be combined
        logger.debug("SetAccumulationTime: " + str(andor.SetAccumulationCycleTime(accumCycleTime)))
        logger.debug("SetNumberOfKinetics: " + str(andor.SetNumberKinetics(numexp))) # this is the number of exposures the user wants
        logger.debug('SetKineticTime: ' + str(andor.SetKineticCycleTime(accumCycleTime)))
        logger.debug("SetTriggerMode: " + str(andor.SetTriggerMode(0)))

        logger.debug("Timings: " + str(andor.GetAcquisitionTimings()))

        logger.debug("SetHSSpeed: " + str(andor.SetHSSpeed(0, readTime)))  # default readTime is index 3 which is 0.5 MHz or ~6 sec

        # write headers
        attributes = [imType, binning, itime, filter]
        header = self.getHeader(attributes)

        logger.debug('StartAcquisition: ' + str(andor.StartAcquisition()))

        status = andor.GetStatus()
        logger.debug(str(status))

        imageAcquired = False

        counter = 1
        while(status[1] == andor.DRV_ACQUIRING):
            status = andor.GetStatus()
            progress = andor.GetAcquisitionProgress()

            runtime = 0
            if(progress[2] == counter or (not isAborted and progress[2] == 0 and imageAcquired)):
                runtime -= time.clock()
                data = np.zeros(width//binning*height//binning, dtype='uint16')  # reserve room for image
                results = andor.GetMostRecentImage16(data)  # store image data
                logger.debug(str(results) + " " + 'success={}'.format(results == 20002))  # print if the results were successful
                logger.debug('image number: ' + str(progress[2]))

                if(results == andor.DRV_SUCCESS):  # if the array filled store successfully
                    data=data.reshape(width//binning,height//binning)  # reshape into image
                    logger.debug(str(data.shape) + " " + str(data.dtype))
                    
                    hdu = fits.PrimaryHDU(data,do_not_scale_image_data=True,uint=True, header=header)
                    #filename = time.strftime('/data/forTCC/image_%Y%m%d_%H%M%S.fits') 
                    filename = als.getImagePath('series')
                    hdu.writeto(filename,clobber=True)

                    logger.debug("wrote: {}".format(filename))
                    
                    protocol.sendData("seriesSent"+str(counter)+" "+str(counter)+","+str(itime)+","+filename)
                    # make a new header and write time to it for new exposure.
                    header = self.getHeader(attributes)

                    if(counter == numexp):
                        logger.info("entered abort")
                        isAborted = True

                    imageAcquired = True
                    counter += 1
                runtime += time.clock()
                logger.debug("Took %f seconds to write." % runtime)
        return "series 1,"+str(counter) # exits with 1 for success
Example #20
0
    def realTimeExposure(self, protocol, imType, itime, binning=1):
        """
        Inputs are the Evora server protocol, the image type, the integration time, and the binning size.
        Runs camera in RunTillAbort mode.
        """
        #global acquired
        retval,width,height = andor.GetDetector()
        logger.debug('GetDetector: ' + str(retval) + " " + str(width) + " " + str(height))

        logger.debug("SetAcquisitionMode: " + str(andor.SetAcquisitionMode(5)))
        logger.debug('SetReadMode: ' + str(andor.SetReadMode(4)))

        logger.debug('SetImage: ' + str(andor.SetImage(binning,binning,1,width,1,height)))
        logger.debug('GetDetector (again): ' + str(andor.GetDetector()))

        logger.debug('SetExposureTime: ' + str(andor.SetExposureTime(itime)))
        logger.debug('SetKineticTime: ' + str(andor.SetKineticCycleTime(0)))


        if(imType == "bias"):
            andor.SetShutter(1,2,0,0) # TLL mode high, shutter mode Permanently Closed, 0 millisec open/close
            logger.debug('SetExposureTime: ' + str(andor.SetExposureTime(0)))
        else:
            if(imType in ['flat', 'object']):
                andor.SetShutter(1,0,5,5)
            else:
                andor.SetShutter(1,2,0,0)
            logger.debug('SetExposureTime: ' + str(andor.SetExposureTime(itime))) # TLL mode high, shutter mode Fully Auto, 5 millisec open/close
            
        data = np.zeros(width//binning*height//binning, dtype='uint16')
        logger.debug("SetHSSpeed: " + str(andor.SetHSSpeed(0, 1)))  # read time on real is fast because they aren't science images
        logger.debug('StartAcquisition: ' + str(andor.StartAcquisition()))

        
        status = andor.GetStatus()
        logger.debug(str(status))
        workingImNum = 1
        start = time.time()
        end = 0
        while(status[1]==andor.DRV_ACQUIRING):
           
            progress = andor.GetAcquisitionProgress()
            currImNum = progress[2] # won't update until an acquisition is done
            status = andor.GetStatus()

            if(status[1] == andor.DRV_ACQUIRING and currImNum == workingImNum):
                logger.debug("Progress: " + str(andor.GetAcquisitionProgress()))
                results = andor.GetMostRecentImage16(data) # store image data
                logger.debug(str(results) + 'success={}'.format(results == 20002)) # print if the results were successful
                
                if(results == andor.DRV_SUCCESS): # if the array filled store successfully
                    data=data.reshape(width//binning,height//binning) # reshape into image
                    logger.debug(str(data.shape) + " " + str(data.dtype))
                    hdu = fits.PrimaryHDU(data,do_not_scale_image_data=True,uint=True)
                    #filename = time.strftime('/tmp/image_%Y%m%d_%H%M%S.fits') 
                    filename = als.getImagePath('real')
                    hdu.writeto(filename,clobber=True)
                    logger.debug("wrote: {}".format(filename))
                    data = np.zeros(width//binning*height//binning, dtype='uint16')

                    protocol.sendData("realSent " + filename)
                    workingImNum += 1
                    end = time.time()
                    logger.debug("Took %f seconds" % (end-start))
                    start = time.time()

        return "real 1" # exits with 1 for success
Example #21
0
    def expose(self, imType=None, expnum=None, itime=2, binning=1, filter="", readTime=3):
        """
        expNum is deprecated and should be removed.
        This handles a single exposure and no more.  Inputs are the image type integration time, binning type
        filter type, as a string, and the index for the specified horizontal readout time.
        """
        if expnum is None:
            self.num += 1
            expnum = self.num
        else:
            self.num = expnum

        if imType is None: # if the image type is not specified it defaults to object
            imType = "object"

        retval, width, height = andor.GetDetector()
        logger.debug('GetDetector: ' + str(retval) + " " + str(width) + " " + str(height))
        # print 'SetImage:', andor.SetImage(1,1,1,width,1,height)
        logger.debug('SetReadMode: ' + str(andor.SetReadMode(4)))
        logger.debug('SetAcquisitionMode: ' + str(andor.SetAcquisitionMode(1)))
        logger.debug('SetImage: ' + str(andor.SetImage(binning,binning,1,width,1,height)))
        logger.debug('GetDetector (again): ' + str(andor.GetDetector()))

        if(imType == "bias"):
            andor.SetShutter(1,2,0,0) # TLL mode high, shutter mode Permanently Closed, 0 millisec open/close
            logger.debug('SetExposureTime: ' + str(andor.SetExposureTime(0)))
        else:
            if(imType in ['flat', 'object']):
                andor.SetShutter(1,0,5,5)
            else:
                andor.SetShutter(1,2,0,0)
            logger.debug('SetExposureTime: ' + str(andor.SetExposureTime(itime)))  # TLL mode high, shutter mode Fully Auto, 5 millisec open/close

        # set Readout speeds 0, 1, 2, or 3
        #print("SetVSSpeed:", andor.SetVSSpeed(3))
        logger.debug("SetHSSpeed: " + str(andor.SetHSSpeed(0, readTime)))  # default readTime is index 3 which is 0.5 MHz or ~6 sec

        results, expTime, accTime, kTime = andor.GetAcquisitionTimings()
        logger.debug("Adjusted Exposure Time: " + str([results, expTime, accTime, kTime]))

        attributes = [imType, binning, itime, filter]
        header = self.getHeader(attributes)

        logger.debug('StartAcquisition: ' + str(andor.StartAcquisition()))

        status = andor.GetStatus()
        logger.debug(str(status))
        while status[1] == andor.DRV_ACQUIRING:
            status = andor.GetStatus()

        data = np.zeros(width//binning*height//binning, dtype='uint16')
        logger.debug(str(data.shape))
        result = andor.GetAcquiredData16(data)

        success = None
        if(result == 20002):
            success = 1 # for true
        else:
            success = 0 # for false

        logger.debug(str(result) + 'success={}'.format(result == 20002))
        filename = None
        if success == 1:
            data=data.reshape(width//binning,height//binning)
            logger.debug(str(data.shape) + " " + str(data.dtype))
            hdu = fits.PrimaryHDU(data,do_not_scale_image_data=True,uint=True, header=header)
            #filename = time.strftime('/data/forTCC/image_%Y%m%d_%H%M%S.fits')
            filename = als.getImagePath('expose')
            hdu.writeto(filename,clobber=True)
            logger.debug("wrote: {}".format(filename))
        return "expose " + str(success) + ","+str(filename) + "," + str(itime)
Example #22
0
    def parseCommand(self, command):
        """
        This method parses the command inputed by the user from the command promp text control box.
        If the command is good it will return a list with the command that is sent to the server
        followed by the necessary arguments.  If the command is bad then a string is sent back that
        will be displayed to the user about what went wrong.  For any help commands this is delt with
        outside the parser.
        """
        scriptLine = command.split()
        print(scriptLine)

        command = None
        subcommand = None

        commandList = ["expose", "filter", "help", "set"]
        exposeSub = ["abort", "bias", "dark", "flat", "object", "help"]
        filterSub = ["home", "status", "help"]
        helpSub = ["expose", "filter", "set"]
        setSub = ["binning", "filter", "temp", "warmup", "help"]

        runList = []  # first entry is the command to send the next entries depend on the command being sent
        try:
            command = scriptLine[0]
            subcommand = scriptLine[1]
        except IndexError:
            return "ERROR: command and/or subcommand not given..."
        else:
            if command in commandList:

                # Possible commands (the order of time=X.X, basename=somename, and number=XX is ambiguous)
                # expose abort
                # expose bias basename=bias number=XX
                # expose dark time=X.X basename=dark number=XX
                # expose flat time=X.X basename=flat number=XX
                # expose object time=X.X basename=object number=XX
                # expose help abort
                # expose help bias
                # expose help dark
                # expose help flat
                # expose help object
                if command == "expose":

                    if subcommand in exposeSub:
                        if subcommand == "abort":
                            runList.append("abort")  # only command to send
                            return runList
                        elif subcommand == "bias":
                            print("exposing of this type")
                            try:
                                arg1 = scriptLine[2]
                                arg2 = scriptLine[3]
                            except IndexError:
                                return "ERROR: no basename or number arguements..."
                            else:
                                if len(scriptLine[0:]) > 4:
                                    return 'ERROR: too many arguments given in "expose bias"...'
                                arg1 = arg1.split("=")
                                arg2 = arg2.split("=")
                                argDict = {}
                                print(arg1, arg2)

                                if (len(arg1) == 2 and (arg1[0] in ["basename", "number"])) and (
                                    len(arg2) == 2 and (arg2[0] in ["basename", "number"])
                                ):
                                    # map arguements to be able to call them in order
                                    argDict[arg1[0]] = arg1[1]
                                    argDict[arg2[0]] = arg2[1]

                                    if als.isInt(argDict["number"]):
                                        if int(argDict["number"]) > 0:
                                            if argDict["basename"].strip() is not "":
                                                # final stop; everything has been checked so now we build up the list to return
                                                runList.append("series")
                                                runList.append(subcommand)
                                                runList.append(int(argDict["number"]))
                                                runList.append(argDict["basename"])
                                                print("The specified number of exposures is", float(argDict["number"]))
                                                return runList  # [series, bias, number, basename]
                                            else:
                                                return "ERROR: basename specified is empty..."
                                        else:
                                            return "ERROR: number of exposures needs to be above 0..."
                                    else:
                                        return "ERROR: specified number of exposures is not number..."
                                else:
                                    return "SyntaxError: basename or number of exposures is incorrectly specified..."

                        elif subcommand in ["dark", "flat", "object"]:
                            print("exposing of this type")
                            try:
                                arg1 = scriptLine[2]
                                arg2 = scriptLine[3]
                                arg3 = scriptLine[4]
                            except IndexError:
                                return "ERROR: no time, basename, and/or exposure number given..."
                            else:
                                if len(scriptLine[0:]) > 5:
                                    return 'ERROR: too many arugments given in "expose (dark/flat/object)"'

                                arg1 = arg1.split("=")
                                arg2 = arg2.split("=")
                                arg3 = arg3.split("=")
                                argDict = {}
                                print(arg1, arg2, arg3)
                                # Makes sure that when args are split by equals that there are two entries and that the first one is
                                # either time or basename.
                                if (
                                    (len(arg1) == 2 and (arg1[0] in ["time", "basename", "number"]))
                                    and (len(arg2) == 2 and (arg2[0] in ["time", "basename", "number"]))
                                    and (len(arg3) == 2 and (arg3[0] in ["time", "basename", "number"]))
                                ):
                                    # map arguments to be able to call them in order
                                    argDict[arg1[0]] = arg1[1]
                                    argDict[arg2[0]] = arg2[1]
                                    argDict[arg3[0]] = arg3[1]

                                    if als.isNumber(argDict["time"]) and als.isInt(argDict["number"]):
                                        # final stop; everything has been checked so now we build up the list to return
                                        if float(argDict["time"]) >= 0 or int(argDict["number"]) > 0:
                                            if argDict["basename"].strip() is not "":
                                                runList.append("series")
                                                runList.append(subcommand)
                                                runList.append(int(argDict["number"]))
                                                runList.append(float(argDict["time"]))
                                                runList.append(argDict["basename"])
                                                print("The specified time is", float(argDict["time"]))
                                                print("The specified number of exposures is", float(argDict["number"]))
                                                return runList  # [series, dark/flat/object, number, time, basename]
                                            else:
                                                return "ERROR: specified basename is empty..."
                                        else:
                                            return "ERROR: specified time is negative or the number of images is not 1 or more..."

                                    else:
                                        return "ERROR: specified time and/or number of exposures not a number..."
                                else:
                                    return (
                                        "SyntaxError: time argument, basename, and/or number of exposures is wrong..."
                                    )
                        else:
                            try:
                                helpArg = scriptLine[2]
                            except IndexError:
                                return 'ERROR: argument after "help" not given...'
                            else:
                                if len(scriptLine[0:]) > 3:
                                    return 'ERROR: too many arguments after "help"...'
                                runList.append(command)
                                runList.append(subcommand)
                                runList.append(helpArg)
                                return runList
                    else:
                        return "ERROR: not a recognized subcommand...", subcommand

                # possible commands (only one arg):
                # set binning (1 or 2)
                # set filter (1, 2, 3, 4, 5, or 6)
                # set temp (-80 to -10)
                # set help (binning, filter temp)
                if command == "set":

                    if subcommand in setSub:
                        try:
                            arg1 = scriptLine[2]
                        except IndexError:
                            return 'ERROR: didn\'t specify an argument after "subcommand"...'
                        else:
                            if len(scriptLine[0:]) > 3:
                                return "ERROR: there are too many arguments specified..."

                            if subcommand == "binning":
                                if als.isInt(arg1):
                                    if int(arg1) == 1 or int(arg1) == 2:

                                        runList.append(command)
                                        runList.append(subcommand)
                                        runList.append(arg1)
                                        return runList  # [set, binning, 1]
                                    else:
                                        return "ValueError: binning value is out of range, must be 1 or 2..."
                                else:
                                    return "SyntaxError: binning value is not an int..."
                            if subcommand == "temp":
                                if als.isInt(arg1):
                                    if int(arg1) >= -80 and int(arg1) <= -10:
                                        runList.append("setTEC")
                                        runList.append(arg1)
                                        return runList
                                    else:
                                        return "ValueError: temperature out of range of -80 to -10..."
                                elif arg1 == "warmup":
                                    runList.append("warmup")  # command for sending warmup
                                    return runList
                                else:
                                    return "SyntaxError: temperature is not a number..."
                            if subcommand == "filter":
                                if als.isInt(arg1):
                                    if int(arg1) >= 1 and int(arg1) <= 6:  # 6 filter positions: (1, 2, 3, 4, 5, 6)
                                        runList.append(command)
                                        runList.appedn(subcommand)
                                        runList.append(arg1)
                                        return runList
                                    else:
                                        return (
                                            "ValueError: filter position out of range, must specify int from 1 to 6..."
                                        )
                                else:
                                    return "SyntaxError: filter position given is not an int..."
                            if subcommand == "help":
                                if arg1 in ["binning", "temp"]:
                                    runList.append(command)
                                    runList.append(subcommand)
                                    runList.append(arg1)
                                    return runList
                                else:
                                    return 'ERROR: %s after "help" is not recognized...' % arg1
                    else:
                        return "ERROR: %s is not a recognized subcommand..." % subcommand

                # possible commands
                # filter home  # will slew filter to home
                # filter status # will give details on the state of connection
                # filter help (filter or home) # gives details on how to run the command and what it does
                if command == "filter":
                    if subcommand in filterSub:  # home, status, help

                        if subcommand == "home":
                            runList.append(command)
                            runList.append(subcommand)
                            return runList
                        if subcommand == "status":
                            runList.append(command)
                            runList.append(subcommand)
                            return runList
                        if subcommand == "help":
                            try:
                                arg1 = scriptLine[2]
                            except IndexError:
                                return 'ERROR: no argument after "filter help" specified...'
                            else:
                                if len(scriptLine[0:]) > 3:  # make sure there aren't anymore args given than needed
                                    return 'ERROR: extra argument after "help" given...'
                                if arg1 == "home":
                                    print("slews to filter")
                                if arg1 == "status":
                                    print("gives the status of the filter")
                                runList.append(command)
                                runList.append(subcommand)
                                runList.append(arg1)
                                return runList
                    else:
                        return "ERROR: %s is not a recognized subcommand..." % subcommand

                # possible commands
                # help expose
                # help set
                # help filter
                if command == "help":
                    if subcommand in helpSub:
                        runList.append(command)
                        runList.append(subcommand)
                        return runList
                    else:
                        return "ERROR: %s is not a recognized subcommand..." % subcommand
            else:
                return "ERROR: %s is not a recognized command..." % command
Example #23
0
    def executeCommand(self, runList):
        """
        This will take the known order of runList from the command and then send it to the server
        while also displaying pertanent information.  It will essentially be reusing methods,
        whenever possible from the acquisitionClasses.py file.
        Returns: Nothing is returned through this method.
        """

        val = self.parent.scriptStatus.activityText.GetValue()
        print(val)

        if type(runList) == list:
            self.parent.scriptStatus.activityText.SetValue(val + str(runList) + "\n")
            self.parent.scriptStatus.activityText.SetInsertionPointEnd()

            print(runList)
            print("sending command")

            # surround in str to get rid of unicode, otherwise fails at sending
            sendCommand = str(runList[0])
            if sendCommand == "series":
                imtype = str(runList[1])
                number = str(runList[2])

                exposeClass = self.parent.parent.parent.takeImage.exposureInstance
                exposeClass.seriesImageNumber = int(number)
                exposeClass.logFunction = (
                    self.logScript
                )  # point to the correct log function that prints to log tab and script status

                # example runList (['series', 'bias', int(number), 'basename'])
                if imtype == "bias":

                    basename = str(runList[3])
                    exposeClass.currentImage = basename
                    overwrite = None
                    if als.checkForFile("/data/copyfile/" + self.currentImage + "_001.fits"):
                        dialog = wx.MessageDialog(
                            None,
                            "Do you want to change temperature during exposure?",
                            "",
                            wx.OK | wx.CANCEL | wx.ICON_QUESTION,
                        )
                        overwrite = dialog.ShowModal()
                        dialog.Destroy()

                    if overwrite is not None or overwrite == wx.ID_OK:
                        d = self.protocol.addDeferred("seriesSent")
                        d.addCallback(exposeClass.displaySeriesImage_thread)

                        d = self.protocol.sendCommand(
                            sendCommand + " " + imtype + " " + number + " 0 " + str(self.parent.parent.parent.binning)
                        )
                        d.addCallback(exposeClass.seriesCallback)

                        # start timer
                        thread.start_new_thread(exposeClass.exposeTimer, (0,))

                if imtype in ["flat", "object", "dark"]:
                    exposeClass.expButton.Enable(False)
                    exposeClass.stopExp.Enable(True)
                    exposeClass.abort = True

                    itime = str(runList[3])
                    basename = str(runList[4])
                    exposeClass.currentImage = basename

                    overwrite = None
                    if als.checkForFile("/data/copyfile/" + self.currentImage + "_001.fits"):
                        dialog = wx.MessageDialog(
                            None,
                            "Do you want to change temperature during exposure?",
                            "",
                            wx.OK | wx.CANCEL | wx.ICON_QUESTION,
                        )
                        overwrite = dialog.ShowModal()
                        dialog.Destroy()

                    if overwrite is not None or overwrite == wx.ID_OK:
                        for i in range(int(number)):
                            d = self.protocol.addDeferred("seriesSent" + str(i + 1))
                            d.addCallback(exposeClass.displaySeriesImage_thread)

                        d = self.protocol.sendCommand(
                            sendCommand
                            + " "
                            + imtype
                            + " "
                            + number
                            + " "
                            + itime
                            + " "
                            + str(self.parent.parent.parent.binning)
                        )
                        d.addCallback(exposeClass.seriesCallback)
                        # start timer
                        thread.start_new_thread(exposeClass.exposeTimer, (float(itime),))

            if sendCommand == "abort":
                exposeClass = self.parent.parent.parent.takeImage.exposureInstance
                exposeClass.onStop(None)

            if sendCommand == "expose" and runList[1] == "help":
                # report on all the help options
                helpString = ""
                if runList[2] == "abort":
                    helpString += (
                        '"expose abort" is used to stop the current exposure.  This can be '
                        + "an exposure started through the imaging or scripting tab. Invoke with "
                        + '"expose abort".'
                    )
                if runList[2] == "bias":
                    helpString += (
                        '"expose bias" is used to take a number of biases in one command. Invoke this '
                        + 'command with "expose bias arg1 arg2", where arg1 and arg2, in no particular '
                        + "order, are time=XX in seconds and basename=imagename."
                    )
                if runList[2] == "dark":
                    helpString += (
                        '"expose dark" is used to take a number of darks in one command. Invoke this '
                        + 'command with "expose dark arg1 arg2 arg3", where arg1, arg2, and arg3, in no particular '
                        + "order, are time=XX in seconds, number=XX as an int, and basename=imagename."
                    )
                if runList[2] == "flat":
                    helpString += (
                        '"expose flat" is used to take a number of darks in one command. Invoke this '
                        + 'command with "expose flat arg1 arg2 arg3", where arg1, arg2, and arg3, in no particular '
                        + "order, are time=XX in seconds, number=XX as an int, and basename=imagename."
                    )
                if runList[2] == "object":
                    helpString += (
                        '"expose object" is used to take a number of darks in one command. Invoke this '
                        + 'command with "expose object arg1 arg2 arg3", where arg1, arg2, and arg3, in no particular '
                        + "order, are time=XX in seconds, number=XX as an int, and basename=imagename."
                    )
                self.sendToStatus(helpString)

            ### Deal with set commands
            # command: set temp XX
            if sendCommand == "setTEC":
                temp = int(runList[1])
                tempClass = self.parent.parent.parent.takeImage.tempInstance
                tempClass.tempToSend = temp
                tempClass.onCool(None)

            # command: set temp warmup
            if sendCommand == "warmup":
                tempClass = self.parent.parent.parent.takeImage.tempInstance
                tempClass.onStopCooling(None)

            # command: set filter X
            if sendCommand == "set":
                if runList[1] == "filter":
                    pos = int(runList[2])

            # command: set binning X
            if sendCommand == "set":
                if runList[1] == "binning":
                    topInstance = self.parent.parent.parent
                    bin = str(runList[2])
                    if bin == "1":
                        topInstance.on1x1(None)
                        file = topInstance.menuBar.GetMenu(0)
                        file.FindItemById(1120).Check(check=True)
                    else:
                        topInstance.on2x2(None)
                        file = topInstance.menuBar.GetMenu(0)
                        file.FindItemById(1121).Check(check=True)

            # command: set help binning
            #          set help temp
            #          set help filter
            if sendCommand == "set":
                if runList[1] == "help":
                    if runList[2] == "binning":
                        helpBinning = (
                            '"set binning" is used to set the binning type of the CCD. To invoke use the following '
                            + 'command: "set binning arg1", where arg1 is the binning type of 1 or 2.'
                        )
                        self.sendToStatus(helpBinning)
                    if runList[2] == "temp":
                        helpTemp = (
                            '"set temp" is used to set the temperature of the CCD. To invoke use the following '
                            + 'command: "set temp arg1", where arg1 is an int between -80 to -10 '
                            + "or warmup."
                        )
                        self.sendToStatus(helpTemp)
                    if runList[2] == "filter":
                        helpFilter = (
                            '"set filter" is used to set the filter wheel position. To invoke use the following '
                            + 'command: "set filter arg1", where arg1 is an int between 1 and 6.'
                        )
                        self.sendToStatus(helpFilter)
            # command: help expose
            #          help set
            #          help filter
            if sendCommand == "help":
                if runList[1] == "expose":
                    helpExpose = '"expose" command is explicitely for taking several images in one command. '
                    helpExpose += 'This is invoked by typing "expose imageType" where imageType is either '
                    helpExpose += 'bias, dark, flat, or object. Use "expose help" followed by image type to '
                    helpExpose += 'see what arguments are needed (e.g. "expose help bias").'
                    self.sendToStatus(helpExpose)

                if runList[1] == "set":
                    helpSet = '"set" command is used to set the camera attributes of binning, temperature, and '
                    helpSet += 'filter position.  Use "set help" followed by one of the attributes (binning, temp, '
                    helpSet += 'filter) to get info on the need arguements (e.g. "set help temp").'
                    self.sendToStatus(helpSet)
                if runList[1] == "filter":
                    helpFilter = '"filter" command is used to control the filter attributes.'
                    self.sendToStatus(helpFilter)
        else:
            print("something went wrong")
            print(runList)
            dialog = wx.MessageDialog(None, runList, "", wx.OK | wx.ICON_ERROR)
            dialog.ShowModal()
            dialog.Destroy()
        self.commandBox.SetFocus()
Example #24
0
 def sendToStatus(self, string):
     send = als.timeStamp()
     send += " " + string
     wx.CallAfter(self.threadSafeScriptingStatus, send)
    def onExpose(self, event):
        """
        Executes when the expose button is pressed. It checks that the variable
        self.exposeToSend is a float. It it passes then this value is sent to Evora.  If it
        fails a dialog box tells the user the varible is not a number and will not send it
        to Evora.
        """
        if als.isNumber(self.timeToSend):
            if(float(self.timeToSend) < 0):
                dialog = wx.MessageDialog(None, "Exposure time can not be less than 0...will not expose", "", wx.OK|wx.ICON_ERROR)
                dialog.ShowModal()
                dialog.Destroy()

        else:
            dialog = wx.MessageDialog(None, "Exposure time not a number...will not expose.",
                                      "", wx.OK|wx.ICON_ERROR)
            dialog.ShowModal()
            dialong.Destroy()

        if self.nameToSend is "":
            dialog = wx.MessageDialog(None,"No name was given...will not expose", "",
                                      wx.OK|wx.ICON_ERROR)
            dialog.ShowModal()
            dialog.Destroy()
        else:
            pass



        if als.isNumber(self.timeToSend) and self.nameToSend is not "":
            #self.protocol.sendLine("Exposing with name " + str(self.nameToSend) + " and time " + str(self.timeToSend) + " s")
            
            line = self.getAttributesToSend().split()
        
            # get image type 
            imType = int(line[0])
            itime = float(line[3])
        
            #self.expButton.SetLabel("Abort")
            if(imType == 1): # single exposure
                self.expButton.Enable(False)
                self.stopExp.Enable(True)
                self.abort = True
                line = " ".join(line[1:]) # bring all the parameters together
                d = self.protocol.sendCommand("expose " + line)
                d.addCallback(self.expose_callback_thread)
                thread.start_new_thread(self.exposeTimer, (itime,))

            if(imType == 2): # real time exposure
                self.expButton.Enable(False)
                self.stopExp.Enable(True)
                self.abort = True
                line = " ".join(line[1:])
                # start callback that looks for a path leading to a real image
                d = self.protocol.addDeferred("realSent")
                d.addCallback(self.displayRealImage_thread)

                d = self.protocol.sendCommand("real " + line)
                d.addCallback(self.realCallback) # this will clear the image path queue

                # start timer
                thread.start_new_thread(self.exposeTimer, (itime,))

            if(imType == 3): # series exposure
                dialog = wx.TextEntryDialog(None, "How many exposure?", "Entry", "1", wx.OK | wx.CANCEL)
                answer = dialog.ShowModal()
                dialog.Destroy()
                if answer == wx.ID_OK:
                    self.seriesImageNumber = dialog.GetValue()
                    if(als.isInt(self.seriesImageNumber)):
                        print "Number of image to be taken:", int(self.seriesImageNumber)
                        self.expButton.Enable(False)
                        self.stopExp.Enable(True)
                        self.abort = True

                        line[2] = self.seriesImageNumber
                        line = " ".join(line[1:])
                        
                        d = self.protocol.addDeferred("seriesSent")
                        d.addCallback(self.displaySeriesImage_thread)

                        d = self.protocol.sendCommand("series " + str(line))
                        d.addCallback(self.seriesCallback)
                        
                        # start timer
                        thread.start_new_thread(self.exposeTimer, (itime,))

                    else:
                        dialog = wx.MessageDialog(None, "Entry was not a valid integer!", "", wx.OK | wx.ICON_ERROR)
                        dialog.ShowModal()
                        dialog.Destroy()