Exemplo n.º 1
0
class ScriptDummy(Script):
    #This is the signal that will be emitted during the processing.
    #By including int as an argument, it lets the signal know to expect
    #an integer argument when emitting.
    # updateProgress = QtCore.Signal(int)

    _DEFAULT_SETTINGS = Parameter([
        Parameter('path', 'C:\Users\Experiment\Desktop\\tmp_data', str,
                  'path for data'),
        Parameter('tag', 'dummy_tag', str, 'tag for data'),
        Parameter('save', True, bool, 'save data on/off'),
        Parameter('count', 3, int),
        Parameter('name', 'this is a counter'),
        Parameter('wait_time', 0.1, float),
        Parameter('point2', [
            Parameter('x', 0.1, float, 'x-coordinate'),
            Parameter('y', 0.1, float, 'y-coordinate')
        ])
    ])

    _INSTRUMENTS = {}
    _SCRIPTS = {}

    def __init__(self, name=None, settings=None, log_output=None):
        """
        Example of a script
        Args:
            name (optional): name of script, if empty same as class name
            settings (optional): settings for this script, if empty same as default settings
        """
        Script.__init__(self, name, settings, log_output=log_output)

    def _function(self):
        """
        This is the actual function that will be executed. It uses only information that is provided in the settings property
        will be overwritten in the __init__
        """

        # some generic function
        import time
        import random

        count = self.settings['count']
        name = self.settings['name']
        wait_time = self.settings['wait_time']

        data = []
        self.log(
            'I am a test function counting to {:d} and creating random values'.
            format(count))
        for i in range(count):
            time.sleep(wait_time)
            self.log('count {:02d}'.format(i))
            data.append(random.random())

        self.data = {'random data': data}

        if self.settings['save']:
            self.save()
Exemplo n.º 2
0
 def _parameters_default(self):
     '''
     returns the default parameter_list of the instrument
     :return:
     '''
     parameters_default = Parameter([
         Parameter('port', 'COM5', ['COM5', 'COM3'], 'com port to which maestro controler is connected')
     ])
     return parameters_default
Exemplo n.º 3
0
    def parameters_default(self):
        '''
        returns the default parameter_list of the instrument
        :return:
        '''

        parameter_list_default = [
            Parameter('start', 1.8e6, (float, int), 'start value of sweep'),
            Parameter('stop', 1.9e6, (float, int), 'end value of sweep'),
            Parameter('samplecount', 101, int, 'number of data points'),
            Parameter('gridnode', 'oscs/0/freq',
                      ['oscs/0/freq', 'oscs/1/freq'], 'start value of sweep'),
            Parameter('xmapping', 0, [0, 1],
                      'mapping 0 = linear, 1 = logarithmic'),
            Parameter('bandwidthcontrol', 2, [2],
                      '2 = automatic bandwidth control'),
            Parameter(
                'scan', 0, [0, 1, 2],
                'scan direction 0 = sequential, 1 = binary (non-sequential, each point once), 2 = bidirecctional (forward then reverse)'
            ),
            Parameter('loopcount', 1, int, 'number of times it sweeps'),
            Parameter('averaging/sample', 1, int,
                      'number of samples to average over')
        ]
        return parameter_list_default
Exemplo n.º 4
0
 def _settings_default(self):
     '''
     returns the default settings of the script
     settings contain Parameters, Instruments and Scripts
     :return:
     '''
     settings_default = Parameter([
         Parameter('parameter', 1),
         Parameter('file_path', './some/path'),
         Parameter('instrument', Instrument())
     ])
     return settings_default
Exemplo n.º 5
0
 def _parameters_default(self):
     '''
     returns the default parameter_list of the instrument this function should be over written in any subclass
     '''
     parameters_default = Parameter([
         Parameter('test1', 0, int, 'test parameter (int)'),
         Parameter('test2', [
             Parameter('test2_1', 'string', str, 'test parameter (str)'),
             Parameter('test2_2', 0.0, float, 'test parameter (float)')
         ])
     ])
     return parameters_default
Exemplo n.º 6
0
class ScriptDummyWithQtSignal(Script, QThread):
    # NOTE THAT THE ORDER OF Script and QThread IS IMPORTANT!!
    _DEFAULT_SETTINGS = Parameter([
        Parameter('count', 10, int),
        Parameter('name', 'this is a counter'),
        Parameter('wait_time', 0.1, float)
    ])

    _INSTRUMENTS = {}
    _SCRIPTS = {}

    #This is the signal that will be emitted during the processing.
    #By including int as an argument, it lets the signal know to expect
    #an integer argument when emitting.
    updateProgress = Signal(int)

    def __init__(self, name=None, settings=None, log_output=None):
        """
        Example of a script that emits a QT signal for the gui
        Args:
            name (optional): name of script, if empty same as class name
            settings (optional): settings for this script, if empty same as default settings
        """
        Script.__init__(self, name, settings, log_output=log_output)
        # QtCore.QThread.__init__(self)
        QThread.__init__(self)

    def _function(self):
        """
        This is the actual function that will be executed. It uses only information that is provided in the settings property
        will be overwritten in the __init__
        """

        # some generic function
        import time
        import random

        count = self.settings['count']
        name = self.settings['name']
        wait_time = self.settings['wait_time']

        self.log('I am a test function counting to {:d}...'.format(count))

        data = []
        for i in range(count):
            time.sleep(wait_time)
            progress = int(100 * (i + 1) / count)
            self.updateProgress.emit(progress)

            data.append(random.random())

        self.data = {'random data': data}
Exemplo n.º 7
0
    def parameters_default(self):
        """
        returns the default parameter_list of the instrument
        :return:
        """

        possible_com_ports = ['COM' + str(i) for i in range(0, 256)]
        parameter_list_default = [
            Parameter('port', 'COM4', possible_com_ports, 'com port to which the gauge controller is connected'),
            Parameter('timeout', 1.0, float, 'amount of time to wait for a response from the gauge controller for each query'),
            Parameter('baudrate', 9600, int, 'baudrate of serial communication with gauge')
        ]

        return parameter_list_default
Exemplo n.º 8
0
class NI7845RReadAnalogIO(Instrument):

    import src.labview_fpga_lib.read_ai_ao.read_ai_ao as FPGAlib

    _DEFAULT_SETTINGS = Parameter([
        Parameter('AO0', 0.0, float, 'analog output channel 0 in volt'),
        Parameter('AO1', 0.0, float, 'analog output channel 1 in volt'),
        Parameter('AO2', 0.0, float, 'analog output channel 2 in volt'),
        Parameter('AO3', 0.0, float, 'analog output channel 3 in volt'),
        Parameter('AO4', 0.0, float, 'analog output channel 4 in volt'),
        Parameter('AO5', 0.0, float, 'analog output channel 5 in volt'),
        Parameter('AO6', 0.0, float, 'analog output channel 6 in volt'),
        Parameter('AO7', 0.0, float, 'analog output channel 7 in volt')
    ])

    _PROBES = {
        'AI0': 'analog input channel 0 in bit',
        'AI1': 'analog input channel 1 in bit',
        'AI2': 'analog input channel 2 in bit',
        'AI3': 'analog input channel 3 in bit',
        'AI4': 'analog input channel 4 in bit',
        'AI5': 'analog input channel 5 in bit',
        'AI6': 'analog input channel 6 in bit',
        'AI7': 'analog input channel 7 in bit'
    }

    def __init__(self, name=None, settings=None):
        super(NI7845RReadAnalogIO, self).__init__(name, settings)

        # start fpga
        self.fpga = self.FPGAlib.NI7845R()
        self.fpga.start()
        self.update(self.settings)

    def __del__(self):
        self.fpga.stop()

    def read_probes(self, key):
        assert key in self._PROBES.keys(), "key assertion failed %s" % str(key)
        value = getattr(self.FPGAlib,
                        'read_{:s}'.format(key))(self.fpga.session,
                                                 self.fpga.status)
        return value

    def update(self, settings):
        super(NI7845RReadAnalogIO, self).update(settings)

        for key, value in settings.iteritems():
            if key in ['AO0', 'AO1', 'AO2', 'AO3', 'AO4', 'AO5', 'AO6', 'AO7']:
                print('SGL_to_U32(value)', volt_2_bit(value))
                getattr(self.FPGAlib,
                        'set_{:s}'.format(key))(volt_2_bit(value),
                                                self.fpga.session,
                                                self.fpga.status)
