Example #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)
Example #2
0
class Driver(BaseDriver):
    error_command = ':SYST:ERR?'
    support_models = ['E4407B']

    quants = [
        #         QOption('Sweep', value='ON',
        #             set_cmd='INIT:CONT %(option)s', options=[('OFF', 'OFF'), ('ON', 'ON')]),
        #         QOption('Trace Mode', value='WRIT',ch=1,
        #             set_cmd='TRAC%(ch)d:MODE %(option)s',get_cmd='TRAC%(ch)d:MODE?',
        #             options=[('Write', 'WRIT'), ('Maxhold', 'MAXH'),('Minhold','MINH'),
        #             ('View','VIEW'),('Blank','BLAN'),('Videoavg','VID'),('Poweravg','POW')]),
        QOption('Marker',
                value='ON',
                set_cmd=':CALCulate:MARKer1:STATe %(option)s',
                options=[('OFF', 'OFF'), ('ON', 'ON')]),
        QString('Marker_center',
                set_cmd=':CALCulate:MARKer1:CENTer %(value)s',
                get_cmd=':CALCulate:MARKer1:X?'),
        QString('Marker_amp',
                set_cmd=':CALCulate:MARKer1:Y %(value)s',
                get_cmd=':CALCulate:MARKer1:Y?'),
        QReal('Marker_right',
              set_cmd=' :CALCulate:MARKer1:MAXimum:RIGHt %(value)s',
              get_cmd=':CALCulate:MARKer1:X?'),
        # QReal('Marker_center', unit='Hz', set_cmd=':CALCulate:MARKer1:X %(value)e', get_cmd=':CALCulate:MARKer1:X?'),
        QReal('Frequency_center',
              unit='Hz',
              set_cmd=':SENSe:FREQuency:Center %(value)e%(unit)s',
              get_cmd=':SENSe:FREQuency:Center?'),
        QReal('sweep_span',
              unit='Hz',
              set_cmd=':SENSe:FREQuency:SPAN %(value)e%(unit)s',
              get_cmd=':SENSe:FREQuency:SPAN?'),
        QInteger('sweep_point',
                 set_cmd=':SENSe:SWEep:POINts %(value)d',
                 get_cmd=':SENSe:SWEep:POINts?'),
        QInteger('repeats_Average',
                 set_cmd=':SENSe:AVERage:COUNt %(value)d',
                 get_cmd=':SENSe:AVERage:COUNt?'),

        # QReal('Frequency Start', unit='Hz', set_cmd='SENS:FREQ:STAR %(value)e%(unit)s', get_cmd='SENS:FREQ:STAR?'),

        #     QReal('Frequency Stop', unit='Hz', set_cmd='SENS:FREQ:STOP %(value)e%(unit)s', get_cmd='SENS:FREQ:STOP?'),
        #     QInteger('Sweep Points',value=601, set_cmd=':SWE:POIN %(value)d',get_cmd=':SWE:POIN?')
    ]
Example #3
0
class Driver(BaseDriver):
    support_models = [
        'J7211A',
        'J7211B',
        'J7211C',
    ]
    '''Agilent Attenuation Control Unit'''

    quants = [
        QInteger('Att', unit='dB', set_cmd=':ATT %(value)d', get_cmd=':ATT?'),
    ]
