Example #1
0
    def __init__(self, name: str, address: str, num_channels: int,
                 **kwargs: Any) -> None:
        super().__init__(name, address, **kwargs)

        self.max_current = _RohdeSchwarzHMC804x._max_currents[num_channels]

        self.add_parameter('state',
                           label='Output enabled',
                           set_cmd='OUTPut:MASTer:STATe {}',
                           get_cmd='OUTPut:MASTer:STATe?',
                           val_mapping={
                               'ON': 1,
                               'OFF': 0
                           },
                           vals=vals.Enum('ON', 'OFF'))

        # channel-specific parameters
        channels = ChannelList(self,
                               "SupplyChannel",
                               RohdeSchwarzHMC804xChannel,
                               snapshotable=False)
        for ch_num in range(1, num_channels + 1):
            ch_name = f"ch{ch_num}"
            channel = RohdeSchwarzHMC804xChannel(self, ch_name, ch_num)
            channels.append(channel)
            self.add_submodule(ch_name, channel)
        self.add_submodule("channels", channels.to_channel_tuple())

        self.connect_message()
Example #2
0
    def __init__(self,
                 name: str,
                 address: str,
                 min_val: number = -5,
                 max_val: number = 5,
                 **kwargs) -> None:
        """

        Creates an instance of the Decadac instruments

        Args:
            name: What this instrument is called locally.

            address: The address of the DAC. For a serial port this
                is ASRLn::INSTR where n is replaced with the address set in the
                VISA control panel. Baud rate and other serial parameters must
                also be set in the VISA control panel.

            min_val: The minimum value in volts that can be output by the DAC.
                This value should correspond to the DAC code 0.

            max_val: The maximum value in volts that can be output by the DAC.
                This value should correspond to the DAC code 65536.

        """

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

        # Do feature detection
        self._feature_detect()

        # Create channels
        channels = ChannelList(self,
                               "Channels",
                               self.DAC_CHANNEL_CLASS,
                               snapshotable=False)
        slots = ChannelList(self, "Slots", self.DAC_SLOT_CLASS)
        for i in range(5):  # Create the 6 DAC slots
            slots.append(
                self.DAC_SLOT_CLASS(self, f"Slot{i}", i, min_val, max_val))
            slot_channels = slots[i].channels
            slot_channels = cast(ChannelList, slot_channels)
            channels.extend(slot_channels)
        self.add_submodule("slots", slots.to_channel_tuple())
        self.add_submodule("channels", channels.to_channel_tuple())

        self.connect_message()
Example #3
0
    def __init__(self, name: str, address: str, **kwargs: Any) -> None:
        super().__init__(name, address, terminator="\r\n", **kwargs)

        sensors = ChannelList(self,
                              "sensor",
                              Model_325_Sensor,
                              snapshotable=False)

        for inp in ['A', 'B']:
            sensor = Model_325_Sensor(self, f'sensor_{inp}', inp)
            sensors.append(sensor)
            self.add_submodule(f'sensor_{inp}', sensor)

        self.add_submodule("sensor", sensors.to_channel_tuple())

        heaters = ChannelList(self,
                              "heater",
                              Model_325_Heater,
                              snapshotable=False)

        for loop in [1, 2]:
            heater = Model_325_Heater(self, f'heater_{loop}', loop)
            heaters.append(heater)
            self.add_submodule(f'heater_{loop}', heater)

        self.add_submodule("heater", heaters.to_channel_tuple())

        curves = ChannelList(self,
                             "curve",
                             Model_325_Curve,
                             snapshotable=False)

        for curve_index in range(1, 35):
            curve = Model_325_Curve(self, curve_index)
            curves.append(curve)

        self.add_submodule("curve", curves)

        self.connect_message()
Example #4
0
    def __init__(self,
                 name: str,
                 address: str,
                 terminator: str = '\r\n',
                 **kwargs: Any) -> None:
        super().__init__(name, address, terminator=terminator, **kwargs)

        # Allow access to channels either by referring to the channel name
        # or through a channel list, i.e. instr.A.temperature() and
        # instr.channels[0].temperature() refer to the same parameter.
        # Note that `snapshotable` is set to false in order to avoid duplicate
        # snapshotting which otherwise will happen because each channel is also
        # added as a submodule to the instrument.
        channels = ChannelList(self,
                               "TempSensors",
                               self.CHANNEL_CLASS,
                               snapshotable=False)
        for name, command in self.channel_name_command.items():
            channel = self.CHANNEL_CLASS(self, name, command)
            channels.append(channel)
            self.add_submodule(name, channel)
        self.add_submodule("channels", channels.to_channel_tuple())

        self.connect_message()
