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)
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()