Пример #1
0
class Driver(BaseDriver):
    support_models = ['DPO4104B']

    quants = [
        QReal('X Scale', set_cmd='HOR:SCA %(value)e', get_cmd='HOR:SCA?'),
        QInteger('Bytes per Point', set_cmd='WFMI:BYT_N?', get_cmd='WFMI:BYT_N?'),
        QReal('X Step', set_cmd=':WFMI:XIN %(value)e', get_cmd=':WFMI:XIN?'),
        QReal('X Zero', set_cmd=':WFMI:XZER %(value)e', get_cmd=':WFMI:XZER?'),
        QReal('Y Scale', set_cmd=':CH%(ch)d:SCA %(value)e', get_cmd=':CH%(ch)d:SCA?'),
        QReal('Y Position', set_cmd=':CH%(ch)d:POS %(value)e', get_cmd=':CH%(ch)d:POS?'),
        QReal('Y Mult', set_cmd=':WFMI:YMU %(value)e', get_cmd=':WFMI:YMU?'),
        QReal('Y Offset', set_cmd=':WFMI:YOF %(value)e', get_cmd=':WFMI:YOF?'),
        QReal('Y Zero', set_cmd=':WFMI:YZER %(value)e', get_cmd=':WFMI:YZER?'),
        QVector('Histogram', get_cmd='HIStogram:DATa?'),
        QReal('Histogram Start', get_cmd='HIStogram:STARt?'),
        QReal('Histogram End', get_cmd='HIStogram:END?')
    ]

    def resetHist(self):
        self.write('HIStogram:COUNt RESET')

    def get_Trace(self, ch=1, start=1, stop=100000):
        self.write(':DAT:SOU CH%d' % ch)
        self.write(':DAT:START %d' % start)
        self.write(':DAT:STOP %d' % stop)
        y = np.array(self.query_ascii_values('CURV?'))
        y_offset = self.getValue('Y Offset')
        y_scale = self.getValue('Y Mult')
        y_zero = self.getValue('Y Zero')
        y = (y-y_offset)*y_scale+y_zero
        x = np.arange(start-1, stop, 1)*self.getValue('X Step') + self.getValue('X Zero')
        return x, (y*10-self.getValue('Y Position', ch=ch))*self.getValue('Y Scale', ch=ch)
Пример #2
0
class Driver(BaseDriver):
    error_command = ''
    surport_models = ['81110A']

    quants = [
        QReal('Frequency', unit='Hz', set_cmd='', get_cmd=''),
        QReal('High Level', unit='V', set_cmd='', get_cmd=''),
        QReal('Low Level', unit='V', set_cmd='', get_cmd=''),
        QReal()
    ]
Пример #3
0
class Driver(BaseDriver):
    support_models = ['E8257D', 'SMF100A', 'SMB100A']

    quants = [
        QReal('Frequency',
              unit='Hz',
              set_cmd=':FREQ %(value).13e',
              get_cmd=':FREQ?'),
        QReal('Power',
              unit='dBm',
              set_cmd=':POWER %(value).8e',
              get_cmd=':POWER?'),
        QOption('Output',
                set_cmd=':OUTP %(option)s',
                options=[('OFF', 'OFF'), ('ON', 'ON')]),
    ]
Пример #4
0
class Driver(BaseDriver):
    support_models = ['WX1284', 'WX2184']

    quants = [
        QReal('Sample Rate',
              unit='S/s',
              set_cmd=':FREQ:RAST %(value)g',
              get_cmd=':FREQ:RAST?'),
    ]

    def performOpen(self):
        pass

    def performSetValue(self, quant, value, **kw):
        pass

    def performGetValue(self, quant, **kw):
        pass
Пример #5
0
class Driver(BaseDriver):
    support_models = ['IT6302']

    quants = [
        QReal(
            'CH1 Voltage',
            unit='V',
            #set_cmd='SYST:REM;INST CH1;VOLT %(value).13e'
            set_cmd='INST CH1;VOLT %(value).13e',
            get_cmd='MEAS? CH1'),
        QReal(
            'CH1 Current',
            unit='A',
            #set_cmd='SYST:REM;INST CH1;CURR %(value).13e'
            set_cmd='INST CH1;CURR %(value).13e',
            get_cmd='MEAS:CURR? CH1'),
        QReal(
            'CH2 Voltage',
            unit='V',
            #set_cmd='SYST:REM;INST CH2;VOLT %(value).13e'
            set_cmd='INST CH2;VOLT %(value).13e',
            get_cmd='MEAS? CH2'),
        QReal(
            'CH2 Current',
            unit='A',
            #set_cmd='SYST:REM;INST CH2;CURR %(value).13e'
            set_cmd='INST CH2;CURR %(value).13e',
            get_cmd='MEAS:CURR? CH2'),
        QReal(
            'CH3 Voltage',
            unit='V',
            #set_cmd='SYST:REM;INST CH3;VOLT %(value).13e'
            set_cmd='INST CH3;VOLT %(value).13e',
            get_cmd='MEAS? CH3'),
        QReal(
            'CH3 Current',
            unit='A',
            #set_cmd='SYST:REM;INST CH3;CURR %(value).13e'
            set_cmd='INST CH3;CURR %(value).13e',
            get_cmd='MEAS:CURR? CH3'),
        QOption('Output',
                set_cmd='OUTP %(option)s',
                options=[('OFF', 'OFF'), ('ON', 'ON')]),
    ]

    def performOpen(self):
        self.write('SYST:REM')
