def __init__(self, name, serial_number, dll_path=None, **kwargs): super().__init__(name, **kwargs) self.serial_number = serial_number self.dll = ct.CDLL(dll_path or self.dll_path) self.initDevice() self.add_parameter('frequency', label='Frequency', unit='Hz', get_cmd=self.get_frequency, set_cmd=self.set_frequency, vals=vals.Numbers()) self.add_parameter('power', label='Power', unit='dBm', get_cmd=self.get_power, set_cmd=self.set_power, vals=vals.Numbers()) self.add_parameter('output', label='output', get_cmd=self.get_output_state, set_cmd=self.set_output_state, vals=vals.Bool())
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.gpu_thread = get_cl_thread(self.parent.gpu_queue) self.add_parameter('enabled', ManualParameter, vals=vals.Bool(), default_value=False) self.enabled.set(False)
def __init__(self, name: str, address: str, channel_map: dict, reset_currents: bool = False): """ Create an instance of the SPI S4g FluxCurrent instrument. Arguments: name: address: used to connect to the SPI rack e.g., "COM10" channel map: {"parameter_name": (module_nr, dac_nr)} reset_currents: if True, ramps all currents to zero upon connecting. For an example of how to use this instrument see examples/SPI_rack_examples/SPI_rack_example.py """ t0 = time.time() super().__init__(name) self.channel_map = channel_map self.spi_rack = SPI_rack(address, 9600, timeout=1) self.spi_rack.unlock() self.add_parameter( 'cfg_ramp_rate', unit='A/s', initial_value=0.1e-3, # 0.1 mA/s docstring='Limits the rate at which currents can be changed.', vals=validators.Numbers(min_value=0, max_value=np.infty), parameter_class=ManualParameter) self.add_parameter( 'cfg_verbose', initial_value=True, vals=validators.Bool(), docstring='If True, prints progress while ramping values.', parameter_class=ManualParameter) # Determine the set of modules required from the channel map module_ids = set([ch_map[0] for ch_map in channel_map.values()]) # instantiate the controllers for the individual modules self.current_sources = {} for mod_id in module_ids: # N.B. reset currents has a slow ramp build in. self.current_sources[mod_id] = S4g_module( self.spi_rack, module=mod_id, reset_currents=reset_currents) for parname, (mod_id, dac) in self.channel_map.items(): self.add_parameter(parname, get_cmd=partial(self._get_current, parname), set_cmd=partial(self._set_current, parname), unit="A", vals=validators.Numbers(min_value=-50e-3, max_value=50e-3)) self.connect_message(begin_time=t0)
def __init__( self, parent: InstrumentBase, dac_instrument: DACInterface, channel_id: int, layout_id: int, name: str = "nanotune_gate", label: str = "nanotune gate", line_type: str = "dc_current", safety_range: Tuple[float, float] = (-3, 0), use_ramp: bool = True, ramp_rate: float = 0.1, max_jump: float = 0.05, delay: float = 0.001, fast_readout_source: Optional[InstrumentChannel] = None, **kwargs, ) -> None: """ Args: dac_instrument (Optional[Parameter]): line_type (Optional[str]): min_v (Optional[float]): max_v (Optional[float]): use_ramp (Optional[bool]): ramp_rate (Optional[float]): max_jump (Optional[float]): delay (Optional[float]): Delay in between setting and measuring another parameter """ assert issubclass(dac_instrument.__class__, DACInterface) super().__init__(parent, name) self._dac_instrument = dac_instrument self._dac_channel = self._dac_instrument.nt_channels[channel_id] super().add_parameter( name="channel_id", label="instrument channel id", set_cmd=None, get_cmd=None, initial_value=channel_id, vals=vals.Ints(0), ) super().add_parameter( name="dc_voltage", label=f"{label} dc voltage", set_cmd=self.set_dc_voltage, get_cmd=self._dac_channel.get_dc_voltage, vals=vals.Numbers(*safety_range), ) self.has_ramp = self._dac_channel.supports_hardware_ramp super().add_parameter( name="label", label="gate label", set_cmd=self._dac_channel.set_label, get_cmd=self._dac_channel.get_label, initial_value=label, vals=vals.Strings(), ) qc_safety_range = (safety_range[0] - 0.01, safety_range[1] + 0.01) super().add_parameter( name="safety_range", label=f"{label} DC voltage safety range", set_cmd=self.set_safety_range, get_cmd=self.get_safety_range, initial_value=list(safety_range), vals=vals.Lists(), ) super().add_parameter( name="inter_delay", label=f"{label} inter delay", set_cmd=self._dac_channel.set_inter_delay, get_cmd=self._dac_channel.get_inter_delay, initial_value=delay, vals=vals.Numbers(), ) super().add_parameter( name="post_delay", label=label + " post delay", set_cmd=self._dac_channel.set_post_delay, get_cmd=self._dac_channel.get_post_delay, initial_value=delay, vals=vals.Numbers(), ) super().add_parameter( name="max_jump", label=f"{label} maximum voltage jump", set_cmd=self.set_max_jump, get_cmd=self.get_max_jump, initial_value=max_jump, vals=vals.Numbers(), ) super().add_parameter( name="step", label=f"{label} voltage step", set_cmd=self._dac_channel.set_step, get_cmd=self._dac_channel.get_step, initial_value=max_jump, vals=vals.Numbers(), ) super().add_parameter( name="ramp_rate", label=f"{label} ramp rate", set_cmd=self._dac_channel.set_ramp_rate, get_cmd=self._dac_channel.get_ramp_rate, initial_value=ramp_rate, vals=vals.Numbers(), ) super().add_parameter( name="use_ramp", label=f"{label} ramp setting", set_cmd=self.set_ramp, get_cmd=self.get_ramp, initial_value=use_ramp, vals=vals.Bool(), ) super().add_parameter( name="relay_state", label=f"{label} DAC channel relay state", set_cmd=self._dac_channel.set_relay_state, get_cmd=self._dac_channel.get_relay_state, initial_value=self._dac_channel.get_relay_state(), vals=vals.Strings(), ) super().add_parameter( name="layout_id", label=f"{label} device layout id", set_cmd=None, get_cmd=None, initial_value=layout_id, vals=vals.Ints(0), ) super().add_parameter( name="current_valid_range", label=f"{label} current valid range", set_cmd=self.set_current_valid_range, get_cmd=self.get_current_valid_range, initial_value=[], vals=vals.Lists(), ) super().add_parameter( name="transition_voltage", label=f"{label} transition voltage", set_cmd=self.set_transition_voltage, get_cmd=self.compute_transition_voltage, initial_value=0, vals=vals.Numbers(), ) super().add_parameter( name="amplitude", label=f"{label} sawtooth amplitude", set_cmd=self._dac_channel.set_amplitude, get_cmd=self._dac_channel.get_amplitude, initial_value=0, vals=vals.Numbers(-0.5, 0.5), ) super().add_parameter( name="offset", label=f"{label} sawtooth offset", set_cmd=self._set_offset, get_cmd=self._dac_channel.get_offset, initial_value=0, vals=vals.Numbers(*qc_safety_range), ) super().add_parameter( name="frequency", label=f"{label} sawtooth frequency", set_cmd=self._dac_channel.set_frequency, get_cmd=self._dac_channel.get_frequency, initial_value=0, vals=vals.Numbers(), )
def add_parameters(self): ####################################################################### # QWG specific ####################################################################### for i in range(self.device_descriptor.numChannels // 2): ch_pair = i * 2 + 1 sfreq_cmd = 'qutech:output{}:frequency'.format(ch_pair) sph_cmd = 'qutech:output{}:phase'.format(ch_pair) # NB: sideband frequency has a resolution of ~0.23 Hz: self.add_parameter('ch_pair{}_sideband_frequency'.format(ch_pair), parameter_class=HandshakeParameter, unit='Hz', label=('Sideband frequency channel ' + 'pair {} (Hz)'.format(i)), get_cmd=sfreq_cmd + '?', set_cmd=sfreq_cmd + ' {}', vals=vals.Numbers(-300e6, 300e6), get_parser=float) self.add_parameter('ch_pair{}_sideband_phase'.format(ch_pair), parameter_class=HandshakeParameter, unit='deg', label=('Sideband phase channel' + ' pair {} (deg)'.format(i)), get_cmd=sph_cmd + '?', set_cmd=sph_cmd + ' {}', vals=vals.Numbers(-180, 360), get_parser=float) self.add_parameter( 'ch_pair{}_transform_matrix'.format(ch_pair), parameter_class=HandshakeParameter, label=('Transformation matrix channel' + 'pair {}'.format(i)), get_cmd=self._gen_ch_get_func(self._getMatrix, ch_pair), set_cmd=self._gen_ch_set_func(self._setMatrix, ch_pair), # NB range is not a hardware limit vals=vals.Arrays(-2, 2, shape=(2, 2))) for i in range(1, self.device_descriptor.numTriggers + 1): triglev_cmd = 'qutech:trigger{}:level'.format(i) # individual trigger level per trigger input: self.add_parameter('tr{}_trigger_level'.format(i), unit='V', label='Trigger level channel {} (V)'.format(i), get_cmd=triglev_cmd + '?', set_cmd=triglev_cmd + ' {}', vals=self.device_descriptor.mvals_trigger_level, get_parser=float) self.add_parameter('run_mode', get_cmd='AWGC:RMO?', set_cmd='AWGC:RMO ' + '{}', vals=vals.Enum('NONE', 'CONt', 'SEQ', 'CODeword')) # NB: setting mode "CON" (valid SCPI abbreviation) reads back as "CONt" # Channel parameters # for ch in range(1, self.device_descriptor.numChannels + 1): amp_cmd = 'SOUR{}:VOLT:LEV:IMM:AMPL'.format(ch) offset_cmd = 'SOUR{}:VOLT:LEV:IMM:OFFS'.format(ch) state_cmd = 'OUTPUT{}:STATE'.format(ch) waveform_cmd = 'SOUR{}:WAV'.format(ch) output_voltage_cmd = 'QUTEch:OUTPut{}:Voltage'.format(ch) dac_temperature_cmd = 'STATus:DAC{}:TEMperature'.format(ch) gain_adjust_cmd = 'DAC{}:GAIn:DRIFt:ADJust'.format(ch) dac_digital_value_cmd = 'DAC{}:DIGitalvalue'.format(ch) # Set channel first to ensure sensible sorting of pars # Compatibility: 5014, QWG self.add_parameter('ch{}_state'.format(ch), label='Status channel {}'.format(ch), get_cmd=state_cmd + '?', set_cmd=state_cmd + ' {}', val_mapping={ True: '1', False: '0' }, vals=vals.Bool()) self.add_parameter( 'ch{}_amp'.format(ch), parameter_class=HandshakeParameter, label='Channel {} Amplitude '.format(ch), unit='Vpp', docstring='Amplitude channel {} (Vpp into 50 Ohm)'.format(ch), get_cmd=amp_cmd + '?', set_cmd=amp_cmd + ' {:.6f}', vals=vals.Numbers(-1.6, 1.6), get_parser=float) self.add_parameter( 'ch{}_offset'.format(ch), # parameter_class=HandshakeParameter, label='Offset channel {}'.format(ch), unit='V', get_cmd=offset_cmd + '?', set_cmd=offset_cmd + ' {:.3f}', vals=vals.Numbers(-.25, .25), get_parser=float) self.add_parameter('ch{}_default_waveform'.format(ch), get_cmd=waveform_cmd + '?', set_cmd=waveform_cmd + ' "{}"', vals=vals.Strings()) self.add_parameter('status_dac{}_temperature'.format(ch), unit='C', label=('DAC {} temperature'.format(ch)), get_cmd=dac_temperature_cmd + '?', get_parser=float, docstring='Reads the temperature of a DAC.\n' \ +'Temperature measurement interval is 10 seconds\n' \ +'Return:\n float with temperature in Celsius') self.add_parameter('output{}_voltage'.format(ch), unit='V', label=('Channel {} voltage output').format(ch), get_cmd=output_voltage_cmd + '?', get_parser=float, docstring='Reads the output voltage of a channel.\n' \ +'Notes:\n Measurement interval is 10 seconds.\n' \ +' The output voltage will only be read if the channel is disabled:\n' \ +' E.g.: qwg.chX_state(False)\n' \ +' If the channel is enabled it will return an low value: >0.1\n' \ +'Return:\n float in voltage') self.add_parameter('dac{}_gain_drift_adjust'.format(ch), unit='', label=('DAC {}, gain drift adjust').format(ch), get_cmd=gain_adjust_cmd + '?', set_cmd=gain_adjust_cmd + ' {}', vals=vals.Ints(0, 4095), get_parser=int, docstring='Gain drift adjust setting of the DAC of a channel.\n' \ +'Used for calibration of the DAC. Do not use to set the gain of a channel!\n' \ +'Notes:\n The gain setting is from 0 to 4095 \n' \ +' Where 0 is 0 V and 4095 is 3.3V \n' \ +'Get Return:\n Setting of the gain in interger (0 - 4095)\n'\ +'Set parameter:\n Integer: Gain of the DAC in , min: 0, max: 4095') self.add_parameter('_dac{}_digital_value'.format(ch), unit='', label=('DAC {}, set digital value').format(ch), set_cmd=dac_digital_value_cmd + ' {}', vals=vals.Ints(0, 4095), docstring='FOR DEVELOPMENT ONLY: Set a digital value directly into the DAC\n' \ +'Used for testing the DACs.\n' \ +'Notes:\n\tThis command will also set the ' \ +'\tinternal correction matrix (Phase and amplitude) of the channel pair to [0,0,0,0], ' \ +'disabling any influence from the wave memory.' \ +'This will also stop the wave the other channel of the pair!\n\n' \ +'Set parameter:\n\tInteger: Value to write to the DAC, min: 0, max: 4095\n' \ +'\tWhere 0 is minimal DAC scale and 4095 is maximal DAC scale \n') self.add_parameter('status_frontIO_temperature', unit='C', label=('FrontIO temperature'), get_cmd='STATus:FrontIO:TEMperature?', get_parser=float, docstring='Reads the temperature of the frontIO.\n' \ +'Temperature measurement interval is 10 seconds\n' \ +'Return:\n float with temperature in Celsius') self.add_parameter('status_fpga_temperature', unit='C', label=('FPGA temperature'), get_cmd='STATus:FPGA:TEMperature?', get_parser=int, docstring='Reads the temperature of the FPGA.\n' \ +'Temperature measurement interval is 10 seconds\n' \ +'Return:\n float with temperature in Celsius') for cw in range(self.device_descriptor.numCodewords): for j in range(self.device_descriptor.numChannels): ch = j + 1 # Codeword 0 corresponds to bitcode 0 cw_cmd = 'sequence:element{:d}:waveform{:d}'.format(cw, ch) self.add_parameter('codeword_{}_ch{}_waveform'.format(cw, ch), get_cmd=cw_cmd + '?', set_cmd=cw_cmd + ' "{:s}"', vals=vals.Strings()) # Waveform parameters self.add_parameter('WlistSize', label='Waveform list size', unit='#', get_cmd='wlist:size?', get_parser=int) self.add_parameter('Wlist', label='Waveform list', get_cmd=self._getWlist) self.add_parameter('get_system_status', unit='JSON', label=('System status'), get_cmd='SYSTem:STAtus?', vals=vals.Strings(), get_parser=self.JSON_parser, docstring='Reads the current system status. E.q. channel ' \ +'status: on or off, overflow, underdrive.\n' \ +'Return:\n JSON object with system status') # Trigger parameters doc_trgs_log_inp = 'Reads the current input values on the all the trigger ' \ +'inputs.\nReturn:\n uint32 where trigger 1 (T1) ' \ +'is on the Least significant bit (LSB), T2 on the second ' \ +'bit after LSB, etc.\n\n For example, if only T3 is ' \ +'connected to a high signal, the return value is: ' \ +'4 (0b0000100)\n\n Note: To convert the return value ' \ +'to a readable ' \ +'binary output use: `print(\"{0:#010b}\".format(qwg.' \ +'triggers_logic_input()))`' self.add_parameter( 'triggers_logic_input', label='Read triggers input value', get_cmd='QUTEch:TRIGgers:LOGIcinput?', get_parser=np.uint32, # Did not convert to readable # string because a uint32 is more # usefull when other logic is needed docstring=doc_trgs_log_inp) self._add_codeword_parameters() self.add_function('deleteWaveformAll', call_cmd='wlist:waveform:delete all') doc_sSG = "Synchronize both sideband frequency" \ + " generators, i.e. restart them with their defined phases." self.add_function('syncSidebandGenerators', call_cmd='QUTEch:OUTPut:SYNCsideband', docstring=doc_sSG)
def __init__(self, name, **kwargs): t0 = time() super().__init__(name, **kwargs) self.add_parameter('frequency', label='Frequency ', unit='Hz', initial_value=5e9, parameter_class=ManualParameter, vals=vals.Numbers()) self.add_parameter('span', label='Span ', unit='Hz', initial_value=.25e6, parameter_class=ManualParameter, vals=vals.Numbers()) self.add_parameter('power', label='Power ', unit='dBm', initial_value=0, parameter_class=ManualParameter, vals=vals.Numbers(max_value=20)) self.add_parameter('ref_lvl', label='Reference power ', unit='dBm', initial_value=0, parameter_class=ManualParameter, vals=vals.Numbers(max_value=20)) self.add_parameter('external_reference', parameter_class=ManualParameter, initial_value=False, vals=vals.Bool()) self.add_parameter('device_type', parameter_class=ManualParameter) self.add_parameter('device_mode', initial_value='sweeping', parameter_class=ManualParameter, vals=vals.Anything()) self.add_parameter('acquisition_mode', parameter_class=ManualParameter, initial_value='average', vals=vals.Enum('average', 'min-max')) self.add_parameter('scale', parameter_class=ManualParameter, initial_value='log-scale', vals=vals.Enum('log-scale', 'lin-scale', 'log-full-scale', 'lin-full-scale')) self.add_parameter('running', parameter_class=ManualParameter, initial_value=False, vals=vals.Bool()) self.add_parameter('decimation', parameter_class=ManualParameter, initial_value=1, vals=vals.Ints(1, 8)) self.add_parameter('bandwidth', label='Bandwidth', unit='Hz', initial_value=0, parameter_class=ManualParameter, vals=vals.Numbers()) # rbw Resolution bandwidth in Hz. RBW can be arbitrary. self.add_parameter('rbw', label='Resolution Bandwidth', unit='Hz', initial_value=1e3, parameter_class=ManualParameter, vals=vals.Numbers()) # vbw Video bandwidth in Hz. VBW must be less than or equal to RBW. # VBW can be arbitrary. For best performance use RBW as the VBW. self.add_parameter('vbw', label='Video Bandwidth', unit='Hz', initial_value=1e3, parameter_class=ManualParameter, vals=vals.Numbers()) self.add_parameter('avg', label='Number of averages', initial_value=2, parameter_class=ManualParameter, vals=vals.Numbers()) t1 = time() print('Initialized SignalHound in %.2fs' % (t1 - t0))
def __init__(self, name, dll_path=None, **kwargs): t0 = time() super().__init__(name, **kwargs) self.log = logging.getLogger('Main.DeviceInt') logging.info(__name__ + ' : Initializing instrument SignalHound USB 124A') self.dll = ct.CDLL(dll_path or self.dll_path) self.hf = constants self.add_parameter('frequency', label='Frequency ', unit='Hz', initial_value=5e9, parameter_class=ManualParameter, vals=vals.Numbers()) self.add_parameter('span', label='Span ', unit='Hz', initial_value=.25e6, parameter_class=ManualParameter, vals=vals.Numbers()) self.add_parameter('power', label='Power ', unit='dBm', initial_value=0, parameter_class=ManualParameter, vals=vals.Numbers(max_value=20)) self.add_parameter('ref_lvl', label='Reference power ', unit='dBm', initial_value=0, parameter_class=ManualParameter, vals=vals.Numbers(max_value=20)) self.add_parameter('external_reference', parameter_class=ManualParameter, initial_value=False, vals=vals.Bool()) self.add_parameter('device_type', get_cmd=self._do_get_device_type) self.add_parameter('device_mode', initial_value='sweeping', parameter_class=ManualParameter, vals=vals.Anything()) self.add_parameter('acquisition_mode', parameter_class=ManualParameter, initial_value='average', vals=vals.Enum('average', 'min-max')) self.add_parameter('scale', parameter_class=ManualParameter, initial_value='log-scale', vals=vals.Enum('log-scale', 'lin-scale', 'log-full-scale', 'lin-full-scale')) self.add_parameter('running', parameter_class=ManualParameter, initial_value=False, vals=vals.Bool()) self.add_parameter('decimation', parameter_class=ManualParameter, initial_value=1, vals=vals.Ints(1, 8)) self.add_parameter('bandwidth', label='Bandwidth', unit='Hz', initial_value=0, parameter_class=ManualParameter, vals=vals.Numbers()) # rbw Resolution bandwidth in Hz. RBW can be arbitrary. self.add_parameter('rbw', label='Resolution Bandwidth', unit='Hz', initial_value=1e3, parameter_class=ManualParameter, vals=vals.Numbers()) # vbw Video bandwidth in Hz. VBW must be less than or equal to RBW. # VBW can be arbitrary. For best performance use RBW as the VBW. self.add_parameter('vbw', label='Video Bandwidth', unit='Hz', initial_value=1e3, parameter_class=ManualParameter, vals=vals.Numbers()) self.openDevice() self.device_type() t1 = time() print('Initialized SignalHound in %.2fs' % (t1 - t0))
def __init__(self, name, address, **kwargs): super().__init__(name, address, terminator='\n', **kwargs) # Add range parameters self.add_parameter('range_1', label='Channel 1 range', vals=vals.Ints(1, 4), parameter_class=GroupParameter) self.add_parameter('range_2', label='Channel 2 range', vals=vals.Ints(1, 4), parameter_class=GroupParameter) self.add_parameter('range_3', label='Channel 3 range', vals=vals.Ints(1, 4), parameter_class=GroupParameter) # Add current parameters self.add_parameter('current_1', label='Channel 1 current', vals=vals.Ints(0, 100), parameter_class=GroupParameter) self.add_parameter('current_2', label='Channel 2 current', vals=vals.Ints(0, 100), parameter_class=GroupParameter) self.add_parameter('current_3', label='Channel 3 current', vals=vals.Ints(0, 100), parameter_class=GroupParameter) # Add on/off parameters self.add_parameter('on_1', label='Channel 1 on', vals=vals.Bool(), parameter_class=GroupParameter, val_mapping={ True: 1, False: 0 }) self.add_parameter('on_2', label='Channel 2 on', vals=vals.Bool(), parameter_class=GroupParameter, val_mapping={ True: 1, False: 0 }) self.add_parameter('on_3', label='Channel 3 on', vals=vals.Bool(), parameter_class=GroupParameter, val_mapping={ True: 1, False: 0 }) # Add gated parameters self.add_parameter('gated_1', label='Channel 1 gated', vals=vals.Bool(), parameter_class=GroupParameter, val_mapping={ True: 1, False: 0 }) self.add_parameter('gated_2', label='Channel 2 gated', vals=vals.Bool(), parameter_class=GroupParameter, val_mapping={ True: 1, False: 0 }) self.add_parameter('gated_3', label='Channel 3 gated', vals=vals.Bool(), parameter_class=GroupParameter, val_mapping={ True: 1, False: 0 }) # Setup group parameter using status command to update all the parameters at once status_group_parameters = [ self.range_1, self.range_2, self.range_3, self.current_1, self.current_2, self.current_3, self.on_1, self.on_2, self.on_3, self.gated_1, self.gated_2, self.gated_3 ] self.status_group = Group(status_group_parameters, get_parser=status_parser, get_cmd='STATUS?') # Connect to the instrument and get an IDN # self.connect_message() print('Connect string:', self.ask('ID?'))
def __init__(self, name, dll_path=None, **kwargs): """ Args: name: Name of the instrument. dll_path: Path to ``sa_api.dll`` Defaults to the default dll within Spike installation **kwargs: """ super().__init__(name, **kwargs) self._parameters_synced = False self._trace_updated = False log.info('Initializing instrument SignalHound USB 124B') self.dll = ct.CDLL(dll_path or self.dll_path) self._set_ctypes_argtypes() self.hf = Constants self.add_parameter('frequency', label='Frequency', unit='Hz', initial_value=5e9, vals=vals.Numbers(), parameter_class=SweepTraceParameter, docstring='Center frequency for sweep.' 'This is the set center, the actual ' 'center may be subject to round off ' 'compared to this value') self.add_parameter('span', label='Span', unit='Hz', initial_value=.25e6, vals=vals.Numbers(), parameter_class=SweepTraceParameter, docstring='Width of frequency span' 'This is the set span, the actual ' 'span may be subject to round off ' 'compared to this value') self.add_parameter('npts', label='Number of Points', get_cmd=None, set_cmd=False, docstring='Number of points in frequency sweep.') self.add_parameter('avg', label='Averages', initial_value=1, get_cmd=None, set_cmd=None, vals=vals.Ints(), docstring='Number of averages to perform. ' 'Averages are performed in software by ' 'acquiring multiple sweeps') self.add_parameter('ref_lvl', label='Reference power', unit='dBm', initial_value=0, vals=vals.Numbers(max_value=20), parameter_class=TraceParameter, docstring="Setting reference level will " "automatically select gain and attenuation" "optimal for measuring at and below " "this level") self.add_parameter( 'external_reference', initial_value=False, vals=vals.Bool(), parameter_class=ExternalRefParameter, docstring='Use an external 10 MHz reference source. ' 'Note that Signal Hound does not support ' 'disabling external ref. To disable close ' 'the connection and restart.') self.add_parameter('device_type', set_cmd=False, get_cmd=self._get_device_type) self.add_parameter('device_mode', get_cmd=lambda: 'sweeping', set_cmd=False, docstring='The driver currently only ' 'supports sweeping mode. ' 'It is therefor not possible' 'to set this parameter to anything else') self.add_parameter('acquisition_mode', get_cmd=lambda: 'average', set_cmd=False, docstring="The driver only supports averaging " "mode it is therefor not possible to set" "this parameter to anything else") self.add_parameter('rbw', label='Resolution Bandwidth', unit='Hz', initial_value=1e3, vals=vals.Numbers(0.1, 250e3), parameter_class=TraceParameter, docstring='Resolution Bandwidth (RBW) is' 'the bandwidth of ' 'spectral energy represented in each ' 'frequency bin') self.add_parameter('vbw', label='Video Bandwidth', unit='Hz', initial_value=1e3, vals=vals.Numbers(), parameter_class=TraceParameter, docstring='The video bandwidth (VBW) is applied ' 'after the signal has been converted to ' 'frequency domain as power, voltage, ' 'or log units. It is implemented as a ' 'simple rectangular window, averaging the ' 'amplitude readings for each frequency ' 'bin over several overlapping FFTs. ' 'For best performance use RBW as the VBW.') self.add_parameter('reject_image', label='Reject image', unit='', initial_value=True, parameter_class=TraceParameter, get_cmd=None, docstring="Apply software filter to remove " "undersampling mirroring", vals=vals.Bool()) self.add_parameter('sleep_time', label='Sleep time', unit='s', initial_value=0.1, get_cmd=None, set_cmd=None, docstring="Time to sleep before and after " "getting data from the instrument", vals=vals.Numbers(0)) # We don't know the correct values of # the sweep parameters yet so we supply # some defaults. The correct will be set when we call configure below self.add_parameter(name='trace', sweep_len=1, start_freq=1, stepsize=1, parameter_class=FrequencySweep) self.add_parameter('power', label='Power', unit='dBm', get_cmd=self._get_power_at_freq, set_cmd=False, docstring="The maximum power in a window of 250 kHz" "around the specified frequency with " "Resolution bandwidth set to 1 kHz." "The integration window is specified by " "the VideoBandWidth (set by vbw)") # scale is defined after the trace and power parameter so that # it can change the units of those in it's set method when the # scale changes self.add_parameter('scale', initial_value='log-scale', vals=vals.Enum('log-scale', 'lin-scale', 'log-full-scale', 'lin-full-scale'), parameter_class=ScaleParameter) self.openDevice() self.configure() self.connect_message()
def __init__(self, instrument_name, **kwargs): super().__init__(instrument_name, **kwargs) self._input_channels = { "I": Channel(instrument_name=self.instrument_name(), name="I", input=True), "Q": Channel(instrument_name=self.instrument_name(), name="Q", input=True), "pulse_mod": Channel( instrument_name=self.instrument_name(), name="pulse_mod", input=True ), } self._output_channels = { "RF_out": Channel( instrument_name=self.instrument_name(), name="RF_out", output=True ) } self._channels = { **self._input_channels, **self._output_channels, "sync": Channel( instrument_name=self.instrument_name(), name="sync", output=True ), } self.pulse_implementations = [ SinePulseImplementation( pulse_requirements=[ ("frequency", {"min": 1e6, "max": 40e9}), ("power", {"min": -120, "max": 25}), ("duration", {"min": 100e-9}), ] ), FrequencyRampPulseImplementation( pulse_requirements=[ ("frequency_start", {"min": 1e6, "max": 40e9}), ("frequency_stop", {"min": 1e6, "max": 40e9}), ("power", {"min": -120, "max": 25}), ("duration", {"min": 100e-9}), ] ), ] self.envelope_padding = Parameter( "envelope_padding", unit="s", set_cmd=None, initial_value=0, vals=vals.Numbers(min_value=0, max_value=10e-3), docstring="Padding for any pulses that use IQ modulation. " "This is to ensure that any IQ pulses such as sine waves " "are applied a bit before the pulse starts. The marker pulse " "used for pulse modulation does not use any envelope padding.", ) self.marker_amplitude = Parameter( unit="V", set_cmd=None, initial_value=1.5, docstring="Amplitude of marker pulse used for gating", ) self.fix_frequency = Parameter( set_cmd=None, initial_value=False, vals=vals.Bool(), docstring="Whether to fix frequency to current value, or to " "dynamically choose frequency during setup", ) self.frequency_carrier_choice = Parameter( set_cmd=None, initial_value="center", vals=vals.MultiType(vals.Enum("min", "center", "max"), vals.Numbers()), docstring="The choice for the microwave frequency, This is used if " "pulses with multiple frequencies are used, or if frequency " "modulation is needed. Ignored if fix_frequency = True. " 'Can be either "max", "min", or "center", or a ' "number which is the offset from the center", ) self.frequency = Parameter( unit="Hz", set_cmd=None, initial_value=self.instrument.frequency() ) self.power = Parameter( unit="dBm", set_cmd=None, initial_value=self.instrument.power(), docstring="Power that the microwave source will be set to. " "Set to equal the maximum power of the pulses", ) self.IQ_modulation = Parameter( initial_value=None, vals=vals.Bool(), docstring="Whether to use IQ modulation. Cannot be directly set, but " "is set internally if there are pulses with multiple " "frequencies, self.fix_frequency() is True, or " "self.force_IQ_modulation() is True.", ) self.IQ_channels = Parameter( initial_value='IQ', vals=vals.Enum('IQ', 'I', 'Q'), set_cmd=None, docstring="Which channels to use for IQ modulation." "Double-sideband modulation is used if only 'I' or 'Q' " "is chosen, while single-sideband modulation is used when" "'IQ' is chosen." ) self.force_IQ_modulation = Parameter( initial_value=False, vals=vals.Bool(), set_cmd=None, docstring="Whether to force IQ modulation.", ) self.marker_per_pulse = Parameter( initial_value=True, vals=vals.Bool(), set_cmd=None, docstring='Use a separate marker per pulse. If False, a single ' 'marker pulse is requested for the first pulse to the last ' 'pulse. In this case, envelope padding will be added to ' 'either side of the single marker pulse.' ) # Add parameters that are not set via setup self.additional_settings = ParameterNode() for parameter_name in [ "phase", "maximum_power", "IQ_impairment", "I_leakage", "Q_leakage", "Q_offset", "IQ_ratio", "IQ_wideband", "IQ_crestfactor", "reference_oscillator_source", "reference_oscillator_output_frequency", "reference_oscillator_external_frequency", ]: parameter = getattr(self.instrument, parameter_name) setattr(self.additional_settings, parameter_name, parameter)
def __init__(self, name, address, **kwargs): super().__init__(name, address, **kwargs) self.add_parameter('error', label='Error Code', get_cmd='LERR?', get_parser=int) self.add_parameter('advanced_trigger', label='Advanced Trigger Mode', get_cmd='ADVT?', get_parser=lambda v: bool(int(v)), set_cmd='ADVT {:d}', vals=vals.Bool()) self.add_parameter('trigger_source', label='Trigger Source', get_cmd='TSRC?', get_parser=int, set_cmd='TSRC {:d}', val_mapping={ 'Internal': 0, 'External rising edge': 1, 'External falling edge': 2, 'Single shot external rising edge': 3, 'Single shot external falling edge': 4, 'Single shot': 5, 'Line': 6 }) self.add_parameter('trigger_level', label='Trigger Level', unit='V', get_cmd='TLVL?', get_parser=float, set_cmd='TLVL {:f}', vals=vals.Numbers(-3.5, 3.5)) self.add_parameter( name='trigger_holdoff', label='Trigger Holdoff', unit='s', docstring='Minimum time between triggers. Advanced triggering must ' 'be enabled for this parameter to have an effect.', get_cmd='HOLD?', get_parser=float, set_cmd='HOLD {:f}') self.add_parameter( 'trigger_inhibit', label='Trigger Inhibit', docstring= 'Outputs inhibited when the external inhibit input is high.', get_cmd='INHB?', get_parser=int, set_cmd='INHB {}', val_mapping={ 'off': 0, 'triggers': 1, 'AB': 2, 'AB, CD': 3, 'AB, CD, EF': 4, 'AB, CD, EF, GH': 5 }) self.add_parameter( 'trigger_prescale_factor', label='Trigger Prescale Factor', docstring='Channel output is enabled on every nth trigger. ' 'Requires advanced triggering to be enabled.', get_cmd='PRES?0', get_parser=int, set_cmd='PRES 0,{:d}', vals=vals.Numbers(1, (1 << 30) - 1)) # Burst mode parameters self.add_parameter('burst_mode', label='Burst Mode', get_cmd='BURM?', get_parser=lambda v: bool(int(v)), set_cmd='BURM {}', vals=vals.Bool()) self.add_parameter('burst_delay', label='Burst Delay', unit='s', get_cmd='BURD?', get_parser=float, set_cmd='BURD {:.12f}', vals=vals.Numbers(0, 2000)) self.add_parameter('burst_count', label='Burst Count', get_cmd='BURC?', get_parser=int, set_cmd='BURC {:d}', vals=vals.Numbers(1, 4294967295)) self.add_parameter('burst_period', label='Burst Period', get_cmd='BURP?', get_parser=float, set_cmd='BURP {:.8f}', vals=vals.Numbers(1e-7, 42.9)) # Output channels for ch_id, ch_name in [(0, 'T0'), (1, 'AB'), (2, 'CD'), (3, 'EF'), (4, 'GH')]: self.add_submodule(ch_name, DG645Channel(self, ch_name, ch_id)) # Show IDN self.connect_message()
import logging import re from functools import partial from time import sleep, time from qcodes import validators as vals from qcodes import Instrument, InstrumentChannel, VisaInstrument from qcodes import Parameter log = logging.getLogger(__name__) DLCpro_val_dict = { int: vals.Ints(), float: vals.Numbers(), str: vals.Strings(), bool: vals.Bool() } DLCpro_get_parser_dict = { int: int, float: float, str: lambda s: s.strip('\"'), bool: None } DLCpro_set_parser_dict = { int: None, float: None, str: lambda s: f'\"{s}\"', bool: None }
def add_parameters(self): ####################################################################### # QWG specific ####################################################################### # Channel pair parameters for i in range(self.device_descriptor.numChannels // 2): ch_pair = i * 2 + 1 sfreq_cmd = 'qutech:output{}:frequency'.format(ch_pair) sph_cmd = 'qutech:output{}:phase'.format(ch_pair) # NB: sideband frequency has a resolution of ~0.23 Hz: self.add_parameter('ch_pair{}_sideband_frequency'.format(ch_pair), parameter_class=HandshakeParameter, unit='Hz', label=('Sideband frequency channel ' + 'pair {} (Hz)'.format(i)), get_cmd=sfreq_cmd + '?', set_cmd=sfreq_cmd + ' {}', vals=vals.Numbers(-300e6, 300e6), get_parser=float) self.add_parameter('ch_pair{}_sideband_phase'.format(ch_pair), parameter_class=HandshakeParameter, unit='deg', label=('Sideband phase channel' + ' pair {} (deg)'.format(i)), get_cmd=sph_cmd + '?', set_cmd=sph_cmd + ' {}', vals=vals.Numbers(-180, 360), get_parser=float) self.add_parameter( 'ch_pair{}_transform_matrix'.format(ch_pair), parameter_class=HandshakeParameter, label=('Transformation matrix channel' + 'pair {}'.format(i)), get_cmd=self._gen_ch_get_func(self._getMatrix, ch_pair), set_cmd=self._gen_ch_set_func(self._setMatrix, ch_pair), # NB range is not a hardware limit vals=vals.Arrays(-2, 2, shape=(2, 2))) # Triggers parameter for i in range(1, self.device_descriptor.numTriggers + 1): triglev_cmd = 'qutech:trigger{}:level'.format(i) # individual trigger level per trigger input: self.add_parameter('tr{}_trigger_level'.format(i), unit='V', label='Trigger level channel {} (V)'.format(i), get_cmd=triglev_cmd + '?', set_cmd=triglev_cmd + ' {}', vals=self.device_descriptor.mvals_trigger_level, get_parser=float) self.add_parameter('run_mode', get_cmd='AWGC:RMO?', set_cmd='AWGC:RMO ' + '{}', vals=vals.Enum('NONE', 'CONt', 'SEQ', 'CODeword')) # NB: setting mode "CON" (valid SCPI abbreviation) reads back as "CONt" self.add_parameter('dio_mode', unit='', label='DIO input operation mode', get_cmd='DIO:MODE?', set_cmd='DIO:MODE ' + '{}', vals=vals.Enum('MASTER', 'SLAVE'), val_mapping={'MASTER': 'MASter', 'SLAVE': 'SLAve'}, docstring='Get or set the DIO input operation mode\n' \ 'Paramaters:\n' \ '\tMASTER: Use DIO codeword (lower 14 bits) input '\ 'from its own IORearDIO board' \ '\t\tEnables single-ended and differential inputs\n' \ '\tSLAVE; Use DIO codeword (upper 14 bits) input '\ 'from the connected master IORearDIO board\n' '\t\tDisables SE and DIFF inputs\n' ) self.add_parameter('dio_is_calibrated', unit='', label='DIO calibration status', get_cmd='DIO:CALibrate?', val_mapping={ True: '1', False: '0' }, docstring="""Get DIO calibration status\n Result:\n \tTrue: DIO is calibrated\n \tFalse: DIO is not calibrated""") self.add_parameter('dio_active_index', unit='', label='DIO calibration index', get_cmd='DIO:INDexes:ACTive?', set_cmd='DIO:INDexes:ACTive {}', get_parser=np.uint32, vals=vals.Ints(0, 20), docstring='Get and set DIO calibration index\n' \ 'See dio_calibrate() paramater\n' ) self.add_parameter('dio_suitable_indexes', unit='', label='DIO suitable indexes', get_cmd='DIO:INDexes?', get_parser=self._int_to_array, docstring='Get DIO all suitable indexes\n' \ '\t- The array is ordered by most preferable index first\n' ) self.add_parameter( 'dio_calibrated_inputs', unit='', label='DIO calibrated inputs', get_cmd='DIO:INPutscalibrated?', get_parser=int, docstring='Get all DIO inputs which are calibrated\n') self.add_parameter('dio_lvds', unit='bool', label='LVDS DIO connection detected', get_cmd='DIO:LVDS?', val_mapping={ True: '1', False: '0' }, docstring='Get the DIO LVDS connection status.\n' 'Result:\n' '\tTrue: Cable detected\n' '\tFalse: No cable detected') self.add_parameter( 'dio_interboard', unit='bool', label='DIO interboard detected', get_cmd='DIO:IB?', val_mapping={ True: '1', False: '0' }, docstring='Get the DIO interboard status.\n' 'Result:\n' '\tTrue: To master interboard connection detected\n' '\tFalse: No interboard connection detected') # Channel parameters # for ch in range(1, self.device_descriptor.numChannels + 1): amp_cmd = 'SOUR{}:VOLT:LEV:IMM:AMPL'.format(ch) offset_cmd = 'SOUR{}:VOLT:LEV:IMM:OFFS'.format(ch) state_cmd = 'OUTPUT{}:STATE'.format(ch) waveform_cmd = 'SOUR{}:WAV'.format(ch) output_voltage_cmd = 'QUTEch:OUTPut{}:Voltage'.format(ch) dac_temperature_cmd = 'STATus:DAC{}:TEMperature'.format(ch) gain_adjust_cmd = 'DAC{}:GAIn:DRIFt:ADJust'.format(ch) dac_digital_value_cmd = 'DAC{}:DIGitalvalue'.format(ch) # Set channel first to ensure sensible sorting of pars # Compatibility: 5014, QWG self.add_parameter('ch{}_state'.format(ch), label='Status channel {}'.format(ch), get_cmd=state_cmd + '?', set_cmd=state_cmd + ' {}', val_mapping={ True: '1', False: '0' }, vals=vals.Bool()) self.add_parameter( 'ch{}_amp'.format(ch), parameter_class=HandshakeParameter, label='Channel {} Amplitude '.format(ch), unit='Vpp', docstring='Amplitude channel {} (Vpp into 50 Ohm)'.format(ch), get_cmd=amp_cmd + '?', set_cmd=amp_cmd + ' {:.6f}', vals=vals.Numbers(-1.6, 1.6), get_parser=float) self.add_parameter( 'ch{}_offset'.format(ch), # parameter_class=HandshakeParameter, label='Offset channel {}'.format(ch), unit='V', get_cmd=offset_cmd + '?', set_cmd=offset_cmd + ' {:.3f}', vals=vals.Numbers(-.25, .25), get_parser=float) self.add_parameter('ch{}_default_waveform'.format(ch), get_cmd=waveform_cmd + '?', set_cmd=waveform_cmd + ' "{}"', vals=vals.Strings()) self.add_parameter('status_dac{}_temperature'.format(ch), unit='C', label=('DAC {} temperature'.format(ch)), get_cmd=dac_temperature_cmd + '?', get_parser=float, docstring='Reads the temperature of a DAC.\n' \ +'Temperature measurement interval is 10 seconds\n' \ +'Return:\n float with temperature in Celsius') self.add_parameter('output{}_voltage'.format(ch), unit='V', label=('Channel {} voltage output').format(ch), get_cmd=output_voltage_cmd + '?', get_parser=float, docstring='Reads the output voltage of a channel.\n' \ +'Notes:\n Measurement interval is 10 seconds.\n' \ +' The output voltage will only be read if the channel is disabled:\n' \ +' E.g.: qwg.chX_state(False)\n' \ +' If the channel is enabled it will return an low value: >0.1\n' \ +'Return:\n float in voltage') self.add_parameter('dac{}_gain_drift_adjust'.format(ch), unit='', label=('DAC {}, gain drift adjust').format(ch), get_cmd=gain_adjust_cmd + '?', set_cmd=gain_adjust_cmd + ' {}', vals=vals.Ints(0, 4095), get_parser=int, docstring='Gain drift adjust setting of the DAC of a channel.\n' \ +'Used for calibration of the DAC. Do not use to set the gain of a channel!\n' \ +'Notes:\n The gain setting is from 0 to 4095 \n' \ +' Where 0 is 0 V and 4095 is 3.3V \n' \ +'Get Return:\n Setting of the gain in interger (0 - 4095)\n'\ +'Set parameter:\n Integer: Gain of the DAC in , min: 0, max: 4095') self.add_parameter('_dac{}_digital_value'.format(ch), unit='', label=('DAC {}, set digital value').format(ch), set_cmd=dac_digital_value_cmd + ' {}', vals=vals.Ints(0, 4095), docstring='FOR DEVELOPMENT ONLY: Set a digital value directly into the DAC\n' \ +'Used for testing the DACs.\n' \ +'Notes:\n\tThis command will also set the ' \ +'\tinternal correction matrix (Phase and amplitude) of the channel pair to [0,0,0,0], ' \ +'disabling any influence from the wave memory.' \ +'This will also stop the wave the other channel of the pair!\n\n' \ +'Set parameter:\n\tInteger: Value to write to the DAC, min: 0, max: 4095\n' \ +'\tWhere 0 is minimal DAC scale and 4095 is maximal DAC scale \n') self.add_parameter('ch{}_bit_select'.format(ch), unit='', label=('Channel {}, set bit selection for this channel').format(ch), get_cmd=self._gen_ch_get_func( self._get_bit_select, ch), set_cmd=self._gen_ch_set_func( self._set_bit_select, ch), get_parser=np.uint32, docstring='Codeword bit select for a channel\n' \ +'Set: \n' \ +'\tParamater: Integer, the bit select\n' \ +'\nWhen a bit is enabled (1) in the bitSelect, this bit is used as part of the codeword for that channel. ' \ +' If a bit is disabled (0), it will be ignored.\n' \ +'This can be used to control individual channels with a their own codeword.\n' \ +'Note that codeword 1 will start on the first enabled bit. Bit endianness: LSB, lowest bit right \n' \ +'\nExamples:\n' \ +'\tCh1: 0b000011(0x03); Only the first and second bit will be used as codeword for channel 1.\n'\ +'\tCh2: 0b001100(0x0C); Only the third and forth bit will be used as codeword for channel 2.\n'\ +'\tCh3: 0b110000(0x30); Only the fifth and sixth bit will be used as codeword for channel 3.\n'\ +'\tCh4: 0b110000(0x30); Only the fifth and sixth bit will be used as codeword for channel 4.\n'\ +'The bit select of different channels are only allowed to overlap each other if their least significant bit is the same.\n' \ +'So a bitSelect of ch1: 0b011, and ch2: 0b010 is not allowed. This will be checked on `start()`. Errors are reported by `getError()` or `getErrors()`.' \ +'\n\n Get:\n' \ +'\tResult: Integer that represent the bit select of the channel\n') self.add_parameter( 'ch{}_bit_map'.format(ch), unit='', label='Channel {}, set bit map for this channel'.format(ch), get_cmd=f"DAC{ch}:BITmap?", set_cmd=self._gen_ch_set_func(self._set_bit_map, ch), get_parser=self._int_to_array, docstring='Codeword bit map for a channel\n') # Trigger parameters doc_trgs_log_inp = 'Reads the current input values on the all the trigger ' \ +'inputs for a channel, after the bitSelect.\nReturn:\n uint32 where trigger 1 (T1) ' \ +'is on the Least significant bit (LSB), T2 on the second ' \ +'bit after LSB, etc.\n\n For example, if only T3 is ' \ +'connected to a high signal, the return value is: ' \ +'4 (0b0000100)\n\n Note: To convert the return value ' \ +'to a readable ' \ +'binary output use: `print(\"{0:#010b}\".format(qwg.' \ +'triggers_logic_input()))`' self.add_parameter( 'ch{}_triggers_logic_input'.format(ch), label='Read triggers input value', get_cmd='QUTEch:TRIGgers{}:LOGIcinput?'.format(ch), get_parser=np.uint32, # Did not convert to readable # string because a uint32 is more # usefull when other logic is needed docstring=doc_trgs_log_inp) # Single parameters self.add_parameter('status_frontIO_temperature', unit='C', label='FrontIO temperature', get_cmd='STATus:FrontIO:TEMperature?', get_parser=float, docstring='Reads the temperature of the frontIO.\n' \ +'Temperature measurement interval is 10 seconds\n' \ +'Return:\n float with temperature in Celsius') self.add_parameter('status_fpga_temperature', unit='C', label=('FPGA temperature'), get_cmd='STATus:FPGA:TEMperature?', get_parser=int, docstring='Reads the temperature of the FPGA.\n' \ +'Temperature measurement interval is 10 seconds\n' \ +'Return:\n float with temperature in Celsius') # Paramater for codeword per channel for cw in range(self.device_descriptor.numCodewords): for j in range(self.device_descriptor.numChannels): ch = j + 1 # Codeword 0 corresponds to bitcode 0 cw_cmd = 'sequence:element{:d}:waveform{:d}'.format(cw, ch) self.add_parameter('codeword_{}_ch{}_waveform'.format(cw, ch), get_cmd=cw_cmd + '?', set_cmd=cw_cmd + ' "{:s}"', vals=vals.Strings()) # Waveform parameters self.add_parameter('WlistSize', label='Waveform list size', unit='#', get_cmd='wlist:size?', get_parser=int) self.add_parameter('Wlist', label='Waveform list', get_cmd=self._getWlist) self.add_parameter('get_system_status', unit='JSON', label="System status", get_cmd='SYSTem:STAtus?', vals=vals.Strings(), get_parser=self.JSON_parser, docstring='Reads the current system status. E.q. channel ' \ +'status: on or off, overflow, underdrive.\n' \ +'Return:\n JSON object with system status') self.add_parameter( 'get_max_codeword_bits', unit='', label=('Max codeword bits'), get_cmd=self._nr_cw_bits_cmd, vals=vals.Strings(), get_parser=int, docstring= 'Reads the maximal number of codeword bits for all channels') self.add_parameter('codeword_protocol', unit='', label='Codeword protocol', get_cmd=self._getCodewordProtocol, set_cmd=self._setCodewordProtocol, vals=vals.Enum('MICROWAVE', 'FLUX'), docstring='Reads the current system status. E.q. channel ' \ +'status: on or off, overflow, underdrive.\n' \ +'Return:\n JSON object with system status') self._add_codeword_parameters() self.add_function('deleteWaveformAll', call_cmd='wlist:waveform:delete all') doc_sSG = "Synchronize both sideband frequency" \ + " generators, i.e. restart them with their defined phases." self.add_function('syncSidebandGenerators', call_cmd='QUTEch:OUTPut:SYNCsideband', docstring=doc_sSG)
def _add_awg_parameters(self): # Channel pair parameters for i in range(self._dev_desc.numChannels // 2): ch_pair = i * 2 + 1 self.add_parameter( f'ch_pair{ch_pair}_sideband_frequency', parameter_class=HandshakeParameter, unit='Hz', label=('Sideband frequency channel pair {} (Hz)'.format(i)), get_cmd=_gen_get_func_1par(self.get_sideband_frequency, ch_pair), set_cmd=_gen_set_func_1par(self.set_sideband_frequency, ch_pair), vals=vals.Numbers(-300e6, 300e6), get_parser=float, docstring='Frequency of the sideband modulator\n' 'Resolution: ~0.23 Hz') self.add_parameter( f'ch_pair{ch_pair}_sideband_phase', parameter_class=HandshakeParameter, unit='deg', label=('Sideband phase channel pair {} (deg)'.format(i)), get_cmd=_gen_get_func_1par(self.get_sideband_phase, ch_pair), set_cmd=_gen_set_func_1par(self.set_sideband_phase, ch_pair), vals=vals.Numbers(-180, 360), get_parser=float, docstring='Sideband phase difference between channels') self.add_parameter( f'ch_pair{ch_pair}_transform_matrix', parameter_class=HandshakeParameter, unit='%', label=('Transformation matrix channel pair {}'.format(i)), get_cmd=_gen_get_func_1par(self._get_matrix, ch_pair), set_cmd=_gen_set_func_1par(self._set_matrix, ch_pair), vals=vals.Arrays( -2, 2, shape=(2, 2)), # NB range is not a hardware limit docstring= 'Transformation matrix for mixer correction per channel pair') # Channel parameters for ch in range(1, self._dev_desc.numChannels + 1): self.add_parameter( f'ch{ch}_state', label=f'Output state channel {ch}', get_cmd=_gen_get_func_1par(self.get_output_state, ch), set_cmd=_gen_set_func_1par(self.set_output_state, ch), val_mapping={ True: '1', False: '0' }, vals=vals.Bool(), docstring='Enables or disables the output of channels\n' 'Default: Disabled') self.add_parameter( f'ch{ch}_amp', parameter_class=HandshakeParameter, label=f'Channel {ch} Amplitude ', unit='Vpp', get_cmd=_gen_get_func_1par(self.get_amplitude, ch), set_cmd=_gen_set_func_1par(self.set_amplitude, ch), vals=vals.Numbers(-1.6, 1.6), get_parser=float, docstring=f'Amplitude channel {ch} (Vpp into 50 Ohm)') self.add_parameter( f'ch{ch}_offset', # parameter_class=HandshakeParameter, FIXME: was commented out label=f'Offset channel {ch}', unit='V', get_cmd=_gen_get_func_1par(self.get_offset, ch), set_cmd=_gen_set_func_1par(self.set_offset, ch), vals=vals.Numbers(-.25, .25), get_parser=float, docstring=f'Offset channel {ch}') self.add_parameter( f'ch{ch}_default_waveform', get_cmd=_gen_get_func_1par(self.get_waveform, ch), set_cmd=_gen_set_func_1par(self.set_waveform, ch), # FIXME: docstring vals=vals.Strings()) # end for(ch... # FIXME: enable if/when support for marker/trigger board is added again # Triggers parameter # for trigger in range(1, self._dev_desc.numTriggers+1): # triglev_cmd = f'qutech:trigger{trigger}:level' # # individual trigger level per trigger input: # self.add_parameter( # f'tr{trigger}_trigger_level', # unit='V', # label=f'Trigger level channel {trigger} (V)', # # FIXME # get_cmd=triglev_cmd + '?', # set_cmd=triglev_cmd + ' {}', # vals=self._dev_desc.mvals_trigger_level, # get_parser=float, # snapshot_exclude=True) # # FIXME: docstring # Single parameters self.add_parameter('run_mode', get_cmd=self.get_run_mode, set_cmd=self.set_run_mode, vals=vals.Enum('NONE', 'CONt', 'SEQ', 'CODeword'), docstring=_run_mode_doc + '\n Effective after start command')