Beispiel #1
0
    def _create_controls(self):
        attenuator_box = QCheckBoxPlayback("Attenuator")
        attenuator_box.setChecked(True)
        self._atten_box = attenuator_box

        hdr_gain_label = QtGui.QLabel("HDR Gain:")
        hdr_gain_box = QDoubleSpinBoxPlayback()
        hdr_gain_box.setRange(-10, 30)
        hdr_gain_box.setValue(-10)
        hdr_gain_box.setSuffix(" dB")
        self._hdr_gain_label = hdr_gain_label
        self._hdr_gain_box = hdr_gain_box

        self._max_level = QDoubleSpinBoxPlayback()
        self._max_level.setRange(PLOT_YMIN, PLOT_YMAX)
        self._max_level.setValue(PLOT_TOP)
        self._max_level.setSuffix(" dBm")
        self._max_level.setSingleStep(PLOT_STEP)
        self._max_label = QtGui.QLabel('Maximum: ')

        self._min_level = QDoubleSpinBoxPlayback()
        self._min_level.setRange(PLOT_YMIN, PLOT_YMAX)
        self._min_level.setValue(PLOT_BOTTOM)
        self._min_level.setSuffix(" dBm")
        self._min_level.setSingleStep(PLOT_STEP)
        self._min_label = QtGui.QLabel('Minimum: ')

        self._reference_offset = QtGui.QLabel("Offset")
        self._reference_offset.setToolTip("Add a reference offset to all plots")

        self._reference_offset_spinbox = QDoubleSpinBoxPlayback()
        self._reference_offset_spinbox.setRange(-200, 200)
Beispiel #2
0
    def _create_controls(self):
        self._conts_box = QCheckBoxPlayback("Continuous")
        self._conts_box.setChecked(True)

        self._single_button = QtGui.QPushButton('Single')

        self._mode_label = QtGui.QLabel('Mode:')

        self._mode = QComboBoxPlayback()
        self._mode.setToolTip("Change the device input mode")

        self._level_trigger = QCheckBoxPlayback("Level Trigger")
        self._level_trigger.setToolTip("Enable Frequency Level Triggers")

        self._trig_fstart_label = QtGui.QLabel("Start:")
        self._trig_fstart = QDoubleSpinBoxPlayback()

        # FIXME: use values from device properties
        self._trig_fstart.setRange(0, 20000)
        self._trig_fstart.setSuffix(" MHz")

        self._trig_fstop_label = QtGui.QLabel("Stop:")
        self._trig_fstop = QDoubleSpinBoxPlayback()
        # FIXME: use values from device properties
        self._trig_fstop.setRange(0, 20000)
        self._trig_fstop.setSuffix(" MHz")

        self._trig_amp_label = QtGui.QLabel("Level:")
        self._trig_amp = QDoubleSpinBoxPlayback()
        self._trig_amp.setSuffix(" dBm")
        self._trig_amp.setRange(-2000, 2000)
Beispiel #3
0
 def _bw_controls(self):
     bw = QtGui.QLabel('Span:')
     self._bw = bw
     bw_edit = QDoubleSpinBoxPlayback()
     bw_edit.setSuffix(' MHz')
     def freq_change():
         self.controller.apply_settings(span=bw_edit.value() * M)
     bw_edit.valueChanged.connect(freq_change)
     self._bw_edit = bw_edit
     return bw, bw_edit
Beispiel #4
0
 def _center_freq(self):
     cfreq = QtGui.QLabel('Center:')
     self._cfreq = cfreq
     freq_edit = QDoubleSpinBoxPlayback()
     freq_edit.setSuffix(' MHz')
     self._freq_edit = freq_edit
     def freq_change():
         self.controller.apply_settings(center=freq_edit.value() * M)
         if self.gui_state.device_settings['iq_output_path'] == 'CONNECTOR':
             self.controller.apply_device_settings(freq = freq_edit.value() * M)
     freq_edit.valueChanged.connect(freq_change)
     return cfreq, freq_edit
Beispiel #5
0
    def _create_controls(self):
        self._channel_power = QCheckBoxPlayback("Channel Power")
        self._channel_power.setToolTip("Enable Channel Power Measurement")

        self._horizontal_cursor = QCheckBoxPlayback("Horizontal Cursor")
        self._horizontal_cursor.setToolTip(
            "Enable Horizontal Cursor on reference Plot")

        self._cursor_spinbox = QDoubleSpinBoxPlayback()
        self._cursor_spinbox.setRange(-2000, 2000)
        self._cursor_spinbox.setEnabled(False)
        self._cursor_spinbox.quiet_update(value=-100)
Beispiel #6
0
    def _bw_controls(self):
        bw = QtGui.QLabel('Span:')
        self._bw = bw
        bw_edit = QDoubleSpinBoxPlayback()
        bw_edit.setSuffix(' MHz')

        def freq_change():
            self.start_stop_changed = False
            self.controller.apply_settings(span=bw_edit.value() * M)

        bw_edit.editingFinished.connect(freq_change)
        self._bw_edit = bw_edit
        return bw, bw_edit
Beispiel #7
0
    def _center_freq(self):
        cfreq = QtGui.QLabel('Center:')
        self._cfreq = cfreq
        freq_edit = QDoubleSpinBoxPlayback()
        freq_edit.setSuffix(' MHz')
        self._freq_edit = freq_edit

        def freq_change():
            self.start_stop_changed = False
            self.controller.apply_settings(center=freq_edit.value() * M)
            if self.gui_state.device_settings['iq_output_path'] == 'CONNECTOR':
                self.controller.apply_device_settings(freq=freq_edit.value() *
                                                      M)

        freq_edit.editingFinished.connect(freq_change)
        return cfreq, freq_edit
Beispiel #8
0
 def _fstop_controls(self):
     fstop = QtGui.QLabel('Stop:')
     self._fstop = fstop
     freq = QDoubleSpinBoxPlayback()
     freq.setSuffix(' MHz')
     def freq_change():
         fstart = self.gui_state.center - self.gui_state.span / 2.0
         fstop = freq.value() * M
         fstart = min(fstart, fstop - self.dut_prop.TUNING_RESOLUTION)
         self.controller.apply_settings(
             center = (fstop + fstart) / 2.0,
             span = (fstop - fstart),
             )
     freq.valueChanged.connect(freq_change)
     self._fstop_edit = freq
     return fstop, freq
Beispiel #9
0
 def _fstart_controls(self):
     fstart = QtGui.QLabel('Start:')
     self._fstart = fstart
     freq = QDoubleSpinBoxPlayback()
     freq.setSuffix(' MHz')
     def freq_change():
         self.start_stop_changed = True
         fstart = float(freq.value() * M)
         fstop = float(self._fstop_edit.value() * M)
         fstop = float(max(fstop, fstart + self.dut_prop.TUNING_RESOLUTION))
         self.controller.apply_settings(
             center = (fstop + fstart) / 2.0,
             span = (fstop - fstart),
             )
     freq.editingFinished.connect(freq_change)
     self._fstart_edit = freq
     return fstart, freq
Beispiel #10
0
    def _create_controls(self):
        self._dec_label = QtGui.QLabel('DDC:')
        self._dec_box = QComboBoxPlayback()
        self._dec_box.setToolTip("Choose Decimation Rate")
        # FIXME: use values from device properties
        dec_values = [
            '1', '4', '8', '16', '32', '64', '128', '256', '512', '1024'
        ]
        for d in dec_values:
            self._dec_box.addItem(d)
        self._dec_values = dec_values

        self._fshift_label = QtGui.QLabel("FShift:")
        self._fshift_edit = QDoubleSpinBoxPlayback()
        self._fshift_edit.setSuffix(' MHz')
        self._fshift_edit.setToolTip("Frequency Shift")
        self._fshift_edit.setWrapping(True)

        self._antenna_label = QtGui.QLabel('Antenna:')
        self._antenna_box = QComboBoxPlayback()
        self._antenna_box.setToolTip("Choose Antenna")
        self._antenna_box.quiet_update(["Antenna 1", "Antenna 2"])

        self._iq_output_label = QtGui.QLabel("IQ Path:")
        self._iq_output_box = QComboBoxPlayback()
        self._iq_output_box.setToolTip("Choose IQ Path")
        self._iq_output_box.quiet_update(["Digitizer", "Connector"])

        self._gain_label = QtGui.QLabel("RF Gain:")
        self._gain_box = QComboBoxPlayback()
        self._gain_box.setToolTip("Choose RF Gain setting")
        gain_values = ['VLow', 'Low', 'Med', 'High']
        self._gain_box.quiet_update(gain_values)
        self._gain_values = [g.lower() for g in gain_values]

        self._ifgain_label = QtGui.QLabel("IF Gain:")
        self._ifgain_box = QtGui.QSpinBox()
        self._ifgain_box.setToolTip("Choose IF Gain setting")
        # FIXME: use values from device properties
        self._ifgain_box.setRange(-10, 25)
        self._ifgain_box.setSuffix(" dB")

        self._pll_label = QtGui.QLabel("PLL Ref:")
        self._pll_box = QComboBoxPlayback()
        self._pll_box.setToolTip("Choose PLL Reference")
        self._pll_box.quiet_update(["Internal", "External"])
Beispiel #11
0
    def _fstart_controls(self):
        fstart = QtGui.QLabel('Start:')
        self._fstart = fstart
        freq = QDoubleSpinBoxPlayback()
        freq.setSuffix(' MHz')

        def freq_change():
            self.start_stop_changed = True
            fstart = float(freq.value() * M)
            fstop = float(self._fstop_edit.value() * M)
            fstop = float(max(fstop, fstart + self.dut_prop.TUNING_RESOLUTION))
            self.controller.apply_settings(
                center=(fstop + fstart) / 2.0,
                span=(fstop - fstart),
            )

        freq.editingFinished.connect(freq_change)
        self._fstart_edit = freq
        return fstart, freq
Beispiel #12
0
    def _create_controls(self):
        self._channel_power = QCheckBoxPlayback("Channel Power")
        self._channel_power.setToolTip("Enable Channel Power Measurement")

        self._horizontal_cursor = QCheckBoxPlayback("Horizontal Cursor")
        self._horizontal_cursor.setToolTip("Enable Horizontal Cursor on reference Plot")

        self._cursor_spinbox = QDoubleSpinBoxPlayback()
        self._cursor_spinbox.setRange(-2000, 2000)
        self._cursor_spinbox.setEnabled(False)
        self._cursor_spinbox.quiet_update(value = -100)
