Esempio n. 1
0
    def __init__(self, name, address, step_attenuator=False, **kwargs):
        super().__init__(name, address, **kwargs)

        # Only listed most common spellings idealy want a
        # .upper val for Enum or string
        on_off_validator = vals.Enum('on', 'On', 'ON', 'off', 'Off', 'OFF')
        on_off_mapping = create_on_off_val_mapping(1, 0)

        self.add_parameter(name='frequency',
                           label='Frequency',
                           unit='Hz',
                           get_cmd='FREQ:CW?',
                           set_cmd='FREQ:CW' + ' {:.4f}',
                           get_parser=float,
                           set_parser=float,
                           vals=vals.Numbers(1e5, 20e9),
                           docstring='Adjust the RF output frequency')
        self.add_parameter(name='frequency_offset',
                           label='Frequency offset',
                           unit='Hz',
                           get_cmd='FREQ:OFFS?',
                           set_cmd='FREQ:OFFS {}',
                           get_parser=float,
                           vals=Numbers(min_value=-200e9, max_value=200e9))
        self.add_parameter('frequency_mode',
                           label='Frequency mode',
                           set_cmd='FREQ:MODE {}',
                           get_cmd='FREQ:MODE?',
                           get_parser=lambda s: s.strip(),
                           vals=vals.Enum('FIX', 'CW', 'SWE', 'LIST'))
        self.add_parameter(name='phase',
                           label='Phase',
                           unit='deg',
                           get_cmd='PHASE?',
                           set_cmd='PHASE' + ' {:.8f}',
                           get_parser=self.rad_to_deg,
                           set_parser=self.deg_to_rad,
                           vals=vals.Numbers(-180, 180))
        self.add_parameter(name='power',
                           label='Power',
                           unit='dBm',
                           get_cmd='POW:AMPL?',
                           set_cmd='POW:AMPL' + ' {:.4f}',
                           get_parser=float,
                           set_parser=float,
                           vals=vals.Numbers(-130, 25))
        self.add_parameter('status',
                           get_cmd=':OUTP?',
                           set_cmd='OUTP {}',
                           get_parser=parse_on_off,
                           vals=on_off_validator)
        self.add_parameter(name='modulation_rf_enabled',
                           get_cmd='OUTP:MOD?',
                           set_cmd='OUTP:MOD {}',
                           val_mapping=on_off_mapping)
        self.add_parameter(
            'IQmodulator_enabled',
            get_cmd='DM:STATe?',
            set_cmd='DM:STATe {}',
            val_mapping=on_off_mapping,
            docstring=
            'Enables or disables the internal I/Q modulator. Source can be external or internal.'
        )

        for source in [1, 2]:
            self.add_parameter(f'IQsource{source}',
                               get_cmd=f'DM:SOUR{source}?',
                               set_cmd=f'DM:SOUR{source} {{}}',
                               get_parser=lambda s: s.strip(),
                               vals=vals.Enum('OFF', 'EXT', 'EXT600', 'INT'),
                               docstring=IQsource_docstring)

        self.connect_message()
Esempio n. 2
0
    def __init__(
        self,
        name: str,
        address: str,
        timeout: float = 20,
        channels: int = 4,
        silence_pyvisapy_warning: bool = False,
        **kwargs: Any,
    ):
        """
        Initialises the oscilloscope.

        Args:
            name: Name of the instrument used by QCoDeS
            address: Instrument address as used by VISA
            timeout: Visa timeout, in secs.
            channels: The number of channels on the scope.
            silence_pyvisapy_warning: Don't warn about pyvisa-py at startup
        """
        super().__init__(name,
                         address,
                         timeout=timeout,
                         terminator="\n",
                         **kwargs)
        self.connect_message()

        # Check if we are using pyvisa-py as our visa lib and warn users that
        # this may cause long digitize operations to fail
        if (self.visa_handle.visalib.library_path == "py"
                and not silence_pyvisapy_warning):
            self.log.warning(
                "Timeout not handled correctly in pyvisa_py. This may cause"
                " long acquisitions to fail. Either use ni/keysight visalib"
                " or set timeout to longer than longest expected acquisition"
                " time.")

        # switch the response header off else none of our parameters will work
        self.write(":SYSTem:HEADer OFF")

        # Then set up the data format used to retrieve waveforms
        self.write(":WAVEFORM:FORMAT WORD")
        self.write(":WAVEFORM:BYTEORDER LSBFirst")
        self.write(":WAVEFORM:STREAMING ON")

        # Query the oscilloscope parameters
        # Set sample rate, bandwidth and memory depth limits
        self._query_capabilities()
        # Number of channels can't be queried on most older scopes. Use a parameter
        # for now.
        self.no_channels = channels

        # Run state
        self.run_mode = Parameter(
            name="run_mode",
            instrument=self,
            label="run mode",
            get_cmd=":RST?",
            vals=vals.Enum("RUN", "STOP", "SING"),
        )

        # Timing Parameters
        self.timebase_range = Parameter(
            name="timebase_range",
            instrument=self,
            label="Range of the time axis",
            unit="s",
            get_cmd=":TIM:RANG?",
            set_cmd=":TIM:RANG {}",
            vals=vals.Numbers(5e-12, 20),
            get_parser=float,
        )
        self.timebase_position = Parameter(
            name="timebase_position",
            instrument=self,
            label="Offset of the time axis",
            unit="s",
            get_cmd=":TIM:POS?",
            set_cmd=":TIM:POS {}",
            vals=vals.Numbers(),
            get_parser=float,
        )
        self.timebase_roll_enabled = Parameter(
            name="timebase_roll_enabled",
            instrument=self,
            label="Is rolling mode enabled",
            get_cmd=":TIM:ROLL:ENABLE?",
            set_cmd=":TIM:ROLL:ENABLE {}",
            val_mapping={
                True: 1,
                False: 0
            },
        )

        # Trigger
        self.trigger_mode = Parameter(
            name="trigger_mode",
            instrument=self,
            label="Trigger mode",
            get_cmd=":TRIG:MODE?",
        )
        self.trigger_sweep = Parameter(
            name="trigger_sweep",
            instrument=self,
            label="Trigger sweep mode",
            get_cmd=":TRIG:SWE?",
            set_cmd=":TRIG:SWE {}",
            vals=vals.Enum("AUTO", "TRIG"),
        )
        self.trigger_state = Parameter(
            name="trigger_state",
            instrument=self,
            label="Trigger state",
            get_cmd=":AST?",
            vals=vals.Enum("ARM", "TRIG", "ATRIG", "ADONE"),
            snapshot_value=False,
        )

        # Edge trigger parameters
        # Note that for now we only support parameterized edge triggers - this may
        # be something worth expanding.
        # To set trigger level, use the "trigger_level" parameter in each channel
        self.trigger_edge_source = Parameter(
            name="trigger_edge_source",
            instrument=self,
            label="Source channel for the edge trigger",
            get_cmd=":TRIGger:EDGE:SOURce?",
            set_cmd=":TRIGger:EDGE:SOURce {}",
            vals=vals.Enum(*([f"CHAN{i}" for i in range(1, 4 + 1)] +
                             [f"DIG{i}"
                              for i in range(16 + 1)] + ["AUX", "LINE"])),
        )
        self.trigger_edge_slope = Parameter(
            name="trigger_edge_slope",
            instrument=self,
            label="slope of the edge trigger",
            get_cmd=":TRIGger:EDGE:SLOPe?",
            set_cmd=":TRIGger:EDGE:SLOPe {}",
            vals=vals.Enum("POS", "POSITIVE", "NEG", "NEGATIVE", "EITH"),
        )
        self.trigger_level_aux = Parameter(
            name="trigger_level_aux",
            instrument=self,
            label="Tirgger level AUX",
            unit="V",
            get_cmd=":TRIGger:LEVel? AUX",
            set_cmd=":TRIGger:LEVel AUX,{}",
            get_parser=float,
            vals=vals.Numbers(),
        )

        # Aquisition
        # If sample points, rate and timebase_scale are set in an
        # incomensurate way, the scope only displays part of the waveform
        self.acquire_points = Parameter(
            name="acquire_points",
            instrument=self,
            label="sample points",
            get_cmd=":ACQ:POIN?",
            set_cmd=":ACQ:POIN {}",
            get_parser=int,
            vals=vals.Numbers(min_value=self.min_pts, max_value=self.max_pts),
        )
        self.sample_rate = Parameter(
            name="sample_rate",
            instrument=self,
            label="sample rate",
            get_cmd=":ACQ:SRAT?",
            set_cmd=":ACQ:SRAT {}",
            unit="Hz",
            get_parser=float,
            vals=vals.Numbers(min_value=self.min_srat,
                              max_value=self.max_srat),
        )
        # Note: newer scopes allow a per-channel bandwidth. This is not implemented yet.
        self.bandwidth = Parameter(
            name="bandwidth",
            instrument=self,
            label="bandwidth",
            get_cmd=":ACQ:BAND?",
            set_cmd=":ACQ:BAND {}",
            unit="Hz",
            get_parser=float,
            vals=vals.Numbers(min_value=self.min_bw, max_value=self.max_bw),
        )
        self.acquire_interpolate = Parameter(
            name="acquire_interpolate",
            instrument=self,
            get_cmd=":ACQ:INTerpolate?",
            set_cmd=":ACQuire:INTerpolate {}",
            vals=vals.Enum(0, 1, "INT1", "INT2", "INT4", "INT8", "INT16",
                           "INT32"),
        )
        self.acquire_mode = Parameter(
            name="acquire_mode",
            instrument=self,
            label="Acquisition mode",
            get_cmd="ACQuire:MODE?",
            set_cmd="ACQuire:MODE {}",
            vals=vals.Enum(
                "ETIMe",
                "RTIMe",
                "PDETect",
                "HRESolution",
                "SEGMented",
                "SEGPdetect",
                "SEGHres",
            ),
        )
        self.average = Parameter(
            name="average",
            instrument=self,
            label="Averages",
            get_cmd=self._get_avg,
            set_cmd=self._set_avg,
            vals=vals.Ints(min_value=1, max_value=10486575),
        )

        # Automatically digitize before acquiring a trace
        self.auto_digitize: Parameter = Parameter(
            name="auto_digitize",
            instrument=self,
            label="Auto digitize",
            set_cmd=None,
            get_cmd=None,
            val_mapping=create_on_off_val_mapping(),
            docstring=(
                "Digitize before each waveform download. "
                "If you need to acquire from multiple channels simultaneously "
                "or you wish to acquire with the scope running freely, "
                "set this value to False."),
            initial_value=True,
        )
        self.cache_setpoints: Parameter = Parameter(
            name="cache_setpoints",
            instrument=self,
            label="Cache setpoints",
            set_cmd=None,
            get_cmd=None,
            val_mapping=create_on_off_val_mapping(),
            docstring=
            ("Cache setpoints. If false, the preamble is queried before each"
             " acquisition, which may add latency to measurements. If you"
             " are taking repeated measurements, set this to True and update"
             " setpoints manually by calling `instr.chX.update_setpoints()`."),
            initial_value=False,
        )

        # Channels
        _channels = ChannelList(self,
                                "channels",
                                InfiniiumChannel,
                                snapshotable=False)
        for i in range(1, self.no_channels + 1):
            channel = InfiniiumChannel(self, f"chan{i}", i)
            _channels.append(channel)
            self.add_submodule(f"ch{i}", channel)
        self.add_submodule("channels", _channels.to_channel_tuple())

        # Functions
        _functions = ChannelList(self,
                                 "functions",
                                 InfiniiumFunction,
                                 snapshotable=False)
        for i in range(1, 16 + 1):
            function = InfiniiumFunction(self, f"func{i}", i)
            _functions.append(function)
            self.add_submodule(f"func{i}", function)
        # Have to call channel list "funcs" here as functions is a
        # reserved name in Instrument.
        self.add_submodule("funcs", _functions.to_channel_tuple())

        # Submodules
        meassubsys = UnboundMeasurement(self, "measure")
        self.add_submodule("measure", meassubsys)
Esempio n. 3
0
    def __init__(self, parent: Instrument, name: str, channel: int) -> None:
        """
        Args:
            parent: The Instrument instance to which the channel is
                to be attached.
            name: The name used in the DataSet
            channel: The channel number, either 1 or 2.
        """

        super().__init__(parent, name)

        self.channel = channel

        num_channels = self._parent.num_channels

        fg = 'function generator'

        if channel not in list(range(1, num_channels + 1)):
            raise ValueError('Illegal channel value.')

        self.add_parameter('state',
                           label='Channel {} state'.format(channel),
                           get_cmd='OUTPut{}:STATe?'.format(channel),
                           set_cmd='OUTPut{}:STATe {{}}'.format(channel),
                           vals=vals.Ints(0, 1),
                           get_parser=int)

        ##################################################
        # FGEN PARAMETERS

        # TODO: Setting high and low will change this parameter's value
        self.add_parameter(
            'fgen_amplitude',
            label='Channel {} {} amplitude'.format(channel, fg),
            get_cmd='FGEN:CHANnel{}:AMPLitude?'.format(channel),
            set_cmd='FGEN:CHANnel{}:AMPLitude {{}}'.format(channel),
            unit='V',
            vals=vals.Numbers(0, 0.5),
            get_parser=float)

        self.add_parameter(
            'fgen_offset',
            label='Channel {} {} offset'.format(channel, fg),
            get_cmd='FGEN:CHANnel{}:OFFSet?'.format(channel),
            set_cmd='FGEN:CHANnel{}:OFFSet {{}}'.format(channel),
            unit='V',
            vals=vals.Numbers(0, 0.250),  # depends on ampl.
            get_parser=float)

        self.add_parameter('fgen_frequency',
                           label='Channel {} {} frequency'.format(channel, fg),
                           get_cmd='FGEN:CHANnel{}:FREQuency?'.format(channel),
                           set_cmd=partial(self._set_fgfreq, channel),
                           unit='Hz',
                           get_parser=float)

        self.add_parameter(
            'fgen_dclevel',
            label='Channel {} {} DC level'.format(channel, fg),
            get_cmd='FGEN:CHANnel{}:DCLevel?'.format(channel),
            set_cmd='FGEN:CHANnel{}:DCLevel {{}}'.format(channel),
            unit='V',
            vals=vals.Numbers(-0.25, 0.25),
            get_parser=float)

        self.add_parameter('fgen_signalpath',
                           label='Channel {} {} signal path'.format(
                               channel, fg),
                           set_cmd='FGEN:CHANnel{}:PATH {{}}'.format(channel),
                           get_cmd='FGEN:CHANnel{}:PATH?'.format(channel),
                           val_mapping={
                               'direct': 'DIR',
                               'DCamplified': 'DCAM',
                               'AC': 'AC'
                           })

        self.add_parameter('fgen_period',
                           label='Channel {} {} period'.format(channel, fg),
                           get_cmd='FGEN:CHANnel{}:PERiod?'.format(channel),
                           unit='s',
                           get_parser=float)

        self.add_parameter('fgen_phase',
                           label='Channel {} {} phase'.format(channel, fg),
                           get_cmd='FGEN:CHANnel{}:PHASe?'.format(channel),
                           set_cmd='FGEN:CHANnel{}:PHASe {{}}'.format(channel),
                           unit='degrees',
                           vals=vals.Numbers(-180, 180),
                           get_parser=float)

        self.add_parameter(
            'fgen_symmetry',
            label='Channel {} {} symmetry'.format(channel, fg),
            set_cmd='FGEN:CHANnel{}:SYMMetry {{}}'.format(channel),
            get_cmd='FGEN:CHANnel{}:SYMMetry?'.format(channel),
            unit='%',
            vals=vals.Numbers(0, 100),
            get_parser=float)

        self.add_parameter('fgen_type',
                           label='Channel {} {} type'.format(channel, fg),
                           set_cmd='FGEN:CHANnel{}:TYPE {{}}'.format(channel),
                           get_cmd='FGEN:CHANnel{}:TYPE?'.format(channel),
                           val_mapping={
                               'SINE': 'SINE',
                               'SQUARE': 'SQU',
                               'TRIANGLE': 'TRI',
                               'NOISE': 'NOIS',
                               'DC': 'DC',
                               'GAUSSIAN': 'GAUSS',
                               'EXPONENTIALRISE': 'EXPR',
                               'EXPONENTIALDECAY': 'EXPD',
                               'NONE': 'NONE'
                           })

        ##################################################
        # AWG PARAMETERS

        # this command internally uses power in dBm
        # the manual claims that this command only works in AC mode
        # (OUTPut[n]:PATH is AC), but I've tested that it does what
        # one would expect in DIR mode.
        self.add_parameter(
            'awg_amplitude',
            label='Channel {} AWG peak-to-peak amplitude'.format(channel),
            set_cmd='SOURCe{}:VOLTage {{}}'.format(channel),
            get_cmd='SOURce{}:VOLTage?'.format(channel),
            unit='V',
            get_parser=float,
            vals=vals.Numbers(0.250, 0.500))

        # markers
        for mrk in range(1, 3):

            self.add_parameter(
                'marker{}_high'.format(mrk),
                label='Channel {} marker {} high level'.format(channel, mrk),
                set_cmd='SOURce{}:MARKer{}:VOLTage:HIGH {{}}'.format(
                    channel, mrk),
                get_cmd='SOURce{}:MARKer{}:VOLTage:HIGH?'.format(channel, mrk),
                unit='V',
                vals=vals.Numbers(-1.4, 1.4),
                get_parser=float)

            self.add_parameter(
                'marker{}_low'.format(mrk),
                label='Channel {} marker {} low level'.format(channel, mrk),
                set_cmd='SOURce{}:MARKer{}:VOLTage:LOW {{}}'.format(
                    channel, mrk),
                get_cmd='SOURce{}:MARKer{}:VOLTage:LOW?'.format(channel, mrk),
                unit='V',
                vals=vals.Numbers(-1.4, 1.4),
                get_parser=float)

            self.add_parameter(
                'marker{}_waitvalue'.format(mrk),
                label='Channel {} marker {} wait state'.format(channel, mrk),
                set_cmd='OUTPut{}:WVALue:MARKer{} {{}}'.format(channel, mrk),
                get_cmd='OUTPut{}:WVALue:MARKer{}?'.format(channel, mrk),
                vals=vals.Enum('FIRST', 'LOW', 'HIGH'))

        ##################################################
        # MISC.

        self.add_parameter(
            'resolution',
            label='Channel {} bit resolution'.format(channel),
            get_cmd='SOURce{}:DAC:RESolution?'.format(channel),
            set_cmd='SOURce{}:DAC:RESolution {{}}'.format(channel),
            vals=vals.Enum(8, 9, 10),
            get_parser=int,
            docstring=("""
                                      8 bit resolution allows for two
                                      markers, 9 bit resolution
                                      allows for one, and 10 bit
                                      does NOT allow for markers"""))
