class ThorPM100(ThorlabsPM100, Instrument):
    num_averages = DumbNotifiedProperty()

    def __init__(self,
                 address='USB0::0x1313::0x8072::P2004571::0::INSTR',
                 num_averages=100,
                 calibration=None):
        """A quick wrapper to create a gui and bring in nplab features to the pm100 thorlabs power meter """
        rm = visa.ResourceManager()
        instr = rm.open_resource(address)
        super(ThorPM100, self).__init__(instr)
        self.num_averages = 100
        self.ui = None
        if calibration == None:
            self.calibration = 1.0
        else:
            self.calibration = calibration

    def read_average(self, num_averages=None):
        """a quick averaging tool for the pm100 power meter """
        if num_averages == None:
            num_averages = self.num_averages
        values = []
        for i in range(num_averages):
            values.append(self.read)
        return np.average(values)

    def read_average_power(self):
        """Return the average power including a calibration """
        return self.read_average() * self.calibration

    average_power = NotifiedProperty(read_average_power)

    def update_power(self):
        """Update the power in the gui """
        self.ui.controls['Power'].setText(str(self.average_power))

    def get_qt_ui(self):
        if self.ui == None:
            self.ui = ThorlabsPM100_widget(self)
        return self.ui

    def set_wavelength(self, wavelength):
        self.power_meter.sense.correction.wavelength = wavelength

    def get_wavelength(self):
        return self.sense.correction.wavelength

    wavelength = NotifiedProperty(get_wavelength, set_wavelength)
Beispiel #2
0
class inspire_OPO(SerialInstrument):
    port_settings = dict(
        baudrate=9600,
        bytesize=serial.EIGHTBITS,
        parity=serial.PARITY_NONE,
        stopbits=serial.STOPBITS_ONE,
        timeout=1,  #wait at most one second for a response
        writeTimeout=1,  #similarly, fail if writing takes >1s
        xonxoff=False,
        rtscts=False,
        dsrdtr=False,
    )

    def __init__(self, port):
        self.mode = 'power'
        self.initialise()

    def initialise(self):
        self.write('00 550.0')

    def set_wavelength(self, wavelength):
        wavelength = str(int(wavelength)) + '.0'
        self.write(self.mode_dict[self.mode] + wavelength)

    def get_wavelength(self):
        wavelength = self.query('50 550.0')
        return wavelength

    wavelength = NotifiedProperty(get_wavelength, set_wavelength)

    def enable_power_mode(self):
        self.query(mode_dict['power'] + ' ' + self.wavelength)

    mode_dict = {'tune': '03', 'power': '04'}

    def SHG_on(self):
        self.query('08 000.0')

    def SHG_off(self):
        self.query('09 000.0')

    def SHG_find(self):
        self.query('10 000.0')

    def SHG_optimise(self):
        self.query('11 000.0')

    def auto_cavity(self):
        self.query('07 ' + self.wavelength)
Beispiel #3
0
class Maitai(SerialInstrument):
    port_settings = dict(
        baudrate=38400,
        bytesize=serial.EIGHTBITS,
        parity=serial.PARITY_NONE,
        stopbits=serial.STOPBITS_ONE,
        timeout=1,  #wait at most one second for a response
        writeTimeout=1,  #similarly, fail if writing takes >1s
        xonxoff=True,
        rtscts=False,
        dsrdtr=False,
    )
    termination_character = "\n"

    def __init__(self, port):
        '''Maitai Ti:saphire laser: just requires port number to inialise '''
        super(Maitai, self).__init__(port)
        self.set_watchdog(0)

    def on(self):
        '''Turn the Maitai on'''
        self.write('ON')

    def off(self):
        '''Turn the Maitai off'''
        self.write('OFF')

    def open_shutter(self):
        '''Opens the shutter using the shutter state property'''
        self.shutter_state = True

    def close_shutter(self):
        '''Close the shutter using the shutter state property '''
        self.shutter_state = False

    def get_shutter_state(self):
        '''Get shutter state and convert it to a bool
        returns:
            bool: True == open and False == close'''
        return bool(int(self.query('SHUTTER?')))

    def set_shutter_state(self, state):
        ''' Sets the shutter from a bool
        Args:
            bool True == Open, false == closed
        '''
        self.write('SHUTTER ' + str(int(state)))

    shutter_state = NotifiedProperty(get_shutter_state, set_shutter_state)

    def get_humidity(self):
        '''Returns the humidity '''
        return self.query('READ:HUM?')

    def get_power(self):
        '''Returns the IR power
        '''
        return self.query('READ:PLASER:POWER?')

    def get_current_wavelength(self):
        ''' The current real time wavelength - allowing you to check if the maitai ahs moved to the set wavelength yet
        '''
        return self.query('READ:WAVELENGTH?')

    current_wavelength = property(get_current_wavelength)

    def save(self):
        '''Save tje current maitai settings for restart '''
        self.write('SAVE')

    def get_set_wavelength(self):
        ''' wavelength(float):  The current set wavelength of the Maitai (in nm)
                                must between 690 and 1020
        '''
        return float(self.query('WAVELENGTH?')[:-2])

    def set_wavelength(self, wavelength):
        if wavelength > 690 and wavelength < 1020:
            return self.write('WAVELENGTH ')
        else:
            self.log('Wavelength out of range (' + wavelength + ')')

    wavelength = NotifiedProperty(get_set_wavelength, set_wavelength)

    def set_watchdog(self, n):
        '''Sets the watchdog timer i.e. the ammount of time the laser will 
        keep itself on without stay alive command. If set to zero this is disabled
        '''
        self.write('TIMER:WATCHDOG ' + str(n))

    def get_qt_ui(self):
        return MaitaiControlUI(self)
