Example #1
0
    def _activate_alignment_tab(self):

        self.time_window_widget = ScienDSpinBox()
        self.time_window_widget.setMinimum(0)
        self.time_window_widget.setValue(self._alignment_time_window)
        self.time_window_widget.setSuffix('s')
        self.time_window_widget.editingFinished.connect(
            self._change_time_window)
        self._alignment_tab.time_window_layout.addWidget(
            self.time_window_widget, 1)
        self._alignment_tab.clean.clicked.connect(self._clean_time_window)

        for read_mode in self.spectrumlogic().camera_constraints.read_modes:
            self._alignment_tab.read_modes.addItem(str(read_mode.name),
                                                   read_mode.name)
            if read_mode == self._alignment_read_mode:
                self._alignment_tab.read_modes.setCurrentText(
                    str(read_mode.name))

        self.alignment_exposure_time_widget = ScienDSpinBox()
        self.alignment_exposure_time_widget.setMinimum(0)
        self.alignment_exposure_time_widget.setValue(
            self._alignment_exposure_time)
        self.alignment_exposure_time_widget.setSuffix('s')
        self._alignment_tab.exposure_time_layout.addWidget(
            self.alignment_exposure_time_widget)
        self._change_time_window()

        self._alignment_tab.start_acquisition.clicked.connect(
            partial(self.start_acquisition, 1))
        self._start_acquisition_buttons.append(
            self._alignment_tab.start_acquisition)
        self._alignment_tab.stop_acquisition.clicked.connect(
            self.stop_acquisition)
        self._stop_acquisition_buttons.append(
            self._alignment_tab.stop_acquisition)

        self._alignment_tab.graph.setLabel('left',
                                           'photon counts',
                                           units='counts/s')
        self._alignment_tab.graph.setLabel('bottom',
                                           'acquisition time',
                                           units='s')
        self._counter_plot = self._alignment_tab.graph.plot(
            self._counter_data[0], self._counter_data[1])

        self._alignment_tab.read_modes.currentTextChanged.connect(
            self.set_alignment_params)
        self.alignment_exposure_time_widget.editingFinished.connect(
            self.set_alignment_params)
Example #2
0
    def init_spin_box(self):
        """ Initialize all the spinboxes """
        self._min_percentile = ScienDSpinBox()
        self._min_manual = ScienDSpinBox()
        self._max_percentile = ScienDSpinBox()
        self._max_manual = ScienDSpinBox()

        self._min_percentile.setSuffix('%')
        self._min_percentile.setMinimum(0)
        self._min_percentile.setMaximum(100)
        self._min_percentile.setValue(0)

        self._min_manual.setSuffix(self.unit)

        self._max_percentile.setSuffix('%')
        self._max_percentile.setMinimum(0)
        self._max_percentile.setMaximum(100)
        self._max_percentile.setValue(100)

        self._max_manual.setSuffix(self.unit)

        self.min.addWidget(self._min_manual)
        self.min.addWidget(self._min_percentile)
        self.max.addWidget(self._max_percentile)
        self.max.addWidget(self._max_manual)

        self._min_percentile.valueChanged.connect(self.shortcut_to_cb_centiles)
        self._min_manual.valueChanged.connect(self.shortcut_to_cb_manual)
        self._max_percentile.valueChanged.connect(self.shortcut_to_cb_centiles)
        self._max_manual.valueChanged.connect(self.shortcut_to_cb_manual)

        self.manual.clicked.connect(self.update_cb_range)
        self.percentile.clicked.connect(self.update_cb_range)
Example #3
0
 def paint(self, painter, option, index):
     painter.save()
     r = option.rect
     painter.translate(r.topLeft())
     widget = ScienDSpinBox()
     if 'dec' in self.item_dict:
         widget.setDecimals(self.item_dict['dec'])
     if 'unit' in self.item_dict:
         widget.setSuffix(self.item_dict['unit'])
     widget.setGeometry(r)
     widget.setValue(index.data(self._access_role))
     widget.render(painter)
     painter.restore()
Example #4
0
    def createEditor(self, parent, option, index):
        """
        Create for the display and interaction with the user an editor.

        @param QtGui.QWidget parent: The parent object (probably QTableView)
        @param QtGui.QStyleOptionViewItemV4 option: This is a setting option which you can use for
                                                    style configuration.
        @param QtCore.QModelIndex index: That index will be passed by the model object of the
                                         QTableView to the delegated object. This index contains
                                         information about the selected current cell.

        An editor can be in principle any QWidget, which you want to use to display the current
        (model-)data. Therefore the editor is like a container, which handles the passed entries
        from the user interface and should save the data to the model object of the QTableWidget.
        The setEditorData function reads data from the model.

        Do not save the created editor as a class variable! This consumes a lot of unneeded memory.
        It is way better to create an editor if it is needed. The inherent function closeEditor()
        of QStyledItemDelegate takes care of closing and destroying the editor for you, if it is not
        needed any longer.
        """
        editor = ScienDSpinBox(parent=parent)
        if 'min' in self.item_dict:
            editor.setMinimum(self.item_dict['min'])
        if 'max' in self.item_dict:
            editor.setMaximum(self.item_dict['max'])
        if 'dec' in self.item_dict:
            editor.setDecimals(self.item_dict['dec'])
        if 'unit' in self.item_dict:
            editor.setSuffix(self.item_dict['unit'])
        editor.setGeometry(option.rect)
        editor.editingFinished.connect(self.commitAndCloseEditor)
        return editor
Example #5
0
    def __init__(self, parent=None, parameters_dict=None):
        super().__init__(parent)
        if parameters_dict is None:
            self._parameters = OrderedDict()
        else:
            self._parameters = parameters_dict

        self._width_hint = 90 * len(self._parameters)
        self._ach_widgets = OrderedDict()

        main_layout = QtGui.QHBoxLayout()
        for param in self._parameters:
            label = QtGui.QLabel(param)
            label.setAlignment(QtCore.Qt.AlignCenter)
            if self._parameters[param]['type'] == float:
                widget = ScienDSpinBox()
                widget.setMinimum(self._parameters[param]['min'])
                widget.setMaximum(self._parameters[param]['max'])
                widget.setDecimals(6, False)
                widget.setValue(self._parameters[param]['init'])
                widget.setSuffix(self._parameters[param]['unit'])
                # Set size constraints
                widget.setFixedWidth(90)
                # Forward editingFinished signal of child widget
                widget.editingFinished.connect(self.editingFinished)
            elif self._parameters[param]['type'] == int:
                widget = ScienSpinBox()
                widget.setValue(self._parameters[param]['init'])
                widget.setMinimum(self._parameters[param]['min'])
                widget.setMaximum(self._parameters[param]['max'])
                widget.setSuffix(self._parameters[param]['unit'])
                # Set size constraints
                widget.setFixedWidth(90)
                # Forward editingFinished signal of child widget
                widget.editingFinished.connect(self.editingFinished)
            elif self._parameters[param]['type'] == str:
                widget = QtGui.QLineEdit()
                widget.setText(self._parameters[param]['init'])
                # Set size constraints
                widget.setFixedWidth(90)
                # Forward editingFinished signal of child widget
                widget.editingFinished.connect(self.editingFinished)
            elif self._parameters[param]['type'] == bool:
                widget = QtGui.QCheckBox()
                widget.setChecked(self._parameters[param]['init'])
                # Set size constraints
                widget.setFixedWidth(90)
                # Forward editingFinished signal of child widget
                widget.stateChanged.connect(self.editingFinished)
            elif issubclass(self._parameters[param]['type'], Enum):
                widget = QtGui.QComboBox()
                for option in self._parameters[param]['type']:
                    widget.addItem(option.name, option)
                widget.setCurrentText(self._parameters[param]['init'].name)
                # Set size constraints
                widget.setFixedWidth(90)
                # Forward editingFinished signal of child widget
                widget.currentIndexChanged.connect(self.editingFinished)

            self._ach_widgets[param] = {'label': label, 'widget': widget}

            v_layout = QtGui.QVBoxLayout()
            v_layout.addWidget(label)
            v_layout.addWidget(widget)
            v_layout.setAlignment(label, QtCore.Qt.AlignHCenter)
            v_layout.setAlignment(widget, QtCore.Qt.AlignHCenter)
            main_layout.addLayout(v_layout)

        main_layout.addStretch(1)
        main_layout.setSpacing(0)
        main_layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(main_layout)
    def __init__(self, parameters):
        """ Definition, configuration and initialisation of the optimizer settings GUI. Adds a row
            with the value, min, max and vary for each variable in parameters.
            @param parameters Parameters: lmfit parameters collection to be displayed here
        """
        super().__init__()

        self.parameters = parameters

        # create labels and layout
        self._layout = QtWidgets.QGridLayout(self)
        self.useLabel = QtWidgets.QLabel('Edit?')
        self.valueLabel = QtWidgets.QLabel('Value')
        self.minimumLabel = QtWidgets.QLabel('Minimum')
        self.maximumLabel = QtWidgets.QLabel('Maximum')
        self.exprLabel = QtWidgets.QLabel('Expression')
        self.varyLabel = QtWidgets.QLabel('Vary?')

        # add labels to layout
        self._layout.addWidget(self.useLabel, 0, 0)
        self._layout.addWidget(self.valueLabel, 0, 2)
        self._layout.addWidget(self.minimumLabel, 0, 3)
        self._layout.addWidget(self.maximumLabel, 0, 4)
        self._layout.addWidget(self.exprLabel, 0, 5)
        self._layout.addWidget(self.varyLabel, 0, 6)

        # create all parameter fields and add to layout
        self.widgets = {}
        self.paramUseSettings = {}
        n = 2
        for name, param in parameters.items():
            self.paramUseSettings[name] = False
            self.widgets[name + '_use'] = useCheckbox = QtWidgets.QCheckBox()
            self.widgets[name +
                         '_label'] = parameterNameLabel = QtWidgets.QLabel(
                             str(name))
            self.widgets[name + '_value'] = valueSpinbox = ScienDSpinBox()
            self.widgets[name + '_min'] = minimumSpinbox = ScienDSpinBox()
            self.widgets[name + '_max'] = maximumSpinbox = ScienDSpinBox()
            self.widgets[name +
                         '_expr'] = expressionLineEdit = QtWidgets.QLineEdit()
            self.widgets[name + '_vary'] = varyCheckbox = QtWidgets.QCheckBox()
            valueSpinbox.setMaximum(np.inf)
            valueSpinbox.setMinimum(-np.inf)
            minimumSpinbox.setMaximum(np.inf)
            minimumSpinbox.setMinimum(-np.inf)
            maximumSpinbox.setMaximum(np.inf)
            maximumSpinbox.setMinimum(-np.inf)
            if param.value is not None and not math.isnan(param.value):
                useCheckbox.setChecked(self.paramUseSettings[name])
                valueSpinbox.setValue(param.value)
                minimumSpinbox.setValue(param.min)
                minimumSpinbox.setValue(param.max)
                expressionLineEdit.setText(param.expr)
                varyCheckbox.setChecked(param.vary)

            self._layout.addWidget(useCheckbox, n, 0)
            self._layout.addWidget(parameterNameLabel, n, 1)
            self._layout.addWidget(valueSpinbox, n, 2)
            self._layout.addWidget(minimumSpinbox, n, 3)
            self._layout.addWidget(maximumSpinbox, n, 4)
            self._layout.addWidget(expressionLineEdit, n, 5)
            self._layout.addWidget(varyCheckbox, n, 6)
            n += 1

        # space at the bottom of the list
        self._layout.setRowStretch(n, 1)
    def createEditor(self, parent, option, index):
        """ Create for the display and interaction with the user an editor.

        @param QtGui.QWidget parent: The parent object, here QTableWidget
        @param QtGui.QStyleOptionViewItemV4 option: This is a setting option
                                                    which you can use for style
                                                    configuration.
        @param QtCore.QModelIndex index: That index will be passed by the model
                                         object of the QTableWidget to the
                                         delegated object. This index contains
                                         information about the selected current
                                         cell.

        An editor can be in principle any QWidget, which you want to use to
        display the current (model-)data. Therefore the editor is like a
        container, which handles the passed entries from the user interface and
        should save the data to the model object of the QTableWidget. The
        setEditorData function reads data from the model.

        Do not save the created editor as a class variable! This consumes a lot
        of unneeded memory. It is way better to create an editor if it is
        needed. The inherent function closeEditor() of QStyledItemDelegate
        takes care of closing and destroying the editor for you, if it is not
        needed any longer.
        """
        editor = ScienDSpinBox(parent=parent)
        editor.setMinimum(self.item_dict['min'])
        editor.setMaximum(self.item_dict['max'])
        editor.setSingleStep(self.item_dict['view_stepsize'])
        editor.setDecimals(self.item_dict['dec'])
        editor.installEventFilter(self)
        editor.setValue(self.item_dict['init_val'])
        editor.setMaximumHeight(100)
        return editor