Esempio n. 4
0
    def __init__(self, name, address, **kwargs):
        super().__init__(name, address, terminator='\n', **kwargs)

        self.waveform = RSWaveformGenerator(self)

        self.add_parameter(name='clock',
                           label='Clock',
                           unit='Hz',
                           get_cmd=':SOUR:TSIG:CLOC?',
                           set_cmd=':SOUR:TSIG:CLOC {:.3f}',
                           get_parser=float,
                           vals=vals.Numbers(
                               1e3, 600e6))  # Actually 1kHz-300MHz, or 600MHz.
        self.add_parameter(name='amplitude',
                           label='Amplitude',
                           unit='V',
                           get_cmd='SOUR:OUTP:ANAL:BAL:AMPL?',
                           set_cmd='SOUR:OUTP:ANAL:BAL:AMPL {:.3f}V',
                           get_parser=float,
                           vals=vals.Numbers(0, 0.7))

        self.add_parameter('output',
                           label='Output',
                           get_cmd=':OUTP:STAT?',
                           set_cmd=':OUTP:STAT {}',
                           val_mapping=create_on_off_val_mapping(on_val='1',
                                                                 off_val='0'))
        self.add_parameter('source',
                           label='Baseband source',
                           get_cmd=':SOUR:STAT?',
                           set_cmd=':SOUR:STAT {}',
                           val_mapping=create_on_off_val_mapping(on_val='1',
                                                                 off_val='0'))
        self.add_parameter(
            'activeoutput',
            label='Active output',
            get_cmd=':OUTP:AOUT?',
            set_cmd=':OUTP:AOUT {}',
            vals=vals.Enum('BBO', 'DIG'))  # Ours only supports BBO, I think

        self.add_parameter('wvfile',
                           label='Waveform file',
                           get_cmd=':SOUR:WAV:SEL?',
                           set_cmd=':SOUR:WAV:SEL \'{}\'')

        self.add_parameter(
            'runmode',
            label='Trigger run mode',
            get_cmd=':SOUR:TRIG:MODE?',
            set_cmd=':SOUR:TRIG:MODE {}',
            vals=vals.Enum('CONT', 'SING',
                           'REPN'))  # Continuous, Single, or Repeat N times
        self.add_parameter(
            'repeatcount',
            label='Repeat count',
            get_cmd=':SOUR:TRIG:RCO?',
            set_cmd=':SOUR:TRIG:RCO {}',
            get_parser=int,
            vals=vals.Ints(
                1, 100))  # Up to 100 repetitions, only for REPN runmode
        self.add_parameter('triggersource',
                           label='Trigger source',
                           get_cmd=':SOUR:TRIG:SOUR?',
                           set_cmd=':SOUR:TRIG:SOUR {}',
                           vals=vals.Enum('MAN', 'EXT', 'BUS', 'AUTO'))
        # 'MAN'  trigger from front panel or bus
        # 'EXT'  trigger from back panel input
        # 'BUS'  trigger from remote bus (e.g. USB interface)
        # 'AUTO' triggers are sent repeatedly from the firmware

        self.add_function('reset', call_cmd='*RST')
        self.add_function('run_self_tests', call_cmd='*TST?')

        self.connect_message()
Esempio n. 5
0
    def __init__(self, parent: 'ANC300', name: str, axis: int,
                 sn: str) -> None:
        """Creates a new Anc300Axis class instance.
        
        The Attocube ANC300 piezo controller has up to 7 axis. Each of them are controlled
        by the same class.

        Args:
            parent: the internal QCoDeS name of the instrument this axis belongs to
            name: the internal QCoDeS name of the axis itself
            axis: the Index of the axis (1..7)
            sn: serial number of the axis controller to change some features

        Attributes:
            frequency: Set the frequency of the output signal. The maximum is restricted by the
                combination of output voltage and Capacitance of the piezo actuators.
            amplitude: Set the maximum level of the output signal.
            voltage: (Readonly) Reads the current stepping voltage.
            offset: Add a constant voltage to the output signal. Attention: the output level is
                only from 0 to 150 V.
            filter: Set the filter frequency of the internal low pass filter.
                For the ANM150 this attribute is not present.
                For the ANM200 and ANM300 this attribute has different allowed values.
            mode: Setting to a certain mode typically switches other functionalities off.
                'gnd': Setting to this mode diables all outputs and connects them to chassis mass.
                'inp': (Not for ANM150) In this mode, AC-IN and DC-IN can be enabled using the
                specific attributes. Setting to inp mode disables stepping and offset modes.
                'cap': Setting to cap mode starts a capacitance measurement. The axis returns to
                gnd mode afterwards. It is not needed to switch to gnd mode before.
                'stp': This enables stepping mode. AC-IN and DC-IN functionalities are not modified,
                while an offset function would be turned off.
                'off': This enables offset mode. AC-IN and DC-IN functionalities are not modified,
                while any stepping would be turned off.
                'stp+': This enables additive offset + stepping mode. Stepping waveforms are added
                to an offset. AC-IN and DC-IN functionalities are not modified.
                'stp-': This enables subtractive offset + stepping mode. Stepping waveforms are
                subtracted from an offset. AC-IN and DC-IN functionalities, are not modified.
            ac: When switching on the AC-IN feature, a voltage of up to 10 VAC can be added to the
                output (gain 1, no amplification) using the AC-IN BNC on the frontplate of the module.
            dc: When switching on the DC-IN feature, a voltage in the range -10 .. +10 V can be
                added to the output. The gain is 15.
            move: Start the movement with the given steps. For moving out use positive numbers and
                to move in use negative numbers.
            start: Start a continous movement in the given direction.
            triggerUp: Set/get input trigger up number on axis
            triggerDown: Set/get input trigger down number on axis
        """
        super().__init__(parent, name)
        self._axisnr = axis
        if sn != 'ANM200':
            self.add_parameter('frequency',
                               label='Set/get the stepping frequency',
                               get_cmd='getf {}'.format(axis),
                               set_cmd='setf {}'.format(axis) + ' {}',
                               vals=vals.Ints(1, 10000),
                               get_parser=int,
                               unit='Hz',
                               docstring="""
                               Set the frequency of the output signal. The maximum is restricted by
                               the combination of output voltage and Capacitance of the piezo actuators.
                               """)
        self.add_parameter(
            'amplitude',
            label='Set/get the stepping amplitude',
            get_cmd='getv {}'.format(axis),
            set_cmd='setv {}'.format(axis) + ' {}',
            vals=vals.Numbers(0.0, 150.0),
            get_parser=float,
            unit='V',
            docstring="Set the maximum level of the output signal.")
        self.add_parameter('voltage',
                           label='Set/get the stepping voltage',
                           get_cmd='geto {}'.format(axis),
                           set_cmd=False,
                           get_parser=float,
                           unit='V',
                           docstring="Reads the current stepping voltage.")
        self.add_parameter('offset',
                           label='Set/get the offset voltage',
                           get_cmd='geta {}'.format(axis),
                           set_cmd='seta {}'.format(axis) + ' {}',
                           vals=vals.Numbers(0.0, 150.0),
                           get_parser=float,
                           unit='V',
                           docstring="""
                           Add a constant voltage to the output signal.
                           Attention: the output level is only from 0 to 150 V.
                           """)
        if sn == 'ANM200':
            self.add_parameter(
                'filter',
                label='Set/get filter setting',
                get_cmd='getfil {}'.format(axis),
                set_cmd='setfil {}'.format(axis) + ' {}',
                vals=vals.Enum('1.6', '16', '160', '1600'),
                unit='Hz',
                docstring=
                "Set the filter frequency of the internal low pass filter.")
        if sn == 'ANM300':
            self.add_parameter(
                'filter',
                label='Set/get filter setting',
                get_cmd='getfil {}'.format(axis),
                set_cmd='setfil {}'.format(axis) + ' {}',
                vals=vals.Enum('off', '16', '160'),
                unit='Hz',
                docstring=
                "Set the filter frequency of the internal low pass filter.")
        if sn == 'ANM150':
            mode_vals = ['gnd', 'cap', 'stp', 'off', 'stp+', 'stp-']
        elif sn == 'ANM200':
            mode_vals = ['gnd', 'cap', 'stp', 'off', 'stp+', 'stp-', 'inp']
        else:  # ANM300
            mode_vals = ['gnd', 'cap', 'stp', 'off', 'stp+', 'stp-', 'inp']
        mode_docs = """
                    'gnd': Setting to this mode diables all outputs and connects them to chassis mass.
                    'cap': Setting to cap mode starts a capacitance measurement. The axis returns to
                           gnd mode afterwards. It is not needed to switch to gnd mode before.
                    'stp': This enables stepping mode. AC-IN and DC-IN functionalities are not
                           modified, while an offset function would be turned off.
                    'off': This enables offset mode. AC-IN and DC-IN functionalities are not
                           modified, while any stepping would be turned off.
                    'stp+': This enables additive offset + stepping mode. Stepping waveforms are
                            added to an offset. AC-IN and DC-IN functionalities are not modified.
                    'stp-': This enables subtractive offset + stepping mode. Stepping waveforms are
                            subtracted from an offset. AC-IN and DC-IN functionalities, are not modified.
                    """
        if 'inp' in mode_vals:
            mode_docs += """
                         'inp': In this mode, AC-IN and DC-IN can be enabled using the specific
                         attributes. Setting to inp mode disables stepping and offset modes.
                         """
        self.add_parameter('mode',
                           label='Set/get mode',
                           get_cmd='getm {}'.format(axis),
                           set_cmd='setm {}'.format(axis) + ' {}',
                           vals=vals.Enum(*mode_vals),
                           docstring="""
                           Setting to a certain mode typically switches other functionalities off.
                           Especially, there are the following modes:
                           """ + mode_docs)
        if sn != 'ANM150':
            self.add_parameter('ac',
                               label='Set/get status of AC-IN input',
                               get_cmd='getaci {}'.format(axis),
                               set_cmd='setaci {}'.format(axis) + ' {}',
                               vals=vals.Enum('off', 'on'),
                               docstring="""
                               When switching on the AC-IN feature, a voltage of up to 10 VAC
                               can be added to the output (gain 1, no amplification) using
                               the AC-IN BNC on the frontplate of the module.
                               """)
            self.add_parameter('dc',
                               label='Set/get status of DC-IN input',
                               get_cmd='getdci {}'.format(axis),
                               set_cmd='setdci {}'.format(axis) + ' {}',
                               vals=vals.Enum('off', 'on'),
                               docstring="""
                               When switching on the DC-IN feature, a voltage in the range
                               -10 .. +10 V can be added to the output. The gain is 15.
                               """)
        self.add_parameter('move',
                           label='Move steps',
                           get_cmd=False,
                           set_cmd=self._domove,
                           vals=vals.Ints(),
                           docstring="""
                           Start the movement with the given steps. For moving out
                           use positive numbers and to move in use negative numbers.
                           """)
        self.add_parameter(
            'start',
            label='Move continously',
            get_cmd=False,
            set_cmd=self._contmove,
            vals=vals.Enum('up', 'down'),
            docstring="Start a continous movement in the given direction.")
        self.add_parameter('triggerUp',
                           label='Set/get input trigger up number on axis',
                           get_cmd='gettu {}'.format(axis),
                           set_cmd='settu {}'.format(axis) + ' {}',
                           vals=vals.Enum('off', '1', '2', '3', '4', '5', '6',
                                          '7'),
                           docstring="Set/get input trigger up number on axis")
        self.add_parameter(
            'triggerDown',
            label='Set/get input trigger down numbers on axis',
            get_cmd='gettd {}'.format(axis),
            set_cmd='settd {}'.format(axis) + ' {}',
            vals=vals.Enum('off', '1', '2', '3', '4', '5', '6', '7'),
            docstring="Set/get input trigger down number on axis")
Esempio n. 6
0
    def __init__(self,
                 name,
                 address,
                 reset=False,
                 clock=1e9,
                 numpoints=1000,
                 **kw):
        '''
        Initializes the AWG520.

        Args:
            name (str)    : name of the instrument
            address (str) : GPIB address (Note: 520 cannot be controlled
                               via ethernet)
            reset (bool)     : resets to default values, default=false
            numpoints (int)  : sets the number of datapoints

        Output:
            None
        '''
        super().__init__(name, address, **kw)

        self._address = address
        self._values = {}
        self._values['files'] = {}
        self._clock = clock
        self._numpoints = numpoints
        self._fname = ''

        self.add_function('reset', call_cmd='*RST')
        self.add_parameter('state', get_cmd=self.get_state)

        # Add parameters
        self.add_parameter('trigger_mode',
                           get_cmd='AWGC:RMOD?',
                           set_cmd='AWGC:RMOD ' + '{}',
                           vals=vals.Enum('CONT', 'TRIG', 'ENH', 'GAT'))
        self.add_parameter('trigger_impedance',
                           unit='Ohm',
                           label='Trigger impedance (Ohm)',
                           get_cmd='TRIG:IMP?',
                           set_cmd='TRIG:IMP ' + '{}',
                           vals=vals.Enum(50, 1000),
                           get_parser=float)
        self.add_parameter('trigger_level',
                           unit='V',
                           label='Trigger level (V)',
                           get_cmd='TRIG:LEV?',
                           set_cmd='TRIG:LEV ' + '{:.3f}',
                           vals=vals.Numbers(-5, 5),
                           get_parser=float)

        self.add_parameter('clock_freq',
                           label='Clock frequency (Hz)',
                           get_cmd='SOUR:FREQ?',
                           set_cmd='SOUR:FREQ ' + '{}',
                           vals=vals.Numbers(1e6, 1e9),
                           get_parser=float)
        # Todo check if max freq is 1.2 GHz for the AWG 520 aswell
        self.add_parameter('numpoints',
                           label='Number of datapoints per wave',
                           get_cmd=self._do_get_numpoints,
                           set_cmd=self._do_set_numpoints,
                           vals=vals.Ints(100, int(1e9)))

        for ch in [1, 2]:
            amp_cmd = 'SOUR{}:VOLT:LEV:IMM:AMPL'.format(ch)
            offset_cmd = 'SOUR{}:VOLT:LEV:IMM:OFFS'.format(ch)

            self.add_parameter('ch{}_filename'.format(ch),
                               set_cmd=self._gen_ch_set_func(
                                   self._do_set_filename, ch),
                               vals=vals.Anything())
            self.add_parameter('ch{}_amp'.format(ch),
                               label='Amplitude channel {} (V)'.format(ch),
                               unit='V',
                               get_cmd=amp_cmd + '?',
                               set_cmd=amp_cmd + ' {:.6f}',
                               vals=vals.Numbers(0.02, 2.0),
                               get_parser=float)

            self.add_parameter('ch{}_offset'.format(ch),
                               label='Offset channel {} (V)'.format(ch),
                               unit='V',
                               get_cmd=offset_cmd + '?',
                               set_cmd=offset_cmd + ' {:.3f}',
                               vals=vals.Numbers(-1.0, 1.0),
                               get_parser=float)
            self.add_parameter('ch{}_status'.format(ch),
                               get_cmd='OUTP{}?'.format(ch),
                               set_cmd='OUTP{}'.format(ch) + ' {}',
                               vals=vals.Enum('ON', 'OFF'),
                               get_parser=float)

            for j in [1, 2]:
                # TODO: check that 520 does not have marker delay feature
                # m_del_cmd = 'SOUR{}:MARK{}:DEL'.format(ch, j)
                m_high_cmd = 'SOUR{}:MARK{}:VOLT:LEV:IMM:HIGH'.format(ch, j)
                m_low_cmd = 'SOUR{}:MARK{}:VOLT:LEV:IMM:LOW'.format(ch, j)

                self.add_parameter(
                    'ch{}_m{}_high'.format(ch, j),
                    label='Channel {} Marker {} high level (V)'.format(ch, j),
                    get_cmd=m_high_cmd + '?',
                    set_cmd=m_high_cmd + ' {:.3f}',
                    vals=vals.Numbers(-2., 2.),
                    get_parser=float)
                self.add_parameter(
                    'ch{}_m{}_low'.format(ch, j),
                    label='Channel {} Marker {} low level (V)'.format(ch, j),
                    get_cmd=m_low_cmd + '?',
                    set_cmd=m_low_cmd + ' {:.3f}',
                    vals=vals.Numbers(-2., 2.),
                    get_parser=float)

        # Add functions
        if reset:
            self.reset()
        else:
            self.get_all()
        self.connect_message()
