Beispiel #1
0
    def __init__(self):
        """ 1. setup the VNA as an instrument (if it's not already setup)
            2. specify experimental parameters
            3. specify paths of the target files: 
               database file and a new folder with raw (txt, png) files """

        import pdb; pdb.set_trace()  # noqa BREAKPOINT

        self.vna_name = 'VNA_Keysight'
        # this is a qcodes VisaInstrument (interface between visa and qcodes)
        self.vna_class = Keysight_P9373A
        self.vna_address = "TCPIP0::maip-franck::hislip0,4880::INSTR"

        # -- check if instrument 'VNA' already exists. If not, create it
        if Instrument.exist(self.vna_name, self.vna_class):
            # an instrument is created by qcodes in a global context,
            # from which it can be retrieved manually using find_instrument
            self.vna = Instrument.find_instrument(
                self.vna_name, self.vna_class)
        else:
            self.vna = self.vna_class(self.vna_name, self.vna_address,
                                      300e3, 13.5e9, -90, 13, 2)
        
        # -- name the experiment -> automatic file names
        self.exp_name = 'test_exp'  # name used by qcodes
        self.cooldown_date = '20-09-22'
        self.sample_name = 'test_sample'

        # -- set experiment parameters (global constants, used in different measurement functions)
        self.num_freq_points = 2001  # 2001  # number of measurement points
        self.vnapower = -30  # applied power
        # 3.7e9  #3.387015e9 #6.608e9-3.5e6  # start frequency of sweep
        self.start_frequency = 3e9
        # 5.7e9  #3.387065e9 #6.611e9 +3.5e6  # stop frequency of sweep
        self.stop_frequency = 10.e9
        self.frequency_span = self.stop_frequency - self.start_frequency
        self.center_frequency = (self.stop_frequency - self.start_frequency) / \
            2. + self.start_frequency  # just used for power sweep
        self.measuredtrace = 'S21'  # spectral density measured between port 1 and 2
        # IF Bandwidth, must be in (10,30,50,70,100,300,500,700,1000,3000,5000,7000,10000)Hz
        self.ifbandwidth = 10
        self.powersweepstart = -30  # start for power sweep
        self.powersweepstop = 13  # stop for powersweep
        # number of power sweeps (perhaps +/-1) MUST BE AN EVEN NUMBER AT LEAST 6
        self.num_power_points = 3
        # groupdelayref=0.0000000225
        # vna.groupdelay.set(groupdelayref)#resets to 0 instead of working -> rounding to 0
        # print(vna.groupdelay.get())


        self.create_database_experiment_and_folders()

        self.ask_what_to_do()