Beispiel #4
0
class Image_Filter_box(Instrument):
    threshold = DumbNotifiedProperty()
    bin_fac = DumbNotifiedProperty()
    min_size = DumbNotifiedProperty()
    max_size = DumbNotifiedProperty()
    bilat_height = DumbNotifiedProperty()
    bilat_size = DumbNotifiedProperty()
    morph_kernel_size = DumbNotifiedProperty()
    show_particles = DumbNotifiedProperty()
    return_original_with_particles = DumbNotifiedProperty()

    def __init__(self,
                 threshold=40,
                 bin_fac=4,
                 min_size=2,
                 max_size=6,
                 bilat_size=3,
                 bilat_height=40,
                 morph_kernel_size=3):
        self.threshold = threshold
        self.bin_fac = bin_fac
        self.min_size = min_size
        self.max_size = max_size
        self.bilat_size = bilat_size
        self.bilat_height = bilat_height
        self.morph_kernel_size = morph_kernel_size
        self.filter_options = [
            'None', 'STBOC_with_size_filter', 'strided_rescale',
            'StrBiThresOpen'
        ]
        self.show_particles = False
        self.return_original_with_particles = False
        self.current_filter_index = 0
        self.update_functions = []

    def current_filter(self, image):
        if self.current_filter_proxy == None:
            return image
        else:
            return self.current_filter_proxy(image)

    def set_current_filter_index(self, filter_index):
        filter_name = self.filter_options[filter_index]
        self._filter_index = filter_index
        if filter_name == 'None':
            self.current_filter_proxy = None
        else:
            self.current_filter_proxy = getattr(self, filter_name)
        self._current_filter_str = filter_name

    def get_current_filter_index(self):
        return self._filter_index

    current_filter_index = NotifiedProperty(fget=get_current_filter_index,
                                            fset=set_current_filter_index)

    def STBOC_with_size_filter(self, g, return_centers=False):
        try:
            return STBOC_with_size_filter(
                g,
                bin_fac=self.bin_fac,
                bilat_size=self.bilat_size,
                bilat_height=self.bilat_height,
                threshold=self.threshold,
                min_size=self.min_size,
                max_size=self.max_size,
                morph_kernel_size=self.morph_kernel_size,
                show_particles=self.show_particles,
                return_original_with_particles=self.
                return_original_with_particles,
                return_centers=return_centers)
        except Exception as e:
            self.log('Image processing has failed due to: ' + str(e),
                     level='WARN')

    def strided_rescale(self, g):
        try:
            return strided_rescale(g, bin_fac=self.bin_fac)
        except Exception as e:
            self.log('Image processing has failed due to: ' + str(e),
                     level='WARN')

    def StrBiThresOpen(self, g):
        try:
            return StrBiThresOpen(g,
                                  bin_fac=self.bin_fac,
                                  bilat_size=self.bilat_size,
                                  bilat_height=self.bilat_height,
                                  threshold=self.threshold,
                                  morph_kernel_size=self.morph_kernel_size)
        except Exception as e:
            self.log('Image processing has failed due to: ' + str(e),
                     level='WARN')

    def connect_function_to_property_changes(self, function):
        #    print function
        for variable_name in vars(self.__class__):
            self.update_functions.append(function)
            if (type(getattr(self.__class__,
                             variable_name)) == DumbNotifiedProperty
                    or type(getattr(self.__class__,
                                    variable_name)) == NotifiedProperty):

                register_for_property_changes(self, variable_name,
                                              self.update_functions[-1])

    def get_qt_ui(self):
        return Camera_filter_Control_ui(self)