Beispiel #13
0
    def _create_controls(self):
        self._conts_box = QCheckBoxPlayback("Continuous")
        self._conts_box.setChecked(True)

        self._single_button = QtGui.QPushButton('Single')

        self._mode_label = QtGui.QLabel('Mode:')

        self._mode = QComboBoxPlayback()
        self._mode.setToolTip("Change the device input mode")

        self._level_trigger = QCheckBoxPlayback("Level Trigger")
        self._level_trigger.setToolTip("Enable Frequency Level Triggers")

        self._trig_fstart_label = QtGui.QLabel("Start:")
        self._trig_fstart = QDoubleSpinBoxPlayback()

        # FIXME: use values from device properties
        self._trig_fstart.setRange(0, 20000)
        self._trig_fstart.setSuffix(" MHz")

        self._trig_fstop_label = QtGui.QLabel("Stop:")
        self._trig_fstop = QDoubleSpinBoxPlayback()
        # FIXME: use values from device properties
        self._trig_fstop.setRange(0, 20000)
        self._trig_fstop.setSuffix(" MHz")

        self._trig_amp_label = QtGui.QLabel("Level:")
        self._trig_amp = QDoubleSpinBoxPlayback()
        self._trig_amp.setSuffix(" dBm")
        self._trig_amp.setRange(-2000, 2000)
Beispiel #14
0
    def _create_controls(self):
        self._dec_label = QtGui.QLabel('DDC:')
        self._dec_box = QComboBoxPlayback()
        self._dec_box.setToolTip("Choose Decimation Rate")
        # FIXME: use values from device properties
        dec_values = ['1', '4', '8', '16', '32', '64', '128', '256', '512', '1024']
        for d in dec_values:
            self._dec_box.addItem(d)
        self._dec_values = dec_values

        self._fshift_label = QtGui.QLabel("FShift:")
        self._fshift_edit = QDoubleSpinBoxPlayback()
        self._fshift_edit.setSuffix(' MHz')
        self._fshift_edit.setToolTip("Frequency Shift")
        self._fshift_edit.setWrapping(True)

        self._antenna_label = QtGui.QLabel('Antenna:')
        self._antenna_box = QComboBoxPlayback()
        self._antenna_box.setToolTip("Choose Antenna")
        self._antenna_box.quiet_update(["Antenna 1", "Antenna 2"])

        self._iq_output_label = QtGui.QLabel("IQ Path:")
        self._iq_output_box = QComboBoxPlayback()
        self._iq_output_box.setToolTip("Choose IQ Path")
        self._iq_output_box.quiet_update(["Digitizer", "Connector"])

        self._gain_label = QtGui.QLabel("RF Gain:")
        self._gain_box = QComboBoxPlayback()
        self._gain_box.setToolTip("Choose RF Gain setting")
        gain_values = ['VLow', 'Low', 'Med', 'High']
        self._gain_box.quiet_update(gain_values)
        self._gain_values = [g.lower() for g in gain_values]

        self._ifgain_label = QtGui.QLabel("IF Gain:")
        self._ifgain_box = QtGui.QSpinBox()
        self._ifgain_box.setToolTip("Choose IF Gain setting")
        # FIXME: use values from device properties
        self._ifgain_box.setRange(-10, 25)
        self._ifgain_box.setSuffix(" dB")

        self._pll_label = QtGui.QLabel("PLL Ref:")
        self._pll_box = QComboBoxPlayback()
        self._pll_box.setToolTip("Choose PLL Reference")
        self._pll_box.quiet_update(["Internal", "External"])
Beispiel #15
0
class DeviceControls(QtGui.QWidget):
    """
    A widget based from the Qt QGroupBox widget with a layout containing widgets that
    can be used to control the WSA4000/WSA5000
    :param name: The name of the groupBox
    """

    def __init__(self, controller):
        super(DeviceControls, self).__init__()

        self.controller = controller
        controller.device_change.connect(self.device_changed)
        controller.state_change.connect(self.state_changed)

        self._create_controls()
        self.setLayout(QtGui.QGridLayout())
        self._build_layout()
        self._connect_device_controls()

    def _create_controls(self):
        self._dec_label = QtGui.QLabel('DDC:')
        self._dec_box = QComboBoxPlayback()
        self._dec_box.setToolTip("Choose Decimation Rate")
        # FIXME: use values from device properties
        dec_values = ['1', '4', '8', '16', '32', '64', '128', '256', '512', '1024']
        for d in dec_values:
            self._dec_box.addItem(d)
        self._dec_values = dec_values

        self._fshift_label = QtGui.QLabel("FShift:")
        self._fshift_edit = QDoubleSpinBoxPlayback()
        self._fshift_edit.setSuffix(' MHz')
        self._fshift_edit.setToolTip("Frequency Shift")
        self._fshift_edit.setWrapping(True)

        self._antenna_label = QtGui.QLabel('Antenna:')
        self._antenna_box = QComboBoxPlayback()
        self._antenna_box.setToolTip("Choose Antenna")
        self._antenna_box.quiet_update(["Antenna 1", "Antenna 2"])

        self._iq_output_label = QtGui.QLabel("IQ Path:")
        self._iq_output_box = QComboBoxPlayback()
        self._iq_output_box.setToolTip("Choose IQ Path")
        self._iq_output_box.quiet_update(["Digitizer", "Connector"])

        self._gain_label = QtGui.QLabel("RF Gain:")
        self._gain_box = QComboBoxPlayback()
        self._gain_box.setToolTip("Choose RF Gain setting")
        gain_values = ['VLow', 'Low', 'Med', 'High']
        self._gain_box.quiet_update(gain_values)
        self._gain_values = [g.lower() for g in gain_values]

        self._ifgain_label = QtGui.QLabel("IF Gain:")
        self._ifgain_box = QtGui.QSpinBox()
        self._ifgain_box.setToolTip("Choose IF Gain setting")
        # FIXME: use values from device properties
        self._ifgain_box.setRange(-10, 25)
        self._ifgain_box.setSuffix(" dB")

        self._pll_label = QtGui.QLabel("PLL Ref:")
        self._pll_box = QComboBoxPlayback()
        self._pll_box.setToolTip("Choose PLL Reference")
        self._pll_box.quiet_update(["Internal", "External"])

    def _build_layout(self, dut_prop=None):
        features = dut_prop.SWEEP_SETTINGS if dut_prop else []

        grid = self.layout()
        clear_layout(grid)

        grid.addWidget(self._dec_label, 1, 0, 1, 1)
        grid.addWidget(self._dec_box, 1, 1, 1, 1)
        grid.addWidget(self._fshift_label, 1, 3, 1, 1)
        grid.addWidget(self._fshift_edit, 1, 4, 1, 1)

        # 4k features
        if 'antenna' in features:
            grid.addWidget(self._antenna_label, 2, 3, 1, 1)
            grid.addWidget(self._antenna_box, 2, 4, 1, 1)

        if 'gain' in features:
            grid.addWidget(self._gain_label, 3, 0, 1, 1)
            grid.addWidget(self._gain_box, 3, 1, 1, 1)

            # FIXME: 'ifgain' appears in 5k list too
            grid.addWidget(self._ifgain_label, 3, 3, 1, 1)
            grid.addWidget(self._ifgain_box, 3, 4, 1, 1)

        # 5k features
        if 'attenuator' in features:
            if dut_prop.IQ_OUTPUT_CONNECTOR:
                grid.addWidget(self._iq_output_label, 3, 3, 1, 1)
                grid.addWidget(self._iq_output_box, 3, 4, 1, 1)
            
            grid.addWidget(self._pll_label, 3, 0, 1, 1)
            grid.addWidget(self._pll_box, 3, 1, 1, 1)

        grid.setColumnStretch(0, 4)
        grid.setColumnStretch(1, 8)
        grid.setColumnStretch(2, 1)
        grid.setColumnStretch(3, 4)
        grid.setColumnStretch(4, 8)
        grid.setRowStretch(7, 1) # expand empty space at the bottom
        self.resize_widget()

    def _connect_device_controls(self):
        def new_antenna():
            self.controller.apply_device_settings(antenna=
                int(self._antenna_box.currentText().split()[-1]))

        def new_dec():
            self.controller.apply_settings(decimation=int(
                self._dec_box.currentText()))

        def new_freq_shift():
            self.controller.apply_settings(
                fshift=self._fshift_edit.value() * M)

        def new_gain():
            self.plot_state.dev_set['gain'] = self._gain_box.currentText().split()[-1].lower().encode('ascii')
            self.cap_dut.configure_device(self.plot_state.dev_set)

        def new_ifgain():
            self.plot_state.dev_set['ifgain'] = self._ifgain_box.value()
            self.cap_dut.configure_device(self.plot_state.dev_set)

        def new_pll_reference():
            if self._pll_box.currentText() == 'Internal':
                src = 'INT'
            else:
                src = 'EXT'
            self.controller.apply_device_settings(pll_reference=src)

        def new_iq_path():
            self.controller.apply_device_settings(
                iq_output_path= str(self._iq_output_box.currentText().upper()))

        self._antenna_box.currentIndexChanged.connect(new_antenna)
        self._gain_box.currentIndexChanged.connect(new_gain)
        self._dec_box.currentIndexChanged.connect(new_dec)
        self._fshift_edit.valueChanged.connect(new_freq_shift)
        self._ifgain_box.valueChanged.connect(new_ifgain)
        self._iq_output_box.currentIndexChanged.connect(new_iq_path)
        self._pll_box.currentIndexChanged.connect(new_pll_reference)

    def device_changed(self, dut):
        self.dut_prop = dut.properties
        self._build_layout(self.dut_prop)

    def state_changed(self, state, changed):

        if state.playback:
            # for playback simply update everything on every state change
            self._dec_box.playback_value(str(state.decimation))
            self._fshift_edit.playback_value(state.fshift / M)
            self._pll_box.playback_value('External'
                if state.device_settings.get('pll_reference') == 'EXT' else
                'Internal')
            self._iq_output_box.playback_value('Digitizer')
            return

        if 'playback' in changed:
            decimation_available = self.dut_prop.MIN_DECIMATION[
                state.rfe_mode()] is not None
            self._dec_box.setEnabled(decimation_available)
            self._fshift_edit.setEnabled(decimation_available)
            self._pll_box.quiet_update(["Internal", "External"])
            self._pll_box.setEnabled(True)
            self._iq_output_box.quiet_update(["Digitizer", "Connector"])
            self._iq_output_box.setEnabled(True)

        if 'device_settings.trigger' in changed:
            if state.device_settings['trigger']['type'] == 'None':
                if self._level_trigger.isChecked():
                    self._level_trigger.click()

        if 'mode' in changed:
            if state.sweeping():
                self._dec_box.setEnabled(False)
                self._fshift_edit.setEnabled(False)
            else:
                decimation_available = self.dut_prop.MIN_DECIMATION[
                    state.rfe_mode()] is not None
                self._dec_box.setEnabled(decimation_available)
                self._fshift_edit.setEnabled(decimation_available)
            fshift_max = self.dut_prop.FULL_BW[state.rfe_mode()] / M
            self._fshift_edit.setRange(-fshift_max, fshift_max)

        if 'device_settings.iq_output_path' in changed:
            if 'CONNECTOR' == state.device_settings['iq_output_path']:
                # remove all digitizer controls
                self._dec_box.setEnabled(False)
                self._fshift_edit.setEnabled(False)
                self._fshift_label.setEnabled(False)
                self._level_trigger.setEnabled(False)
                self._trig_fstart.setEnabled(False)
                self._trig_fstop.setEnabled(False)
                self._trig_amp.setEnabled(False)

            elif 'DIGITIZER' == state.device_settings['iq_output_path']:
                # enable digitizer controls
                if not self.gui_state.device_settings['iq_output_path']  == 'DIGITIZER':
                    self._dec_box.setEnabled(True)
                    self._fshift_edit.setEnabled(True)
                    self._fshift_label.setEnabled(True)
                    self._trig_fstart.setEnabled(True)
                    self._trig_fstop.setEnabled(True)
                    self._trig_amp.setEnabled(True)
                    self._level_trigger.setEnabled(True)

        self.gui_state = state

    def resize_widget(self):
        self.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Maximum)

    def showEvent(self, event):
        self.activateWindow()