Example #4
0
class Driver(BaseDriver):
    support_models = ['wx2184']

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

        QReal('Amp', unit='V',
           set_cmd=':VOLT:LEV:AMPL %(value)f',
           get_cmd=':VOLT:LEV:AMPL?'),

        QReal('Offset', unit='V',
           set_cmd=':VOLT:LEV:OFFS %(value)f',
           get_cmd=':VOLT:LEV:OFFS?'),

        QReal('Frequency', unit='Hz',
           set_cmd=':FREQ %(value)f',
           get_cmd=':FREQ?'),

        QReal('Phase', unit='Deg',
           set_cmd=':SIN:PHAS %(value)f',
           get_cmd=':SIN:PHAS?'),

        QOption('Output',
			set_cmd=':OUTP %(option)s',
			get_cmd=':OUTP?',
			options=[('OFF', 'OFF'), ('ON', 'ON')]),

        QInteger('Select_ch',value=1,unit='',
			set_cmd=':INST:SEL %(value)d',
			get_cmd=':INST:SEL?',
            ),
            #options=[('1', '1'), ('2', '2'), ('3', '3'), ('4', '4')]

        QInteger('Select_trac',value=1,unit='',
			set_cmd=':TRAC:SEL %(value)d',
			get_cmd=':TRAC:SEL?'),

            ]
    def dc(self,ch=1,offs=1.0):
        self.write(':INST:SEL CH%d' %ch)
        self.write(':FUNC:MODE FIX')
        self.write(':FUNC:SHAP DC')
        self.write(':DC %f' %offs)
        self.write(':OUTP ON')

    def sin(self,ch=1,freq=2e8,amp=0.5,offs=0.0,phas=0):
        self.write(':INST:SEL CH%d' %ch)
        self.write(':FUNC:MODE FIX')
        self.write(':FUNC:SHAP SIN')
        self.write(':FREQ %f' %freq)
        self.write(':VOLT:LEV:AMPL %f' %amp)
        self.write(':VOLT:LEV:OFFS %f' %offs)
        self.write(':SIN:PHAS %f' %phas)
        self.write(':OUTP ON')

    def reset(self,samplerate=2.3e9):
        self.write('*CLS')
        self.write('*RST')
        #选择特定function
        self.write(':FUNC:MODE USER')
        #设置采样率
        self.write(':FREQ:RAST %d' %samplerate)
        #设置外部时钟
        self.write(':ROSCillator:SOURce EXTernal')
        #清除原有波形
        self.write(':INST:SEL CH1')
        self.write(':TRAC:DEL:ALL')
        self.write(':INST:SEL CH3')
        self.write(':TRAC:DEL:ALL')
        #将几个通道的设置设为同一个,详见manual
        # self.write(':INST:COUPle:STATe ON')
        # self.write(':INIT:CONT OFF')
        # self.write(':TRIG:COUN 1')
        # self.write('enable')

    #创建波形文件
    def crwave(self,segment_num,sample_num):
        self.write(':TRAC:DEF %d,%d' %(segment_num,sample_num))

    #在创建好的波形文件中,写入或者更新具体波形
    def upwave(self,points,ch=1,trac=1):
        pointslen=len(points)
        pointslen2=2*pointslen
        #选择特定function
        self.write(':FUNC:MODE USER')
        #选择特定channel
        self.write(':INST:SEL %d' %ch)
        #定义特定的segment
        self.write(':TRAC:DEF %d,%d' %(trac,pointslen))
        #选择特定的segment
        self.write(':TRAC:SEL %d' %trac)
        #选择模式为SINGLE,(包括DUPLicate,SINGle等,详见manual)
        self.write(':TRAC:MODE SING' )
        #写入波形数据
        message=':TRAC:DATA'# % (len(str(pointslen2)),pointslen2)
        points = points.clip(-1,1)
        values=np.zeros(pointslen).astype(np.uint16)
        #乘积选用8191是为了防止最终值大于16383
        values = (points * 8191).astype(np.uint16)+8192 #.astype(np.uint16)
        byte=np.zeros(pointslen2).astype(np.uint8)
        #将原先的两比特数据点,分割为高低两个比特
        byte[0:pointslen2:2]=(values & 0b11111111).astype(np.uint8)
        byte[1:pointslen2:2]=((values & 0b11111100000000) >> 8).astype(np.uint8)
        #write_binary_value中的message参数不要包括#42048的信息,因为pyvisa可以自动算出结果。详见pyvisa中util.py内的to_binary_block
        #wx2184选用little_endian。这表示程序按照我给的顺序将二进制包写进去
        self.write_binary_values(message, byte, datatype='B',is_big_endian=False,termination=None, encoding=None)
        # self.write('enable' )

	#运行波形
    def ruwave(self,amp=2,offset=0,ch=1,trac=1,trigdelay=0):
        self.write(':INST:SEL %d' %ch)
        self.write(':VOLT:LEV:AMPL %f' %amp)
        self.write(':VOLT:LEV:OFFS %f' %offset)
        self.write(':TRAC:SEL %d' %trac)
        self.write(':OUTP ON')
        self.write(':INIT:CONT OFF')
        self.write(':TRIG:COUN 1')
        self.write(':TRIG:DEL %d' %trigdelay)

    def ruwave1(self,amp=2,offset=0,ch=1,trac=1):
        self.write(':INST:SEL %d' %ch)
        self.write(':VOLT:LEV:AMPL %f' %amp)
        self.write(':VOLT:LEV:OFFS %f' %offset)
        self.write(':TRAC:SEL %d' %trac)
        self.write(':OUTP ON')
        self.write(':INIT:CONT ON')

    def ruwave2(self,amp=2,ch=1,trac=1):
        self.write(':INST:SEL %d' %ch)
        self.write(':VOLT:LEV:AMPL %f' %amp)
        self.write(':TRAC:SEL %d' %trac)
        self.write(':OUTP ON')
        self.write(':INIT:CONT OFF')
        self.write(':TRIG:COUN 1')