Пример #6
0
class Driver(BaseDriver):
    support_models = ['E8363C', 'ZNB20-2Port']

    quants = [
        QReal('Power', value=-20, unit='dBm', set_cmd='SOUR:POW %(value)e', get_cmd='SOUR:POW?'),
        QReal('Frequency center', value=5e9, unit='Hz', set_cmd='SENS:FREQ:CENT %(value)e', get_cmd='SENS:FREQ:CENT?'),
        QReal('Frequency span', value=2e9, unit='Hz', set_cmd='SENS:FREQ:SPAN %(value)e', get_cmd='SENS:FREQ:SPAN?'),
        QReal('Frequency start', value=4e9, unit='Hz', set_cmd='SENS:FREQ:STAR %(value)e', get_cmd='SENS:FREQ:STAR?'),
        QReal('Frequency stop', value=6e9, unit='Hz', set_cmd='SENS:FREQ:STOP %(value)e', get_cmd='SENS:FREQ:STOP?'),
        QVector('Frequency', unit='Hz'),
        QVector('Trace'),
        QVector('S'),
        QOption('Sweep', value='ON',
          set_cmd='INIT:CONT %(option)s', options=[('OFF', 'OFF'), ('ON', 'ON')]),
        QInteger('Number of points', value=201, unit='',
          set_cmd='SENS:SWE:POIN %(value)d', get_cmd='SENS:SWE:POIN?'),
        QOption('Format', value='MLOG',
          set_cmd='CALC:FORM %(option)s', get_cmd='CALC:FORM?',
          options=[('Mlinear', 'MLIN'),
                   ('Mlog', 'MLOG'),
                   ('Phase', 'PHAS'),
                   ('Unwrapped phase', 'UPH'),
                   ('Imag', 'IMAG'),
                   ('Real', 'REAL'),
                   ('Polar', 'POL'),
                   ('Smith', 'SMIT'),
                   ('SWR', 'SWR'),
                   ('Group Delay', 'GDEL')]),
        QOption('SweepType', value='',
          set_cmd='SENS:SWE:TYPE %(option)s', get_cmd='SENS:SWE:TYPE?',
          options=[('Linear', 'LIN'),
                   ('Log', 'LOG'),
                   ('Power', 'POW'),
                   ('CW', 'CW'),
                   ('Segment', 'SEGM'),
                   ('Phase', 'PHAS')])
    ]

    '''
    def performSetValue(self, quant, value, **kw):
        if quant.name == 'Power':
            self.setValue('Power:Start', value)
            self.setValue('Power:Center', value)
            self.setValue('Power:Stop', value)
        else:
            super(Driver, self).performSetValue(quant, value, **kw)
    '''

    def performGetValue(self, quant, **kw):
        get_vector_methods = {
            'Frequency': self.get_Frequency,
            'Trace': self.get_Trace,
            'S': self.get_S,
        }
        if quant.name in get_vector_methods.keys():
            return get_vector_methods[quant.name](ch = kw.get('ch', 1))
        else:
            return super(Driver, self).performGetValue(quant, **kw)

    def get_Trace(self, ch=1):
        '''Get trace'''
        return self.get_S(ch, formated=True)

    def get_S(self, ch=1, formated=False):
        '''Get the complex value of S paramenter or formated data'''
        #Select the measurement
        self.pna_select(ch)

        #Stop the sweep
        self.setValue('Sweep', 'OFF')
        #Begin a measurement
        self.write('INIT:IMM')
        self.write('*WAI')
        #Get the data
        self.write('FORMAT:BORD NORM')
        self.write('FORMAT ASCII')
        if formated:
            data = np.asarray(self.query_ascii_values("CALC%d:DATA? FDATA" % ch))
        else:
            data = np.asarray(self.query_ascii_values("CALC%d:DATA? SDATA" % ch))
            data = data[::2]+1j*data[1::2]
        #Start the sweep
        self.setValue('Sweep', 'ON')
        return data

    def pna_select(self, ch=1):
        '''Select the measurement'''
        if self.model == 'E8363C':
            quote = '" '
        elif self.model in ['ZNB20-2Port']:
            quote = "' "
        msg = self.query('CALC%d:PAR:CAT?' % ch).strip(quote)
        measname = msg.split(',')[0]
        self.write('CALC%d:PAR:SEL "%s"' % (ch, measname))

    def get_Frequency(self, ch=1):
        """Return the frequency of pna measurement"""

        #Select the measurement
        self.pna_select(ch)
        if self.model == 'E8363C':
            cmd = 'CALC:X?'
        elif self.model in ['ZNB20-2Port']:
            cmd = 'CALC:DATA:STIM?'
        return np.asarray(self.query_ascii_values(cmd))

    def set_segments(self, segments=[], form='Start Stop'):
        self.write('SENS:SEGM:DEL:ALL')
        if form == 'Start Stop':
            cmd = ['SENS:SEGM:LIST SSTOP,%d' % len(segments)]
            for kw in segments:
                data = '1,%(num)d,%(start)g,%(stop)g,%(IFBW)g,0,%(power)g' % kw
                cmd.append(data)
        else:
            cmd = ['SENS:SEGM:LIST CSPAN,%d' % len(segments)]
            for kw in segments:
                data = '1,%(num)d,%(center)g,%(span)g,%(IFBW)g,0,%(power)g' % kw
                cmd.append(data)
        self.write('FORMAT ASCII')
        self.write(','.join(cmd))