Esempio n. 7
0
    def __init__(self, name, **kwargs):

        super().__init__(name=name, **kwargs)

        self.add_parameter(name='power',
                           label='Power',
                           unit='dBm',
                           parameter_class=ManualParameter,
                           vals=vals.Numbers(-150, 25))

        self.add_parameter(name='avg',
                           label='Averages',
                           unit='',
                           parameter_class=ManualParameter,
                           vals=vals.Numbers(1, 1000))

        self.add_parameter(name='average_mode',
                           parameter_class=ManualParameter,
                           vals=vals.Enum('auto', 'flatten', 'reduce',
                                          'moving'))

        self.add_parameter(name='average_state',
                           parameter_class=ManualParameter,
                           vals=vals.OnOff())

        self.add_parameter(name='bandwidth',
                           label='Bandwidth',
                           unit='Hz',
                           parameter_class=ManualParameter,
                           vals=vals.Numbers(1, 1e6))

        self.add_parameter(name='center_frequency',
                           unit='Hz',
                           parameter_class=ManualParameter,
                           vals=vals.Numbers(100e3, 20e9))

        self.add_parameter(name='span_frequency',
                           unit='Hz',
                           parameter_class=ManualParameter,
                           vals=vals.Numbers(0, 20e9))

        self.add_parameter(name='start_frequency',
                           unit='Hz',
                           parameter_class=ManualParameter,
                           vals=vals.Numbers(100e3, 20e9))

        self.add_parameter(name='stop_frequency',
                           unit='Hz',
                           parameter_class=ManualParameter,
                           vals=vals.Numbers(100e3, 20e9))

        self.add_parameter(name='number_sweeps_all',
                           parameter_class=ManualParameter,
                           vals=vals.Ints(1, 100000))

        self.add_parameter(name='npts',
                           parameter_class=ManualParameter,
                           vals=vals.Ints(1, 100001))

        self.add_parameter(name='min_sweep_time',
                           parameter_class=ManualParameter,
                           vals=vals.OnOff())

        self.add_parameter(name='sweep_time',
                           parameter_class=ManualParameter,
                           vals=vals.Numbers(0, 1e5))

        self.add_parameter(name='sweep_type',
                           parameter_class=ManualParameter,
                           vals=vals.Enum('lin', 'linear', 'log',
                                          'logarithmic', 'pow', 'power', 'cw',
                                          'poin', 'point', 'segm', 'segment'))
Esempio n. 8
0
    def __init__(self,
                 name: str,
                 address: str,
                 timeout: float = 20,
                 **kwargs: Any):
        """
        Initialises the oscilloscope.

        Args:
            name: Name of the instrument used by QCoDeS
            address: Instrument address as used by VISA
            timeout: visa timeout, in secs.
        """

        super().__init__(name,
                         address,
                         timeout=timeout,
                         terminator='\n',
                         **kwargs)
        self.connect_message()

        # Scope trace boolean
        self.trace_ready = False

        # switch the response header off,
        # else none of our parameters will work
        self.write(':SYSTem:HEADer OFF')

        # functions

        # general parameters

        # the parameters are in the same order as the front panel.
        # Beware, he list of implemented parameters is not complete. Refer to
        # the manual (Infiniium prog guide) for an equally infiniium list.

        # time base

        # timebase_scale is commented out for same reason as channel scale
        # use range instead
        # self.add_parameter('timebase_scale',
        #                    label='Scale of the one time devision',
        #                    unit='s/Div',
        #                    get_cmd=':TIMebase:SCALe?',
        #                    set_cmd=':TIMebase:SCALe {}',
        #                    vals=Numbers(),
        #                    get_parser=float,
        #                    )

        self.add_parameter(
            'timebase_range',
            label='Range of the time axis',
            unit='s',
            get_cmd=':TIMebase:RANGe?',
            set_cmd=':TIMebase:RANGe {}',
            vals=Numbers(5e-12, 20),
            get_parser=float,
        )
        self.add_parameter(
            'timebase_position',
            label='Offset of the time axis',
            unit='s',
            get_cmd=':TIMebase:POSition?',
            set_cmd=':TIMebase:POSition {}',
            vals=Numbers(),
            get_parser=float,
        )

        self.add_parameter('timebase_roll_enabled',
                           label='Is rolling mode enabled',
                           get_cmd=':TIMebase:ROLL:ENABLE?',
                           set_cmd=':TIMebase:ROLL:ENABLE {}',
                           val_mapping={
                               True: 1,
                               False: 0
                           })

        # trigger
        self.add_parameter('trigger_enabled',
                           label='Is trigger enabled',
                           get_cmd=':TRIGger:AND:ENABLe?',
                           set_cmd=':TRIGger:AND:ENABLe {}',
                           val_mapping={
                               True: 1,
                               False: 0
                           })

        self.add_parameter(
            'trigger_edge_source',
            label='Source channel for the edge trigger',
            get_cmd=':TRIGger:EDGE:SOURce?',
            set_cmd=':TRIGger:EDGE:SOURce {}',
            vals=Enum(*([f'CHANnel{i}' for i in range(1, 4 + 1)] +
                        [f'CHAN{i}' for i in range(1, 4 + 1)] +
                        [f'DIGital{i}' for i in range(16 + 1)] +
                        [f'DIG{i}' for i in range(16 + 1)] +
                        ['AUX', 'LINE'])))  # add enum for case insesitivity
        self.add_parameter('trigger_edge_slope',
                           label='slope of the edge trigger',
                           get_cmd=':TRIGger:EDGE:SLOPe?',
                           set_cmd=':TRIGger:EDGE:SLOPe {}',
                           vals=Enum('positive', 'negative', 'neither'))
        self.add_parameter(
            'trigger_level_aux',
            label='Tirgger level AUX',
            unit='V',
            get_cmd=':TRIGger:LEVel? AUX',
            set_cmd=':TRIGger:LEVel AUX,{}',
            get_parser=float,
            vals=Numbers(),
        )
        # Aquisition
        # If sample points, rate and timebase_scale are set in an
        # incomensurate way, the scope only displays part of the waveform
        self.add_parameter('acquire_points',
                           label='sample points',
                           get_cmd='ACQ:POIN?',
                           get_parser=int,
                           set_cmd=self._cmd_and_invalidate('ACQ:POIN {}'),
                           unit='pts',
                           vals=vals.Numbers(min_value=1, max_value=100e6))

        self.add_parameter('acquire_sample_rate',
                           label='sample rate',
                           get_cmd='ACQ:SRAT?',
                           set_cmd=self._cmd_and_invalidate('ACQ:SRAT {}'),
                           unit='Sa/s',
                           get_parser=float)

        # this parameter gets used internally for data aquisition. For now it
        # should not be used manually
        self.add_parameter('data_source',
                           label='Waveform Data source',
                           get_cmd=':WAVeform:SOURce?',
                           set_cmd=':WAVeform:SOURce {}',
                           vals = Enum( *(\
                                [f'CHANnel{i}' for i in range(1, 4+1)]+\
                                [f'CHAN{i}' for i in range(1, 4+1)]+\
                                [f'DIFF{i}' for i in range(1, 2+1)]+\
                                [f'COMMonmode{i}' for i in range(3, 4+1)]+\
                                [f'COMM{i}' for i in range(3, 4+1)]+\
                                [f'FUNCtion{i}' for i in range(1, 16+1)]+\
                                [f'FUNC{i}' for i in range(1, 16+1)]+\
                                [f'WMEMory{i}' for i in range(1, 4+1)]+\
                                [f'WMEM{i}' for i in range(1, 4+1)]+\
                                [f'BUS{i}' for i in range(1, 4+1)]+\
                                ['HISTogram', 'HIST', 'CLOCK']+\
                                ['MTRend', 'MTR']))
                           )

        # TODO: implement as array parameter to allow for setting the other filter
        # ratios
        self.add_parameter(
            'acquire_interpolate',
            get_cmd=':ACQuire:INTerpolate?',
            set_cmd=self._cmd_and_invalidate(':ACQuire:INTerpolate {}'),
            val_mapping={
                True: 1,
                False: 0
            })

        self.add_parameter('acquire_mode',
                           label='Acquisition mode',
                           get_cmd='ACQuire:MODE?',
                           set_cmd='ACQuire:MODE {}',
                           vals=Enum('ETIMe', 'RTIMe', 'PDETect',
                                     'HRESolution', 'SEGMented', 'SEGPdetect',
                                     'SEGHres'))

        self.add_parameter('acquire_timespan',
                            get_cmd=(lambda: self.acquire_points.get_latest() \
                                            /self.acquire_sample_rate.get_latest()),
                            unit='s',
                            get_parser=float
                            )

        # time of the first point
        self.add_parameter('waveform_xorigin',
                           get_cmd='WAVeform:XORigin?',
                           unit='s',
                           get_parser=float)

        self.add_parameter('data_format',
                           set_cmd='SAV:WAV:FORM {}',
                           val_mapping={
                               'csv': 'CSV',
                               'binary': 'BIN',
                               'asciixy': 'ASC'
                           },
                           docstring=("Set the format for saving "
                                      "files using save_data function"))
        # Channels
        channels = ChannelList(self,
                               "Channels",
                               InfiniiumChannel,
                               snapshotable=False)

        for i in range(1, 5):
            channel = InfiniiumChannel(self, f'chan{i}', i)
            channels.append(channel)
            self.add_submodule(f'ch{i}', channel)
        channels.lock()
        self.add_submodule('channels', channels)

        # Submodules
        meassubsys = MeasurementSubsystem(self, 'measure')
        self.add_submodule('measure', meassubsys)
    def __init__(self, name, address, **kwargs):
        super().__init__(name, address, terminator='\n', **kwargs)

        self.add_parameter(name='frequency',
                           label='Frequency',
                           unit='Hz',
                           get_cmd='SOUR:FREQ?',
                           set_cmd='SOUR:FREQ {:.2f}',
                           get_parser=float,
                           vals=vals.Numbers(1e6, 20e9))
        self.add_parameter(name='phase',
                           label='Phase',
                           unit='deg',
                           get_cmd='SOUR:PHAS?',
                           set_cmd='SOUR:PHAS {:.2f}',
                           get_parser=float,
                           vals=vals.Numbers(0, 360))
        self.add_parameter(name='power',
                           label='Power',
                           unit='dBm',
                           get_cmd='SOUR:POW?',
                           set_cmd='SOUR:POW {:.2f}',
                           get_parser=float,
                           vals=vals.Numbers(-120, 25))
        self.add_parameter('status',
                           label='RF Output',
                           get_cmd=':OUTP:STAT?',
                           set_cmd=':OUTP:STAT {}',
                           get_parser=self.get_parser_on_off,
                           set_parser=self.set_parser_on_off)
        self.add_parameter('IQ_state',
                           label='IQ Modulation',
                           get_cmd=':IQ:STAT?',
                           set_cmd=':IQ:STAT {}',
                           get_parser=self.get_parser_on_off,
                           set_parser=self.set_parser_on_off)
        self.add_parameter('pulsemod_state',
                           label='Pulse Modulation',
                           get_cmd=':SOUR:PULM:STAT?',
                           set_cmd=':SOUR:PULM:STAT {}',
                           get_parser=self.get_parser_on_off,
                           set_parser=self.set_parser_on_off)
        self.add_parameter('pulsemod_source',
                           label='Pulse Modulation Source',
                           get_cmd='SOUR:PULM:SOUR?',
                           set_cmd='SOUR:PULM:SOUR {}',
                           vals=vals.Enum('INT', 'EXT', 'int', 'ext'))
        self.add_parameter('ref_osc_source',
                           label='Reference Oscillator Source',
                           get_cmd='SOUR:ROSC:SOUR?',
                           set_cmd='SOUR:ROSC:SOUR {}',
                           vals=vals.Enum('INT', 'EXT', 'int', 'ext'))
        # Define LO source INT/EXT (Only with K-90 option)
        self.add_parameter('LO_source',
                           label='Local Oscillator Source',
                           get_cmd='SOUR:LOSC:SOUR?',
                           set_cmd='SOUR:LOSC:SOUR {}',
                           vals=vals.Enum('INT', 'EXT', 'int', 'ext'))
        # Define output at REF/LO Output (Only with K-90 option)
        self.add_parameter('ref_LO_out',
                           label='REF/LO Output',
                           get_cmd='CONN:REFL:OUTP?',
                           set_cmd='CONN:REFL:OUTP {}',
                           vals=vals.Enum('REF', 'LO', 'OFF', 'ref', 'lo',
                                          'off', 'Off'))
        # Frequency mw_source outputs when used as a reference
        self.add_parameter('ref_osc_output_freq',
                           label='Reference Oscillator Output Frequency',
                           get_cmd='SOUR:ROSC:OUTP:FREQ?',
                           set_cmd='SOUR:ROSC:OUTP:FREQ {}',
                           vals=vals.Enum('10MHz', '100MHz', '1000MHz'))
        # Frequency of the external reference mw_source uses
        self.add_parameter('ref_osc_external_freq',
                           label='Reference Oscillator External Frequency',
                           get_cmd='SOUR:ROSC:EXT:FREQ?',
                           set_cmd='SOUR:ROSC:EXT:FREQ {}',
                           vals=vals.Enum('10MHz', '100MHz', '1000MHz'))

        # IQ impairments
        self.add_parameter('IQ_impairments',
                           label='IQ Impairments',
                           get_cmd=':SOUR:IQ:IMP:STAT?',
                           set_cmd=':SOUR:IQ:IMP:STAT {}',
                           get_parser=self.get_parser_on_off,
                           set_parser=self.set_parser_on_off)
        self.add_parameter('I_offset',
                           label='I Offset',
                           get_cmd='SOUR:IQ:IMP:LEAK:I?',
                           set_cmd='SOUR:IQ:IMP:LEAK:I {:.2f}',
                           get_parser=float,
                           vals=vals.Numbers(-10, 10))
        self.add_parameter('Q_offset',
                           label='Q Offset',
                           get_cmd='SOUR:IQ:IMP:LEAK:Q?',
                           set_cmd='SOUR:IQ:IMP:LEAK:Q {:.2f}',
                           get_parser=float,
                           vals=vals.Numbers(-10, 10))
        self.add_parameter('IQ_gain_imbalance',
                           label='IQ Gain Imbalance',
                           get_cmd='SOUR:IQ:IMP:IQR?',
                           set_cmd='SOUR:IQ:IMP:IQR {:.2f}',
                           get_parser=float,
                           vals=vals.Numbers(-1, 1))
        self.add_parameter('IQ_angle',
                           label='IQ Angle Offset',
                           get_cmd='SOUR:IQ:IMP:QUAD?',
                           set_cmd='SOUR:IQ:IMP:QUAD {:.2f}',
                           get_parser=float,
                           vals=vals.Numbers(-8, 8))

        self.add_function('reset', call_cmd='*RST')
        self.add_function('run_self_tests', call_cmd='*TST?')

        self.connect_message()
Esempio n. 10
0
    def __init__(self,
                 name: str,
                 address: str,
                 step_attenuator: Optional[bool] = None,
                 terminator: str = '\n',
                 **kwargs: Any) -> None:
        super().__init__(name, address, terminator=terminator, **kwargs)

        if step_attenuator is not None:
            warnings.warn("step_attenuator argument to E8527D is deprecated "
                          "and has no effect. It will be removed in the "
                          "future.")

        # Query installed options
        self._options = self.ask_raw('DIAG:CPU:INFO:OPT:DET?')

        # Determine installed frequency option
        frequency_option = None
        for f_option in ['513', '520', '521', '532', '540', '550', '567']:
            if f_option in self._options:
                frequency_option = f_option
        if frequency_option is None:
            raise RuntimeError('Could not determine the frequency option')

        # convert installed frequency option to frequency ranges, based on:
        # https://www.keysight.com/us/en/assets/7018-01233/configuration-guides
        # /5989-1325.pdf
        # the frequency range here is the max range and not the specified
        # (calibrated) one
        f_options_dict = {
            "513": (100e3, 13e9),
            "520": (100e3, 20e9),
            "521": (10e6, 20e9),
            "532": (100e3, 31.8e9),
            "540": (100e3, 40e9),
            "550": (100e3, 50e9),
            "567": (100e3, 70e9)
        }

        # assign min and max frequencies
        self._min_freq: float
        self._max_freq: float
        self._min_freq, self._max_freq = f_options_dict[frequency_option]

        # Based on installed frequency option and presence/absence of step
        # attenuator (option '1E1') determine power range based on:
        # https://www.keysight.com/us/en/assets/7018-01211/data-sheets
        # /5989-0698.pdf

        # assign min and max powers
        self._min_power: float
        self._max_power: float

        if '1E1' in self._options:
            if frequency_option in ['513', '520', '521', '532', '540']:
                self._min_power = -135
                self._max_power = 10
            else:
                self._min_power = -110
                self._max_power = 5
        else:
            # default minimal power is -20 dBm
            if frequency_option in ['513', '520', '521', '532', '540']:
                self._min_power = -20
                self._max_power = 10
            else:
                self._min_power = -20
                self._max_power = 5

        self.add_parameter(name='frequency',
                           label='Frequency',
                           unit='Hz',
                           get_cmd='FREQ:CW?',
                           set_cmd='FREQ:CW' + ' {:.4f}',
                           get_parser=float,
                           set_parser=float,
                           vals=vals.Numbers(self._min_freq, self._max_freq))

        self.add_parameter(name='phase',
                           label='Phase',
                           unit='deg',
                           get_cmd='PHASE?',
                           set_cmd='PHASE' + ' {:.8f}',
                           get_parser=self.rad_to_deg,
                           set_parser=self.deg_to_rad,
                           vals=vals.Numbers(-180, 180))

        self.add_parameter(name='power',
                           label='Power',
                           unit='dBm',
                           get_cmd='POW:AMPL?',
                           set_cmd='POW:AMPL' + ' {:.4f}',
                           get_parser=float,
                           set_parser=float,
                           vals=vals.Numbers(self._min_power, self._max_power))

        self.add_parameter('status',
                           get_cmd=':OUTP?',
                           set_cmd='OUTP {}',
                           val_mapping=create_on_off_val_mapping(on_val='1',
                                                                 off_val='0'))

        self.connect_message()
