示例#1
0
        def measure_point(Ithresh=np.inf):
            print('Setting Vg=' + str(Vg) + ' V...')
            sourceVg.set_voltage(Vg)
            print('Stabilising...')
            progressbar_wait(stabilise_time)

            # measure
            Vgm = sourceVg.get_voltage()
            Ileak = sourceVg.get_current()

            # save data
            self.save_row(locals())

            # save VNA data
            if use_vna:
                # save VNA data
                print("Getting VNA spectra...")
                vna.single_sweep(wait=False)
                # display sweep progress
                progressbar_wait(sweeptime)
                # make sure sweep is really done
                while not vna.is_sweep_done():
                    time.sleep(0.5)
                table = vna.get_table([1, 2, 3, 4])
                timestamp = time.strftime('%Y-%m-%d_%Hh%Mm%Ss')
                spectrum_file = timestamp + '_Vg={:.3f}.txt'.format(Vg)
                np.savetxt(os.path.join(spectra_fol, spectrum_file),
                           np.transpose(table))

            return np.abs(Ileak) > Ithresh
示例#2
0
    def measure(self, data_dir, Vg1s, Vg2s, Vds, commongate, Rg1, Rg2, Rds,
                stabilise_time, **kwargs):
        print("Starting acquisition script...")
        print(
            "Because I need to save my data somewhere, I will save it in the following directory:"
        )
        print(data_dir)

        # initialise instruments
        try:
            self.sourceVg1 = sourceVg1 = VoltageSource(
            )  # here we should add safety limits
            self.sourceVg2 = sourceVg2 = VoltageSource()
            self.sourceVds = sourceVds = VoltageSource()
            self.meterVg1 = meterVg1 = VoltMeter()
            self.meterVg2 = meterVg2 = VoltMeter()
            self.meterVds = meterVds = VoltMeter()
        except:
            print("There has been an error setting up one of the instruments.")
            raise

        # prepare saving data
        filename = time.strftime('%Y-%m-%d_%Hh%Mm%Ss') + '.txt'
        self.prepare_saving('testdata/' + filename)

        # loops
        sourceVds.set_voltage(Vds)
        for Vg2 in Vg2s:
            sourceVg2.set_voltage(Vg2)
            for Vg1 in Vg1s:
                if self.flags['quit_requested']:
                    return locals()

                sourceVg1.set_voltage(Vg1)

                # stabilise
                progressbar_wait(stabilise_time)

                # measure
                Vg1m = meterVg1.get_voltage()
                Vg2m = meterVg2.get_voltage()
                Vdsm = meterVds.get_voltage()

                # do calculations
                Ileak1 = (Vg1 - Vg1m) / Rg1
                Ileak2 = (Vg2 - Vg2m) / Rg2
                Rs = Rds * Vdsm / (Vds - Vdsm)

                # save data
                self.save_row(locals())

        print("Acquisition done.")

        return locals()
示例#3
0
    def measure(self, data_dir, Vgs, Vchucks, Rg, comment, stabilise_time,
                stab_chuck_time, use_vna, init_bilt, **kwargs):
        print("===================================")
        print("Starting acquisition script...")

        chuck_string = ''
        vna_string = ''

        # initialise instruments
        print("Setting up DC sources and voltmeters...")
        bilt = Bilt('TCPIP0::192.168.0.2::5025::SOCKET')
        if init_bilt:
            # source (bilt, channel, range, filter, slope in V/ms, label):
            self.sourceVg = sourceVg = BiltVoltageSource(
                bilt, "I1", "12", "1", 0.005, "Vg")
        else:
            self.sourceVg = sourceVg = BiltVoltageSource(bilt,
                                                         "I1",
                                                         initialise=False)
        # voltmeter (bilt, channel, filt, label=None)
        self.meterVg = meterVg = BiltVoltMeter(bilt, "I5;C1", "2", "Vgm")
        print("DC sources and voltmeters are set up.")

        print("Setting up Yokogawa for chuck voltage...")
        # connect to the Yoko without initialising, this will lead to
        # an exception if the Yoko is not properly configured (voltage
        # source, range 30V, output ON)
        self.yoko = yoko = Yoko7651('GPIB::3::INSTR',
                                    initialise=False,
                                    rang=30,
                                    slope=1.)
        print("Yokogawa is set up.")

        if use_vna:
            print("Setting up VNA...")
            vna = AnritsuVNA('GPIB::6::INSTR')
            sweeptime = vna.get_sweep_time()

            if vna.get_sweep_type() != 'FSEGM':
                raise Exception('Please use segmented frequency sweep')

            # check if the RF power is the same on both ports and for all
            # frequency segments
            count = int(vna.query(':SENS:FSEGM:COUN?'))
            vna_pow = None
            for i in range(1, count + 1):
                port1pow = float(
                    vna.query(':SENS:FSEGM{}:POW:PORT1?'.format(i)))
                port2pow = float(
                    vna.query(':SENS:FSEGM{}:POW:PORT2?'.format(i)))
                if vna_pow is None and port1pow == port2pow:
                    vna_pow = port1pow
                elif vna_pow is not None and port1pow == port2pow and port1pow == vna_pow:
                    continue
                else:
                    raise Exception(
                        "Please select the same power for all ports and frequency segments"
                    )
            port1att = vna.get_source_att(1)
            port2att = vna.get_source_att(2)
            if port1att == port2att:
                vna_pow -= port1att
            else:
                raise Exception(
                    "Please select the same attenuators for both ports")
            vna_string = '_pwr={:.0f}'.format(vna_pow)

            print("VNA is set up.")

        # prepare saving DC data
        timestamp = time.strftime('%Y-%m-%d_%Hh%Mm%Ss')
        filename = timestamp + vna_string + ('_' + comment if comment else '')
        self.prepare_saving(os.path.join(data_dir, filename + '.txt'))

        if use_vna:
            # prepare saving RF data
            spectra_fol = os.path.join(data_dir, filename)
            create_path(spectra_fol)
            # save segmented frequency sweep data to file
            with open(os.path.join(spectra_fol, 'VNAconfig'), 'w') as f:
                vna.dump_freq_segments(f)

        for Vchuck in Vchucks:
            print("Setting Vchuck = {}".format(Vchuck))

            # set Vchuck
            yoko.set_voltage(Vchuck)

            # wait
            time.sleep(stab_chuck_time)

            for Vg in Vgs:
                if self.flags['quit_requested']:
                    print("Stopping acquisition.")
                    return locals()

                print("Setting Vg = {}".format(Vg))

                # set Vg
                sourceVg.set_voltage(Vg)

                # wait
                time.sleep(stabilise_time)

                # read voltages
                Vgm = meterVg.get_voltage()

                # do calculations
                Ileak = (Vg - Vgm) / Rg

                # save DC data
                self.save_row(locals())

                if use_vna:
                    # save VNA data
                    print("Getting VNA spectra...")
                    vna.single_sweep(wait=False)
                    # display sweep progress
                    progressbar_wait(sweeptime)
                    # make sure sweep is really done
                    while not vna.is_sweep_done():
                        time.sleep(0.5)
                    table = vna.get_table([1, 2, 3, 4])
                    timestamp = time.strftime('%Y-%m-%d_%Hh%Mm%Ss')
                    spectrum_file = timestamp + '_Vg={:.3f}_Vchuck={:.1f}.txt'.format(
                        Vg, Vchuck)
                    np.savetxt(os.path.join(spectra_fol, spectrum_file),
                               np.transpose(table))

        print("Acquisition done.")

        return locals()