Beispiel #16
0
class CaptureControls(QtGui.QWidget):
    """
    A widget with a layout containing widgets that
    can be used to control the amplitude configurations of the GUI
    :param name: A controller that emits/receives Qt signals from multiple widgets
    :param name: The name of the groupBox
    """
    def __init__(self, controller):
        super(CaptureControls, self).__init__()

        self.controller = controller
        controller.plot_change.connect(self.plot_changed)
        controller.device_change.connect(self.device_changed)
        controller.state_change.connect(self.state_changed)

        grid = QtGui.QGridLayout()
        self.setLayout(QtGui.QGridLayout())

        self._create_controls()
        self._build_layout()
        self._connect_capture_controls()

    def _create_controls(self):
        self._conts_box = QCheckBoxPlayback("Continuous")
        self._conts_box.setChecked(True)

        self._single_button = QtGui.QPushButton('Single')

        self._mode_label = QtGui.QLabel('Mode:')

        self._mode = QComboBoxPlayback()
        self._mode.setToolTip("Change the device input mode")

        self._level_trigger = QCheckBoxPlayback("Level Trigger")
        self._level_trigger.setToolTip("Enable Frequency Level Triggers")

        self._trig_fstart_label = QtGui.QLabel("Start:")
        self._trig_fstart = QDoubleSpinBoxPlayback()

        # FIXME: use values from device properties
        self._trig_fstart.setRange(0, 20000)
        self._trig_fstart.setSuffix(" MHz")

        self._trig_fstop_label = QtGui.QLabel("Stop:")
        self._trig_fstop = QDoubleSpinBoxPlayback()
        # FIXME: use values from device properties
        self._trig_fstop.setRange(0, 20000)
        self._trig_fstop.setSuffix(" MHz")

        self._trig_amp_label = QtGui.QLabel("Level:")
        self._trig_amp = QDoubleSpinBoxPlayback()
        self._trig_amp.setSuffix(" dBm")
        self._trig_amp.setRange(-2000, 2000)

    def _build_layout(self, dut_prop=None):

        grid = self.layout()

        grid.addWidget(self._mode_label, 0, 0, 1, 1)
        grid.addWidget(self._mode, 0, 1, 1, 2)

        grid.addWidget(self._conts_box, 0, 3, 1, 1)
        grid.addWidget(self._single_button, 0, 4, 1, 1)
        grid.addWidget(self._level_trigger, 1, 0, 1, 2)

        grid.addWidget(self._trig_fstart_label, 2, 0, 1, 1)
        grid.addWidget(self._trig_fstart, 2, 1, 1, 1)

        grid.addWidget(self._trig_fstop_label, 2, 3, 1, 1)
        grid.addWidget(self._trig_fstop, 2, 4, 1, 1)

        grid.addWidget(self._trig_amp_label, 1, 3, 1, 1)
        grid.addWidget(self._trig_amp, 1, 4, 1, 1)
        self._trig_state(False)

        self.setLayout(grid)
        self.resize_widget()

    def _connect_capture_controls(self):
        def single_capture():
            self.controller.apply_plot_options(cont_cap_mode=False)
            self.controller.start_capture(single=True)

        def cont_capture():
            self.controller.apply_plot_options(
                cont_cap_mode=self._conts_box.isChecked())
            if self._conts_box.isChecked():
                self.controller.start_capture(single=True)

        def new_input_mode():
            input_mode = TEXT_TO_MODE[self._mode.currentText()]
            if not input_mode:
                return
            self.controller.apply_settings(mode=input_mode)
            #FIXME rfe_mode should not be in device settings dictionary
            if self.gui_state.device_settings['iq_output_path'] == 'CONNECTOR':
                self.controller.apply_device_settings(rfe_mode=input_mode)

        def enable_trigger():
            trigger_settings = self.gui_state.device_settings['trigger']
            if self._level_trigger.isChecked():
                self._trig_state(True)

                start = self.gui_state.center - (self.gui_state.span / 4)
                stop = self.gui_state.center + (self.gui_state.span / 4)
                level = trigger_settings['amplitude']
                self.controller.apply_device_settings(
                    trigger={
                        'type': 'LEVEL',
                        'fstart': start,
                        'fstop': stop,
                        'amplitude': trigger_settings['amplitude']
                    })
            else:
                self.controller.apply_device_settings(
                    trigger={
                        'type': 'NONE',
                        'fstart': trigger_settings['fstart'],
                        'fstop': trigger_settings['fstop'],
                        'amplitude': trigger_settings['amplitude']
                    })
                self._trig_state(False)

        def new_trigger():
            self.controller.apply_device_settings(
                trigger={
                    'type': 'LEVEL',
                    'fstart': self._trig_fstart.value() * M,
                    'fstop': self._trig_fstop.value() * M,
                    'amplitude': self._trig_amp.value()
                })

        self._mode.currentIndexChanged.connect(new_input_mode)
        self._single_button.clicked.connect(single_capture)
        self._conts_box.clicked.connect(cont_capture)
        self._level_trigger.clicked.connect(enable_trigger)
        self._trig_fstart.editingFinished.connect(new_trigger)
        self._trig_fstop.editingFinished.connect(new_trigger)
        self._trig_amp.editingFinished.connect(new_trigger)

    def device_changed(self, dut):
        self.dut_prop = dut.properties
        self._update_modes()

    def state_changed(self, state, changed):
        self.gui_state = state
        if 'playback' in changed:
            # restore controls after playback is stopped
            self._level_trigger.setEnabled(
                state.mode in self.dut_prop.LEVEL_TRIGGER_RFE_MODES)
            self._update_modes(current_mode=state.mode)
            self._level_trigger.playback_value(False)

        if state.playback:
            # for playback simply update on every state change
            self._mode.playback_value(MODE_TO_TEXT[state.mode])

        if 'device_settings.trigger' in changed:
            if state.device_settings['trigger']['type'] == 'LEVEL':
                trigger = state.device_settings['trigger']
                self._trig_fstart.quiet_update(value=trigger['fstart'] / M)
                self._trig_fstop.quiet_update(value=trigger['fstop'] / M)
                self._trig_amp.quiet_update(value=trigger['amplitude'])
            else:
                if self._level_trigger.checkState():
                    self._level_trigger.click()

        if 'device_settings.iq_output_path' in changed:
            if state.device_settings['iq_output_path'] == 'CONNECTOR':
                self._update_modes(include_sweep=False)
                self._level_trigger.setEnabled(False)
                self._trig_fstart.setEnabled(False)
                self._trig_fstop.setEnabled(False)
                self._trig_amp.setEnabled(False)

            elif state.device_settings['iq_output_path'] == 'DIGITIZER':
                self._update_modes()
                self._trig_fstart.setEnabled(True)
                self._trig_fstop.setEnabled(True)
                self._trig_amp.setEnabled(True)
                self._level_trigger.setEnabled(True)

        if 'mode' in changed:
            if state.mode not in self.dut_prop.LEVEL_TRIGGER_RFE_MODES:
                # forcibly disable triggers
                if self._level_trigger.isChecked():
                    self._level_trigger.click()
                self._trig_state(False)
                self._level_trigger.setEnabled(False)

            else:
                self._level_trigger.setEnabled(True)

    def plot_changed(self, state, changed):
        if 'cont_cap_mode' in changed:
            if not state['cont_cap_mode']:
                if self._conts_box.isChecked():
                    self._conts_box.click()

    def _update_modes(self, include_sweep=True, current_mode=None):
        modes = []
        if current_mode:
            current_mode = MODE_TO_TEXT[current_mode]
        if include_sweep:

            modes.extend(self.dut_prop.SPECA_MODES)
            if not self.controller.developer_mode:
                modes.remove('Sweep ZIF')
        modes.extend(self.dut_prop.RFE_MODES)

        self._mode.quiet_update((MODE_TO_TEXT[m] for m in modes), current_mode)
        self._mode.setEnabled(True)

    def _trig_state(self, state):
        self._trig_fstart.setEnabled(state)
        self._trig_amp.setEnabled(state)
        self._trig_fstop.setEnabled(state)
        self._trig = state

    def resize_widget(self):
        self.setSizePolicy(QtGui.QSizePolicy.Preferred,
                           QtGui.QSizePolicy.Maximum)