Esempio n. 11
0
 def set_R_Attn(self, R_bias, Attn):  
     self._Attn = Attn
     self._R_bias = R_bias
     self.I_to_V = lambda i: i*self._R_bias*self._Attn
     self.I.vals = vals.Numbers(-4/self._R_bias/self._Attn, 4/self._R_bias/self._Attn)
Esempio n. 12
0
    def __init__(self, name, address=None, **kwargs):
        '''
        Initializes the Keysight_P9374A, and communicates with the wrapper.

        Input:
          name (string)    : name of the instrument
          address (string) : GPIB address
          reset (bool)     : resets to default values, default=False
        '''
        if address == None:
            raise Exception('TCP IP address needed')
        logging.info(__name__ + ' : Initializing instrument Keysight PNA')

        super().__init__(name, address, terminator='\n', **kwargs)

        # Add in parameters
        self.add_parameter('fstart',
                           get_cmd=':SENS1:FREQ:STAR?',
                           set_cmd=':SENS1:FREQ:STAR {}',
                           vals=vals.Numbers(),
                           get_parser=float,
                           unit='Hz')
        self.add_parameter('fstop',
                           get_cmd=':SENS1:FREQ:STOP?',
                           set_cmd=':SENS1:FREQ:STOP {}',
                           vals=vals.Numbers(),
                           get_parser=float,
                           unit='Hz')
        self.add_parameter('fcenter',
                           get_cmd=':SENS1:FREQ:CENT?',
                           set_cmd=':SENS1:FREQ:CENT {}',
                           vals=vals.Numbers(),
                           get_parser=float,
                           unit='Hz')
        self.add_parameter('fspan',
                           get_cmd=':SENS1:FREQ:SPAN?',
                           set_cmd=':SENS1:FREQ:SPAN {}',
                           vals=vals.Numbers(),
                           get_parser=float,
                           unit='Hz')

        self.add_parameter('rfout',
                           get_cmd=':OUTP?',
                           set_cmd=':OUTP {}',
                           vals=vals.Ints(0, 1),
                           get_parser=int)

        self.add_parameter('num_points',
                           get_cmd=':SENS1:SWE:POIN?',
                           set_cmd=':SENS1:SWE:POIN {}',
                           vals=vals.Ints(1, 1601),
                           get_parser=int)
        self.add_parameter('ifbw',
                           get_cmd=':SENS1:BWID?',
                           set_cmd=':SENS1:BWID {}',
                           vals=vals.Numbers(10, 1.5e6),
                           get_parser=float)
        self.add_parameter('power',
                           get_cmd=":SOUR1:POW?",
                           set_cmd=":SOUR1:POW {}",
                           unit='dBm',
                           get_parser=float,
                           vals=vals.Numbers(-85, 10))
        self.add_parameter('power_start',
                           get_cmd=':SOUR1:POW:STAR?',
                           set_cmd=':SOUR1:POW:STAR {}',
                           unit='dBm',
                           get_parser=float,
                           vals=vals.Numbers(-85, 10))
        self.add_parameter('power_stop',
                           get_cmd=':SOUR:POW:STOP?',
                           set_cmd=':SOUR1:POW:STOP {}',
                           unit='dBm',
                           get_parser=float,
                           vals=vals.Numbers(-85, 20)),
        self.add_parameter('averaging',
                           get_cmd=':SENS1:AVER?',
                           set_cmd=':SENS1:AVER {}',
                           get_parser=int,
                           vals=vals.Ints(0, 1))
        self.add_parameter('average_trigger',
                           get_cmd=':TRIG:AVER?',
                           set_cmd=':TRIG:AVER {}',
                           get_parser=int,
                           vals=vals.Ints(0, 1))
        self.add_parameter('avgnum',
                           get_cmd=':SENS1:AVER:COUN?',
                           set_cmd=':SENS1:AVER:COUN {}',
                           vals=vals.Ints(1),
                           get_parser=int)
        self.add_parameter('phase_offset',
                           get_cmd=':CALC1:CORR:OFFS:PHAS?',
                           set_cmd=':CALC1:CORR:OFFS:PHAS {}',
                           get_parser=float,
                           vals=vals.Numbers())
        self.add_parameter('electrical_delay',
                           get_cmd='CALC1:CORR:EDEL:TIME?',
                           set_cmd='CALC1:CORR:EDEL:TIME {}',
                           unit='s',
                           get_parser=float,
                           vals=vals.Numbers())
        #TODO: Set trg sources
        self.add_parameter('trigger_source',
                           get_cmd='TRIG:SOUR?',
                           set_cmd='TRIG:SOUR {}',
                           vals=vals.Enum('INT', 'EXT', 'MAN', 'BUS'))
        self.add_parameter('trform',
                           get_cmd=':CALC1:FORM?',
                           set_cmd=':CALC1:FORM {}',
                           vals=vals.Enum(
                               'MLOG',
                               'PHAS',
                               'GDEL',
                               'SCOM',
                               'SMIT',
                               'SADM',
                               'POL',
                               'MLIN',
                               'SWR',
                               'REAL',
                               'IMAG',
                               'UPH',
                               'PPH',
                               'SLIN',
                               'SLOG',
                           ))

        self.add_parameter('math',
                           get_cmd=':CALC1:MATH:FUNC?',
                           set_cmd=':CALC1:MATH:FUNC {}',
                           vals=vals.Enum('ADD', 'SUBT', 'DIV', 'MULT',
                                          'NORM'))
        self.add_parameter('sweep_type',
                           get_cmd=':SENS1:SWE:TYPE?',
                           set_cmd=':SENS1:SWE:TYPE {}',
                           vals=vals.Enum('LIN', 'LOG', 'SEGM', 'POW'))
        self.add_parameter('correction',
                           get_cmd=':SENS1:CORR:STAT?',
                           set_cmd=':SENS1:CORR:STAT {}',
                           get_parser=int)
        self.add_parameter('smoothing',
                           get_cmd=':CALC1:SMO:STAT?',
                           set_cmd=':CALC1:SMO:STAT {}',
                           get_parser=float)
        self.add_parameter(
            'sweep_time',
            get_cmd=':SENS1:SWE:TIME?',
            set_cmd=
            None,  #generally just adjust ifbw and number of pts to change it,
            get_parser=float,
            unit='s')
        self.write('CALC1:PAR:MNUM 1'
                   )  #sets the active msmt to the first channel/trace
        self.connect_message()
Esempio n. 13
0
    def __init__(self, parent, name, channel, ch_range, ovp_range, ocp_range):
        super().__init__(parent, name)

        self.vmax = ch_range[0]
        self.imax = ch_range[1]
        self.ovp_range = ovp_range
        self.ocp_range = ocp_range

        select_cmd = ":INSTrument:NSELect {};".format(channel)
        strstrip = lambda s: str(s).strip()

        self.add_parameter("set_voltage",
                           label='Target voltage output',
                           set_cmd="{} :SOURce:VOLTage:LEVel:IMMediate:AMPLitude {}".format(
                               select_cmd, '{}'),
                           get_cmd="{} :SOURce:VOLTage:LEVel:IMMediate:AMPLitude?".format(
                               select_cmd),
                           get_parser=float,
                           unit='V',
                           vals=vals.Numbers(min(0, self.vmax), max(0, self.vmax))
                          )
        self.add_parameter("set_current",
                           label='Target current output',
                           set_cmd="{} :SOURce:CURRent:LEVel:IMMediate:AMPLitude {}".format(
                               select_cmd, '{}'),
                           get_cmd="{} :SOURce:CURRent:LEVel:IMMediate:AMPLitude?".format(
                               select_cmd),
                           get_parser=float,
                           unit='A',
                           vals=vals.Numbers(0, self.imax)
                           )
        self.add_parameter('state',
                           label='Output enabled',
                           set_cmd='{} :OUTPut:STATe {}'.format(select_cmd, '{}'),
                           get_cmd='{} :OUTPut:STATe?'.format(select_cmd),
                           get_parser=strstrip,
                           vals=vals.OnOff()
                           )
        self.add_parameter('mode',
                           label='Get the output mode',
                           get_cmd='{} :OUTPut:MODE?'.format(select_cmd),
                           get_parser=strstrip,
                           val_mapping={'ConstantVoltage': 'CV',
                                        'ConstantCurrent': 'CC',
                                        'Unregulated': 'UR'}
                          )
        self.add_parameter("voltage",
                           label='Measured voltage',
                           get_cmd="{} :MEASure:VOLTage:DC?".format(
                               select_cmd),
                           get_parser=float,
                           unit='V',
                          )
        self.add_parameter("current",
                           label='Measured current',
                           get_cmd="{} :MEASure:CURRent:DC?".format(
                               select_cmd),
                           get_parser=float,
                           unit='A',
                           )
        self.add_parameter("power",
                           label='Measured power',
                           get_cmd="{} :MEASure:POWer?".format(
                               select_cmd),
                           get_parser=float,
                           unit='W',
                           )
        self.add_parameter("ovp_value",
                           label='Over Voltage Protection value',
                           set_cmd="{} :VOLTage:PROTection:LEVel {}".format(
                               select_cmd, '{}'),
                           get_cmd="{} :VOLTage:PROTection:LEVel?".format(
                               select_cmd),
                           get_parser=float,
                           unit='V',
                           vals=vals.Numbers(self.ovp_range[0], self.ovp_range[1])
                           )
        self.add_parameter('ovp_state',
                           label='Over Voltage Protection status',
                           set_cmd='{} :VOLTage:PROTection:STATe {}'.format(select_cmd, '{}'),
                           get_cmd='{} :VOLTage:PROTection:STATe?'.format(select_cmd),
                           get_parser=strstrip,
                           vals=vals.OnOff()
                           )
        self.add_parameter("ocp_value",
                           label='Over Current Protection value',
                           set_cmd="{} :CURRent:PROTection:LEVel {}".format(
                               select_cmd, '{}'),
                           get_cmd="{} :CURRent:PROTection:LEVel?".format(
                               select_cmd),
                           get_parser=float,
                           unit='A',
                           vals=vals.Numbers(self.ocp_range[0], self.ocp_range[1])
                           )
        self.add_parameter('ocp_state',
                           label='Over Current Protection status',
                           set_cmd='{} :CURRent:PROTection:STATe {}'.format(select_cmd, '{}'),
                           get_cmd='{} :CURRent:PROTection:STATe?'.format(select_cmd),
                           get_parser=strstrip,
                           vals=vals.OnOff()
                           )
    def __init__(self, name, address, step_attenuator=False, **kwargs):
        super().__init__(name, address, **kwargs)

        # Only listed most common spellings idealy want a
        # .upper val for Enum or string
        on_off_validator = vals.Enum('on', 'On', 'ON', 'off', 'Off', 'OFF')
        on_off_mapping = create_on_off_val_mapping(1, 0)

        self.add_parameter(name='frequency',
                           label='Frequency',
                           unit='Hz',
                           get_cmd='FREQ:CW?',
                           set_cmd='FREQ:CW' + ' {:.4f}',
                           get_parser=float,
                           set_parser=float,
                           vals=vals.Numbers(1e5, 20e9),
                           docstring='Adjust the RF output frequency')
        self.add_parameter(name='freq_offset',
                           label='Frequency offset',
                           unit='Hz',
                           get_cmd='FREQ:OFFS?',
                           set_cmd='FREQ:OFFS {}',
                           get_parser=float,
                           vals=Numbers(min_value=-200e9, max_value=200e9))
        self.add_parameter(name='frequency_offset',
                           source=self.freq_offset,
                           parameter_class=DelegateParameter,
                           docstring="'frequency_offset' delegate parameter "
                           "for 'freq_offset' is deprecated to "
                           "make the parameter name consistent with "
                           "that of one present in Agilent (Keysight)"
                           " E8267C driver in Qcodes")
        self.add_parameter('freq_mode',
                           label='Frequency mode',
                           set_cmd='FREQ:MODE {}',
                           get_cmd='FREQ:MODE?',
                           get_parser=lambda s: s.strip(),
                           vals=vals.Enum('FIX', 'CW', 'SWE', 'LIST'))
        self.add_parameter(name='frequency_mode',
                           source=self.freq_mode,
                           parameter_class=DelegateParameter,
                           docstring="'frequency_mode' delegate parameter for "
                           "'freq_mode' is deprecated to make the "
                           "parameter name consistent with that of "
                           "one present in Agilent (Keysight) E8267C "
                           "driver in Qcodes")
        self.add_parameter(name='phase',
                           label='Phase',
                           unit='deg',
                           get_cmd='PHASE?',
                           set_cmd='PHASE' + ' {:.8f}',
                           get_parser=self.rad_to_deg,
                           set_parser=self.deg_to_rad,
                           vals=vals.Numbers(-180, 180))
        self.add_parameter(name='power',
                           label='Power',
                           unit='dBm',
                           get_cmd='POW:AMPL?',
                           set_cmd='POW:AMPL' + ' {:.4f}',
                           get_parser=float,
                           set_parser=float,
                           vals=vals.Numbers(-130, 25))
        self.add_parameter('output_rf',
                           get_cmd=':OUTP?',
                           set_cmd='OUTP {}',
                           get_parser=parse_on_off,
                           vals=on_off_validator)
        self.add_parameter(name='status',
                           source=self.output_rf,
                           parameter_class=DelegateParameter,
                           docstring="'status' delegate parameter for "
                           "'output_rf' is deprecated to make the "
                           "parameter name consistent with that of "
                           "one present in Agilent (Keysight) E8267C "
                           "driver in Qcodes")
        self.add_parameter(name='modulation_rf',
                           get_cmd='OUTP:MOD?',
                           set_cmd='OUTP:MOD {}',
                           val_mapping=on_off_mapping)
        self.add_parameter(name='modulation_rf_enabled',
                           source=self.modulation_rf,
                           parameter_class=DelegateParameter,
                           docstring="'modulation_rf_enabled' delegate "
                           "parameter for 'modulation_rf' is "
                           "deprecated to make the parameter name "
                           "consistent with that of one present in "
                           "Agilent (Keysight) E8267C driver in "
                           "Qcodes")
        self.add_parameter(
            'IQmodulator_enabled',
            get_cmd='DM:STATe?',
            set_cmd='DM:STATe {}',
            val_mapping=on_off_mapping,
            docstring=
            'Enables or disables the internal I/Q modulator. Source can be external or internal.'
        )

        for source in [1, 2]:
            self.add_parameter(f'IQsource{source}',
                               get_cmd=f'DM:SOUR{source}?',
                               set_cmd=f'DM:SOUR{source} {{}}',
                               get_parser=lambda s: s.strip(),
                               vals=vals.Enum('OFF', 'EXT', 'EXT600', 'INT'),
                               docstring=IQsource_docstring)

        self.add_parameter(f'IQadjustments_enabled',
                           get_cmd=f'DM:IQAD?',
                           set_cmd=f'DM:IQAD {{}}',
                           val_mapping=on_off_mapping,
                           docstring='Enable or disable IQ adjustments')

        IQoffset_parameters = dict(get_parser=float,
                                   set_parser=float,
                                   vals=vals.Numbers(-100, 100))
        self.add_parameter(f'I_offset',
                           get_cmd=f'DM:IQAD:IOFF?',
                           set_cmd=f'DM:IQAD:IOFF {{}}',
                           **IQoffset_parameters,
                           docstring='I channel offset in percentage')
        self.add_parameter(f'Q_offset',
                           get_cmd=f'DM:IQAD:QOFF?',
                           set_cmd=f'DM:IQAD:QOFF {{}}',
                           **IQoffset_parameters,
                           docstring='Q channel offset in percentage')
        self.add_parameter(f'IQ_quadrature',
                           get_cmd=f'DM:IQAD:QSK?',
                           set_cmd=f'DM:IQAD:QSK {{}}',
                           get_parser=float,
                           set_parser=float,
                           docstring='IQ quadrature offset',
                           unit='deg')

        self.add_parameter(f'pulse_modulation_enabled',
                           get_cmd=f'PULM:STATe?',
                           set_cmd=f'PULM:STATe {{}}',
                           val_mapping=on_off_mapping,
                           docstring='Enable or disable pulse modulation path')
        self.add_parameter(f'pulse_modulation_source',
                           get_cmd=f'PULM:SOURce?',
                           set_cmd=f'PULM:SOURce {{}}',
                           get_parser=lambda s: s.strip(),
                           vals=vals.Enum('EXT', 'INT', 'SCAL'))

        self.add_parameter(
            f'wideband_amplitude_modulation_enabled',
            get_cmd=f'AM:WID:STATe?',
            set_cmd=f'AM:WID:STATe {{}}',
            val_mapping=on_off_mapping,
            docstring=
            'This command enables or disables wideband amplitude modulation')

        self.add_parameter('wideband_IQ_modulation_enabled',
                           get_cmd=f'AM:WID:STATe?',
                           set_cmd=f'AM:WID:STATe {{}}',
                           val_mapping=on_off_mapping)
        self.add_parameter('ALC_status',
                           get_cmd=f'ALC:STATe?',
                           set_cmd=f'ALC:STATe {{}}',
                           val_mapping=on_off_mapping)
        self.add_parameter('FM_status',
                           get_cmd=f'FM:STATe?',
                           set_cmd=f'FM:STATe {{}}',
                           val_mapping=on_off_mapping)
        self.add_parameter('FM_source',
                           get_cmd=f'FM:SOURce?',
                           set_cmd=f'FM:SOURce {{}}',
                           get_parser=lambda s: s.strip(),
                           vals=vals.Enum('EXT1', 'EXT2', 'INT', 'INT1',
                                          'INT2'))
        self.add_parameter('FM_deviation',
                           get_cmd=f'FM:DEViation?',
                           set_cmd=f'FM:DEViation {{}}',
                           get_parser=lambda s: str(s) + 'MHz')

        self.connect_message()