示例#4
0
    def measure(self, data_dir, Vgs, Rg, comment, stabilise_time, use_vna,
                use_chuck, init_bilt, **kwargs):
        print("===================================")
        print("Starting acquisition script...")

        chuck_string = ''
        vna_string = ''

        # initialise instruments
        print("Setting up DC sources and voltmeters...")
        bilt = Bilt('TCPIP0::192.168.0.2::5025::SOCKET')
        if init_bilt:
            # source (bilt, channel, range, filter, slope in V/ms, label):
            self.sourceVg = sourceVg = BiltVoltageSource(
                bilt, "I1", "12", "1", 0.005, "Vg")
        else:
            self.sourceVg = sourceVg = BiltVoltageSource(bilt,
                                                         "I1",
                                                         initialise=False)
        # voltmeter (bilt, channel, filt, label=None)
        self.meterVg = meterVg = BiltVoltMeter(bilt, "I5;C1", "2", "Vgm")
        print("DC sources and voltmeters are set up.")

        if use_chuck:
            print("Setting up Yokogawa for chuck voltage...")
            # connect to the Yoko without initialising, this will lead to
            # an exception if the Yoko is not properly configured (voltage
            # source, range 30V, output ON)
            yoko = Yoko7651('GPIB::3::INSTR', initialise=False, rang=30)
            chuck_string = '_Vchuck={:.1f}'.format(yoko.get_voltage())
            print("Yokogawa is set up.")

        if use_vna:
            print("Setting up VNA")
            self.vna = vna = RohdeSchwarzVNA()
            vna.open('GPIB', '20')

            c1 = vna.channel(1)
            sweeptime = c1.total_sweep_time_ms
            c1.manual_sweep = True
            c1.s_parameter_group = c1.to_logical_ports((1, 2))
            # cf: https://www.rohde-schwarz.com/webhelp/webhelp_zva/program_examples/basic_tasks/typical_stages_of_a_remote_control_program.htm#Command_Synchronization
            vna.write("*SRE 32")
            vna.write("*ESE 1")

            if not c1.sweep_type == 'SEGM':  # need to use not == because != is not implemented in Rohde Schwarz library
                raise Exception('Please use segmented frequency sweep')

            # check if the RF power is the same on both ports and for all
            # frequency segments
            count = int(vna.query(':SENS:SEGM:COUN?').strip())
            vna_pow = None
            for i in range(1, count + 1):
                seg_pow = float(vna.query(':SENS:SEGM{}:POW?'.format(i)))
                if vna_pow is None:
                    vna_pow = seg_pow
                elif vna_pow is not None and seg_pow == vna_pow:
                    continue
                else:
                    raise Exception(
                        "Please select the same power for all ports and frequency segments"
                    )
            port1autoatt = int(vna.query(':SOUR:POW1:ATT:AUTO?').strip())
            port2autoatt = int(vna.query(':SOUR:POW2:ATT:AUTO?').strip())
            if port1autoatt or port2autoatt:
                raise Exception("Please do not use automatic attenuators")
            port1att = float(vna.query(':SOUR:POW1:ATT?').strip())
            port2att = float(vna.query(':SOUR:POW2:ATT?').strip())
            if port1att == port2att:
                vna_pow -= port1att
            else:
                raise Exception(
                    "Please select the same attenuators for both ports")
            vna_string = '_pwr={:.0f}'.format(vna_pow)

            print("VNA is set up.")

        # prepare saving DC data
        timestamp = time.strftime('%Y-%m-%d_%Hh%Mm%Ss')
        filename = timestamp + vna_string + chuck_string + ('_' + comment
                                                            if comment else '')
        self.prepare_saving(os.path.join(data_dir, filename + '.txt'))

        if use_vna:
            # prepare saving RF data
            spectra_fol = os.path.join(data_dir, filename)
            create_path(spectra_fol)

            with open(os.path.join(spectra_fol, 'VNAconfig'), 'w') as f:
                f.write(
                    '# Frequency based segmented sweep setup of Rohde&Schwarz ZVA 67\n'
                )
                f.write('# Attenuator Port 1: {}\n'.format(port1att))
                f.write('# Attenuator Port 2: {}\n'.format(port2att))
                f.write('# Seg no.\tfstart\tfstop\tpoints\tbwidth\tpow\n')
                count = int(vna.query(':SENS:SEGM:COUN?').strip())
                for i in range(1, count + 1):
                    seg_pow = float(
                        vna.query(':SENS:SEGM{}:POW?'.format(i)).strip())
                    bwidth = float(
                        vna.query(':SENS:SEGM{}:BWID?'.format(i)).strip())
                    fstart = float(
                        vna.query(':SENS:SEGM{}:FREQ:STAR?'.format(i)).strip())
                    fstop = float(
                        vna.query(':SENS:SEGM{}:FREQ:STOP?'.format(i)).strip())
                    points = int(
                        vna.query(':SENS:SEGM{}:SWE:POIN?'.format(i)).strip())
                    f.write('{:d}\t{:f}\t{:f}\t{:d}\t{:f}\t{:f}\n'.format(
                        i, fstart, fstop, points, bwidth, seg_pow))

        for Vg in Vgs:
            if self.flags['quit_requested']:
                print("Stopping acquisition.")
                return locals()

            print("Setting Vg = {}".format(Vg))

            # set Vg
            sourceVg.set_voltage(Vg)

            # wait
            time.sleep(stabilise_time)

            # read voltages
            Vgm = meterVg.get_voltage()

            # do calculations
            Ileak = (Vg - Vgm) / Rg

            # save DC data
            self.save_row(locals())

            if use_vna:
                # save VNA data
                print("Getting VNA spectra...")

                vna.write("INIT1:IMM; *OPC")
                # display sweep progress
                progressbar_wait(sweeptime / 1e3)
                # make sure sweep is really done
                while not int(vna.query("*ESR?").strip()):
                    time.sleep(0.5)

                timestamp = time.strftime('%Y-%m-%d_%Hh%Mm%Ss')
                spectrum_file = timestamp + '_Vg=%2.4f' % (Vg)
                #vna.channel(1).save_measurement_locally(os.path.join(spectra_fol, spectrum_file), (1,2))
                spectrum_file = os.path.join(spectra_fol,
                                             spectrum_file + '.s2p')

                unique_filename = unique_alphanumeric_string() + '.s2p'

                scpi = ":MMEM:STOR:TRAC:PORT {0},'{1}',{2},{3}"
                scpi = scpi.format(1, \
                                   unique_filename, \
                                   'COMP', \
                                   '1,2')
                vna.write(scpi)
                # this saves the file on the ZVA in the folder
                # C:\Rohde&Schwarz\Nwa\
                vna.pause(5000)

                vna.file.download_file(unique_filename, spectrum_file)
                vna.file.delete(unique_filename)

        print("Acquisition done.")

        return locals()