class Driver(BaseDriver):
    support_models = [
        'M3202A',
    ]

    quants = [
        QReal('Amplitude', value=1, unit='V', ch=0),
        #DC WaveShape
        QReal('Offset', value=0, unit='V', ch=0),
        #Function Generators(FGs) mode
        QReal('Frequency', unit='Hz', ch=0),
        QReal('Phase', value=0, unit='deg', ch=0),
        QOption('WaveShape',
                ch=0,
                value='HIZ',
                options=[('HIZ', -1), ('NoSignal', 0), ('Sin', 1),
                         ('Triangular', 2), ('Square', 4), ('DC', 5),
                         ('AWG', 6), ('PartnerCH', 8)]),
        #clock
        QReal('clockFrequency', unit='Hz'),
        QReal('clockSyncFrequency', unit='Hz'),
        # 板卡向外输出的时钟,默认状态关闭
        QOption('clockIO', value='OFF', options=[('OFF', 0), ('ON', 1)]),
        QOption('triggerIO',
                value='SyncIN',
                options=[('noSyncOUT', (0, 0)), ('SyncOUT', (0, 1)),
                         ('noSyncIN', (1, 0)), ('SyncIN', (1, 1))]),
        QOption('triggerMode',
                value='ExternalCycle',
                ch=0,
                options=[('Auto', 0), ('SWtri', 1), ('SWtriCycle', 5),
                         ('External', 2), ('ExternalCycle', 6)]),
        QOption('triExtSource',
                value='EXTERN',
                ch=0,
                options=[('EXTERN', 0), ('PXI0', 4000), ('PXI1', 4001),
                         ('PXI2', 4002), ('PXI3', 4003), ('PXI4', 4004),
                         ('PXI5', 4005), ('PXI6', 4006), ('PXI7', 4007)]),
        QOption('triggerBehavior',
                value='RISE',
                ch=0,
                options=[('NONE', 0), ('HIGH', 1), ('LOW', 2), ('RISE', 3),
                         ('FALL', 4)]),
        # Defines the delay between the trigger and the waveform launch in tens of ns
        QInteger(
            'startDelay',
            value=0,
            unit='ns',
            ch=0,
        ),
        # Number of times the waveform is repeated once launched (negative means infinite)
        QInteger(
            'cycles',
            value=0,
            ch=0,
        ),
        # Waveform prescaler value, to reduce the effective sampling rate
        QInteger(
            'prescaler',
            value=0,
            ch=0,
        ),
        QOption('Output',
                ch=0,
                value='Close',
                options=[('Stop', 0), ('Run', 1), ('Pause', 2), ('Resume', 3),
                         ('Close', -1)]),
        QList('WList', value=[]),
        QList('SList', value=[], ch=0),
    ]
    #CHs : 仪器通道
    # CHs=[0,1,2,3]
    CHs = [1, 2, 3, 4]

    # config : 用来存储参数配置,防止由于多通道引起的混乱
    config = {}

    def __init__(self, **kw):
        BaseDriver.__init__(self, **kw)
        self.chassis = kw['CHASSIS']
        self.slot = kw['SLOT']

    def newcfg(self):
        self.config = {}
        for q in self.quants:
            _cfg = {q.name: {}}
            if q.ch is not None:
                for i in self.CHs:
                    _cfg[q.name].update(
                        {i: {
                            'value': q.value,
                            'unit': q.unit
                        }})
            else:
                _cfg[q.name].update({0: {'value': q.value, 'unit': q.unit}})
            self.config.update(_cfg)
        log.info('new config!')

    def loadcfg(self, file=None):
        if file == None:
            file = self.caches_file
        with open(file, 'r', encoding='utf-8') as f:
            self.config = yaml.load(f)
        log.info('load config: %s', file)

    def savecfg(self, file=None):
        if file == None:
            file = self.caches_file
        with open(file, 'w', encoding='utf-8') as f:
            yaml.dump(self.config, f)
        log.info('save config: %s', file)

    def performOpen(self):
        #SD_AOU module
        self.AWG = inspur_sd.SD_AOU()
        self.model = self.AWG.getProductNameBySlot(self.chassis, self.slot)
        moduleID = self.AWG.openWithSlot(self.model, self.chassis, self.slot)
        if moduleID < 0:
            print("Module open error:", moduleID)
        self.caches_file = caches_dir() / (self.model + '_config_caches.yaml')
        try:
            self.loadcfg()
        except Exception:
            log.exception(Exception)
            self.newcfg()
            self.savecfg()

    def performClose(self):
        """Perform the close instrument connection operation"""
        # refer labber driver keysight_pxi_awg.py
        # do not check for error if close was called with an error
        try:
            #             print('0')
            #             print('3')
            #             print('13')
            self.setValue('clockIO', 'OFF')
            #             print('2')
            # clear old waveforms and stop awg
            self.waveformFlush()
            #             print('4')
            for ch in self.CHs:
                #                 print('5')
                self.closeCh(ch)
            # close instrument
            # self.AWG.close()