Пример #7
0
class Driver(BaseDriver):
    error_command = ''
    support_models = ['SR620']
    quants = [
        QVector('Data', unit=''),
        QReal('Ext Level',
              unit='V',
              set_cmd='LEVL 0,%(value)f',
              get_cmd='LEVL? 0'),
        QReal('A Level',
              unit='V',
              set_cmd='LEVL 1,%(value)f',
              get_cmd='LEVL? 1'),
        QReal('B Level',
              unit='V',
              set_cmd='LEVL 2,%(value)f',
              get_cmd='LEVL? 2'),
        QOption('Ext Term',
                set_cmd='TERM 0,%(option)s',
                get_cmd='TERM? 0',
                options=[('50 Ohm', '0'), ('1 MOhm', '1')]),
        QOption('A Term',
                set_cmd='TERM 1,%(option)s',
                get_cmd='TERM? 1',
                options=[('50 Ohm', '0'), ('1 MOhm', '1')]),
        QOption('B Term',
                set_cmd='TERM 2,%(option)s',
                get_cmd='TERM? 2',
                options=[('50 Ohm', '0'), ('1 MOhm', '1')]),
        QOption('Ext Slope',
                set_cmd='TSLP 0,%(option)s',
                get_cmd='TSLP? 0',
                options=[('Positive', '0'), ('Negative', '1')]),
        QOption('A Slope',
                set_cmd='TSLP 1,%(option)s',
                get_cmd='TSLP? 1',
                options=[('Positive', '0'), ('Negative', '1')]),
        QOption('B Slope',
                set_cmd='TSLP 2,%(option)s',
                get_cmd='TSLP? 2',
                options=[('Positive', '0'), ('Negative', '1')]),
        QOption('A Coupling',
                set_cmd='TCPL 1,%(option)s',
                get_cmd='TCPL? 1',
                options=[('DC', '0'), ('AC', '1')]),
        QOption('B Coupling',
                set_cmd='TCPL 2,%(option)s',
                get_cmd='TCPL? 2',
                options=[('DC', '0'), ('AC', '1')]),
        QOption('Mode',
                set_cmd='MODE %(option)s',
                get_cmd='MODE?',
                options=[
                    ('time', '0'),
                    ('width', '1'),
                    ('tr/tf', '2'),
                    ('freq', '3'),
                    ('period', '4'),
                    ('phase', '5'),
                    ('count', '6'),
                ]),
        QOption('Arming Mode',
                set_cmd='ARMM %s',
                get_cmd='ARMM?',
                options=[
                    ('+- time', '0'),
                    ('+ time', '1'),
                    ('1 period', '2'),
                    ('0.01 s gate', '3'),
                    ('0.1 s gate', '4'),
                    ('1.0 s gate', '5'),
                    ('ext trig +- time', '6'),
                    ('ext trig + time', '7'),
                    ('ext gate/trig holdoff', '8'),
                    ('ext 1 period', '9'),
                    ('ext 0.01 s gate', '10'),
                    ('ext 0.1 s gate', '11'),
                    ('ext 1.0 s gate', '12'),
                ]),
    ]

    def performGetValue(self, quant, **kw):
        if quant.name == 'Data':
            if 'count' in kw.keys():
                count = kw['count']
            else:
                count = 100
            return self.get_Data(count)
        else:
            return BaseDriver.performGetValue(self, quant, **kw)

    def get_Data(self, count=100):
        block = b''
        max = 5000
        loop = int(count / max)
        last = count % max
        self.write('*CLS')
        try:
            if last < count:
                for i in range(loop):
                    self.write('BDMP %d' % max)
                    block += self.__read(8 * max)
            self.write('BDMP %d' % last)
            block += self.__read(8 * last)
        except:
            raise
        mode = int(self.query('MODE?'))
        expd = int(self.query('EXPD?'))
        self.write('AUTM 1')

        factors = [
            1.05963812934E-14, 1.05963812934E-14, 1.05963812934E-14,
            1.24900090270331E-9, 1.05963812934E-14, 8.3819032E-8, 0.00390625
        ]
        ret = np.array(list(struct.unpack('<%dq' % count,
                                          block))) * factors[mode]
        if expd != 0:
            ret = ret * 1e-3
        return ret

    def __read(self, size):
        try:
            buff = self.ins.visalib.read(self.ins.session, size)[0]
        except VisaIOWarning:
            pass
        return buff