示例#5
0
    def measure(self, Vgs, stabilise_time, init, use_vna, data_dir, comment, **kwargs):
        print("===================================")
        print("Starting acquisition script...")
        
        vna_string = ''

        # initialise instruments
        try:
            print("----------------------------------------")
            print("Setting up Keithley DC sources...")
            self.sourceVg = sourceVg = K2400('GPIB::24::INSTR', sourcemode='v', vrang=200, irang=10e-6, slope=1, initialise=init)
            print("DC sources are set up.")
        except:
            print("There has been an error setting up DC sources.")
            raise
        
        if use_vna:
            print("Setting up VNA...")
            vna = AnritsuVNA('GPIB::6::INSTR')
            sweeptime = vna.get_sweep_time()
            
            if vna.get_sweep_type() != 'FSEGM':
                raise Exception('Please use segmented frequency sweep')

            # check if the RF power is the same on both ports and for all
            # frequency segments
            count = int(vna.query(':SENS:FSEGM:COUN?'))
            vna_pow = None
            for i in range(1,count+1):
                port1pow = float(vna.query(':SENS:FSEGM{}:POW:PORT1?'.format(i)))
                port2pow = float(vna.query(':SENS:FSEGM{}:POW:PORT2?'.format(i)))
                if vna_pow is None and port1pow == port2pow:
                    vna_pow = port1pow
                elif vna_pow is not None and port1pow == port2pow and port1pow == vna_pow:
                    continue
                else:
                    raise Exception("Please select the same power for all ports and frequency segments")
            port1att = vna.get_source_att(1)
            port2att = vna.get_source_att(2)
            if port1att == port2att:
                vna_pow -= port1att
            else:
                raise Exception("Please select the same attenuators for both ports")
            vna_string = '_pwr={:.0f}'.format(vna_pow)
            
            print("VNA is set up.")
                
        # define name
        timestamp = time.strftime('%Y-%m-%d_%Hh%Mm%Ss')
        filename = timestamp + vna_string  + ('_'+comment if comment else '')

        # prepare saving RF data
        spectra_fol = os.path.join(data_dir, filename)
        create_path(spectra_fol)

        # prepare saving DC data
        self.prepare_saving(os.path.join(data_dir, filename + '.txt'))

        if use_vna:
            # prepare saving RF data
            spectra_fol = os.path.join(data_dir, filename)
            create_path(spectra_fol)
            # save segmented frequency sweep data to file
            with open(os.path.join(spectra_fol, 'VNAconfig'), 'w') as f:
                vna.dump_freq_segments(f)

        # loop
        for Vg in Vgs:
            if self.flags['quit_requested']:
                return locals()

            print('Setting Vg='+str(Vg)+' V...')
            sourceVg.set_voltage(Vg)
            time.sleep(stabilise_time)

            # measure
            Vgm = sourceVg.get_voltage()
            Ileak = sourceVg.get_current()

            # save data
            self.save_row(locals())
            
            # save VNA data
            if use_vna:
                # save VNA data
                print("Getting VNA spectra...")
                vna.single_sweep(wait=False)
                # display sweep progress
                progressbar_wait(sweeptime)
                # make sure sweep is really done
                while not vna.is_sweep_done():
                    time.sleep(0.5)
                table = vna.get_table([1,2,3,4])
                timestamp = time.strftime('%Y-%m-%d_%Hh%Mm%Ss')
                spectrum_file = timestamp+'_Vg={:.3f}.txt'.format(Vg)
                np.savetxt(os.path.join(spectra_fol, spectrum_file), np.transpose(table))


        print("Acquisition done.")
        
        return locals()
    def measure(self, sweep_type, src_Vg, src_Vds, src_Vchuck, src_vna,
                data_dir, comment, mesurement_station, Vdss, Vgs, Vchucks,
                Rg_Bilt_Only, Rds_Bilt_Only, WxL, max_pwr, max_Ileak,
                stabilise_time, slope_vg_vd, slope_vchuck, **kwargs):
        print("****************************************")
        print("===================================")
        print("Starting acquisition script")

        self.sourceVchuck = None

        vna_string = ''
        temp_string = ''

        if (mesurement_station == 'None'):
            print("Please chose a mesurement station first")
            raise

        #initialise instruments
        if (sweep_type == 'initialise_instruments'):
            init_instruments = True
        else:
            init_instruments = False