Example #5
0
    def __init__(self, name: str, address: str, **kwargs: Any) -> None:
        """
        Args:
            name: Name to use internally in QCoDeS.
            address: VISA resource address
        """
        super().__init__(name, address, terminator='\n', **kwargs)

        channels = ChannelList(self,
                               "Channels",
                               AimTTiChannel,
                               snapshotable=False)

        _model = self.get_idn()['model']

        _numOutputChannels = {
            'PL068-P': 1,
            'PL155-P': 1,
            'PL303-P': 1,
            'PL601-P': 1,
            'PL303QMD-P': 2,
            'PL303QMT': 3
        }

        if (not _model in _numOutputChannels.keys()) or (_model is None):
            raise NotKnownModel("Unknown model, connection cannot be "
                                "established.")

        self.numOfChannels = _numOutputChannels[_model]
        for i in range(1, self.numOfChannels + 1):
            channel = AimTTiChannel(self, f'ch{i}', i)
            channels.append(channel)
            self.add_submodule(f'ch{i}', channel)

        self.add_submodule("channels", channels.to_channel_tuple())
        self.connect_message()
Example #6
0
    def __init__(self,
                 name: str,
                 address: str,
                 timeout: float = 20,
                 **kwargs: Any):
        """
        Initialises the TPS2012.

        Args:
            name: Name of the instrument used by QCoDeS
            address: Instrument address as used by VISA
            timeout: visa timeout, in secs. long default (180)
              to accommodate large waveforms
        """

        super().__init__(name, address, timeout=timeout, **kwargs)
        self.connect_message()

        # Scope trace boolean
        self.trace_ready = False

        # functions

        self.add_function('force_trigger',
                          call_cmd='TRIGger FORce',
                          docstring='Force trigger event')
        self.add_function('run',
                          call_cmd='ACQuire:STATE RUN',
                          docstring='Start acquisition')
        self.add_function('stop',
                          call_cmd='ACQuire:STATE STOP',
                          docstring='Stop acquisition')

        # general parameters
        self.add_parameter('trigger_type',
                           label='Type of the trigger',
                           get_cmd='TRIGger:MAIn:TYPe?',
                           set_cmd='TRIGger:MAIn:TYPe {}',
                           vals=vals.Enum('EDGE', 'VIDEO', 'PULSE'))
        self.add_parameter('trigger_source',
                           label='Source for the trigger',
                           get_cmd='TRIGger:MAIn:EDGE:SOURce?',
                           set_cmd='TRIGger:MAIn:EDGE:SOURce {}',
                           vals=vals.Enum('CH1', 'CH2'))
        self.add_parameter('trigger_edge_slope',
                           label='Slope for edge trigger',
                           get_cmd='TRIGger:MAIn:EDGE:SLOpe?',
                           set_cmd='TRIGger:MAIn:EDGE:SLOpe {}',
                           vals=vals.Enum('FALL', 'RISE'))
        self.add_parameter('trigger_level',
                           label='Trigger level',
                           unit='V',
                           get_cmd='TRIGger:MAIn:LEVel?',
                           set_cmd='TRIGger:MAIn:LEVel {}',
                           vals=vals.Numbers())
        self.add_parameter('data_source',
                           label='Data source',
                           get_cmd='DATa:SOUrce?',
                           set_cmd='DATa:SOURce {}',
                           vals=vals.Enum('CH1', 'CH2'))
        self.add_parameter('horizontal_scale',
                           label='Horizontal scale',
                           unit='s',
                           get_cmd='HORizontal:SCAle?',
                           set_cmd=self._set_timescale,
                           get_parser=float,
                           vals=vals.Enum(5e-9, 10e-9, 25e-9, 50e-9, 100e-9,
                                          250e-9, 500e-9, 1e-6, 2.5e-6, 5e-6,
                                          10e-6, 25e-6, 50e-6, 100e-6, 250e-6,
                                          500e-6, 1e-3, 2.5e-3, 5e-3, 10e-3,
                                          25e-3, 50e-3, 100e-3, 250e-3, 500e-3,
                                          1, 2.5, 5, 10, 25, 50))

        # channel-specific parameters
        channels = ChannelList(self,
                               "ScopeChannels",
                               TPS2012Channel,
                               snapshotable=False)
        for ch_num in range(1, 3):
            ch_name = f"ch{ch_num}"
            channel = TPS2012Channel(self, ch_name, ch_num)
            channels.append(channel)
            self.add_submodule(ch_name, channel)
        self.add_submodule("channels", channels.to_channel_tuple())

        # Necessary settings for parsing the binary curve data
        self.visa_handle.encoding = 'latin-1'
        log.info('Set VISA encoding to latin-1')
        self.write('DATa:ENCdg RPBinary')
        log.info('Set TPS2012 data encoding to RPBinary' +
                 ' (Positive Integer Binary)')
        self.write('DATa:WIDTh 2')
        log.info('Set TPS2012 data width to 2')