#             print('6')
            self.savecfg()
#             print('7')
        except Exception:
            #             print('1')
            # never return error here
            pass

    def closeCh(self, ch=0):
        #         print('8')
        self.AWG.AWGstop(ch)
        #         print('9')
        self.AWG.AWGflush(ch)
        #         print('10')
        self.config['SList'][ch]['value'] = []
        #         print('11')
        self.AWG.channelWaveShape(ch, -1)
        #         print('12')
        self.config['WaveShape'][ch]['value'] = 'HIZ'
        self.config['Output'][ch]['value'] = 'Close'

    def performSetValue(self, quant, value, ch=0, **kw):
        _cfg = {}
        if quant.name == 'Amplitude':
            self.AWG.channelAmplitude(ch, value)
        elif quant.name == 'Offset':
            self.AWG.channelOffset(ch, value)
        elif quant.name == 'Frequency':
            self.AWG.channelFrequency(ch, value)
        elif quant.name == 'Phase':
            self.phaseReset(ch)
            self.AWG.channelPhase(ch, value)
        elif quant.name == 'WaveShape':
            options = dict(quant.options)
            self.AWG.channelWaveShape(ch, options[value])
        elif quant.name == 'clockFrequency':
            mode = kw.get('mode', 1)
            self.AWG.clockSetFrequency(value, mode)
            ch = 0
        elif quant.name == 'clockIO':
            options = dict(quant.options)
            self.AWG.clockIOconfig(options[value])
            ch = 0
        elif quant.name == 'triggerIO':
            options = dict(quant.options)
            self.AWG.triggerIOconfigV5(*options[value])
            ch = 0
        elif quant.name == 'Output':
            if value == 'Stop':
                self.AWG.AWGstop(ch)
            elif value == 'Run':
                self.AWG.AWGstart(ch)
            elif value == 'Pause':
                self.AWG.AWGpause(ch)
            elif value == 'Resume':
                self.AWG.AWGresume(ch)
            elif value == 'Close':
                self.closeCh(ch)
        elif quant.name == 'clockSyncFrequency':
            print("clockSyncFrequency can't be set")
            return
        _cfg['value'] = value
        self.config[quant.name][ch].update(_cfg)

    def performGetValue(self, quant, ch=0, **kw):
        _cfg = {}
        if quant.name == 'clockFrequency':
            value = self.AWG.clockGetFrequency()
            ch = 0
            _cfg['value'] = value
        elif quant.name == 'clockSyncFrequency':
            value = self.AWG.clockGetSyncFrequency()
            ch = 0
            _cfg['value'] = value
        elif quant.name in ['clockIO', 'triggerIO']:
            ch = 0
        self.config[quant.name][ch].update(_cfg)
        return self.config[quant.name][ch]['value']

    def phaseReset(self, ch=0):
        self.AWG.channelPhaseReset(ch)
        _cfg = {'value': 0}
        self.config['Phase'][ch].update(_cfg)

    def clockResetPhase(self):
        # self.AWG.clockResetPhase(triggerBehavior, triggerSource, skew = 0.0)
        pass

    def newWaveform(self, file_arrayA, arrayB=None, waveformType=0):
        '''Memory usage: Waveforms created with New are stored in the PC RAM,
        not in the module onboard RAM. Therefore, the limitation in the number
        of waveforms and their sizes is given by the amount of PC RAM.'''
        # waveformType 0: Analog 16Bits, Analog normalized waveforms (-1..1) defined with doubles
        # please refer AWG Waveform types about others
        wave = inspur_sd.SD_Wave()
        if isinstance(file_arrayA, str):
            wave.newFromFile(file_arrayA)
            return wave
        else:
            # 5: DigitalType, Digital waveforms defined with integers
            if waveformType == 5:
                wave.newFromArrayInteger(waveformType, file_arrayA, arrayB)
            else:
                wave.newFromArrayDouble(waveformType, file_arrayA, arrayB)
            return wave

    def waveformLoad(self, waveform, num, paddingMode=0):
        '''num: waveform_num, 在板上内存的波形编号'''
        if num in self.config['WList'][0]['value']:
            self.AWG.waveformReLoad(waveform, num, paddingMode)
        else:
            # This function replaces a waveform located in the module onboard RAM.
            # The size of the newwaveform must be smaller than or equal to the existing waveform.
            self.AWG.waveformLoad(waveform, num, paddingMode)
            self.config['WList'][0]['value'].append(num)

    # def waveformReLoad(self, waveform, num, paddingMode = 0):
    #     '''This function replaces a waveform located in the module onboard RAM.
    #     The size of the newwaveform must be smaller than or equal to the existing waveform.'''
    #     self.AWG.waveformReLoad(waveform, num, paddingMode)

    def waveformFlush(self):
        '''This function deletes all the waveforms from the module onboard RAM
        and flushes all the AWG queues'''
        #         print('14')
        self.AWG.waveformFlush()
        #         print('15')
        self.config['WList'][0]['value'] = []