Beispiel #2
0
    def load_instrument(self,
                        identifier: str,
                        revive_instance: bool = False,
                        **kwargs) -> Instrument:
        """
        Creates an :class:`~.Instrument` instance as described by the
        loaded configuration file.

        Args:
            identifier: The identfying string that is looked up in the yaml
                configuration file, which identifies the instrument to be added.
            revive_instance: If ``True``, try to return an instrument with the
                specified name instead of closing it and creating a new one.
            **kwargs: Additional keyword arguments that get passed on to the
                ``__init__``-method of the instrument to be added.
        """
        # try to revive the instrument
        if revive_instance and Instrument.exist(identifier):
            return Instrument.find_instrument(identifier)

        # load file
        # try to reload file on every call. This makes script execution a
        # little slower but makes the overall workflow more convenient.
        self.load_config_file(self.config_file)

        # load from config
        if identifier not in self._instrument_config.keys():
            raise RuntimeError(f'Instrument {identifier} not found in '
                               'instrument config file')
        instr_cfg = self._instrument_config[identifier]

        # TODO: add validation of config for better verbose errors:

        # check if instrument is already defined and close connection
        if instr_cfg.get('enable_forced_reconnect',
                         get_config_enable_forced_reconnect()):
            with suppress(KeyError):
                self.close_and_remove_instrument(identifier)

        # instantiate instrument
        init_kwargs = instr_cfg.get('init', {})
        # somebody might have a empty init section in the config
        init_kwargs = {} if init_kwargs is None else init_kwargs
        if 'address' in instr_cfg:
            init_kwargs['address'] = instr_cfg['address']
        if 'port' in instr_cfg:
            init_kwargs['port'] = instr_cfg['port']
        # make explicitly passed arguments overide the ones from the config
        # file.
        # We are mutating the dict below
        # so make a copy to ensure that any changes
        # does not leek into the station config object
        # specifically we may be passing non pickleable
        # instrument instances via kwargs
        instr_kwargs = deepcopy(init_kwargs)
        instr_kwargs.update(kwargs)
        name = instr_kwargs.pop('name', identifier)

        if 'driver' in instr_cfg:
            issue_deprecation_warning(
                'use of the "driver"-keyword in the station '
                'configuration file',
                alternative='the "type"-keyword instead, prepending the '
                'driver value'
                ' to it')
            module_name = instr_cfg['driver']
            instr_class_name = instr_cfg['type']
        else:
            module_name = '.'.join(instr_cfg['type'].split('.')[:-1])
            instr_class_name = instr_cfg['type'].split('.')[-1]
        module = importlib.import_module(module_name)
        instr_class = getattr(module, instr_class_name)
        instr = instr_class(name, **instr_kwargs)

        def resolve_instrument_identifier(
                instrument: ChannelOrInstrumentBase,
                identifier: str) -> ChannelOrInstrumentBase:
            """
            Get the instrument, channel or channel_list described by a nested
            string.

            E.g: 'dac.ch1' will return the instance of ch1.
            """
            try:
                for level in identifier.split('.'):
                    instrument = checked_getattr(instrument, level,
                                                 (InstrumentBase, ChannelList))
            except TypeError:
                raise RuntimeError(
                    f'Cannot resolve `{level}` in {identifier} to an '
                    f'instrument/channel for base instrument '
                    f'{instrument!r}.')
            return instrument

        def resolve_parameter_identifier(instrument: ChannelOrInstrumentBase,
                                         identifier: str) -> _BaseParameter:
            parts = identifier.split('.')
            if len(parts) > 1:
                instrument = resolve_instrument_identifier(
                    instrument, '.'.join(parts[:-1]))
            try:
                return checked_getattr(instrument, parts[-1], _BaseParameter)
            except TypeError:
                raise RuntimeError(
                    f'Cannot resolve parameter identifier `{identifier}` to '
                    f'a parameter on instrument {instrument!r}.')

        def setup_parameter_from_dict(parameter: _BaseParameter,
                                      options: Dict[str, Any]) -> None:
            for attr, val in options.items():
                if attr in PARAMETER_ATTRIBUTES:
                    # set the attributes of the parameter, that map 1 to 1
                    setattr(parameter, attr, val)
                # extra attributes that need parsing
                elif attr == 'limits':
                    if isinstance(val, str):
                        issue_deprecation_warning(
                            ('use of a comma separated string for the limits '
                             'keyword'),
                            alternative='an array like "[lower_lim, upper_lim]"'
                        )
                        lower, upper = [float(x) for x in val.split(',')]
                    else:
                        lower, upper = val
                    parameter.vals = validators.Numbers(lower, upper)
                elif attr == 'monitor' and val is True:
                    self._monitor_parameters.append(parameter)
                elif attr == 'alias':
                    setattr(parameter.instrument, val, parameter)
                elif attr == 'initial_value':
                    # skip value attribute so that it gets set last
                    # when everything else has been set up
                    pass
                else:
                    log.warning(f'Attribute {attr} not recognized when '
                                f'instatiating parameter \"{parameter.name}\"')
            if 'initial_value' in options:
                parameter.set(options['initial_value'])

        def add_parameter_from_dict(instr: InstrumentBase, name: str,
                                    options: Dict[str, Any]) -> None:
            # keep the original dictionray intact for snapshot
            options = copy(options)
            param_type: type = _BaseParameter
            kwargs = {}
            if 'source' in options:
                param_type = DelegateParameter
                kwargs['source'] = resolve_parameter_identifier(
                    instr.root_instrument, options['source'])
                options.pop('source')
            instr.add_parameter(name, param_type, **kwargs)
            setup_parameter_from_dict(instr.parameters[name], options)

        def update_monitor():
            if ((self.use_monitor is None and get_config_use_monitor())
                    or self.use_monitor):
                # restart Monitor
                Monitor(*self._monitor_parameters)

        for name, options in instr_cfg.get('parameters', {}).items():
            parameter = resolve_parameter_identifier(instr, name)
            setup_parameter_from_dict(parameter, options)
        for name, options in instr_cfg.get('add_parameters', {}).items():
            parts = name.split('.')
            local_instr = (instr if len(parts) < 2 else
                           resolve_instrument_identifier(
                               instr, '.'.join(parts[:-1])))
            add_parameter_from_dict(local_instr, parts[-1], options)
        self.add_component(instr)
        update_monitor()
        return instr
    def __init__(self): 
        """ 1. setup the VNA as an instrument (if it's not already setup) 
            2. specify experimental parameters 
            3. specify paths of the target files: 
               database file and a new folder with raw (txt, png) files """

        self.vna_name = "VNA_Anritsu"
        self.vna_class = Anritsu_MS46522B  # this is a qcodes VisaInstrument (interface between visa and qcodes)
        self.vna_address = "TCPIP0::169.254.235.118::5001::SOCKET"
        # "TCPIP0::169.254.81.17::5001::SOCKET"
        # "TCPIP0::169.254.235.118::5001::SOCKET"  # "TCPIP0::maip-franck::hislip0,4880::INSTR"

        # (# 'VNA', 'TCPIP0::169.254.235.118::5001::SOCKET',
        # 50e6, 20e9, -30, 30, 2  # )

        # -- check if instrument 'VNA' already exists. If not, create it
        if Instrument.exist(self.vna_name, self.vna_class): 
            # an instrument is created by qcodes in a global context, 
            # from which it can be retrieved manually using find_instrument
            self.vna = Instrument.find_instrument(self.vna_name, self.vna_class)
        else:
            if self.vna_class == Anritsu_MS46522B:
                self.vna = self.vna_class(self.vna_name, self.vna_address,
                                          50e6, 20e9, -30, 30, 2)
            else:
                exit(1)
        
        # -- name the experiment -> automatic file names
        self.exp_name = 'Anritsu_Something'  # name used by qcodes
        self.cooldown_date = '20-09-21'
        self.sample_name = 'sample_not_important'

        self.numberofpoints=2001  #number of measurement points
        self.vnapower=13   #applied power
        self.start_frequency=3.4e9   #3.387015e9#6.608e9-3.5e6    #start frequency of sweep
        self.stop_frequency=7.4e9  #3.387065e9#6.611e9 +3.5e6    #stop frequency of sweep
        self.frequency_span=self.stop_frequency-self.start_frequency
        self.center_frequency=(self.stop_frequency-self.start_frequency)/2. + self.start_frequency			#just used for power sweep
        self.measuredtrace='S21'   #spectral density measured between port 1 and 2
        self.ifbandwidth=100   #IF Bandwidth, must be in (10,30,50,70,100,300,500,700,1000,3000,5000,7000,10000)Hz
        self.powersweepstart=-30    #start for power sweep
        self.powersweepstop=20    #stop for powersweep
        self.powersweepnum=6    #number of power sweeps (perhaps +/-1) MUST BE AN EVEN NUMBER AT LEAST 6

        # # -- set experiment parameters (global constants, used in different measurement functions)
        # self.numberofpoints = 50 # 2001  # number of measurement points
        # self.vnapower = -10  # applied power
        # self.start_frequency = 300e3  # 3.7e9  #3.387015e9 #6.608e9-3.5e6  # start frequency of sweep
        # self.stop_frequency = 13.5e9  # 5.7e9  #3.387065e9 #6.611e9 +3.5e6  # stop frequency of sweep
        # self.frequency_span = self.stop_frequency - self.start_frequency
        # self.center_frequency = (self.stop_frequency - self.start_frequency)/2. + self.start_frequency  # just used for power sweep
        # self.measuredtrace='S21'  # spectral density measured between port 1 and 2
        # self.ifbandwidth=10  # IF Bandwidth, must be in (10,30,50,70,100,300,500,700,1000,3000,5000,7000,10000)Hz
        # self.powersweepstart=-30  # start for power sweep
        # self.powersweepstop=13  # stop for powersweep
        # self.powersweepnum=3  # number of power sweeps (perhaps +/-1) MUST BE AN EVEN NUMBER AT LEAST 6
        # # groupdelayref=0.0000000225
        # # vna.groupdelay.set(groupdelayref)#resets to 0 instead of working -> rounding to 0
        # # print(vna.groupdelay.get())
        
        self.create_database_experiment_and_folders()
