예제 #1
0
class Measurement(MeasurementBase):
    params = {
        'Vdss': Sweep([0.0]),
        'Vg1s': Sweep([0.0]),
        'Vg2s': Sweep([0.0]),
        'commongate': Boolean(False),
        'Rg1': 100e3,
        'Rg2': 100e3,
        'Rds': 22e3,
        'stabilise_time': 0.05,
        'comment': String(''),
        'data_dir':
        Folder(r'D:\MeasurementJANIS\Holger\KTW H5 2x3\2017-11-09 LHe')
    }

    observables = [
        'Vg1', 'Vg1m', 'Ileak1', 'Vg2', 'Vg2m', 'Ileak2', 'Vds', 'Vdsm', 'Rs'
    ]

    alarms = [
        ['np.abs(Ileak1) > 1e-8', MeasurementBase.ALARM_CALLCOPS],
        ['np.abs(Ileak2) > 1e-8', MeasurementBase.ALARM_CALLCOPS],
        ['np.abs(Vg1-Vg2)', MeasurementBase.ALARM_SHOWVALUE
         ]  # useful if we just want to know how much voltage
        # is applied between the two gates
    ]

    def measure(self, data_dir, comment, Vdss, Vg1s, Vg2s, commongate, Rg1,
                Rg2, Rds, stabilise_time, **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')
            self.sourceVds = sourceVds = BiltVoltageSource(bilt,
                                                           "I1",
                                                           initialise=False)
            self.sourceVg1 = sourceVg1 = BiltVoltageSource(bilt,
                                                           "I2",
                                                           initialise=False)
            self.sourceVg2 = sourceVg2 = BiltVoltageSource(bilt,
                                                           "I3",
                                                           initialise=False)
            self.meterVds = meterVds = BiltVoltMeter(bilt, "I5;C1", "2",
                                                     "Vdsm")
            self.meterVg1 = meterVg1 = BiltVoltMeter(bilt, "I5;C2", "2",
                                                     "Vg1m")
            self.meterVg2 = meterVg2 = BiltVoltMeter(bilt, "I5;C3", "2",
                                                     "Vg2m")
            print("DC sources and voltmeters are set up.")
        except:
            print(
                "There has been an error setting up DC sources and voltmeters."
            )
            raise

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

        # prepare saving data
        filename = timestamp + '_' + (comment if comment else '') + '.txt'
        self.prepare_saving(os.path.join(data_dir, filename))

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

                    sourceVg1.set_voltage(Vg1)
                    if commongate:
                        Vg2 = Vg1
                        sourceVg2.set_voltage(Vg1)

                    # stabilise
                    time.sleep(stabilise_time)

                    # measure
                    Vdsm = meterVds.get_voltage()
                    Vg1m = meterVg1.get_voltage()
                    Vg2m = meterVg2.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()

    def tidy_up(self):
        self.end_saving()

        print("Driving all voltages back to zero...")

        self.sourceVds.set_voltage(0.)
        self.sourceVg1.set_voltage(0.)
        self.sourceVg2.set_voltage(0.)
class Measurement(MeasurementBase):
    params = {
        'Vgs': Sweep([0.]),
        'Vg0': 0.,
        'Vchuck0': 10.,
        'Vchuckmax': 30.,
        'CapaRatio': 10.,
        'Rg': 100e3,
        'stabilise_time': 0.3,
        'comment': String(''),
        'data_dir': Folder(r''),
        'use_vna': Boolean(True),
        'init_bilt': Boolean(False),
        'init_yoko': Boolean(False)
    }

    observables = ['Vg', 'Vgm', 'Vchuck', 'Ileak']

    alarms = [
        ['np.abs(Ileak) > 1e-8', MeasurementBase.ALARM_CALLCOPS]
    ]

    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()

    def tidy_up(self):
        self.end_saving()
        print("Driving all voltages back to zero...")
        self.sourceVg.set_voltage(0.)
        self.yoko.set_voltage(0.)
예제 #3
0
class Measurement(MeasurementBase):
    params = {
        'sweep': Boolean(False),
        'startpoint': 0.,
        'direction': 1.,
        'step': 1.,
        'Ithresh': 3e-7,
        'Vmax': 30,
        'stabilise_time': 10,
        'init': Boolean(True),
        'use_vna': Boolean(True),
        'comment': String(''),
        'data_dir': Folder(r'D:\MeasurementJANIS\Holger\test')
    }

    observables = ['Vg', 'Vgm', 'Ileak']

    alarms = []

    def measure(self, step, startpoint, direction, Ithresh, Vmax, sweep,
                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)

        Vg = startpoint

        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

        # measure at 0 V
        measure_point()

        # sweep if requested
        #╦direction = 1. # up
        if direction not in [1., -1.]:
            raise Exception("select valid direction 1. or -1.")
        back_to_zero = False
        decimals = int(max(1., -np.log10(step) + 1.))
        while sweep:
            if self.flags['quit_requested']:
                return locals()
            Vg = np.around(Vg + step * direction, decimals)
            if np.abs(Vg) > Vmax:
                print("Reached maximum voltage! Inverting sweep direction.")
                if direction < 0. and Vg < 0.:
                    back_to_zero = True
                direction = -direction
                continue
            leak = measure_point(Ithresh)
            if leak:
                if direction * Vg < 0.:
                    continue
                if direction < 0. and Vg < 0.:
                    back_to_zero = True
                direction = -direction
            if np.abs(Vg) < 1e-12 and back_to_zero:
                break

        print("Acquisition done.")

        return locals()

    def tidy_up(self):
        self.end_saving()

        print("Driving all voltages back to zero...")

        self.sourceVg.set_voltage(0.)