Example #8
0
class Main(GUIBase):
    """ GUI module to interface a spectrometer """

    spectrumlogic = Connector(interface='SpectrumLogic')
    savelogic = Connector(interface='SaveLogic')

    _cooler_temperature_unit = ConfigOption('cooler_temperature_unit')

    _alignment_read_mode = StatusVar('alignment_read_mode', 'FVB')
    _alignment_exposure_time = StatusVar('alignment_exposure_time', 0)
    _alignment_time_window = StatusVar('alignment_time_window', 60)

    _image_read_mode = StatusVar('image_read_mode', 'IMAGE_ADVANCED')
    _image_acquisition_mode = StatusVar('image_acquisition_mode', 'LIVE')
    _image_exposure_time = StatusVar('image_exposure_time', None)
    _image_readout_speed = StatusVar('image_readout_speed', None)

    _spectrum_read_mode = StatusVar('spectrum_read_mode', 'MULTIPLE_TRACKS')
    _spectrum_acquisition_mode = StatusVar('spectrum_acquisition_mode',
                                           'SINGLE_SCAN')
    _spectrum_exposure_time = StatusVar('spectrum_exposure_time', None)
    _spectrum_readout_speed = StatusVar('spectrum_readout_speed', None)

    _image_data = StatusVar('image_data', np.zeros((1000, 1000)))
    _image_dark = StatusVar('image_dark', np.zeros((1000, 1000)))
    _image_params = StatusVar('image_params', dict())
    _counter_data = StatusVar('counter_data', np.zeros((2, 1000)))
    _spectrum_data = StatusVar('spectrum_data', np.zeros((2, 1000)))
    _spectrum_dark = StatusVar('spectrum_dark', np.zeros(1000))
    _spectrum_params = StatusVar('spectrum_params', dict())

    def __init__(self, config, **kwargs):
        super().__init__(config=config, **kwargs)

    def on_activate(self):
        """ Definition and initialisation of the GUI. """

        # setting up the window
        self._mw = MainWindow()
        self._settings_tab = SettingsTab()
        self._image_tab = ImageTab()
        self._alignment_tab = AlignmentTab()
        self._spectrum_tab = SpectrumTab()

        self._mw.tab.addTab(self._settings_tab, "Settings")
        self._mw.tab.addTab(self._image_tab, "Image")
        self._mw.tab.addTab(self._alignment_tab, "Alignment")
        self._mw.tab.addTab(self._spectrum_tab, "Spectrum")

        self._acquire_dark_buttons = []
        self._start_acquisition_buttons = []
        self._stop_acquisition_buttons = []
        self._save_data_buttons = []

        self._track_buttons = [
            self._image_tab.track1, self._image_tab.track2,
            self._image_tab.track3, self._image_tab.track4
        ]
        self._track_selector = []

        if not self._image_exposure_time:
            self._image_exposure_time = self.spectrumlogic().exposure_time
        if not self._image_readout_speed:
            self._image_readout_speed = self.spectrumlogic().readout_speed
        if not self._alignment_exposure_time:
            self._alignment_exposure_time = self.spectrumlogic().exposure_time
        if not self._spectrum_exposure_time:
            self._spectrum_exposure_time = self.spectrumlogic().exposure_time
        if not self._spectrum_readout_speed:
            self._spectrum_readout_speed = self.spectrumlogic().readout_speed

        self._activate_settings_tab()
        self._activate_image_tab()
        self._activate_alignment_tab()
        self._activate_spectrum_tab()
        self._settings_window = [
            self._image_tab.image_settings,
            self._alignment_tab.counter_settings,
            self._spectrum_tab.spectrum_settings
        ]

        self._manage_stop_acquisition()

    def on_deactivate(self):
        """ Deinitialisation performed during deactivation of the module.
        """
        self._alignment_read_mode = self._alignment_tab.read_modes.currentData(
        )
        self._alignment_exposure_time = self.alignment_exposure_time_widget.value(
        )
        self._image_acquisition_mode = self._image_tab.acquisition_modes.currentData(
        )
        self._image_read_mode = self._image_tab.read_modes.currentData()
        self._image_exposure_time = self.image_exposure_time_widget.value()
        self._image_readout_speed = self._image_tab.readout_speed.currentData()
        self._spectrum_acquisition_mode = self._spectrum_tab.acquisition_modes.currentData(
        )
        self._spectrum_read_mode = self._spectrum_tab.read_modes.currentData()
        self._spectrum_exposure_time = self.spectrum_exposure_time_widget.value(
        )
        self._spectrum_readout_speed = self._spectrum_tab.readout_speed.currentData(
        )
        self._mw.close()

    def show(self):
        """ Make window visible and put it above all other windows """
        QtWidgets.QMainWindow.show(self._mw)
        self._mw.activateWindow()
        self._mw.raise_()

    def _activate_settings_tab(self):
        """ Initialization method for the setting tab """

        spectro_constraints = self.spectrumlogic().spectro_constraints

        self._grating_buttons = [
            self._settings_tab.grating_1, self._settings_tab.grating_2,
            self._settings_tab.grating_3
        ]
        self._input_port_buttons = [
            self._settings_tab.input_front, self._settings_tab.input_side
        ]
        self._input_slit_width = []
        self._output_port_buttons = [
            self._settings_tab.output_front, self._settings_tab.output_side
        ]
        self._output_slit_width = []

        for i in range(3):
            self._grating_buttons[i].setText('{}rpm'.format(
                round(
                    self.spectrumlogic().spectro_constraints.gratings[i].ruling
                    / 1000)))
            self._grating_buttons[i].setCheckable(True)
            self._grating_buttons[i].clicked.connect(
                partial(self._manage_grating_buttons, i))
            if i == self.spectrumlogic().grating:
                self._grating_buttons[i].setDown(True)

        self._input_ports = [
            port for port in spectro_constraints.ports
            if port.type in [PortType.INPUT_FRONT, PortType.INPUT_SIDE]
        ]
        self._output_ports = [
            port for port in spectro_constraints.ports
            if port.type in [PortType.OUTPUT_FRONT, PortType.OUTPUT_SIDE]
        ]

        for i in range(2):

            if i < len(self._input_ports):

                self._input_port_buttons[i].setText(
                    self._input_ports[i].type.name[6:].lower())
                self._input_port_buttons[i].setCheckable(True)
                if self._input_ports[i].type.name == self.spectrumlogic(
                ).input_port:
                    self._input_port_buttons[i].setDown(True)

                input_widget = ScienDSpinBox()
                input_widget.setRange(self._input_ports[i].constraints.min,
                                      self._input_ports[i].constraints.max)
                input_widget.setValue(
                    self.spectrumlogic().get_input_slit_width(
                        self._input_ports[i].type.name))
                input_widget.setSuffix('m')
                input_widget.editingFinished.connect(
                    partial(self._manage_slit_width, i))
                self._input_slit_width.append(input_widget)

                self._settings_tab.input_layout.addWidget(input_widget, i, 2)
                if len(self._input_ports) > 1:
                    self._input_port_buttons[i].clicked.connect(
                        partial(self._manage_port_buttons, i))

            else:
                self._input_port_buttons[i].setEnabled(False)

            if i < len(self._output_ports):

                self._output_port_buttons[i].setText(
                    self._output_ports[i].type.name[7:].lower())
                self._output_port_buttons[i].setCheckable(True)
                if self._output_ports[i].type.name == self.spectrumlogic(
                ).output_port:
                    self._output_port_buttons[i].setDown(True)

                output_widget = ScienDSpinBox()
                output_widget.setRange(self._output_ports[i].constraints.min,
                                       self._output_ports[i].constraints.max)
                output_widget.setValue(
                    self.spectrumlogic().get_output_slit_width(
                        self._output_ports[i].type.name))
                output_widget.setSuffix('m')
                output_widget.editingFinished.connect(
                    partial(self._manage_slit_width, i + 2))
                self._output_slit_width.append(output_widget)

                self._settings_tab.output_layout.addWidget(output_widget, i, 2)
                if len(self._output_ports) > 1:
                    self._output_port_buttons[i].clicked.connect(
                        partial(self._manage_port_buttons, i + 2))

            else:
                self._output_port_buttons[i].setEnabled(False)

        self._calibration_widget = ScienDSpinBox()
        self._calibration_widget.setValue(
            self.spectrumlogic().wavelength_calibration)
        self._calibration_widget.setSuffix('m')
        self._settings_tab.calibration_layout.addWidget(
            self._calibration_widget)

        for gain in self.spectrumlogic().camera_constraints.internal_gains:
            self._settings_tab.camera_gains.addItem(str(gain), gain)
            if gain == self.spectrumlogic().camera_gain:
                self._settings_tab.camera_gains.setCurrentText(str(gain))

        for trigger_mode in self.spectrumlogic(
        ).camera_constraints.trigger_modes:
            self._settings_tab.trigger_modes.addItem(trigger_mode,
                                                     trigger_mode)
            if trigger_mode == self.spectrumlogic().trigger_mode:
                self._settings_tab.trigger_modes.setCurrentText(trigger_mode)

        self._temperature_widget = ScienDSpinBox()
        self._temperature_widget.setRange(-273.15, 500)
        self._temperature_widget.setValue(
            self.spectrumlogic().temperature_setpoint - 273.15)
        self._temperature_widget.setSuffix('°C')
        self._settings_tab.camera_cooler_layout.addWidget(
            self._temperature_widget)

        self._settings_tab.cooler_on.clicked.connect(
            self._manage_cooler_button)
        if self.spectrumlogic().cooler_status:
            self._settings_tab.cooler_on.setDown(True)
            self._settings_tab.cooler_on.setText("OFF")
            self._mw.cooler_on_label.setText("Cooler ON")
        else:
            self._settings_tab.cooler_on.setText("ON")
            self._mw.cooler_on_label.setText("Cooler OFF")
        self._mw.camera_temperature.setText("{}°C".format(
            round(self.spectrumlogic().camera_temperature - 273.15, 2)))

        self._center_wavelength_widget = ScienDSpinBox()
        self._center_wavelength_widget.setMinimum(0)
        self._center_wavelength_widget.setValue(
            self.spectrumlogic().center_wavelength)
        self._center_wavelength_widget.setSuffix("m")
        self._mw.center_wavelength.addWidget(self._center_wavelength_widget, 1)
        self._mw.go_to_wavelength.clicked.connect(
            self._manage_center_wavelength)
        self._mw.center_wavelength_current.setText("{:.2r}m".format(
            ScaledFloat(self.spectrumlogic().center_wavelength)))

        self._calibration_widget.editingFinished.connect(
            self.set_settings_params)
        self._settings_tab.camera_gains.currentTextChanged.connect(
            self.set_settings_params)
        self._settings_tab.trigger_modes.currentTextChanged.connect(
            self.set_settings_params)
        self._temperature_widget.editingFinished.connect(
            self.set_settings_params)
        if not self.spectrumlogic().camera_constraints.has_shutter:
            self._settings_tab.shutter_modes.setEnabled(False)
        else:
            self._settings_tab.shutter_modes.setCurrentText(
                self.spectrumlogic().shutter_state)
            self._settings_tab.shutter_modes.currentTextChanged.connect(
                self.set_settings_params)

        self._update_temperature_timer = QtCore.QTimer()
        self._update_temperature_timer.timeout.connect(
            self._update_temperature)
        self._update_temperature_timer.start(1000)

        self.spectrumlogic().sigUpdateSettings.connect(self._update_settings)

    def _activate_image_tab(self):
        """ Initialization method for the image tab """

        camera_width = self.spectrumlogic().camera_constraints.width
        camera_height = self.spectrumlogic().camera_constraints.height

        for read_mode in self.spectrumlogic().camera_constraints.read_modes:
            if read_mode.name[:5] == "IMAGE":
                self._image_tab.read_modes.addItem(read_mode.name,
                                                   read_mode.name)
                if read_mode == self._image_read_mode:
                    self._image_tab.read_modes.setCurrentText(read_mode.name)

        for acquisition_mode in AcquisitionMode.__members__:
            if acquisition_mode != "MULTI_SCAN":
                self._image_tab.acquisition_modes.addItem(
                    acquisition_mode, acquisition_mode)
                if acquisition_mode == self._image_acquisition_mode:
                    self._image_tab.acquisition_modes.setCurrentText(
                        acquisition_mode)

        self.image_exposure_time_widget = ScienDSpinBox()
        self.image_exposure_time_widget.setMinimum(0)
        self.image_exposure_time_widget.setValue(self._image_exposure_time)
        self.image_exposure_time_widget.setSuffix('s')
        self._image_tab.exposure_time_layout.addWidget(
            self.image_exposure_time_widget)

        for readout_speed in self.spectrumlogic(
        ).camera_constraints.readout_speeds:
            self._image_tab.readout_speed.addItem(
                "{:.2r}Hz".format(ScaledFloat(readout_speed)), readout_speed)
            if readout_speed == self._image_readout_speed:
                self._image_tab.readout_speed.setCurrentText("{:.2r}Hz".format(
                    ScaledFloat(readout_speed)))

        self._image_tab.save.clicked.connect(partial(self.save_data, 0))
        self._save_data_buttons.append(self._image_tab.save)
        self._image_tab.acquire_dark.clicked.connect(
            partial(self.start_dark_acquisition, 0))
        self._acquire_dark_buttons.append(self._image_tab.acquire_dark)
        self._image_tab.start_acquisition.clicked.connect(
            partial(self.start_acquisition, 0))
        self._start_acquisition_buttons.append(
            self._image_tab.start_acquisition)
        self._image_tab.stop_acquisition.clicked.connect(self.stop_acquisition)
        self._stop_acquisition_buttons.append(self._image_tab.stop_acquisition)
        self._image_tab.remove_dark.clicked.connect(
            partial(self.remove_dark, 0))

        self.my_colors = ColorScaleInferno()
        self._image = pg.ImageItem(image=self._image_data,
                                   axisOrder='row-major')
        self._image.setLookupTable(self.my_colors.lut)
        self._image_tab.graph.addItem(self._image)
        self._colorbar = ColorbarWidget(self._image)
        self._image_tab.colorbar.addWidget(self._colorbar)

        self.track_colors = np.array(
            [palette.c5, palette.c2, palette.c6, palette.c4])
        self.plot_colors = self.track_colors
        height = self.spectrumlogic().camera_constraints.height
        for i in range(4):
            self._track_buttons[i].setCheckable(True)
            self._track_buttons[i].clicked.connect(
                partial(self._manage_track_buttons, i))
            tracks = self.spectrumlogic().active_tracks
            if 2 * i < len(tracks):
                top_pos = tracks[2 * i]
                bottom_pos = tracks[2 * i + 1]
            else:
                top_pos = 0
                bottom_pos = 10
            color = self.track_colors[i].getRgb()
            track_color = pg.mkBrush(color[0], color[1], color[2], 100)
            track = pg.LinearRegionItem(
                values=[top_pos, bottom_pos],
                orientation=pg.LinearRegionItem.Horizontal,
                brush=track_color)
            track.setBounds([0, height])
            track.hide()
            self._track_selector.append(track)
            self._image_tab.graph.addItem(track)

        self._image_tab.image_advanced.setCheckable(True)
        self._image_tab.image_advanced.clicked.connect(
            self._manage_image_advanced_button)
        self._image_advanced_widget = pg.ROI(
            [0, 0], [camera_width, camera_height],
            maxBounds=QRectF(QPoint(0, 0), QPoint(camera_width,
                                                  camera_height)))
        self._image_advanced_widget.addScaleHandle((1, 0), (0, 1))
        self._image_advanced_widget.addScaleHandle((0, 1), (1, 0))
        self._image_advanced_widget.hide()
        self._image_tab.graph.addItem(self._image_advanced_widget)

        self._image_tab.horizontal_binning.setRange(1, camera_width - 1)
        self._image_tab.vertical_binning.setRange(1, camera_height - 1)

        self._image_tab.horizontal_binning.editingFinished.connect(
            self.set_image_params)
        self._image_tab.vertical_binning.editingFinished.connect(
            self.set_image_params)
        self._image_tab.read_modes.currentTextChanged.connect(
            self.set_image_params)
        self._image_tab.acquisition_modes.currentTextChanged.connect(
            self.set_image_params)
        self.image_exposure_time_widget.editingFinished.connect(
            self.set_image_params)
        self._image_tab.readout_speed.currentTextChanged.connect(
            self.set_image_params)

    def _activate_alignment_tab(self):

        self.time_window_widget = ScienDSpinBox()
        self.time_window_widget.setMinimum(0)
        self.time_window_widget.setValue(self._alignment_time_window)
        self.time_window_widget.setSuffix('s')
        self.time_window_widget.editingFinished.connect(
            self._change_time_window)
        self._alignment_tab.time_window_layout.addWidget(
            self.time_window_widget, 1)
        self._alignment_tab.clean.clicked.connect(self._clean_time_window)

        for read_mode in self.spectrumlogic().camera_constraints.read_modes:
            self._alignment_tab.read_modes.addItem(str(read_mode.name),
                                                   read_mode.name)
            if read_mode == self._alignment_read_mode:
                self._alignment_tab.read_modes.setCurrentText(
                    str(read_mode.name))

        self.alignment_exposure_time_widget = ScienDSpinBox()
        self.alignment_exposure_time_widget.setMinimum(0)
        self.alignment_exposure_time_widget.setValue(
            self._alignment_exposure_time)
        self.alignment_exposure_time_widget.setSuffix('s')
        self._alignment_tab.exposure_time_layout.addWidget(
            self.alignment_exposure_time_widget)
        self._change_time_window()

        self._alignment_tab.start_acquisition.clicked.connect(
            partial(self.start_acquisition, 1))
        self._start_acquisition_buttons.append(
            self._alignment_tab.start_acquisition)
        self._alignment_tab.stop_acquisition.clicked.connect(
            self.stop_acquisition)
        self._stop_acquisition_buttons.append(
            self._alignment_tab.stop_acquisition)

        self._alignment_tab.graph.setLabel('left',
                                           'photon counts',
                                           units='counts/s')
        self._alignment_tab.graph.setLabel('bottom',
                                           'acquisition time',
                                           units='s')
        self._counter_plot = self._alignment_tab.graph.plot(
            self._counter_data[0], self._counter_data[1])

        self._alignment_tab.read_modes.currentTextChanged.connect(
            self.set_alignment_params)
        self.alignment_exposure_time_widget.editingFinished.connect(
            self.set_alignment_params)

    def _activate_spectrum_tab(self):
        """ Initialization method for the spectrum tab """

        for read_mode in self.spectrumlogic().camera_constraints.read_modes:
            if read_mode.name[:5] != "IMAGE":
                self._spectrum_tab.read_modes.addItem(str(read_mode.name),
                                                      read_mode.name)
                if read_mode == self._spectrum_read_mode:
                    self._spectrum_tab.read_modes.setCurrentText(
                        str(read_mode.name))

        for acquisition_mode in AcquisitionMode.__members__:
            self._spectrum_tab.acquisition_modes.addItem(
                acquisition_mode, acquisition_mode)
            if acquisition_mode == self._spectrum_acquisition_mode:
                self._spectrum_tab.acquisition_modes.setCurrentText(
                    acquisition_mode)

        self.spectrum_exposure_time_widget = ScienDSpinBox()
        self.spectrum_exposure_time_widget.setMinimum(0)
        self.spectrum_exposure_time_widget.setValue(
            self._spectrum_exposure_time)
        self.spectrum_exposure_time_widget.setSuffix('s')
        self._spectrum_tab.exposure_time_layout.addWidget(
            self.spectrum_exposure_time_widget)

        for readout_speed in self.spectrumlogic(
        ).camera_constraints.readout_speeds:
            self._spectrum_tab.readout_speed.addItem(
                "{:.2r}Hz".format(ScaledFloat(readout_speed)), readout_speed)
            if readout_speed == self._spectrum_readout_speed:
                self._spectrum_tab.readout_speed.setCurrentText(
                    "{:.2r}Hz".format(ScaledFloat(readout_speed)))

        self._spectrum_scan_delay_widget = ScienDSpinBox()
        self._spectrum_scan_delay_widget.setMinimum(0)
        self._spectrum_scan_delay_widget.setValue(
            self.spectrumlogic().scan_delay)
        self._spectrum_scan_delay_widget.setSuffix('s')
        self._spectrum_tab.scan_delay.addWidget(
            self._spectrum_scan_delay_widget)

        self._spectrum_tab.scan_number_spin.setValue(
            self.spectrumlogic().number_of_scan)

        self._spectrum_tab.save.clicked.connect(partial(self.save_data, 1))
        self._save_data_buttons.append(self._spectrum_tab.save)
        self._spectrum_tab.acquire_dark.clicked.connect(
            partial(self.start_dark_acquisition, 1))
        self._acquire_dark_buttons.append(self._spectrum_tab.acquire_dark)
        self._spectrum_tab.start_acquisition.clicked.connect(
            partial(self.start_acquisition, 2))
        self._start_acquisition_buttons.append(
            self._spectrum_tab.start_acquisition)
        self._spectrum_tab.stop_acquisition.clicked.connect(
            self.stop_acquisition)
        self._stop_acquisition_buttons.append(
            self._spectrum_tab.stop_acquisition)
        self._spectrum_tab.remove_dark.clicked.connect(
            partial(self.remove_dark, 1))

        self._spectrum_tab.graph.setLabel('left',
                                          'Photoluminescence',
                                          units='counts/s')
        self._spectrum_tab.graph.setLabel('bottom', 'wavelength', units='m')

        self._spectrum_tab.read_modes.currentTextChanged.connect(
            self.set_spectrum_params)
        self._spectrum_tab.acquisition_modes.currentTextChanged.connect(
            self.set_spectrum_params)
        self.spectrum_exposure_time_widget.editingFinished.connect(
            self.set_spectrum_params)
        self._spectrum_tab.read_modes.currentTextChanged.connect(
            self.set_spectrum_params)
        self._spectrum_scan_delay_widget.editingFinished.connect(
            self.set_spectrum_params)
        self._spectrum_tab.scan_number_spin.editingFinished.connect(
            self.set_spectrum_params)

    def _update_settings(self):

        self._manage_grating_buttons(self.spectrumlogic()._grating)

        if len(self._input_ports) > 1:
            input_port_index = 0 if self.spectrumlogic(
            )._input_port == PortType.INPUT_FRONT else 1
            self._manage_port_buttons(input_port_index)
            self._input_slit_width[input_port_index].setValue(
                self.spectrumlogic()._input_slit_width[input_port_index])
        else:
            self._input_slit_width[0].setValue(
                self.spectrumlogic()._input_slit_width[0])
        if len(self._output_ports) > 1:
            output_port_index = 0 if self.spectrumlogic(
            )._output_port == PortType.OUTPUT_FRONT else 1
            self._manage_port_buttons(output_port_index + 2)
            self._output_slit_width[output_port_index].setValue(
                self.spectrumlogic()._output_slit_width[output_port_index])
        else:
            self._output_slit_width[0].setValue(
                self.spectrumlogic()._output_slit_width[0])

        self._calibration_widget.setValue(
            self.spectrumlogic()._wavelength_calibration[
                self.spectrumlogic()._grating])
        self._settings_tab.camera_gains.setCurrentText(
            str(int(self.spectrumlogic()._camera_gain)))
        self._settings_tab.trigger_modes.setCurrentText(
            self.spectrumlogic()._trigger_mode)
        self._temperature_widget.setValue(
            self.spectrumlogic()._temperature_setpoint - 273.15)

        cooler_on = self.spectrumlogic()._cooler_status
        if self._settings_tab.cooler_on.isDown() != cooler_on:
            self._settings_tab.cooler_on.setChecked(cooler_on)
            self._settings_tab.cooler_on.setDown(cooler_on)
            self._settings_tab.cooler_on.setText(
                "ON" if not cooler_on else "OFF")
            self._mw.cooler_on_label.setText(
                "Cooler {}".format("ON" if cooler_on else "OFF"))

        if self.spectrumlogic().camera_constraints.has_shutter:
            self._settings_tab.shutter_modes.setCurrentText(
                self.spectrumlogic()._shutter_state)

        self._mw.center_wavelength_current.setText("{:.2r}m".format(
            ScaledFloat(self.spectrumlogic()._center_wavelength)))

    def set_settings_params(self):

        if self.spectrumlogic().module_state() == 'locked':
            return

        self.spectrumlogic(
        ).wavelength_calibration = self._calibration_widget.value()
        self.spectrumlogic(
        ).camera_gain = self._settings_tab.camera_gains.currentData()
        self.spectrumlogic(
        ).trigger_mode = self._settings_tab.trigger_modes.currentData()
        self.spectrumlogic(
        ).temperature_setpoint = self._temperature_widget.value() + 273.15
        self.spectrumlogic(
        ).shutter_state = self._settings_tab.shutter_modes.currentText()

        self._mw.center_wavelength_current.setText("{:.2r}m".format(
            ScaledFloat(self.spectrumlogic().center_wavelength)))

    def set_image_params(self):

        if self.spectrumlogic().module_state() == 'locked':
            return

        self._manage_image_advanced()
        self.spectrumlogic(
        ).acquisition_mode = self._image_tab.acquisition_modes.currentData()
        self.spectrumlogic(
        ).read_mode = self._image_tab.read_modes.currentData()
        self.spectrumlogic(
        ).exposure_time = self.image_exposure_time_widget.value()
        self.spectrumlogic(
        ).readout_speed = self._image_tab.readout_speed.currentData()

        self.spectrumlogic()._update_acquisition_params()
        if self._image_params != self.spectrumlogic().acquisition_params:
            self._image_tab.dark_acquired_msg.setText("Dark Outdated")
        self._image_params = self.spectrumlogic().acquisition_params

    def set_alignment_params(self):

        if self.spectrumlogic().module_state() == 'locked':
            return

        self.spectrumlogic().acquisition_mode = "LIVE_SCAN"
        self.spectrumlogic(
        ).read_mode = self._alignment_tab.read_modes.currentData()
        self.spectrumlogic(
        ).exposure_time = self.alignment_exposure_time_widget.value()
        self.spectrumlogic().readout_speed = max(
            self.spectrumlogic().camera_constraints.readout_speeds)

        self._manage_tracks()
        self._change_time_window()

    def set_spectrum_params(self):

        if self.spectrumlogic().module_state() == 'locked':
            return

        self._manage_tracks()
        self.spectrumlogic(
        ).acquisition_mode = self._spectrum_tab.acquisition_modes.currentData(
        )
        self.spectrumlogic(
        ).read_mode = self._spectrum_tab.read_modes.currentData()
        self.spectrumlogic(
        ).exposure_time = self.spectrum_exposure_time_widget.value()
        self.spectrumlogic(
        ).readout_speed = self._spectrum_tab.readout_speed.currentData()
        self.spectrumlogic(
        ).scan_delay = self._spectrum_scan_delay_widget.value()
        self.spectrumlogic(
        ).number_of_scan = self._spectrum_tab.scan_number_spin.value()

        self.spectrumlogic()._update_acquisition_params()
        if self._spectrum_params != self.spectrumlogic().acquisition_params:
            self._spectrum_tab.dark_acquired_msg.setText("Dark Outdated")
        self._spectrum_params = self.spectrumlogic().acquisition_params

    def start_dark_acquisition(self, index):

        self._manage_start_acquisition(index)

        self.spectrumlogic().acquisition_mode = "SINGLE_SCAN"
        self.spectrumlogic().shutter_state = "CLOSED"
        self.spectrumlogic().sigUpdateData.connect(
            partial(self._update_dark, index))

        if index == 0:
            self.spectrumlogic(
            ).read_modes = self._image_tab.read_modes.currentData()
            self.spectrumlogic(
            ).exposure_time = self.image_exposure_time_widget.value()
            self.spectrumlogic(
            ).readout_speed = self._image_tab.readout_speed.currentData()
        elif index == 1:
            self.spectrumlogic(
            ).read_modes = self._spectrum_tab.read_modes.currentData()
            self.spectrumlogic(
            ).exposure_time = self.spectrum_exposure_time_widget.value()
            self.spectrumlogic(
            ).readout_speed = self._spectrum_tab.readout_speed.currentData()

        self.spectrumlogic().start_acquisition()

    def start_acquisition(self, index):

        self._manage_start_acquisition(index)
        self.spectrumlogic().sigUpdateData.connect(
            partial(self._update_data, index))

        if index == 0:
            self.set_image_params()
        elif index == 1:
            self.set_alignment_params()
        elif index == 2:
            self.set_spectrum_params()

        self.spectrumlogic().start_acquisition()

    def stop_acquisition(self):

        self.spectrumlogic().stop_acquisition()
        self.spectrumlogic().sigUpdateData.disconnect()
        self._manage_stop_acquisition()

    def _manage_grating_buttons(self, index):

        for i in range(3):
            btn = self._grating_buttons[i]
            if i == index:
                btn.setChecked(True)
                btn.setDown(True)
                self.spectrumlogic().grating = i
            else:
                btn.setChecked(False)
                btn.setDown(False)
        self._mw.center_wavelength_current.setText("{:.2r}m".format(
            ScaledFloat(self.spectrumlogic().center_wavelength)))
        self._calibration_widget.setValue(
            self.spectrumlogic().wavelength_calibration)

    def _manage_port_buttons(self, index):
        for i in range(2):
            if index < 2:
                btn = self._input_port_buttons[i]
                if i == index:
                    self.spectrumlogic().input_port = self.spectrumlogic(
                    ).spectro_constraints.ports[i].type
                    btn.setChecked(True)
                    btn.setDown(True)
                else:
                    btn.setChecked(False)
                    btn.setDown(False)
            elif index > 1:
                btn = self._output_port_buttons[i]
                if i + 2 == index:
                    self.spectrumlogic().output_port = self.spectrumlogic(
                    ).spectro_constraints.ports[i + 2].type
                    btn.setChecked(True)
                    btn.setDown(True)
                else:
                    btn.setChecked(False)
                    btn.setDown(False)

    def _manage_slit_width(self, index):

        if index < 2:
            self.spectrumlogic().set_input_slit_width(
                self._input_slit_width[index].value(),
                self._input_ports[index].type)
        elif index > 1:
            self.spectrumlogic().set_output_slit_width(
                self._output_slit_width[index - 2].value(),
                self._output_ports[index - 2].type)

    def _manage_cooler_button(self):
        cooler_on = not self.spectrumlogic().cooler_status
        self.spectrumlogic().cooler_status = cooler_on
        self._settings_tab.cooler_on.setChecked(cooler_on)
        self._settings_tab.cooler_on.setDown(cooler_on)
        self._settings_tab.cooler_on.setText("ON" if not cooler_on else "OFF")
        self._mw.cooler_on_label.setText(
            "Cooler {}".format("ON" if cooler_on else "OFF"))

    def _manage_center_wavelength(self):

        self.spectrumlogic(
        ).center_wavelength = self._center_wavelength_widget.value()
        self._mw.center_wavelength_current.setText("{:.2r}m".format(
            ScaledFloat(self.spectrumlogic().center_wavelength)))

    def _manage_tracks(self):
        active_tracks = []
        for i in range(4):
            if self._track_selector[i].isVisible():
                track = self._track_selector[i].getRegion()
                active_tracks.append(int(track[0]))
                active_tracks.append(int(track[1]))
        active_tracks = np.array(active_tracks)
        self.plot_colors[np.argsort(active_tracks[::2])]
        if np.any(self.spectrumlogic().active_tracks != active_tracks):
            self._spectrum_tab.dark_acquired_msg.setText("Dark Outdated")
            self.spectrumlogic().active_tracks = active_tracks

    def _manage_image_advanced(self):

        height = self.spectrumlogic().camera_constraints.height
        width = self.spectrumlogic().camera_constraints.width

        hbin = self._image_tab.horizontal_binning.value()
        vbin = self._image_tab.vertical_binning.value()
        image_binning = list((hbin, vbin))
        if list(self.spectrumlogic().image_advanced_binning.values()
                ) != image_binning:
            self._image_tab.dark_acquired_msg.setText("No Dark Acquired")
            self.spectrumlogic().image_advanced_binning = image_binning

        roi_size = self._image_advanced_widget.getArrayRegion(
            self._image_data, self._image).shape
        roi_origin = self._image_advanced_widget.pos()
        vertical_range = [int(roi_origin[0]), int(roi_origin[0]) + roi_size[0]]
        horizontal_range = [
            int(roi_origin[1]),
            int(roi_origin[1]) + roi_size[1]
        ]
        image_advanced = horizontal_range + vertical_range
        if list(self.spectrumlogic().image_advanced_area.values()
                ) != image_advanced:
            self._image_tab.dark_acquired_msg.setText("No Dark Acquired")
            self.spectrumlogic().image_advanced_area = image_advanced

    def _manage_track_buttons(self, index):

        track_selector = self._track_selector[index]
        if track_selector.isVisible():
            track_selector.hide()
        else:
            track_selector.setVisible(True)

    def _manage_image_advanced_button(self):

        if self._image_advanced_widget.isVisible():
            self._image_advanced_widget.hide()
        else:
            self._image_advanced_widget.setVisible(True)

    def _update_temperature(self):

        self._mw.camera_temperature.setText(
            str(round(self.spectrumlogic().camera_temperature - 273.15, 2)) +
            "°C")

    def _manage_start_acquisition(self, index):

        for i in range(3):
            self._settings_window[i].setEnabled(False)
            self._start_acquisition_buttons[i].setEnabled(False)
            if i == index:
                self._stop_acquisition_buttons[i].setEnabled(True)
            else:
                self._stop_acquisition_buttons[i].setEnabled(False)
            if i < 2:
                self._acquire_dark_buttons[i].setEnabled(False)
                self._save_data_buttons[i].setEnabled(False)
        self._spectrum_tab.multiple_scan_settings.setEnabled(False)

    def _manage_stop_acquisition(self):

        for i in range(3):
            self._settings_window[i].setEnabled(True)
            self._start_acquisition_buttons[i].setEnabled(True)
            self._stop_acquisition_buttons[i].setEnabled(False)
            if i < 2:
                self._acquire_dark_buttons[i].setEnabled(True)
                self._save_data_buttons[i].setEnabled(True)
        self._spectrum_tab.multiple_scan_settings.setEnabled(True)

    def _clean_time_window(self):

        time_window = self.time_window_widget.value()
        exposure_time = self.alignment_exposure_time_widget.value()
        number_points = int(time_window / exposure_time)
        self._counter_data = np.zeros((2, number_points))
        self._counter_plot.setData([])

    def _change_time_window(self):

        time_window = self.time_window_widget.value()
        exposure_time = self.alignment_exposure_time_widget.value()
        number_points = int(time_window / exposure_time)
        x = np.linspace(self._counter_data[0, -1] - time_window,
                        self._counter_data[0, -1], number_points)
        if self._counter_data.shape[1] < number_points:
            y = np.empty(number_points)
            y[-self._counter_data.shape[1]:] = self._counter_data[1]
        else:
            y = self._counter_data[1, -number_points:]
        self._counter_data = np.array([x, y])
        self._alignment_tab.graph.setRange(
            xRange=(x[-1] - self.time_window_widget.value(), x[-1]))

    def _update_data(self, index):

        data = self.spectrumlogic().acquired_data

        if index == 0:
            if self._image_dark.shape == data.shape:
                self._image_data = data - self._image_dark
            else:
                self._image_data = data
                self._image_tab.dark_acquired_msg.setText("No Dark Acquired")

            self._image.setImage(self._image_data)
            self._colorbar.refresh_image()

            if self.spectrumlogic().read_mode == "IMAGE_ADVANCED":
                rectf = self._image_advanced_widget.parentBounds()
                self._image.setRect(rectf)
            else:
                width = self.spectrumlogic().camera_constraints.width
                height = self.spectrumlogic().camera_constraints.height
                self._image.setRect(QtCore.QRect(0, 0, width, height))

        elif index == 1:

            counts = data.mean()
            x = self._counter_data[0] + self.spectrumlogic().exposure_time
            y = np.append(self._counter_data[1][1:], counts)
            self._counter_data = np.array([x, y])
            self._alignment_tab.graph.setRange(
                xRange=(x[-1] - self.time_window_widget.value(), x[-1]))
            self._counter_plot.setData(x, y)

        elif index == 2:

            x = self.spectrumlogic().wavelength_spectrum
            if self._spectrum_dark.shape[-1] == data.shape[-1]:
                # TODO : fix bug with dark in multiple tracks and data in FVB : broadcasting error
                y = data - self._spectrum_dark
            else:
                y = data
                self._spectrum_tab.dark_acquired_msg.setText(
                    "No Dark Acquired")

            if self.spectrumlogic().acquisition_mode == "MULTI_SCAN":
                self._spectrum_data = np.array([[x, scan] for scan in y])
                self._spectrum_tab.graph.clear()

                if self.spectrumlogic().read_mode == "MULTIPLE_TRACKS":
                    tracks = y[-1]
                    if self.spectrumlogic().number_of_scan == y.shape[0]:
                        if self._spectrum_tab.multipe_scan_mode.currentText(
                        ) == "Scan Average":
                            tracks = np.mean(y.transpose(0, 2, 1), axis=0).T
                        if self._spectrum_tab.multipe_scan_mode.currentText(
                        ) == "Scan Median":
                            tracks = np.median(y.transpose(0, 2, 1), axis=0).T
                    i = 0
                    for track in tracks:
                        self._spectrum_tab.graph.plot(x,
                                                      track,
                                                      pen=self.plot_colors[i])
                        i += 1
                else:
                    tracks = y[-1]
                    if self.spectrumlogic().number_of_scan == y.shape[0]:
                        if self._spectrum_tab.multipe_scan_mode.currentText(
                        ) == "Scan Average":
                            tracks = np.mean(y, axis=0)
                        if self._spectrum_tab.multipe_scan_mode.currentText(
                        ) == "Scan Median":
                            tracks = np.median(y, axis=0)
                    self._spectrum_tab.graph.plot(x,
                                                  tracks,
                                                  pen=self.plot_colors[0])
            else:
                self._spectrum_data = np.array([x, y])
                self._spectrum_tab.graph.clear()
                if self.spectrumlogic().read_mode == "MULTIPLE_TRACKS":
                    i = 0
                    for track in y:
                        self._spectrum_tab.graph.plot(x,
                                                      track,
                                                      pen=self.plot_colors[i])
                        i += 1
                else:
                    self._spectrum_tab.graph.plot(x,
                                                  y,
                                                  pen=self.plot_colors[0])

        if not self.spectrumlogic().module_state() == 'locked':
            self.spectrumlogic().sigUpdateData.disconnect()
            self._manage_stop_acquisition()

    def _update_dark(self, index):

        dark = self.spectrumlogic().acquired_data

        if index == 0:
            self._image_dark = dark
            self._image_tab.dark_acquired_msg.setText("Dark Acquired")
        elif index == 1:
            self._spectrum_dark = dark
            self._spectrum_tab.dark_acquired_msg.setText("Dark Acquired")

        self.spectrumlogic().sigUpdateData.disconnect()
        self._manage_stop_acquisition()
        self.spectrumlogic(
        ).shutter_state = self._settings_tab.shutter_modes.currentText()

    def remove_dark(self, index):

        if index == 0:
            self._image_dark = np.zeros((1000, 1000))
            self._image_tab.dark_acquired_msg.setText("No Dark Acquired")
        if index == 1:
            self._spectrum_dark = np.zeros(1000)
            self._spectrum_tab.dark_acquired_msg.setText("No Dark Acquired")

    def save_data(self, index):

        filepath = self.savelogic().get_path_for_module(
            module_name='spectrometer')

        if index == 0:
            data = {
                'data':
                np.array(self._image_data /
                         self._image_params['exposure_time (s)']).flatten()
            }
            self.savelogic().save_data(data,
                                       filepath=filepath,
                                       parameters=self._image_params)
        elif index == 1:
            data = {
                'data':
                np.array(self._spectrum_data /
                         self._spectrum_params['exposure_time (s)']).flatten()
            }
            self.savelogic().save_data(data,
                                       filepath=filepath,
                                       parameters=self._spectrum_params)