Beispiel #5
0
class ThreadBox3000(QuickControlBox):
    '''A gui/threading utility for running a function in a thread with a simple control window '''
    def __init__(self, function=None):
        super(ThreadBox3000, self).__init__('ThreadBox3000')
        self.function = function

    def add_controls(self, function):
        '''Inspect the inputted function and automatically generate controls by looking the defaults '''
        full_args = inspect.getargspec(function)
        self.add_checkbox('save_returned')
        self.add_lineedit('function name')
        self.controls['function name'].setText(str(function))
        self.controls['function name'].setReadOnly(True)
        if 'self' in full_args.args:
            full_args.args.remove('self')
        if (full_args.defaults != None
                and len(full_args.args) == len(full_args.defaults)):
            for arg, default in zip(full_args.args, full_args.defaults):
                if type(default) == int:
                    self.add_spinbox(arg)
                    self.controls[arg].setValue(default)
                elif type(default) == float:
                    self.add_doublespinbox(arg)
                    self.controls[arg].setValue(default)
                elif type(default) == bool:
                    self.add_checkbox(arg)
                    self.controls[arg].setChecked(default)
                elif hasattr(default, '__call__'):
                    self.add_lineedit(arg)
                    try:
                        self.controls[arg].setText(default.func_name)
                    except Exception as e:
                        print e
                        self.controls[arg].setText(default.__name__)
                    self.controls[arg].setReadOnly(True)

                else:
                    self.add_lineedit(arg)
                    if type(default) == np.ndarray:

                        temp_txt = np.array2string(default).replace(
                            '   ',
                            ',')  # danger - might need to check formatter
                        temp_txt = temp_txt.replace('  ', ',')
                        temp_txt = temp_txt.replace(' ', ',')
                        temp_txt = temp_txt.replace('[,', '[')
                        temp_txt = temp_txt.replace(',]', ']')
                        txt = 'np.array(' + temp_txt + ')'
                    elif type(default) == str:
                        txt = "'" + default + "'"
                    else:
                        txt = str(default)
                    self.controls[arg].setText(txt)
        self.add_button('start')
        self.controls['start'].pressed.connect(self.start)

    def construct_payload(self):
        '''Construct the function with the arguments set in the control window '''
        def payload(save_group=df._current_group):
            import numpy as np
            input_variables = {}
            for variable in self.controls.keys():
                if variable == 'save_returned' or variable == 'start' or variable == 'function name':
                    continue

                variable_control = self.controls[variable]
                if type(variable_control) == type(QtWidgets.QLineEdit(
                )) and variable_control.isReadOnly() == True:
                    fullargs = inspect.getargspec(self.function)
                    args = fullargs.args
                    try:
                        args.remove('self')
                    except ValueError:
                        pass
                    args = np.array(args)
                    defaults = np.array(fullargs.defaults)
                    default_value = defaults[args == variable]
                    input_variables[variable] = default_value[0]
                    print variable, default_value
                elif (type(variable_control) == QtWidgets.QSpinBox
                      or type(variable_control) == QtWidgets.QDoubleSpinBox):
                    input_variables[variable] = variable_control.value()
                elif type(variable_control) == QtWidgets.QLineEdit:
                    try:
                        exec 'temp_var = ' + variable_control.text() in locals(
                        )
                        input_variables[variable] = temp_var

                    except Exception as e:
                        print e
                        print 'Qlineedit input error for ', variable
                elif type(variable_control) == QtWidgets.QCheckBox:
                    input_variables[variable] = variable_control.isChecked()
            try:
                function_returns = self.function(**input_variables)
            except TypeError:
                print input_variables
                print 'function: ', task
                print 'Did not recieve the correct inputs!'
                print 'did you make an error in your lineedit inputs?'
            if self.controls['save_returned'].isChecked() == True:
                save_group.create_dataset(task,
                                          data=function_returns,
                                          attrs=input_variables)

        return payload

    def clean_box(self):
        '''Remove all of the controls from the box '''
        if len(self.children()) > 1:  #check if the box contains any controls
            for child in self.children()[1:]:
                child.deleteLater()
            self.controls = dict()

    def set_function(self, function):
        '''Sets the function, by clearing the old function with 'clean_box' 
            and adding the controls for he new function '''
        self._function = function
        self.clean_box()
        if function is not None:
            self.add_controls(function)

    def get_function(self):
        '''The getter for the current function '''
        return self._function

    function = NotifiedProperty(fget=get_function, fset=set_function)

    @background_action
    @locked_action
    def start(self):
        '''Construct and start the function '''
        self.construct_payload()()

    def get_qt_ui(self):
        return self
Beispiel #6
0
class Frequency_counter_F390(SerialInstrument):
    port_settings = dict(baudrate=115200,
                         bytesize=serial.EIGHTBITS,
                         parity=serial.PARITY_NONE,
                         xonxoff=True,
                         timeout=1.0)
    termination_character = "\n"
    update_data_signal = QtCore.Signal(np.ndarray)

    def __init__(self, port=None, integration_time=1):
        SerialInstrument.__init__(self, port=port)
        self.live_window = 100
        self._live_view = False
        self.int_time = integration_time
        self.write('FO')  #do not apply low pass filter
        self.write('Z5')  #for 50 Ohms impedance

    function_dict = {
        '0': 'B Input Period',
        '1': 'A Input Period',
        '2': 'A Input Frequency',
        '3': 'B Input Frequency',
        '4': 'Frequency Ratio B:A',
        '5': 'A Input Width High',
        '6': 'A Input Width Low',
        '7': 'A Input Count',
        '8': 'A Input Ratio H:L',
        '9': 'A Input Duty Cycle',
        'C': 'C Input Frequency',
        'D': 'C Input Period'
    }

    def get_function(self):
        '''A property to set the required function of the frequency counter
        Args:
            f: the a string value of the function shown in the table below and in self.function_dict
            
            0 B Input Period
            1 A Input Period
            2 A Input Frequency
            3 B Input Frequency
            4 Frequency Ratio B:A
            5 A Input Width High
            6 A Input Width Low
            7 A Input Count
            8 A Input Ratio H:L
            9 A Input Duty Cycle
            C C Input Frequency
            D C Input Period
        returns:
            the current function
            '''
        return self.function_dict(self._function)

    def set_function(self, f):
        self._function = str(f)
        self.write('F' + str(f))

    function = property(fget=get_function, fset=set_function)

    def get_identity(self):
        '''Returns the device id (good for testing comms) '''
        return self.query('*IDN?')

    def test_communications(self):
        '''A command to allow autodetection to work '''
        if self.get_identity().split(',')[0] == 'Thurlby-Thandar':
            return True

    def measure_next(self):
        '''Return the next valid measurement'''
        try:
            return float(self.query('N?')[:-2])
        except:
            print(self.query('N?')[:-2])

    def measure_next_fast(self):
        '''Return the invalid measurement (i.e. refereshs at LCD refresh rate, not the measreument rate)'''
        try:
            return float(self.query('?')[:-2])
        except:
            print(self.query('?')[:-2])