Пример #8
0
class Driver(BaseDriver):
    support_models = ['AWG5014C', 'AWG5208']

    quants = [
        QReal('Sample Rate',
              unit='S/s',
              set_cmd='SOUR:FREQ %(value)f',
              get_cmd='SOUR:FREQ?'),
        QOption('Run Mode',
                set_cmd='AWGC:RMOD %(option)s',
                get_cmd='AWGC:RMOD?',
                options=[('Continuous', 'CONT'), ('Triggered', 'TRIG'),
                         ('Gated', 'GAT'), ('Sequence', 'SEQ')]),
        QOption('Clock Source',
                set_cmd='AWGC:CLOC:SOUR %(option)s',
                get_cmd='AWGC:CLOC:SOUR?',
                options=[('Internal', 'INT'), ('External', 'EXT')]),
        QOption('Reference Source',
                set_cmd='SOUR:ROSC:SOUR %(option)s',
                get_cmd='SOUR:ROSC:SOUR?',
                options=[('Internal', 'INT'), ('External', 'EXT')]),
        QReal('Vpp',
              unit='V',
              set_cmd='SOURCE%(channel)d:VOLT %(value)f',
              get_cmd='SOURCE%(channel)d:VOLT?'),
        QReal('Offset',
              unit='V',
              set_cmd='SOURCE%(channel)d:VOLT:OFFS %(value)f',
              get_cmd='SOURCE%(channel)d:VOLT:OFFS?'),
        QReal('Volt Low',
              unit='V',
              set_cmd='SOURCE%(channel)d:VOLT:LOW %(value)f',
              get_cmd='SOURCE%(channel)d:VOLT:LOW?'),
        QReal('Volt High',
              unit='V',
              set_cmd='SOURCE%(channel)d:VOLT:HIGH %(value)f',
              get_cmd='SOURCE%(channel)d:VOLT:HIGH?'),
    ]

    def performOpen(self):
        pass

    def performSetValue(self, quant, value, **kw):
        if quant.name == '':
            return
        else:
            return BaseDriver.performSetValue(self, quant, value, **kw)

    def performGetValue(self, quant, **kw):
        if quant.name == '':
            return ''
        else:
            return BaseDriver.performGetValue(self, quant, **kw)

    def creat_waveform(self, name, length, format='REAL'):
        '''
        format: REAL, INT or IQ
        '''
        self.write('WLIS:WAV:NEW "%s",%d,%s;' % (name, length, format))

    def remove_waveform(self, name):
        self.write(':WLIS:WAV:DEL "%s"; *CLS' % name)

    def use_waveform(self, name, ch=1):
        self.write('SOURCE%d:WAVEFORM "%s"' % (ch, name))

    def run_state(self):
        return int(self.query(':AWGC:RST?'))

    def run(self):
        self.write(':AWGC:RUN;')

    def stop(self):
        self.write(':AWGC:STOP;')

    def output_on(self, ch=1):
        self.write(':OUTP%d:STAT 1;' % ch)

    def output_off(self, ch=1):
        self.write(':OUTP%d:STAT 0;' % ch)

    def get_current_waveforms(self):
        current_waveforms = []
        current_waveform_size = 0
        for i in [1, 2, 3, 4]:
            wn = self.query('SOUR%d:WAV?' % i)[1:-2]
            current_waveforms.append(wn)
            if wn != '' and current_waveform_size == 0:
                current_waveform_size = self.query_ascii_values(
                    'WLIS:WAV:LENGTH? "%s"' % wn, 'd')[0]
        return current_waveform_size, current_waveforms

    def update_waveform(self, points, name='ABS', IQ='I', mk1=None, mk2=None):
        w_type = self.query('WLISt:WAVeform:TYPE? "%s"' % name).strip()
        if w_type == 'REAL':
            self._update_waveform_float(points, name, IQ)
        elif w_type == 'IQ':
            self._update_waveform_float(points[0], name, 'I')
            self._update_waveform_float(points[1], name, 'Q')
        else:
            self._update_waveform_int(points, name, mk1, mk2)

    def _update_waveform_int(self, points, name='ABS', mk1=None, mk2=None):
        """
        points : a 1D numpy.array which values between -1 and 1.
        mk1, mk2: a string contain only '0' and '1'.
        """
        message = 'WLIST:WAVEFORM:DATA "%s",' % name
        points = points.clip(-1, 1)
        values = (points * 0x1fff).astype(int) + 0x1fff
        if mk1 is not None:
            for i in range(min(len(mk1), len(values))):
                if mk1[i] == '1':
                    values[i] = values[i] + 0x4000
        if mk2 is not None:
            for i in range(min(len(mk2), len(values))):
                if mk2[i] == '1':
                    values[i] = values[i] + 0x8000
        self.write_binary_values(message,
                                 values,
                                 datatype=u'H',
                                 is_big_endian=False,
                                 termination=None,
                                 encoding=None)

    def _update_waveform_float(self, points, name='ABS', IQ='I'):
        if self.model == 'AWG5208':
            message = 'WLIST:WAVEFORM:DATA:%s "%s",' % (IQ, name)
        else:
            message = 'WLIST:WAVEFORM:DATA "%s",' % name
        values = points.clip(-1, 1)
        self.write_binary_values(message,
                                 values,
                                 datatype=u'f',
                                 is_big_endian=False,
                                 termination=None,
                                 encoding=None)

    def update_marker(self, name, mk1, mk2):
        values = []
        for i in range(len(mk1)):
            d = 0
            if mk1[i] == '1':
                d += 64
            if mk2[i] == '1':
                d += 128
            values.append(d)
        message = 'WLIST:WAVEFORM:MARKER:DATA "%s",' % name
        self.write_binary_values(message,
                                 values,
                                 datatype=u'B',
                                 is_big_endian=False,
                                 termination=None,
                                 encoding=None)