Exemplo n.º 9
0
    def Ttest_QString(self):
        from PyQt4 import QtCore
        test = Instrument()

        test.update_parameters(
            Parameter('test1', QtCore.QString(unicode('10'))))

        test.update_parameters({'test1': QtCore.QString(unicode('10'))})
Exemplo n.º 10
0
 def Ttest_dynamic_setter(self):
     test = Instrument()
     new_val = 30
     #test.test1 = 30
     test.update_parameters(Parameter('test1', 30))
     if get_elemet('test1', test.parameters).value != test.test1:
         #print(test.parameters)
         self.fail('setter function doesn\'t work')
Exemplo n.º 11
0
class ScriptDummyWithInstrument(Script):

    _DEFAULT_SETTINGS = Parameter([
        Parameter('count', 0, int),
        Parameter('name', 'this is a counter'),
        Parameter('wait_time', 0.1, float)
    ])

    _INSTRUMENTS = {'dummy_instrument': DummyInstrument}
    _SCRIPTS = {}

    def __init__(self, instruments, name=None, settings=None, log_output=None):
        """
        Example of a script that makes use of an instrument
        Args:
            instruments: instruments the script will make use of
            name (optional): name of script, if empty same as class name
            settings (optional): settings for this script, if empty same as default settings
        """

        # call init of superclass
        Script.__init__(self,
                        name,
                        settings,
                        instruments,
                        log_output=log_output)

    def _function(self):
        """
        This is the actual function that will be executed. It uses only information that is provided in _DEFAULT_SETTINGS
        for this dummy example we just implement a counter
        """

        import time

        count = self.settings['count']
        name = self.settings['name']
        wait_time = self.settings['wait_time']

        self.log('I am a test function counting to {:d}...'.format(count))
        for i in range(count):

            self.log('signal from dummy instrument {:s}: {:0.3f}'.format(
                name, self.instruments['dummy_instrument'].value1))
            time.sleep(wait_time)
Exemplo n.º 12
0
class ScriptDummyWithSubScript(Script):

    _DEFAULT_SETTINGS = Parameter([
        Parameter('repetitions', 0, int,
                  'times the subscript will be executed')
    ])

    _INSTRUMENTS = {}
    _SCRIPTS = {'sub_script': ScriptDummy}

    def __init__(self, scripts, name=None, settings=None, log_output=None):
        """
        Example of a script that makes use of an instrument
        Args:
            scripts: suscript that will be excecuted by this script
            name (optional): name of script, if empty same as class name
            settings (optional): settings for this script, if empty same as default settings
        """

        # call init of superclass
        Script.__init__(self,
                        name,
                        settings,
                        scripts=scripts,
                        log_output=log_output)

    def _function(self):
        """
        This is the actual function that will be executed. It uses only information that is provided in _DEFAULT_SETTINGS
        for this dummy example we just implement a counter
        """

        import time

        script = self.scripts['sub_script']

        N = self.settings['repetitions']

        self.log(
            'I am a test function runnning suscript {:s} {:d} times'.format(
                script.name, N))
        for i in range(N):
            self.log('run number {:d} / {:d}'.format(i + 1, N))
            script.run()
Exemplo n.º 13
0
    def parameters_default(self):
        """
        parameters_default lists the default Parameters used by the Spectrum Analyzer

        Returns: a list of Parameter objects for the parameters associated with the instrument.
        """

        parameter_list_default = [
            Parameter(
                'visa_resource', 'USB0::0x0957::0xFFEF::CN0323B356::INSTR',
                (str), 'pyVisa instrument identifier, '
                'to make a connection using the pyVisa package.'),
            Parameter('start_frequency', 1.5e9, (int),
                      'start frequency of spectrum analyzer frequency range'),
            Parameter('stop_frequency', 3e9, (int),
                      'stop frequency of spectrum analyzer frequency range')
        ]

        return parameter_list_default
Exemplo n.º 14
0
    def test_create_widget_parameters(self):


        parameters = Parameter([
            Parameter('test1', 0, int, 'test parameter (int)'),
            Parameter('test2' ,
                      [Parameter('test2_1', 'string', str, 'test parameter (str)'),
                       Parameter('test2_2', 0.0, float, 'test parameter (float)'),
                       Parameter('test2_3', 'a', ['a', 'b', 'c'], 'test parameter (list)'),
                       Parameter('test2_4', False, bool, 'test parameter (bool)')
                       ]),
            Parameter('test3', 'aa', ['aa', 'bb', 'cc'], 'test parameter (list)'),
            Parameter('test4', False, bool, 'test parameter (bool)')
        ])

        app = QtGui.QApplication(sys.argv)
        ex = UI(parameters)
Exemplo n.º 15
0
 def check_settings_list(settings):
     '''
     check if settings is a list of settings or a dictionary
     if it is a dictionary we create a settings list from it
     '''
     if isinstance(settings, dict):
         settings_new = []
         for key, value in settings.iteritems():
             settings_new.append(Parameter(key, value))
     elif isinstance(settings, list):
         # if list element is not a  parameter, instrument or script cast it into a parameter
         settings_new = [
             element if isinstance(element,
                                   (Parameter, Instrument,
                                    Script)) else Parameter(element)
             for element in settings
         ]
     else:
         raise TypeError(
             'settings should be a valid list or dictionary!')
     return settings_new
Exemplo n.º 16
0
 def _parameters_default(self):
     '''
     returns the default parameter_list of the instrument
     :return:
     '''
     parameters_default = Parameter([
         Parameter('channel', 0, int, 'channel to which motor is connected'),
         Parameter('open', True, bool, 'beam block open or closed'),
         Parameter('settle_time', 0.2, float,'settling time'),
         Parameter('position_open', 4*1900, int,'position corresponding to open'),
         Parameter('position_closed', 4*950, int,'position corresponding to closed')
     ])
     return parameters_default
Exemplo n.º 17
0
 def settings_default(self):
     '''
     returns the default settings of the script
     settings contain Parameters, Instruments and Scripts
     :return:
     '''
     settings_default = [
         Parameter('a', 0, [0, 1]),
         Parameter('txt', 'a', ['a', 'b']),
         Parameter('param',
                   [Parameter('a', 0, [0, 1]),
                    Parameter('b', 2, [2, 3])]),
         Parameter({'b': 0.1}),
         Parameter({'b': True}),
         Instrument_Dummy('dummy inst')
     ]
     return settings_default