#         print('16')
#         self.config['SList'][0]['value']=[]
#         print('17')

    def AWGflush(self, ch=0):
        '''This function empties the queue of the selected Arbitrary Waveform Generator,
        Waveforms are not removed from the module onboard RAM.'''
        self.AWG.AWGflush(ch)
        self.config['SList'][0]['value'] = []

    def _getParams(self, ch):
        triggerModeIndex = self.getValue('triggerMode', ch=ch)
        triggerModeOptions = self.quantities['triggerMode'].options
        triggerMode = dict(triggerModeOptions)[triggerModeIndex]

        if triggerModeIndex in ['External', 'ExternalCycle']:

            triExtSourceIndex = self.getValue('triExtSource', ch=ch)
            triExtSourceOptions = self.quantities['triExtSource'].options
            triExtSource = dict(triExtSourceOptions)[triExtSourceIndex]
            if triExtSourceIndex in ['EXTERN']:
                # 若未设置过,则从config读取默认配置;若已设置,则结果不变
                triggerIO = self.getValue('triggerIO')
                self.setValue('triggerIO', triggerIO)

            triggerBehaviorIndex = self.getValue('triggerBehavior', ch=ch)
            triggerBehaviorOptions = self.quantities['triggerBehavior'].options
            triggerBehavior = dict(
                triggerBehaviorOptions)[triggerBehaviorIndex]

            self.AWG.AWGtriggerExternalConfig(ch, triExtSource,
                                              triggerBehavior)

        startDelay = self.getValue('startDelay', ch=ch)
        cycles = self.getValue('cycles', ch=ch)
        prescaler = self.getValue('prescaler', ch=ch)

        return triggerMode, startDelay, cycles, prescaler

    def AWGqueueWaveform(self, ch=0, waveform_num=0):
        self.setValue('WaveShape', 'AWG', ch=ch)
        Amplitude = self.getValue('Amplitude', ch=ch)
        self.setValue('Amplitude', Amplitude, ch=ch)

        triggerMode, startDelay, cycles, prescaler = self._getParams(ch)

        self.AWG.AWGqueueWaveform(ch, waveform_num, triggerMode, startDelay,
                                  cycles, prescaler)
        self.config['SList'][ch]['value'].append(waveform_num)

    def AWGrun(self,
               file_arrayA,
               arrayB=None,
               ch=0,
               waveformType=0,
               paddingMode=0):
        '''从文件或序列快速产生波形'''
        print('0')
        self.setValue('WaveShape', 'AWG', ch=ch)
        print('1')
        Amplitude = self.getValue('Amplitude', ch=ch)
        print('2')
        self.setValue('Amplitude', Amplitude, ch=ch)
        print('3')

        triggerMode, startDelay, cycles, prescaler = self._getParams(ch)
        print('4')

        if isinstance(file_arrayA, str):
            # AWGFromFile 有bug
            self.AWG.AWGFromFile(ch, file_arrayA, triggerMode, startDelay,
                                 cycles, prescaler, paddingMode)
        else:
            print('5')
            self.AWG.AWGfromArray(ch, triggerMode, startDelay, cycles,
                                  prescaler, waveformType, file_arrayA, arrayB,
                                  paddingMode)
            print('6')
        self.config['Output'][ch]['value'] = 'Run'
        print('7')
