def __init__(self, name, alazar_name, target_instrument, **kwargs): super().__init__(name, alazar_name, **kwargs) self._target_instrument = target_instrument self.add_parameter(name='t_no_blip', set_cmd=None, unit='ms', initial_value=40) self.add_parameter(name='t_max_wait', set_cmd=None, unit='ms', initial_value=500) self.add_parameter(name='max_wait_action', set_cmd=None, unit='ms', initial_value='start', vals=vals.Enum('start', 'error')) self.add_parameter(name='silent', set_cmd=None, initial_value=True, vals=vals.Bool()) self.add_parameter(name='stage', set_cmd=None, vals=vals.Enum('initialization', 'active', 'read')) self.add_parameter(name='record_initialization_traces', set_cmd=None, initial_value=False, vals=vals.Bool()) # Parameters for the target instrument and command after initialization self.add_parameter(name='target_instrument', get_cmd=lambda: self._target_instrument.name) self.add_parameter(name='target_command', set_cmd=None, initial_value='start', vals=vals.Strings()) self.add_parameter(name='readout_channel', set_cmd=None, vals=vals.Enum('A', 'B', 'C', 'D')) self.add_parameter(name='trigger_channel', set_cmd=None, vals=vals.Enum('A', 'B', 'C', 'D')) self.add_parameter(name='trigger_threshold_voltage', set_cmd=None) self.add_parameter(name='readout_threshold_voltage', set_cmd=None) self.add_parameter(name='initialization_traces', get_cmd=lambda: self._initialization_traces) self.add_parameter(name='post_initialization_traces', get_cmd=lambda: self._post_initialization_traces) self.number_of_buffers_no_blip = None self.number_of_buffers_max_wait = None self._target_command = None self.buffer_no_blip_idx = None self.trace_idx = None self.t_start_list = None
def __init__(self, pulses: list = None, allow_untargeted_pulses: bool = True, allow_targeted_pulses: bool = True, allow_pulse_overlap: bool = True, final_delay: float = None): super().__init__(use_as_attributes=True, log_changes=False, simplify_snapshot=True) # For PulseSequence.satisfies_conditions, we need to separate conditions # into those relating to pulses and to connections. We perform an import # here because it otherwise otherwise leads to circular imports if self.connection_conditions is None or self.pulse_conditions is None: from silq.meta_instruments.layout import connection_conditions from silq.pulses import pulse_conditions PulseSequence.connection_conditions = connection_conditions PulseSequence.pulse_conditions = pulse_conditions self.allow_untargeted_pulses = Parameter( initial_value=allow_untargeted_pulses, set_cmd=None, vals=vals.Bool()) self.allow_targeted_pulses = Parameter( initial_value=allow_targeted_pulses, set_cmd=None, vals=vals.Bool()) self.allow_pulse_overlap = Parameter(initial_value=allow_pulse_overlap, set_cmd=None, vals=vals.Bool()) self.duration = Parameter(unit='s', set_cmd=None) self.final_delay = Parameter(unit='s', set_cmd=None, vals=vals.Numbers()) if final_delay is not None: self.final_delay = final_delay else: self.final_delay = self.default_final_delay self.t_list = Parameter(initial_value=[0]) self.t_start_list = Parameter(initial_value=[]) self.t_stop_list = Parameter() self.enabled_pulses = Parameter(initial_value=[], set_cmd=None, vals=vals.Lists()) self.disabled_pulses = Parameter(initial_value=[], set_cmd=None, vals=vals.Lists()) self.pulses = Parameter(initial_value=[], vals=vals.Lists(), set_cmd=None) self.duration = None # Reset duration to t_stop of last pulse # Perform a separate set to ensure set method is called self.pulses = pulses or []
def _add_cfg_parameters(self): self.add_parameter( 'polycoeffs_freq_conv', docstring='coefficients of the polynomial used to convert ' 'amplitude in V to detuning in Hz. N.B. it is important to ' 'include both the AWG range and channel amplitude in the params.\n' 'In order to convert a set of cryoscope flux arc coefficients to ' ' units of Volts they can be rescaled using [c0*sc**2, c1*sc, c2]' ' where sc is the desired scaling factor that includes the sq_amp ' 'used and the range of the AWG (5 in amp mode).', vals=vals.Arrays(), # initial value is chosen to not raise errors initial_value=np.array([2e9, 0, 0]), parameter_class=ManualParameter) self.add_parameter('cfg_operating_mode', initial_value='Codeword', vals=vals.Enum('Codeword', 'LongSeq'), parameter_class=ManualParameter) self.add_parameter('cfg_awg_channel', initial_value=1, vals=vals.Ints(1, 8), parameter_class=ManualParameter) self.add_parameter('cfg_distort', initial_value=True, vals=vals.Bool(), parameter_class=ManualParameter) self.add_parameter( 'cfg_append_compensation', docstring=( 'If True compensation pulses will be added to individual ' ' waveforms creating very long waveforms for each codeword'), initial_value=True, vals=vals.Bool(), parameter_class=ManualParameter) self.add_parameter('cfg_compensation_delay', parameter_class=ManualParameter, initial_value=3e-6, unit='s', vals=vals.Numbers()) self.add_parameter( 'cfg_pre_pulse_delay', unit='s', label='Pre pulse delay', docstring='This parameter is used for fine timing corrections, the' ' correction is applied in distort_waveform.', initial_value=0e-9, vals=vals.Numbers(0, 1e-6), parameter_class=ManualParameter) self.add_parameter('instr_distortion_kernel', parameter_class=InstrumentRefParameter) self.add_parameter('cfg_max_wf_length', parameter_class=ManualParameter, initial_value=10e-6, unit='s', vals=vals.Numbers(0, 100e-6))
def __init__(self, name, silent=False, **kwargs): super().__init__(name, **kwargs) self._silent = False self.add_parameter('silent', parameter_class=ManualParameter, initial_value=silent, vals=vals.Bool())
def add_source(self, name): """ The name of the source needs to match the name of the module on the DC source """ if name in self._target_names: raise KeyError( "A flux target with name '{}' already exists".format(name)) elif name in self._source_names: raise KeyError( "A flux source with name '{}' already exists".format(name)) j = len(self._source_names) self._source_names.append(name) self._source_active.append(True) self._couplings = np.hstack( (self._couplings, np.zeros((self._couplings.shape[0], 1)))) for i, trg_name in enumerate(self._target_names): self.add_parameter( 'c_{}_{}'.format(trg_name, name), unit='1/V', vals=vals.Numbers(), get_cmd=(lambda self=self, i=i, j=j: self._couplings[i, j]), set_cmd=( lambda x, self=self, i=i, j=j: self._couplings.__setitem__( (i, j), x))) self.add_parameter( 'active_{}'.format(name), vals=vals.Bool(), get_cmd=(lambda self=self, j=j: self._source_active[j]), set_cmd=(lambda x, self=self, j=j: self._source_active.__setitem__( j, x)))
def __init__(self, instrument_name: str, **kwargs): # TODO: pass along actual instrument instead of name super().__init__(name=instrument_name + '_interface', **kwargs) self.instrument = self.find_instrument(name=instrument_name) self._input_channels = {} self._output_channels = {} self._channels = {} self.pulse_sequence = PulseSequence(allow_untargeted_pulses=False, allow_pulse_overlap=False) self.input_pulse_sequence = PulseSequence( allow_untargeted_pulses=False, allow_pulse_overlap=False) self.add_parameter('instrument_name', set_cmd=None, initial_value=instrument_name, vals=vals.Anything()) self.add_parameter('is_primary', set_cmd=None, initial_value=False, vals=vals.Bool()) self.pulse_implementations = []
def _add_mixer_corr_pars(self): self.add_parameter('G_mixer_alpha', vals=vals.Numbers(), parameter_class=ManualParameter, initial_value=1.0) self.add_parameter('G_mixer_phi', vals=vals.Numbers(), unit='deg', parameter_class=ManualParameter, initial_value=0.0) self.add_parameter('D_mixer_alpha', vals=vals.Numbers(), parameter_class=ManualParameter, initial_value=1.0) self.add_parameter('D_mixer_phi', vals=vals.Numbers(), unit='deg', parameter_class=ManualParameter, initial_value=0.0) self.add_parameter( 'mixer_apply_predistortion_matrix', vals=vals.Bool(), docstring=( 'If True applies a mixer correction using mixer_phi and ' 'mixer_alpha to all microwave pulses using.'), parameter_class=ManualParameter, initial_value=True)
def create_awg_parameters(self, channel_name_map: dict): PulsarAWGInterface.create_awg_parameters(self, channel_name_map) pulsar = self.pulsar name = self.awg.name pulsar.add_parameter(f"{name}_use_placeholder_waves", initial_value=False, vals=vals.Bool(), parameter_class=ManualParameter) pulsar.add_parameter(f"{name}_trigger_source", initial_value="Dig1", vals=vals.Enum("Dig1", "DIO", "ZSync"), parameter_class=ManualParameter, docstring="Defines for which trigger source the " "AWG should wait, before playing the " "next waveform. Allowed values are: " "'Dig1', 'DIO', 'ZSync'.") # real and imaginary part of the wave form channel groups for ch_nr in range(len(self.awg.sgchannels)): group = [] for q in ["i", "q"]: id = f"sg{ch_nr + 1}{q}" ch_name = channel_name_map.get(id, f"{name}_{id}") self.create_channel_parameters(id, ch_name, "analog") pulsar.channels.add(ch_name) group.append(ch_name) for ch_name in group: pulsar.channel_groups.update({ch_name: group})
def __init__(self, name, address=None, slot_names=None, **kw): super().__init__(name, **kw) if slot_names is None: self.slot_names = {} else: self.slot_names = slot_names self.module_nr = {} for i in self.slot_names: if self.slot_names[i] in self.module_nr: raise ValueError('Duplicate names in slot_names') self.module_nr[self.slot_names[i]] = i self.modules = self.find_modules() for i in self.modules: module_name = self.slot_names.get(i, i) self.add_parameter('IDN_{}'.format(module_name), label="IDN of module {}".format(module_name), get_cmd=partial(self.get_module_idn, i)) self.add_parameter('volt_{}'.format(module_name), unit='V', label="Output voltage of module " "{}".format(module_name), vals=vals.Numbers(-20, 20), get_cmd=partial(self.get_voltage, i), set_cmd=partial(self.set_voltage, i)) self.add_parameter('volt_{}_step'.format(module_name), unit='V', label="Step size when changing the voltage " "smoothly on module " "{}".format(module_name), parameter_class=ManualParameter, vals=vals.Numbers(0, 20), initial_value=0.005) self.add_parameter('smooth_timestep', unit='s', label="Delay between sending the write commands" "when changing the voltage smoothly", parameter_class=ManualParameter, vals=vals.Numbers(0, 1), initial_value=0.05) self.add_parameter('max_attempts', unit='', label="Number of times get_voltage is retried in " "case of an error.", get_cmd=None, set_cmd=None, docstring="Ignored. Only exists for compatibility " "with physical instrument driver.", vals=vals.Ints(0, 100), initial_value=10) self.add_parameter('verbose', parameter_class=ManualParameter, docstring="Ignored. Only exists for compatibility " "with physical instrument driver.", vals=vals.Bool(), initial_value=False) self._voltages = {i: 0 for i in self.modules}
def __init__(self, name, **kw): super().__init__(name, **kw) self._wave_dict_dist = dict() self.sampling_rate(1e9) self.add_parameter('cfg_oldstyle_kernel_enabled', initial_value=False, vals=vals.Bool(), parameter_class=ManualParameter)
def __init__(self, name, UHFQC, **kw): logging.warning('The UHFQC_LookuptableManagerManager is deprecated') logging.info(__name__ + ' : Initializing instrument') super().__init__(name, **kw) self.UHFQC = UHFQC self.add_parameter('mixer_QI_amp_ratio', vals=vals.Numbers(), parameter_class=ManualParameter, initial_value=1.0) self.add_parameter('mixer_IQ_phase_skewness', vals=vals.Numbers(), unit='deg', parameter_class=ManualParameter, initial_value=0.0) # These parameters are added for mixer skewness correction. # They are intended to be renamed such that they can be combined with # mixer_QI_amp_ratio and mixer_IQ_phase_skewness. self.add_parameter('mixer_alpha', vals=vals.Numbers(), parameter_class=ManualParameter, initial_value=1.0) self.add_parameter('mixer_phi', vals=vals.Numbers(), unit='deg', parameter_class=ManualParameter, initial_value=0.0) self.add_parameter('mixer_apply_predistortion_matrix', vals=vals.Bool(), parameter_class=ManualParameter, initial_value=False) self.add_parameter('acquisition_delay', vals=vals.Numbers(), unit='s', parameter_class=ManualParameter, initial_value=270e-9) self.add_parameter('LutMans', vals=vals.Anything(), set_cmd=self._attach_lutmans_to_Lutmanman) self.add_parameter('sampling_rate', vals=vals.Numbers(), unit='Hz', parameter_class=ManualParameter, initial_value=1.8e9) # Set to a default because box is not expected to change self._voltage_min = -1.0 self._voltage_max = 1.0 - 1.0 / 2**13
def create_awg_parameters(self, channel_name_map): super().create_awg_parameters(channel_name_map) pulsar = self.pulsar name = self.awg.name # Override _min_length parameter created in base class # TODO: Check if this makes sense, it is a constant for the other AWGs # Furthermore, it does not really make sense to manually set the minimum # length which is a property of the instrument... del pulsar.parameters[f"{name}_min_length"] pulsar.add_parameter(f"{name}_min_length", initial_value=self.MIN_LENGTH, parameter_class=ManualParameter) pulsar.add_parameter(f"{name}_use_placeholder_waves", initial_value=False, vals=vals.Bool(), parameter_class=ManualParameter) pulsar.add_parameter(f"{name}_trigger_source", initial_value="Dig1", vals=vals.Enum("Dig1", "DIO", "ZSync"), parameter_class=ManualParameter, docstring="Defines for which trigger source the " "AWG should wait, before playing the " "next waveform. Allowed values are: " "'Dig1', 'DIO', 'ZSync'.") pulsar.add_parameter(f"{name}_prepend_zeros", initial_value=None, vals=vals.MultiType(vals.Enum(None), vals.Ints(), vals.Lists(vals.Ints())), parameter_class=ManualParameter) group = [] for ch_nr in range(8): id = f"ch{ch_nr + 1}" ch_name = channel_name_map.get(id, f"{name}_{id}") self.create_channel_parameters(id, ch_name, "analog") pulsar.channels.add(ch_name) group.append(ch_name) id = f"ch{ch_nr + 1}m" ch_name = channel_name_map.get(id, f"{name}_{id}") self.create_channel_parameters(id, ch_name, "marker") pulsar.channels.add(ch_name) group.append(ch_name) # channel pairs plus the corresponding marker channels are # considered as groups if (ch_nr + 1) % 2 == 0: for ch_name in group: pulsar.channel_groups.update({ch_name: group}) group = []
def __init__(self, name, *arg, **kw): super().__init__(name, *arg, **kw) self.add_parameter('frequency', unit='Hz', set_cmd=None, vals=validators.Numbers(1e3, 20e9), initial_value=10e9) self.add_parameter('power', unit='dBm', set_cmd=None, vals=validators.Numbers(-100, 25), initial_value=-100) self.add_parameter('rf_on', set_cmd=None, vals=validators.Bool(), initial_value=False)
def create_channel_parameters(self, id:str, ch_name:str, ch_type:str): super().create_channel_parameters(id, ch_name, ch_type) pulsar = self.pulsar if ch_type == "analog": pulsar.add_parameter( f"{ch_name}_amplitude_scaling", set_cmd=partial(self.awg_setter, id, "amplitude_scaling"), get_cmd=partial(self.awg_getter, id, "amplitude_scaling"), vals=vals.Numbers(min_value=-1.0, max_value=1.0), initial_value=1.0, docstring=f"Scales the AWG output of channel by a given factor." ) pulsar.add_parameter(f"{ch_name}_internal_modulation", initial_value=False, vals=vals.Bool(), parameter_class=ManualParameter) # first channel of a pair if (int(id[2:]) - 1) % 2 == 0: awg_nr = (int(id[2:]) - 1) // 2 param_name = f"{ch_name}_mod_freq" pulsar.add_parameter( param_name, unit='Hz', initial_value=None, set_cmd=self._hdawg_mod_setter(awg_nr), get_cmd=self._hdawg_mod_getter(awg_nr), docstring="Carrier frequency of internal modulation for " "a channel pair. Positive (negative) sign " "corresponds to upper (lower) side band. Setting " "it to None disables internal modulation." ) # qcodes will not set the initial value if it is None, so we set # it manually here to ensure that internal modulation gets # switched off in the init. pulsar.set(param_name, None) else: # ch_type == "marker" # So far no additional parameters specific to marker channels pass
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) ZI_AcquisitionDevice.__init__(self, *args, **kwargs) self.n_acq_units = len(self.qachannels) self.lo_freqs = [None] * self.n_acq_units # re-create with correct length self.n_acq_int_channels = self.max_qubits_per_channel self._reset_acq_poll_inds() # Mode of the acquisition units ('readout' or 'spectroscopy') # This is different from self._acq_mode (allowed_modes) self._acq_units_modes = {} self._awg_program = [None]*self.n_acq_units self.seqtrigger = None self.timer = None self.awg_active = [False] * self.n_acq_units self.add_parameter( 'allowed_lo_freqs', initial_value=np.arange(1e9, 8.1e9, 100e6), parameter_class=ManualParameter, docstring='List of values that the center frequency (LO) is ' 'allowed to take. As of now this is limited to steps ' 'of 100 MHz.', set_parser=lambda x: list(np.atleast_1d(x).flatten()), vals=validators.MultiType(validators.Lists(), validators.Arrays(), validators.Numbers())) self.add_parameter( 'use_hardware_sweeper', initial_value=False, parameter_class=ManualParameter, docstring='Bool indicating whether the hardware sweeper should ' 'be used in spectroscopy mode', vals=validators.Bool()) self.add_parameter( 'acq_trigger_delay', initial_value=200e-9, parameter_class=ManualParameter, docstring='Delay between the pulse generation and acquisition. ' 'This is used both in the scope and the integration ' 'units for consistency.', vals=validators.Numbers())
def add_target(self, name): if name in self._target_names: raise KeyError( "A flux target with name '{}' already exists".format(name)) elif name in self._source_names: raise KeyError( "A flux source with name '{}' already exists".format(name)) i = len(self._target_names) self._target_names.append(name) self._target_active.append(True) self._offsets = np.append(self._offsets, [0]) self._couplings = np.vstack( (self._couplings, np.zeros((1, self._couplings.shape[1])))) self.add_parameter( 'offset_{}'.format(name), vals=vals.Numbers(), get_cmd=(lambda self=self, i=i: self._offsets[i]), set_cmd=( lambda x, self=self, i=i: self._offsets.__setitem__(i, x))) for j, src_name in enumerate(self._source_names): self.add_parameter( 'c_{}_{}'.format(name, src_name), unit='1/V', vals=vals.Numbers(), get_cmd=(lambda self=self, i=i, j=j: self._couplings[i, j]), set_cmd=( lambda x, self=self, i=i, j=j: self._couplings.__setitem__( (i, j), x))) self.add_parameter( 'active_{}'.format(name), vals=vals.Bool(), get_cmd=(lambda self=self, i=i: self._target_active[i]), set_cmd=(lambda x, self=self, i=i: self._target_active.__setitem__( i, x))) self.add_parameter( 'flux_{}'.format(name), vals=vals.Numbers(), get_cmd=(lambda self=self, name=name: self.get_fluxes()[name]), set_cmd=( lambda x, self=self, name=name: self.set_fluxes({name: x})))
def create_awg_parameters(self, channel_name_map: dict): SHFAcquisitionModulePulsar.create_awg_parameters( self, channel_name_map) pulsar = self.pulsar name = self.awg.name pulsar.add_parameter(f"{name}_use_placeholder_waves", initial_value=False, vals=vals.Bool(), parameter_class=ManualParameter) # real and imaginary part of the wave form channel groups for ch_nr in range(len(self.awg.sgchannels)): group = [] for q in ["i", "q"]: id = f"sg{ch_nr + 1}{q}" ch_name = channel_name_map.get(id, f"{self.awg.name}_{id}") self.create_channel_parameters(id, ch_name, "analog") self.pulsar.channels.add(ch_name) group.append(ch_name) for ch_name in group: self.pulsar.channel_groups.update({ch_name: group})
def __init__(self, name, num_models=10, **kw): super().__init__(name, **kw) self._num_models = num_models self.add_parameter('cfg_hardware_friendly', initial_value=False, parameter_class=ManualParameter, vals=vals.Bool()) self.add_parameter('cfg_sampling_rate', parameter_class=ManualParameter, initial_value=1e9, vals=vals.Numbers()) self.add_parameter('cfg_gain_correction', parameter_class=ManualParameter, initial_value=1, vals=vals.Numbers()) for i in range(self._num_models): self.add_parameter('filter_model_{:02}'.format(i), parameter_class=ManualParameter, initial_value={}, vals=vals.Dict())
def __init__(self, name, port, channel_map): super().__init__(name, port, update_currents=False) self.channel_map = channel_map self.add_parameter('smooth_timestep', unit='s', label="Delay between sending the write commands" "when changing the voltage smoothly", get_cmd=None, set_cmd=None, vals=vals.Numbers(0.002, 1), initial_value=0.01) for ch_number, ch_name in self.channel_map.items(): stepname = f"volt_{ch_name}_step" self.add_parameter(stepname, unit='V', label="Step size when changing the voltage " + f"smoothly on module {ch_name}", get_cmd=None, set_cmd=None, vals=vals.Numbers(0, 20), initial_value=0.001) self.add_parameter( name=f"volt_{ch_name}", label=f"DC source voltage on channel {ch_name}", unit='V', get_cmd=self.channels[ch_number].v, set_cmd=lambda val, ch_number=ch_number: self.set_smooth( {ch_number: val}), ) self.add_parameter('verbose', parameter_class=ManualParameter, vals=vals.Bool(), initial_value=False)
def __init__(self, name, **kw): super().__init__(name, **kw) # Instrument parameters self.add_parameter('ramsey', label='whether we are doing a ram-Z or echo-Z', parameter_class=ManualParameter, vals=vals.Bool()) self.add_parameter('sigma', unit='Phi_0', label='width of the Gaussian (mean is 0)', parameter_class=ManualParameter, vals=vals.Numbers()) self.add_parameter( 'detuning_ramsey', unit='Hz', label='how much the qubit is detuned from the sweetspot', parameter_class=ManualParameter, vals=vals.Numbers()) self.add_parameter('pulse_length', unit='s', label='TOTAL length for both ram-Z and echo-Z', parameter_class=ManualParameter, vals=vals.Numbers())
def __init__(self, parent: InstrumentChannel, name): super().__init__(parent, name) trigger = self.parent._task.triggers.start_trigger self.add_parameter(name='trig_type', label=' type', set_cmd=lambda x: setattr(trigger, "trig_type", x), get_cmd=lambda: getattr(trigger, "trig_type"), vals=vals.Enum(*constants.TriggerType)) self.add_parameter( name='dig_edge_src', label='start trigger digital edge source', set_cmd=lambda x: setattr(trigger, "dig_edge_src", x), get_cmd=lambda: getattr(trigger, "dig_edge_src"), vals=vals.Strings()) self.add_parameter( name='retriggerable', label='start trigger retrigerable', set_cmd=lambda x: setattr(trigger, "retriggerable", x), get_cmd=lambda: getattr(trigger, "retriggerable"), vals=vals.Bool())
unit='ms', get_cmd=None, set_cmd=None, initial_value=1000, vals=validators.Ints(min_value=0)) self.add_parameter(name='trigger_holdoff', label='Trigger Holdoff', docstring=f'If enabled Alazar will ' f'ignore any additional triggers ' f'while capturing a record. If disabled ' f'this will result in corrupt data. ' f'Support for this requires at least ' f'firmware version ' f'{self._trigger_holdoff_min_fw_version}', vals=validators.Bool(), get_cmd=self._get_trigger_holdoff, set_cmd=self._set_trigger_holdoff) model = self.get_idn()['model'] if model != 'ATS9373': raise Exception("The Alazar board kind is not 'ATS9373'," " found '" + str(model) + "' instead.") def _get_trigger_holdoff(self) -> bool: fwversion = self.get_idn()['firmware'] if LooseVersion(fwversion) < \ LooseVersion(self._trigger_holdoff_min_fw_version): return False
def __init__(self, name, **kw): logging.info(__name__ + ' : Initializing instrument') super().__init__(name, **kw) self.add_parameter('QWG', parameter_class=InstrumentParameter) self.add_parameter('F_kernel_instr', parameter_class=InstrumentParameter) self.add_parameter('F_amp', unit='frac', docstring=('Amplitude of flux pulse as fraction of ' 'the peak amplitude. Beware of factor 2' ' with Vpp in the QWG'), initial_value=0.5, parameter_class=ManualParameter) self.add_parameter('F_length', unit='s', parameter_class=ManualParameter, initial_value=200e-9) self.add_parameter('F_ch', label='Flux channel', vals=vals.Ints(), parameter_class=ManualParameter) self.add_parameter('F_delay', label='Flux pulse delay', unit='s', initial_value=0, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('F_compensation_delay', label='compens. pulse delay', unit='s', initial_value=4e-6, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('F_lambda_1', docstring='first lambda coef. for martinis pulse', label='Lambda_1', unit='', initial_value=0, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('F_lambda_2', docstring='second lambda coef. for martinis pulse', label='Lambda_2', unit='', initial_value=0, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('F_lambda_3', docstring='third lambda coef. for martinis pulse', label='Lambda_3', unit='', initial_value=0, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('F_theta_f', docstring='theta_f for martinis pulse', label='theta_f', unit='deg', initial_value=90, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('F_J2', docstring='coupling between 11-02', label='J2', unit='Hz', initial_value=10e6, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('F_f_interaction', label='interaction frequency', unit='Hz', initial_value=5e9, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('F_dac_flux_coef', docstring='conversion factor AWG voltage to flux', label='dac flux coef', unit='(V^-1)', initial_value=1.0, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('F_E_c', label='qubit E_c', unit='Hz', initial_value=250e6, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('F_f_01_max', label='sweet spot freq', unit='Hz', initial_value=6e9, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('F_asymmetry', label='qubit asymmetry', unit='Hz', initial_value=0.0, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('codeword_dict', docstring='Dict assigning codewords to pulses', label='codeword dict', unit='', initial_value={}, vals=vals.Anything(), parameter_class=ManualParameter) self.add_parameter('sampling_rate', docstring='Sampling rate of the QWG', label='sampling rate', unit='Hz', initial_value=1.0e9, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('Z_length', docstring=('Duration of single qubit Z pulse in' ' seconds'), label='Z length', unit='s', initial_value=10e-9, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('Z_amp', docstring=('Amplitude of the single qubit phase ' 'correction in CZ pulses.'), label='Z amplitude', unit='frac', initial_value=0.0, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('Z_amp_grover', docstring=('Amplitude of the single qubit phase ' 'correction for the second CZ pulse ' "used in Grover's algorithm."), label='Z amplitude 2', unit='frac', initial_value=0.0, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('max_waveform_length', unit='s', parameter_class=ManualParameter, initial_value=30e-6) self.add_parameter('codeword_channels', parameter_class=ManualParameter, docstring='Channels used for triggering specific ' 'codewords.', vals=vals.Lists(vals.Ints())) self.add_parameter('disable_CZ', parameter_class=ManualParameter, vals=vals.Bool(), initial_value=False) self.add_parameter('pulse_map', initial_value={'cz': 'adiabatic_Z', 'cz_grover': 'adiabatic_Z_grover', 'square': 'square'}, parameter_class=ManualParameter, vals=vals.Dict()) self.add_parameter('wave_dict_unit', get_cmd=self._get_wave_dict_unit, set_cmd=self._set_wave_dict_unit, docstring='Unit in which the waveforms are ' 'specified.\n' '"frac" means "fraction of the maximum QWG ' 'range".\n' '"V" means volts.', vals=vals.Enum('frac', 'V')) self._wave_dict_unit = 'frac' # Initial value for wave_dict_unit self.add_parameter('V_offset', unit='V', label='V offset', docstring='pulsed sweet spot offset', parameter_class=ManualParameter, initial_value=0, vals=vals.Numbers()) self.add_parameter('V_per_phi0', unit='V', label='V per phi_0', docstring='pulsed voltage required for one phi0 ' 'of flux', parameter_class=ManualParameter, initial_value=1, vals=vals.Numbers()) self.add_parameter('S_gauss_sigma', unit='s', label='gauss sigma', docstring='Width (sigma) of Gaussian shaped flux ' 'pulse.', parameter_class=ManualParameter, initial_value=40e-9, vals=vals.Numbers()) self.add_parameter('S_amp', unit='frac', label='S_amp', docstring='Amplitude of scoping flux pulse.', parameter_class=ManualParameter, initial_value=0.5, vals=vals.Numbers()) self._wave_dict = {}
def __init__(self, name, **kw): super().__init__(name, **kw) # Noise parameters self.add_parameter('T1_q0', unit='s', label='T1 fluxing qubit', parameter_class=ManualParameter, vals=vals.Numbers()) self.add_parameter('T1_q1', unit='s', label='T1 static qubit', parameter_class=ManualParameter, vals=vals.Numbers()) self.add_parameter('T2_q1', unit='s', label='T2 static qubit', parameter_class=ManualParameter, vals=vals.Numbers()) self.add_parameter( 'T2_q0_amplitude_dependent', unit='Hz, a.u., s', label= 'fitcoefficients giving T2echo_q0 as a function of frequency_q0: gc, amp, tau. Function is gc+gc*amp*np.exp(-x/tau)', parameter_class=ManualParameter, vals=vals.Arrays()) # , initial_value=np.array([-1,-1,-1]) # for flux noise simulations self.add_parameter( 'sigma_q0', unit='flux quanta', label= 'standard deviation of the Gaussian from which we sample the flux bias, q0', parameter_class=ManualParameter, vals=vals.Numbers()) self.add_parameter( 'sigma_q1', unit='flux quanta', label= 'standard deviation of the Gaussian from which we sample the flux bias, q1', parameter_class=ManualParameter, vals=vals.Numbers()) # Some system parameters self.add_parameter('w_bus', unit='Hz', label='omega of the bus resonator', parameter_class=ManualParameter, vals=vals.Numbers()) self.add_parameter('alpha_q1', unit='Hz', label='anharmonicity of the static qubit', parameter_class=ManualParameter, vals=vals.Numbers()) self.add_parameter( 'w_q1_sweetspot', label='NB: different from the operating point in general', parameter_class=ManualParameter, vals=vals.Numbers()) self.add_parameter( 'Z_rotations_length', unit='s', label= 'duration of the single qubit Z rotations at the end of the pulse', parameter_class=ManualParameter, vals=vals.Numbers()) # Control parameters for the simulations self.add_parameter( 'dressed_compsub', label= 'true if we use the definition of the comp subspace that uses the dressed 00,01,10,11 states', parameter_class=ManualParameter, vals=vals.Bool()) self.add_parameter('distortions', vals=vals.Bool(), parameter_class=ManualParameter) self.add_parameter( 'voltage_scaling_factor', unit='a.u.', label='scaling factor for the voltage for a CZ pulse', parameter_class=ManualParameter, vals=vals.Numbers()) self.add_parameter( 'n_sampling_gaussian_vec', label= 'array. each element is a number of samples from the gaussian distribution. Std to guarantee convergence is [11]. More are used only to verify convergence', parameter_class=ManualParameter, vals=vals.Arrays()) self.add_parameter('cluster', label='true if we want to use the cluster', parameter_class=ManualParameter, vals=vals.Bool()) self.add_parameter( 'look_for_minimum', label= 'changes cost function to optimize either research of minimum of avgatefid_pc or to get the heat map in general', parameter_class=ManualParameter, vals=vals.Bool()) self.add_parameter( 'T2_scaling', unit='a.u.', label='scaling factor for T2_q0_amplitude_dependent', parameter_class=ManualParameter, vals=vals.Numbers())
def __init__(self, parent, name, channel, min_val=-5, max_val=5): super().__init__(parent, name) # Validate slot and channel values self._CHANNEL_VAL.validate(channel) self._channel = channel self._slot = self._parent._slot # Calculate base address for querying channel parameters # Note that the following values can be found using these offsets # 0: Interrupt Period # 4: DAC High Limit # 5: DAC Low Limit # 6: Slope (double) # 8: DAC Value (double) self._base_addr = 1536 + (16 * 4) * self._slot + 16 * self._channel # Store min/max voltages assert (min_val < max_val) self.min_val = min_val self.max_val = max_val # Add channel parameters # Note we will use the older addresses to read the value from the dac rather than the newer # 'd' command for backwards compatibility self._volt_val = vals.Numbers(self.min_val, self.max_val) self.add_parameter("volt", get_cmd=partial(self._query_address, self._base_addr + 9, 1), get_parser=self._dac_code_to_v, set_cmd=self._set_dac, set_parser=self._dac_v_to_code, vals=self._volt_val, label="Voltage", unit="V") # The limit commands are used to sweep dac voltages. They are not safety features. self.add_parameter("lower_ramp_limit", get_cmd=partial(self._query_address, self._base_addr + 5), get_parser=self._dac_code_to_v, set_cmd="L{};", set_parser=self._dac_v_to_code, vals=self._volt_val, label="Lower_Ramp_Limit", unit="V") self.add_parameter("upper_ramp_limit", get_cmd=partial(self._query_address, self._base_addr + 4), get_parser=self._dac_code_to_v, set_cmd="U{};", set_parser=self._dac_v_to_code, vals=self._volt_val, label="Upper_Ramp_Limit", unit="V") self.add_parameter("update_period", get_cmd=partial(self._query_address, self._base_addr), get_parser=int, set_cmd="T{};", set_parser=int, vals=vals.Ints(50, 65535), label="Update_Period", unit="us") self.add_parameter("slope", get_cmd=partial(self._query_address, self._base_addr + 6, 2), get_parser=int, set_cmd="S{};", set_parser=int, vals=vals.Ints(-(2**32), 2**32), label="Ramp_Slope") # Manual parameters to control whether DAC channels should ramp to voltages or jump self._ramp_val = vals.Numbers(0, 10) self.add_parameter("enable_ramp", parameter_class=ManualParameter, initial_value=False, vals=vals.Bool()) self.add_parameter("ramp_rate", parameter_class=ManualParameter, initial_value=0.1, vals=self._ramp_val, unit="V/s") # Add ramp function to the list of functions self.add_function("ramp", call_cmd=self._ramp, args=(self._volt_val, self._ramp_val)) # If we have access to the VERSADAC (slot) EEPROM, we can set the inital # value of the channel. # NOTE: these values will be overwritten by a K3 calibration if self._parent._VERSA_EEPROM_available: _INITIAL_ADDR = [6, 8, 32774, 32776] self.add_parameter("initial_value", get_cmd=partial(self._query_address, _INITIAL_ADDR[self._channel], versa_eeprom=True), get_parser=self._dac_code_to_v, set_cmd=partial(self._write_address, _INITIAL_ADDR[self._channel], versa_eeprom=True), set_parser=self._dac_v_to_code, vals=vals.Numbers(self.min_val, self.max_val))
def __init__(self, name, **kw): super().__init__(name, **kw) # Noise parameters self.add_parameter( "T1_q0", unit="s", label="T1 fluxing qubit", docstring="T1 fluxing qubit", parameter_class=ManualParameter, vals=vals.Numbers(), initial_value=0, ) self.add_parameter( "T1_q1", unit="s", label="T1 static qubit", docstring="T1 static qubit", parameter_class=ManualParameter, vals=vals.Numbers(), initial_value=0, ) self.add_parameter( "T2_q1", unit="s", label="T2 static qubit", docstring="T2 static qubit", parameter_class=ManualParameter, vals=vals.Numbers(), initial_value=0, ) self.add_parameter( "T2_q0_amplitude_dependent", docstring= "fitcoefficients giving T2_q0 or Tphi_q0 as a function of inverse sensitivity (in units of w_q0/Phi_0): a, b. Function is ax+b", parameter_class=ManualParameter, vals=vals.Arrays(), initial_value=np.array([-1, -1]), ) # for flux noise simulations self.add_parameter( "sigma_q0", unit="flux quanta", docstring= "standard deviation of the Gaussian from which we sample the flux bias, q0", parameter_class=ManualParameter, vals=vals.Numbers(), initial_value=0, ) self.add_parameter( "sigma_q1", unit="flux quanta", docstring= "standard deviation of the Gaussian from which we sample the flux bias, q1", parameter_class=ManualParameter, vals=vals.Numbers(), initial_value=0, ) self.add_parameter( "w_q1_sweetspot", docstring="NB: different from the operating point in general", parameter_class=ManualParameter, vals=vals.Numbers(), ) self.add_parameter( "w_q0_sweetspot", docstring="NB: different from the operating point in general", parameter_class=ManualParameter, vals=vals.Numbers(), ) self.add_parameter( "Z_rotations_length", unit="s", docstring= "duration of the single qubit Z rotations at the end of the pulse", parameter_class=ManualParameter, vals=vals.Numbers(), initial_value=0, ) self.add_parameter( "total_idle_time", unit="s", docstring="duration of the idle time", parameter_class=ManualParameter, vals=vals.Numbers(), initial_value=0, ) # Control parameters for the simulations self.add_parameter( "dressed_compsub", docstring= "true if we use the definition of the comp subspace that uses the dressed 00,01,10,11 states", parameter_class=ManualParameter, vals=vals.Bool(), initial_value=True, ) self.add_parameter( "distortions", parameter_class=ManualParameter, vals=vals.Bool(), initial_value=False, ) self.add_parameter( "voltage_scaling_factor", unit="a.u.", docstring="scaling factor for the voltage for a CZ pulse", parameter_class=ManualParameter, vals=vals.Numbers(), initial_value=1, ) self.add_parameter( "n_sampling_gaussian_vec", docstring= "array. each element is a number of samples from the gaussian distribution. Std to guarantee convergence is [11]. More are used only to verify convergence", parameter_class=ManualParameter, vals=vals.Arrays(), initial_value=np.array([11]), ) self.add_parameter( "cluster", docstring="true if we want to use the cluster", parameter_class=ManualParameter, vals=vals.Bool(), initial_value=False, ) self.add_parameter( "look_for_minimum", docstring= "changes cost function to optimize either research of minimum of avgatefid_pc or to get the heat map in general", parameter_class=ManualParameter, vals=vals.Bool(), initial_value=False, ) self.add_parameter( "T2_scaling", unit="a.u.", docstring="scaling factor for T2_q0_amplitude_dependent", parameter_class=ManualParameter, vals=vals.Numbers(), initial_value=1, ) self.add_parameter( "waiting_at_sweetspot", unit="s", docstring= "time spent at sweetspot during the two halves of a netzero pulse", parameter_class=ManualParameter, vals=vals.Numbers(min_value=0), initial_value=0, ) self.add_parameter( "which_gate", docstring= "Direction of the CZ gate. E.g. 'NE'. Used to extract parameters from the fluxlutman ", parameter_class=ManualParameter, vals=vals.Strings(), initial_value="NE", ) self.add_parameter( "simstep_div", docstring= "Division of the simulation time step. 4 is a good one, corresponding to a time step of 0.1 ns. For smaller values landscapes can deviate significantly from experiment.", parameter_class=ManualParameter, vals=vals.Numbers(min_value=1), initial_value=4, ) self.add_parameter( "gates_num", docstring="Chain the same gate gates_num times.", parameter_class=ManualParameter, # It should be an integer but the measurement control cast to float when setting sweep points vals=vals.Numbers(min_value=1), initial_value=1, ) self.add_parameter( "gates_interval", docstring= "Time interval that separates the gates if gates_num > 1.", parameter_class=ManualParameter, unit='s', vals=vals.Numbers(min_value=0), initial_value=0, ) self.add_parameter( "cost_func", docstring= "Used to calculate the cost function based on the quantities of interest (qoi). Signature: cost_func(qoi). NB: qoi's that represent percentages will be in [0, 1] range. Inspect 'pycqed.simulations.cz_superoperator_simulation_new_functions.simulate_quantities_of_interest_superoperator_new??' in notebook for available qoi's.", parameter_class=ManualParameter, unit='a.u.', vals=vals.Callable(), initial_value=None, ) self.add_parameter( "cost_func_str", docstring= "Not loaded automatically. Convenience parameter to store the cost function string and use `exec('sim_control_CZ.cost_func(' + sim_control_CZ.cost_func_str() + ')')` to load it.", parameter_class=ManualParameter, vals=vals.Strings(), initial_value= "lambda qoi: np.log10((1 - qoi['avgatefid_compsubspace_pc']) * (1 - 0.5) + qoi['L1'] * 0.5)", ) self.add_parameter( "double_cz_pi_pulses", docstring= "If set to 'no_pi_pulses' or 'with_pi_pulses' will simulate two sequential CZs with or without Pi pulses simulated as an ideal superoperator multiplication.", parameter_class=ManualParameter, vals=vals.Strings(), initial_value="", # Use empty string to evaluate to false ) # for ramsey/Rabi simulations self.add_parameter( "detuning", unit="Hz", docstring="detuning of w_q0 from its sweet spot value", parameter_class=ManualParameter, vals=vals.Numbers(), initial_value=0, ) self.add_parameter( "initial_state", docstring="determines initial state for ramsey_simulations_new", parameter_class=ManualParameter, vals=vals.Strings(), initial_value="changeme", ) # for spectral tomo self.add_parameter( "repetitions", docstring="Repetitions of CZ gate, used for spectral tomo", parameter_class=ManualParameter, vals=vals.Numbers(), initial_value=1, ) self.add_parameter( "time_series", docstring="", parameter_class=ManualParameter, vals=vals.Bool(), initial_value=False, ) self.add_parameter( "overrotation_sims", docstring= "instead of constant shift in flux, we use constant rotations around some axis", parameter_class=ManualParameter, vals=vals.Bool(), initial_value=False, ) self.add_parameter( "axis_overrotation", docstring="", parameter_class=ManualParameter, vals=vals.Arrays(), initial_value=np.array([1, 0, 0]), )
def __init__(self, name, address, num_chans=48, update_currents=True, **kwargs): """ Instantiates the instrument. Args: name (str): The instrument name used by qcodes address (str): The VISA name of the resource num_chans (int): Number of channels to assign. Default: 48 update_currents (bool): Whether to query all channels for their current current value on startup. Default: True. Returns: QDac object """ super().__init__(name, address, **kwargs) self._output_n_lines = 50 handle = self.visa_handle self._get_status_performed = False # This is the baud rate on power-up. It can be changed later but # you must start out with this value. handle.baud_rate = 480600 handle.parity = visa.constants.Parity(0) handle.data_bits = 8 self.set_terminator('\n') # TODO: do we want a method for write termination too? handle.write_termination = '\n' # TODO: do we need a query delay for robust operation? self._write_response = '' if self._get_firmware_version() < 0.170202: raise RuntimeError(''' Obsolete QDAC Software version detected. QCoDeS only supports version 0.170202 or newer. Contact [email protected] for an update. ''') self.num_chans = num_chans # Assigned slopes. Entries will eventually be [chan, slope] self._slopes = [] # Function generators (used in _set_voltage) self._fgs = set(range(1, 9)) self._assigned_fgs = {} # {chan: fg} # Sync channels self._syncoutputs = [] # Entries: [chan, syncchannel] self.chan_range = range(1, 1 + self.num_chans) self.channel_validator = vals.Ints(1, self.num_chans) channels = ChannelList(self, "Channels", QDacChannel, snapshotable=False, multichan_paramclass=QDacMultiChannelParameter) for i in self.chan_range: channel = QDacChannel(self, f'chan{i:02}', i) channels.append(channel) # Should raise valueerror if name is invalid (silently fails now) self.add_submodule(f'ch{i:02}', channel) channels.lock() self.add_submodule('channels', channels) for board in range(6): for sensor in range(3): label = f'Board {board}, Temperature {sensor}' self.add_parameter(name=f'temp{board}_{sensor}', label=label, unit='C', get_cmd=f'tem {board} {sensor}', get_parser=self._num_verbose) self.add_parameter(name='cal', set_cmd='cal {}', vals=self.channel_validator) # TO-DO: maybe it's too dangerous to have this settable. # And perhaps ON is a better verbose mode default? self.add_parameter(name='verbose', set_cmd='ver {}', val_mapping={ True: 1, False: 0 }) self.add_parameter(name='fast_voltage_set', label='fast voltage set', get_cmd=None, set_cmd=None, vals=vals.Bool(), initial_value=False, docstring=""""Deprecated with no functionality""") # Initialise the instrument, all channels DC (unbind func. generators) for chan in self.chan_range: # Note: this call does NOT change the voltage on the channel self.write(f'wav {chan} 0 1 0') self.verbose.set(False) self.connect_message() log.info('[*] Querying all channels for voltages and currents...') self._update_cache(readcurrents=update_currents) self._update_currents = update_currents log.info('[+] Done')
def __init__(self, name, **kw): super().__init__(name, **kw) self.msmt_suffix = '_' + self.name # Add instrument reference parameters self.add_parameter('instr_pump', parameter_class=InstrumentRefParameter) self.add_parameter('instr_signal', parameter_class=InstrumentRefParameter) self.add_parameter('instr_lo', parameter_class=InstrumentRefParameter) self.add_parameter('instr_acq', parameter_class=InstrumentRefParameter) self.add_parameter('instr_mc', parameter_class=InstrumentRefParameter) self.add_parameter('instr_pulsar', parameter_class=InstrumentRefParameter) # Add pump control parameters self.add_parameter( 'pump_freq', label='Pump frequency', unit='Hz', get_cmd=( lambda self=self: self.instr_pump.get_instr().frequency()), set_cmd=(lambda val, self=self: self.instr_pump.get_instr(). frequency(val))) self.add_parameter( 'pump_power', label='Pump power', unit='dBm', get_cmd=(lambda self=self: self.instr_pump.get_instr().power()), set_cmd=( lambda val, self=self: self.instr_pump.get_instr().power(val))) self.add_parameter( 'pump_status', label='Pump status', get_cmd=(lambda self=self: self.instr_pump.get_instr().status()), set_cmd=(lambda val, self=self: self.instr_pump.get_instr().status( val))) # Add signal control parameters def set_freq(val, self=self): if self.pulsed(): self.instr_signal.get_instr().frequency(val - self.acq_mod_freq()) if self.instr_lo() != self.instr_signal(): self.instr_lo.get_instr().frequency(val - self.acq_mod_freq()) else: self.instr_signal.get_instr().frequency(val) self.instr_lo.get_instr().frequency(val - self.acq_mod_freq()) # Add signal control parameters def get_freq(self=self): if self.pulsed(): return self.instr_signal.get_instr().frequency() + \ self.acq_mod_freq() else: return self.instr_signal.get_instr().frequency() self.add_parameter('signal_freq', label='Signal frequency', unit='Hz', get_cmd=get_freq, set_cmd=set_freq) self.add_parameter( 'signal_power', label='Signal power', unit='dBm', get_cmd=(lambda self=self: self.instr_signal.get_instr().power()), set_cmd=(lambda val, self=self: self.instr_signal.get_instr(). power(val))) self.add_parameter( 'signal_status', label='Signal status', get_cmd=(lambda self=self: self.instr_signal.get_instr().status()), set_cmd=(lambda val, self=self: self.instr_signal.get_instr(). status(val))) # Add acquisition parameters self.add_parameter('acq_length', parameter_class=ManualParameter, vals=vals.Numbers(0, 2.275e-6), unit='s', initial_value=2.275e-6) self.add_parameter('acq_mod_freq', parameter_class=ManualParameter, vals=vals.Numbers(-900e6, 900e6), unit='Hz', label='Intermediate frequency', initial_value=225e6) self.add_parameter('acq_averages', parameter_class=ManualParameter, vals=vals.Ints(0), initial_value=2**10) self.add_parameter('acq_weights_type', parameter_class=ManualParameter, vals=vals.Enum('DSB', 'SSB'), initial_value='SSB') # add pulse parameters self.add_parameter('pulsed', parameter_class=ManualParameter, vals=vals.Bool(), initial_value=True) self.add_parameter('pulse_length', parameter_class=ManualParameter, vals=vals.Numbers(0, 2.5e-6), unit='s', initial_value=2.5e-6) self.add_parameter('pulse_amplitude', parameter_class=ManualParameter, vals=vals.Numbers(0, 1.0), unit='V', initial_value=0.01)
def __init__(self, name, **kw): super().__init__(name, **kw) self.add_parameter('channel', initial_value=1, vals=vals.Ints(), parameter_class=ManualParameter) self.add_parameter( 'kernel_list', initial_value=[], vals=vals.Lists(vals.Strings()), parameter_class=ConfigParameter, docstring='List of filenames of external kernels to be loaded') self.add_parameter('kernel_dir', initial_value='kernels/', vals=vals.Strings(), parameter_class=ManualParameter, docstring='Path for loading external kernels,' + 'such as room temperature correction kernels.') self.add_parameter('config_changed', vals=vals.Bool(), get_cmd=self._get_config_changed) self.add_parameter( 'kernel', vals=vals.Arrays(), get_cmd=self._get_kernel, docstring=('Returns the predistortion kernel. \n' + 'Recalculates if the parameters changed,\n' + 'otherwise returns a precalculated kernel.\n' + 'Kernel is based on parameters in kernel object \n' + 'and files specified in the kernel list.')) self.add_parameter('skineffect_alpha', unit='', parameter_class=ConfigParameter, initial_value=0, vals=vals.Numbers()) self.add_parameter('skineffect_length', unit='s', parameter_class=ConfigParameter, initial_value=600e-9, vals=vals.Numbers()) self.add_parameter('decay_amp_1', unit='', initial_value=0, parameter_class=ConfigParameter, vals=vals.Numbers()) self.add_parameter('decay_tau_1', unit='s', initial_value=1e-9, parameter_class=ConfigParameter, vals=vals.Numbers()) self.add_parameter('decay_length_1', unit='s', initial_value=100e-9, parameter_class=ConfigParameter, vals=vals.Numbers()) self.add_parameter('decay_amp_2', unit='', initial_value=0, parameter_class=ConfigParameter, vals=vals.Numbers()) self.add_parameter('decay_tau_2', unit='s', initial_value=1e-9, parameter_class=ConfigParameter, vals=vals.Numbers()) self.add_parameter('decay_length_2', unit='s', initial_value=100e-9, parameter_class=ConfigParameter, vals=vals.Numbers()) self.add_parameter('bounce_amp_1', unit='', initial_value=0, parameter_class=ConfigParameter, vals=vals.Numbers()) self.add_parameter('bounce_tau_1', unit='s', initial_value=0, parameter_class=ConfigParameter, vals=vals.Numbers()) self.add_parameter('bounce_length_1', unit='s', initial_value=1e-9, parameter_class=ConfigParameter, vals=vals.Numbers()) self.add_parameter('bounce_amp_2', unit='', initial_value=0, parameter_class=ConfigParameter, vals=vals.Numbers()) self.add_parameter('bounce_tau_2', unit='s', initial_value=0, parameter_class=ConfigParameter, vals=vals.Numbers()) self.add_parameter('bounce_length_2', unit='s', initial_value=1e-9, parameter_class=ConfigParameter, vals=vals.Numbers()) self.add_parameter('poly_a', unit='', initial_value=0, parameter_class=ConfigParameter, vals=vals.Numbers()) self.add_parameter('poly_b', unit='', initial_value=0, parameter_class=ConfigParameter, vals=vals.Numbers()) self.add_parameter('poly_c', unit='', initial_value=1, parameter_class=ConfigParameter, vals=vals.Numbers()) self.add_parameter('poly_length', unit='s', initial_value=600e-9, parameter_class=ConfigParameter, vals=vals.Numbers()) self.add_parameter('corrections_length', unit='s', parameter_class=ConfigParameter, initial_value=10e-6, vals=vals.Numbers()) self.add_parameter('sampling_rate', parameter_class=ManualParameter, initial_value=1e9, vals=vals.Numbers())
def _add_waveform_parameters(self): """ Adds the parameters required to generate the standard waveforms The following prefixes are used for waveform parameters sq cz czd mcz custom """ self.add_parameter('sq_amp', initial_value=.5, # units is part of the total range of AWG8 label='Square pulse amplitude', unit='dac value', vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('sq_length', unit='s', label='Square pulse length', initial_value=40e-9, vals=vals.Numbers(0, 100e-6), parameter_class=ManualParameter) self.add_parameter('cz_length', vals=vals.Numbers(), unit='s', initial_value=35e-9, parameter_class=ManualParameter) self.add_parameter('cz_lambda_2', vals=vals.Numbers(), initial_value=0, parameter_class=ManualParameter) self.add_parameter('cz_lambda_3', vals=vals.Numbers(), initial_value=0, parameter_class=ManualParameter) self.add_parameter('cz_theta_f', vals=vals.Numbers(), unit='deg', initial_value=80, parameter_class=ManualParameter) self.add_parameter('czd_length_ratio', vals=vals.Numbers(0, 1), initial_value=0.5, parameter_class=ManualParameter) self.add_parameter( 'czd_lambda_2', docstring='lambda_2 parameter of the negative part of the cz pulse' ' if set to np.nan will default to the value of the main parameter', vals=vals.MultiType(vals.Numbers(), NP_NANs()), initial_value=np.nan, parameter_class=ManualParameter) self.add_parameter( 'czd_lambda_3', docstring='lambda_3 parameter of the negative part of the cz pulse' ' if set to np.nan will default to the value of the main parameter', vals=vals.MultiType(vals.Numbers(), NP_NANs()), initial_value=np.nan, parameter_class=ManualParameter) self.add_parameter( 'czd_theta_f', docstring='theta_f parameter of the negative part of the cz pulse' ' if set to np.nan will default to the value of the main parameter', vals=vals.MultiType(vals.Numbers(), NP_NANs()), unit='deg', initial_value=np.nan, parameter_class=ManualParameter) self.add_parameter('cz_freq_01_max', vals=vals.Numbers(), # initial value is chosen to not raise errors initial_value=6e9, unit='Hz', parameter_class=ManualParameter) self.add_parameter('cz_J2', vals=vals.Numbers(), unit='Hz', # initial value is chosen to not raise errors initial_value=15e6, parameter_class=ManualParameter) self.add_parameter('cz_freq_interaction', vals=vals.Numbers(), # initial value is chosen to not raise errors initial_value=5e9, unit='Hz', parameter_class=ManualParameter) self.add_parameter('cz_phase_corr_length', unit='s', initial_value=5e-9, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('cz_phase_corr_amp', unit='dac value', initial_value=0, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('czd_amp_ratio', docstring='Amplitude ratio for double sided CZ gate', initial_value=1, vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('czd_amp_offset', docstring='used to add an offset to the negative ' ' pulse that is used in the net-zero cz gate', initial_value=0, unit='dac value', vals=vals.Numbers(), parameter_class=ManualParameter) self.add_parameter('czd_double_sided', initial_value=False, vals=vals.Bool(), parameter_class=ManualParameter) self.add_parameter('mcz_nr_of_repeated_gates', initial_value=1, vals=vals.PermissiveInts(1, 40), parameter_class=ManualParameter) self.add_parameter('mcz_gate_separation', unit='s', label='Gate separation', initial_value=0, docstring=('Separtion between the start of CZ gates' 'in the "multi_cz" gate'), parameter_class=ManualParameter, vals=vals.Numbers(min_value=0)) self.add_parameter( 'custom_wf', initial_value=np.array([]), label='Custom waveform', docstring=('Specifies a custom waveform, note that ' '`custom_wf_length` is used to cut of the waveform if' 'it is set.'), parameter_class=ManualParameter, vals=vals.Arrays()) self.add_parameter( 'custom_wf_length', unit='s', label='Custom waveform length', initial_value=np.inf, docstring=('Used to determine at what sample the custom waveform ' 'is forced to zero. This is used to facilitate easy ' 'cryoscope measurements of custom waveforms.'), parameter_class=ManualParameter, vals=vals.Numbers(min_value=0))