def __init__(self, name, address, timeout=.1, **kwargs): Instrument.__init__(self, name) self.address = address self.timeout = timeout self.add_parameter('attenuation', units='dB', vals=vals.Enum(*np.arange(0, 60.1, 2).tolist()), set_cmd=self._do_set_attenuation, get_cmd=self._do_get_attenuation) self.connect_message()
def __init__(self, name, LO, AWG, acquisition_instr='CBox', single_sideband_demod=False, **kw): logging.info(__name__ + ' : Initializing instrument') Instrument.__init__(self, name, **kw) self.LO = LO self.AWG = AWG self._awg_seq_filename = 'Heterodyne_marker_seq_RF_mod' self.add_parameter('frequency', label='Heterodyne frequency', units='Hz', get_cmd=self.do_get_frequency, set_cmd=self.do_set_frequency, vals=vals.Numbers(9e3, 40e9)) self.add_parameter('f_RO_mod', set_cmd=self.do_set_f_RO_mod, get_cmd=self.do_get_f_RO_mod, vals=vals.Numbers(-200e6, 200e6), label='Intermodulation frequency', units='Hz') self.add_parameter('single_sideband_demod', label='Single sideband demodulation', get_cmd=self.do_get_single_sideband_demod, set_cmd=self.do_set_single_sideband_demod) self.set('single_sideband_demod', single_sideband_demod) self.add_parameter('mod_amp', label='Modulation amplitud', units='V', set_cmd=self._do_set_mod_amp, get_cmd=self._do_get_mod_amp, vals=vals.Numbers(0, 1)) self.add_parameter('acquisition_instr', set_cmd=self._do_set_acquisition_instr, get_cmd=self._do_get_acquisition_instr, vals=vals.Strings()) self.add_parameter('nr_averages', parameter_class=ManualParameter, initial_value=1024, vals=vals.Numbers(min_value=0, max_value=1e6)) # Negative vals should be done by setting the f_RO_mod negative self._f_RO_mod = 0 # ensures that awg_seq_par_changed flag is True self._mod_amp = .5 self._frequency = None self.set('f_RO_mod', -10e6) self.set('mod_amp', .5) self._disable_auto_seq_loading = True self._awg_seq_parameters_changed = True self._mod_amp_changed = True self.acquisition_instr(acquisition_instr)
def __init__(self, name, RF, LO, AWG, acquisition_instr='CBox', single_sideband_demod=False, **kw): logging.info(__name__ + ' : Initializing instrument') Instrument.__init__(self, name, **kw) self.LO = LO self.RF = RF self.AWG = AWG self.add_parameter('frequency', label='Heterodyne frequency', units='Hz', get_cmd=self.do_get_frequency, set_cmd=self.do_set_frequency, vals=vals.Numbers(9e3, 40e9)) self.add_parameter('f_RO_mod', parameter_class=ManualParameter, vals=vals.Numbers(-600e6, 600e6), label='Intermodulation frequency', units='Hz', initial_value=10e6) self.add_parameter('RF_power', label='RF power', units='dBm', set_cmd=self.do_set_RF_power, get_cmd=self.do_get_RF_power) self.add_parameter('single_sideband_demod', label='Single sideband demodulation', parameter_class=ManualParameter) self.add_parameter('acquisition_instr', set_cmd=self._do_set_acquisition_instr, get_cmd=self._do_get_acquisition_instr, vals=vals.Strings()) self.add_parameter('nr_averages', parameter_class=ManualParameter, initial_value=1024, vals=vals.Numbers(min_value=0, max_value=1e6)) self.set('single_sideband_demod', single_sideband_demod) self._awg_seq_filename = 'Heterodyne_marker_seq_RF_mod' self._disable_auto_seq_loading = True self.acquisition_instr(acquisition_instr)
def test_instantiation_from_name_of_existing_non_ami_instrument( magnet_axes_instances, request): mag_x, mag_y, mag_z = magnet_axes_instances request.addfinalizer(AMI430_3D.close_all) non_ami_existing_instrument = Instrument("foo") with pytest.raises(TypeError, match=re.escape( f"Instrument {non_ami_existing_instrument.name} is " f"{type(non_ami_existing_instrument)} but {AMI430} " f"was requested")): AMI430_3D("AMI430-3D", mag_x.name, non_ami_existing_instrument.name, mag_z.name, field_limit)
def snapshot_base( self, update: bool = True, params_to_skip_update: Optional[Sequence[str]] = None) -> Dict: """ State of the station as a JSON-compatible dict. Note: in the station contains an instrument that has already been closed, not only will it not be snapshotted, it will also be removed from the station during the execution of this function. Args: update (bool): If True, update the state by querying the all the children: f.ex. instruments, parameters, components, etc. If False, just use the latest values in memory. params_to_skip_update: Not used Returns: dict: base snapshot """ snap = { 'instruments': {}, 'parameters': {}, 'components': {}, 'default_measurement': _actions_snapshot(self.default_measurement, update) } components_to_remove = [] for name, itm in self.components.items(): if isinstance(itm, Instrument): # instruments can be closed during the lifetime of the # station object, hence this 'if' allows to avoid # snapshotting instruments that are already closed if Instrument.is_valid(itm): snap['instruments'][name] = itm.snapshot(update=update) else: components_to_remove.append(name) elif isinstance(itm, (Parameter, ManualParameter, StandardParameter)): snap['parameters'][name] = itm.snapshot(update=update) else: snap['components'][name] = itm.snapshot(update=update) for c in components_to_remove: self.remove_component(c) return snap
def make_circuit(self, **kw): qubit_name = kw.pop('qubit', self.qubit) qubit = Instrument.find_instrument(qubit_name) amplitude = kw.get('amplitude', self.amplitude) frequency_shift = kw.pop('frequency_shift', self.frequency_shift) off_resonance_amplitude = ('off_resonacne_amplitude', self.off_resonance_amplitude) phase_error = kw.pop('phase_error', self.phase_error) error_gate = kw.pop('error_gate', self.error_gate) g = int(kw.pop('gate', 1) - 1) gate = Bootstrap_array[g] for i in range(len(gate)): amplitude = 0 if gate[i] == 'I' else 1 ''' if gate[i] == 'I': amplitude = off_resonance_amplitude if qubit_name == 'qubit_1' else 0 frequency_shift = -30e6 if qubit_name == 'qubit_1' else 0 ''' axis = [1, 0, 0] if gate[i].startswith('X') else [0, 1, 0] length = qubit.Pi_pulse_length if gate[i].endswith( 'pi') else qubit.halfPi_pulse_length name = 'G%d' % (i + 1) refgate = None if i == 0 else 'G%d' % i if gate[i] == error_gate: self.add_Z(name='error_phase', qubit=qubit, degree=phase_error) self.add_single_qubit_gate(name=name, refgate=refgate, qubit=qubit, axis=axis, amplitude=amplitude, length=length, frequency_shift=frequency_shift) if gate[i] == error_gate: self.add_Z(name='error_phase_2', qubit=qubit, degree=-phase_error) return self
def _get_function(funcStr): if isinstance(funcStr, (types.MethodType, types.FunctionType)): warnings.warn('please set function as a str', DeprecationWarning) f = funcStr elif '.' in funcStr: try: instr_name, method = funcStr.split('.') instr = Instrument.find_instrument(instr_name) f = getattr(instr, method) except Exception as e: f = get_function_from_module(funcStr) else: raise Exception('could not find function %s' % funcStr) return f
def execute_qasm_file(file_url: str, config_json: str, verbosity_level: int = 0): options = json.loads(config_json) MC = Instrument.find_instrument('Demonstrator_MC') CBox = Instrument.find_instrument('CBox') device = Instrument.find_instrument('Starmon') num_avg = int(options.get('num_avg', 512)) nr_soft_averages = int(np.round(num_avg / 512)) MC.soft_avg(nr_soft_averages) device.RO_acq_averages(512) # N.B. hardcoded fixme cfg = device.qasm_config() qasm_fp = _retrieve_file_from_url(file_url) sweep_points = _get_qasm_sweep_points(qasm_fp) s = swf.QASM_Sweep_v2(parameter_name='Circuit number ', unit='#', qasm_fn=qasm_fp, config=cfg, CBox=CBox, verbosity_level=verbosity_level) d = device.get_correlation_detector() d.value_names = ['Q0 ', 'Q1 ', 'Corr. (Q0, Q1) '] d.value_units = ['frac.', 'frac.', 'frac.'] MC.set_sweep_function(s) MC.set_sweep_points(sweep_points) MC.set_detector_function(d) data = MC.run('demonstrator') # FIXME <- add the proper name return _MC_result_to_chart_dict(data)
def test_instances(testdummy, parabola): instruments = [testdummy, parabola] for instrument in instruments: for other_instrument in instruments: instances = instrument.instances() # check that each instrument is in only its own if other_instrument is instrument: assert instrument in instances else: assert other_instrument not in instances # check that we can find each instrument from any other assert instrument is other_instrument.find_instrument(instrument.name) # check that we can find this instrument from the base class assert instrument is Instrument.find_instrument(instrument.name)
def close_and_remove_instrument(self, instrument: Union[Instrument, str] ) -> None: """ Safely close instrument and remove from station and monitor list """ # remove parameters related to this instrument from the # monitor list if isinstance(instrument, str): instrument = Instrument.find_instrument(instrument) self._monitor_parameters = [v for v in self._monitor_parameters if v.root_instrument is not instrument] # remove instrument from station snapshot self.remove_component(instrument.name) # del will remove weakref and close the instrument instrument.close() del instrument
def __init__(self, name, pulsar, **kw): super().__init__(name, pulsar, **kw) self.refphase = {} self.qubit = kw.pop('qubit', 'qubit_2') self.qubits = kw.pop('qubits', None) if self.qubits is not None: self.qubits_name = [qubit.name for qubit in self.qubits] self.refphase = {qubit.name: 0 for qubit in self.qubits} self.pulsar = None self.amplitude = kw.pop('amplitude', 1) self.frequency_shift = kw.pop('frequency_shift', 0) qubit_name = kw.pop('qubit', self.qubit) qubit = Instrument.find_instrument(qubit_name) self.length = kw.pop('duration_time', qubit.Pi_pulse_length)
def make_circuit(self, **kw): qubit_name = kw.pop('qubit', self.qubit) qubit = Instrument.find_instrument(qubit_name) length = kw.get('duration_time', self.length) amplitude = kw.get('amplitude', self.amplitude) frequency_shift = kw.pop('frequency_shift', self.frequency_shift) print('length', length) Pi_length = qubit.Pi_pulse_length Pi_num = length // Pi_length last_length = length % qubit.Pi_pulse_length # driving_length = 0 # while driving_length < length: for i in range(Pi_num): if i % 2 == 0: self.add_single_qubit_gate(name='Rabi_Oscillation_%d' % i, qubit=qubit, amplitude=amplitude, axis=[1, 0, 0], length=length, frequency_shift=frequency_shift) else: self.add_single_qubit_gate(name='Rabi_Oscillation_%d' % i, qubit=qubit, amplitude=amplitude, axis=[-1, 0, 0], length=length, frequency_shift=frequency_shift) self.add_single_qubit_gate( name='Rabi_heating', refgate='Rabi_Oscillation', qubit=qubit, amplitude=amplitude, #axis = [0,1,0], length=3.05e-6 - length, frequency_shift=frequency_shift - 20e6) return self
def test_instances(self): instruments = [self.instrument, self.instrument2] for instrument in instruments: for other_instrument in instruments: instances = instrument.instances() # check that each instrument is in only its own if other_instrument is instrument: self.assertIn(instrument, instances) else: self.assertNotIn(other_instrument, instances) # check that we can find each instrument from any other self.assertEqual( instrument, other_instrument.find_instrument(instrument.name)) # check that we can find this instrument from the base class self.assertEqual(instrument, Instrument.find_instrument(instrument.name))
def test_instances(self): instruments = [self.gates, self.source, self.meter] for instrument in instruments: for other_instrument in instruments: instances = instrument.instances() # check that each instrument is in only its own # instances list # also test type checking in find_instrument, # but we need to use find_component so it executes # on the server if other_instrument is instrument: self.assertIn(instrument, instances) name2 = other_instrument.find_component( instrument.name + '.name', other_instrument._instrument_class) self.assertEqual(name2, instrument.name) else: self.assertNotIn(other_instrument, instances) with self.assertRaises(TypeError): other_instrument.find_component( instrument.name + '.name', other_instrument._instrument_class) # check that we can find each instrument from any other # find_instrument is explicitly mapped in RemoteInstrument # so this call gets executed in the main process self.assertEqual( instrument, other_instrument.find_instrument(instrument.name)) # but find_component is not, so it executes on the server self.assertEqual( instrument.name, other_instrument.find_component(instrument.name + '.name')) # check that we can find this instrument from the base class self.assertEqual(instrument, Instrument.find_instrument(instrument.name))
def AWG_obj(self, **kw): """ Return the AWG object corresponding to a channel or an AWG name. Args: AWG: Name of the AWG Instrument. channel: Name of the channel Returns: An instance of Instrument class corresponding to the AWG requested. """ AWG = kw.get('AWG', None) chan = kw.get('channel', None) if AWG is not None and chan is not None: raise ValueError('Both `AWG` and `channel` arguments passed to ' 'Pulsar.AWG_obj()') elif AWG is None and chan is not None: name = self.channels[chan]['AWG'] elif AWG is not None and chan is None: name = AWG else: raise ValueError('Either `AWG` or `channel` argument needs to be ' 'passed to Pulsar.AWG_obj()') return Instrument.find_instrument(name)
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()
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
def load_instrument(self, identifier: str, **kwargs) -> Instrument: """ Creates an instrument driver 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 **kwargs: additional keyword arguments that get passed on to the __init__-method of the instrument to be added. """ # load file self.load_file(self.filename) # load from config if identifier not in self._instrument_config.keys(): raise RuntimeError('Instrument {} not found in config.' .format(identifier)) instr_cfg = self._instrument_config[identifier] # config is not parsed for errors. On errors qcodes should be able to # to report them # check if instrument is already defined and close connection if instr_cfg.get('enable_forced_reconnect', enable_forced_reconnect): # save close instrument and remove from monitor list with suppress(KeyError): instr = Instrument.find_instrument(identifier) # remove parameters related to this instrument from the monitor list self.monitor_parameters = {k:v for k,v in self.monitor_parameters.items() if v.root_instrument is not instr} instr.close() # remove instrument from station snapshot self.station.components.pop(instr.name) # instantiate instrument module = importlib.import_module(instr_cfg['driver']) instr_class = getattr(module, instr_cfg['type']) 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 # the intuitive line: # 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) instr = instr_class(name=identifier, **instr_kwargs) # setup # local function to refactor common code from defining new parameter # and setting existing one def setup_parameter_from_dict(parameter, options_dict): for attr, val in options_dict.items(): if attr in self.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[id(parameter)] = 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} no recognized when' f' instatiating parameter \"{parameter.name}\"') if 'initial_value' in options_dict: parameter.set(options_dict['initial_value']) # setup existing parameters for name, options in instr_cfg.get('parameters', {}).items(): # get the parameter object from its name: p = instr for level in name.split('.'): p = getattr(p, level) setup_parameter_from_dict(p, options) # setup new parameters for name, options in instr_cfg.get('add_parameters', {}).items(): # allow only top level paremeters for now # pop source only temporarily source = options.pop('source', False) if source: source_p = instr for level in source.split('.'): source_p = getattr(source_p, level) instr.add_parameter(name, DelegateParameter, source=source_p) else: instr.add_parameter(name, Parameter) p = getattr(instr, name) setup_parameter_from_dict(p, options) # restore source options['source'] = source # add the instrument to the station self.station.add_component(instr) # restart Monitor Monitor(*self.monitor_parameters.values()) return instr
def __init__(self, name, timeout=5, address=''): Instrument.__init__(self, name) self._address = address self._terminator = '' self.add_parameter('timeout', unit='s', initial_value=5, parameter_class=ManualParameter, vals=vals.MultiType(vals.Numbers(min_value=0), vals.Enum(None))) self.add_parameter('address', unit='', initial_value='', parameter_class=ManualParameter, vals=vals.Strings()) self.add_parameter('DC_output', label='DC Output (ON/OFF)', parameter_class=ManualParameter, vals=vals.Ints(0, 1)) for i in range(1, 5): self.add_parameter('ch{}_state'.format(i), initial_value=1, label='Status channel {}'.format(i), parameter_class=ManualParameter, vals=vals.Ints(0, 1)) self.add_parameter('ch{}_amp'.format(i), initial_value=1., label='Amplitude channel {}'.format(i), unit='Vpp', parameter_class=ManualParameter, vals=vals.Numbers(0.02, 4.5)) self.add_parameter('ch{}_offset'.format(i), initial_value=0, label='Offset channel {}'.format(i), unit='V', parameter_class=ManualParameter, vals=vals.Numbers(-.1, .1)) self.add_parameter('ch{}_waveform'.format(i), initial_value="", label='Waveform channel {}'.format(i), parameter_class=ManualParameter, vals=vals.Strings()) self.add_parameter('ch{}_direct_output'.format(i), initial_value=1, label='Direct output channel {}'.format(i), parameter_class=ManualParameter, vals=vals.Ints(0, 1)) self.add_parameter('ch{}_filter'.format(i), initial_value='INF', label='Low pass filter channel {}'.format(i), unit='Hz', parameter_class=ManualParameter, vals=vals.Enum(20e6, 100e6, 9.9e37, 'INF', 'INFinity')) self.add_parameter('ch{}_DC_out'.format(i), initial_value=0, label='DC output level channel {}'.format(i), unit='V', parameter_class=ManualParameter, vals=vals.Numbers(-3, 5)) for j in range(1, 3): self.add_parameter('ch{}_m{}_del'.format(i, j), initial_value=0, label='Channel {} Marker {} delay'.format( i, j), unit='ns', parameter_class=ManualParameter, vals=vals.Numbers(0, 1)) self.add_parameter( 'ch{}_m{}_high'.format(i, j), initial_value=2, label='Channel {} Marker {} high level'.format(i, j), unit='V', parameter_class=ManualParameter, vals=vals.Numbers(-2.7, 2.7)) self.add_parameter( 'ch{}_m{}_low'.format(i, j), initial_value=0, label='Channel {} Marker {} low level'.format(i, j), unit='V', parameter_class=ManualParameter, vals=vals.Numbers(-2.7, 2.7)) self.add_parameter('clock_freq', label='Clock frequency', unit='Hz', vals=vals.Numbers(1e6, 1.2e9), parameter_class=ManualParameter, initial_value=1.2e9) self.awg_files = {} self.file = None self.stop() # to init self._state
def setup_dmm(dmm: Instrument) -> None: dmm.aperture_time(1.0) dmm.autozero("OFF") dmm.autorange("OFF")
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
def XY_rotation(self, degree = 90, length = None, waiting_time = 0, refgate = None, refpoint = 'end', refqubit = None): # global phase # IQ_Modulation = self.frequency if length is not None: pulse_length = length else: pulse_length = self.halfPi_pulse_length if degree == 90 else degree*self.Pi_pulse_length/180 pulse_amp = self.amplitude pulse_delay = Instrument.find_instrument(self.qubit).pulse_delay if self.qubit == 'qubit_2' and refqubit == 'qubit_2': pulse_delay = 0 ## voltage pulse is not used here voltage_pulse = SquarePulse(channel = self.channel_VP, name = '%s_voltage_pulse'%self.name, amplitude = 0, length = 0)#pulse_length + waiting_time) PM_pulse = SquarePulse(channel = self.channel_PM, name = '%s_PM_pulse'%self.name, amplitude = 2, length = pulse_length+self.PM_before+self.PM_after) if self.frequency_shift == 0: microwave_pulse_I = SquarePulse(channel = self.channel_I, name = '%s_microwave_pulse_I'%self.name, amplitude = pulse_amp*np.cos(-self.refphase + self.axis_angle), length = pulse_length) microwave_pulse_Q = SquarePulse(channel = self.channel_Q, name = '%s_microwave_pulse_Q'%self.name, amplitude = pulse_amp*np.sin(-self.refphase + self.axis_angle), length = pulse_length) elif self.frequency_shift != 0: ##here frequency and phase is not yet ready!!!!!!!!!!! phase = self.IQ_phase-self.refphase + self.axis_angle freq = self.frequency_shift microwave_pulse_I = CosPulse(channel = self.channel_I, name = '%s_microwave_pulse_I'%self.name, frequency = freq, amplitude = pulse_amp, length = pulse_length, phase = phase) microwave_pulse_Q = CosPulse(channel = self.channel_Q, name = '%s_microwave_pulse_Q'%self.name, frequency = freq, amplitude = pulse_amp, length = pulse_length, phase = phase-90) ''' adiabatic sweep for test ''' if type(self.frequency_shift) is list : phase = self.IQ_phase-self.refphase + self.axis_angle freq = self.frequency_shift start_freq = self.frequency_shift[0] end_freq = self.frequency_shift[1] microwave_pulse_I = AdiabaticCosPulse(channel = self.channel_I, name = '%s_microwave_pulse_I'%self.name, start_frequency = start_freq, end_frequency = end_freq, amplitude = pulse_amp, length = pulse_length, phase = phase) microwave_pulse_Q = AdiabaticCosPulse(channel = self.channel_Q, name = '%s_microwave_pulse_Q'%self.name, start_frequency = start_freq, end_frequency = end_freq, amplitude = pulse_amp, length = pulse_length, phase = phase-90) ''' ''' self.pulses[0] = { 'pulse': voltage_pulse, 'pulse_name': voltage_pulse.name, 'refpulse': None if refgate == None else refgate[0]['pulse_name'], 'refpoint': refpoint, 'waiting': 0 } self.pulses[1] = { 'pulse': microwave_pulse_I, 'pulse_name': microwave_pulse_I.name, 'refpulse': None if refgate == None else refgate[-2]['pulse_name'], ## name of the refpulse 'refpoint': refpoint, 'waiting': waiting_time + pulse_delay } self.pulses[2] = { 'pulse': microwave_pulse_Q, 'pulse_name': microwave_pulse_Q.name, 'refpulse': '%s_microwave_pulse_I'%self.name, 'refpoint': 'start', 'waiting': 0 } ## here you just construct a dictionary which contains all the information of pulses you use self.pulses[3] = { 'pulse': PM_pulse, 'pulse_name': PM_pulse.name, 'refpulse': '%s_microwave_pulse_I'%self.name, 'refpoint': 'start', 'waiting': -self.PM_before } return True
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
The script will run immediately as an anonymous script. Args: program: A list of program instructions. One line per list item, e.g. ['for ii = 1, 10 do', 'print(ii)', 'end' ] """ mainprog = '\r\n'.join(program) + '\r\n' wrapped = 'loadandrunscript\r\n{}endscript\n'.format(mainprog) if debug: log.debug('Wrapped the following script:') log.debug(wrapped) return wrapped if __name__ == "__main__": try: # ats_inst.close() # acquisition_controller.close() Instrument.close_all() except KeyError: pass except NameError: pass Bfield = Keithley_2600(name='Bfield', address="GPIB::26::INSTR") # Bfield.smua.curr.set(0e-6) print(Bfield.smua.sourcerange_i.get()) Instrument.close_all()
def tearDown(self): Instrument.close_all()
def common_init(self, name, LO, AWG, acquisition_instr='CBox', single_sideband_demod=False, **kw): logging.info(__name__ + ' : Initializing instrument') Instrument.__init__(self, name, **kw) self.LO = LO self.AWG = AWG self.add_parameter('frequency', label='Heterodyne frequency', unit='Hz', vals=vals.Numbers(9e3, 40e9), get_cmd=self._get_frequency, set_cmd=self._set_frequency) self.add_parameter('f_RO_mod', label='Intermodulation frequency', unit='Hz', vals=vals.Numbers(-600e6, 600e6), set_cmd=self._set_f_RO_mod, get_cmd=self._get_f_RO_mod) self.add_parameter('single_sideband_demod', vals=vals.Bool(), label='Single sideband demodulation', parameter_class=ManualParameter, initial_value=single_sideband_demod) self.add_parameter('external_trigger', vals=vals.Bool(), label='wait for external trigger', parameter_class=ManualParameter, initial_value=False) self.add_parameter('acquisition_instr', vals=vals.Strings(), label='Acquisition instrument', set_cmd=self._set_acquisition_instr, get_cmd=self._get_acquisition_instr) self.add_parameter('nr_averages', label='Number of averages', vals=vals.Numbers(min_value=0, max_value=1e6), parameter_class=ManualParameter, initial_value=1024) self.add_parameter('status', vals=vals.Enum('On', 'Off'), set_cmd=self._set_status, get_cmd=self._get_status) self.add_parameter('trigger_separation', label='Trigger separation', unit='s', vals=vals.Numbers(0), set_cmd=self._set_trigger_separation, get_cmd=self._get_trigger_separation) self.add_parameter('RO_length', label='Readout length', unit='s', vals=vals.Numbers(0), set_cmd=self._set_RO_length, get_cmd=self._get_RO_length) self.add_parameter('auto_seq_loading', vals=vals.Bool(), label='Automatic AWG sequence loading', parameter_class=ManualParameter, initial_value=True) self.add_parameter( 'acq_marker_channels', vals=vals.Strings(), label='Acquisition trigger channels', docstring='comma (,) separated string of marker channels', set_cmd=self._set_acq_marker_channels, get_cmd=self._get_acq_marker_channels) self._trigger_separation = 10e-6 self._RO_length = 2274e-9 self._awg_seq_filename = '' self._awg_seq_parameters_changed = True self._UHFQC_awg_parameters_changed = True self.acquisition_instr(acquisition_instr) self.status('Off') self._f_RO_mod = 10e6 self._frequency = 5e9 self.frequency(5e9) self.f_RO_mod(10e6) self._eps = 0.01 # Hz slack for comparing frequencies self._acq_marker_channels = ('ch4_marker1,ch4_marker2,' + 'ch3_marker1,ch3_marker2')
def setUp(self): Instrument.close_all()
def test_is_valid(self): assert Instrument.is_valid(self.instrument) self.instrument.close() assert not Instrument.is_valid(self.instrument)
from pycqed.measurement import sweep_functions as swf from tess.TessConnect import TessConnection import logging default_execute_options = {} tc = TessConnection() tc.connect("execute_Starmon") default_simulate_options = { "num_avg": 10000, "iterations": 1 } try: MC = Instrument.find_instrument('MC') st = MC.station new_station = False except KeyError: st = qc.station.Station() new_station = True """ Create the station for which the Instruments can connect to. A virtual representation of the physical setup. In our case, the CCL. Since we're calling the station, """ try: MC_demo = measurement_control.MeasurementControl( 'Demonstrator_MC', live_plot_enabled=True, verbose=True) datadir = os.path.abspath(os.path.join(
def close_all_instruments(): """Makes sure that after startup and teardown, all instruments are closed""" Instrument.close_all() yield Instrument.close_all()
def test_is_valid(testdummy): assert Instrument.is_valid(testdummy) testdummy.close() assert not Instrument.is_valid(testdummy)
def _close_before_and_after(): Instrument.close_all() try: yield finally: Instrument.close_all()
def test_base_instrument_errors(self): b = Instrument('silent', server_name=None) with self.assertRaises(NotImplementedError): b.write('hello!') with self.assertRaises(NotImplementedError): b.ask('how are you?') with self.assertRaises(TypeError): b.add_function('skip', call_cmd='skip {}', args=['not a validator']) with self.assertRaises(NoCommandError): b.add_function('jump') with self.assertRaises(NoCommandError): b.add_parameter('height')