Exemplo n.º 18
0
class GalvoScan(Script, QThread):
    updateProgress = Signal(int)

    _DEFAULT_SETTINGS = Parameter([
        Parameter('path',  'C:\\Users\\Experiment\\Desktop\\tmp_data', str, 'path to folder where data is saved'),
        Parameter('tag', 'some_name'),
        Parameter('save', True, bool,'check to automatically save data'),
        Parameter('point_a', (0.0, 0.0), tuple, 'top left corner point of scan region'),
        Parameter('point_b', (0.1, -0.1), tuple, 'bottom right corner point of scan region'),
        Parameter('num_points', (120,120), tuple, 'number of points to scan in x,y'),
        Parameter('time_per_pt', .001, float, 'time in s to measure at each point')
        Parameter('settle_time', .0002, float, 'wait time between points to allow galvo to settle')
    ])

    _INSTRUMENTS = {'daq':  NIDAQ}

    _SCRIPTS = {}

    def __init__(self, instruments = None, name = None, settings = None,  log_output = None, timeout = 1000000000):

        self._recording = False
        self._timeout = timeout
        self.clockAdjust = int((self.settings['time_per_pt'] + self.settings['settle_time'] ) / self.settings['settle_time'] )

        Script.__init__(self, name, settings=settings, instruments=instruments, log_output=log_output)
        QThread.__init__(self)

        xVmin = min(self.settings['point_a'][0], self.settings['point_b'][0])
        xVmax = max(self.settings['point_a'][0], self.settings['point_b'][0])
        yVmin = min(self.settings['point_a'][1], self.settings['point_b'][1])
        yVmax = max(self.settings['point_a'][1], self.settings['point_b'][1])

        self.x_array = np.repeat(np.linspace(xVmin, xVmax, self.settings['num_points'[0]]), self.clockAdjust)
        self.y_array = np.linspace(yVmin, yVmax, self.settings['num_points'[1]])
        self.dt = (self.settings['time_per_pt']+self.settings['settle_time'])/self.clockAdjust
        self.image_data = np.zeros((self.settings['num_points'[1]],self.settings['num_points'[0]]))

    def _function(self):
        """
        This is the actual function that will be executed. It uses only information that is provided in the settings property
        will be overwritten in the __init__
        """
        self.data.clear() # clear data queue

        self.log()

        for yNum in xrange(0, len(self.yArray)):
            # if (not (queue is None) and not (queue.empty()) and (queue.get() == 'STOP')):
            #     break
            # initialize APD thread
            readthread = APDIn.ReadAPD("Dev1/ctr0", 1 / self.dt,
                                       len(self.xArray) + 1)
            self.initPt = np.transpose(np.column_stack((self.xArray[0],
                                          self.yArray[yNum])))
            self.initPt = (np.repeat(self.initPt, 2, axis=1))
            # move galvo to first point in line
            pointthread = DaqOut.DaqOutputWave(self.initPt, 1 / self.dt, "Dev1/ao0:1")
            pointthread.run()
            pointthread.waitToFinish()
            pointthread.stop()
            writethread = DaqOut.DaqOutputWave(self.xArray, 1 / self.dt,
                                               "Dev1/ao0")
            # start counter and scanning sequence
            readthread.runCtr()
            writethread.run()
            writethread.waitToFinish()
            writethread.stop()
            self.xLineData,_ = readthread.read()
            self.diffData = np.diff(self.xLineData)
            self.summedData = np.zeros(len(self.xArray)/self.clockAdjust)
            for i in range(0,int((len(self.xArray)/self.clockAdjust))):
                self.summedData[i] = np.sum(self.diffData[(i*self.clockAdjust+1):(i*self.clockAdjust+self.clockAdjust-1)])
            #also normalizing to kcounts/sec
            self.imageData[yNum] = self.summedData*(.001/self.timePerPt)
            # clean up APD tasks
            readthread.stopCtr()
            readthread.stopClk()
            if(not(self.canvas == None)):
                self.dispImageGui()

        # if self.settings['save']:
        #     self.save()


    def plot(self, axes):

        raise NotImplementedError
Exemplo n.º 19
0
class MaestroController(Instrument):
    # When connected via USB, the Maestro creates two virtual serial ports
    # /dev/ttyACM0 for commands and /dev/ttyACM1 for communications.
    # Be sure the Maestro is configured for "USB Dual Port" serial mode.
    # "USB Chained Mode" may work as well, but hasn't been tested.
    #
    # Pololu protocol allows for multiple Maestros to be connected to a single
    # communication channel. Each connected device is then indexed by number.
    # This device number defaults to 0x0C (or 12 in decimal), which this module
    # assumes.  If two or more controllers are connected to different serial
    # ports, then you can specify the port number when intiating a controller
    # object. Ports will typically start at 0 and count by twos.  So with two
    # controllers ports 0 and 2 would be used.

    import serial

    _DEFAULT_SETTINGS = Parameter([
        Parameter('port', 'COM5', ['COM5', 'COM3'],
                  'com port to which maestro controler is connected')
    ])

    _PROBES = {}

    def __init__(self, name=None, settings=None):

        self.usb = None
        super(MaestroController, self).__init__(name, settings)
        self.update(self.settings)
        # Open the command port
        # self.usb = self.serial.Serial(port)
        # Command lead-in and device 12 are sent for each Pololu serial commands.
        self.PololuCmd = chr(0xaa) + chr(0xc)
        # Track target position for each servo. The function isMoving() will
        # use the Target vs Current servo position to determine if movement is
        # occuring.  Upto 24 servos on a Maestro, (0-23). Targets start at 0.
        self.Targets = [0] * 24
        # Servo minimum and maximum targets can be restricted to protect components.
        self.Mins = [0] * 24
        self.Maxs = [0] * 24

    def update(self, settings):
        # call the update_parameter_list to update the parameter list
        super(MaestroController, self).update(settings)
        # now we actually apply these newsettings to the hardware
        for key, value in settings.iteritems():
            if key == 'port':
                try:
                    self.usb = self.serial.Serial(value)
                except OSError:
                    print('Couln\'t connect to maestro controler at port {:s}'.
                          format(value))

    def read_probes(self, key):
        '''
        requestes value from the instrument and returns it
        Args:
            key: name of requested value

        Returns: reads values from instrument

        '''
        # todo: replace getter old_functions with this function
        assert key in self._PROBES.keys()

        value = None

        return value

    @property
    def is_connected(self):
        '''
        check if instrument is active and connected and return True in that case
        :return: bool
        '''
        if self.usb is None:
            self._is_connected = False
        else:
            self._is_connected = True

        #todo: implement check

        return self._is_connected

    # Cleanup by closing USB serial port
    def __del__(self):
        if not self.usb == None:
            self.usb.close()

    # Set channels min and max value range.  Use this as a safety to protect
    # from accidentally moving outside known safe parameters. A setting of 0
    # allows unrestricted movement.
    #
    # ***Note that the Maestro itself is configured to limit the range of servo travel
    # which has precedence over these values.  Use the Maestro Control Center to configure
    # ranges that are saved to the controller.  Use setRange for software controllable ranges.
    def set_range(self, chan, min, max):
        self.Mins[chan] = min
        self.Maxs[chan] = max

    # Return Minimum channel range value
    def get_min(self, chan):
        return self.Mins[chan]

    # Return Minimum channel range value
    def get_max(self, chan):
        return self.Maxs[chan]

    # Set channel to a specified target value.  Servo will begin moving based
    # on Speed and Acceleration parameters previously set.
    # Target values will be constrained within Min and Max range, if set.
    # For servos, target represents the pulse width in of quarter-microseconds
    # Servo center is at 1500 microseconds, or 6000 quarter-microseconds
    # Typcially valid servo range is 3000 to 9000 quarter-microseconds
    # If channel is configured for digital output, values < 6000 = Low ouput
    def set_target(self, chan, target):
        # if Min is defined and Target is below, force to Min
        if self.Mins[chan] > 0 and target < self.Mins[chan]:
            target = self.Mins[chan]
        # if Max is defined and Target is above, force to Max
        if self.Maxs[chan] > 0 and target > self.Maxs[chan]:
            target = self.Maxs[chan]
        #
        lsb = target & 0x7f  #7 bits for least significant byte
        msb = (target >> 7) & 0x7f  #shift 7 and take next 7 bits for msb
        # Send Pololu intro, device number, command, channel, and target lsb/msb
        cmd = self.PololuCmd + chr(0x04) + chr(chan) + chr(lsb) + chr(msb)
        self.usb.write(cmd)
        # Record Target value
        self.Targets[chan] = target

    def disable(self, chan):

        target = 0
        #
        lsb = target & 0x7f  #7 bits for least significant byte
        msb = (target >> 7) & 0x7f  #shift 7 and take next 7 bits for msb
        # Send Pololu intro, device number, command, channel, and target lsb/msb
        cmd = self.PololuCmd + chr(0x04) + chr(chan) + chr(lsb) + chr(msb)
        self.usb.write(cmd)
        # Record Target value
        self.Targets[chan] = target

    # Set speed of channel
    # Speed is measured as 0.25microseconds/10milliseconds
    # For the standard 1ms pulse width change to move a servo between extremes, a speed
    # of 1 will take 1 minute, and a speed of 60 would take 1 second.
    # Speed of 0 is unrestricted.
    def set_speed(self, chan, speed):
        lsb = speed & 0x7f  #7 bits for least significant byte
        msb = (speed >> 7) & 0x7f  #shift 7 and take next 7 bits for msb
        # Send Pololu intro, device number, command, channel, speed lsb, speed msb
        cmd = self.PololuCmd + chr(0x07) + chr(chan) + chr(lsb) + chr(msb)
        self.usb.write(cmd)

    # Set acceleration of channel
    # This provide soft starts and finishes when servo moves to target position.
    # Valid values are from 0 to 255. 0=unrestricted, 1 is slowest start.
    # A value of 1 will take the servo about 3s to move between 1ms to 2ms range.
    def set_accel(self, chan, accel):
        lsb = accel & 0x7f  #7 bits for least significant byte
        msb = (accel >> 7) & 0x7f  #shift 7 and take next 7 bits for msb
        # Send Pololu intro, device number, command, channel, accel lsb, accel msb
        cmd = self.PololuCmd + chr(0x09) + chr(chan) + chr(lsb) + chr(msb)
        self.usb.write(cmd)

    # Get the current position of the device on the specified channel
    # The result is returned in a measure of quarter-microseconds, which mirrors
    # the Target parameter of setTarget.
    # This is not reading the true servo position, but the last target position sent
    # to the servo. If the Speed is set to below the top speed of the servo, then
    # the position result will align well with the acutal servo position, assuming
    # it is not stalled or slowed.
    def get_position(self, chan):
        cmd = self.PololuCmd + chr(0x10) + chr(chan)
        self.usb.write(cmd)
        lsb = ord(self.usb.read())
        msb = ord(self.usb.read())
        return (msb << 8) + lsb

    # # Test to see if a servo has reached its target position.  This only provides
    # # useful results if the Speed parameter is set slower than the maximum speed of
    # # the servo.
    # # ***Note if target position goes outside of Maestro's allowable range for the
    # # channel, then the target can never be reached, so it will appear to allows be
    # # moving to the target.  See setRange comment.
    # def isMoving(self, chan):
    #     if self.Targets[chan] > 0:
    #         if self.getPosition(chan) <> self.Targets[chan]:
    #             return True
    #     return False

    # # Have all servo outputs reached their targets? This is useful only if Speed and/or
    # # Acceleration have been set on one or more of the channels. Returns True or False.
    # def getMovingState(self):
    #     cmd = self.PololuCmd + chr(0x13)
    #     self.usb.write(cmd)
    #     if self.usb.read() == chr(0):
    #         return False
    #     else:
    #         return True

    # # Run a Maestro Script subroutine in the currently active script. Scripts can
    # # have multiple subroutines, which get numbered sequentially from 0 on up. Code your
    # # Maestro subroutine to either infinitely loop, or just end (return is not valid).
    # def runScriptSub(self, subNumber):
    #     cmd = self.PololuCmd + chr(0x27) + chr(subNumber)
    #     # can pass a param with comman 0x28
    #     # cmd = self.PololuCmd + chr(0x28) + chr(subNumber) + chr(lsb) + chr(msb)
    #     self.usb.write(cmd)
    #
    # # Stop the current Maestro Script
    # def stopScript(self):
    #     cmd = self.PololuCmd + chr(0x24)
    #     self.usb.write(cmd)

    # Stop the current Maestro Script
    def go_home(self):
        cmd = self.PololuCmd + chr(0x22)
        self.usb.write(cmd)