#    def start_countinous_fast(self):
#        '''Starts fast streaming of values at the LCD refresh rate '''
#        self.write('C?')
#    def start_countinous_single(self):
#        '''Starts continuous streaming of values at the rate of the measurement time'''
#        self.write('E?')
#    def stop_countinous(self):
#        self.write('STOP')

    def get_live_view_window(self):
        return self._live_window

    def set_live_view_window(self, window_length):
        self._live_window = window_length
        '''Set the number of the stored values in the deque '''
        self.live_deque = deque(maxlen=window_length)

    live_window = NotifiedProperty(get_live_view_window, set_live_view_window)

    int_times = {0.3: '1', 1: '2', 10: '3', 100: '4'}
    impedances = {'50': 'Z5', '1M': 'Z1'}

    def get_int_time(self):
        '''A property for the integration time possible values are:
                0.3 s, 1s, 10s,100s '''
        return self._int_time

    def set_int_time(self, integration_time):
        self._int_time = integration_time
        try:
            self.write('M' + self.int_times[integration_time])
        except KeyError:
            self.log('Invalid integration time', level='WARN')

    int_time = NotifiedProperty(get_int_time, set_int_time)

    def get_qt_ui(self):
        self.ui = CounterUI(self)
        self.display_ui = self.ui.preview_widget
        self.control_ui = self.ui.control_widget
        return self.ui

    def get_preview_widget(self):
        self.display_ui = CounterPreviewWidget(self)
        return self.display_ui

    def get_control_widget(self):
        self.control_ui = CounterControlUI(self)
        return self.control_ui

    def _live_view_function(self):
        '''The function that is run within the live preview thread '''
        while self._live_view:
            data = None
            data = self.measure_next_fast()
            #     while data == None:
            time.sleep(self.int_time)
            self.live_deque.append([data, time.time()])
            self.display_ui.update_data_signal.emit(np.array(self.live_deque))

    def get_live_view(self):
        '''Setting up the notificed property
        live view to allow live view to be switch on and off '''
        return self._live_view

    def set_live_view(self, enabled):
        if enabled == True:
            try:
                self._live_view = True
                self._live_view_stop_event = threading.Event()
                self._live_view_thread = threading.Thread(
                    target=self._live_view_function)
                self._live_view_thread.start()
            except AttributeError as e:  #if any of the attributes aren't there
                print("Error:", e)
        else:
            if not self._live_view:
                return  # do nothing if it's not running.
            print("stopping live view thread")
            try:
                self._live_view = False
                self._live_view_stop_event.set()
                self._live_view_thread.join()
                del (self._live_view_stop_event, self._live_view_thread)
            except AttributeError:
                raise Exception(
                    "Tried to stop live view but it doesn't appear to be running!"
                )

    live_view = NotifiedProperty(get_live_view, set_live_view)