Пример #9
0
class Driver(BaseDriver):
    error_command = ''
    support_models = ['DG645']

    quants = [
        QReal('Trigger Rate',
              unit='Hz',
              set_cmd='TRAT %(value).6E',
              get_cmd='TRAT?'),
        QReal('T0 Amplitude',
              unit='V',
              set_cmd='LAMP 0,%(value).2f',
              get_cmd='LAMP?0'),
        QReal('T0 Offset',
              unit='V',
              set_cmd='LOFF 0,%(value).2f',
              get_cmd='LOFF?0'),
        QReal('T0 Length',
              unit='s',
              set_cmd='DLAY 1,0,%(value).6E',
              get_cmd='DLAY?1'),
        QOption('T0 Polarity',
                set_cmd='LPOL 0,%(option)s',
                get_cmd='LPOL?0',
                options=[('pos', '1'), ('neg', '0')]),
        QReal('AB Amplitude',
              unit='V',
              set_cmd='LAMP 1,%(value).2f',
              get_cmd='LAMP?1'),
        QReal('AB Offset',
              unit='V',
              set_cmd='LOFF 1,%(value).2f',
              get_cmd='LOFF?1'),
        QReal('AB Delay',
              unit='s',
              set_cmd='DLAY 2,0,%(value).6E',
              get_cmd='DLAY?2'),
        QReal('AB Length',
              unit='s',
              set_cmd='DLAY 3,2,%(value).6E',
              get_cmd='DLAY?3'),
        QOption('AB Polarity',
                set_cmd='LPOL 1,%(option)s',
                get_cmd='LPOL?1',
                options=[('pos', '1'), ('neg', '0')]),
        QReal('CD Amplitude',
              unit='V',
              set_cmd='LAMP 2,%(value).2f',
              get_cmd='LAMP?2'),
        QReal('CD Offset',
              unit='V',
              set_cmd='LOFF 2,%(value).2f',
              get_cmd='LOFF?2'),
        QReal('CD Delay',
              unit='s',
              set_cmd='DLAY 4,0,%(value).6E',
              get_cmd='DLAY?4'),
        QReal('CD Length',
              unit='s',
              set_cmd='DLAY 5,4,%(value).6E',
              get_cmd='DLAY?5'),
        QOption('CD Polarity',
                set_cmd='LPOL 2,%(option)s',
                get_cmd='LPOL?2',
                options=[('pos', '1'), ('neg', '0')]),
        QReal('EF Amplitude',
              unit='V',
              set_cmd='LAMP 3,%(value).2f',
              get_cmd='LAMP?3'),
        QReal('EF Offset',
              unit='V',
              set_cmd='LOFF 3,%(value).2f',
              get_cmd='LOFF?3'),
        QReal('EF Delay',
              unit='s',
              set_cmd='DLAY 6,0,%(value).6E',
              get_cmd='DLAY?6'),
        QReal('EF Length',
              unit='s',
              set_cmd='DLAY 7,6,%(value).6E',
              get_cmd='DLAY?7'),
        QOption('EF Polarity',
                set_cmd='LPOL 3,%(option)s',
                get_cmd='LPOL?3',
                options=[('pos', '1'), ('neg', '0')]),
        QReal('GH Amplitude',
              unit='V',
              set_cmd='LAMP 4,%(value).2f',
              get_cmd='LAMP?4'),
        QReal('GH Offset',
              unit='V',
              set_cmd='LOFF 4,%(value).2f',
              get_cmd='LOFF?4'),
        QReal('GH Delay',
              unit='s',
              set_cmd='DLAY 8,0,%(value).6E',
              get_cmd='DLAY?8'),
        QReal('GH Length',
              unit='s',
              set_cmd='DLAY 9,8,%(value).6E',
              get_cmd='DLAY?9'),
        QOption('GH Polarity',
                set_cmd='LPOL 4,%(option)s',
                get_cmd='LPOL?4',
                options=[('pos', '1'), ('neg', '0')])
    ]

    def performGetValue(self, quant, **kw):
        get_Delays = [
            'T0 Length', 'AB Delay', 'AB Length', 'CD Delay', 'CD Length',
            'EF Delay', 'EF Length', 'GH Delay', 'GH Length'
        ]
        if quant.name in get_Delays and quant.get_cmd is not '':
            cmd = quant._formatGetCmd(**kw)
            res = self.query_ascii_values(cmd)
            quant.value = res[1]
            return quant.value
        else:
            return super(Driver, self).performGetValue(quant, **kw)