Example #6
0
class Driver(BaseDriver):
    support_models = ['E8363B', 'E8363C', 'E5071C', 'ZNB20-2Port', 'N5232A']

    quants = [
        QReal('Power',
              value=-20,
              unit='dBm',
              set_cmd='SOUR:POW %(value)e%(unit)s',
              get_cmd='SOUR:POW?'),
        QReal('Frequency center',
              value=5e9,
              unit='Hz',
              set_cmd='SENS:FREQ:CENT %(value)e%(unit)s',
              get_cmd='SENS:FREQ:CENT?'),
        QReal('Frequency span',
              value=2e9,
              unit='Hz',
              set_cmd='SENS:FREQ:SPAN %(value)e%(unit)s',
              get_cmd='SENS:FREQ:SPAN?'),
        QReal('Frequency start',
              value=4e9,
              unit='Hz',
              set_cmd='SENS:FREQ:STAR %(value)e%(unit)s',
              get_cmd='SENS:FREQ:STAR?'),
        QReal('Frequency stop',
              value=6e9,
              unit='Hz',
              set_cmd='SENS:FREQ:STOP %(value)e%(unit)s',
              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')
        if self.model in ['E5071C']:
            self.write(':FORM:DATA ASC')
            cmd = ("CALC%d:DATA:FDATA?" %
                   ch) if formated else ("CALC%d:DATA:SDATA?" % ch)
        else:
            self.write('FORMAT ASCII')
            cmd = ("CALC%d:DATA? FDATA" %
                   ch) if formated else ("CALC%d:DATA? SDATA" % ch)
        data = np.asarray(self.query_ascii_values(cmd))
        if formated:
            if self.model in ['E5071C']:
                data = data[::2]
        else:
            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 in ['E5071C']:
            return
        if self.model in ['E8363C', 'E8363B', 'N5232A']:
            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?'
            return np.asarray(self.query_ascii_values(cmd))
        if self.model in ['E8363B', 'N5232A']:
            freq_star = self.getValue('Frequency start')
            freq_stop = self.getValue('Frequency stop')
            num_of_point = self.getValue('Number of points')
            return np.array(np.linspace(freq_star, freq_stop, num_of_point))
        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))