Beispiel #17
0
class AmplitudeControls(QtGui.QWidget):
    """
    A widget with a layout containing widgets that
    can be used to control the amplitude configurations of the GUI
    :param name: A controller that emits/receives Qt signals from multiple widgets
    :param name: The name of the groupBox
    """

    def __init__(self, controller, plot):
        super(AmplitudeControls, self).__init__()

        self.controller = controller
        controller.device_change.connect(self.device_changed)
        controller.state_change.connect(self.state_changed)
        controller.plot_change.connect(self.plot_changed)
        self._plot = plot

        grid = QtGui.QGridLayout()
        self.setLayout(QtGui.QGridLayout())

        self._create_controls()
        self._connect_device_controls()
        self._connect_plot_controls()
        self.plot_state = {'y_axis': [PLOT_TOP, PLOT_BOTTOM]}

    def _create_controls(self):
        attenuator_box = QCheckBoxPlayback("Attenuator")
        attenuator_box.setChecked(True)
        self._atten_box = attenuator_box

        hdr_gain_label = QtGui.QLabel("HDR Gain:")
        hdr_gain_box = QDoubleSpinBoxPlayback()
        hdr_gain_box.setRange(-10, 30)
        hdr_gain_box.setValue(-10)
        hdr_gain_box.setSuffix(" dB")
        self._hdr_gain_label = hdr_gain_label
        self._hdr_gain_box = hdr_gain_box

        self._max_level = QDoubleSpinBoxPlayback()
        self._max_level.setRange(PLOT_YMIN, PLOT_YMAX)
        self._max_level.setValue(PLOT_TOP)
        self._max_level.setSuffix(" dBm")
        self._max_level.setSingleStep(PLOT_STEP)
        self._max_label = QtGui.QLabel('Maximum: ')

        self._min_level = QDoubleSpinBoxPlayback()
        self._min_level.setRange(PLOT_YMIN, PLOT_YMAX)
        self._min_level.setValue(PLOT_BOTTOM)
        self._min_level.setSuffix(" dBm")
        self._min_level.setSingleStep(PLOT_STEP)
        self._min_label = QtGui.QLabel('Minimum: ')

        self._reference_offset = QtGui.QLabel("Offset")
        self._reference_offset.setToolTip("Add a reference offset to all plots")

        self._reference_offset_spinbox = QDoubleSpinBoxPlayback()
        self._reference_offset_spinbox.setRange(-200, 200)

    def _build_layout(self, dut_prop=None):
        features = dut_prop.SWEEP_SETTINGS if dut_prop else []
        grid = self.layout()

        grid.addWidget(self._max_label, 0, 0, 1, 1)
        grid.addWidget(self._max_level, 0, 1, 1, 1)
        grid.addWidget(self._min_label, 0, 3, 1, 1)
        grid.addWidget(self._min_level, 0, 4, 1, 1)
        grid.addWidget(self._reference_offset, 1, 0, 1,1)
        grid.addWidget(self._reference_offset_spinbox, 1, 1, 1,1)

        if 'attenuator' in features:
            grid.addWidget(self._atten_box, 1, 3, 1, 2)
        if 'hdr_gain' in features:
            grid.addWidget(self._hdr_gain_label, 2, 0, 1, 1)
            grid.addWidget(self._hdr_gain_box, 2, 1, 1, 1)
            self._hdr_gain_box.quiet_update(value=dut_prop.SPECA_DEFAULTS['device_settings']['hdr_gain'])
        grid.setColumnStretch(0, 3)
        grid.setColumnStretch(1, 6)
        grid.setColumnStretch(2, 1)
        grid.setColumnStretch(3, 4)
        grid.setColumnStretch(4, 6)

        grid.setRowStretch(3, 1) # expand empty space at the bottom
        self.setLayout(grid)
        self.resize_widget()

    def device_changed(self, dut):
        self.dut_prop = dut.properties
        self._build_layout(self.dut_prop)

    def state_changed(self, state, changed):
        if state.playback:
            self._atten_box.playback_value(
                state.device_settings.get('attenuator', False))
        elif 'playback' in changed:
            self._atten_box.setEnabled(True)

        if 'mode' in changed:
            if state.mode == 'HDR':
                self._hdr_gain_box.show()
                self._hdr_gain_label.show()
                self.resize_widget()
            else:
                self._hdr_gain_box.hide()
                self._hdr_gain_label.hide()
                self.resize_widget()

        if 'device_settings.iq_output_path' in changed:
            if state.device_settings['iq_output_path'] == 'CONNECTOR':
                self._max_level.setEnabled(False)
                self._min_level.setEnabled(False)
            elif state.device_settings['iq_output_path'] == 'CONNECTOR':
                self._max_level.setEnabled(True)
                self._min_level.setEnabled(True)

    def plot_changed(self, state, changed):
        self.plot_state = state
        if 'y_axis' in changed:
            self._min_level.quiet_update(value = int(min(state['y_axis'])))
            self._max_level.quiet_update(value = int(max(state['y_axis'])))

    def resize_widget(self):
        self.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Maximum)

    def _connect_device_controls(self):
        def new_hdr_gain():
            self.controller.apply_device_settings(hdr_gain = self._hdr_gain_box.value())
        def new_attenuator():
            self.controller.apply_device_settings(attenuator = self._atten_box.isChecked())

        def change_reference_offset_value():
            self.controller.apply_plot_options(reference_offset_value = self._reference_offset_spinbox.value())

        self._hdr_gain_box.valueChanged.connect(new_hdr_gain)
        self._atten_box.clicked.connect(new_attenuator)
        self._reference_offset_spinbox.editingFinished.connect(change_reference_offset_value)

    def _connect_plot_controls(self):
        def update_plot_min():
            if self._min_level.value() > self._max_level.value():
                self._min_level.quiet_update(value = int(min(self.plot_state['y_axis'])))
            else:
                self.controller.apply_plot_options(y_axis = [self._max_level.value(), self._min_level.value()])

        def update_plot_max():
            if self._max_level.value() < self._min_level.value():
                self._max_level.quiet_update(value = int(max(self.plot_state['y_axis'])))
            else:
                self.controller.apply_plot_options(y_axis = [self._max_level.value(), self._min_level.value()])

        self._min_level.editingFinished.connect(update_plot_min)
        self._max_level.editingFinished.connect(update_plot_max)

    def get_max_level(self):
        return self._max_level.value()

    def get_min_level(self):
        return self._min_level.value()

    def showEvent(self, event):
        self.activateWindow()
Beispiel #18
0
class DeviceControls(QtGui.QWidget):
    """
    A widget based from the Qt QGroupBox widget with a layout containing widgets that
    can be used to control the WSA4000/WSA5000
    :param name: The name of the groupBox
    """
    def __init__(self, controller):
        super(DeviceControls, self).__init__()

        self.controller = controller
        controller.device_change.connect(self.device_changed)
        controller.state_change.connect(self.state_changed)

        self._create_controls()
        self.setLayout(QtGui.QGridLayout())
        self._build_layout()
        self._connect_device_controls()

    def _create_controls(self):
        self._dec_label = QtGui.QLabel('DDC:')
        self._dec_box = QComboBoxPlayback()
        self._dec_box.setToolTip("Choose Decimation Rate")
        # FIXME: use values from device properties
        dec_values = [
            '1', '4', '8', '16', '32', '64', '128', '256', '512', '1024'
        ]
        for d in dec_values:
            self._dec_box.addItem(d)
        self._dec_values = dec_values

        self._fshift_label = QtGui.QLabel("FShift:")
        self._fshift_edit = QDoubleSpinBoxPlayback()
        self._fshift_edit.setSuffix(' MHz')
        self._fshift_edit.setToolTip("Frequency Shift")
        self._fshift_edit.setWrapping(True)

        self._antenna_label = QtGui.QLabel('Antenna:')
        self._antenna_box = QComboBoxPlayback()
        self._antenna_box.setToolTip("Choose Antenna")
        self._antenna_box.quiet_update(["Antenna 1", "Antenna 2"])

        self._iq_output_label = QtGui.QLabel("IQ Path:")
        self._iq_output_box = QComboBoxPlayback()
        self._iq_output_box.setToolTip("Choose IQ Path")
        self._iq_output_box.quiet_update(["Digitizer", "Connector"])

        self._gain_label = QtGui.QLabel("RF Gain:")
        self._gain_box = QComboBoxPlayback()
        self._gain_box.setToolTip("Choose RF Gain setting")
        gain_values = ['VLow', 'Low', 'Med', 'High']
        self._gain_box.quiet_update(gain_values)
        self._gain_values = [g.lower() for g in gain_values]

        self._ifgain_label = QtGui.QLabel("IF Gain:")
        self._ifgain_box = QtGui.QSpinBox()
        self._ifgain_box.setToolTip("Choose IF Gain setting")
        # FIXME: use values from device properties
        self._ifgain_box.setRange(-10, 25)
        self._ifgain_box.setSuffix(" dB")

        self._pll_label = QtGui.QLabel("PLL Ref:")
        self._pll_box = QComboBoxPlayback()
        self._pll_box.setToolTip("Choose PLL Reference")
        self._pll_box.quiet_update(["Internal", "External"])

    def _build_layout(self, dut_prop=None):
        features = dut_prop.SWEEP_SETTINGS if dut_prop else []

        grid = self.layout()
        clear_layout(grid)

        grid.addWidget(self._dec_label, 1, 0, 1, 1)
        grid.addWidget(self._dec_box, 1, 1, 1, 1)
        grid.addWidget(self._fshift_label, 1, 3, 1, 1)
        grid.addWidget(self._fshift_edit, 1, 4, 1, 1)

        # 4k features
        if 'antenna' in features:
            grid.addWidget(self._antenna_label, 2, 3, 1, 1)
            grid.addWidget(self._antenna_box, 2, 4, 1, 1)

        if 'gain' in features:
            grid.addWidget(self._gain_label, 3, 0, 1, 1)
            grid.addWidget(self._gain_box, 3, 1, 1, 1)

            # FIXME: 'ifgain' appears in 5k list too
            grid.addWidget(self._ifgain_label, 3, 3, 1, 1)
            grid.addWidget(self._ifgain_box, 3, 4, 1, 1)

        # 5k features
        if 'attenuator' in features:
            if dut_prop.IQ_OUTPUT_CONNECTOR:
                grid.addWidget(self._iq_output_label, 3, 3, 1, 1)
                grid.addWidget(self._iq_output_box, 3, 4, 1, 1)

            grid.addWidget(self._pll_label, 3, 0, 1, 1)
            grid.addWidget(self._pll_box, 3, 1, 1, 1)

        grid.setColumnStretch(0, 4)
        grid.setColumnStretch(1, 8)
        grid.setColumnStretch(2, 1)
        grid.setColumnStretch(3, 4)
        grid.setColumnStretch(4, 8)
        grid.setRowStretch(7, 1)  # expand empty space at the bottom
        self.resize_widget()

    def _connect_device_controls(self):
        def new_antenna():
            self.controller.apply_device_settings(
                antenna=int(self._antenna_box.currentText().split()[-1]))

        def new_dec():
            self.controller.apply_settings(
                decimation=int(self._dec_box.currentText()))

        def new_freq_shift():
            self.controller.apply_settings(fshift=self._fshift_edit.value() *
                                           M)

        def new_gain():
            self.plot_state.dev_set['gain'] = self._gain_box.currentText(
            ).split()[-1].lower().encode('ascii')
            self.cap_dut.configure_device(self.plot_state.dev_set)

        def new_ifgain():
            self.plot_state.dev_set['ifgain'] = self._ifgain_box.value()
            self.cap_dut.configure_device(self.plot_state.dev_set)

        def new_pll_reference():
            if self._pll_box.currentText() == 'Internal':
                src = 'INT'
            else:
                src = 'EXT'
            self.controller.apply_device_settings(pll_reference=src)

        def new_iq_path():
            self.controller.apply_device_settings(
                iq_output_path=str(self._iq_output_box.currentText().upper()))

        self._antenna_box.currentIndexChanged.connect(new_antenna)
        self._gain_box.currentIndexChanged.connect(new_gain)
        self._dec_box.currentIndexChanged.connect(new_dec)
        self._fshift_edit.valueChanged.connect(new_freq_shift)
        self._ifgain_box.valueChanged.connect(new_ifgain)
        self._iq_output_box.currentIndexChanged.connect(new_iq_path)
        self._pll_box.currentIndexChanged.connect(new_pll_reference)

    def device_changed(self, dut):
        self.dut_prop = dut.properties
        self._build_layout(self.dut_prop)

    def state_changed(self, state, changed):

        if state.playback:
            # for playback simply update everything on every state change
            self._dec_box.playback_value(str(state.decimation))
            self._fshift_edit.playback_value(state.fshift / M)
            self._pll_box.playback_value(
                'External' if state.device_settings.get('pll_reference') ==
                'EXT' else 'Internal')
            self._iq_output_box.playback_value('Digitizer')
            return

        if 'playback' in changed:
            decimation_available = self.dut_prop.MIN_DECIMATION[
                state.rfe_mode()] is not None
            self._dec_box.setEnabled(decimation_available)
            self._fshift_edit.setEnabled(decimation_available)
            self._pll_box.quiet_update(["Internal", "External"])
            self._pll_box.setEnabled(True)
            self._iq_output_box.quiet_update(["Digitizer", "Connector"])
            self._iq_output_box.setEnabled(True)

        if 'device_settings.trigger' in changed:
            if state.device_settings['trigger']['type'] == 'None':
                if self._level_trigger.isChecked():
                    self._level_trigger.click()

        if 'mode' in changed:
            if state.sweeping():
                self._dec_box.setEnabled(False)
                self._fshift_edit.setEnabled(False)
            else:
                decimation_available = self.dut_prop.MIN_DECIMATION[
                    state.rfe_mode()] is not None
                self._dec_box.setEnabled(decimation_available)
                self._fshift_edit.setEnabled(decimation_available)
            fshift_max = self.dut_prop.FULL_BW[state.rfe_mode()] / M
            self._fshift_edit.setRange(-fshift_max, fshift_max)

        if 'device_settings.iq_output_path' in changed:
            if 'CONNECTOR' == state.device_settings['iq_output_path']:
                # remove all digitizer controls
                self._dec_box.setEnabled(False)
                self._fshift_edit.setEnabled(False)
                self._fshift_label.setEnabled(False)
                self._level_trigger.setEnabled(False)
                self._trig_fstart.setEnabled(False)
                self._trig_fstop.setEnabled(False)
                self._trig_amp.setEnabled(False)

            elif 'DIGITIZER' == state.device_settings['iq_output_path']:
                # enable digitizer controls
                if not self.gui_state.device_settings[
                        'iq_output_path'] == 'DIGITIZER':
                    self._dec_box.setEnabled(True)
                    self._fshift_edit.setEnabled(True)
                    self._fshift_label.setEnabled(True)
                    self._trig_fstart.setEnabled(True)
                    self._trig_fstop.setEnabled(True)
                    self._trig_amp.setEnabled(True)
                    self._level_trigger.setEnabled(True)

        self.gui_state = state

    def resize_widget(self):
        self.setSizePolicy(QtGui.QSizePolicy.Preferred,
                           QtGui.QSizePolicy.Maximum)

    def showEvent(self, event):
        self.activateWindow()