Example #9
0
    def _activate_spectrum_tab(self):
        """ Initialization method for the spectrum tab """

        for read_mode in self.spectrumlogic().camera_constraints.read_modes:
            if read_mode.name[:5] != "IMAGE":
                self._spectrum_tab.read_modes.addItem(str(read_mode.name),
                                                      read_mode.name)
                if read_mode == self._spectrum_read_mode:
                    self._spectrum_tab.read_modes.setCurrentText(
                        str(read_mode.name))

        for acquisition_mode in AcquisitionMode.__members__:
            self._spectrum_tab.acquisition_modes.addItem(
                acquisition_mode, acquisition_mode)
            if acquisition_mode == self._spectrum_acquisition_mode:
                self._spectrum_tab.acquisition_modes.setCurrentText(
                    acquisition_mode)

        self.spectrum_exposure_time_widget = ScienDSpinBox()
        self.spectrum_exposure_time_widget.setMinimum(0)
        self.spectrum_exposure_time_widget.setValue(
            self._spectrum_exposure_time)
        self.spectrum_exposure_time_widget.setSuffix('s')
        self._spectrum_tab.exposure_time_layout.addWidget(
            self.spectrum_exposure_time_widget)

        for readout_speed in self.spectrumlogic(
        ).camera_constraints.readout_speeds:
            self._spectrum_tab.readout_speed.addItem(
                "{:.2r}Hz".format(ScaledFloat(readout_speed)), readout_speed)
            if readout_speed == self._spectrum_readout_speed:
                self._spectrum_tab.readout_speed.setCurrentText(
                    "{:.2r}Hz".format(ScaledFloat(readout_speed)))

        self._spectrum_scan_delay_widget = ScienDSpinBox()
        self._spectrum_scan_delay_widget.setMinimum(0)
        self._spectrum_scan_delay_widget.setValue(
            self.spectrumlogic().scan_delay)
        self._spectrum_scan_delay_widget.setSuffix('s')
        self._spectrum_tab.scan_delay.addWidget(
            self._spectrum_scan_delay_widget)

        self._spectrum_tab.scan_number_spin.setValue(
            self.spectrumlogic().number_of_scan)

        self._spectrum_tab.save.clicked.connect(partial(self.save_data, 1))
        self._save_data_buttons.append(self._spectrum_tab.save)
        self._spectrum_tab.acquire_dark.clicked.connect(
            partial(self.start_dark_acquisition, 1))
        self._acquire_dark_buttons.append(self._spectrum_tab.acquire_dark)
        self._spectrum_tab.start_acquisition.clicked.connect(
            partial(self.start_acquisition, 2))
        self._start_acquisition_buttons.append(
            self._spectrum_tab.start_acquisition)
        self._spectrum_tab.stop_acquisition.clicked.connect(
            self.stop_acquisition)
        self._stop_acquisition_buttons.append(
            self._spectrum_tab.stop_acquisition)
        self._spectrum_tab.remove_dark.clicked.connect(
            partial(self.remove_dark, 1))

        self._spectrum_tab.graph.setLabel('left',
                                          'Photoluminescence',
                                          units='counts/s')
        self._spectrum_tab.graph.setLabel('bottom', 'wavelength', units='m')

        self._spectrum_tab.read_modes.currentTextChanged.connect(
            self.set_spectrum_params)
        self._spectrum_tab.acquisition_modes.currentTextChanged.connect(
            self.set_spectrum_params)
        self.spectrum_exposure_time_widget.editingFinished.connect(
            self.set_spectrum_params)
        self._spectrum_tab.read_modes.currentTextChanged.connect(
            self.set_spectrum_params)
        self._spectrum_scan_delay_widget.editingFinished.connect(
            self.set_spectrum_params)
        self._spectrum_tab.scan_number_spin.editingFinished.connect(
            self.set_spectrum_params)