Example #7
0
class Driver(BaseDriver):
    error_command = 'SYST:ERR?'
    support_models = ['FSL18']

    quants = [
        QOption('Sweep', value='ON',
            set_cmd='INIT:CONT %(option)s', options=[('OFF', 'OFF'), ('ON', 'ON')]),
        QOption('Trace Mode', value='WRIT',ch=1,
            set_cmd='DISP:TRAC%(ch)d:MODE %(option)s',get_cmd='DISP:TRAC%(ch)d:MODE?',
            options=[('Write', 'WRIT'), ('Maxhold', 'MAXH'),('Minhold','MINH'),
            ('View','VIEW'),('Average','AVER')]),

        QReal('Frequency Start', unit='Hz', set_cmd='SENS:FREQ:STAR %(value)e%(unit)s', get_cmd='SENS:FREQ:STAR?'),
        QReal('Frequency Stop', unit='Hz', set_cmd='SENS:FREQ:STOP %(value)e%(unit)s', get_cmd='SENS:FREQ:STOP?'),
        QInteger('Sweep Points',value=601, set_cmd='SENS:SWE:POIN %(value)d',get_cmd='SENS:SWE:POIN?')
    ]

    def get_Trace(self, average=1, ch=1):
        '''Get the Trace Data '''

        points=self.getValue('Sweep Points')
        #Stop the sweep
        self.setValue('Sweep', 'OFF')
        if average==1:
            self.setValue('Trace Mode','Write',ch=ch)
            self.write(':SWE:COUN 1')
        else:
            self.setValue('Trace Mode','Average',ch=ch)
            self.write(':TRAC:AVER:COUN %d' % average)
            self.write(':SWE:COUN %d' % average)
            self.write(':TRAC:AVER:RES')
        #Begin a measurement
        self.write('INIT:IMM')
        self.write('*WAI')
        count=float(self.query('SWE:COUN:CURR?'))
        while  count < average:
            count=float(self.query('SWE:COUN:CURR?'))
            time.sleep(0.01)
        #Get the data
        self.write('FORMAT:BORD NORM')
        self.write('FORMAT ASCII')
        data = self.query_ascii_values("TRAC:DATA? TRACE%d" % ch)
        # data_raw = self.query("TRAC:DATA? TRACE%d" % ch).strip('\n')
        # _data = re.split(r",",data_raw[11:])
        # data=[]
        # for d in _data[:points]:
        #     data.append(float(d))
        #Start the sweep
        self.setValue('Sweep', 'ON')
        return np.array(data)


    def get_Frequency(self):
        """Return the frequency of DSA measurement"""

        freq_star=self.getValue('Frequency Start')
        freq_stop=self.getValue('Frequency Stop')
        sweep_point=self.getValue('Sweep Points')
        return np.array(np.linspace(freq_star,freq_stop,sweep_point))

    def get_SNR(self,signalfreqlist=[],signalbandwidth=10e6,average=1, ch=1):
        '''get SNR_dB '''

        Y_unit =self.query(':UNIT:POW?;:UNIT:POW W').strip('\n')
        Frequency=self.get_Frequency()
        Spectrum=self.get_Trace(average=average, ch=ch)
        Signal_power=0
        Total_power=sum(Spectrum)
        for sf in signalfreqlist:
            for f in Frequency :
                if f > (sf-signalbandwidth/2) and f < (sf+signalbandwidth/2):
                    index = np.where(Frequency==f)
                    Signal_power = Signal_power + Spectrum[index]
        self.write(':UNIT:POW %s'%Y_unit)
        _SNR=Signal_power/(Total_power-Signal_power)
        SNR = 10*np.log10(_SNR)
        return SNR