Beispiel #19
0
class CaptureControls(QtGui.QWidget):
    """
    A widget with a layout containing widgets that
    can be used to control the amplitude configurations of the GUI
    :param name: A controller that emits/receives Qt signals from multiple widgets
    :param name: The name of the groupBox
    """

    def __init__(self, controller):
        super(CaptureControls, self).__init__()

        self.controller = controller
        controller.plot_change.connect(self.plot_changed)
        controller.device_change.connect(self.device_changed)
        controller.state_change.connect(self.state_changed)

        grid = QtGui.QGridLayout()
        self.setLayout(QtGui.QGridLayout())

        self._create_controls()
        self._build_layout()
        self._connect_capture_controls()

    def _create_controls(self):
        self._conts_box = QCheckBoxPlayback("Continuous")
        self._conts_box.setChecked(True)

        self._single_button = QtGui.QPushButton('Single')

        self._mode_label = QtGui.QLabel('Mode:')

        self._mode = QComboBoxPlayback()
        self._mode.setToolTip("Change the device input mode")

        self._level_trigger = QCheckBoxPlayback("Level Trigger")
        self._level_trigger.setToolTip("Enable Frequency Level Triggers")

        self._trig_fstart_label = QtGui.QLabel("Start:")
        self._trig_fstart = QDoubleSpinBoxPlayback()

        # FIXME: use values from device properties
        self._trig_fstart.setRange(0, 20000)
        self._trig_fstart.setSuffix(" MHz")

        self._trig_fstop_label = QtGui.QLabel("Stop:")
        self._trig_fstop = QDoubleSpinBoxPlayback()
        # FIXME: use values from device properties
        self._trig_fstop.setRange(0, 20000)
        self._trig_fstop.setSuffix(" MHz")

        self._trig_amp_label = QtGui.QLabel("Level:")
        self._trig_amp = QDoubleSpinBoxPlayback()
        self._trig_amp.setSuffix(" dBm")
        self._trig_amp.setRange(-2000, 2000)

    def _build_layout(self, dut_prop=None):

        grid = self.layout()

        grid.addWidget(self._mode_label, 0, 0, 1, 1)
        grid.addWidget(self._mode, 0, 1, 1, 2)

        grid.addWidget(self._conts_box, 0, 3, 1, 1)
        grid.addWidget(self._single_button, 0, 4, 1, 1)
        grid.addWidget(self._level_trigger, 1, 0, 1, 2)

        grid.addWidget(self._trig_fstart_label, 2, 0, 1, 1)
        grid.addWidget(self._trig_fstart, 2, 1, 1, 1)

        grid.addWidget(self._trig_fstop_label, 2, 3, 1, 1)
        grid.addWidget(self._trig_fstop, 2, 4, 1, 1)

        grid.addWidget(self._trig_amp_label, 1, 3, 1, 1)
        grid.addWidget(self._trig_amp, 1, 4, 1, 1)
        self._trig_state(False)

        self.setLayout(grid)
        self.resize_widget()

    def _connect_capture_controls(self):

        def single_capture():
            self.controller.apply_plot_options(cont_cap_mode = False)
            self.controller.start_capture(single = True)

        def cont_capture():
            self.controller.apply_plot_options(cont_cap_mode = self._conts_box.isChecked())
            if self._conts_box.isChecked():
                self.controller.start_capture(single = True)

        def new_input_mode():
            input_mode = TEXT_TO_MODE[self._mode.currentText()]
            if not input_mode:
                return
            self.controller.apply_settings(mode=input_mode)
            #FIXME rfe_mode should not be in device settings dictionary
            if self.gui_state.device_settings['iq_output_path'] == 'CONNECTOR':
                self.controller.apply_device_settings(rfe_mode = input_mode)

        def enable_trigger():
            trigger_settings = self.gui_state.device_settings['trigger']
            if self._level_trigger.isChecked():
                self._trig_state(True)

                start = self.gui_state.center - (self.gui_state.span / 4)
                stop = self.gui_state.center + (self.gui_state.span / 4)
                level = trigger_settings['amplitude']
                self.controller.apply_device_settings(trigger = {'type': 'LEVEL',
                                                                'fstart': start,
                                                                'fstop': stop,
                                                                'amplitude': trigger_settings['amplitude']})
            else:
                self.controller.apply_device_settings(trigger = {'type': 'NONE',
                                                                'fstart': trigger_settings['fstart'],
                                                                'fstop': trigger_settings['fstop'],
                                                                'amplitude': trigger_settings['amplitude']})
                self._trig_state(False)

        def new_trigger():
            self.controller.apply_device_settings(trigger = {'type': 'LEVEL',
                                                    'fstart': self._trig_fstart.value() * M,
                                                    'fstop': self._trig_fstop.value() * M,
                                                    'amplitude': self._trig_amp.value()})

        self._mode.currentIndexChanged.connect(new_input_mode)
        self._single_button.clicked.connect(single_capture)
        self._conts_box.clicked.connect(cont_capture)
        self._level_trigger.clicked.connect(enable_trigger)
        self._trig_fstart.editingFinished.connect(new_trigger)
        self._trig_fstop.editingFinished.connect(new_trigger)
        self._trig_amp.editingFinished.connect(new_trigger)

    def device_changed(self, dut):
        self.dut_prop = dut.properties
        self._update_modes()

    def state_changed(self, state, changed):
        self.gui_state = state
        if 'playback' in changed:
            # restore controls after playback is stopped
            self._level_trigger.setEnabled(state.mode in self.dut_prop.LEVEL_TRIGGER_RFE_MODES)
            self._update_modes(current_mode=state.mode)
            self._level_trigger.playback_value(False)

        if state.playback:
            # for playback simply update on every state change
            self._mode.playback_value(MODE_TO_TEXT[state.mode])
        
        if 'device_settings.trigger' in changed:
            if state.device_settings['trigger']['type'] == 'LEVEL':
                trigger = state.device_settings['trigger']
                self._trig_fstart.quiet_update(value=trigger['fstart'] / M)
                self._trig_fstop.quiet_update(value=trigger['fstop'] / M)
                self._trig_amp.quiet_update(value=trigger['amplitude'])
            else:
                if self._level_trigger.checkState():
                    self._level_trigger.click()

        if 'device_settings.iq_output_path' in changed:
            if state.device_settings['iq_output_path'] == 'CONNECTOR':
                self._update_modes(include_sweep=False)
                self._level_trigger.setEnabled(False)
                self._trig_fstart.setEnabled(False)
                self._trig_fstop.setEnabled(False)
                self._trig_amp.setEnabled(False)

            elif state.device_settings['iq_output_path'] == 'DIGITIZER':
                self._update_modes()
                self._trig_fstart.setEnabled(True)
                self._trig_fstop.setEnabled(True)
                self._trig_amp.setEnabled(True)
                self._level_trigger.setEnabled(True)

        if 'mode' in changed:
            if state.mode not in self.dut_prop.LEVEL_TRIGGER_RFE_MODES:
                # forcibly disable triggers
                if self._level_trigger.isChecked():
                    self._level_trigger.click()
                self._trig_state(False)
                self._level_trigger.setEnabled(False)

            else:
                self._level_trigger.setEnabled(True)

    def plot_changed(self, state, changed):
        if 'cont_cap_mode' in changed:
            if not state['cont_cap_mode']:
                if self._conts_box.isChecked():
                    self._conts_box.click()

    def _update_modes(self, include_sweep=True, current_mode=None):
        modes = []
        if current_mode:
            current_mode = MODE_TO_TEXT[current_mode]
        if include_sweep:

            modes.extend(self.dut_prop.SPECA_MODES)
            if not self.controller.developer_mode:
                modes.remove('Sweep ZIF')
        modes.extend(self.dut_prop.RFE_MODES)

        self._mode.quiet_update((MODE_TO_TEXT[m] for m in modes), current_mode)
        self._mode.setEnabled(True)

    def _trig_state(self, state):
        self._trig_fstart.setEnabled(state)
        self._trig_amp.setEnabled(state)
        self._trig_fstop.setEnabled(state)
        self._trig = state

    def resize_widget(self):
        self.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Maximum)