Beispiel #7
0
class Digikrom(SerialInstrument):
    port_settings = dict(
        baudrate=9600,
        bytesize=serial.EIGHTBITS,
        parity=serial.PARITY_NONE,
        stopbits=serial.STOPBITS_ONE,
        timeout=1,  #wait at most one second for a response
        writeTimeout=1,  #similarly, fail if writing takes >1s
        xonxoff=False,
        rtscts=False,
        dsrdtr=False,
    )

    def __init__(self, port=None, serial_number=[50, 52, 51, 49, 55]):
        self.termination_character = ''
        self.serial_number = serial_number
        super(Digikrom, self).__init__(port=port)

    def query(self,
              message,
              convert_to_hex=True,
              return_as_dec=True,
              max_len_returned=10,
              block=True):
        """The digikrom uses fixed length commands and has no termination character
        therefore the query function from serialinstrument needs to be overwritten.
        As the digikrom requires input in hex commands must be changed from decimal
        (as listed in the manual) to hex. The returned messages also need the same treatment
        The maximum length of the returned str can also be specified to maximise speed
        as currently it just waits for timeout"""
        if convert_to_hex == True:
            message_hex = self.encode_bytes(message)
        else:
            message_hex = message
        self.write(message_hex)
        returned_message = self.ser.read(max_len_returned)
        if return_as_dec == True:
            returned_message = self.decode_bytes(returned_message)

        if returned_message[-1] == 24:
            block = False
            self.set_status_byte(returned_message[-2])
        elif (returned_message != [message]):
            self.set_status_byte(returned_message[-1])
            while block == True:
                block_message = self.decode_bytes(self.ser.read_all())
                if len(block_message) == 1:
                    if block_message[0] == 24:
                        block = False
        return returned_message

    @staticmethod
    def decode_bytes(byte_str):
        """The digikrom uses decimal charcters therefore it is helpful to translate
        hex (returned from the digikrom) into a list of decimal values to prevent
        asci mishaps
        """
        decimal_list = []
        for byte in byte_str:
            decimal_list.append(ord(byte))
        return decimal_list

    @staticmethod
    def encode_bytes(decimal_list):
        """The digikrom uses decimal charcters but recieves hex therefore it is
        helpful to translate decimal values into hex to send to the digikrom
        """
        if type(decimal_list) != list:
            decimal_list = [decimal_list]
        byte_str = ''
        for decimal in decimal_list:
            byte = chr(decimal)
            byte_str += byte
        return byte_str

    def set_status_byte(self, status_byte):
        """Extract the status from the status byte """
        binary_byte = bin(status_byte)[2:]
        if len(binary_byte) != 8:
            binary_byte = (8 - len(binary_byte)) * '0' + binary_byte
        if binary_byte[0] == 1:
            motor_movement_order = 'negative'
        else:
            motor_movement_order = 'positive'
        if binary_byte[4] == 1:
            scan_direction = 'positive'
        else:
            scan_direction = 'negative'
        if binary_byte[7] == '0':
            value_accepted = True
            value_error = None
        else:
            value_accepted = False
            if binary_byte[6] == '1':
                value_error = 'repeat set'
            elif binary_byte[5] == '1':
                value_error = 'value too large'
            elif binary_byte[5] == '0':
                value_error = 'value too small'
        CSR_mode = bool(int(binary_byte[2]))
        status_dict = {
            'value_accepted': value_accepted,
            'value_error': value_error,
            'motor_movement_order': motor_movement_order,
            'scan_direction': scan_direction,
            'CSR_mode': CSR_mode
        }

        if value_accepted == True:
            level = 'debug'
        else:
            level = 'warn'
        self.log(status_dict, level=level)
        self._status_byte = status_dict

    def get_wavelength(self):
        """The get wavlength command number is 29 and data is returned as 3 bytes,
        the high byte, the mid byte and the low bye. These byte correspond to
        multiples of 65536, 256 and 1. as shown below"""
        returned_message = self.query(29)
        wl = returned_message[1] * 65536
        wl += 256 * returned_message[2]
        wl += returned_message[3]
        self.set_status_byte(returned_message[-2])
        return wl / 100.0

    def set_wavelength(self, wl):
        """The set wavlength command number is 16 and data is sent as 3 bytes,
        the high byte, the mid byte and the low bye. These byte correspond to
        multiples of 65536, 256 and 1. as shown below"""
        self.query(16, block=False)
        wl = wl * 100
        high_byte = int(old_div(wl, 65536))
        wl = wl - high_byte * 65536
        mid_byte = int(old_div(wl, 256))
        wl = wl - mid_byte * 256
        low_byte = int(wl)
        self.query([high_byte, mid_byte, low_byte])

    centre_wavlength = NotifiedProperty(get_wavelength, set_wavelength)

    def get_grating_id(self):
        info = self.query(19)
        info_dict = {
            'number_of_gratings': info[1],
            'current_grating': info[2],
            'grating_ruling': info[3] * 256 + info[4],
            'grating_blaze': info[5] * 256 + info[6]
        }
        return info_dict

    def set_grating(self, grating_number):
        """This command changes gratings , if additional gratings installed.."""
        self.query(26)
        self.query(grating_number)

    def reset(self):
        """This command returns the grating to home position """
        self.query([255, 255, 255])

    def clear(self):
        """This command restores factory calibration values for the grating and slits.
        This command also executes a reset, which returns the grating to home position."""
        self.query(25)

    def CSR(self, bandpass_value):
        """ This command sets monochromator to Constant Spectral Resolution mode.
        The slit width will vary throughout a scan. This is useful, for example,
        where measurement of a constant interval of frequency is desired
        (spectral power distribution measurements)."""
        self.query(28)
        high_byte = int(old_div(bandpass_value, 256))
        bandpass_value = bandpass_value - high_byte * 256
        low_byte = int(bandpass_value)
        self.query([high_byte, low_byte])

    def echo(self):
        """The ECHO command is used to verify communications with the DK240/480.
        """
        self.log(self.query(27), level='info')

    def gval(self, repositioning_wl):
        """This command allows recalibration of the monochromator positioning
        scale factor and should be used immediately after using the ZERO command
        (see page 15). The monochromator should be set to the peak of a known spectral line,
        then the position of that line is input using the CALIBRATE command.
        """
        self.query(18)
        repositioning_wl = repositioning_wl * 100
        high_byte = int(old_div(repositioning_wl, 65536))
        repositioning_wl = repositioning_wl - high_byte * 65536
        mid_byte = int(old_div(repositioning_wl, 256))
        repositioning_wl = repositioning_wl - mid_byte * 256
        low_byte = int(repositioning_wl)
        self.query([high_byte, mid_byte, low_byte])

    def get_serial(self):
        """ Returns the 5 digit serial number of the monochromator."""
        return self.query(33)[1:-2]

    def get_slit_widths(self):
        """Returns the current four byte (six byte for DK242) slit width.
        First two bytes are high and low byte of the entrance slit width in microns.
        Second two bytes are the high and low byte of the exit slit width.
        For DK242, the last two bytes are for middle slit width."""
        slit_info = self.query(30)[1:-2]
        slit_info = np.array(slit_info)
        low_byte = slit_info[1::2]
        high_byte = slit_info[::2]
        slit_info = 256 * high_byte + low_byte
        return slit_info

    def set_all_slits(self, slit_width):
        """ Adjusts all slits to a given width.
        """
        high_byte = int(old_div(slit_width, 256))
        slit_width = slit_width - high_byte * 256
        low_byte = int(slit_width)
        self.query(14)
        self.query([high_byte, low_byte])

    def set_slit_1_width(self, slit_width):
        """Adjusts entrance slit to a given width."""
        high_byte = int(old_div(slit_width, 256))
        slit_width = slit_width - high_byte * 256
        low_byte = int(slit_width)
        self.query(31)
        self.query([high_byte, low_byte])

    def set_slit_2_width(self, slit_width):
        """Adjusts exit slit to a given width."""
        """Slit 2 (exit) not installed 05042019"""
        high_byte = int(old_div(slit_width, 256))
        slit_width = slit_width - high_byte * 256
        low_byte = int(slit_width)
        self.query(32)
        self.query([high_byte, low_byte])

    def set_slit_3_width(self, slit_width):
        """Adjusts middle slit to a given width."""
        high_byte = int(old_div(slit_width, 256))
        slit_width = slit_width - high_byte * 256
        low_byte = int(slit_width)
        self.query(34)
        self.query([high_byte, low_byte])

    def test_communications(self):
        """Check there is the correct digikrom at other end of the COM port."""
        try:
            serial_num = self.get_serial()
        except:
            return False
        if serial_num == self.serial_number:
            return True
        else:
            return False