Esempio n. 15
0
    def __init__(self, parent, name, channum):
        """
        Args:
            parent (Instrument): The instrument to which the channel is
                attached.
            name (str): The name of the channel
            channum (int): The number of the channel in question (1-2)
        """
        super().__init__(parent, name)

        def val_parser(parser, inputstring):
            """
            Parses return values from instrument. Meant to be used when a query
            can return a meaningful finite number or a numeric representation
            of infinity

            Args:
                inputstring (str): The raw return value
                parser (type): Either int or float, what to return in finite
                    cases
            """

            inputstring = inputstring.strip()

            if float(inputstring) == 9.9e37:
                output = float('inf')
            else:
                output = float(inputstring)
                if parser == int:
                    output = parser(output)

            return output

        self.add_parameter('function_type',
                           label='Channel {} function type'.format(channum),
                           set_cmd='SOURce{}:FUNCtion {{}}'.format(channum),
                           get_cmd='SOURce{}:FUNCtion?'.format(channum),
                           get_parser=str.rstrip,
                           vals=vals.Enum('SIN', 'SQU', 'TRI', 'RAMP', 'PULS',
                                          'PRBS', 'NOIS', 'ARB', 'DC'))

        self.add_parameter(
            'frequency_mode',
            label='Channel {} frequency mode'.format(channum),
            set_cmd='SOURce{}:FREQuency:MODE {{}}'.format(channum),
            get_cmd='SOURce{}:FREQuency:MODE?'.format(channum),
            get_parser=str.rstrip,
            vals=vals.Enum('CW', 'LIST', 'SWEEP', 'FIXED'))

        self.add_parameter(
            'frequency',
            label='Channel {} frequency'.format(channum),
            set_cmd='SOURce{}:FREQuency {{}}'.format(channum),
            get_cmd='SOURce{}:FREQuency?'.format(channum),
            get_parser=float,
            unit='Hz',
            # TODO: max. freq. actually really tricky
            vals=vals.Numbers(1e-6, 30e6))

        self.add_parameter('phase',
                           label='Channel {} phase'.format(channum),
                           set_cmd='SOURce{}:PHASe {{}}'.format(channum),
                           get_cmd='SOURce{}:PHASe?'.format(channum),
                           get_parser=float,
                           unit='deg',
                           vals=vals.Numbers(0, 360))
        self.add_parameter(
            'amplitude_unit',
            label='Channel {} amplitude unit'.format(channum),
            set_cmd='SOURce{}:VOLTage:UNIT {{}}'.format(channum),
            get_cmd='SOURce{}:VOLTage:UNIT?'.format(channum),
            vals=vals.Enum('VPP', 'VRMS', 'DBM'),
            get_parser=str.rstrip)

        self.add_parameter(
            'amplitude',
            label='Channel {} amplitude'.format(channum),
            set_cmd='SOURce{}:VOLTage {{}}'.format(channum),
            get_cmd='SOURce{}:VOLTage?'.format(channum),
            unit='',  # see amplitude_unit
            get_parser=float)

        self.add_parameter(
            'offset',
            label='Channel {} voltage offset'.format(channum),
            set_cmd='SOURce{}:VOLTage:OFFSet {{}}'.format(channum),
            get_cmd='SOURce{}:VOLTage:OFFSet?'.format(channum),
            unit='V',
            get_parser=float)
        self.add_parameter('output',
                           label='Channel {} output state'.format(channum),
                           set_cmd='OUTPut{} {{}}'.format(channum),
                           get_cmd='OUTPut{}?'.format(channum),
                           val_mapping={
                               'ON': 1,
                               'OFF': 0
                           })

        self.add_parameter(
            'ramp_symmetry',
            label='Channel {} ramp symmetry'.format(channum),
            set_cmd='SOURce{}:FUNCtion:RAMP:SYMMetry {{}}'.format(channum),
            get_cmd='SOURce{}:FUNCtion:RAMP:SYMMetry?'.format(channum),
            get_parser=float,
            unit='%',
            vals=vals.Numbers(0, 100))

        # TRIGGER MENU
        self.add_parameter(
            'trigger_source',
            label='Channel {} trigger source'.format(channum),
            set_cmd='TRIGger{}:SOURce {{}}'.format(channum),
            get_cmd='TRIGger{}:SOURce?'.format(channum),
            vals=vals.Enum('IMM', 'EXT', 'TIM', 'BUS'),
            get_parser=str.rstrip,
        )

        self.add_parameter('trigger_count',
                           label='Channel {} trigger count'.format(channum),
                           set_cmd='TRIGger{}:COUNt {{}}'.format(channum),
                           get_cmd='TRIGger{}:COUNt?'.format(channum),
                           vals=vals.Ints(1, 1000000),
                           get_parser=partial(val_parser, int))

        self.add_parameter('trigger_delay',
                           label='Channel {} trigger delay'.format(channum),
                           set_cmd='TRIGger{}:DELay {{}}'.format(channum),
                           get_cmd='TRIGger{}:DELay?'.format(channum),
                           vals=vals.Numbers(0, 1000),
                           get_parser=float,
                           unit='s')

        # TODO: trigger level doesn't work remotely. Why?

        self.add_parameter('trigger_slope',
                           label='Channel {} trigger slope'.format(channum),
                           set_cmd='TRIGger{}:SLOPe {{}}'.format(channum),
                           get_cmd='TRIGger{}:SLOPe?'.format(channum),
                           vals=vals.Enum('POS', 'NEG'),
                           get_parser=str.rstrip)

        self.add_parameter('trigger_timer',
                           label='Channel {} trigger timer'.format(channum),
                           set_cmd='TRIGger{}:TIMer {{}}'.format(channum),
                           get_cmd='TRIGger{}:TIMer?'.format(channum),
                           vals=vals.Numbers(1e-6, 8000),
                           get_parser=float)

        # output menu
        self.add_parameter('output_polarity',
                           label='Channel {} output polarity'.format(channum),
                           set_cmd='OUTPut{}:POLarity {{}}'.format(channum),
                           get_cmd='OUTPut{}:POLarity?'.format(channum),
                           get_parser=str.rstrip,
                           vals=vals.Enum('NORM', 'INV'))
        # BURST MENU
        self.add_parameter('burst_state',
                           label='Channel {} burst state'.format(channum),
                           set_cmd='SOURce{}:BURSt:STATe {{}}'.format(channum),
                           get_cmd='SOURce{}:BURSt:STATe?'.format(channum),
                           val_mapping={
                               'ON': 1,
                               'OFF': 0
                           },
                           vals=vals.Enum('ON', 'OFF'))

        self.add_parameter('burst_mode',
                           label='Channel {} burst mode'.format(channum),
                           set_cmd='SOURce{}:BURSt:MODE {{}}'.format(channum),
                           get_cmd='SOURce{}:BURSt:MODE?'.format(channum),
                           get_parser=str.rstrip,
                           val_mapping={
                               'N Cycle': 'TRIG',
                               'Gated': 'GAT'
                           },
                           vals=vals.Enum('N Cycle', 'Gated'))

        self.add_parameter(
            'burst_ncycles',
            label='Channel {} burst no. of cycles'.format(channum),
            set_cmd='SOURce{}:BURSt:NCYCles {{}}'.format(channum),
            get_cmd='SOURce{}:BURSt:NCYCLes?'.format(channum),
            get_parser=partial(val_parser, int),
            vals=vals.MultiType(vals.Ints(1), vals.Enum('MIN', 'MAX', 'INF')))

        self.add_parameter(
            'burst_phase',
            label='Channel {} burst start phase'.format(channum),
            set_cmd='SOURce{}:BURSt:PHASe {{}}'.format(channum),
            get_cmd='SOURce{}:BURSt:PHASe?'.format(channum),
            vals=vals.Numbers(-360, 360),
            unit='degrees',
            get_parser=float)

        self.add_parameter(
            'burst_polarity',
            label='Channel {} burst gated polarity'.format(channum),
            set_cmd='SOURce{}:BURSt:GATE:POLarity {{}}'.format(channum),
            get_cmd='SOURce{}:BURSt:GATE:POLarity?'.format(channum),
            vals=vals.Enum('NORM', 'INV'))

        self.add_parameter(
            'burst_int_period',
            label=('Channel {}'.format(channum) + ' burst internal period'),
            set_cmd='SOURce{}:BURSt:INTernal:PERiod {{}}'.format(channum),
            get_cmd='SOURce{}:BURSt:INTernal:PERiod'.format(channum),
            unit='s',
            vals=vals.Numbers(1e-6, 8e3),
            get_parser=float,
            docstring=('The burst period is the time '
                       'between the starts of consecutive '
                       'bursts when trigger is immediate.'))
Esempio n. 16
0
    def __init__(self, name, address, **kwargs):
        super().__init__(name, address, terminator='\n', timeout=60, **kwargs)
        self._data_processor = None
        #By default we are working with the channel number 1, so SENSe<cnum>: if all queries is just SENSe1: ...

        # if 'P9373' in self.ask('*IDN?'):
        self._is_big_endian = True
        # else:
        #     self._is_big_endian = False

        # Acquisition parameters
        self.add_parameter('freq_start',
                           label='Start frequency',
                           unit='Hz',
                           get_cmd='SENSe1:FREQuency:STARt?',
                           get_parser=float,
                           set_cmd='SENSe1:FREQuency:STARt {:f}',
                           vals=vals.Numbers(1., 20e9))

        self.add_parameter('freq_stop',
                           label='Stop frequency',
                           unit='Hz',
                           get_cmd='SENSe1:FREQuency:STOP?',
                           get_parser=float,
                           set_cmd='SENSe1:FREQuency:STOP {:f}',
                           vals=vals.Numbers(1., 20e9))

        self.add_parameter('freq_center',
                           label='Center frequency',
                           unit='Hz',
                           get_cmd='SENSe1:FREQuency:CENTer?',
                           get_parser=float,
                           set_cmd='SENSe1:FREQuency:CENTer {:f}',
                           vals=vals.Numbers(1., 20e9))

        self.add_parameter('freq_span',
                           label='Frequency span',
                           unit='Hz',
                           get_cmd='SENSe1:FREQuency:SPAN?',
                           get_parser=float,
                           set_cmd='SENSe1:FREQuency:SPAN {:f}',
                           vals=vals.Numbers(0., 10e9))

        self.add_parameter(
            'freq_CW',
            label='CW frequency',
            unit='Hz',
            docstring=
            '''Sets the frequency of the single-frequency continuous wave sweep.
            This is the frequency which will be used for CW or POWer sweeps.''',
            get_cmd='SENS:FREQ:CW?',
            get_parser=float,
            set_cmd='SENS:FREQ:CW {:f}',
            vals=vals.Numbers(0., 20e9))

        self.add_parameter('power_start',
                           label='Start power',
                           unit='dB',
                           docstring='Start power for the power sweep mode',
                           get_cmd='SOUR:POW:STAR?',
                           get_parser=float,
                           set_cmd='SOUR:POW:STAR {:f}',
                           vals=vals.Numbers(-30., 30))

        self.add_parameter('power_stop',
                           label='Stop power',
                           unit='dB',
                           docstring='Stop power for the power sweep mode',
                           get_cmd='SOUR:POW:STOP?',
                           get_parser=float,
                           set_cmd='SOUR:POW:STOP {:f}',
                           vals=vals.Numbers(-30., 30))

        self.add_parameter('output',
                           docstring='''Turns the output power ON or OFF''',
                           get_cmd='OUTP?',
                           set_cmd='OUTP {}',
                           val_mapping={
                               'ON': 1,
                               'OFF': 0,
                               True: 1,
                               False: 0,
                               1: 1,
                               0: 0
                           })
        #val_mapping = OrderedDict((True, 1), (False, 0), (1, 1), (0, 0), ('ON', 1), ('OFF', 0)))

        self.add_parameter('power',
                           label='power',
                           unit='dB',
                           docstring='''Sets the source power''',
                           get_cmd='SOUR:POW?',
                           get_parser=float,
                           set_cmd='SOUR:POW {:f}',
                           vals=vals.Numbers(-60., 20.))

        self.add_parameter('averaging',
                           docstring='''Averaging ON/OFF''',
                           get_cmd='SENS:AVER?',
                           set_cmd='SENS:AVER {}',
                           val_mapping={
                               True: 1,
                               False: 0
                           })

        self.add_parameter('averaging_mode',
                           docstring='''
            Sets the type of averaging to perform: Point or Sweep.
            POINT - Averaging measurements are made on each data point before stepping to the next data point.
            SWEEP - Averaging measurements are made on subsequent sweeps until the required number of averaging sweeps are performed.
            Default setting is sweep.
            ''',
                           get_cmd='SENS:AVER:MODE?',
                           set_cmd='SENS:AVER:MODE {}',
                           val_mapping={
                               'point': 'POIN',
                               'sweep': 'SWE'
                           })

        self.add_parameter(
            'averages',
            label='averages',
            docstring=
            '''Sets the number of averages. Averaging should be True as well.''',
            get_cmd='SENS:AVER:COUN?',
            get_parser=int,
            set_cmd='SENS:AVER:COUN {:d}',
            vals=vals.Ints(1, 1 << 16))

        self.add_parameter('sweep_points',
                           label='Points in sweep',
                           get_cmd='SENS:SWE:POIN?',
                           get_parser=int,
                           set_cmd='SENS:SWE:POIN {:d}',
                           vals=vals.Ints(1, 32001))

        self.add_parameter(
            'sweep_time',
            unit='s',
            docstring='''The time in seconds required to complete a single sweep.
            Setting to zero will result in minimum possible time required to run the sweep.
            The setting is valid for any sweep type.''',
            get_cmd='SENS:SWE:TIME?',
            get_parser=float,
            set_cmd='SENS:SWE:TIME {:f}',
            vals=vals.Numbers(0, 86400))

        self.add_parameter(
            'bandwidth',
            label='bandwidth',
            docstring=
            '''Sets the measurement bandwidth in Hz, working range is a list of values from 1Hz to 15MHz.
            Automatically rounds the input value to the closest value from the list.''',
            get_cmd='SENS:BAND?',
            get_parser=float,
            set_cmd='SENS:BAND {:f}',
            vals=vals.Numbers(1, 15e6))

        self.add_parameter('sweep_type',
                           docstring='''Type of the sweep.''',
                           get_cmd='SENS:SWE:TYPE?',
                           set_cmd='SENS:SWE:TYPE {}',
                           vals=vals.Enum('LIN', 'LOG', 'POW', 'CW', 'SEGM',
                                          'PHAS'))

        self.add_parameter(
            'trigger',
            docstring=
            '''Mode of the internal trigger of the instrument: hold, continuous, groups or single.''',
            get_cmd='SENS:SWE:MODE?',
            set_cmd='SENS:SWE:MODE {}',
            vals=vals.Enum('hold', 'cont', 'gro', 'sing'))

        self.add_parameter(
            'trigger_source',
            docstring=
            '''Source of the internal trigger of the instrument: EXTernal, IMMediate, or MANual.''',
            get_cmd='TRIG:SOUR?',
            set_cmd='TRIG:SOUR {}',
            vals=vals.Enum('EXT', 'IMM', 'MAN'))

        self._num_repetitions = 1
        self._segment_freqs = []

        # *IDN?
        self.connect_message()
Esempio n. 17
0
    def __init__(self, parent:Instrument, name:str, duration_get_cmd:callable=None) -> None:
        super().__init__(parent, name)

        self.add_parameter(
            'channel', ManualParameter, 
            docstring='Output channel of the pulse generator'
        )
        if name == 'awg':
            # the primary awg must always be triggered at time zero
            self.add_parameter(
                'reference',  
                docstring='Time relative to which the in/output starts.',
                get_cmd=lambda:'awg output start'
            )
            self.add_parameter(
                'offset', unit='s', 
                docstring='In/output time offset from reference point.',
                get_cmd=lambda: 0.
            )
        else:
            self.add_parameter(
                'reference', ManualParameter, 
                docstring='Time relative to which the in/output starts.',
                vals=vals.Enum('zero', 'awg output start', 'fixed point'),
                initial_value='fixed point'
            )
            self.add_parameter(
                'offset', ManualParameter, unit='s', 
                docstring='In/output time offset from reference point.',
                vals=vals.Numbers(), initial_value=0.
            )
        if duration_get_cmd is not None:
            # if duration_get_cmd is given, use it to compute duration
            # and make duration only gettable
            self.add_parameter(
                'duration', unit='s', get_cmd=duration_get_cmd, 
                docstring='Duration of the in/output.',
            )
        else:
            self.add_parameter(
                'duration', ManualParameter, unit='s', 
                docstring='Duration of the in/output.',
                vals=vals.Numbers(min_value=0.), initial_value=None
            )
        self.add_parameter(
            'trigger_delay', ManualParameter, unit='s', 
            docstring='Time delay between sending a trigger pulse and start of '
                      'in/output on the instrument. Usually found in the data sheet.',
            vals=vals.Numbers(min_value=0.), initial_value=0.
        )
        self.add_parameter(
            'trigger_duration', ManualParameter, unit='s', 
            docstring='Duration of the trigger pulse sent to the instrument.',
            vals=vals.Numbers(min_value=0.), initial_value=100e-9
        )
        self.add_parameter(
            'trigger_holdoff', ManualParameter, unit='s', 
            docstring='Minimum time required before a trigger can be processed '
                      'after in/output finishes.',
            vals=vals.Numbers(min_value=0.), initial_value=0.
        )