Beispiel #20
0
class MeasurementControls(QtGui.QWidget):
    def __init__(self, controller):
        super(MeasurementControls, self).__init__()

        self.controller = controller
        controller.device_change.connect(self.device_changed)
        controller.state_change.connect(self.state_changed)
        controller.plot_change.connect(self.plot_changed)

        self._create_controls()
        self.setLayout(QtGui.QGridLayout())
        self._build_layout()
        self._connect_controls()

    def _create_controls(self):
        self._channel_power = QCheckBoxPlayback("Channel Power")
        self._channel_power.setToolTip("Enable Channel Power Measurement")

        self._horizontal_cursor = QCheckBoxPlayback("Horizontal Cursor")
        self._horizontal_cursor.setToolTip(
            "Enable Horizontal Cursor on reference Plot")

        self._cursor_spinbox = QDoubleSpinBoxPlayback()
        self._cursor_spinbox.setRange(-2000, 2000)
        self._cursor_spinbox.setEnabled(False)
        self._cursor_spinbox.quiet_update(value=-100)

    def _build_layout(self):
        grid = self.layout()
        clear_layout(grid)
        grid.addWidget(self._channel_power, 0, 0, 1, 1)

        grid.addWidget(self._horizontal_cursor, 0, 1, 1, 1)
        grid.addWidget(self._cursor_spinbox, 0, 2, 1, 1)

        grid.setRowStretch(1, 1)  # expand empty space at the bottom
        self.resize_widget()

    def _connect_controls(self):
        def enable_channel_power():
            self.controller.apply_plot_options(
                channel_power=self._channel_power.isChecked())

        def enable_cursor():
            self.controller.apply_plot_options(
                horizontal_cursor=self._horizontal_cursor.isChecked())

        def change_cursor_value():
            self.controller.apply_plot_options(
                horizontal_cursor_value=self._cursor_spinbox.value())

        self._channel_power.clicked.connect(enable_channel_power)
        self._horizontal_cursor.clicked.connect(enable_cursor)
        self._cursor_spinbox.editingFinished.connect(change_cursor_value)

    def device_changed(self, dut):
        self.dut_prop = dut.properties

    def state_changed(self, state, changed):
        self.gui_state = state
        if 'device_settings.iq_output_path' in changed:
            if state.device_settings['iq_output_path'] == 'CONNECTOR':
                self._channel_power.setEnabled(False)
                self._horizontal_cursor.setEnabled(False)
                self._cursor_spinbox.setEnabled(False)
            elif state.device_settings['iq_output_path'] == 'DIGITIZER':
                self._channel_power.setEnabled(True)
                self._horizontal_cursor.setEnabled(True)
                self._cursor_spinbox.setEnabled(True)

    def plot_changed(self, state, changed):
        self.plot_state = state
        if 'horizontal_cursor_value' in changed:
            self._cursor_spinbox.quiet_update(
                value=float(state['horizontal_cursor_value']))

        if 'horizontal_cursor' in changed:
            if state['horizontal_cursor']:
                self._cursor_spinbox.setEnabled(True)
            else:
                self._cursor_spinbox.setEnabled(False)

    def resize_widget(self):
        self.setSizePolicy(QtGui.QSizePolicy.Preferred,
                           QtGui.QSizePolicy.Maximum)

    def showEvent(self, event):
        self.activateWindow()
Beispiel #21
0
class DeviceControls(QtGui.QGroupBox):
    """
    A widget based from the Qt QGroupBox widget with a layout containing widgets that
    can be used to control the WSA4000/WSA5000
    :param name: The name of the groupBox
    """

    def __init__(self, controller, name="Device Control"):
        super(DeviceControls, self).__init__()

        self.controller = controller
        controller.device_change.connect(self.device_changed)
        controller.state_change.connect(self.state_changed)
        self.setStyleSheet(GROUP_BOX_FONT)
        self.setTitle(name)

        self._create_controls()
        self.setLayout(QtGui.QGridLayout())
        self._build_layout()
        self._connect_device_controls()

    def _create_controls(self):
        self._mode_label = QtGui.QLabel('Mode:')
        self._mode = QComboBoxPlayback()
        self._mode.setToolTip("Change the device input mode")

        self._rbw_label = QtGui.QLabel('RBW:')
        self._rbw_box = QComboBoxPlayback()
        self._rbw_box.setToolTip("Change the RBW of the FFT plot")
        self._update_rbw_options()

        self._dec_label = QtGui.QLabel('DDC:')
        self._dec_box = QComboBoxPlayback()
        self._dec_box.setToolTip("Choose Decimation Rate")
        # FIXME: use values from device properties
        dec_values = ['1', '4', '8', '16', '32', '64', '128', '256', '512', '1024']
        for d in dec_values:
            self._dec_box.addItem(d)
        self._dec_values = dec_values

        self._fshift_label = QtGui.QLabel("FShift:")
        self._fshift_edit = QDoubleSpinBoxPlayback()
        self._fshift_edit.setSuffix(' MHz')
        self._fshift_edit.setToolTip("Frequency Shift")
        self._fshift_edit.setWrapping(True)

        self._antenna_label = QtGui.QLabel('Antenna:')
        self._antenna_box = QComboBoxPlayback()
        self._antenna_box.setToolTip("Choose Antenna")
        self._antenna_box.quiet_update(["Antenna 1", "Antenna 2"])

        self._iq_output_label = QtGui.QLabel("IQ Path:")
        self._iq_output_box = QComboBoxPlayback()
        self._iq_output_box.setToolTip("Choose IQ Path")
        self._iq_output_box.quiet_update(["Digitizer", "Connector"])

        self._gain_label = QtGui.QLabel("RF Gain:")
        self._gain_box = QComboBoxPlayback()
        self._gain_box.setToolTip("Choose RF Gain setting")
        gain_values = ['VLow', 'Low', 'Med', 'High']
        self._gain_box.quiet_update(gain_values)
        self._gain_values = [g.lower() for g in gain_values]

        self._ifgain_label = QtGui.QLabel("IF Gain:")
        self._ifgain_box = QtGui.QSpinBox()
        self._ifgain_box.setToolTip("Choose IF Gain setting")
        # FIXME: use values from device properties
        self._ifgain_box.setRange(-10, 25)
        self._ifgain_box.setSuffix(" dB")

        self._pll_label = QtGui.QLabel("PLL Ref:")
        self._pll_box = QComboBoxPlayback()
        self._pll_box.setToolTip("Choose PLL Reference")
        self._pll_box.quiet_update(["Internal", "External"])

        self._level_trigger = QCheckBoxPlayback("Level Trigger")
        self._level_trigger.setToolTip("Enable Frequency Level Triggers")

        self._trig_fstart_label = QtGui.QLabel("Start:")
        self._trig_fstart = QDoubleSpinBoxPlayback()
        # FIXME: use values from device properties
        self._trig_fstart.setRange(0, 20000)
        self._trig_fstart.setSuffix(" MHz")
        self._trig_fstart.lineEdit().setReadOnly(True)

        self._trig_fstop_label = QtGui.QLabel("Stop:")
        self._trig_fstop = QDoubleSpinBoxPlayback()
        # FIXME: use values from device properties
        self._trig_fstop.setRange(0, 20000)
        self._trig_fstop.setSuffix(" MHz")
        self._trig_fstop.lineEdit().setReadOnly(True)

        self._trig_amp_label = QtGui.QLabel("Level:")
        self._trig_amp = QDoubleSpinBoxPlayback()
        self._trig_amp.setSuffix(" dBm")
        self._trig_amp.setRange(-2000, 2000)
        self._trig_amp.lineEdit().setReadOnly(True)

    def _build_layout(self, dut_prop=None):
        features = dut_prop.SWEEP_SETTINGS if dut_prop else []

        grid = self.layout()
        clear_layout(grid)

        grid.addWidget(self._mode_label, 0, 0, 1, 1)
        grid.addWidget(self._mode, 0, 1, 1, 1)
        grid.addWidget(self._rbw_label, 0, 3, 1, 1)
        grid.addWidget(self._rbw_box, 0, 4, 1, 1)

        grid.addWidget(self._dec_label, 1, 0, 1, 1)
        grid.addWidget(self._dec_box, 1, 1, 1, 1)
        grid.addWidget(self._fshift_label, 1, 3, 1, 1)
        grid.addWidget(self._fshift_edit, 1, 4, 1, 1)

        # 4k features
        if 'antenna' in features:
            grid.addWidget(self._antenna_label, 2, 3, 1, 1)
            grid.addWidget(self._antenna_box, 2, 4, 1, 1)

        if 'gain' in features:
            grid.addWidget(self._gain_label, 3, 0, 1, 1)
            grid.addWidget(self._gain_box, 3, 1, 1, 1)

            # FIXME: 'ifgain' appears in 5k list too
            grid.addWidget(self._ifgain_label, 3, 3, 1, 1)
            grid.addWidget(self._ifgain_box, 3, 4, 1, 1)

        # 5k features
        if 'attenuator' in features:

            # FIXME: 'iq_output' isn't in device properties yet
            grid.addWidget(self._iq_output_label, 3, 3, 1, 1)
            grid.addWidget(self._iq_output_box, 3, 4, 1, 1)
            
            grid.addWidget(self._pll_label, 3, 0, 1, 1)
            grid.addWidget(self._pll_box, 3, 1, 1, 1)

        grid.addWidget(self._level_trigger, 4, 0, 1, 2)

        grid.addWidget(self._trig_fstart_label, 5, 0, 1, 1)
        grid.addWidget(self._trig_fstart, 5, 1, 1, 1)

        grid.addWidget(self._trig_fstop_label, 5, 3, 1, 1)
        grid.addWidget(self._trig_fstop, 5, 4, 1, 1)
        
        grid.addWidget(self._trig_amp_label, 6, 0, 1, 1)
        grid.addWidget(self._trig_amp, 6, 1, 1, 1)
        self._trig_state(False)

        grid.setColumnStretch(0, 4)
        grid.setColumnStretch(1, 8)
        grid.setColumnStretch(2, 1)
        grid.setColumnStretch(3, 4)
        grid.setColumnStretch(4, 8)

    def _connect_device_controls(self):
        def new_antenna():
            self.controller.apply_device_settings(antenna=
                int(self._antenna_box.currentText().split()[-1]))

        def new_dec():
            self.controller.apply_settings(decimation=int(
                self._dec_box.currentText()))

        def new_freq_shift():
            self.controller.apply_settings(
                fshift=self._fshift_edit.value() * M)

        def new_gain():
            self.plot_state.dev_set['gain'] = self._gain_box.currentText().split()[-1].lower().encode('ascii')
            self.cap_dut.configure_device(self.plot_state.dev_set)

        def new_ifgain():
            self.plot_state.dev_set['ifgain'] = self._ifgain_box.value()
            self.cap_dut.configure_device(self.plot_state.dev_set)

        def new_pll_reference():
            if self._pll_box.currentText() == 'Internal':
                src = 'INT'
            else:
                src = 'EXT'
            self.controller.apply_device_settings(pll_reference=src)

        def new_iq_path():
            self.controller.apply_device_settings(
                iq_output_path= str(self._iq_output_box.currentText().upper()))

        def new_input_mode():
            input_mode = self._mode.currentText()
            if not input_mode:
                return
            self.controller.apply_settings(mode=input_mode)
            #FIXME rfe_mode should not be in device settings dictionary
            if self.gui_state.device_settings['iq_output_path'] == 'CONNECTOR':
                self.controller.apply_device_settings(rfe_mode = input_mode)

        def enable_trigger():
            trigger_settings = self.gui_state.device_settings['trigger']
            if self._level_trigger.isChecked():
                self._trig_state(True)

                start = self.gui_state.center - (self.gui_state.span / 4)
                stop = self.gui_state.center + (self.gui_state.span / 4)
                level = trigger_settings['amplitude']
                self.controller.apply_device_settings(trigger = {'type': 'LEVEL',
                                                                'fstart': start,
                                                                'fstop': stop,
                                                                'amplitude': trigger_settings['amplitude']})
            else:
                self.controller.apply_device_settings(trigger = {'type': 'NONE',
                                                                'fstart': trigger_settings['fstart'],
                                                                'fstop': trigger_settings['fstop'],
                                                                'amplitude': trigger_settings['amplitude']})
                self._trig_state(False)

        def new_trigger():
            self.controller.apply_device_settings(trigger = {'type': 'LEVEL',
                                                    'fstart': self._trig_fstart.value() * M,
                                                    'fstop': self._trig_fstop.value() * M,
                                                    'amplitude': self._trig_amp.value()})
        def new_rbw():
            self.controller.apply_settings(rbw=self._rbw_values[
                self._rbw_box.currentIndex()])

        self._antenna_box.currentIndexChanged.connect(new_antenna)
        self._gain_box.currentIndexChanged.connect(new_gain)
        self._dec_box.currentIndexChanged.connect(new_dec)
        self._fshift_edit.valueChanged.connect(new_freq_shift)
        self._ifgain_box.valueChanged.connect(new_ifgain)
        self._mode.currentIndexChanged.connect(new_input_mode)
        self._iq_output_box.currentIndexChanged.connect(new_iq_path)
        self._pll_box.currentIndexChanged.connect(new_pll_reference)
        self._level_trigger.clicked.connect(enable_trigger)
        self._trig_fstart.valueChanged.connect(new_trigger)
        self._trig_fstop.valueChanged.connect(new_trigger)
        self._trig_amp.valueChanged.connect(new_trigger)
        self._rbw_box.currentIndexChanged.connect(new_rbw)

    def device_changed(self, dut):
        self.dut_prop = dut.properties
        self._build_layout(self.dut_prop)
        self._update_modes()


    def _update_modes(self, include_sweep=True):
        modes = []
        if include_sweep:
            modes.extend(self.dut_prop.SPECA_MODES)
        modes.extend(self.dut_prop.RFE_MODES)
        self._mode.quiet_update(modes)


    def state_changed(self, state, changed):
        self.gui_state = state

        if state.playback:
            # for playback simply update everything on every state change
            self._mode.playback_value(state.mode)
            self._level_trigger.playback_value(False)
            self._dec_box.playback_value(str(state.decimation))
            self._fshift_edit.playback_value(state.fshift / M)
            self._rbw_box.playback_value(str(state.rbw))
            self._pll_box.playback_value('External'
                if state.device_settings.get('pll_reference') == 'EXT' else
                'Internal')
            self._iq_output_box.playback_value('Digitizer')
            return

        if 'playback' in changed:
            # restore controls after playback is stopped
            self._update_modes()
            self._level_trigger.setEnabled(
                state.mode in self.dut_prop.LEVEL_TRIGGER_RFE_MODES)
            decimation_available = self.dut_prop.MIN_DECIMATION[
                state.rfe_mode()] is not None
            self._dec_box.setEnabled(decimation_available)
            self._fshift_edit.setEnabled(decimation_available)
            self._update_rbw_options()
            self._pll_box.quiet_update(["Internal", "External"])
            self._pll_box.setEnabled(True)
            self._iq_output_box.quiet_update(["Digitizer", "Connector"])
            self._iq_output_box.setEnabled(True)

        if 'center' in changed:
            if self._level_trigger.isChecked():
                self._level_trigger.click()
        if 'mode' in changed:
            if state.mode not in self.dut_prop.LEVEL_TRIGGER_RFE_MODES:
                self._level_trigger.setEnabled(False)

                # forcibly disable triggers
                if self._level_trigger.isChecked():
                    self._level_trigger.click()
                    self.rig_state(False)

            else:
                self._level_trigger.setEnabled(True)

            if state.sweeping():
                self._dec_box.setEnabled(False)
                self._fshift_edit.setEnabled(False)
            else:
                decimation_available = self.dut_prop.MIN_DECIMATION[
                    state.rfe_mode()] is not None
                self._dec_box.setEnabled(decimation_available)
                self._fshift_edit.setEnabled(decimation_available)
            fshift_max = self.dut_prop.FULL_BW[state.rfe_mode()] / M
            self._fshift_edit.setRange(-fshift_max, fshift_max)

            self._update_rbw_options()

        if 'device_settings.iq_output_path' in changed:
            if 'CONNECTOR' in state.device_settings['iq_output_path']:
                # remove sweep capture modes
                self._update_modes()
                c = self._mode.count()

                # remove all sweep modes while using IQ out
                self._update_modes(include_sweep=False)

                if state.sweeping():
                    self._mode.setCurrentIndex(0)

                # remove all digitizer controls
                self._rbw_label.hide()
                self._rbw_box.hide()
                self._dec_box.hide()
                self._fshift_edit.hide()
                self._fshift_label.hide()

            elif 'DIGITIZER' in state.device_settings['iq_output_path']:
                # show digitizer controls
                self._rbw_label.show()
                self._rbw_box.show()
                self._dec_box.show()
                self._fshift_edit.show()
                self._fshift_label.show()
                # insert all sweep modes only if no sweep mode is in the combo box
                self._update_modes()

        if 'device_settings.trigger' in changed:
            if state.device_settings['trigger']['type'] == 'LEVEL':
                trigger = state.device_settings['trigger']
                self._trig_fstart.quiet_update(value=trigger['fstart'] / M)
                self._trig_fstop.quiet_update(value=trigger['fstop'] / M)
                self._trig_amp.quiet_update(value=trigger['amplitude'])

    def _rbw_replace_items(self, items):
        for i in range(self._rbw_box.count()):
            self._rbw_box.removeItem(0)
        self._rbw_box.addItems(items)

    def _update_rbw_options(self):
        """
        populate RBW drop-down with reasonable values for the current mode
        """
        # FIXME: calculate values from FULL_BW[rfe_mode] instead
        if hasattr(self, 'gui_state') and self.gui_state.rfe_mode() == 'HDR':
            self._rbw_use_hdr_values()
        else:
            self._rbw_use_normal_values()

    def _rbw_use_normal_values(self):
        values = [v * 1000 for v in RBW_VALUES]  # wat
        self._rbw_values = values
        self._rbw_box.quiet_update(
            [str(p) + ' KHz' for p in RBW_VALUES])

    def _rbw_use_hdr_values(self):
        values = HDR_RBW_VALUES
        self._rbw_values = values
        self._rbw_box.quiet_update(
            [str(p) + ' Hz' for p in HDR_RBW_VALUES])

    def _trig_state(self, state):
        self._trig_fstart.setEnabled(state)
        self._trig_amp.setEnabled(state)
        self._trig_fstop.setEnabled(state)
        self._trig = state