Exemplo n.º 20
0
class NI7845RPidSimpleLoop(Instrument):

    import src.labview_fpga_lib.pid_loop_simple.pid_loop_simple as FPGAlib

    _DEFAULT_SETTINGS = Parameter([
        Parameter('ElementsToWrite', 500, int,
                  'total elements to write to buffer'),
        Parameter('PiezoOut', 0.0, float, 'piezo output in volt'),
        Parameter('Setpoint', 0.0, float, 'set point for PID loop in volt'),
        Parameter('SamplePeriodsPID', int(4e5), int,
                  'sample period of PID loop in ticks (40 MHz)'),
        Parameter('SamplePeriodsAcq', 200, int,
                  'sample period of acquisition loop in ticks (40 MHz)'),
        Parameter('gains', [
            Parameter('proportional', 0, int,
                      'proportional gain of PID loop in ??'),
            Parameter('integral', 0, int, 'integral gain of PID loop in ??'),
        ]),
        Parameter('PI_on', False, bool, 'turn PID loop on/off'),
        Parameter('Acquire', False, bool, 'data acquisition on/off'),
        Parameter('fifo_size', 0, int, 'size of fifo for data acquisition'),
        Parameter('TimeoutBuffer', 0, int,
                  'time after which buffer times out in clock ticks (40MHz)')
    ])

    _PROBES = {
        'AI1': 'analog input channel 1',
        'AI1_filtered': 'analog input channel 1',
        'AI2': 'analog input channel 2',
        'DeviceTemperature': 'device temperature of fpga',
        'ElementsWritten': 'elements written to DMA'
    }

    def __init__(self, name=None, settings=None):
        super(NI7845RPidSimpleLoop, self).__init__(name, settings)

        # start fpga
        self.fpga = self.FPGAlib.NI7845R()
        self.fpga.start()
        self.update(self.settings)

    def __del__(self):
        print('stopping fpga NI7845RPidSimpleLoop')
        self.fpga.stop()

    def read_probes(self, key):
        assert key in self._PROBES.keys(), "key assertion failed %s" % str(key)
        value = getattr(self.FPGAlib,
                        'read_{:s}'.format(key))(self.fpga.session,
                                                 self.fpga.status)
        return value

    def update(self, settings):
        super(NI7845RPidSimpleLoop, self).update(settings)

        for key, value in settings.iteritems():
            if key in ['PiezoOut']:
                if self.settings['PI_on'] == True:
                    print('PI is active, manual piezo control not active!')
                else:
                    getattr(self.FPGAlib,
                            'set_{:s}'.format(key))(volt_2_bit(value),
                                                    self.fpga.session,
                                                    self.fpga.status)
            elif key in ['Setpoint']:
                getattr(self.FPGAlib,
                        'set_{:s}'.format(key))(volt_2_bit(value),
                                                self.fpga.session,
                                                self.fpga.status)
            elif key in ['PI_on']:
                getattr(self.FPGAlib,
                        'set_PIDActive')(value, self.fpga.session,
                                         self.fpga.status)
            elif key in ['Acquire']:
                getattr(self.FPGAlib,
                        'set_AcquireData')(value, self.fpga.session,
                                           self.fpga.status)
            elif key in ['gains']:
                if 'proportional' in value:
                    getattr(self.FPGAlib,
                            'set_PI_gain_prop')(value['proportional'],
                                                self.fpga.session,
                                                self.fpga.status)
                if 'integral' in value:
                    getattr(self.FPGAlib, 'set_PI_gain_int')(value['integral'],
                                                             self.fpga.session,
                                                             self.fpga.status)
            elif key in [
                    'ElementsToWrite', 'sample_period_PI', 'SamplePeriodsAcq',
                    'PI_on'
            ]:
                getattr(self.FPGAlib,
                        'set_{:s}'.format(key))(value, self.fpga.session,
                                                self.fpga.status)
            elif key in ['fifo_size']:
                self.FPGAlib.configure_FIFO_AI(value, self.fpga.session,
                                               self.fpga.status)

    def start_fifo(self):
        self.FPGAlib.start_FIFO_AI(self.fpga.session, self.fpga.status)

    def stop_fifo(self):
        self.FPGAlib.stop_FIFO_AI(self.fpga.session, self.fpga.status)

    def read_fifo(self, block_size):
        '''
        read a block of data from the FIFO
        :return: data from channels AI1 and AI2 and the elements remaining in the FIFO
        '''

        fifo_data = self.FPGAlib.read_FIFO_AI(block_size, self.fpga.session,
                                              self.fpga.status)

        if str(self.fpga.status) != 0:
            raise LabviewFPGAException(self.fpga.status)

        return fifo_data