Beispiel #4
0
    def load_instrument(self, identifier: str,
                        revive_instance: bool = False,
                        **kwargs) -> Instrument:
        """
        Creates an :class:`~.Instrument` instance as described by the
        loaded config file.

        Args:
            identifier: the identfying string that is looked up in the yaml
                configuration file, which identifies the instrument to be added
            revive_instance: If true, try to return an instrument with the
                specified name instead of closing it and creating a new one.
            **kwargs: additional keyword arguments that get passed on to the
                __init__-method of the instrument to be added.
        """
        # try to revive the instrument
        if revive_instance and Instrument.exist(identifier):
            return Instrument.find_instrument(identifier)

        # load file
        # try to reload file on every call. This makes script execution a
        # little slower but makes the overall workflow more convenient.
        self.load_config_file(self.config_file)

        # load from config
        if identifier not in self._instrument_config.keys():
            raise RuntimeError(f'Instrument {identifier} not found in '
                               'instrument config file')
        instr_cfg = self._instrument_config[identifier]

        # TODO: add validation of config for better verbose errors:

        # check if instrument is already defined and close connection
        if instr_cfg.get('enable_forced_reconnect',
                         get_config_enable_forced_reconnect()):
            with suppress(KeyError):
                self.close_and_remove_instrument(identifier)

        # instantiate instrument
        init_kwargs = instr_cfg.get('init', {})
        # somebody might have a empty init section in the config
        init_kwargs = {} if init_kwargs is None else init_kwargs
        if 'address' in instr_cfg:
            init_kwargs['address'] = instr_cfg['address']
        if 'port' in instr_cfg:
            init_kwargs['port'] = instr_cfg['port']
        # make explicitly passed arguments overide the ones from the config
        # file.
        # We are mutating the dict below
        # so make a copy to ensure that any changes
        # does not leek into the station config object
        # specifically we may be passing non pickleable
        # instrument instances via kwargs
        instr_kwargs = deepcopy(init_kwargs)
        instr_kwargs.update(kwargs)
        name = instr_kwargs.pop('name', identifier)

        module = importlib.import_module(instr_cfg['driver'])
        instr_class = getattr(module, instr_cfg['type'])
        instr = instr_class(name, **instr_kwargs)

        # local function to refactor common code from defining new parameter
        # and setting existing one
        def resolve_parameter_identifier(instrument: InstrumentBase,
                                         identifier: str) -> Parameter:

            parts = identifier.split('.')
            try:
                for level in parts[:-1]:
                    instrument = checked_getattr(instrument, level,
                                                 InstrumentBase)
            except TypeError:
                raise RuntimeError(
                    f'Cannot resolve `{level}` in {identifier} to an '
                    f'instrument/channel for base instrument '
                    f'{instrument!r}.')
            try:
                return checked_getattr(instrument, parts[-1], Parameter)
            except TypeError:
                raise RuntimeError(
                    f'Cannot resolve parameter identifier `{identifier}` to '
                    f'a parameter on instrument {instrument!r}.')

        def setup_parameter_from_dict(instr: Instrument, name: str,
                                      options: Dict[str, Any]):
            parameter = resolve_parameter_identifier(instr, name)
            for attr, val in options.items():
                if attr in PARAMETER_ATTRIBUTES:
                    # set the attributes of the parameter, that map 1 to 1
                    setattr(parameter, attr, val)
                # extra attributes that need parsing
                elif attr == 'limits':
                    lower, upper = [float(x) for x in val.split(',')]
                    parameter.vals = validators.Numbers(lower, upper)
                elif attr == 'monitor' and val is True:
                    self._monitor_parameters.append(parameter)
                elif attr == 'alias':
                    setattr(instr, val, parameter)
                elif attr == 'initial_value':
                    # skip value attribute so that it gets set last
                    # when everything else has been set up
                    pass
                else:
                    log.warning(f'Attribute {attr} not recognized when '
                                f'instatiating parameter \"{parameter.name}\"')
            if 'initial_value' in options:
                parameter.set(options['initial_value'])

        def add_parameter_from_dict(instr: Instrument, name: str,
                                    options: Dict[str, Any]):
            # keep the original dictionray intact for snapshot
            options = copy(options)
            if 'source' in options:
                instr.add_parameter(
                    name,
                    DelegateParameter,
                    source=resolve_parameter_identifier(instr,
                                                        options['source']))
                options.pop('source')
            else:
                instr.add_parameter(name, Parameter)
            setup_parameter_from_dict(instr, name, options)

        def update_monitor():
            if ((self.use_monitor is None and get_config_use_monitor())
                    or self.use_monitor):
                # restart Monitor
                Monitor(*self._monitor_parameters)

        for name, options in instr_cfg.get('parameters', {}).items():
            setup_parameter_from_dict(instr, name, options)
        for name, options in instr_cfg.get('add_parameters', {}).items():
            add_parameter_from_dict(instr, name, options)
        self.add_component(instr)
        update_monitor()
        return instr