Beispiel #22
0
class AmplitudeControls(QtGui.QWidget):
    """
    A widget with a layout containing widgets that
    can be used to control the amplitude configurations of the GUI
    :param name: A controller that emits/receives Qt signals from multiple widgets
    :param name: The name of the groupBox
    """
    def __init__(self, controller, plot):
        super(AmplitudeControls, self).__init__()

        self.controller = controller
        controller.device_change.connect(self.device_changed)
        controller.state_change.connect(self.state_changed)
        controller.plot_change.connect(self.plot_changed)
        self._plot = plot

        grid = QtGui.QGridLayout()
        self.setLayout(QtGui.QGridLayout())

        self._create_controls()
        self._connect_device_controls()
        self._connect_plot_controls()
        self.plot_state = {'y_axis': [PLOT_TOP, PLOT_BOTTOM]}

    def _create_controls(self):
        attenuator_box = QCheckBoxPlayback("Attenuator")
        attenuator_box.setChecked(True)
        self._atten_box = attenuator_box

        hdr_gain_label = QtGui.QLabel("HDR Gain:")
        hdr_gain_box = QDoubleSpinBoxPlayback()
        hdr_gain_box.setRange(-10, 30)
        hdr_gain_box.setValue(-10)
        hdr_gain_box.setSuffix(" dB")
        self._hdr_gain_label = hdr_gain_label
        self._hdr_gain_box = hdr_gain_box

        self._max_level = QDoubleSpinBoxPlayback()
        self._max_level.setRange(PLOT_YMIN, PLOT_YMAX)
        self._max_level.setValue(PLOT_TOP)
        self._max_level.setSuffix(" dBm")
        self._max_level.setSingleStep(PLOT_STEP)
        self._max_label = QtGui.QLabel('Maximum: ')

        self._min_level = QDoubleSpinBoxPlayback()
        self._min_level.setRange(PLOT_YMIN, PLOT_YMAX)
        self._min_level.setValue(PLOT_BOTTOM)
        self._min_level.setSuffix(" dBm")
        self._min_level.setSingleStep(PLOT_STEP)
        self._min_label = QtGui.QLabel('Minimum: ')

        self._reference_offset = QtGui.QLabel("Offset")
        self._reference_offset.setToolTip(
            "Add a reference offset to all plots")

        self._reference_offset_spinbox = QDoubleSpinBoxPlayback()
        self._reference_offset_spinbox.setRange(-200, 200)

    def _build_layout(self, dut_prop=None):
        features = dut_prop.SWEEP_SETTINGS if dut_prop else []
        grid = self.layout()

        grid.addWidget(self._max_label, 0, 0, 1, 1)
        grid.addWidget(self._max_level, 0, 1, 1, 1)
        grid.addWidget(self._min_label, 0, 3, 1, 1)
        grid.addWidget(self._min_level, 0, 4, 1, 1)
        grid.addWidget(self._reference_offset, 1, 0, 1, 1)
        grid.addWidget(self._reference_offset_spinbox, 1, 1, 1, 1)

        if 'attenuator' in features:
            grid.addWidget(self._atten_box, 1, 3, 1, 2)
        if 'hdr_gain' in features:
            grid.addWidget(self._hdr_gain_label, 2, 0, 1, 1)
            grid.addWidget(self._hdr_gain_box, 2, 1, 1, 1)
            self._hdr_gain_box.quiet_update(
                value=dut_prop.SPECA_DEFAULTS['device_settings']['hdr_gain'])
        grid.setColumnStretch(0, 3)
        grid.setColumnStretch(1, 6)
        grid.setColumnStretch(2, 1)
        grid.setColumnStretch(3, 4)
        grid.setColumnStretch(4, 6)

        grid.setRowStretch(3, 1)  # expand empty space at the bottom
        self.setLayout(grid)
        self.resize_widget()

    def device_changed(self, dut):
        self.dut_prop = dut.properties
        self._build_layout(self.dut_prop)

    def state_changed(self, state, changed):
        if state.playback:
            self._atten_box.playback_value(
                state.device_settings.get('attenuator', False))
        elif 'playback' in changed:
            self._atten_box.setEnabled(True)

        if 'mode' in changed:
            if state.mode == 'HDR':
                self._hdr_gain_box.show()
                self._hdr_gain_label.show()
                self.resize_widget()
            else:
                self._hdr_gain_box.hide()
                self._hdr_gain_label.hide()
                self.resize_widget()

        if 'device_settings.iq_output_path' in changed:
            if state.device_settings['iq_output_path'] == 'CONNECTOR':
                self._max_level.setEnabled(False)
                self._min_level.setEnabled(False)
            elif state.device_settings['iq_output_path'] == 'CONNECTOR':
                self._max_level.setEnabled(True)
                self._min_level.setEnabled(True)

    def plot_changed(self, state, changed):
        self.plot_state = state
        if 'y_axis' in changed:
            self._min_level.quiet_update(value=int(min(state['y_axis'])))
            self._max_level.quiet_update(value=int(max(state['y_axis'])))

    def resize_widget(self):
        self.setSizePolicy(QtGui.QSizePolicy.Preferred,
                           QtGui.QSizePolicy.Maximum)

    def _connect_device_controls(self):
        def new_hdr_gain():
            self.controller.apply_device_settings(
                hdr_gain=self._hdr_gain_box.value())

        def new_attenuator():
            self.controller.apply_device_settings(
                attenuator=self._atten_box.isChecked())

        def change_reference_offset_value():
            self.controller.apply_plot_options(
                reference_offset_value=self._reference_offset_spinbox.value())

        self._hdr_gain_box.valueChanged.connect(new_hdr_gain)
        self._atten_box.clicked.connect(new_attenuator)
        self._reference_offset_spinbox.editingFinished.connect(
            change_reference_offset_value)

    def _connect_plot_controls(self):
        def update_plot_min():
            if self._min_level.value() > self._max_level.value():
                self._min_level.quiet_update(
                    value=int(min(self.plot_state['y_axis'])))
            else:
                self.controller.apply_plot_options(
                    y_axis=[self._max_level.value(),
                            self._min_level.value()])

        def update_plot_max():
            if self._max_level.value() < self._min_level.value():
                self._max_level.quiet_update(
                    value=int(max(self.plot_state['y_axis'])))
            else:
                self.controller.apply_plot_options(
                    y_axis=[self._max_level.value(),
                            self._min_level.value()])

        self._min_level.editingFinished.connect(update_plot_min)
        self._max_level.editingFinished.connect(update_plot_max)

    def get_max_level(self):
        return self._max_level.value()

    def get_min_level(self):
        return self._min_level.value()

    def showEvent(self, event):
        self.activateWindow()