class MWSpectraVsPower(Script, QThread):

    # NOTE THAT THE ORDER OF Script and QThread IS IMPORTANT!!
    _DEFAULT_SETTINGS = Parameter([
        Parameter('path', 'Z:/Lab/Cantilever/Measurements/', str,
                  'path for data'),
        Parameter('tag', 'dummy_tag', str, 'tag for data'),
        Parameter('save', True, bool, 'save data on/off'),
        Parameter('start_frequency', 2.7e9, float,
                  'start frequency of spectrum'),
        Parameter('end_frequency', 3e9, float, 'end frequency of spectrum'),
        Parameter('microwave_frequency', 3e9, float, 'frequency of microwave'),
        Parameter('uwave_power_min', -45.0, float,
                  'microwave power min (dBm)'),
        Parameter('uwave_power_max', -12.0, float,
                  'microwave power max (dBm)'),
        Parameter('uwave_power_step', 2.0, float,
                  'microwave power step (dBm)'),
        Parameter('wait_time', 2.0, float,
                  'time to wait after change in power (seconds)')
    ])

    _INSTRUMENTS = {
        'microwave_generator': MicrowaveGenerator,
        'cryo_station': CryoStation,
        'spectrum_analyzer': SpectrumAnalyzer
    }

    _SCRIPTS = {}

    #This is the signal that will be emitted during the processing.
    #By including int as an argument, it lets the signal know to expect
    #an integer argument when emitting.
    updateProgress = Signal(int)

    def __init__(self,
                 instruments=None,
                 name=None,
                 settings=None,
                 log_output=None):
        """
        Example of a script that emits a QT signal for the gui
        Args:
            name (optional): name of script, if empty same as class name
            settings (optional): settings for this script, if empty same as default settings
        """
        Script.__init__(self,
                        name,
                        settings=settings,
                        instruments=instruments,
                        log_output=log_output)
        # QtCore.QThread.__init__(self)
        QThread.__init__(self)
        # self.data = deque()

    def _function(self):
        """
        This is the actual function that will be executed. It uses only information that is provided in the settings property
        will be overwritten in the __init__
        """
        def calc_progress(power):
            min, max = self.settings['uwave_power_min'], self.settings[
                'uwave_power_max']

            progress = power - min / (max - min) * 100

            return progress

        # set up instruments
        # todo: FINISH IMPLEMENTATIUON
        self.instruments['microwave_generator'].FREQ = self.settings[
            'microwave_frequency']

        self.save(save_data=False,
                  save_instrumets=True,
                  save_log=False,
                  save_settings=True)

        power_values = [
            float(power)
            for power in np.arange(self.settings['uwave_power_min'],
                                   self.settings['uwave_power_max'],
                                   self.settings['uwave_power_step'])
        ]

        stage_1_temp = []
        stage_2_temp = []
        platform_temp = []
        times = []
        spectrum = []
        uwave_power = []

        for power in power_values:
            # for power in range(self.settings['uwave_power_min'], self.settings['uwave_power_max'], self.settings['uwave_power_step']):
            # set u-wave power
            self.instruments['microwave_generator'].AMPR = power
            time.sleep(self.settings['wait_time']
                       )  #since the spectrum analyzer takes a full second =)

            uwave_power.append(power)
            times.append(time.strftime('%Y_%m_%d_%H_%M_%S'))
            stage_1_temp.append(self.instruments['cryo_station'].platform_temp)
            stage_2_temp.append(self.instruments['cryo_station'].stage_1_temp)
            platform_temp.append(self.instruments['cryo_station'].stage_2_temp)

            trace = self.instruments['spectrum_analyzer'].trace
            freq = [item[0] for item in trace]
            trans = [item[1] for item in trace]

            spectrum.append(trans)

            data = {
                'stage_1_temp': stage_1_temp,
                'stage_2_temp': stage_2_temp,
                'platform_temp': platform_temp,
                'times': times,
                'spectrum': spectrum,
                'frequency': freq,
                'uwave_power': uwave_power
            }

            self.data = data

            self.save(save_data=True,
                      save_instrumets=False,
                      save_log=False,
                      save_settings=False)

            progress = calc_progress(power)

            self.log('current u-wave power : {:0.2f} dBm'.format(power))

            self.updateProgress.emit(progress)
        self.save(save_data=False,
                  save_instrumets=False,
                  save_log=True,
                  save_settings=False)

        self.instruments['microwave_generator'].AMPR = -60

    def plot(self, axes):

        spectrum = self.data[-1]['spectrum']
        freq = self.data[-1]['frequency']

        axes.plot(freq, spectrum)
Exemplo n.º 22
0
class ZISweeper(Script, QThread):
    updateProgress = Signal(int)

    _DEFAULT_SETTINGS = Parameter([
        Parameter('path', 'C:\\Users\\Experiment\\Desktop\\tmp_data', str,
                  'path to folder where data is saved'),
        Parameter('tag', 'some_name'),
        Parameter('save', True, bool, 'check to automatically save data'),
        Parameter('start', 1.8e6, float, 'start value of sweep'),
        Parameter('stop', 1.9e6, float, 'end value of sweep'),
        Parameter('samplecount', 101, int, 'number of data points'),
        Parameter('gridnode', 'oscs/0/freq', ['oscs/0/freq', 'oscs/1/freq'],
                  'output channel =not 100% sure, double check='),
        Parameter('xmapping', 0, [0, 1],
                  'mapping 0 = linear, 1 = logarithmic'),
        Parameter('bandwidthcontrol', 2, [2],
                  '2 = automatic bandwidth control'),
        Parameter(
            'scan', 0, [0, 1, 2],
            'scan direction 0 = sequential, 1 = binary (non-sequential, each point once), 2 = bidirecctional (forward then reverse)'
        ),
        Parameter('loopcount', 1, int, 'number of times it sweeps'),
        Parameter('averaging/sample', 1, int,
                  'number of samples to average over')
    ])

    _INSTRUMENTS = {'zihf2': ZIHF2}

    _SCRIPTS = {}

    def __init__(self,
                 instruments,
                 name=None,
                 settings=None,
                 log_output=None,
                 timeout=1000000000):

        self._recording = False
        self._timeout = timeout

        Script.__init__(self,
                        name,
                        settings,
                        instruments,
                        log_output=log_output)
        QThread.__init__(self)

        self.sweeper = self.instruments['zihf2'].daq.sweep(self._timeout)
        self.sweeper.set('sweep/device', self.instruments['zihf2'].device)

        self.data = deque()

        # todo: clean this up! and plot data in gui!
        self._sweep_values = {
            'frequency': [],
            'x': [],
            'y': [],
            'phase': [],
            'r': []
        }.keys()

    def settings_to_commands(self, settings):
        '''
        converts dictionary to list of  setting, which can then be passed to the zi controler
        :param dictionary = dictionary that contains the commands
        :return: commands = list of commands, which can then be passed to the zi controler
        '''
        # create list that is passed to the ZI controler

        commands = []
        for key, val in settings.iteritems():
            if isinstance(val, dict) and 'value' in val:
                commands.append(['sweep/%s' % (key), val['value']])
            elif key in ('start', 'stop', 'samplecount', 'gridnode',
                         'xmapping', 'bandwidthcontrol', 'scan', 'loopcount',
                         'averaging/sample'):
                commands.append(['sweep/%s' % (key), val])
        return commands

    def _function(self):
        """
        This is the actual function that will be executed. It uses only information that is provided in the settings property
        will be overwritten in the __init__
        """
        self.data.clear()  # clear data queue
        commands = self.settings_to_commands(self.settings)

        self.sweeper.set(commands)

        path = '/%s/demods/%d/sample' % (
            self.instruments['zihf2'].device,
            self.instruments['zihf2'].settings['demods']['channel'])
        self.sweeper.subscribe(path)
        self.sweeper.execute()

        while not self.sweeper.finished():
            time.sleep(1)
            progress = int(100 * self.sweeper.progress())
            print('progress', progress)
            data = self.sweeper.read(True)  # True: flattened dictionary

            #  ensures that first point has completed before attempting to read data
            if path not in data:
                continue

            data = data[path][0][
                0]  # the data is nested, we remove the outer brackets with [0][0]
            # now we only want a subset of the data porvided by ZI
            data = {k: data[k] for k in self._sweep_values}

            start = time.time()
            self.data.append(data)

            if (time.time() - start) > self._timeout:
                # If for some reason the sweep is blocking, force the end of the
                # measurement
                print("\nSweep still not finished, forcing finish...")
                self.sweeper.finish()
                self._recording = False

            print("Individual sweep %.2f%% complete. \n" % (progress))

            self.updateProgress.emit(progress)
            print('len data: ', len(self.data))
        if self.sweeper.finished():
            self._recording = False
            progress = 100  # make sure that progess is set 1o 100 because we check that in the old_gui

            if self.settings['save']:
                self.save()

    def plot(self, axes):

        r = self.data[-1]['r']
        freq = self.data[-1]['frequency']
        freq = freq[np.isfinite(r)]
        r = r[np.isfinite(r)]
        plotting.plot_psd(freq, r, axes)