Example #7
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)
        self.add_submodule("channels", channels.to_channel_tuple())

        # Submodules
        meassubsys = MeasurementSubsystem(self, 'measure')
        self.add_submodule('measure', meassubsys)
Example #8
0
    def __init__(
            self,
            name: str,
            address: str,
            # Set frequency ranges
            min_freq: Union[int, float],
            max_freq: Union[int, float],
            # Set power ranges
            min_power: Union[int, float],
            max_power: Union[int, float],
            nports: int,  # Number of ports on the PNA
            **kwargs: Any) -> None:
        super().__init__(name, address, terminator='\n', **kwargs)
        self.min_freq = min_freq
        self.max_freq = max_freq

        self.log.info(
            "Initializing %s with power range %r-%r, freq range %r-%r.", name,
            min_power, max_power, min_freq, max_freq)

        #Ports
        ports = ChannelList(self, "PNAPorts", PNAPort)
        for port_num in range(1, nports + 1):
            port = PNAPort(self, f"port{port_num}", port_num, min_power,
                           max_power)
            ports.append(port)
            self.add_submodule(f"port{port_num}", port)
        self.add_submodule("ports", ports.to_channel_tuple())

        # Drive power
        self.add_parameter('power',
                           label='Power',
                           get_cmd='SOUR:POW?',
                           get_parser=float,
                           set_cmd='SOUR:POW {:.2f}',
                           unit='dBm',
                           vals=Numbers(min_value=min_power,
                                        max_value=max_power))

        # IF bandwidth
        self.add_parameter('if_bandwidth',
                           label='IF Bandwidth',
                           get_cmd='SENS:BAND?',
                           get_parser=float,
                           set_cmd='SENS:BAND {:.2f}',
                           unit='Hz',
                           vals=Numbers(min_value=1, max_value=15e6))

        # Number of averages (also resets averages)
        self.add_parameter('averages_enabled',
                           label='Averages Enabled',
                           get_cmd="SENS:AVER?",
                           set_cmd="SENS:AVER {}",
                           val_mapping={
                               True: '1',
                               False: '0'
                           })
        self.add_parameter('averages',
                           label='Averages',
                           get_cmd='SENS:AVER:COUN?',
                           get_parser=int,
                           set_cmd='SENS:AVER:COUN {:d}',
                           unit='',
                           vals=Numbers(min_value=1, max_value=65536))

        # Setting frequency range
        self.add_parameter('start',
                           label='Start Frequency',
                           get_cmd='SENS:FREQ:STAR?',
                           get_parser=float,
                           set_cmd='SENS:FREQ:STAR {}',
                           unit='Hz',
                           vals=Numbers(min_value=min_freq,
                                        max_value=max_freq))
        self.add_parameter('stop',
                           label='Stop Frequency',
                           get_cmd='SENS:FREQ:STOP?',
                           get_parser=float,
                           set_cmd='SENS:FREQ:STOP {}',
                           unit='Hz',
                           vals=Numbers(min_value=min_freq,
                                        max_value=max_freq))
        self.add_parameter('center',
                           label='Center Frequency',
                           get_cmd='SENS:FREQ:CENT?',
                           get_parser=float,
                           set_cmd='SENS:FREQ:CENT {}',
                           unit='Hz',
                           vals=Numbers(min_value=min_freq,
                                        max_value=max_freq))
        self.add_parameter('span',
                           label='Frequency Span',
                           get_cmd='SENS:FREQ:SPAN?',
                           get_parser=float,
                           set_cmd='SENS:FREQ:SPAN {}',
                           unit='Hz',
                           vals=Numbers(min_value=min_freq,
                                        max_value=max_freq))
        self.add_parameter('cw',
                           label='CW Frequency',
                           get_cmd='SENS:FREQ:CW?',
                           get_parser=float,
                           set_cmd='SENS:FREQ:CW {}',
                           unit='Hz',
                           vals=Numbers(min_value=min_freq,
                                        max_value=max_freq))

        # Number of points in a sweep
        self.add_parameter('points',
                           label='Points',
                           get_cmd='SENS:SWE:POIN?',
                           get_parser=int,
                           set_cmd='SENS:SWE:POIN {}',
                           unit='',
                           vals=Numbers(min_value=1, max_value=100001))

        # Electrical delay
        self.add_parameter('electrical_delay',
                           label='Electrical Delay',
                           get_cmd='CALC:CORR:EDEL:TIME?',
                           get_parser=float,
                           set_cmd='CALC:CORR:EDEL:TIME {:.6e}',
                           unit='s',
                           vals=Numbers(min_value=0, max_value=100000))

        # Sweep Time
        self.add_parameter('sweep_time',
                           label='Time',
                           get_cmd='SENS:SWE:TIME?',
                           get_parser=float,
                           unit='s',
                           vals=Numbers(0, 1e6))
        # Sweep Mode
        self.add_parameter('sweep_mode',
                           label='Mode',
                           get_cmd='SENS:SWE:MODE?',
                           set_cmd='SENS:SWE:MODE {}',
                           vals=Enum("HOLD", "CONT", "GRO", "SING"))
        # Sweep Type
        self.add_parameter('sweep_type',
                           label='Type',
                           get_cmd='SENS:SWE:TYPE?',
                           set_cmd='SENS:SWE:TYPE {}',
                           vals=Enum('LIN', 'LOG', 'POW', 'CW', 'SEGM',
                                     'PHAS'))

        # Group trigger count
        self.add_parameter('group_trigger_count',
                           get_cmd="SENS:SWE:GRO:COUN?",
                           get_parser=int,
                           set_cmd="SENS:SWE:GRO:COUN {}",
                           vals=Ints(1, 2000000))
        # Trigger Source
        self.add_parameter('trigger_source',
                           get_cmd="TRIG:SOUR?",
                           set_cmd="TRIG:SOUR {}",
                           vals=Enum("EXT", "IMM", "MAN"))

        # Axis Parameters
        self.add_parameter('frequency_axis',
                           unit='Hz',
                           label="Frequency",
                           parameter_class=PNAAxisParameter,
                           startparam=self.start,
                           stopparam=self.stop,
                           pointsparam=self.points,
                           vals=Arrays(shape=(self.points, )))
        self.add_parameter('frequency_log_axis',
                           unit='Hz',
                           label="Frequency",
                           parameter_class=PNALogAxisParamter,
                           startparam=self.start,
                           stopparam=self.stop,
                           pointsparam=self.points,
                           vals=Arrays(shape=(self.points, )))
        self.add_parameter('time_axis',
                           unit='s',
                           label="Time",
                           parameter_class=PNATimeAxisParameter,
                           startparam=None,
                           stopparam=self.sweep_time,
                           pointsparam=self.points,
                           vals=Arrays(shape=(self.points, )))

        # Traces
        self.add_parameter('active_trace',
                           label='Active Trace',
                           get_cmd="CALC:PAR:MNUM?",
                           get_parser=int,
                           set_cmd="CALC:PAR:MNUM {}",
                           vals=Numbers(min_value=1, max_value=24))
        # Note: Traces will be accessed through the traces property which
        # updates the channellist to include only active trace numbers
        self._traces = ChannelList(self, "PNATraces", PNATrace)
        self.add_submodule("traces", self._traces)
        # Add shortcuts to first trace
        trace1 = self.traces[0]
        params = trace1.parameters
        if not isinstance(params, dict):
            raise RuntimeError(f"Expected trace.parameters to be a dict got "
                               f"{type(params)}")
        for param in params.values():
            self.parameters[param.name] = param
        # And also add a link to run sweep
        self.run_sweep = trace1.run_sweep
        # Set this trace to be the default (it's possible to end up in a
        # situation where no traces are selected, causing parameter snapshots
        # to fail)
        self.active_trace(trace1.trace_num)

        # Set auto_sweep parameter
        # If we want to return multiple traces per setpoint without sweeping
        # multiple times, we should set this to false
        self.add_parameter('auto_sweep',
                           label='Auto Sweep',
                           set_cmd=None,
                           get_cmd=None,
                           vals=Bool(),
                           initial_value=True)

        # A default output format on initialisation
        self.write('FORM REAL,32')
        self.write('FORM:BORD NORM')

        self.connect_message()