Beispiel #8
0
class Shamrock(Instrument):
    def __init__(self):
        super(Shamrock, self).__init__()
        #for Windows
        self.dll2 = CDLL(
            "C:\\Program Files\\Andor SOLIS\\Drivers\\Shamrock64\\atshamrock")
        self.dll = CDLL(
            "C:\\Program Files\\Andor SOLIS\\Drivers\\Shamrock64\\ShamrockCIF")

        tekst = c_char()
        error = self.dll.ShamrockInitialize(byref(tekst))

        self.current_shamrock = 0  #for more than one Shamrock this has to be varied, see ShamrockGetNumberDevices
        self.center_wavelength = 0.0

    def verbose(self, error, function=''):
        self.log("[%s]: %s" % (function, error), level='info')

    #basic Shamrock features
    def Initialize(self):
        error = self.dll.ShamrockInitialize("")
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)

    def GetNumberDevices(self):
        no_shamrocks = c_int()
        error = self.dll.ShamrockGetNumberDevices(byref(no_shamrocks))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return no_shamrocks.value

    num_shamrocks = property(GetNumberDevices)

    def Close(self):
        error = self.dll.ShamrockClose()
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)

    def GetSerialNumber(self):
        ShamrockSN = c_char()
        error = self.dll.ShamrockGetSerialNumber(self.current_shamrock,
                                                 byref(ShamrockSN))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return ShamrockSN

    serial_number = property(GetSerialNumber)

    def EepromGetOpticalParams(self):
        self.FocalLength = c_float()
        self.AngularDeviation = c_float()
        self.FocalTilt = c_float()
        error = self.dll.ShamrockEepromGetOpticalParams(
            self.current_shamrock, byref(self.FocalLength),
            byref(self.AngularDeviation), byref(self.FocalTilt))
        return {
            'FocalLength': self.FocalLength,
            'AngularDeviation': self.AngularDeviation,
            'FocalTilt': self.FocalTilt
        }

    #basic Grating features
    def GratingIsPresent(self):
        is_present = c_int()
        error = self.dll.ShamrockGratingIsPresent(self.current_shamrock,
                                                  is_present)
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return is_present.vlaue

    grating_present = property(GratingIsPresent)

    def GetTurret(self):
        Turret = c_int()
        error = self.dll.ShamrockGetTurret(self.current_shamrock,
                                           byref(Turret))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return Turret.value

    def SetTurret(self, turret):
        error = self.dll.ShamrockSetTurret(self.current_shamrock,
                                           c_int(turret))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)

    turret_position = NotifiedProperty(GetTurret, SetTurret)

    def GetNumberGratings(self):
        self.noGratings = c_int()
        error = self.dll.ShamrockGetNumberGratings(self.current_shamrock,
                                                   byref(self.noGratings))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return self.noGratings

    num_gratings = property(GetNumberGratings)

    def GetGrating(self):
        grating = c_int()
        error = self.dll.ShamrockGetGrating(self.current_shamrock,
                                            byref(grating))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return grating

    current_grating = property(GetGrating)

    def GetGratingInfo(self):
        lines = c_float()
        blaze = c_char()
        home = c_int()
        offset = c_int()
        error = self.dll.ShamrockGetGratingInfo(self.current_shamrock,
                                                self.current_grating,
                                                byref(lines), byref(blaze),
                                                byref(home), byref(offset))
        CurrGratingInfo = [lines.value, blaze.value, home.value, offset.value]
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return CurrGratingInfo

    GratingInfo = property(GetGratingInfo)

    def GetGratingOffset(self):
        GratingOffset = c_int()  #not this is in steps, so int
        error = self.dll.ShamrockGetGratingOffset(self.current_shamrock,
                                                  self.current_grating,
                                                  byref(GratingOffset))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return GratingOffset

    def SetGratingOffset(self, offset):
        error = self.dll.ShamrockSetGratingOffset(self.current_shamrock,
                                                  self.current_grating,
                                                  c_int(offset))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)

    Grating_offset = NotifiedProperty(GetGratingOffset, SetGratingOffset)

    def GetDetectorOffset(self):
        DetectorOffset = c_int()  #not this is in steps, so int
        error = self.dll.ShamrockGetDetectorOffset(self.current_shamrock,
                                                   byref(self.DetectorOffset))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return DetectorOffset

    def SetDetectorOffset(self, offset):
        error = self.dll.ShamrockSetDetectorOffset(self.current_shamrock,
                                                   self.current_grating,
                                                   c_int(offset))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)

    detector_offset = NotifiedProperty(GetDetectorOffset, SetDetectorOffset)

    #Wavelength features
    def WavelengthIsPresent(self):
        ispresent = c_int()
        error = self.dll.ShamrockWavelengthIsPresent(self.current_shamrock,
                                                     byref(ispresent))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return ispresent.value

    motor_present = property(WavelengthIsPresent)

    def GetWavelength(self):
        curr_wave = c_float()
        error = self.dll.ShamrockGetWavelength(self.current_shamrock,
                                               byref(curr_wave))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return curr_wave.value

    def SetWavelength(self, centre_wl):
        error = self.dll.ShamrockSetWavelength(self.current_shamrock,
                                               c_float(centre_wl))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)

    center_wavelength = NotifiedProperty(GetWavelength, SetWavelength)

    def AtZeroOrder(self):
        is_at_zero = c_int()
        error = self.dll.ShamrockAtZeroOrder(self.current_shamrock,
                                             byref(is_at_zero))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return is_at_zero.value

    wavelength_is_zero = property(AtZeroOrder)

    def GetWavelengthLimits(self):
        min_wl = c_float()
        max_wl = c_float()
        error = self.dll.ShamrockGetWavelengthLimits(self.current_shamrock,
                                                     self.current_grating,
                                                     byref(min_wl),
                                                     byref(max_wl))
        wl_limits = [min_wl.value, max_wl.value]
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return wl_limits

    wavelength_limits = property(GetWavelengthLimits)

    def GotoZeroOrder(self):
        error = self.dll.ShamrockGotoZeroOrder(self.current_shamrock)
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)

    #Slit functions
    def AutoSlitIsPresent(self):
        present = c_int()
        slits = []

        for i in range(1, 5):
            self.dll.ShamrockAutoSlitIsPresent(self.current_shamrock, i,
                                               present)
            slits.append(present.value)
        return slits

    Autoslits = property(AutoSlitIsPresent)

    #Sets the slit to the default value (10um)
    def AutoSlitReset(self, slit):
        error = self.dll.ShamrockAutoSlitReset(self.current_shamrock,
                                               self.current_slit)
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)

    #finds if input slit is present
    def SlitIsPresent(self):
        slit_present = c_int()
        error = self.dll.ShamrockSlitIsPresent(self.current_shamrock,
                                               byref(slit_present))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return slit_present.value

    slit_present = property(SlitIsPresent)

    #Output Slits
    def GetAutoSlitWidth(self, slit):
        slitw = c_float()
        error = self.dll.ShamrockGetAutoSlitWidth(self.current_shamrock, slit,
                                                  byref(slitw))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return slitw.value

    def SetAutoSlitWidth(self, slit, width):
        slit_w = c_float(width)
        error = self.dll.ShamrockSetAutoSlitWidth(self.current_shamrock, slit,
                                                  slit_w)
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return width

    #Input Slits
    def GetSlit(self):
        slitw = c_float()
        error = self.dll.ShamrockGetSlit(self.current_shamrock, byref(slitw))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return slitw.value

    def SetSlit(self, width):
        slit_w = c_float(width)
        error = self.dll.ShamrockSetSlit(self.current_shamrock, slit_w)
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)

    slit_width = NotifiedProperty(GetSlit, SetSlit)

    def SlitReset(self):
        error = self.dll.ShamrockSlitReset(self.current_shamrock)
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)

    #Calibration functions
    def SetPixelWidth(self, width):
        error = self.dll.ShamrockSetPixelWidth(self.current_shamrock,
                                               c_float(width))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)

    def GetPixelWidth(self):
        pixelw = c_float()
        error = self.dll.ShamrockGetPixelWidth(self.current_shamrock,
                                               byref(pixelw))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return pixelw.value

    pixel_width = NotifiedProperty(GetPixelWidth, SetPixelWidth)

    def GetNumberPixels(self):
        numpix = c_int()
        error = self.dll.ShamrockGetNumberPixels(self.current_shamrock,
                                                 byref(numpix))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return numpix.value

    def SetNumberPixels(self, pixels):
        error = self.dll.ShamrockSetNumberPixels(self.current_shamrock, pixels)
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)

    pixel_number = NotifiedProperty(GetNumberPixels, SetNumberPixels)

    def GetCalibration(self):
        ccalib = c_float * self.pixel_number
        ccalib_array = ccalib()
        error = self.dll.ShamrockGetCalibration(self.current_shamrock,
                                                pointer(ccalib_array),
                                                self.pixel_number)
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        calib = []
        for i in range(len(ccalib_array)):
            calib.append(ccalib_array[i])
        return calib[:]

    wl_calibration = property(GetCalibration)

    def GetPixelCalibrationCoefficients(self):
        ca = c_float()
        cb = c_float()
        cc = c_float()
        cd = c_float()
        error = self.dll.ShamrockGetPixelCalibrationCoefficients(
            self.current_shamrock, byref(ca), byref(cb), byref(cc), byref(cd))
        self.verbose(ERROR_CODE[error], sys._getframe().f_code.co_name)
        return [ca, cb, cc, cd]

    PixelCalibrationCoefficients = property(GetPixelCalibrationCoefficients)

    def get_qt_ui(self):
        return ShamrockControlUI(self)