Exemplo n.º 23
0
class ZISweeperHighResolution(Script, QThread):
    updateProgress = Signal(int)

    _DEFAULT_SETTINGS = Parameter([
        Parameter('path', 'C:\\Users\\Experiment\\Desktop\\tmp_data\\fast',
                  str, 'path to folder where data is saved'),
        Parameter('tag', 'some_name'),
        Parameter('save', True, bool, 'check to automatically save data'),
        Parameter('high_res_df', 1000, float,
                  'frequency step of high res. scan'),
        Parameter('high_res_N', 21, int,
                  'number of data points of high res. scan'),
    ])

    _INSTRUMENTS = {}

    _SCRIPTS = {'zi sweep': ZISweeper}

    def __init__(self,
                 scripts,
                 name=None,
                 settings=None,
                 log_output=None,
                 timeout=1000000000):
        self._recording = False
        self._timeout = timeout

        Script.__init__(self,
                        name,
                        settings,
                        scripts=scripts,
                        log_output=log_output)
        QThread.__init__(self)

        self.data = deque()

        # todo: clean this up! and plot data in gui!
        self._sweep_values = {
            'frequency': [],
            'x': [],
            'y': [],
            'phase': [],
            'r': []
        }.keys()

    def _receive_signal(self, progess_sub_script):
        # calculate progress of this script based on progress in subscript

        if self.current_subscript == 'quick scan':
            progress = int(self.weights['quick scan'] * progess_sub_script)
        elif self.current_subscript == 'high res scan':
            progress = int(self.weights['quick scan'] * 100 +
                           self.weights['high res scan'] * progess_sub_script)
        else:
            progress = None
        # if calculated progress is 100 force it to 99, because we still have to save before script is finished
        if progress >= 100:
            progress = 99

        if progress is not None:
            self.updateProgress.emit(progress)

        if progess_sub_script == 100:
            self.current_subscript = None

    def _function(self):
        """
        This is the actual function that will be executed. It uses only information that is provided in the settings property
        will be overwritten in the __init__
        """
        def calculate_weights():
            """
            calculate a weight inversely proportional to the expected to duration of the two steps in the
            script

            Returns: weights as a dictionary for the two steps

            """
            weights = {}

            # estimate run time of step 1 (fast sweep)
            f_range = sweeper_script.settings[
                'stop'] - sweeper_script.settings['start']
            N_samples = sweeper_script.settings['samplecount']
            df = f_range / N_samples

            t = N_samples / df

            weights['quick scan'] = t

            # estimate run time of step 2 (high res sweep)
            df = self.settings['high_res_df']
            N_samples = self.settings['high_res_N']

            t = N_samples / df

            weights['high res scan'] = t

            total_time = sum([v for k, v in weights.iteritems()])

            weights = {k: v / total_time for k, v in weights.iteritems()}

            print('weights', weights)

            return weights

        def run_scan(name):
            self.current_subscript = name
            sweeper_script.start()
            while self.current_subscript is name:
                time.sleep(0.1)

        def calc_new_range():

            df = self.settings['high_res_df']
            N = self.settings['high_res_N']

            r = sweeper_script.data[-1]['r']
            freq = sweeper_script.data[-1]['frequency']
            freq = freq[np.isfinite(r)]
            r = r[np.isfinite(r)]

            fo = freq[np.argmax(r)]

            f_start, f_end = fo - N / 2 * df, fo + N / 2 * df

            # make sure that we convert back to native python types (numpy file types don't pass the Parameter validation)
            return float(f_start), float(f_end), int(N)

        sweeper_script = self.scripts['zi sweep']
        #save initial settings, so that we can rest at the end of the script
        initial_settings = deepcopy(sweeper_script.settings)
        self.weights = calculate_weights()

        # take the signal from the subscript and route it to a function that takes care of it
        sweeper_script.updateProgress.connect(self._receive_signal)

        print('====== start quick scan ============')

        run_scan('quick scan')

        print('====== calculate new scan range ====')
        f_start, f_stop, N = calc_new_range()

        print('f_start, f_stop, N', f_start, f_stop, N)

        print('====== update sweeper ==============')
        sweeper_script.update({
            'start': f_start,
            'stop': f_stop,
            'samplecount': N
        })

        print('====== start high res scan =========')
        # print(sweeper_script.sweeper.finished())
        # print(sweeper_script.sweeper.progress())

        run_scan('high res scan')

        sweeper_script.updateProgress.disconnect()
        self.data = sweeper_script.data[-1]

        self._recording = False

        if self.settings['save']:
            self.save()

        # set the sweeper script back to initial settings
        sweeper_script.update(initial_settings)
        # make sure that progess is set 1o 100 because we check that in the old_gui
        self.updateProgress.emit(100)

    def plot(self, axes):
        if self.current_subscript == 'quick scan' and self.scripts[
                'zi sweep'].data:
            self.scripts['zi sweep'].plot(axes)
        elif self.current_subscript in ('high res scan', None) and self.data:
            r = self.data['r']
            freq = self.data['frequency']
            freq = freq[np.isfinite(r)]
            r = r[np.isfinite(r)]
            plotting.plot_psd(freq, r, axes, False)
Exemplo n.º 24
0
class KeysightGetSpectrum(Script):

    # NOTE THAT THE ORDER OF Script and QThread IS IMPORTANT!!
    _DEFAULT_SETTINGS = Parameter([
        Parameter('path',
                  'Z:/Lab/Cantilever/Measurements/----data_tmp_default----',
                  str, 'path for data'),
        Parameter('tag', 'dummy_tag', str, 'tag for data'),
        Parameter('save', True, bool, 'save data on/off'),
        Parameter('start_frequency', 2.7e9, float,
                  'start frequency of spectrum'),
        Parameter('stop_frequency', 3e9, float, 'end frequency of spectrum'),
        Parameter('output_power', 0.0, float, 'output power (dBm)'),
        Parameter('output_on', True, bool, 'enable output'),
    ])

    _INSTRUMENTS = {'spectrum_analyzer': SpectrumAnalyzer}

    _SCRIPTS = {}

    def __init__(self,
                 instruments=None,
                 name=None,
                 settings=None,
                 log_output=None):
        """
        Example of a script that emits a QT signal for the gui
        Args:
            name (optional): name of script, if empty same as class name
            settings (optional): settings for this script, if empty same as default settings
        """
        Script.__init__(self,
                        name,
                        settings=settings,
                        instruments=instruments,
                        log_output=log_output)

    def _function(self):
        """
        This is the actual function that will be executed. It uses only information that is provided in the settings property
        will be overwritten in the __init__
        """
        def setup_instrument():
            print('self.settings', self.settings)
            inst = self.instruments['spectrum_analyzer']
            if inst.settings['start_frequency'] != self.settings[
                    'start_frequency']:
                inst.start_frequency = self.settings['start_frequency']

            if inst.settings['stop_frequency'] != self.settings[
                    'stop_frequency']:
                inst.stop_frequency = self.settings['stop_frequency']

            if self.settings['output_on']:
                if inst.settings['mode'] != 'TrackingGenerator':
                    inst.mode = 'TrackingGenerator'
                if inst.settings['output_power'] != self.settings[
                        'output_power']:
                    inst.output_power = self.settings['output_power']
                if inst.settings['output_on'] != self.settings['output_on']:
                    inst.output_on = self.settings['output_on']

        setup_instrument()

        trace = self.instruments['spectrum_analyzer'].trace

        self.data = {
            'spectrum': [item[1] for item in trace],
            'frequency': [item[0] for item in trace]
        }

        if self.settings['save']:
            self.save()

    def plot(self, axes):

        spectrum = self.data['spectrum']
        freq = self.data['frequency']

        axes.plot(freq, spectrum)
Exemplo n.º 25
0
 def value(self, value):
     if Parameter.is_valid(value, self.valid_values):
         self._value = value
     else:
         raise TypeError("wrong type {:s}, expected {:s}".format(str(value), str(self.valid_values)))