Esempio n. 18
0
    def __init__(self, name, address, timeout=20, **kwargs):
        """
        Initialises the oscilloscope.

        Args:
            name (str): Name of the instrument used by QCoDeS
        address (string): Instrument address as used by VISA
            timeout (float): visa timeout, in secs.
        """

        super().__init__(name,
                         address,
                         timeout=timeout,
                         terminator='\n',
                         **kwargs)
        self.connect_message()
        self.write('*RST')  # resets oscilloscope - initialize to known state
        self.write('*CLS')  # clears status registers and output queue

        # Turns off system headers to allow faster throughput
        # and immediate access to the data values requested by queries.
        self.write(':SYSTem:HEADer OFF')

        # Scope trace boolean
        self.trace_ready = False

        # NOTE: The list of implemented parameters is not complete. Refer to
        # the manual (Infiniium prog guide).

        # Timebase
        self.add_parameter(
            'timebase_reference',
            label='Reference of the time axis',
            get_cmd=':TIMebase:REFerence?',
            set_cmd=':TIMebase:REFerence {}',
            vals=Enum('CENT', 'CENTer')  # NOTE: needs more values
        )
        self.add_parameter(
            'timebase_range',
            label='Range of the time axis',
            unit='s',
            get_cmd=':TIMebase:RANGe?',
            set_cmd=':TIMebase:RANGe {}',
            vals=vals.Numbers(2e-9, 20),
            get_parser=float,
        )
        self.add_parameter(
            'timebase_position',
            label='Offset of the time axis',
            unit='s',
            get_cmd=':TIMebase:POSition?',
            set_cmd=':TIMebase:POSition {}',
            vals=vals.Numbers(),
            get_parser=float,
        )

        # Trigger
        # TODO: add enum for case insesitivity
        self.add_parameter(
            'trigger_edge_source',
            label='Source channel for the edge trigger',
            get_cmd=':TRIGger:EDGE:SOURce?',
            set_cmd=':TRIGger:EDGE:SOURce {}',
            vals=Enum(*(['CHANnel{}'.format(i) for i in range(1, 4 + 1)] +
                        ['CHAN{}'.format(i) for i in range(1, 4 + 1)] +
                        ['DIGital{}'.format(i) for i in range(16 + 1)] +
                        ['DIG{}'.format(i)
                         for i in range(16 + 1)] + ['AUX', 'LINE'])))

        self.add_parameter('trigger_edge_slope',
                           label='slope of the edge trigger',
                           get_cmd=':TRIGger:EDGE:SLOPe?',
                           set_cmd=':TRIGger:EDGE:SLOPe {}',
                           vals=Enum('positive', 'negative', 'neither'))

        self.add_parameter(
            'trigger_level_aux',
            label='Tirgger level AUX',
            unit='V',
            get_cmd=':TRIGger:LEVel? AUX',
            set_cmd=':TRIGger:LEVel AUX,{}',
            get_parser=float,
            vals=Numbers(),
        )

        # Acquisition
        # If sample points, rate and timebase_scale are set in an
        # incommensurate way, the scope only displays part of the waveform

        self.add_parameter('acquire_mode',
                           label='acquisition mode',
                           get_cmd='ACQuire:MODE?',
                           set_cmd='ACQuire:MODE {}',
                           vals=Enum('RTIMe', 'ETIMe', 'PDETect',
                                     'HRESolution', 'SEGMented'))

        self.add_parameter(
            'acquire_average',
            label='average on/off',
            get_cmd='ACQuire:AVERage?',
            set_cmd='ACQuire:AVERage {}',
            val_mapping={
                True: 1,
                False: 0
            },
        )

        self.add_parameter(
            'acquire_points',
            label='sample points',
            get_cmd='ACQuire:POINts?',
            get_parser=int,
            set_cmd=self._cmd_and_invalidate('ACQuire:POINts {}'),
            unit='pts',
            vals=vals.Numbers(min_value=1, max_value=100e6))

        self.add_parameter('acquire_sample_rate',
                           label='sample rate',
                           get_cmd='ACQ:SRAT?',
                           set_cmd=self._cmd_and_invalidate('ACQ:SRAT {}'),
                           unit='Sa/s',
                           get_parser=float)

        self.add_parameter(
            'data_source',
            label='Waveform Data source',
            get_cmd=':WAVeform:SOURce?',
            set_cmd=':WAVeform:SOURce {}',
            vals=Enum(*(['CHANnel{}'.format(i) for i in range(1, 4 + 1)] +
                        ['CHAN{}'.format(i) for i in range(1, 4 + 1)] +
                        ['FUNCtion{}'.format(i) for i in range(1, 16 + 1)] +
                        ['FUNC{}'.format(i) for i in range(1, 16 + 1)] +
                        ['WMEMory{}'.format(i) for i in range(1, 4 + 1)] +
                        ['WMEM{}'.format(i) for i in range(1, 4 + 1)] +
                        ['HISTogram', 'HIST', 'POD1', 'POD2', 'PODALL'])))

        ## TODO: implement as array parameter to allow for setting the other filter
        # Ratios
        self.add_parameter(
            'acquire_interpolate',
            get_cmd=':ACQuire:INTerpolate?',
            set_cmd=self._cmd_and_invalidate(':ACQuire:INTerpolate {}'),
            val_mapping={
                True: 1,
                False: 0
            })

        self.add_parameter('acquire_timespan',
                           get_cmd=(lambda: self.acquire_points.get_latest() /
                                    self.acquire_sample_rate.get_latest()),
                           unit='s',
                           get_parser=float)

        # Time of the first point
        self.add_parameter('waveform_xorigin',
                           get_cmd='WAVeform:XORigin?',
                           unit='s',
                           get_parser=float)

        # Channels
        channels = ChannelList(self,
                               "Channels",
                               InfiniiumChannel,
                               snapshotable=False)

        for i in range(1, 5):
            channel = InfiniiumChannel(self, 'chan{}'.format(i), i)
            channels.append(channel)
            self.add_submodule('ch{}'.format(i), channel)
        channels.lock()
        self.add_submodule('channels', channels)
Esempio n. 19
0
    def add_calibration_parameters(self):
        # First add a function so a user can poll if calibration data has
        # been set correctly in the VSM in order to correctly use the
        # orthogonalized parameters
        self.add_parameter(
                            'getCalibrationDataAvailable',
                            docstring='Use this to check if the calibration data has been '\
                                      'set correctly in the VSM. Outputs an integer 0 (False), 1 (True)',
                            get_cmd='CALIBRATIONDATAPATH' + '?',
                            get_parser=int,
                            vals=validators.Ints(0,1)
                        )

        # Raw attenuationa and phase
        #  Two input pulses
        for pulse in ('gaussian', 'derivative'):
            #  Two DACs
            for dac in ('att', 'phase'):
                # All channels and modules at once (no getter)
                var_name = '_{p}_{d}_raw'.format(p=pulse, d=dac)
                var_scpi = ':{p}:{d}:RAW'.format(p=pulse.upper(), d=dac.upper())
                # Individual outputs: per (module, channel) pair
                for channel in self.channels:
                    for mod in self.modules:
                        doc_dac = 'Raw {d} DAC value (0--65535) for the {p} ' \
                                  'input of channel {c} ' \
                                  'of module {m}.'.format(p=pulse, d=dac,
                                                          c=channel, m=mod)
                        ch_name = '_mod{m}_ch{c}'.format(m=mod, c=channel)
                        ch_scpi = ':MODULE{m}:CHANNEL{c}'.format(m=mod,
                                                                 c=channel)
                        scpi_name = 'CALIBRATION' + ch_scpi + var_scpi
                        self.add_parameter(
                            ch_name + var_name,
                            label=ch_name + var_name,
                            docstring=doc_dac,
                            get_cmd=scpi_name + '?',
                            set_cmd=scpi_name + ' {}',
                            get_parser=int,
                            set_parser=int,
                            vals=validators.Numbers(min_value=0, max_value=2**16-1)
                        )

      # orthogonalized attenuation and phase
        #  Two input pulses
        for pulse in ('gaussian', 'derivative'):
            for channel in self.channels:
                for mod in self.modules:
                    ch_name = 'mod{m}_ch{c}'.format(m=mod, c=channel)
                    ch_scpi = ':MODULE{m}:CHANNEL{c}'.format(m=mod, c=channel)

                    doc_var = 'Attenuation value (in dB) for the {p} ' \
                              'input of channel {c} ' \
                              'of module {m}.\nN.B. Safe range: '\
                              '0.1<=v<=1.0'.format(p=pulse, c=channel, m=mod)
                    var_name = '_'+ch_name + '_{p}_att_db'.format(p=pulse)
                    var_scpi = ch_scpi + ':{p}:ATTENUATION:DB'.format(p=pulse.upper())
                    scpi_name = 'CALIBRATION' + var_scpi
                    self.add_parameter(var_name,
                                       docstring=doc_var,
                                       get_cmd=scpi_name + '?',
                                       set_cmd=scpi_name + ' {}',
                                       unit='dB',
                                       get_parser=float,
                                       vals=validators.Numbers())
                    doc_var = 'Amplitude value (linear) for the {p} ' \
                              'input of channel {c} ' \
                              'of module {m}.'.format(p=pulse, c=channel, m=mod)
                    var_name = ch_name + '_{p}_amp'.format(p=pulse)

                    var_scpi = ch_scpi + ':{p}:ATTENUATION:LIN'.format(p=pulse.upper())
                    scpi_name = 'CALIBRATION' + var_scpi
                    self.add_parameter(var_name,
                                       docstring=doc_var,
                                       get_cmd=scpi_name + '?',
                                       set_cmd=scpi_name + ' {}',
                                       get_parser=float,
                                       vals=validators.Numbers(min_value=0.1,
                                                               max_value=1.0))

                    doc_var = 'Phase value (in rad) for the {p} ' \
                              'input of channel {c} ' \
                              'of module {m}.'.format(p=pulse, c=channel, m=mod)
                    var_name = '_' + ch_name + '_{p}_phs_rad'.format(p=pulse)
                    var_scpi = ch_scpi + ':{p}:PHASE:RAD'.format(p=pulse.upper())
                    scpi_name = 'CALIBRATION' + var_scpi
                    self.add_parameter(var_name,
                                       docstring=doc_var,
                                       get_cmd=scpi_name + '?',
                                       set_cmd=scpi_name + ' {}',
                                       unit='rad',
                                       get_parser=float,
                                       vals=validators.Numbers())
                    doc_var = 'Phase value (in deg) for the {p} ' \
                              'input of channel {c} ' \
                              'of module {m}.'.format(p=pulse, c=channel, m=mod)
                    var_name = ch_name + '_{p}_phase'.format(p=pulse)
                    var_scpi = ch_scpi + ':{p}:PHASE:DEG'.format(p=pulse.upper())
                    scpi_name = 'CALIBRATION' + var_scpi
                    self.add_parameter(var_name,
                                       docstring=doc_var,
                                       get_cmd=scpi_name + '?',
                                       set_cmd=scpi_name + ' {}',
                                       unit='deg',
                                       get_parser=float,
                                       vals=validators.Numbers(-125,45))
Esempio n. 20
0
    def __init__(
        self,
        name: str,
        device_type: str,
        readout_methods: Optional[Dict[str, qc.Parameter]] = None,
        gate_parameters: Optional[Dict[int, Any]] = None,
        ohmic_parameters: Optional[Dict[int, Any]] = None,
        sensor_parameters: Optional[Dict[int, Any]] = None,
        measurement_options: Optional[Dict[str, Dict[str, Any]]] = None,
        sensor_side: str = "left",
        initial_valid_ranges: Optional[vltg_rngs_tp] = None,
        normalization_constants: Optional[nrm_cnst_tp] = None,
    ) -> None:

        super().__init__(name)

        super().add_parameter(
            name="device_type",
            label="device type",
            docstring="",
            set_cmd=None,
            get_cmd=None,
            initial_value=device_type,
            vals=vals.Strings(),
        )

        all_meths = nt.config['core']['readout_methods']
        if readout_methods is not None:
            assert list(set(all_meths).intersection(readout_methods.keys()))
        else:
            readout_methods = {}
        self._readout_methods = readout_methods
        super().add_parameter(
            name="readout_methods",
            label=f"{name} readout methods",
            docstring="readout methods to use for measurements",
            set_cmd=self.set_readout_methods,
            get_cmd=self.get_readout_methods,
            initial_value=readout_methods,
            vals=vals.Dict(),
        )

        self._measurement_options = measurement_options
        super().add_parameter(
            name="measurement_options",
            label=f"{name} measurement options",
            docstring="readout methods to use for measurements",
            set_cmd=self.set_measurement_options,
            get_cmd=self.get_measurement_options,
            initial_value=measurement_options,
            vals=vals.Dict(),
        )

        super().add_parameter(
            name="sensor_side",
            label="sensor side",
            docstring="side where the sensor is located",
            set_cmd=None,
            get_cmd=None,
            initial_value=sensor_side,
            vals=vals.Enum("left", "right"),
        )

        self.layout = nt.config["device"][self.device_type()]
        self.gates: List[Gate] = []
        self.sensor_gates: List[Gate] = []
        self.ohmics: List[Ohmic] = []
        required_parameter_fields = ['channel_id', 'dac_instrument']
        if gate_parameters is not None:
            for layout_id, gate_param in gate_parameters.items():
                for required_param in required_parameter_fields:
                    assert gate_param.get(required_param) is not None
                alias = self.layout[layout_id]
                gate_param['layout_id'] = layout_id
                gate_param['use_ramp'] = True
                gate = Gate(
                    parent=self,
                    name=alias,
                    **gate_param,
                )
                super().add_submodule(alias, gate)
                self.gates.append(gate)

        # if self.sensor_side() == "right":
        #     self.outer_barriers.reverse()
        #     self.plungers.reverse()

        if sensor_parameters is not None:
            for layout_id, sens_param in sensor_parameters.items():
                for required_param in required_parameter_fields:
                    assert sens_param.get(required_param) is not None
                alias = self.layout[layout_id]
                sens_param['layout_id'] = layout_id
                sens_param['use_ramp'] = True
                gate = Gate(
                    parent=self,
                    name=alias,
                    **sens_param,
                )
                super().add_submodule(alias, gate)
                self.sensor_gates.append(gate)

        if ohmic_parameters is not None:
            for ohmic_id, ohm_param in ohmic_parameters.items():
                for required_param in required_parameter_fields:
                    assert ohm_param.get(required_param) is not None
                alias = f"ohmic_{ohmic_id}"
                ohm_param['ohmic_id'] = ohmic_id
                ohmic = Ohmic(
                    parent=self,
                    name=alias,
                    **ohm_param,
                )
                super().add_submodule(alias, ohmic)
                self.ohmics.append(ohmic)

        if initial_valid_ranges is None:
            initial_valid_ranges = {}
            for gate in self.gates:
                initial_valid_ranges[gate.layout_id()] = gate.safety_range()

        self._initial_valid_ranges: vltg_rngs_tp = {}
        super().add_parameter(
            name="initial_valid_ranges",
            label="initial valid ranges",
            docstring="",
            set_cmd=self.set_initial_valid_ranges,
            get_cmd=self.get_initial_valid_ranges,
            initial_value=initial_valid_ranges,
            vals=vals.Dict(),
        )

        super().add_parameter(
            name="quality",
            label="device quality",
            docstring="",
            set_cmd=None,
            get_cmd=None,
            initial_value=0,
            vals=vals.Numbers(),
        )
        if normalization_constants is not None:
            self._normalization_constants = normalization_constants
        else:
            self._normalization_constants = {
                key: (0, 1)
                for key in ["dc_current", "rf", "dc_sensor"]
            }

        super().add_parameter(
            name="normalization_constants",
            label="open circuit signal",
            docstring=("Signal measured with all gates at  zero. Used as "
                       "normalization during data post processing"),
            set_cmd=self.set_normalization_constants,
            get_cmd=self.get_normalization_constants,
            initial_value=self._normalization_constants,
            vals=vals.Dict(),
        )