Пример #10
0
class Driver(BaseDriver):
    support_models = ['ATS9870']
    quants = [
        QOption('Clock Source', value='External 10MHz Ref',
                options=[
                    ('Internal', 1),
                    ('External', 2),
                    ('Medium External', 3),
                    ('Slow External', 4),
                    ('External AC', 5),
                    ('External DC', 6),
                    ('External 10MHz Ref', EXTERNAL_CLOCK_10MHz_REF),
                    ('Internal Div 5', 0x10),
                    ('Master', 0x11),
                    ('Internal Set VCO', 0x12)
                ]),

        QOption('Sample Rate', value='1G',
                options=[
                    ('1k',    SAMPLE_RATE_1KSPS),   ('2k',    SAMPLE_RATE_2KSPS),
                    ('5k',    SAMPLE_RATE_5KSPS),   ('10k',   SAMPLE_RATE_10KSPS),
                    ('20k',   SAMPLE_RATE_20KSPS),  ('50k',   SAMPLE_RATE_50KSPS),
                    ('100k',  SAMPLE_RATE_100KSPS), ('200k',  SAMPLE_RATE_200KSPS),
                    ('500k',  SAMPLE_RATE_500KSPS), ('1M',    SAMPLE_RATE_1MSPS),
                    ('2M',    SAMPLE_RATE_2MSPS),   ('5M',    SAMPLE_RATE_5MSPS),
                    ('10M',   SAMPLE_RATE_10MSPS),  ('20M',   SAMPLE_RATE_20MSPS),
                    ('25M',   SAMPLE_RATE_25MSPS),  ('50M',   SAMPLE_RATE_50MSPS),
                    ('100M',  SAMPLE_RATE_100MSPS), ('125M',  SAMPLE_RATE_125MSPS),
                    ('160M',  SAMPLE_RATE_160MSPS), ('180M',  SAMPLE_RATE_180MSPS),
                    ('200M',  SAMPLE_RATE_200MSPS), ('250M',  SAMPLE_RATE_250MSPS),
                    ('400M',  SAMPLE_RATE_400MSPS), ('500M',  SAMPLE_RATE_500MSPS),
                    ('800M',  SAMPLE_RATE_800MSPS), ('1G',    SAMPLE_RATE_1GSPS),
                    ('1200M', SAMPLE_RATE_1200MSPS), ('1500M', SAMPLE_RATE_1500MSPS),
                    ('1600M', SAMPLE_RATE_1600MSPS), ('1800M', SAMPLE_RATE_1800MSPS),
                    ('2G',    SAMPLE_RATE_2GSPS),
                ]),

        QReal('Trigger Delay', value=0, unit='s'),
        QReal('Trigger Timeout', value=1, unit='s'),

        QOption('A Term', value='50 Ohm', options=[
                ('1 MOhm', 1), ('50 Ohm', 2), ('75 Ohm', 4), ('300 Ohm', 8)]),
        QOption('B Term', value='50 Ohm', options=[
                ('1 MOhm', 1), ('50 Ohm', 2), ('75 Ohm', 4), ('300 Ohm', 8)]),
        QOption('Ext Coupling', value='DC', options=[('DC', 2), ('AC', 1)]),
        QOption('A Coupling', value='DC', options=[('DC', 2), ('AC', 1)]),
        QOption('B Coupling', value='DC', options=[('DC', 2), ('AC', 1)]),
        QReal('A Range', value=1, unit='V'),
        QReal('B Range', value=1, unit='V'),
        QOption('A Bandwidth limit', value='Disable',
                options=[('Disable', 0), ('Enable', 1)]),
        QOption('B Bandwidth limit', value='Disable',
                options=[('Disable', 0), ('Enable', 1)]),

        QOption('Trigger Mode', value='J',
                options=[
                    ('J',            0),
                    ('K',            1),
                    ('J or K',       2),
                    ('J and K',      3),
                    ('J xor K',      4),
                    ('J and not K',  5),
                    ('not J and K',  6),
                ]),
        QReal('J Level', value=0.1, unit='V'),
        QReal('K Level', value=0.1, unit='V'),
        QOption('J Slope', value='Positive', options=[
                ('Positive', 1), ('Negative', 2)]),
        QOption('K Slope', value='Positive', options=[
                ('Positive', 1), ('Negative', 2)]),
        QOption('J Source', value='External',
                options=[('ChA', 0), ('ChB', 1), ('External', 2), ('Disable', 3), ('ChC', 4), ('ChD', 5)]),
        QOption('K Source', value='Disable',
                options=[('ChA', 0), ('ChB', 1), ('External', 2), ('Disable', 3), ('ChC', 4), ('ChD', 5)]),
    ]

    def __init__(self, **kw):
        BaseDriver.__init__(self, **kw)
        self.systemID = kw['systemID']
        self.boardID = kw['boardID']
        self.dig = None
        self.config_updated = False
        self.dt = 1E-9

    def __load_wrapper(self):
        if self.dig is None:
            self.dig = AlazarTechDigitizer(self.systemID, self.boardID)

    def set_configs(self):
        """Set digitizer configuration based on driver settings"""
        if self.config_updated:
            return
        logger.debug('set config ...')
        # clock configuration
        SourceId = self.getCmdOption('Clock Source')
        SampleRateId = self.getCmdOption('Sample Rate')
        # 10 MHz ref, use 1GHz rate + divider. NB!! divide must be 1,2,4,10
        #SampleRateId = int(1E9)
        #Decimation = int(round(1E9/lFreq[self.getValueIndex('Sample Rate')]))
        self.dig.AlazarSetCaptureClock(SourceId, SampleRateId)
        # define time step from sample rate
        lFreq = [1E3, 2E3, 5E3, 10E3, 20E3, 50E3, 100E3, 200E3, 500E3,
                 1E6, 2E6, 5E6, 10E6, 20E6, 25E6, 50E6, 100E6, 125E6, 160E6,
                 180E6, 200E6, 250E6, 400E6, 500E6, 800E6, 1E9, 1.2E9, 1.5E9,
                 1.6E9, 1.8E9, 2E9]
        self.dt = 1/lFreq[self.getIndex('Sample Rate')]
        #
        # configure inputs
        for ch in ['A', 'B']:
            chIds = {'A': CHANNEL_A, 'B': CHANNEL_B}
            chId = chIds[ch]
            Coupling = self.getCmdOption('%s Coupling' % ch)
            InputRange = self.dig.get_input_range(
                self.getValue('%s Range' % ch))
            Impedance = self.getCmdOption('%s Term' % ch)
            self.dig.AlazarInputControl(chId, Coupling, InputRange, Impedance)
            # bandwidth limit
            BW = self.getCmdOption('%s Bandwidth limit' % ch)
            self.dig.AlazarSetBWLimit(chId, BW)
        Coupling = self.getCmdOption('Ext Coupling')
        self.dig.AlazarSetExternalTrigger(Coupling)
        #
        # configure trigger
        Mode = self.getCmdOption('Trigger Mode')
        JSource = self.getCmdOption('J Source')
        KSource = self.getCmdOption('J Source')
        JSlope = self.getCmdOption('J Slope')
        KSlope = self.getCmdOption('K Slope')
        JLevel, KLevel = 0, 0

        # convert relative level to U8
        for egn in ['J', 'K']:
            sour = self.getValue('%s Source' % egn)
            trigLevel = self.getValue('%s Level' % egn)
            Amp = {
                INPUT_RANGE_PM_4_V: 4.0, INPUT_RANGE_PM_2_V: 2.0,
                INPUT_RANGE_PM_1_V: 1.0, INPUT_RANGE_PM_400_MV: 0.4,
                INPUT_RANGE_PM_200_MV: 0.2, INPUT_RANGE_PM_100_MV: 0.1,
                INPUT_RANGE_PM_40_MV: 0.04
            }
            if sour == 'ChA':
                maxLevel = Amp[self.dig.get_input_range(
                    self.getValue('A Range'))]
            elif sour == 'ChB':
                maxLevel = Amp[self.dig.get_input_range(
                    self.getValue('B Range'))]
            elif sour == 'External':
                maxLevel = 5.0
            if abs(trigLevel) > maxLevel:
                trigLevel = maxLevel*np.sign(trigLevel)
            Level = int(128 + 127*trigLevel/maxLevel)
            if egn == 'J':
                JLevel = Level
            else:
                KLevel = Level
        # set config
        self.dig.AlazarSetTriggerOperation(Mode,
                                           TRIG_ENGINE_J, JSource, JSlope, JLevel,
                                           TRIG_ENGINE_K, KSource, KSlope, KLevel)
        #
        # set trig delay and timeout
        Delay = int(self.getValue('Trigger Delay')/self.dt)
        self.dig.AlazarSetTriggerDelay(Delay)
        timeout = self.getValue('Trigger Timeout')
        self.dig.AlazarSetTriggerTimeOut(time=timeout)
        self.config_updated = True
        logger.debug('set config ... Done')

    def performSetValue(self, quant, value, **kw):
        # if quant.name not in ['']:
        BaseDriver.performSetValue(self, quant, value, **kw)
        self.config_updated = False

    def performGetValue(self, quant, **kw):
        self.__load_wrapper()
        # self.set_configs()
        return quant.getValue(**kw)

    def errors(self):
        self.__load_wrapper()
        ret = []
        try:
            while True:
                e = self.dig._error_list.pop(0)
                ret.append(e)
        except IndexError:
            return ret
        return []

    def getTraces_DMA(self, samplesPerRecord=1024, pre=0, repeats=1000,
                      procces=None, beforeCapture=None, timeout=10, sum=False):
        self.__load_wrapper()
        self.set_configs()
        a, b = self.dig.get_Traces_DMA(
            pre, samplesPerRecord-pre, repeats, procces, beforeCapture, timeout, sum)
        #a, b = self.dig.get_Traces_NPT(samplesPerRecord, repeats, procces, timeout)
        return np.asarray(a), np.asarray(b)

    def setHeterodyneFrequency(self, samplesPerRecord, heterodyne_freq=[]):
        Exp = []
        t = np.arange(0, samplesPerRecord, 1) * 1e-9
        for f in heterodyne_freq:
            Exp.append(np.exp(1j*2*np.pi*f*t))
        self._Exp = np.asarray(Exp).T

    def getFFT(self, samplesPerRecord=1024, pre=0, repeats=1000, heterodyne_freq=None,
               beforeCapture=None, timeout=10):
        self.__load_wrapper()
        self.set_configs()
        n = samplesPerRecord
        if heterodyne_freq is not None:
            self.setHeterodyneFrequency(samplesPerRecord, heterodyne_freq)

        def procces(ch1, ch2, e=self._Exp):
            return ch1[:n].dot(e).T/n, ch2[:n].dot(e).T/n

        A, B = self.dig.get_Traces_DMA(
            pre, samplesPerRecord-pre, repeats, procces, beforeCapture, timeout)
        return np.asarray(A), np.asarray(B)