#        #select correct vna
#        if (use_vna == 'True' and mesurement_station == 'JANIS'):
#            src_vna = 'anritsu'
#        elif (use_vna == 'True' and mesurement_station == 'Cascade'):
#            src_vna = 'zva67'
#        else:
#            src_vna = 'None'

#------------------------------------------------------------------------#
#------------------------------------------------------------------------#
#set instruments

        if (mesurement_station == 'JANIS'):
            yoko_address = 'GPIB::3::INSTR'
            k2000_address = 'GPIB::20::INSTR'
            bilt_address = 'TCPIP0::192.168.0.2::5025::SOCKET'
            anritsu_address = 'GPIB::6::INSTR'
            temperature_address = 'GPIB::14::INSTR'

            position_source_bilt = "I"
            position_meter_bilt = "I5;C"

        if (mesurement_station == 'Cascade'):
            yoko_address = 'GPIB::10::INSTR'
            k2000_address = 'GPIB::15::INSTR'
            bilt_address = 'TCPIP0::192.168.0.5::5025::SOCKET'
            zva67_address = '192.168.0.3'
            temperature_address = 'ASRL5::INSTR'

            position_source_bilt = "I3;C"
            position_meter_bilt = "I1;C"

        k2400_address = 'GPIB::24::INSTR'
        k2600_address = 'GPIB::24::INSTR'

        #------------------------------------------------------------------------#
        #------------------------------------------------------------------------#

        # initialise SI9700 temperature controler
        if (mesurement_station == 'JANIS'):
            try:
                print("----------------------------------------")
                print("Setting up SI9700 temperature controller...")
                tc = SI9700(temperature_address)
                temp_string = '_T={:.1f}'.format(
                    (tc.get_temp('a') + tc.get_temp('b')) / 2)
                print("Temperature controller SI9700 is set up.")

            except:
                print(
                    "There has been an error setting up the SI9700 temperature controller."
                )
                raise

        elif (mesurement_station == 'Cascade'):
            try:
                print("----------------------------------------")
                print("Setting up TIC500 temperature controller...")
                tc = TIC500(temperature_address)
                temp_string = '_T={:.1f}'.format(tc.get_temp('Chuck'))
                print("Temperature controller TIC500 is set up.")

            except:
                print(
                    "There has been an error setting up the TIC500 temperature controller."
                )
                raise

        # initialise K2400
        if (src_Vg == 'K2400' or src_Vds == 'K2400' or src_Vchuck == 'K2400'):
            try:
                print("----------------------------------------")
                print("Setting up K2400 DC source...")

                if src_Vg == 'K2400':
                    self.sourceVg = sourceVg = K2400(
                        k2400_address,
                        sourcemode='v',
                        vrang=200,
                        irang=100e-3,
                        slope=slope_vg_vd,
                        initialise=init_instruments)
                if src_Vds == 'K2400':
                    self.sourceVds = sourceVds = K2400(
                        k2400_address,
                        sourcemode='v',
                        vrang=200,
                        irang=100e-3,
                        slope=slope_vg_vd,
                        initialise=init_instruments)
                if src_Vchuck == 'K2400':
                    self.sourceVchuck = sourceVchuck = K2400(
                        k2400_address,
                        sourcemode='v',
                        vrang=200,
                        irang=100e-3,
                        slope=slope_vchuck,
                        initialise=init_instruments)

                print("K2400 DC source are set up.")
            except:
                print("There has been an error setting up K2400 DC sources.")
                raise

        # initialise K2600
        if (src_Vg == 'K2600' or src_Vds == 'K2600' or src_Vchuck == 'K2600'):
            try:
                print("----------------------------------------")
                print("Setting up K2600 DC source...")

                if src_Vg == 'K2600':
                    self.sourceVg = sourceVg = K2600(
                        k2600_address,
                        slope=slope_vg_vd,
                        initialise=init_instruments)
                if src_Vds == 'K2600':
                    self.sourceVds = sourceVds = K2600(
                        k2600_address,
                        slope=slope_vg_vd,
                        initialise=init_instruments)
                if src_Vchuck == 'K2600':
                    self.sourceVchuck = sourceVchuck = K2600(
                        k2600_address,
                        slope=slope_vchuck,
                        initialise=init_instruments)

                print("K2600 DC source are set up.")
            except:
                print("There has been an error setting up K2600 DC sources.")
                raise

        # initialise YOKO
        if (src_Vchuck == 'Yoko'):
            try:
                print("----------------------------------------")
                print("Setting up Yokogawa DC source...")

                self.sourceVchuck = sourceVchuck = Yoko7651(
                    yoko_address,
                    initialise=init_instruments,
                    rang=30,
                    slope=slope_vchuck)

                print("Yokogawa DC source are set up.")

            except:
                print("There has been an error setting up the chuck voltage.")
                raise

        # initialise BILT
        if (src_Vg[0:4] == 'Bilt' or src_Vds[0:4] == 'Bilt'):
            try:
                print("----------------------------------------")
                print("Setting up BILT DC sources and voltmeters...")
                bilt = Bilt(bilt_address)

                if (src_Vg[0:4] == 'Bilt'):
                    src_Vg, port_Vg = src_Vg.split('_')
                    self.sourceVg = sourceVg = BiltVoltageSource(
                        bilt,
                        position_source_bilt + port_Vg,
                        rang="12",
                        filt="1",
                        slope=slope_vg_vd,
                        label=None,
                        initialise=init_instruments)
                    self.meterVg = meterVg = BiltVoltMeter(
                        bilt,
                        position_meter_bilt + port_Vg,
                        filt="2",
                        label="Vgm")

                if (src_Vds[0:4] == 'Bilt'):
                    src_Vds, port_Vds = src_Vds.split('_')
                    self.sourceVds = sourceVds = BiltVoltageSource(
                        bilt,
                        position_source_bilt + port_Vds,
                        rang="12",
                        filt="1",
                        slope=slope_vg_vd,
                        label=None,
                        initialise=init_instruments)
                    self.meterVds = meterVds = BiltVoltMeter(
                        bilt,
                        position_meter_bilt + port_Vds,
                        filt="2",
                        label="Vdsm")

                print("BILT DC sources and voltmeters are set up.")

            except:
                print(
                    "There has been an error setting up BILT DC sources and voltmeters."
                )
                raise

        # initialise VNA ZVA67
        if src_vna == 'zva67':
            print("Setting up VNA")
            self.vna = vna = RohdeSchwarzVNA()
            vna.open('TCPIP', '192.168.0.3')

            c1 = vna.channel(1)
            sweeptime = c1.total_sweep_time_ms
            c1.init_nonblocking_sweep((1, 2))

            if not c1.is_corrected():
                raise Exception('Please calibrate or switch on correction.')
            if c1.sweep_type != 'SEGM':
                raise Exception('Please use segmented frequency sweep')

            # check if the RF power is the same on both ports and for all
            # frequency segments
            vna_pow = np.unique(np.asarray(c1.get_frequency_segments())[:, 5])
            if len(vna_pow) > 1:
                raise Exception(
                    "Please select the same power for all ports and frequency segments"
                )
            vna_pow = vna_pow[0]
            if c1.is_auto_attenuator(1) or c1.is_auto_attenuator(2):
                raise Exception("Please do not use automatic attenuators")
            port1att = c1.get_attenuator(1)
            if port1att == c1.get_attenuator(2):
                vna_pow -= port1att
            else:
                raise Exception(
                    "Please select the same attenuators for both ports")
            vna_string = '_pwr={:.0f}'.format(vna_pow)

            print("VNA is set up.")

        # initialise VNA ANRITSU
        if (src_vna == 'anritsu'):
            try:
                print("----------------------------------------")
                print("Setting up ANRITSU VNA")
                vna = AnritsuVNA(anritsu_address)
                sweeptime = vna.get_sweep_time()

                if vna.get_sweep_type() != 'FSEGM':
                    raise Exception('Please use segmented frequency sweep')

                # check if the RF power is the same on both ports and for all
                # frequency segments
                count = int(vna.query(':SENS:FSEGM:COUN?'))
                vna_pow = None
                for i in range(1, count + 1):
                    port1pow = float(
                        vna.query(':SENS:FSEGM{}:POW:PORT1?'.format(i)))
                    port2pow = float(
                        vna.query(':SENS:FSEGM{}:POW:PORT2?'.format(i)))
                    if vna_pow is None and port1pow == port2pow:
                        vna_pow = port1pow
                    elif vna_pow is not None and port1pow == port2pow and port1pow == vna_pow:
                        continue
                    else:
                        raise Exception(
                            "Please select the same power for all ports and frequency segments"
                        )
                port1att = vna.get_source_att(1)
                port2att = vna.get_source_att(2)
                if port1att == port2att:
                    vna_pow -= port1att
                else:
                    raise Exception(
                        "Please select the same attenuators for both ports")
                vna_string = '_pwr={:.0f}'.format(vna_pow)

                print("ANRITSU VNA is set up.")

            except:
                print("There has been an error setting up the ANRITSU VNA.")
                raise

        print("----------------------------------------")

        #------------------------------------------------------------------------#
        #------------------------------------------------------------------------#

        # define name
        timestamp = time.strftime('%Y-%m-%d_%Hh%Mm%Ss')
        filename = timestamp + vna_string + temp_string + ('_' + comment
                                                           if comment else '')

        # prepare saving DC data
        self.prepare_saving(os.path.join(data_dir, filename + '.txt'))

        # prepare saving RF data
        if src_vna != 'None':
            spectra_fol = os.path.join(data_dir, filename)
            create_path(spectra_fol)

        # save config
        if src_vna == 'zva67':
            # prepare saving RF data
            spectra_fol = os.path.join(data_dir, filename)
            create_path(spectra_fol)

            c1.save_frequency_segments(os.path.join(spectra_fol, 'VNAconfig'))

        sweeptime_min = len(Vgs) * len(Vdss) * len(
            Vchucks) * stabilise_time * (c1.total_sweep_time_ms *
                                         1e3 if src_vna == 'zva67' else 1) / 60
        remain_time_min = sweeptime_min
        progress_percent = 0

        if (sweep_type == 'give_time'
                or sweep_type == 'initialise_instruments'):
            # save data
            self.save_row(locals())
            # stop
            return locals()

        #------------------------------------------------------------------------#
        #------------------------------------------------------------------------#

        # loops
        print("........................................")
        print("Starting mesurement")
        print("++++++++++++++++++++++++++++++++++++++++")

        for Vchuck in Vchucks:
            if src_Vchuck != "None":
                sourceVchuck.set_voltage(Vchuck)

            if (sweep_type == 'fix_Vds_sweep_Vg'):
                for Vds in Vdss:

                    sourceVds.set_voltage(Vds)

                    for Vg in Vgs:

                        sourceVg.set_voltage(Vg)

                        # quit request
                        if self.flags['quit_requested']:
                            return locals()

                        # stabilise
                        time.sleep(stabilise_time)

                        # measure & calculate
                        if (src_Vds == 'K2400' or src_Vds == 'K2600'):
                            #mesure current directly
                            Ids = sourceVds.get_current()
                        if (src_Vds[0:4] == 'Bilt'):
                            #mesure current and convert in tension with resistor
                            Vdsm = meterVds.get_voltage()
                            Rs = Rds_Bilt_Only * Vdsm / (Vds - Vdsm)
                            Ids = Vds / Rs

                        if (src_Vg == 'K2400' or src_Vg == 'K2600'):
                            #mesure current directly
                            Ileak = sourceVg.get_current()
                        if (src_Vg[0:4] == 'Bilt'):
                            #mesure current and convert in tension with resistor
                            Vgm = meterVg.get_voltage()
                            Ileak = (Vg - Vgm) / Rg_Bilt_Only

                        pwr = (Vds * Ids) / (WxL)

                        # get temp
                        if (mesurement_station == 'JANIS'):
                            Ta = tc.get_temp('a')
                            Tb = tc.get_temp('b')

                        elif (mesurement_station == 'Cascade'):
                            Ta = tc.get_temp('Chuck')
                            Tb = tc.get_temp('Chuck')

                        # save data
                        self.save_row(locals())

                        #print
                        print("Getting mesurement Vg = {}".format(Vg) +
                              " and Vds = {}".format(Vds))

                        # save VNA data
                        if src_vna == 'zva67':
                            # save VNA data
                            print("Getting VNA spectra...")

                            c1.start_nonblocking_sweep()
                            # make sure sweep is really done

                            # display sweep progress
                            progressbar_wait(sweeptime / 1e3)
                            # make sure sweep is really done
                            while not c1.isdone_nonblocking_sweep():
                                time.sleep(0.5)

                            timestamp = time.strftime('%Y-%m-%d_%Hh%Mm%Ss')
                            spectrum_file = timestamp + '_Vg=%2.4f' % (
                                Vg) + '_Vds=%2.4f' % (Vds)
                            spectrum_file = os.path.join(
                                spectra_fol, spectrum_file + '.s2p')
                            c1.save_nonblocking_sweep(spectrum_file, (1, 2))

                        if src_vna == 'Anritsu':
                            vna.single_sweep()

                            table = vna.get_table(range(1, 4))
                            timestamp = time.strftime('%Y-%m-%d_%Hh%Mm%Ss')
                            spectrum_file = timestamp + '_Vg=%2.4f' % (
                                Vg) + '_Vds=%2.4f' % (Vds) + '.txt'

                            np.savetxt(
                                os.path.join(spectra_fol, spectrum_file),
                                np.transpose(table))

                        #mesure time
                        remain_time_min = remain_time_min - (
                            stabilise_time *
                            (c1.total_sweep_time_ms *
                             1e3 if src_vna == 'zva67' else 1) / 60)
                        progress_percent = (sweeptime_min - remain_time_min
                                            ) / sweeptime_min * 100

            if (sweep_type == 'fix_Vg_sweep_Vds'):
                for Vg in Vgs:

                    sourceVg.set_voltage(Vg)

                    first_pass = True

                    for Vds in Vdss:

                        #check power limit
                        if first_pass:
                            pwr = 0
                        else:
                            pwr = (Vds * Ids) / (WxL)
                        if (pwr > max_pwr):
                            pwr_limit = True
                        elif (pwr < max_pwr):
                            pwr_limit = False

                        if not pwr_limit:

                            sourceVds.set_voltage(Vds)

                            #quit request
                            if self.flags['quit_requested']:
                                return locals()

                            # stabilise
                            time.sleep(stabilise_time)

                            # measure & calculate
                            if (src_Vds == 'K2400' or src_Vds == 'K2600'):
                                #mesure current directly
                                Ids = sourceVds.get_current()
                            if (src_Vds[0:4] == 'Bilt'):
                                #mesure current and convert in tension with resistor
                                Vdsm = meterVds.get_voltage()
                                Rs = Rds_Bilt_Only * Vdsm / (Vds - Vdsm)
                                Ids = Vds / Rs

                            if (src_Vg == 'K2400' or src_Vg == 'K2600'):
                                #mesure current directly
                                Ileak = sourceVg.get_current()
                            if (src_Vg[0:4] == 'Bilt'):
                                #mesure current and convert in tension with resistor
                                Vgm = meterVg.get_voltage()
                                Ileak = (Vg - Vgm) / Rg_Bilt_Only

                            pwr = (Vds * Ids) / (WxL)

                            # get temp
                            if (mesurement_station == 'JANIS'):
                                Ta = tc.get_temp('a')
                                Tb = tc.get_temp('b')

                            elif (mesurement_station == 'Cascade'):
                                Ta = tc.get_temp('Chuck')
                                Tb = tc.get_temp('Chuck')

                            # do calculations
                            Ileak = (Vg - Vgm) / Rg_Bilt_Only

                            # save data
                            self.save_row(locals())

                            #print
                            print("Getting mesurement Vg = {}".format(Vg) +
                                  " and Vds = {}".format(Vds))

                        # save VNA data
                        if src_vna == 'zva67':
                            # save VNA data
                            print("Getting VNA spectra...")

                            c1.start_nonblocking_sweep()

                            # display sweep progress
                            progressbar_wait(sweeptime / 1e3)
                            # make sure sweep is really done
                            while not c1.isdone_nonblocking_sweep():
                                time.sleep(0.5)

                            timestamp = time.strftime('%Y-%m-%d_%Hh%Mm%Ss')
                            spectrum_file = timestamp + '_Vg=%2.4f' % (
                                Vg) + '_Vds=%2.4f' % (Vds)
                            spectrum_file = os.path.join(
                                spectra_fol, spectrum_file + '.s2p')
                            c1.save_nonblocking_sweep(spectrum_file, (1, 2))

                        if src_vna == 'Anritsu':
                            vna.single_sweep()

                            table = vna.get_table(range(1, 4))
                            timestamp = time.strftime('%Y-%m-%d_%Hh%Mm%Ss')
                            spectrum_file = timestamp + '_Vg=%2.4f' % (
                                Vg) + '_Vds=%2.4f' % (Vds) + '.txt'

                            np.savetxt(
                                os.path.join(spectra_fol, spectrum_file),
                                np.transpose(table))

                        #mesure time
                        remain_time_min = remain_time_min - (
                            stabilise_time *
                            (c1.total_sweep_time_ms *
                             1e3 if src_vna == 'zva67' else 1) / 60)
                        progress_percent = (sweeptime_min - remain_time_min
                                            ) / sweeptime_min * 100

                        first_pass = False

        print("++++++++++++++++++++++++++++++++++++++++")
        print("Stopping measurement")
        print("........................................")

        return locals()