Beispiel #23
0
class MeasurementControls(QtGui.QWidget):

    def __init__(self, controller):
        super(MeasurementControls, self).__init__()

        self.controller = controller
        controller.device_change.connect(self.device_changed)
        controller.state_change.connect(self.state_changed)
        controller.plot_change.connect(self.plot_changed)

        self._create_controls()
        self.setLayout(QtGui.QGridLayout())
        self._build_layout()
        self._connect_controls()

    def _create_controls(self):
        self._channel_power = QCheckBoxPlayback("Channel Power")
        self._channel_power.setToolTip("Enable Channel Power Measurement")

        self._horizontal_cursor = QCheckBoxPlayback("Horizontal Cursor")
        self._horizontal_cursor.setToolTip("Enable Horizontal Cursor on reference Plot")

        self._cursor_spinbox = QDoubleSpinBoxPlayback()
        self._cursor_spinbox.setRange(-2000, 2000)
        self._cursor_spinbox.setEnabled(False)
        self._cursor_spinbox.quiet_update(value = -100)

    def _build_layout(self):
        grid = self.layout()
        clear_layout(grid)
        grid.addWidget(self._channel_power, 0, 0, 1, 1)

        grid.addWidget(self._horizontal_cursor, 0, 1, 1,1)
        grid.addWidget(self._cursor_spinbox, 0, 2, 1,1)

        grid.setRowStretch(1, 1) # expand empty space at the bottom
        self.resize_widget()

    def _connect_controls(self):
        def enable_channel_power():
            self.controller.apply_plot_options(channel_power = self._channel_power.isChecked())

        def enable_cursor():
            self.controller.apply_plot_options(horizontal_cursor = self._horizontal_cursor.isChecked())

        def change_cursor_value():
            self.controller.apply_plot_options(horizontal_cursor_value = self._cursor_spinbox.value())

        self._channel_power.clicked.connect(enable_channel_power)
        self._horizontal_cursor.clicked.connect(enable_cursor)
        self._cursor_spinbox.editingFinished.connect(change_cursor_value)

    def device_changed(self, dut):
        self.dut_prop = dut.properties

    def state_changed(self, state, changed):
        self.gui_state = state
        if 'device_settings.iq_output_path' in changed:
            if state.device_settings['iq_output_path'] == 'CONNECTOR':
                self._channel_power.setEnabled(False)
                self._horizontal_cursor.setEnabled(False)
                self._cursor_spinbox.setEnabled(False)
            elif state.device_settings['iq_output_path'] == 'DIGITIZER':
                self._channel_power.setEnabled(True)
                self._horizontal_cursor.setEnabled(True)
                self._cursor_spinbox.setEnabled(True)

    def plot_changed(self, state, changed):
        self.plot_state = state
        if 'horizontal_cursor_value' in changed:
                self._cursor_spinbox.quiet_update(value = float(state['horizontal_cursor_value']))

        if 'horizontal_cursor' in changed:
           if state['horizontal_cursor']:
                    self._cursor_spinbox.setEnabled(True)
           else:
                self._cursor_spinbox.setEnabled(False)

    def resize_widget(self):
        self.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Maximum)

    def showEvent(self, event):
        self.activateWindow()
Beispiel #24
0
    def _create_controls(self):
        self._mode_label = QtGui.QLabel('Mode:')
        self._mode = QComboBoxPlayback()
        self._mode.setToolTip("Change the device input mode")

        self._rbw_label = QtGui.QLabel('RBW:')
        self._rbw_box = QComboBoxPlayback()
        self._rbw_box.setToolTip("Change the RBW of the FFT plot")
        self._update_rbw_options()

        self._dec_label = QtGui.QLabel('DDC:')
        self._dec_box = QComboBoxPlayback()
        self._dec_box.setToolTip("Choose Decimation Rate")
        # FIXME: use values from device properties
        dec_values = ['1', '4', '8', '16', '32', '64', '128', '256', '512', '1024']
        for d in dec_values:
            self._dec_box.addItem(d)
        self._dec_values = dec_values

        self._fshift_label = QtGui.QLabel("FShift:")
        self._fshift_edit = QDoubleSpinBoxPlayback()
        self._fshift_edit.setSuffix(' MHz')
        self._fshift_edit.setToolTip("Frequency Shift")
        self._fshift_edit.setWrapping(True)

        self._antenna_label = QtGui.QLabel('Antenna:')
        self._antenna_box = QComboBoxPlayback()
        self._antenna_box.setToolTip("Choose Antenna")
        self._antenna_box.quiet_update(["Antenna 1", "Antenna 2"])

        self._iq_output_label = QtGui.QLabel("IQ Path:")
        self._iq_output_box = QComboBoxPlayback()
        self._iq_output_box.setToolTip("Choose IQ Path")
        self._iq_output_box.quiet_update(["Digitizer", "Connector"])

        self._gain_label = QtGui.QLabel("RF Gain:")
        self._gain_box = QComboBoxPlayback()
        self._gain_box.setToolTip("Choose RF Gain setting")
        gain_values = ['VLow', 'Low', 'Med', 'High']
        self._gain_box.quiet_update(gain_values)
        self._gain_values = [g.lower() for g in gain_values]

        self._ifgain_label = QtGui.QLabel("IF Gain:")
        self._ifgain_box = QtGui.QSpinBox()
        self._ifgain_box.setToolTip("Choose IF Gain setting")
        # FIXME: use values from device properties
        self._ifgain_box.setRange(-10, 25)
        self._ifgain_box.setSuffix(" dB")

        self._pll_label = QtGui.QLabel("PLL Ref:")
        self._pll_box = QComboBoxPlayback()
        self._pll_box.setToolTip("Choose PLL Reference")
        self._pll_box.quiet_update(["Internal", "External"])

        self._level_trigger = QCheckBoxPlayback("Level Trigger")
        self._level_trigger.setToolTip("Enable Frequency Level Triggers")

        self._trig_fstart_label = QtGui.QLabel("Start:")
        self._trig_fstart = QDoubleSpinBoxPlayback()
        # FIXME: use values from device properties
        self._trig_fstart.setRange(0, 20000)
        self._trig_fstart.setSuffix(" MHz")
        self._trig_fstart.lineEdit().setReadOnly(True)

        self._trig_fstop_label = QtGui.QLabel("Stop:")
        self._trig_fstop = QDoubleSpinBoxPlayback()
        # FIXME: use values from device properties
        self._trig_fstop.setRange(0, 20000)
        self._trig_fstop.setSuffix(" MHz")
        self._trig_fstop.lineEdit().setReadOnly(True)

        self._trig_amp_label = QtGui.QLabel("Level:")
        self._trig_amp = QDoubleSpinBoxPlayback()
        self._trig_amp.setSuffix(" dBm")
        self._trig_amp.setRange(-2000, 2000)
        self._trig_amp.lineEdit().setReadOnly(True)
Beispiel #25
0
    def _create_controls(self):
        attenuator_box = QCheckBoxPlayback("Attenuator")
        attenuator_box.setChecked(True)
        self._atten_box = attenuator_box

        hdr_gain_label = QtGui.QLabel("HDR Gain:")
        hdr_gain_box = QDoubleSpinBoxPlayback()
        hdr_gain_box.setRange(-10, 30)
        hdr_gain_box.setValue(-10)
        hdr_gain_box.setSuffix(" dB")
        self._hdr_gain_label = hdr_gain_label
        self._hdr_gain_box = hdr_gain_box

        self._max_level = QDoubleSpinBoxPlayback()
        self._max_level.setRange(PLOT_YMIN, PLOT_YMAX)
        self._max_level.setValue(PLOT_TOP)
        self._max_level.setSuffix(" dBm")
        self._max_level.setSingleStep(PLOT_STEP)
        self._max_label = QtGui.QLabel('Maximum: ')

        self._min_level = QDoubleSpinBoxPlayback()
        self._min_level.setRange(PLOT_YMIN, PLOT_YMAX)
        self._min_level.setValue(PLOT_BOTTOM)
        self._min_level.setSuffix(" dBm")
        self._min_level.setSingleStep(PLOT_STEP)
        self._min_label = QtGui.QLabel('Minimum: ')

        self._reference_offset = QtGui.QLabel("Offset")
        self._reference_offset.setToolTip(
            "Add a reference offset to all plots")

        self._reference_offset_spinbox = QDoubleSpinBoxPlayback()
        self._reference_offset_spinbox.setRange(-200, 200)