Example #10
0
    def _activate_image_tab(self):
        """ Initialization method for the image tab """

        camera_width = self.spectrumlogic().camera_constraints.width
        camera_height = self.spectrumlogic().camera_constraints.height

        for read_mode in self.spectrumlogic().camera_constraints.read_modes:
            if read_mode.name[:5] == "IMAGE":
                self._image_tab.read_modes.addItem(read_mode.name,
                                                   read_mode.name)
                if read_mode == self._image_read_mode:
                    self._image_tab.read_modes.setCurrentText(read_mode.name)

        for acquisition_mode in AcquisitionMode.__members__:
            if acquisition_mode != "MULTI_SCAN":
                self._image_tab.acquisition_modes.addItem(
                    acquisition_mode, acquisition_mode)
                if acquisition_mode == self._image_acquisition_mode:
                    self._image_tab.acquisition_modes.setCurrentText(
                        acquisition_mode)

        self.image_exposure_time_widget = ScienDSpinBox()
        self.image_exposure_time_widget.setMinimum(0)
        self.image_exposure_time_widget.setValue(self._image_exposure_time)
        self.image_exposure_time_widget.setSuffix('s')
        self._image_tab.exposure_time_layout.addWidget(
            self.image_exposure_time_widget)

        for readout_speed in self.spectrumlogic(
        ).camera_constraints.readout_speeds:
            self._image_tab.readout_speed.addItem(
                "{:.2r}Hz".format(ScaledFloat(readout_speed)), readout_speed)
            if readout_speed == self._image_readout_speed:
                self._image_tab.readout_speed.setCurrentText("{:.2r}Hz".format(
                    ScaledFloat(readout_speed)))

        self._image_tab.save.clicked.connect(partial(self.save_data, 0))
        self._save_data_buttons.append(self._image_tab.save)
        self._image_tab.acquire_dark.clicked.connect(
            partial(self.start_dark_acquisition, 0))
        self._acquire_dark_buttons.append(self._image_tab.acquire_dark)
        self._image_tab.start_acquisition.clicked.connect(
            partial(self.start_acquisition, 0))
        self._start_acquisition_buttons.append(
            self._image_tab.start_acquisition)
        self._image_tab.stop_acquisition.clicked.connect(self.stop_acquisition)
        self._stop_acquisition_buttons.append(self._image_tab.stop_acquisition)
        self._image_tab.remove_dark.clicked.connect(
            partial(self.remove_dark, 0))

        self.my_colors = ColorScaleInferno()
        self._image = pg.ImageItem(image=self._image_data,
                                   axisOrder='row-major')
        self._image.setLookupTable(self.my_colors.lut)
        self._image_tab.graph.addItem(self._image)
        self._colorbar = ColorbarWidget(self._image)
        self._image_tab.colorbar.addWidget(self._colorbar)

        self.track_colors = np.array(
            [palette.c5, palette.c2, palette.c6, palette.c4])
        self.plot_colors = self.track_colors
        height = self.spectrumlogic().camera_constraints.height
        for i in range(4):
            self._track_buttons[i].setCheckable(True)
            self._track_buttons[i].clicked.connect(
                partial(self._manage_track_buttons, i))
            tracks = self.spectrumlogic().active_tracks
            if 2 * i < len(tracks):
                top_pos = tracks[2 * i]
                bottom_pos = tracks[2 * i + 1]
            else:
                top_pos = 0
                bottom_pos = 10
            color = self.track_colors[i].getRgb()
            track_color = pg.mkBrush(color[0], color[1], color[2], 100)
            track = pg.LinearRegionItem(
                values=[top_pos, bottom_pos],
                orientation=pg.LinearRegionItem.Horizontal,
                brush=track_color)
            track.setBounds([0, height])
            track.hide()
            self._track_selector.append(track)
            self._image_tab.graph.addItem(track)

        self._image_tab.image_advanced.setCheckable(True)
        self._image_tab.image_advanced.clicked.connect(
            self._manage_image_advanced_button)
        self._image_advanced_widget = pg.ROI(
            [0, 0], [camera_width, camera_height],
            maxBounds=QRectF(QPoint(0, 0), QPoint(camera_width,
                                                  camera_height)))
        self._image_advanced_widget.addScaleHandle((1, 0), (0, 1))
        self._image_advanced_widget.addScaleHandle((0, 1), (1, 0))
        self._image_advanced_widget.hide()
        self._image_tab.graph.addItem(self._image_advanced_widget)

        self._image_tab.horizontal_binning.setRange(1, camera_width - 1)
        self._image_tab.vertical_binning.setRange(1, camera_height - 1)

        self._image_tab.horizontal_binning.editingFinished.connect(
            self.set_image_params)
        self._image_tab.vertical_binning.editingFinished.connect(
            self.set_image_params)
        self._image_tab.read_modes.currentTextChanged.connect(
            self.set_image_params)
        self._image_tab.acquisition_modes.currentTextChanged.connect(
            self.set_image_params)
        self.image_exposure_time_widget.editingFinished.connect(
            self.set_image_params)
        self._image_tab.readout_speed.currentTextChanged.connect(
            self.set_image_params)
