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)
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() ]
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')]), ]
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
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')
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))
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
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)
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)
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)
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)