class LabviewFpgaTimetrace(Script, QThread):
    updateProgress = Signal(int)

    _DEFAULT_SETTINGS = Parameter([
        Parameter('path',  'C:\\Users\\Experiment\\Desktop\\tmp_data', str, 'path to folder where data is saved'),
        Parameter('tag', 'some_name'),
        Parameter('save', True, bool,'check to automatically save data'),
        Parameter('dt', 200, int, 'sample period of acquisition loop in ticks (40 MHz)'),
        Parameter('N', 2000, int, 'numer of samples'),
        Parameter('TimeoutBuffer', 0, int, 'time after which buffer times out in clock ticks (40MHz)'),
        Parameter('BlockSize', 1000, int, 'block size of chunks that are read from FPGA'),
    ])

    _INSTRUMENTS = {'fpga' : NI7845RPidSimpleLoop}

    _SCRIPTS = {}

    def __init__(self, instruments, name = None, settings = None, log_output = None):

        self._recording = False

        Script.__init__(self, name, settings, instruments, log_output = log_output)
        QThread.__init__(self)

        self.data = deque()



    def _function(self):
        """
        This is the actual function that will be executed. It uses only information that is provided in the settings property
        will be overwritten in the __init__
        """

        def calculate_progress(loop_index):
            progress = int(100.0 * loop_index / number_of_reads)

        self._recording = True
        self.data.clear() # clear data queue

        # reset FIFO
        block_size = self.settings['BlockSize']
        self.instruments['fpga'].update({'fifo_size' :block_size * 2})
        time.sleep(0.1)
        self.instruments['fpga'].start_fifo()
        time.sleep(0.1)
        number_of_reads = int(np.ceil(1.0 * self.settings['N'] / self.settings['BlockSize']))
        print('number_of_reads', number_of_reads)
        N_actual = number_of_reads * block_size
        if N_actual!=self.settings['N']:
            self.log('warning blocksize not comensurate with number of datapoints, set N = {:d}'.format(N_actual))
            self.settings.update({'N' : N_actual})
            time.sleep(0.1)

        # apply settings to instrument
        instr_settings = {
            'SamplePeriodsAcq' : self.settings['dt'],
            'ElementsToWrite' : self.settings['N'],
            'TimeoutBuffer' : self.settings['TimeoutBuffer']

        }
        self.instruments['fpga'].update(instr_settings)
        time.sleep(0.1)
        self.instruments['fpga'].update({'Acquire' : True})

        time.sleep(1)

        print('ElementsWritten: ', self.instruments['fpga'].ElementsWritten)

        ai1 = np.zeros(N_actual)
        for i in range(number_of_reads):
            data = self.instruments['fpga'].read_fifo(block_size)
            print(i, 'ddd', data)
            print('block_size', block_size)
            ai1[i* block_size:(i+1)*block_size] = deepcopy(data['AI1'])
            # append data to queue
            self.data.append({
                'AI1' : ai1
            })


            progress = calculate_progress(i)

            self.updateProgress.emit(progress)

        self._recording = False
        progress = 100 # make sure that progess is set 1o 100 because we check that in the old_gui

        if self.settings['save']:
            self.save()


    def plot(self, axes):

        r = self.data[-1]['AI1']
        axes.plot(r)
Exemplo n.º 27
0
class DummyInstrument(Instrument):

    _DEFAULT_SETTINGS = Parameter([
        Parameter('test1', 0, int, 'some int parameter'),
        Parameter('output probe2', 0, int, 'return value of probe 2 (int)'),
        Parameter('test2', [
            Parameter('test2_1', 'string', str, 'test parameter (str)'),
            Parameter('test2_2', 0.0, float, 'test parameter (float)')
        ])
    ])

    _PROBES = {
        'value1': 'this is some value from the instrument',
        'value2': 'this is another',
        'internal': 'gives the internal state variable',
        'deep_internal': 'gives another internal state variable'
    }

    def __init__(self, name=None, settings=None):
        super(DummyInstrument, self).__init__(name, settings)
        self._internal_state = None
        self._internal_state_deep = None

    def update(self, settings):
        '''
        updates the internal dictionary and sends changed values to instrument
        Args:
            settings: parameters to be set
        # mabe in the future:
        # Returns: boolean that is true if update successful

        '''
        Instrument.update(self, settings)

        for key, value in settings.iteritems():
            if key == 'test1':
                self._internal_state = value

    def read_probes(self, key):
        """
        requestes value from the instrument and returns it
        Args:
            key: name of requested value

        Returns: reads values from instrument

        """
        assert key in self._PROBES.keys()

        import random
        if key == 'value1':
            value = random.random()
        elif key == 'value2':
            value = self.settings['output probe2']
        elif key == 'internal':
            value = self._internal_state
        elif key == 'deep_internal':
            value = self._internal_state_deep

        return value

    @property
    def is_connected(self):
        '''
        check if instrument is active and connected and return True in that case
        :return: bool
        '''
        return self._is_connected
Exemplo n.º 28
0
class SpectrumAnalyzer(Instrument):
    """
    This class provides a python implementation of the Keysight N9320B 9kHz-3.0GHz spectrum analyzer
    with trigger generator.
    """

    _INSTRUMENT_IDENTIFIER = u'Keysight Technologies,N9320B,CN0323B356,0B.03.58'
    # String returned by spectrum analyzer upon querying it with '*IDN?'

    _DEFAULT_SETTINGS = Parameter([
        Parameter(
            'visa_resource', 'USB0::0x0957::0xFFEF::CN0323B356::INSTR', (str),
            'pyVisa instrument identifier, to make a connection using the pyVisa package.'
        ),
        Parameter('start_frequency', 0.0, float,
                  'start frequency of spectrum analyzer frequency range'),
        Parameter(
            'mode', 'SpectrumAnalyzer',
            ['SpectrumAnalyzer', 'TrackingGenerator'],
            'switches between normal spectrum analyzer mode or spectrum analyzer PLUS output, '
            'i.e., tracking generator'),
        Parameter('stop_frequency', 3e9, float,
                  'stop frequency of spectrum analyzer frequency range'),
        Parameter('output_on', False, bool, 'toggles the tracking generator'),
        Parameter(
            'connection_timeout', 1000, int, 'the time to wait for a response '
            'from the spectrum analyzer with each query'),
        Parameter('output_power', -20.0, float,
                  'the output power (in dBm) of the tracking generator')
    ])

    _PROBES = {
        'start_frequency': 'the lower bound of the frequency sweep',
        'stop_frequency': 'the upper bound of the frequency sweep',
        'trace': 'the frequency sweep of the inputted signal',
        'tracking_generator': 'checks if the tracking generator is on',
        'bandwidth': 'the curent bandwidth of the spectrum analyzer',
        'output_power': 'the power of the tracking generator',
        'mode': 'Spectrum Analyzer Mode or Tracking Generator Mode'
    }

    def __init__(self, name='SpectrumAnalyzer', settings={}):
        """

        Args:
            name (str): optional name of instance of class
            settings (list): list of other values to initialize class with

        """
        super(SpectrumAnalyzer, self).__init__(name, settings)

        rm = visa.ResourceManager()
        self.spec_anal = rm.open_resource(self.settings['visa_resource'])
        self.spec_anal.read_termination = '\n'
        self.spec_anal.timeout = self.settings['connection_timeout']
        self.spec_anal.write('*RST')
        self._last_update_time = time.time()
        self._wait_for_spec_anal()
        self.update({'mode': 'SpectrumAnalyzer'})

    def update(self, settings):
        super(SpectrumAnalyzer, self).update(settings)

        self._wait_for_spec_anal()
        for key, value in settings.iteritems():
            if key == 'start_frequency':
                assert 0.0 < value < 3e9, \
                    "start frequency must be between 0 and 3e9, you tried to set it to {0}!".format(value)
                self._set_start_frequency(value)
            elif key == 'stop_frequency':
                assert 0.0 < value < 3e9, \
                    "stop frequency must be between 0 and 3e9, you tried to set it to {0}!".format(value)
                self._set_stop_frequency(value)
            elif key == 'output_on':
                self._toggle_output(value)
            elif key == 'output_power':
                self._set_output_power(value)
            elif key == 'mode':
                self._set_mode(value)
            else:
                message = '{0} is not a parameter of {1}'.format(
                    key, self.name)

    def read_probes(self, probe_name):
        self._wait_for_spec_anal()

        if probe_name == 'start_frequency':
            return self._get_start_frequency()
        elif probe_name == 'stop_frequency':
            return self._get_stop_frequency()
        elif probe_name == 'trace':
            return self._get_trace()
        elif probe_name == 'output_on':
            return self._is_output_on()
        elif probe_name == 'bandwidth':
            return self._get_bandwidth()
        elif probe_name == 'output_power':
            return self._get_output_power()
        elif probe_name == 'mode':
            return self._get_mode()
        else:
            message = 'no probe with that name exists!'
            raise AttributeError(message)

    def is_connected(self):
        """
        Checks if the instrument is connected.
        Returns: True if connected, False otherwise.

        """
        identification = self.spec_anal.query('*IDN?')
        return identification == self._INSTRUMENT_IDENTIFIER

    def _set_start_frequency(self, start_freq):
        self.spec_anal.write('SENS:FREQ:START ' + str(start_freq))

    def _get_start_frequency(self):
        return float(self.spec_anal.query('SENS:FREQ:START?\n'))

    def _set_stop_frequency(self, stop_freq):
        self.spec_anal.write('SENS:FREQ:STOP ' + str(stop_freq))

    def _get_stop_frequency(self):
        return float(self.spec_anal.query('SENS:FREQ:STOP?\n'))

    def _toggle_output(self, state):

        if state:
            assert self._get_mode(
            ) == 'TrackingGenerator', "output can't be on while in SpectrumAnalyzer mode"
            self.spec_anal.write('OUTPUT 1')
        elif not state:
            self.spec_anal.write('OUTPUT 0')

    def _is_output_on(self):
        if self.mode == 'SpectrumAnalyzer':
            return False
        elif self.mode == 'TrackingGenerator':
            return bool(int(self.spec_anal.query('OUTPUT:STATE?')))

    def _get_mode(self):
        mode_response = str(self.spec_anal.query('CONFIGURE?')).strip()
        if mode_response == 'SAN':
            return 'SpectrumAnalyzer'
        elif mode_response == 'TGEN':
            return 'TrackingGenerator'

    def _set_mode(self, mode):
        if mode == 'TrackingGenerator':
            self.spec_anal.write('CONFIGURE:TGENERATOR')
        elif mode == 'SpectrumAnalyzer':
            self.output_on = False
            self.spec_anal.write('CONFIGURE:SANALYZER')

    def _get_trace(self):
        amplitudes = [
            float(i)
            for i in str(self.spec_anal.query(
                'TRACE:DATA? TRACE1' + ';*OPC?')).rstrip(';1').split(',')
        ]
        num_points = len(amplitudes)
        frequencies = np.linspace(start=self.start_frequency,
                                  stop=self.stop_frequency,
                                  num=num_points).tolist()
        return [(frequencies[i], amplitudes[i]) for i in range(num_points)]

    def _get_bandwidth(self):
        return float(self.spec_anal.query('BANDWIDTH?'))

    def _get_output_power(self):
        return float(self.spec_anal.query('SOURCE:POWER?'))

    def _set_output_power(self, power):
        assert self.mode == 'TrackingGenerator', "mode need to be 'TrackingGenerator' to change power"

        return self.spec_anal.write('SOURCE:POWER ' + str(power))

    def __del__(self):
        self.wait_for_spec_anal()
        self._set_mode('SpectrumAnalyzer')
        self.spec_anal.close()

    def _wait_for_spec_anal(self):
        if self._last_update_time - time.time() < 1.0:
            time.sleep(1)

        self._last_update_time = time.time()