Example #11
0
    def _activate_settings_tab(self):
        """ Initialization method for the setting tab """

        spectro_constraints = self.spectrumlogic().spectro_constraints

        self._grating_buttons = [
            self._settings_tab.grating_1, self._settings_tab.grating_2,
            self._settings_tab.grating_3
        ]
        self._input_port_buttons = [
            self._settings_tab.input_front, self._settings_tab.input_side
        ]
        self._input_slit_width = []
        self._output_port_buttons = [
            self._settings_tab.output_front, self._settings_tab.output_side
        ]
        self._output_slit_width = []

        for i in range(3):
            self._grating_buttons[i].setText('{}rpm'.format(
                round(
                    self.spectrumlogic().spectro_constraints.gratings[i].ruling
                    / 1000)))
            self._grating_buttons[i].setCheckable(True)
            self._grating_buttons[i].clicked.connect(
                partial(self._manage_grating_buttons, i))
            if i == self.spectrumlogic().grating:
                self._grating_buttons[i].setDown(True)

        self._input_ports = [
            port for port in spectro_constraints.ports
            if port.type in [PortType.INPUT_FRONT, PortType.INPUT_SIDE]
        ]
        self._output_ports = [
            port for port in spectro_constraints.ports
            if port.type in [PortType.OUTPUT_FRONT, PortType.OUTPUT_SIDE]
        ]

        for i in range(2):

            if i < len(self._input_ports):

                self._input_port_buttons[i].setText(
                    self._input_ports[i].type.name[6:].lower())
                self._input_port_buttons[i].setCheckable(True)
                if self._input_ports[i].type.name == self.spectrumlogic(
                ).input_port:
                    self._input_port_buttons[i].setDown(True)

                input_widget = ScienDSpinBox()
                input_widget.setRange(self._input_ports[i].constraints.min,
                                      self._input_ports[i].constraints.max)
                input_widget.setValue(
                    self.spectrumlogic().get_input_slit_width(
                        self._input_ports[i].type.name))
                input_widget.setSuffix('m')
                input_widget.editingFinished.connect(
                    partial(self._manage_slit_width, i))
                self._input_slit_width.append(input_widget)

                self._settings_tab.input_layout.addWidget(input_widget, i, 2)
                if len(self._input_ports) > 1:
                    self._input_port_buttons[i].clicked.connect(
                        partial(self._manage_port_buttons, i))

            else:
                self._input_port_buttons[i].setEnabled(False)

            if i < len(self._output_ports):

                self._output_port_buttons[i].setText(
                    self._output_ports[i].type.name[7:].lower())
                self._output_port_buttons[i].setCheckable(True)
                if self._output_ports[i].type.name == self.spectrumlogic(
                ).output_port:
                    self._output_port_buttons[i].setDown(True)

                output_widget = ScienDSpinBox()
                output_widget.setRange(self._output_ports[i].constraints.min,
                                       self._output_ports[i].constraints.max)
                output_widget.setValue(
                    self.spectrumlogic().get_output_slit_width(
                        self._output_ports[i].type.name))
                output_widget.setSuffix('m')
                output_widget.editingFinished.connect(
                    partial(self._manage_slit_width, i + 2))
                self._output_slit_width.append(output_widget)

                self._settings_tab.output_layout.addWidget(output_widget, i, 2)
                if len(self._output_ports) > 1:
                    self._output_port_buttons[i].clicked.connect(
                        partial(self._manage_port_buttons, i + 2))

            else:
                self._output_port_buttons[i].setEnabled(False)

        self._calibration_widget = ScienDSpinBox()
        self._calibration_widget.setValue(
            self.spectrumlogic().wavelength_calibration)
        self._calibration_widget.setSuffix('m')
        self._settings_tab.calibration_layout.addWidget(
            self._calibration_widget)

        for gain in self.spectrumlogic().camera_constraints.internal_gains:
            self._settings_tab.camera_gains.addItem(str(gain), gain)
            if gain == self.spectrumlogic().camera_gain:
                self._settings_tab.camera_gains.setCurrentText(str(gain))

        for trigger_mode in self.spectrumlogic(
        ).camera_constraints.trigger_modes:
            self._settings_tab.trigger_modes.addItem(trigger_mode,
                                                     trigger_mode)
            if trigger_mode == self.spectrumlogic().trigger_mode:
                self._settings_tab.trigger_modes.setCurrentText(trigger_mode)

        self._temperature_widget = ScienDSpinBox()
        self._temperature_widget.setRange(-273.15, 500)
        self._temperature_widget.setValue(
            self.spectrumlogic().temperature_setpoint - 273.15)
        self._temperature_widget.setSuffix('°C')
        self._settings_tab.camera_cooler_layout.addWidget(
            self._temperature_widget)

        self._settings_tab.cooler_on.clicked.connect(
            self._manage_cooler_button)
        if self.spectrumlogic().cooler_status:
            self._settings_tab.cooler_on.setDown(True)
            self._settings_tab.cooler_on.setText("OFF")
            self._mw.cooler_on_label.setText("Cooler ON")
        else:
            self._settings_tab.cooler_on.setText("ON")
            self._mw.cooler_on_label.setText("Cooler OFF")
        self._mw.camera_temperature.setText("{}°C".format(
            round(self.spectrumlogic().camera_temperature - 273.15, 2)))

        self._center_wavelength_widget = ScienDSpinBox()
        self._center_wavelength_widget.setMinimum(0)
        self._center_wavelength_widget.setValue(
            self.spectrumlogic().center_wavelength)
        self._center_wavelength_widget.setSuffix("m")
        self._mw.center_wavelength.addWidget(self._center_wavelength_widget, 1)
        self._mw.go_to_wavelength.clicked.connect(
            self._manage_center_wavelength)
        self._mw.center_wavelength_current.setText("{:.2r}m".format(
            ScaledFloat(self.spectrumlogic().center_wavelength)))

        self._calibration_widget.editingFinished.connect(
            self.set_settings_params)
        self._settings_tab.camera_gains.currentTextChanged.connect(
            self.set_settings_params)
        self._settings_tab.trigger_modes.currentTextChanged.connect(
            self.set_settings_params)
        self._temperature_widget.editingFinished.connect(
            self.set_settings_params)
        if not self.spectrumlogic().camera_constraints.has_shutter:
            self._settings_tab.shutter_modes.setEnabled(False)
        else:
            self._settings_tab.shutter_modes.setCurrentText(
                self.spectrumlogic().shutter_state)
            self._settings_tab.shutter_modes.currentTextChanged.connect(
                self.set_settings_params)

        self._update_temperature_timer = QtCore.QTimer()
        self._update_temperature_timer.timeout.connect(
            self._update_temperature)
        self._update_temperature_timer.start(1000)

        self.spectrumlogic().sigUpdateSettings.connect(self._update_settings)
    def createEditor(self, parent, option, index):
        """ Create for the display and interaction with the user an editor.

        @param QtGui.QWidget parent: The parent object, here QTableWidget
        @param QtGui.QStyleOptionViewItemV4 option: This is a setting option
                                                    which you can use for style
                                                    configuration.
        @param QtCore.QModelIndex index: That index will be passed by the model
                                         object of the QTableWidget to the
                                         delegated object. This index contains
                                         information about the selected current
                                         cell.

        An editor can be in principle any QWidget, which you want to use to
        display the current (model-)data. Therefore the editor is like a
        container, which handles the passed entries from the user interface and
        should save the data to the model object of the QTableWidget. The
        setEditorData function reads data from the model.

        Do not save the created editor as a class variable! This consumes a lot
        of unneeded memory. It is way better to create an editor if it is
        needed. The inherent function closeEditor() of QStyledItemDelegate
        takes care of closing and destroying the editor for you, if it is not
        needed any longer.
        """
        editor = ScienDSpinBox(parent=parent)
        editor.setMinimum(self.item_dict['min'] / self.norm_val)
        editor.setMaximum(self.item_dict['max'] / self.norm_val)
        editor.setSingleStep(self.item_dict['view_stepsize'] / self.norm_val)
        editor.setDecimals(self.item_dict['dec'])
        editor.installEventFilter(self)
        editor.setValue(self.item_dict['init_val'] / self.norm_val)
        editor.setMaximumHeight(100)
        return editor
