def move_stage_to(self, xPos=None, yPos=None, test=False):
     """
     Move the microscope stage to the new position
     :param xPos: x coordinate of the new position in micrometers
     :param yPos: y coordinate of the new position in micrometers
     :return:
     """
     log.info("In function move_stage_to.")
     # Check if the positions are defined
     if xPos is None or yPos is None:
         raise HardwareError(
             "Error in moving stage to x,y position. Positions can't be None."
             " X = {}, Y = {}".format(xPos, yPos))
     # For testing return the path so it can be tested it is safe to move there
     if test:
         x_current, y_current = self.get_stage_pos()
         xy_path = [(x_current, y_current), (xPos, y_current), (xPos, yPos)]
         return xy_path
     try:
         # Turn the Async Mode on so it comes back to the software after moving and doesnt hang when live mode is on
         # and we want to move the stage
         self.Zen.GUI.Acquisition.Stage.PositionX.AsyncMode = "True"
         self.Zen.GUI.Acquisition.Stage.PositionX.Value = xPos
         self.Zen.GUI.Acquisition.Stage.PositionY.AsyncMode = "True"
         self.Zen.GUI.Acquisition.Stage.PositionY.Value = yPos
     except:
         raise HardwareError(
             "Error in moving stage to position (connectZenBlack.py).")
     return xPos, yPos
    def move_stage_to(self, xPos, yPos, test=False):
        '''Move stage to new position.
        
        Input:
         xPos, yPos: new stage position in micrometers.
         test: if True return travel path and do not move stage
         
        Return:
         xPos, yPos: x and y position of stage in micrometer after stage movement (if test = False)
         x_path, y_path: projected travel path (if test = True)
        '''
        if xPos is None or yPos is None:
            print('No xPos')
            raise HardwareError('Position not defined in move_stage_to.')

        if test:
            x_current = self.Zen.Devices.Stage.ActualPositionX
            y_current = self.Zen.Devices.Stage.ActualPositionY
            xy_path = [(x_current, y_current), (xPos, y_current), (xPos, yPos)]
            return xy_path

        try:
            self.Zen.Devices.Stage.TargetPositionX = xPos
            self.Zen.Devices.Stage.Apply()
            self.Zen.Devices.Stage.TargetPositionY = yPos
            self.Zen.Devices.Stage.Apply()
            # check new position
            xStage = self.Zen.Devices.Stage.ActualPositionX
            yStage = self.Zen.Devices.Stage.ActualPositionY
        except:
            raise HardwareError('Error in move_stage_to.')
        return xStage, yStage
 def get_all_objectives(self, nPositions):
     """
     Function to retrieve the name and magnification of all objectives
     uses self.get_objective_changer_object()
     WARNING: The objectives will move
     :param nPositions: Number of objective positions
     :return: objectives_dict = {'magnification': {'Position': position, 'name': name}}
     """
     try:
         # Get the objective changer object
         objective_changer = self.get_objective_changer_object()
         objectives_dict = {}
         for position in range(1, nPositions + 1):
             magnification = objective_changer.Magnification(position)
             name = objective_changer.Name(position)
             objectives_dict[magnification] = {
                 'Position': position,
                 'Name': name
             }
             objinfo = ''
             objinfo = objinfo + ' ' + format(position)
             objinfo = objinfo + '\t' + format(magnification)
             objinfo = objinfo + '\t' + name
             print objinfo
     except:
         raise HardwareError('Error in get_all_objectives.')
     return objectives_dict
    def get_all_objectives(self, nPositions):
        '''Retrieve name and magnification of all objectives.
        Warning! The objectives will move.
        
        Input:
         nPositions:  number of objective positions
         
        Output:
         objectivesDict: dictionary of all objectives mounted at microscope 
                         in form {'magnification': {'Position': position, 'Name': name}
        '''

        try:
            # retrieve ZEN ObjectiveChanger object
            objective_changer = self.Zen.Devices.ObjectiveChanger
            objectivesDict = {}

            for position in range(1, nPositions + 1):
                magnification = objective_changer.GetMagnificationByPosition(
                    position)
                name = objective_changer.GetNameByPosition(position)
                objectivesDict[magnification] = {
                    'Position': position,
                    'Name': name
                }
                objinfo = ''
                objinfo = objinfo + ' ' + format(position)
                objinfo = objinfo + '\t' + format(magnification)
                objinfo = objinfo + '\t' + name
                print objinfo
        except:
            raise HardwareError('Error in get_all_objectives.')
        return objectivesDict
 def store_focus(self):
     """
     Function to store actual focus position as offset from cover slip.
     Note (Important)- In Zen Blue: Stored focus position is lost when switching objective,
     even when returning to original objective.
     :return:  z: position of focus drive after store focus
     """
     log.info("In function store_focus.")
     # Check if correct objective was selected
     if self.get_objective_name() == '':
         self.set_autofocus_not_ready()
         raise AutofocusError(
             message='No objective selected to store autofocus position.')
     try:
         # There is no Async mode specifically for the CommandExecute object in Zen Black.
         # hence we turn it on globally and then turn it off right after
         self.Zen.GlobalAsyncMode = True
         self.Zen.CommandExecute("DefiniteFoc.DetermineFocus")
         z = self.get_focus_pos()
     except:
         raise HardwareError("Error in storing focus (connectZenBlack.py).")
     # The reason for turning it off right after is because we don't want to turn it on globally at all times.
     # for some commands, we want them to finish execution before handing the control back to our software
     self.Zen.GlobalAsyncMode = False
     # Get objective used to set Definite Focus
     # (Definite Focus will lose stored focus position after change of objective)
     self.DFObjective = self.get_objective_name()
     self.DFStoredFocus = z
     self.set_autofocus_ready()
     # Track absolute focus position for recovery in case of Definite Focus failure
     self.set_last_known_focus_position(z)
     return z
    def store_focus(self):
        '''Store actual focus position as offset from coverslip.
        
        Input:
         none
         
        Output:
         z: position of focus drive after store focus
         
        Stored focus position is lost when switching objective, even when returning to original objective.
        '''
        # check if correct objective was selected
        if self.get_objective_name() == '':
            self.set_autofocus_not_ready()
            raise AutofocusError(
                message='No objective selected to store autofocus position.')
        try:
            self.Zen.Acquisition.StoreFocus()
            z = self.Zen.Devices.Focus.ActualPosition
        except:
            raise HardwareError('Error in store_focus.')
        # Get objective used to set Definite Focus (Definite Focus will lose stored focus position after change of objective)
        self.DFObjective = self.get_objective_name()
        # Save stored position. We will use this position to move the objective to this position before recalling this positions
        # If the stored position is close to the find_surface position, Definite Focus works much faster.
        self.DFStoredFocus = z
        self.set_autofocus_ready()

        # track absolute focus position for recovery in case of Definite Focus failure
        self.set_last_known_focus_position(z)

        return z
    def recall_focus(self):
        '''Find stored focus position as offset from coverslip.
        
        Input:
         none
         
        Output:
         z: position of focus drive after recall focus
         
        Stored focus position is lost when switching objective, even when returning to original objective.
        '''
        # Zen.Acquisition.RecallFocus will fail if Zen cannot find a stored position.
        # This can happen if the objective was switched. After each objective switch a new focus position has to be stored within Zen.
        # We do not know a way to catch a failure directly (tired exception and time out)
        # Therefore we try to catch common indicators that RecallFocus will fail/failed

        # If autofocus is not ready raise exception
        self.get_autofocus_ready()
        # Is z position after RecallFocus the same
        try:
            # Move the objective to the stored focus position before recalling this positions
            # If the stored position is close to the find_surface position, Definite Focus works much faster.
            self.move_focus_to(self.DFStoredFocus)
            self.Zen.Acquisition.RecallFocus()
            # Store position, that will keep definite focus in optimal operational range
            print('From connectZenBlue.self.Zen.Devices.Focus: {}'.format(
                self.Zen.Devices.Focus))
            z = self.store_focus()
        except:
            raise HardwareError('Error in recall_focus.')
        # track absolute focus position for recovery in case of Definite Focus failure
        self.set_last_known_focus_position(z)
        return z
    def switch_objective(self, targetPosition):
        """
        Function to switch objective to the new target position
        uses self.get_objective_changer_object()
        :param targetPosition:  Position of new objective on objective switcher (0, 1, 2 .. n)
        :return:  objectiveName: name of new objective
        """
        log.info("In function switch_objective.")
        # Move focus drive to load position
        focus = self.get_focus_pos()
        self.move_focus_to_load()
        # Get name of original objective. We have to let autofocus know if we changed the objective
        original_objective_name = self.get_objective_name()
        try:
            self.Zen.GUI.Acquisition.AcquisitionMode.Objective.ByIndex = targetPosition
            # get name of new objective
            objective_name = self.get_objective_name()
        except:
            raise HardwareError(
                'Error in Switching Objectives (connectZenBlack.py).')

        # Move focus drive back to original position
        self.move_focus_to(focus)

        # check if objective was really changed
        if objective_name != original_objective_name:
            # Because objectives where changed the stored focus position for definite focus is no longer available
            self.set_autofocus_not_ready()
        return objective_name
    def trigger_pump(self, seconds, port='COM1', baudrate=19200):
        '''Trigger pump
        
        Input:
         seconds: the number of seconds pump is activated
         port: com port, default = 'COM1'
         baudrate: baudrate for connection, can be set on pump, typically = 19200
         
        Output:
         none
        '''
        try:
            # connect to pump through RS232
            pump = Braintree(port='COM1', baudrate=19200)

            #activate pump
            pump.start_pump()

            # continue pumping for seconds
            time.sleep(seconds)

            # stop pump and close connection
            pump.close_connection()
        except:
            raise HardwareError('Error in trigger_pump.')

        log.debug('Pump activated for : %s sec', seconds)
 def remove_all(self):
     """
     Function to remove all images within the Zen Black software window
     :return:
     """
     log.info("In function remove_all (images).")
     try:
         self.Zen.GUI.File.CloseAll.Execute()
     except:
         raise HardwareError(
             "Error in Removing all images (connectZenBlack.py).")
 def get_focus_pos(self):
     '''Return current position of focus drive.
     
     Return:
      zPos: position of focus drive in micrometer
     '''
     ## Get current stage position
     try:
         zPos = self.Zen.Devices.Focus.ActualPosition
     except:
         raise HardwareError('Error in get_focus_pos.')
     return zPos
 def save_image(self, fileName):
     '''save last acquired imageAICS in original file format using microscope software
     
     Input:
      file: file name and path for imageAICS save
     '''
     try:
         self.image.Save_2(fileName)
         log.info('save imageAICS to ' + fileName)
     except Exception as err:
         log.exception(err)
         raise HardwareError('Error in save_image to {}.'.format(fileName))
 def get_stage_pos(self):
     """
     Function to return the current position of the stage
     :return: x, y = stage coordinates in micrometers
     """
     log.info("In function get_stage_pos.")
     try:
         x = self.Zen.GUI.Acquisition.Stage.PositionX.Value
         y = self.Zen.GUI.Acquisition.Stage.PositionY.Value
     except:
         raise HardwareError(
             "Error in getting stage position (connectZenBlack.py).")
     return x, y
 def find_surface(self):
     """
     Function to fins cover slip using Definite Focus 2
     :return: z = Position of focus drive after finding the surface
     """
     log.info("In function find_surface (using DF2).")
     try:
         self.Zen.SetSelected("DefiniteFoc.FindFocus", True)
         z = self.get_focus_pos()
     except:
         raise HardwareError(
             "Error in finding surface using DF2 (connectZenBlack.py).")
     return z
 def get_stage_pos(self):
     '''Return current position of Microscope stage.
     
     Return:
      xPos, yPos: x and y position of stage in micrometer
     '''
     ## Get current stage position
     try:
         xPos = self.Zen.Devices.Stage.ActualPositionX
         yPos = self.Zen.Devices.Stage.ActualPositionY
     except:
         raise HardwareError('Error in get_stage_pos.')
     return xPos, yPos
 def get_focus_pos(self):
     """
     Function to return the current position of the focus drive
     :return: z: position of the focus drive
     """
     log.info("In function get_focus_pos.")
     try:
         z = self.Zen.GUI.Acquisition.ZStack.FocusPosition.Value
     except:
         raise HardwareError(
             'Error in Getting position of the focus drive (connectZenBlack.py).'
         )
     return z
 def get_objective_position(self):
     """
     Function to get the position of the imagine objective
     :return: position: position of actual objective, objective in imaging position
     """
     try:
         # Retrieve ZEN ObjectiveChanger object
         objective_changer = self.get_objective_changer_object()
         # Get position of objective
         position = objective_changer.RevolverPosition
     except:
         raise HardwareError('Error in get_objective_name.')
     return position
 def remove_all(self):
     '''Remove all images from display within ZEN software.
     
     Input:
      none
      
     Output:
      none
     '''
     try:
         self.Zen.Application.Documents.RemoveAll(True)
     except:
         raise HardwareError('Error in remove_all.')
 def save_image(self, fileName):
     """
     Function to save image at a specified file path
     :param fileName: file path (including the file name) as a string
     :return:
     """
     try:
         self.image.Save_2(fileName)
         log.info('Saved image to path: {}. '.format(fileName))
     except Exception as err:
         log.exception(err)
         raise HardwareError(
             'Error in saving image to path: {} in connectZenBlack.py.'.
             format(fileName))
 def show_image(self):
     '''Display last acquired image in ZEN software.
     
     Input:
      none
      
     Output:
      none
     '''
     try:
         if self.image is None:
             print 'No active image in ZEN Blue software'
         else:
             self.Zen.Application.Documents.Add(self.image)
     except:
         raise HardwareError('Error in show_image.')
 def live_mode_stop(self, experiment=None):
     """
     Function to stop live mode in the Acquisition tab
     :param experiment: Name of the experiment settings
     :return:
     """
     log.info("In function live_mode_stop.")
     if experiment is None:
         experiment = self.get_active_experiment()
     try:
         # Turn the Async Mode on so it doesnt wait on live mode stop to finish to continue with the software
         self.Zen.GUI.Acquisition.Live.AsyncMode = "True"
         self.Zen.SetSelected("Scan.IsFastScanning", False)
     except:
         raise HardwareError(
             "Error in Stopping Live Mode (connectZenBlack.py).")
 def z_relative_move(self, delta):
     '''Move focus relative to current position.
     
     Input:
      delta: distance in mum
     
     Output: 
      z: new position of focus drive
     '''
     try:
         zStart = self.Zen.Devices.Focus.ActualPosition
         zEndCalc = zStart + delta
         self.Zen.Devices.Focus.MoveTo(zEndCalc)
         z = self.Zen.Devices.Focus.ActualPosition
     except:
         raise HardwareError('Error in z_relative_move.')
     return z
 def z_relative_move(self, delta):
     """
     Function to move focus relative to the current position
     It finds current focus position using API call, calculates new position by adding delta to the old one,
     and moves focus to the new position using another Zen API call
     :param delta: distance in micrometers
     :return: z: Updated position of focus drive
     """
     try:
         zStart = self.get_focus_pos()
         zEndCalc = zStart + delta
         self.move_focus_to(zEndCalc)
         z = self.get_focus_pos()
     except:
         raise HardwareError(
             'Error in Relative movement of focus in the z direction (connectZenBlack.py).'
         )
     return z
 def move_focus_to(self, zPos):
     """
     Function to move the focus drive to the new position
     :param zPos: the z position in micrometers
     :return:
     """
     log.info("In function move_focus_to.")
     try:
         # Turn the Async Mode on so it comes back to the software after moving and doesnt hang when live mode is on
         # and we want to move the focus
         self.Zen.GUI.Acquisition.Zstack.FocusPosition.AsyncMode = "True"
         self.Zen.GUI.Acquisition.ZStack.FocusPosition.Value = zPos
         z_focus = self.get_focus_pos()
     except:
         raise HardwareError(
             'Error in Moving focus drive to a specified location (connectZenBlack.py).'
         )
     return z_focus
 def live_mode_stop(self, experiment=None):
     '''Stop live mode of ZEN software.
     
     Input: 
      experiment: name of ZEN experiment (default = None)
      
     Output:
      none
     '''
     try:
         if experiment:
             expClass = self.Zen.Acquisition.Experiments.GetByName(
                 experiment)
             self.Zen.Acquisition.StopLive_2(expClass)
         else:
             self.Zen.Acquisition.StopLive()
     except:
         raise HardwareError('Error in live_mode_stop.')
    def get_objective_position(self):
        '''Get position of actual objective.
        
        Input: 
         none
         
        Output: 
         position: position of actual objective, objective in imaging position
        '''
        try:
            # retrieve ZEN ObjectiveChanger object
            objRevolver = self.Zen.Devices.ObjectiveChanger

            # get name of objective
            position = objRevolver.ActualPosition
        except:
            raise HardwareError('Error in get_objective_name.')
        return position
    def get_objective_magnification(self):
        '''Get magnification of actual objective.
        
        Input: 
         none
         
        Output: 
         magnification: magnification of actual objective, objective in imaging position
        '''
        try:
            # retrieve ZEN ObjectiveChanger object
            objRevolver = self.Zen.Devices.ObjectiveChanger

            # get magnification
            magnification = objRevolver.Magnification
        except:
            raise HardwareError('Error in get_objective_magnification.')
        return magnification
 def recall_focus(self):
     """
     Function to find stored focus position as offset from cover slip.
     Note (Important)- In Zen Blue: Stored focus position is lost when switching objective,
     even when returning to original objective.
     :return: z: position of focus drive after recall focus
     """
     log.info("In function recall_focus.")
     # If autofocus is not ready, raise exception
     self.get_autofocus_ready()
     # Is z position after RecallFocus the same
     try:
         self.Zen.CommandExecute("DefiniteFoc.Stabilize")
         z = self.get_focus_pos()
     except:
         raise HardwareError('Error in Recalling DF2 (connectZenBlack.py).')
     # Track absolute focus position for recovery in case of Definite Focus failure
     self.set_last_known_focus_position(z)
     return z
    def snap_image(self, experiment=None):
        """
        Function to snap an image given acquisition parameters
        :param experiment: Name of the experiment settings
        :return:
        """
        log.info("In function snap_image.")
        current_objective = self.get_objective_name()
        try:
            if experiment is None:
                experiment = self.get_active_experiment()
            self.load_experiment(experiment)
            self.image = self.Zen.GUI.Acquisition.Snap.Execute()
        except:
            raise HardwareError("Error in Snap Image (connectZenBlack.py).")

        # set flag for definite focus if objective was changed
        if current_objective != self.get_objective_name(
        ) or self.get_objective_name() == '':
            self.set_autofocus_not_ready()
    def find_surface(self):
        '''Find cover slip using Definite Focus 2.
        
        Input:
         none
         
        Output: 
         z: position of focus drive after find surface
        '''
        # FindSurface always returns None
        # exception does not work
        try:
            self.Zen.Acquisition.FindSurface()
            z = self.Zen.Devices.Focus.ActualPosition
        except:
            raise HardwareError('Error in find_surface.')

        # Track absolute focus position for recovery in case of Definite Focus failure
        self.set_last_known_focus_position(z)
        return z