Esempio n. 21
0
    def __init__(self, name, address, step_attenuator=False, **kwargs):
        super().__init__(name, address, **kwargs)

        # Only listed most common spellings idealy want a
        # .upper val for Enum or string
        on_off_validator = vals.Enum('on', 'On', 'ON', 'off', 'Off', 'OFF')
        on_off_mapping = create_on_off_val_mapping(1, 0)

        self.add_parameter(name='frequency',
                           label='Frequency',
                           unit='Hz',
                           get_cmd='FREQ:CW?',
                           set_cmd='FREQ:CW' + ' {:.4f}',
                           get_parser=float,
                           set_parser=float,
                           vals=vals.Numbers(1e5, 20e9),
                           docstring='Adjust the RF output frequency')
        self.add_parameter(name='frequency_offset',
                           label='Frequency offset',
                           unit='Hz',
                           get_cmd='FREQ:OFFS?',
                           set_cmd='FREQ:OFFS {}',
                           get_parser=float,
                           vals=Numbers(min_value=-200e9, max_value=200e9))
        self.add_parameter('frequency_mode',
                           label='Frequency mode',
                           set_cmd='FREQ:MODE {}',
                           get_cmd='FREQ:MODE?',
                           get_parser=lambda s: s.strip(),
                           vals=vals.Enum('FIX', 'CW', 'SWE', 'LIST'))
        self.add_parameter(name='phase',
                           label='Phase',
                           unit='deg',
                           get_cmd='PHASE?',
                           set_cmd='PHASE' + ' {:.8f}',
                           get_parser=self.rad_to_deg,
                           set_parser=self.deg_to_rad,
                           vals=vals.Numbers(-180, 180))
        self.add_parameter(name='power',
                           label='Power',
                           unit='dBm',
                           get_cmd='POW:AMPL?',
                           set_cmd='POW:AMPL' + ' {:.4f}',
                           get_parser=float,
                           set_parser=float,
                           vals=vals.Numbers(-130, 25))
        # self.add_parameter('status',
        self.add_parameter(
            'rf_output',  ### MLu edit 2020-04-07 Instrument driver looks for key 'rf_output'
            get_cmd=':OUTP?',
            set_cmd='OUTP {}',
            get_parser=parse_on_off,
            vals=on_off_validator)
        self.add_parameter(name='modulation_rf_enabled',
                           get_cmd='OUTP:MOD?',
                           set_cmd='OUTP:MOD {}',
                           val_mapping={
                               'on': 1,
                               'off': 0
                           })
        # val_mapping=on_off_mapping)
        self.add_parameter(
            'IQmodulator_enabled',
            get_cmd='DM:STATe?',
            set_cmd='DM:STATe {}',
            val_mapping=on_off_mapping,
            docstring=
            'Enables or disables the internal I/Q modulator. Source can be external or internal.'
        )

        for source in [1, 2]:
            self.add_parameter(f'IQsource{source}',
                               get_cmd=f'DM:SOUR{source}?',
                               set_cmd=f'DM:SOUR{source} {{}}',
                               get_parser=lambda s: s.strip(),
                               vals=vals.Enum('OFF', 'EXT', 'EXT600', 'INT'),
                               docstring=IQsource_docstring)

        self.add_parameter(f'IQadjustments_enabled',
                           get_cmd=f'DM:IQAD?',
                           set_cmd=f'DM:IQAD {{}}',
                           val_mapping=on_off_mapping,
                           docstring='Enable or disable IQ adjustments')

        IQoffset_parameters = dict(get_parser=float,
                                   set_parser=float,
                                   vals=vals.Numbers(-100, 100))
        self.add_parameter(f'I_offset',
                           get_cmd=f'DM:IQAD:IOFF?',
                           set_cmd=f'DM:IQAD:IOFF {{}}',
                           **IQoffset_parameters,
                           docstring='I channel offset in percentage')
        self.add_parameter(f'Q_offset',
                           get_cmd=f'DM:IQAD:QOFF?',
                           set_cmd=f'DM:IQAD:QOFF {{}}',
                           **IQoffset_parameters,
                           docstring='Q channel offset in percentage')
        self.add_parameter(f'IQ_quadrature',
                           get_cmd=f'DM:IQAD:QSK?',
                           set_cmd=f'DM:IQAD:QSK {{}}',
                           get_parser=float,
                           set_parser=float,
                           docstring='IQ quadrature offset',
                           unit='deg')

        self.add_parameter(f'pulse_modulation_enabled',
                           get_cmd=f'PULM:STATe?',
                           set_cmd=f'PULM:STATe {{}}',
                           val_mapping=on_off_mapping,
                           docstring='Enable or disable pulse modulation path')
        self.add_parameter(f'pulse_modulation_source',
                           get_cmd=f'PULM:SOURce?',
                           set_cmd=f'PULM:SOURce {{}}',
                           get_parser=lambda s: s.strip(),
                           vals=vals.Enum('EXT', 'INT', 'SCAL'))

        self.add_parameter(
            f'wideband_amplitude_modulation_enabled',
            get_cmd=f'AM:WID:STATe?',
            set_cmd=f'AM:WID:STATe {{}}',
            val_mapping=on_off_mapping,
            docstring=
            'This command enables or disables wideband amplitude modulation')

        self.connect_message()
Esempio n. 22
0
    def __init__(self, name, setup_folder, address, reset=False,
                 clock=1e9, numpoints=1000, timeout=180, **kwargs):
        '''
        Initializes the AWG5014.

        Input:
            name (string)           : name of the instrument
            setup_folder (string)   : folder where externally generate seqs
                                        are stored
            address (string)        : GPIB or ethernet address
            reset (bool)            : resets to default values, default=false
            numpoints (int)         : sets the number of datapoints
            timeout (float)         : visa timeout, in secs. long default (180)
                                        to accommodate large waveforms

        Output:
            None
        '''
        super().__init__(name, address, timeout=timeout, **kwargs)

        self._address = address

        self._values = {}
        self._values['files'] = {}
        self._clock = clock
        self._numpoints = numpoints

        self.add_function('reset', call_cmd='*RST')

        self.add_parameter('state',
                           get_cmd=self.get_state)
        self.add_parameter('run_mode',
                           get_cmd='AWGC:RMOD?',
                           set_cmd='AWGC:RMOD ' + '{}',
                           vals=vals.Enum('CONT', 'TRIG', 'SEQ', 'GAT'))
        # Trigger parameters #
        # ! Warning this is the same as run mode, do not use! exists
        # Solely for legacy purposes
        self.add_parameter('trigger_mode',
                           get_cmd='AWGC:RMOD?',
                           set_cmd='AWGC:RMOD ' + '{}',
                           vals=vals.Enum('CONT', 'TRIG', 'SEQ', 'GAT'))
        self.add_parameter('trigger_impedance',
                           label='Trigger impedance (Ohm)',
                           units='Ohm',
                           get_cmd='TRIG:IMP?',
                           set_cmd='TRIG:IMP ' + '{}',
                           vals=vals.Enum(50, 1000),
                           get_parser=float)
        self.add_parameter('trigger_level',
                           units='V',
                           label='Trigger level (V)',
                           get_cmd='TRIG:LEV?',
                           set_cmd='TRIG:LEV ' + '{:.3f}',
                           vals=vals.Numbers(-5, 5),
                           get_parser=float)
        self.add_parameter('trigger_slope',
                           get_cmd='TRIG:SLOP?',
                           set_cmd='TRIG:SLOP ' + '{}',
                           vals=vals.Enum('POS', 'NEG'))  # ,
                           # get_parser=self.parse_int_pos_neg)
        self.add_parameter('trigger_source',
                           get_cmd='TRIG:source?',
                           set_cmd='TRIG:source ' + '{}',
                           vals=vals.Enum('INT', 'EXT'))
        # Event parameters #
        self.add_parameter('event_polarity',
                           get_cmd='EVEN:POL?',
                           set_cmd='EVEN:POL ' + '{}',
                           vals=vals.Enum('POS', 'NEG'))
        self.add_parameter('event_impedance',
                           label='Event impedance (Ohm)',
                           get_cmd='EVEN:IMP?',
                           set_cmd='EVEN:IMP ' + '{}',
                           vals=vals.Enum(50, 1000),
                           get_parser=float)
        self.add_parameter('event_level',
                           label='Event level (V)',
                           get_cmd='EVEN:LEV?',
                           set_cmd='EVEN:LEV ' + '{:.3f}',
                           vals=vals.Numbers(-5, 5),
                           get_parser=float)
        self.add_parameter('event_jump_timing',
                           get_cmd='EVEN:JTIM?',
                           set_cmd='EVEN:JTIM {}',
                           vals=vals.Enum('SYNC', 'ASYNC'))

        self.add_parameter('clock_freq',
                           label='Clock frequency (Hz)',
                           get_cmd='SOUR:FREQ?',
                           set_cmd='SOUR:FREQ ' + '{}',
                           vals=vals.Numbers(1e6, 1.2e9),
                           get_parser=float)

        self.add_parameter('numpoints',
                           label='Number of datapoints per wave',
                           get_cmd=self._do_get_numpoints,
                           set_cmd=self._do_set_numpoints,
                           vals=vals.Ints(100, int(1e9)))
        self.add_parameter('setup_filename',
                           get_cmd='AWGC:SNAM?')
                           # set_cmd=self.do_set_setup_filename,
                           # vals=vals.Strings())
                           # set function has optional args and therefore
                           # does not work with QCodes

        # Channel parameters #
        for i in range(1, 5):
            amp_cmd = 'SOUR{}:VOLT:LEV:IMM:AMPL'.format(i)
            offset_cmd = 'SOUR{}:VOLT:LEV:IMM:OFFS'.format(i)
            state_cmd = 'OUTPUT{}:STATE'.format(i)
            waveform_cmd = 'SOUR{}:WAV'.format(i)
            # Set channel first to ensure sensible sorting of pars
            self.add_parameter('ch{}_state'.format(i),
                               label='Status channel {}'.format(i),
                               get_cmd=state_cmd + '?',
                               set_cmd=state_cmd + ' {}',
                               vals=vals.Ints(0, 1))
            self.add_parameter('ch{}_amp'.format(i),
                               label='Amplitude channel {} (Vpp)'.format(i),
                               units='Vpp',
                               get_cmd=amp_cmd + '?',
                               set_cmd=amp_cmd + ' {:.6f}',
                               vals=vals.Numbers(0.02, 4.5),
                               get_parser=float)
            self.add_parameter('ch{}_offset'.format(i),
                               label='Offset channel {} (V)'.format(i),
                               units='V',
                               get_cmd=offset_cmd + '?',
                               set_cmd=offset_cmd + ' {:.3f}',
                               vals=vals.Numbers(-.1, .1),
                               get_parser=float)
            self.add_parameter('ch{}_waveform'.format(i),
                               label='Waveform channel {}'.format(i),
                               get_cmd=waveform_cmd + '?',
                               set_cmd=waveform_cmd + ' "{}"',
                               vals=vals.Strings(),
                               get_parser=parsestr)
            # Marker channels
            for j in range(1, 3):
                m_del_cmd = 'SOUR{}:MARK{}:DEL'.format(i, j)
                m_high_cmd = 'SOUR{}:MARK{}:VOLT:LEV:IMM:HIGH'.format(i, j)
                m_low_cmd = 'SOUR{}:MARK{}:VOLT:LEV:IMM:LOW'.format(i, j)

                self.add_parameter(
                    'ch{}_m{}_del'.format(i, j),
                    label='Channel {} Marker {} delay (ns)'.format(i, j),
                    get_cmd=m_del_cmd + '?',
                    set_cmd=m_del_cmd + ' {:.3f}e-9',
                    vals=vals.Numbers(0, 1),
                    get_parser=float)
                self.add_parameter(
                    'ch{}_m{}_high'.format(i, j),
                    label='Channel {} Marker {} high level (V)'.format(i, j),
                    get_cmd=m_high_cmd + '?',
                    set_cmd=m_high_cmd + ' {:.3f}',
                    vals=vals.Numbers(-2.7, 2.7),
                    get_parser=float)
                self.add_parameter(
                    'ch{}_m{}_low'.format(i, j),
                    label='Channel {} Marker {} low level (V)'.format(i, j),
                    get_cmd=m_low_cmd + '?',
                    set_cmd=m_low_cmd + ' {:.3f}',
                    vals=vals.Numbers(-2.7, 2.7),
                    get_parser=float)

        # # Add functions

        # self.add_function('get_state')
        # self.add_function('set_event_jump_timing')
        # self.add_function('get_event_jump_timing')
        # self.add_function('generate_awg_file')
        # self.add_function('send_awg_file')
        # self.add_function('load_awg_file')
        # self.add_function('get_error')
        # self.add_function('pack_waveform')
        # self.add_function('clear_visa')
        # self.add_function('initialize_dc_waveforms')

        # # Setup filepaths
        self.waveform_folder = "Waveforms"
        self._rem_file_path = "Z:\\Waveforms\\"

        # NOTE! this directory has to exist on the AWG!!
        self._setup_folder = setup_folder

        self.goto_root()
        self.change_folder(self.waveform_folder)

        self.set('trigger_impedance', 50)
        if self.get('clock_freq') != 1e9:
            logging.warning('AWG clock freq not set to 1GHz')

        self.connect_message()
Esempio n. 23
0
    def __init__(self, name, address, number=2, **kwargs):
        """Initializes the Oxford Instruments IPS 120 Magnet Power Supply.

        Args:
            name (string)    : name of the instrument
            address (string) : instrument address
            number (int)     : ISOBUS instrument number
        """
        log.debug('Initializing instrument')
        super().__init__(name, address, **kwargs)

        self._address = address
        self._number = number
        self._values = {}
        self.visa_handle.set_visa_attribute(
            visa.constants.VI_ATTR_ASRL_STOP_BITS,
            visa.constants.VI_ASRL_STOP_TWO)

        # Add parameters
        self.add_parameter('mode',
                           get_cmd=self._get_mode,
                           set_cmd=self._set_mode,
                           vals=vals.Ints())
        self.add_parameter('mode2', get_cmd=self._get_mode2)
        self.add_parameter('activity',
                           get_cmd=self._get_activity,
                           set_cmd=self._set_activity,
                           vals=vals.Ints())
        self.add_parameter('switch_heater',
                           get_cmd=self._get_switch_heater,
                           set_cmd=self._set_switch_heater,
                           vals=vals.Ints())
        self.add_parameter('field_setpoint',
                           unit='T',
                           get_cmd=self._get_field_setpoint,
                           set_cmd=self._set_field_setpoint,
                           vals=vals.Numbers(-8, 8))
        self.add_parameter('sweeprate_field',
                           unit='T/min',
                           get_cmd=self._get_sweeprate_field,
                           set_cmd=self._set_sweeprate_field,
                           vals=vals.Numbers(0, 0.524))
        self.add_parameter('system_status', get_cmd=self._get_system_status)
        self.add_parameter('system_status2', get_cmd=self._get_system_status2)
        self.add_parameter('polarity', get_cmd=self._get_polarity)
        self.add_parameter('voltage', unit='V', get_cmd=self._get_voltage)
        self.add_parameter('voltage_limit',
                           unit='V',
                           get_cmd=self._get_voltage_limit)

        # Find the F field limits
        MaxField = self.field_setpoint.vals._max_value
        MinField = self.field_setpoint.vals._min_value
        MaxFieldSweep = self.sweeprate_field.vals._max_value
        MinFieldSweep = self.sweeprate_field.vals._min_value
        # A to B conversion
        ABconversion = 115.733 / 14  # Ampere per Tesla
        self.add_parameter('current_setpoint',
                           unit='A',
                           get_cmd=self._get_current_setpoint,
                           set_cmd=self._set_current_setpoint,
                           vals=vals.Numbers(ABconversion * MinField,
                                             ABconversion * MaxField))
        self.add_parameter('sweeprate_current',
                           unit='A/min',
                           get_cmd=self._get_sweeprate_current,
                           set_cmd=self._set_sweeprate_current,
                           vals=vals.Numbers(ABconversion * MinFieldSweep,
                                             ABconversion * MaxFieldSweep))
        self.add_parameter('remote_status',
                           get_cmd=self._get_remote_status,
                           set_cmd=self._set_remote_status,
                           vals=vals.Ints())
        self.add_parameter('current', unit='A', get_cmd=self._get_current)
        self.add_parameter('magnet_current',
                           unit='A',
                           get_cmd=self._get_magnet_current)
        self.add_parameter('field', unit='T', get_cmd=self._get_field)
        self.add_parameter('persistent_current',
                           unit='A',
                           get_cmd=self._get_persistent_current)
        self.add_parameter('persistent_field',
                           unit='T',
                           get_cmd=self._get_persistent_field)
        self.add_parameter('magnet_inductance',
                           unit='H',
                           get_cmd=self._get_magnet_inductance)
        self.add_parameter('lead_resistance',
                           unit='mOhm',
                           get_cmd=self._get_lead_resistance)
        self.add_parameter('current_limit_lower',
                           unit='A',
                           get_cmd=self._get_current_limit_lower)
        self.add_parameter('current_limit_upper',
                           unit='A',
                           get_cmd=self._get_current_limit_upper)
        self.add_parameter('heater_current',
                           unit='mA',
                           get_cmd=self._get_heater_current)
        self.add_parameter('trip_field',
                           unit='T',
                           get_cmd=self._get_trip_field)
        self.add_parameter('trip_current',
                           unit='A',
                           get_cmd=self._get_trip_current)

        # to handle VisaIOError which occurs at first read
        try:
            self.visa_handle.write('@%s%s' % (self._number, 'V'))
            sleep(100e-3)
            self._read()
        except visa.VisaIOError:
            pass
    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))