示例#7
0
    def measure(self, data_dir, Vgs, Rg, comment, stabilise_time, use_vna,
                use_chuck, init_bilt, **kwargs):
        print("===================================")
        print("Starting acquisition script...")

        chuck_string = ''
        vna_string = ''

        # initialise instruments
        print("Setting up DC sources and voltmeters...")
        bilt = Bilt('TCPIP0::192.168.0.5::5025::SOCKET')
        if init_bilt:
            # source (bilt, channel, range, filter, slope in V/ms, label):
            self.sourceVg = sourceVg = BiltVoltageSource(
                bilt, "I3;C1", "12", "1", 0.005, "Vg")
        else:
            self.sourceVg = sourceVg = BiltVoltageSource(bilt,
                                                         "I3;C1",
                                                         initialise=False)
        # voltmeter (bilt, channel, filt, label=None)
        self.meterVg = meterVg = BiltVoltMeter(bilt, "I1;C1", "2", "Vgm")
        print("DC sources and voltmeters are set up.")

        if use_chuck:
            print("Setting up Yokogawa for chuck voltage...")
            # connect to the Yoko without initialising, this will lead to
            # an exception if the Yoko is not properly configured (voltage
            # source, range 30V, output ON)
            yoko = Yoko7651('GPIB::10::INSTR', initialise=False, rang=30)
            chuck_string = '_Vchuck={:.1f}'.format(yoko.get_voltage())
            print("Yokogawa is set up.")

        if use_vna:
            print("Setting up VNA")
            self.vna = vna = RohdeSchwarzVNA()
            vna.open('TCPIP', '192.168.0.3')

            c1 = vna.channel(1)
            sweeptime = c1.total_sweep_time_ms
            c1.init_nonblocking_sweep((1, 2))

            if not c1.is_corrected():
                raise Exception('Please calibrate or switch on correction.')
            if c1.sweep_type != 'SEGM':
                raise Exception('Please use segmented frequency sweep')

            # check if the RF power is the same on both ports and for all
            # frequency segments
            vna_pow = np.unique(np.asarray(c1.get_frequency_segments())[:, 5])
            if len(vna_pow) > 1:
                raise Exception(
                    "Please select the same power for all ports and frequency segments"
                )
            vna_pow = vna_pow[0]
            if c1.is_auto_attenuator(1) or c1.is_auto_attenuator(2):
                raise Exception("Please do not use automatic attenuators")
            port1att = c1.get_attenuator(1)
            if port1att == c1.get_attenuator(2):
                vna_pow -= port1att
            else:
                raise Exception(
                    "Please select the same attenuators for both ports")
            vna_string = '_pwr={:.0f}'.format(vna_pow)

            print("VNA is set up.")

        # prepare saving DC data
        timestamp = time.strftime('%Y-%m-%d_%Hh%Mm%Ss')
        filename = timestamp + vna_string + chuck_string + ('_' + comment
                                                            if comment else '')
        self.prepare_saving(os.path.join(data_dir, filename + '.txt'))

        if use_vna:
            # prepare saving RF data
            spectra_fol = os.path.join(data_dir, filename)
            create_path(spectra_fol)

            c1.save_frequency_segments(os.path.join(spectra_fol, 'VNAconfig'))

        for Vg in Vgs:
            if self.flags['quit_requested']:
                print("Stopping acquisition.")
                return locals()

            print("Setting Vg = {}".format(Vg))

            # set Vg
            sourceVg.set_voltage(Vg)

            # wait
            time.sleep(stabilise_time)

            # read voltages
            Vgm = meterVg.get_voltage()

            # do calculations
            Ileak = (Vg - Vgm) / Rg

            # save DC data
            self.save_row(locals())

            if use_vna:
                # save VNA data
                print("Getting VNA spectra...")

                c1.start_nonblocking_sweep()
                # display sweep progress
                progressbar_wait(sweeptime / 1e3)
                # make sure sweep is really done
                while not c1.isdone_nonblocking_sweep():
                    time.sleep(0.5)

                timestamp = time.strftime('%Y-%m-%d_%Hh%Mm%Ss')
                spectrum_file = timestamp + '_Vg=%2.4f' % (Vg)
                spectrum_file = os.path.join(spectra_fol,
                                             spectrum_file + '.s2p')
                c1.save_nonblocking_sweep(spectrum_file, (1, 2))

        print("Acquisition done.")

        return locals()
    def measure(self, data_dir, Vgs, Vg0, Vchuck0, Vchuckmax, CapaRatio, Rg,
                comment, stabilise_time, use_vna, init_bilt, init_yoko,
                **kwargs):
        print("===================================")
        print("Starting acquisition script...")

        # initialise instruments
        try:
            print("Setting up DC sources and voltmeters...")
            bilt = Bilt('TCPIP0::192.168.0.2::5025::SOCKET')
            if init_bilt:
                # source (bilt, channel, range, filter, slope in V/ms, label):
                self.sourceVg = sourceVg = BiltVoltageSource(bilt, "I1", "12", "1", 0.005, "Vg")
            else:
                self.sourceVg = sourceVg = BiltVoltageSource(bilt, "I1", initialise=False)
            # voltmeter (bilt, channel, filt, label=None)
            self.meterVg = meterVg = BiltVoltMeter(bilt, "I5;C1", "2", "Vgm")
            # voltage source for chuck
            self.yoko = yoko = Yoko7651("GPIB::3::INSTR", func="VOLT",
                                        rang=30., slope=1.,
                                        initialise=init_yoko, verbose=True)
            print("DC sources and voltmeters are set up.")
        except:
            print("There has been an error setting up DC sources and voltmeters:")
            raise
            
        try:
            print("Setting up VNA...")
            vna = AnritsuVNA('GPIB::6::INSTR')
            sweeptime = vna.get_sweep_time()
            print("VNA is set up.")
        except:
            print("There has been an error setting up the VNA:")
            raise

        timestamp = time.strftime('%Y-%m-%d_%Hh%Mm%Ss')

        # prepare saving DC data
        filename = timestamp + ('_'+comment if comment else '')
        self.prepare_saving(os.path.join(data_dir, filename+'.txt'))
        
        if use_vna:
            # prepare saving RF data
            spectra_fol = os.path.join(data_dir, filename)
            try:
                os.makedirs(spectra_fol)
            except OSError as e:
                if e.errno != errno.EEXIST:
                    raise
            if vna.get_sweep_type() == 'FSEGM':
                with open(os.path.join(spectra_fol, 'VNAconfig'), 'w') as f:
                    vna.dump_freq_segments(f)

        for Vg in Vgs:
            if self.flags['quit_requested']:
                print("Stopping acquisition.")
                return locals()            
            
            print("Setting Vg = {}".format(Vg))
        
            # calculate new chuck voltage to keep field constant
        
            # set Vg
            sourceVg.set_voltage(Vg)
            
            Vchuck = Vchuck0+CapaRatio*(Vg-Vg0)
            if np.abs(Vchuck) <= Vchuckmax:
                print("Set chuck voltage:", Vchuck)
                yoko.set_voltage(Vchuck)
            else:
                print("Chuck voltage too high:", Vchuck)
                print("Not changing chuck voltage.")
                Vchuck = yoko.get_voltage()
            
            # wait
            time.sleep(stabilise_time)
        
            # read voltages
            Vgm = meterVg.get_voltage()
            
            # do calculations
            Ileak = (Vg-Vgm)/Rg
    
            # save DC data
            self.save_row(locals())

            if use_vna:
                # save VNA data
                print("Getting VNA spectra...")
                vna.single_sweep(wait=False)
                # display sweep progress
                progressbar_wait(sweeptime)
                # make sure sweep is really done
                while not vna.is_sweep_done():
                    time.sleep(0.5)
                table = vna.get_table([1,2,3,4])
                timestamp = time.strftime('%Y-%m-%d_%Hh%Mm%Ss')
                spectrum_file = timestamp+'_Vg=%2.4f_Vchuck=%2.4f'%(Vg, Vchuck)+'.txt'
                np.savetxt(os.path.join(spectra_fol, spectrum_file), np.transpose(table))

        print("Acquisition done.")
        
        return locals()