Beispiel #9
0
class Arduino_tri_shutter(SerialInstrument):
    '''Control class for tri shutter '''
    def __init__(self, port=None):
        '''Set up baudrate etc and recenters the stage to the center of it's range (50um)
        
        Args:
            port(int/str):  The port the device is connected 
                            to in any of the accepted serial formats
            
        '''
        self.termination_character = '\n'
        self.port_settings = {
            'baudrate': 9600,
            #       'bytesize':serial.EIGHTBITS,
            'timeout': 2,  #wait at most one second for a response
        }
        self.termination_character = '\r\n'
        SerialInstrument.__init__(self, port=port)

    def set_shutter_1_state(self, state):
        """Set State Command for Shutter 1 used by check box """
        if state == True:
            self._open_shutter_1()
        elif state == False:
            self._close_shutter_1()

    def set_shutter_2_state(self, state):
        """Set State Command for Shutter 2 used by check box """
        if state == True:
            self._open_shutter_2()
        elif state == False:
            self._close_shutter_2()

    def set_mirror_1_state(self, state):
        """Set State Command for flipper 1 used by check box """
        if state == True:
            self._flip_mirror_0()
        elif state == False:
            self._flip_mirror_1()

    def open_shutter_1(self):
        """Usable open shutter 1 function that updates GUI when used"""
        self.Shutter_1_State = True

    def close_shutter_1(self):
        """Usable close shutter 1 function that updates GUI when used"""
        self.Shutter_1_State = False

    def open_shutter_2(self):
        """Usable open shutter 2 function that updates GUI when used"""
        self.Shutter_2_State = True

    def close_shutter_2(self):
        """Usable close shutter 2 function that updates GUI when used"""
        self.Shutter_2_State = False

    def flip_mirror_0(self):
        """Usable open flip_mirror 1  function that updates GUI when used"""
        self.Flipper_1_State = False

    def flip_mirror_1(self):
        """Usable close flip mirror 1 function that updates GUI when used"""
        self.Flipper_1_State = False

    def _open_shutter_1(self):
        """do not use! Hidden access to open shutter """
        self.query('A')

    def _close_shutter_1(self):
        """do not use! hidden close shutter function"""
        self.query('B')

    def _open_shutter_2(self):
        """do not use! Hidden access to open shutter """
        self.query('C')

    def _close_shutter_2(self):
        """do not use! hidden close shutter function"""
        self.query('D')

    def _flip_mirror_0(self):
        """do not use! hidden open flipper function"""
        self.query('E')

    def _flip_mirror_1(self):
        """do not use! hidden open flipper function"""
        self.query('F')