Beispiel #5
0
 def __init__(self): 
     """ 1. setup the VNA as an instrument (if it's not already setup) 
         2. specify experimental parameters 
         3. specify paths of the target files: 
            database file and a new folder with raw (txt, png) files """
     self.vna_name = 'VNA'
     self.vna_class = Anritsu_MS46522B  # this is a qcodes VisaInstrument (interface between visa and qcodes)
     
     
     # Anritsu_MS46522B("VNA2", "TCPIP0::169.254.235.118::5001::SOCKET", 50e6, 20e9, -30, 30, 2)
     
     # -- check if instrument 'VNA' already exists. If not, create it
     if Instrument.exist(self.vna_name, self.vna_class): 
         # an instrument is created by qcodes in a global context, 
         # from which it can be retrieved manually using find_instrument
         self.vna = Instrument.find_instrument(self.vna_name, self.vna_class)
     else:
         self.vna = self.vna_class(self.vna_name, 
                                   'TCPIP0::169.254.235.118::5001::SOCKET', 
                                   50e6, 20e9, -30, 30, 2)
     
     # -- name the experiment -> automatic file names
     self.exp_name = 'Warm_VNA_Noise'  # name used by qcodes
     self.cooldown_date = '20-09-18'
     self.sample_name = 'no_sample'
     
     # -- set experiment parameters (global constants, used in different measurement functions)
     self.numberofpoints = 20 # 2001  # number of measurement points
     self.vnapower = -10  # applied power
     self.start_frequency = 3.7e9  #3.387015e9 #6.608e9-3.5e6  # start frequency of sweep
     self.stop_frequency = 5.7e9  #3.387065e9 #6.611e9 +3.5e6  # stop frequency of sweep
     self.frequency_span = self.stop_frequency - self.start_frequency
     self.center_frequency = (self.stop_frequency - self.start_frequency)/2. + self.start_frequency  # just used for power sweep
     self.measuredtrace='S21'  # spectral density measured between port 1 and 2
     self.ifbandwidth=10  # IF Bandwidth, must be in (10,30,50,70,100,300,500,700,1000,3000,5000,7000,10000)Hz
     self.powersweepstart=-30  # start for power sweep
     self.powersweepstop=20  # stop for powersweep
     self.powersweepnum=6  # number of power sweeps (perhaps +/-1) MUST BE AN EVEN NUMBER AT LEAST 6
     # groupdelayref=0.0000000225
     # vna.groupdelay.set(groupdelayref)#resets to 0 instead of working -> rounding to 0
     # print(vna.groupdelay.get())
     
     
     # -- set the path where the raw data should be saved to (pngs, txts)
     self.raw_path = ('C:\\Users\\Desktop\\tests' + 
                      '\\' + self.cooldown_date + '_' + self.sample_name + '\\'
                      'raw')
     
     # set the .db path
     qc.config["core"]["db_location"] = (
             os.path.join('C:\\Users\\Desktop\\tests',
                          'test.db'))
     
     # store a qcodesrc file with the loaded .db path to the measurements folder
     qc.config.save_config(
             os.path.join("C:\\Users\\Desktop\\tests", ".qcodesrc"))
     
     # -- check if in the standard folder -see qcodes config file- an experiment with exp_name already exists
     #    if not, create a new folder at path
     #    if so, just print the last exp. ID and go on
     try:
         # qcodes interface of loading an experiment: 
         # -- tries to connect to a database (specificed in config data structure) and searches for the exp_name
         self.exp = load_experiment_by_name(self.exp_name, sample=self.sample_name)
         print('Experiment loaded. Last ID no: ', self.exp.last_counter)  # keep track of the experiment number
     except ValueError:
         print("Experiment name ", self.exp_name, " with sample name ", self.sample_name, " not found in ", 
               qc.config["core"]["db_location"])
         
         print('Starting new experiment.')
         self.exp = new_experiment(self.exp_name, self.sample_name)
         
         os.makedirs(self.raw_path, exist_ok=True)
         
         
     # ---- always create a new folder for each day of taking measurements
     self.raw_path_with_date = os.path.join(self.raw_path, date.today().strftime("%y-%m-%d"))
     
     if not os.path.isdir(self.raw_path_with_date):
         os.makedirs(self.raw_path_with_date, exist_ok=True)  # force-create the directory