Example #13
0
class ColorbarWidget(QtWidgets.QWidget):
    """ Create the widget, based on the corresponding *.ui file."""
    def __init__(self, image_widget, unit='c/s'):
        # Get the path to the *.ui file
        this_dir = os.path.dirname(__file__)
        ui_file = os.path.join(this_dir, 'ui_colorbar.ui')

        # Load it
        super(ColorbarWidget, self).__init__()
        uic.loadUi(ui_file, self)

        self._cb_min = 0
        self._cb_max = 100
        self.unit = unit

        self.init_spin_box()
        self.init_colorbar()

        self.set_image(image_widget)

        self.percentile.clicked.emit()
        self.percentile.setChecked(True)

    def init_spin_box(self):
        """ Initialize all the spinboxes """
        self._min_percentile = ScienDSpinBox()
        self._min_manual = ScienDSpinBox()
        self._max_percentile = ScienDSpinBox()
        self._max_manual = ScienDSpinBox()

        self._min_percentile.setSuffix('%')
        self._min_percentile.setMinimum(0)
        self._min_percentile.setMaximum(100)
        self._min_percentile.setValue(0)

        self._min_manual.setSuffix(self.unit)

        self._max_percentile.setSuffix('%')
        self._max_percentile.setMinimum(0)
        self._max_percentile.setMaximum(100)
        self._max_percentile.setValue(100)

        self._max_manual.setSuffix(self.unit)

        self.min.addWidget(self._min_manual)
        self.min.addWidget(self._min_percentile)
        self.max.addWidget(self._max_percentile)
        self.max.addWidget(self._max_manual)

        self._min_percentile.valueChanged.connect(self.shortcut_to_cb_centiles)
        self._min_manual.valueChanged.connect(self.shortcut_to_cb_manual)
        self._max_percentile.valueChanged.connect(self.shortcut_to_cb_centiles)
        self._max_manual.valueChanged.connect(self.shortcut_to_cb_manual)

        self.manual.clicked.connect(self.update_cb_range)
        self.percentile.clicked.connect(self.update_cb_range)

    def init_colorbar(self):
        """ Create the colorbar """
        self.my_colors = ColorScaleInferno()
        self._color_map = ColorScaleMagma()
        self._cb = ColorBar(self.my_colors.cmap_normed,
                            width=100,
                            cb_min=self._cb_min,
                            cb_max=self._cb_max)
        self.colorbar.addItem(self._cb)
        self.colorbar.hideAxis('bottom')
        self.colorbar.setLabel('left', 'Intensity', units=self.unit)
        self.colorbar.setMouseEnabled(x=False, y=False)

    def set_image(self, image_widget):
        """ Set the image widget associated to the colorbar """
        self._image = image_widget
        self._min_manual.setValue(np.min(self._image.image))
        self._min_percentile.setValue(0)
        self._max_manual.setValue(np.max(self._image.image))
        self._max_percentile.setValue(100)
        self.refresh_colorbar()

    def get_cb_range(self):
        """ Determines the cb_min and cb_max values for the image """
        # If "Manual" is checked, or the image data is empty (all zeros), then take manual cb range.
        if self.manual.isChecked() or np.count_nonzero(self._image.image) < 1:
            cb_min = self._min_manual.value()
            cb_max = self._max_manual.value()

        # Otherwise, calculate cb range from percentiles.
        else:
            # Exclude any zeros (which are typically due to unfinished scan)
            image_nonzero = self._image.image[np.nonzero(self._image.image)]

            # Read centile range
            low_centile = self._min_percentile.value()
            high_centile = self._max_percentile.value()

            cb_min = np.percentile(image_nonzero, low_centile)
            cb_max = np.percentile(image_nonzero, high_centile)

        cb_range = [cb_min, cb_max]

        return cb_range

    def refresh_colorbar(self):
        """ Adjust the colorbar. """
        cb_range = self.get_cb_range()
        self._cb.refresh_colorbar(cb_range[0], cb_range[1])

    def refresh_image(self):
        """ Update the image colors range."""

        image_data = self._image.image
        cb_range = self.get_cb_range()
        self._image.setImage(image=image_data,
                             levels=(cb_range[0], cb_range[1]))
        self.refresh_colorbar()

    def update_cb_range(self):
        """ Redraw colour bar and image."""
        self.refresh_colorbar()
        self.refresh_image()

    def shortcut_to_cb_manual(self):
        """ Someone edited the absolute counts range for the colour bar, better update."""
        self.manual.setChecked(True)
        self.update_cb_range()

    def shortcut_to_cb_centiles(self):
        """Someone edited the centiles range for the colour bar, better update."""
        self.percentile.setChecked(True)
        self.update_cb_range()