#   def get_state(self):
#       return self.query('Read')
#   def set_state(self,state):
#       self.query(state)

    def get_qt_ui(self):
        self.ui = tri_shutter_ui(self)
        return self.ui

    def read_state(self):
        states = self.query('S')
        states = states.split(',')
        states = [bool(int(state)) for state in states]
        return states

    states = NotifiedProperty(fget=read_state)

    def get_state_1(self):
        return self.states[0]

    def get_state_2(self):
        return self.states[1]

    def get_state_3(self):
        return self.states[2]

    Shutter_1_State = NotifiedProperty(fset=set_shutter_1_state,
                                       fget=get_state_1)
    Shutter_2_State = NotifiedProperty(fset=set_shutter_2_state,
                                       fget=get_state_2)
    Flipper_1_State = NotifiedProperty(fset=set_mirror_1_state,
                                       fget=get_state_3)
Beispiel #10
0
class Trandor(Andor):  #Andor
    ''' Wrapper class for the Triax and the andor
    '''
    def __init__(self, White_Shutter=None):

        # print '__________________'
        # print 'Triax Information:'

        super(Trandor, self).__init__()
        self.triax = Triax('GPIB0::1::INSTR', Calibration_Arrays,
                           CCD_Size)  #Initialise triax
        self.White_Shutter = White_Shutter
        self.SetParameter('SetTemperature', -90)  #Turn on andor cooler
        self.CoolerON()
        self.triax.ccd_size = CCD_Size

        # print '______________________'
        # print 'Current Grating:',self.triax.Grating()
        # print 'Current Slit Width:', self.triax.Slit(),'um'
        # print '______________________'
        self.Notch_Filters_Tested = True

    def Grating(self, Set_To=None):
        return self.triax.Grating(Set_To)

    def Generate_Wavelength_Axis(self):
        return self.triax.Get_Wavelength_Array()

    def Set_Center_Wavelength(self, wavelength):
        ''' backwards compatability with lab codes that use trandor.Set_Center_Wavelength'''
        self.triax.Set_Center_Wavelength(wavelength)

    def Test_Notch_Alignment(self):
        Accepted = False
        while Accepted is False:
            Input = eval(
                input(
                    'WARNING! A slight misalignment of the narrow band notch filters could be catastrophic! Has the laser thoughput been tested? [Yes/No]'
                ))
            if Input.upper() in ['Y', 'N', 'YES', 'NO']:
                Accepted = True
                if len(Input) > 1:
                    Input = Input.upper()[0]
        if Input.upper() == 'Y':
            print('You are now free to capture spectra')
            self.Notch_Filters_Tested = True
        else:
            print(
                'The next spectrum capture will be allowed for you to test this. Please LOWER the laser power and REDUCE the integration time.'
            )
            self.Notch_Filters_Tested = None

    def capture(self, Close_White_Shutter=True):
        """
        Edits the capture function is a white light shutter object is supplied, to ensure it is closed while the image is taken.
        This behaviour can be overwirtten by passing Close_White_Shutter=False
        """

        if self.Notch_Filters_Tested is False:
            self.Test_Notch_Alignment()
            return (np.array(list(range(CCD_Size))) * 0, 1, (CCD_Size, ))

        else:
            if self.Notch_Filters_Tested is None:
                self.Notch_Filters_Tested = False
            if self.White_Shutter is not None and Close_White_Shutter is True:
                try:
                    self.White_Shutter.close_shutter()
                except:
                    Dump = 1
                Output = Andor_Capture_Function(self)
                try:
                    self.White_Shutter.open_shutter()
                except:
                    Dump = 1
                return Output
            else:
                return Andor_Capture_Function(self)

    x_axis = NotifiedProperty(
        Generate_Wavelength_Axis)  #This is grabbed by the Andor code