예제 #1
0
    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())
예제 #2
0
 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)
예제 #4
0
    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(),
        )
예제 #5
0
    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))
예제 #7
0
    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))
예제 #8
0
    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()
예제 #10
0
    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)
예제 #11
0
    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()
예제 #12
0
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
}
예제 #13
0
    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)
예제 #14
0
    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')