Exemplo n.º 29
0
 def value(self, value):
     if Parameter.is_valid(value, self.valid_values):
         self._value = value
     else:
         raise TypeError("wrong type {:s}, expected {:s}".format(
             str(value), str(self.valid_values)))
Exemplo n.º 30
0
class CryoStation(Instrument):

    _DEFAULT_SETTINGS = Parameter(
        Parameter('path', 'C:/Cryostation/Temperature Data/', str,
                  'path to log file of cryostation'), )
    '''
    instrument class to talk to get infos from Montana Cryostation
    Now this doesn't actually communicate with the Cryostation but only reads data from a log-file
    '''
    def __init__(self, name=None, settings=None):

        super(CryoStation, self).__init__(name, settings)
        # apply all settings to instrument
        self.update(self.settings)

        try:
            # create available probes dynamically from headers of logfile
            filepath = "{:s}/MI_DiagnosticsDataLog {:s}.csv".format(
                self.settings['path'], time.strftime('%m_%d_%Y'))
            data = pd.read_csv(filepath)
            self._dynamic_probes = {
                elem.lstrip().lower().replace(' ', '_').replace(
                    '.', '').replace(')', '').replace('(',
                                                      '').replace('/', '-'):
                elem
                for elem in data.columns
            }
            self._is_connected = True

        except IOError:
            self._is_connected = False
        except:
            raise

    def update(self, settings):
        '''
        updates the internal dictionary, just call function of super class

        '''
        super(CryoStation, self).update(settings)

    @property
    def is_connected(self):
        '''
        check if instrument is active and connected and return True in that case
        :return: bool
        '''
        return self._is_connected

    @property
    def _PROBES(self):
        '''

        Returns: a dictionary that contains the values that can be read from the instrument
        the key is the name of the value and the value of the dictionary is an info

        '''
        user_specific_probes = {
            'Platform_Temp': 'temperature of platform',
            'Stage_1_Temp': 'temperature of stage 1',
            'Stage_2_Temp': 'temperature of stage 2'
        }

        user_specific_probes.update(self._dynamic_probes)

        return user_specific_probes

    def read_probes(self, key):
        '''

        requests value from the instrument and returns it
        Args:
            key: name of requested value

        Returns: reads values from instrument

        '''
        assert key in self._PROBES.keys(), "key assertion failed {:s}".format(
            str(key))

        # catch change of date
        time_tag = datetime.datetime.now()
        filepath = "{:s}/MI_DiagnosticsDataLog {:s}.csv".format(
            self.settings['path'], time_tag.strftime('%m_%d_%Y'))
        while os.path.exists(filepath) == False:
            time_tag -= datetime.timedelta(hours=1)
            filepath = "{:s}/MI_DiagnosticsDataLog {:s}.csv".format(
                self.settings['path'], time_tag.strftime('%m_%d_%Y'))

        data = pd.read_csv(filepath)

        # create dictionary with last row as values
        data = dict(data.iloc[-1])

        # since we striped some characters when defining the probes we have to find the right key,
        # which is give by the valeu in self._dynamic_probes
        key = self._dynamic_probes[key]

        return data[key]
Exemplo n.º 31
0
    def _parameters_default(self):
        '''
        returns the default parameter_list of the instrument
        :return:
        '''

        parameters_default = Parameter([
            Parameter('freq', 1e6, float, 'frequency of output channel'),
            Parameter('sigins', [
                Parameter('channel', 0, [0, 1], 'signal input channel'),
                Parameter('imp50', 1, [0, 1],
                          '50Ohm impedance on (1) or off (0)'),
                Parameter('ac', False, bool, 'ac coupling on (1) or off (0)'),
                Parameter('range', 10, [0.01, 0.1, 1, 10],
                          'range of signal input'),
                Parameter('diff', False, bool,
                          'differential signal on (1) or off (0)')
            ]),
            Parameter('sigouts', [
                Parameter('channel', 0, [0, 1], 'signal output channel'),
                Parameter('on', False, bool, 'output on (1) or off (0)'),
                Parameter('add', False, bool,
                          'add aux signal on (1) or off (0)'),
                Parameter('range', 10, [0.01, 0.1, 1, 10],
                          'range of signal output')
            ]),
            Parameter('demods', [
                Parameter('channel', 0, [0, 1], 'demodulation channel'),
                Parameter('order', 4, int, 'filter order'),
                Parameter('rate', 10e3, [10e3], 'rate'),
                Parameter('harmonic', 1, int,
                          'harmonic at which to demodulate'),
                Parameter('phaseshift', 0.0, float,
                          'phaseshift of demodulation'),
                Parameter('oscselect', 0, [0, 1],
                          'oscillator for demodulation'),
                Parameter('adcselect', 0, int, 'adcselect')
            ]),
            Parameter('aux', [
                Parameter('channel', 0, [0, 1], 'auxilary channel'),
                Parameter('offset', 1.0, float, 'offset in volts')
            ])
        ])

        return parameters_default