Пример #11
0
class Driver(BaseDriver):
    error_command = ''
    support_models = ['33120A', '33220A']
    quants = [
        QReal('Frequency', unit='Hz',
          set_cmd='FREQ %(value).11E Hz',
          get_cmd='FREQ?'),
        QReal('Vpp', unit='V',
          set_cmd='VOLT %(value).5E VPP',
          get_cmd='VOLT?'),
        QReal('Offset', unit='V',
          set_cmd='VOLT:OFFS %(value).5E V',
          get_cmd='VOLT:OFFS?'),
        QVector('Waveform', unit='V'),
        QString('Trigger',
          set_cmd='TRIG:SOUR %(value)s',
          get_cmd='TRIG:SOUR?')
    ]

    def performOpen(self):
        self.write('FORM:BORD NORM')
        self.waveform_list = self.query('DATA:CAT?')[1:-1].split('","')
        self.current_waveform = self.query('FUNC:SHAP?')
        if self.current_waveform == 'USER':
            self.current_waveform = self.query('FUNC:USER?')
        self.arb_waveforms = self.query('DATA:NVOL:CAT?')[1:-1].split('","')
        self.trigger_source = self.query('TRIG:SOUR?')
        self.inner_waveform = ["SINC","NEG_RAMP","EXP_RISE","EXP_FALL","CARDIAC"]

        if self.model == '33120A':
            self.max_waveform_size = 16000
            self.trigger_count  = int(float(self.query('BM:NCYC?')))
        elif self.model == '33220A':
            self.max_waveform_size = 16384
            self.trigger_count  = int(float(self.query("BURS:NCYC?")))

    def performSetValue(self, quant, value, **kw):
        if quant.name == 'Waveform':
            if len(value) > self.max_waveform_size:
                value = value[:self.max_waveform_size]
            value = np.array(value)
            vpp  = value.max() - value.min()
            offs = (value.max() + value.min())/2.0
            name = kw['name'] if 'name' in kw.keys() else 'ABS'
            freq = kw['freq'] if 'freq' in kw.keys() else None
            self.update_waveform(2*(value-offs)/vpp, name=name)
            self.use_waveform(name, vpp=vpp, offs=offs, freq=freq)
        else:
            BaseDriver.performSetValue(self, quant, value, **kw)

    def __del_func(self, name):
        if name in self.arb_waveforms:
            if name == self.current_waveform:
                self.DC(0)
            self.write('DATA:DEL %s' % name)
            self.arb_waveforms.remove(name)
            self.waveform_list.remove(name)

    def update_waveform(self, values, name='ABS'):
        if self.model == '33120A':
            clip = lambda x: (2047*x).clip(-2047,2047).astype(int)
        elif self.model == '33220A':
            clip = lambda x: (8191*x).clip(-8191,8191).astype(int)
        values = clip(values)
        self.write_binary_values('DATA:DAC VOLATILE,', values,
                                 datatype='h', is_big_endian=True)
        if len(name) > 8:
            name = name[:8]
        name = name.upper()

        if len(self.arb_waveforms) >= 4:
            for wf in self.arb_waveforms:
                if wf != self.current_waveform:
                    self.__del_func(wf)

        self.write('DATA:COPY %s,VOLATILE' % name)

    def use_waveform(self, name, freq=None, vpp=None, offs=None, ch=1):
        freq_s = ("%.11E" % freq) if freq != None else "DEF"
        vpp_s  = ("%.5E"  % vpp)  if vpp  != None else "DEF"
        offs_s = ("%.5E"  % offs) if offs != None else "DEF"
        name = name.upper()
        if name in self.inner_waveform:
            self.write('APPL:%s %s,%s,%s' % (name, freq_s, vpp_s, offs_s))
        else:
            self.write('FUNC:USER %s' % name)
            self.write('APPL:USER %s,%s,%s' % (freq_s, vpp_s, offs_s))
        if self.trigger_source != 'IMM':
            self.set_trigger(source = self.trigger_source,
                             count  = self.trigger_count)
        self.current_waveform = name
        time.sleep(1)

    def DC(self, v):
        """输出直流电压"""
        self.write('APPL:DC DEF,DEF,%.5E' % v)
        self.current_waveform = 'DC'

    def off(self):
        self.DC(0)

    def set_trigger(self, source='IMM', count=1):
        """设置触发

        source : 触发源,可设为'IMM', 'EXT' 或 'BUS'
        count  : 脉冲串的个数
        """
        if source not in ['IMM', 'EXT', 'BUS']:
            return
        if count < 1 or count > 50000:
            return
        self.trigger_source = source
        self.write("TRIG:SOUR %s" % source)
        self.trigger_count = count
        if count != 1:
            self.write("BM:NCYC %d" % count)
        if source != 'IMM':
            self.write("BM:STAT ON")

    def refresh(self):
        """刷新波形"""
        if self.current_waveform == "DC":
            return
        if self.current_waveform not in self.inner_waveform:
            self.write("FUNC:SHAP USER")
        else:
            self.write("FUNC:SHAP %s" % self.current_waveform)