Esempio n. 25
0
    def __init__(self, parent: "Infiniium", name: str, channel: int,
                 **kwargs: Any):
        """
        Initialize an infiniium channel.
        """
        self._channel = channel

        super().__init__(parent, name, **kwargs)
        # display
        self.display = Parameter(
            name="display",
            instrument=self,
            label=f"Channel {channel} display on/off",
            set_cmd=f"CHAN{channel}:DISP {{}}",
            get_cmd=f"CHAN{channel}:DISP?",
            val_mapping=create_on_off_val_mapping(on_val=1, off_val=0),
        )

        # scaling
        self.offset = Parameter(
            name="offset",
            instrument=self,
            label=f"Channel {channel} offset",
            set_cmd=f"CHAN{channel}:OFFS {{}}",
            unit="V",
            get_cmd=f"CHAN{channel}:OFFS?",
            get_parser=float,
        )
        self.range = Parameter(
            name="range",
            instrument=self,
            label=f"Channel {channel} range",
            unit="V",
            set_cmd=f"CHAN{channel}:RANG {{}}",
            get_cmd=f"CHAN{channel}:RANG?",
            get_parser=float,
            vals=vals.Numbers(),
        )

        # Trigger level
        self.trigger_level = Parameter(
            name="trigger_level",
            instrument=self,
            label=f"Channel {channel} trigger level",
            unit="V",
            set_cmd=f":TRIG:LEV CHAN{channel},{{}}",
            get_cmd=f":TRIG:LEV? CHAN{channel}",
            get_parser=float,
            vals=vals.Numbers(),
        )

        # Trace data
        self.time_axis = DSOTimeAxisParam(
            name="time_axis",
            instrument=self,
            label="Time",
            unit="s",
            xorigin=0.0,
            xincrement=0.0,
            points=1,
            vals=vals.Arrays(shape=(self.parent.acquire_points, )),
            snapshot_value=False,
        )
        self.trace = DSOTraceParam(
            name="trace",
            instrument=self,
            label=f"Channel {channel} trace",
            unit="V",
            channel=self.channel_name,
            vals=vals.Arrays(shape=(self.parent.acquire_points, )),
            snapshot_value=False,
        )

        # Measurement subsystem
        self.add_submodule("measure", BoundMeasurement(self, "measure"))
Esempio n. 26
0
    def __init__(self, parent: 'DG1062', name: str, channel: int):
        """
        Args:
            parent: The instrument this channel belongs to
            name (str)
            channel (int)
        """

        super().__init__(parent, name)
        self.channel = channel

        for param, unit in [
            ("freq", "Hz"),
            ("ampl", "V"),
            ("offset", "V"),
            ("phase", "deg"),
            ("sample_rate", "1/s")
        ]:
            self.add_parameter(
                param,
                unit=unit,
                get_cmd=partial(self._get_waveform_param, param),
                set_cmd=partial(self._set_waveform_param, param),
            )

        self.add_parameter(
            "waveform",
            get_cmd=partial(self._get_waveform_param, "waveform")
        )

        self.add_parameter(
            "impedance",
            get_cmd=f":OUTPUT{channel}:IMP?",
            set_cmd=f":OUTPUT{channel}:IMP {{}}",
            unit="Ohm",
            vals=vals.MultiType(
                vals.Ints(
                    min_value=DG1062Channel.min_impedance,
                    max_value=DG1062Channel.max_impedance
                ),
                vals.Enum("INF", "MIN", "MAX", "HighZ")
            ),
            get_parser=(lambda value: "HighZ"
                            if float(value) > DG1062Channel.max_impedance
                            else float(value)),
            set_parser=lambda value: "INF" if value == "HighZ" else value
        )

        self.add_parameter(
            "sync",
            get_cmd=f":OUTPUT{channel}:SYNC?",
            set_cmd=f"OUTPUT{channel}:SYNC {{}}",
            vals=vals.Enum(0, 1, "ON", "OFF"),
        )

        self.add_parameter(
            "polarity",
            get_cmd=f":OUTPUT{channel}:GAT:POL?",
            set_cmd=f":OUTPUT{channel}:GAT:POL {{}}",
            vals=vals.OnOff(),
            val_mapping={1: 'POSITIVE', 0: 'NEGATIVE'},
        )

        self.add_parameter(
            "state",
            get_cmd=f"OUTPUT{channel}:STATE?",
            set_cmd=f"OUTPUT{channel}:STATE {{}}",
        )

        self.add_parameter(
            "duty_cycle",
            get_cmd=self._get_duty_cycle,
            set_cmd=self._set_duty_cycle,
            unit="%",
            vals=vals.Numbers(min_value=1, max_value=99),
            docstring=('This functions reads/sets the duty '
                       'cycle for a square and pulse wave '
                       'since these inherit a duty cycle.\n'
                       'For other waveforms it will give '
                       'the user an error')
        )

        burst = DG1062Burst(cast(DG1062, self.parent), "burst", self.channel)
        self.add_submodule("burst", burst)

        # We want to be able to do the following:
        # >>> help(gd.channels[0].sin)
        # >>> gd.channels[0].sin(freq=2E3, ampl=1.0, offset=0, phase=0)
        # We do not use add_function as it is more cumbersome to use.
        for waveform in self.waveforms:
            f = partial_with_docstring(
                self.apply,
                docstring="Args: " + ", ".join(self.waveform_params[waveform]),
                waveform=waveform
            )
            setattr(self, waveform.lower(), f)

        # Retrieve current waveform from device
        self.waveform()
Esempio n. 27
0
    def __init__(self,
                 name: str,
                 address: str,
                 num_channels: int,
                 timeout: float = 10,
                 **kwargs) -> None:
        """
        Args:
            name: The name used internally by QCoDeS in the DataSet
            address: The VISA resource name of the instrument
            timeout: The VISA timeout time (in seconds)
            num_channels: Number of channels on the AWG
        """

        self.num_channels = num_channels

        super().__init__(name,
                         address,
                         timeout=timeout,
                         terminator='\n',
                         **kwargs)

        # The 'model' value begins with 'AWG'
        self.model = self.IDN()['model'][3:]

        if self.model not in ['70001A', '70002A']:
            raise ValueError('Unknown model type: {}. Are you using '
                             'the right driver for your instrument?'
                             ''.format(self.model))

        self.add_parameter('current_directory',
                           label='Current file system directory',
                           set_cmd='MMEMory:CDIRectory "{}"',
                           get_cmd='MMEMory:CDIRectory?',
                           vals=vals.Strings())

        self.add_parameter('mode',
                           label='Instrument operation mode',
                           set_cmd='INSTrument:MODE {}',
                           get_cmd='INSTrument:MODE?',
                           vals=vals.Enum('AWG', 'FGEN'))

        ##################################################
        # Clock parameters

        self.add_parameter('sample_rate',
                           label='Clock sample rate',
                           set_cmd='CLOCk:SRATe {}',
                           get_cmd='CLOCk:SRATe?',
                           unit='Sa/s',
                           get_parser=float,
                           vals=SRValidator(self))

        self.add_parameter('clock_source',
                           label='Clock source',
                           set_cmd='CLOCk:SOURce {}',
                           get_cmd='CLOCk:SOURce?',
                           val_mapping={
                               'Internal': 'INT',
                               'Internal, 10 MHZ ref.': 'EFIX',
                               'Internal, variable ref.': 'EVAR',
                               'External': 'EXT'
                           })

        self.add_parameter('clock_external_frequency',
                           label='External clock frequency',
                           set_cmd='CLOCk:ECLock:FREQuency {}',
                           get_cmd='CLOCk:ECLock:FREQuency?',
                           get_parser=float,
                           unit='Hz',
                           vals=vals.Numbers(6.25e9, 12.5e9))

        for ch_num in range(1, num_channels + 1):
            ch_name = 'ch{}'.format(ch_num)
            channel = AWGChannel(self, ch_name, ch_num)
            self.add_submodule(ch_name, channel)

        # Folder on the AWG where to files are uplaoded by default
        self.wfmxFileFolder = "\\Users\\OEM\\Documents"
        self.seqxFileFolder = "\\Users\\OEM\Documents"

        self.current_directory(self.wfmxFileFolder)

        self.connect_message()
Esempio n. 28
0
    def __init__(self, parent: 'DG1062', name: str, channel: int):
        super().__init__(parent, name)
        self.channel = channel

        self.add_parameter(
            "on",
            get_cmd=f":SOUR{channel}:BURS?",
            set_cmd=f":SOUR{channel}:BURS {{}}",
            vals=vals.Enum(0, 1, "ON", "OFF")
        )

        self.add_parameter(
            "polarity",
            get_cmd=f":SOUR{channel}:BURS:GATE:POL?",
            set_cmd=f":SOUR{channel}:BURS:GATE:POL {{}}",
            vals=vals.Enum("NORM", "INV")
        )

        self.add_parameter(
            "period",
            get_cmd=f":SOUR{channel}:BURS:INT:PER?",
            set_cmd=f":SOUR{channel}:BURS:INT:PER {{}}",
            vals=vals.MultiType(
                vals.Numbers(min_value=3E-6, max_value=500),
                vals.Enum("MIN", "MAX")
            )
        )

        self.add_parameter(
            "mode",
            get_cmd=f":SOUR{channel}:BURS:MODE?",
            set_cmd=f":SOUR{channel}:BURS:MODE {{}}",
            vals=vals.Enum("TRIG", "INF", "GAT")
        )

        self.add_parameter(
            "ncycles",
            get_cmd=f":SOUR{channel}:BURS:NCYC?",
            set_cmd=f":SOUR{channel}:BURS:NCYC {{}}",
            vals=vals.Numbers(min_value=1, max_value=500000)
        )

        self.add_parameter(
            "phase",
            get_cmd=f":SOUR{channel}:BURS:PHAS?",
            set_cmd=f":SOUR{channel}:BURS:PHAS {{}}",
            vals=vals.Numbers(min_value=0, max_value=360)
        )

        self.add_parameter(
            "time_delay",
            get_cmd=f":SOUR{channel}:BURS:TDEL?",
            set_cmd=f":SOUR{channel}:BURS:TDEL {{}}",
            vals=vals.Numbers(min_value=0)
        )

        self.add_parameter(
            "trigger_slope",
            get_cmd=f":SOUR{channel}:BURS:TRIG:SLOP?",
            set_cmd=f":SOUR{channel}:BURS:TRIG:SLOP {{}}",
            vals=vals.Enum("POS", "NEG")
        )

        self.add_parameter(
            "source",
            get_cmd=f":SOUR{channel}:BURS:TRIG:SOUR?",
            set_cmd=f":SOUR{channel}:BURS:TRIG:SOUR {{}}",
            vals=vals.Enum("INT", "EXT", "MAN")
        )

        self.add_parameter(
            "idle",
            get_cmd=f":SOUR{channel}:BURST:IDLE?",
            set_cmd=f":SOUR{channel}:BURST:IDLE {{}}",
            vals=vals.MultiType(
                vals.Enum("FPT", "TOP", "BOTTOM", "CENTER"),
                vals.Numbers()  # DIY
            )
        )
Esempio n. 29
0
    def __init__(self,
                 name,
                 address,
                 reset=False,
                 numdacs=16,
                 dac_step=10,
                 dac_delay=.1,
                 safe_version=True,
                 polarity=['BIP', 'BIP', 'BIP', 'BIP'],
                 use_locks=False,
                 **kwargs):
        '''
        Initialzes the IVVI, and communicates with the wrapper

        Args:
            name (string)        : name of the instrument
            address (string)     : ASRL address
            reset (bool)         : resets to default values, default=false
            numdacs (int)        : number of dacs, multiple of 4, default=16
            polarity (string[4]) : list of polarities of each set of 4 dacs
                                   choose from 'BIP', 'POS', 'NEG',
                                   default=['BIP', 'BIP', 'BIP', 'BIP']
            dac_step (float)         : max step size for dac parameter
            dac_delay (float)        : delay (in seconds) for dac
            safe_version (bool)    : if True then do not send version commands
                                     to the IVVI controller
            use_locks (bool) : if True then locks are used in the `ask`
                              function of the driver. The IVVI driver is not
                              thread safe, this locking mechanism makes it
                              thread safe at the cost of making the call to ask
                              blocking.
        '''
        t0 = time.time()
        super().__init__(name, address, **kwargs)
        if use_locks:
            self.lock = threading.Lock()
        else:
            self.lock = None

        self.safe_version = safe_version

        if numdacs % 4 == 0 and numdacs > 0:
            self._numdacs = int(numdacs)
        else:
            raise ValueError('numdacs must be a positive multiple of 4, '
                             'not {}'.format(numdacs))

        # values based on descriptor
        self.visa_handle.baud_rate = 115200
        self.visa_handle.parity = visa.constants.Parity(1)  # odd parity
        self.visa_handle.write_termination = ''
        self.visa_handle.read_termination = ''

        self.add_parameter('version', get_cmd=self._get_version)

        self.add_parameter('check_setpoints',
                           get_cmd=None,
                           set_cmd=None,
                           initial_value=False,
                           label='Check setpoints',
                           vals=Bool(),
                           docstring=('Whether to check if the setpoint is the'
                                      ' same as the current DAC value to '
                                      'prevent an unnecessary set command.'))

        # Time to wait before sending a set DAC command to the IVVI
        self.add_parameter('dac_set_sleep',
                           get_cmd=None,
                           set_cmd=None,
                           initial_value=0.05,
                           label='DAC set sleep',
                           unit='s',
                           vals=Numbers(0),
                           docstring=('When check_setpoints is set to True, '
                                      'this is the waiting time between the'
                                      'command that checks the current DAC '
                                      'values and the final set DAC command'))

        # Minimum time to wait before the read buffer contains data
        self.add_parameter('dac_read_buffer_sleep',
                           get_cmd=None,
                           set_cmd=None,
                           initial_value=0.025,
                           label='DAC read buffer sleep',
                           unit='s',
                           vals=Numbers(0),
                           docstring=('While receiving bytes from the IVVI, '
                                      'sleeping is done in multiples of this '
                                      'value. Change to a lower value for '
                                      'a shorter minimum time to wait.'))

        self.add_parameter('dac voltages',
                           label='Dac voltages',
                           get_cmd=self._get_dacs)

        self.add_function('trigger', call_cmd=self._send_trigger)

        # initialize pol_num, the voltage offset due to the polarity
        self.pol_num = np.zeros(self._numdacs)
        for i in range(int(self._numdacs / 4)):
            self.set_pol_dacrack(polarity[i],
                                 np.arange(1 + i * 4, 1 + (i + 1) * 4),
                                 get_all=False)

        for i in range(1, numdacs + 1):
            self.add_parameter('dac{}'.format(i),
                               label='Dac {}'.format(i),
                               unit='mV',
                               get_cmd=self._gen_ch_get_func(self._get_dac, i),
                               set_cmd=self._gen_ch_set_func(self._set_dac, i),
                               vals=vals.Numbers(
                                   self.pol_num[i - 1],
                                   self.pol_num[i - 1] + self.Fullrange),
                               step=dac_step,
                               inter_delay=dac_delay,
                               max_val_age=10)

        self._update_time = 5  # seconds
        self._time_last_update = 0  # ensures first call will always update

        t1 = time.time()

        # make sure we ignore termination characters
        # See http://www.ni.com/tutorial/4256/en/#toc2 on Termination Character
        # Enabled
        v = self.visa_handle
        v.set_visa_attribute(visa.constants.VI_ATTR_TERMCHAR_EN, 0)
        v.set_visa_attribute(visa.constants.VI_ATTR_ASRL_END_IN, 0)
        v.set_visa_attribute(visa.constants.VI_ATTR_ASRL_END_OUT, 0)
        v.set_visa_attribute(visa.constants.VI_ATTR_SEND_END_EN, 0)

        # basic test to confirm we are properly connected
        try:
            self.get_all()
        except Exception as ex:
            print('IVVI: get_all() failed, maybe connected to wrong port?')
            print(traceback.format_exc())

        print('Initialized IVVI-rack in %.2fs' % (t1 - t0))
Esempio n. 30
0
    def __init__(self,
                 name,
                 address='COM5',
                 spi_module=1,
                 spi_baud=1000000,
                 spi_timeout=1,
                 reset=False,
                 dac_step=10,
                 dac_delay=.1,
                 dac_max_delay=0.2,
                 divider=1000,
                 safe_version=True,
                 use_locks=True,
                 **kwargs):
        """
        Initialzes the D5a, and communicates with the wrapper

        Args:
            name (string)        : name of the instrument
            address (string)     : ASRL address
            reset (bool)         : resets to default values, default=false
            dac_step (float)         : max step size for dac parameter
            dac_delay (float)        : delay (in seconds) for dac
            dac_max_delay (float)    : maximum delay before emitting a warning
        """
        self.verbose = 1
        self.spi_rack = SPI_rack(address, spi_baud, spi_timeout)
        self.spi_rack.unlock()

        self.D5a = D5a_module(self.spi_rack, spi_module, reset_voltages=reset)

        t0 = time.time()
        super().__init__(name, **kwargs)
        if use_locks:
            self.lock = threading.Lock()
        else:
            self.lock = None

        self._numdacs = 16
        self.divider = divider
        self._dacoffset = 1

        if divider == 1000:
            unit = 'mV'
        elif divider == 1:
            unit = 'V'
        else:
            unit = 'a.u.'

        for i in range(self._dacoffset, self._numdacs + self._dacoffset):
            self.add_parameter('dac{}'.format(i),
                               label='dac{} '.format(i),
                               unit=unit,
                               get_cmd=partial(self._get_voltage,
                                               i - self._dacoffset),
                               set_cmd=partial(self._set_voltage,
                                               i - self._dacoffset),
                               vals=vals.Numbers(-2000, 2000),
                               step=dac_step,
                               delay=dac_delay,
                               max_delay=dac_max_delay,
                               max_val_age=10)

        t1 = time.time()

        if self.verbose:
            print('Initialized %s in %.2fs' % (self.name, t1 - t0))