diff --git a/software/control/core.py b/software/control/core.py index d6d1d9ab..86b8d9c9 100644 --- a/software/control/core.py +++ b/software/control/core.py @@ -3329,195 +3329,6 @@ def set_autolevel(self,enabled): print('set autolevel to ' + str(enabled)) -class ImageArrayDisplayWindow(QMainWindow): - - def __init__(self, window_title=''): - super().__init__() - self.setWindowTitle(window_title) - self.setWindowFlags(self.windowFlags() | Qt.CustomizeWindowHint) - self.setWindowFlags(self.windowFlags() & ~Qt.WindowCloseButtonHint) - self.widget = QWidget() - - # interpret image data as row-major instead of col-major - pg.setConfigOptions(imageAxisOrder='row-major') - - self.graphics_widget_1 = pg.GraphicsLayoutWidget() - self.graphics_widget_1.view = self.graphics_widget_1.addViewBox() - self.graphics_widget_1.view.setAspectLocked(True) - self.graphics_widget_1.img = pg.ImageItem(border='w') - self.graphics_widget_1.view.addItem(self.graphics_widget_1.img) - self.graphics_widget_1.view.invertY() - - self.graphics_widget_2 = pg.GraphicsLayoutWidget() - self.graphics_widget_2.view = self.graphics_widget_2.addViewBox() - self.graphics_widget_2.view.setAspectLocked(True) - self.graphics_widget_2.img = pg.ImageItem(border='w') - self.graphics_widget_2.view.addItem(self.graphics_widget_2.img) - self.graphics_widget_2.view.invertY() - - self.graphics_widget_3 = pg.GraphicsLayoutWidget() - self.graphics_widget_3.view = self.graphics_widget_3.addViewBox() - self.graphics_widget_3.view.setAspectLocked(True) - self.graphics_widget_3.img = pg.ImageItem(border='w') - self.graphics_widget_3.view.addItem(self.graphics_widget_3.img) - self.graphics_widget_3.view.invertY() - - self.graphics_widget_4 = pg.GraphicsLayoutWidget() - self.graphics_widget_4.view = self.graphics_widget_4.addViewBox() - self.graphics_widget_4.view.setAspectLocked(True) - self.graphics_widget_4.img = pg.ImageItem(border='w') - self.graphics_widget_4.view.addItem(self.graphics_widget_4.img) - self.graphics_widget_4.view.invertY() - ## Layout - layout = QGridLayout() - layout.addWidget(self.graphics_widget_1, 0, 0) - layout.addWidget(self.graphics_widget_2, 0, 1) - layout.addWidget(self.graphics_widget_3, 1, 0) - layout.addWidget(self.graphics_widget_4, 1, 1) - self.widget.setLayout(layout) - self.setCentralWidget(self.widget) - - # set window size - desktopWidget = QDesktopWidget(); - width = min(desktopWidget.height()*0.9,1000) #@@@TO MOVE@@@# - height = width - self.setFixedSize(int(width),int(height)) - - def display_image(self,image,illumination_source): - if illumination_source < 11: - self.graphics_widget_1.img.setImage(image,autoLevels=False) - elif illumination_source == 11: - self.graphics_widget_2.img.setImage(image,autoLevels=False) - elif illumination_source == 12: - self.graphics_widget_3.img.setImage(image,autoLevels=False) - elif illumination_source == 13: - self.graphics_widget_4.img.setImage(image,autoLevels=False) - - -class ConfigurationManager(QObject): - def __init__(self,filename="channel_configurations.xml"): - QObject.__init__(self) - self.config_filename = filename - self.configurations = [] - self.read_configurations() - - def save_configurations(self): - self.write_configuration(self.config_filename) - - def write_configuration(self,filename): - self.config_xml_tree.write(filename, encoding="utf-8", xml_declaration=True, pretty_print=True) - - def read_configurations(self): - if(os.path.isfile(self.config_filename)==False): - utils_config.generate_default_configuration(self.config_filename) - print('genenrate default config files') - self.config_xml_tree = etree.parse(self.config_filename) - self.config_xml_tree_root = self.config_xml_tree.getroot() - self.num_configurations = 0 - for mode in self.config_xml_tree_root.iter('mode'): - self.num_configurations += 1 - self.configurations.append( - Configuration( - mode_id = mode.get('ID'), - name = mode.get('Name'), - color = self.get_channel_color(mode.get('Name')), - exposure_time = float(mode.get('ExposureTime')), - analog_gain = float(mode.get('AnalogGain')), - illumination_source = int(mode.get('IlluminationSource')), - illumination_intensity = float(mode.get('IlluminationIntensity')), - camera_sn = mode.get('CameraSN'), - z_offset = float(mode.get('ZOffset')), - pixel_format = mode.get('PixelFormat'), - _pixel_format_options = mode.get('_PixelFormat_options'), - emission_filter_position = int(mode.get('EmissionFilterPosition', 1)) - ) - ) - - def update_configuration(self,configuration_id,attribute_name,new_value): - conf_list = self.config_xml_tree_root.xpath("//mode[contains(@ID," + "'" + str(configuration_id) + "')]") - mode_to_update = conf_list[0] - mode_to_update.set(attribute_name,str(new_value)) - self.save_configurations() - - def update_configuration_without_writing(self, configuration_id, attribute_name, new_value): - conf_list = self.config_xml_tree_root.xpath("//mode[contains(@ID," + "'" + str(configuration_id) + "')]") - mode_to_update = conf_list[0] - mode_to_update.set(attribute_name,str(new_value)) - - def write_configuration_selected(self,selected_configurations,filename): # to be only used with a throwaway instance - for conf in self.configurations: - self.update_configuration_without_writing(conf.id, "Selected", 0) - for conf in selected_configurations: - self.update_configuration_without_writing(conf.id, "Selected", 1) - self.write_configuration(filename) - for conf in selected_configurations: - self.update_configuration_without_writing(conf.id, "Selected", 0) - - def get_channel_color(self, channel): - channel_info = CHANNEL_COLORS_MAP.get(self.extract_wavelength(channel), {'hex': 0xFFFFFF, 'name': 'gray'}) - return channel_info['hex'] - - def extract_wavelength(self, name): - # Split the string and find the wavelength number immediately after "Fluorescence" - parts = name.split() - if 'Fluorescence' in parts: - index = parts.index('Fluorescence') + 1 - if index < len(parts): - return parts[index].split()[0] # Assuming 'Fluorescence 488 nm Ex' and taking '488' - for color in ['R', 'G', 'B']: - if color in parts or "full_" + color in parts: - return color - return None - - -class ContrastManager: - def __init__(self): - self.contrast_limits = {} - self.acquisition_dtype = None - - def update_limits(self, channel, min_val, max_val): - self.contrast_limits[channel] = (min_val, max_val) - - def get_limits(self, channel, dtype=None): - if dtype is not None: - if self.acquisition_dtype is None: - self.acquisition_dtype = dtype - elif self.acquisition_dtype != dtype: - self.scale_contrast_limits(dtype) - return self.contrast_limits.get(channel, self.get_default_limits()) - - def get_default_limits(self): - if self.acquisition_dtype is None: - return (0, 1) - elif np.issubdtype(self.acquisition_dtype, np.integer): - info = np.iinfo(self.acquisition_dtype) - return (info.min, info.max) - elif np.issubdtype(self.acquisition_dtype, np.floating): - return (0.0, 1.0) - else: - return (0, 1) - - def get_scaled_limits(self, channel, target_dtype): - min_val, max_val = self.get_limits(channel) - if self.acquisition_dtype == target_dtype: - return min_val, max_val - - source_info = np.iinfo(self.acquisition_dtype) - target_info = np.iinfo(target_dtype) - - scaled_min = (min_val - source_info.min) / (source_info.max - source_info.min) * (target_info.max - target_info.min) + target_info.min - scaled_max = (max_val - source_info.min) / (source_info.max - source_info.min) * (target_info.max - target_info.min) + target_info.min - - return scaled_min, scaled_max - - def scale_contrast_limits(self, target_dtype): - print(f"{self.acquisition_dtype} -> {target_dtype}") - for channel in self.contrast_limits.keys(): - self.contrast_limits[channel] = self.get_scaled_limits(channel, target_dtype) - - self.acquisition_dtype = target_dtype - - class NavigationViewer(QFrame): signal_coordinates_clicked = Signal(float, float) # Will emit x_mm, y_mm when clicked