def open_image_files(self): # Get the most recent images dir images_dir = HexrdConfig().images_dir selected_files, selected_filter = QFileDialog.getOpenFileNames( self.ui, dir=images_dir) if selected_files: # Save the chosen dir HexrdConfig().set_images_dir(selected_files[0]) # Make sure the number of files and number of detectors match num_detectors = len(HexrdConfig().get_detector_names()) if len(selected_files) != num_detectors: msg = ('Number of files must match number of detectors: ' + str(num_detectors)) QMessageBox.warning(self.ui, 'HEXRD', msg) return # If it is a hdf5 file allow the user to select the path ext = os.path.splitext(selected_files[0])[1] if (ImageFileManager().is_hdf5(ext) and not ImageFileManager().path_exists(selected_files[0])): ImageFileManager().path_prompt(selected_files[0]) dialog = LoadImagesDialog(selected_files, self.ui) if dialog.exec_(): detector_names, image_files = dialog.results() ImageFileManager().load_images(detector_names, image_files) self.ui.action_edit_ims.setEnabled(True) self.ui.action_edit_angles.setEnabled(True) self.update_all() self.new_images_loaded.emit()
def load_images(self): caption = HexrdConfig().images_dirtion = 'Select file(s)' selected_file, selected_filter = QFileDialog.getOpenFileName( self.ui, caption, dir=HexrdConfig().images_dir) if selected_file: HexrdConfig().set_images_dir(selected_file) files, manual = ImageLoadManager().load_images([selected_file]) dialog = LoadImagesDialog(files, manual, self.ui.parent()) if not dialog.exec_(): return # If it is a hdf5 file allow the user to select the path ext = os.path.splitext(selected_file)[1] if (ImageFileManager().is_hdf(ext) and not ImageFileManager().path_exists(selected_file)): path_selected = ImageFileManager().path_prompt(selected_file) if not path_selected: return ImageLoadManager().read_data(files, parent=self.ui) file_names = [os.path.split(f[0])[1] for f in files] self.ui.files_label.setText(', '.join(file_names)) self.enable_widgets(self.ui.outline, self.ui.add_template, self.ui.transforms, self.ui.add_transform, enabled=True) self.enable_widgets(self.parent().action_show_toolbar, self.ui.save, enabled=False) self.parent().action_show_toolbar.setChecked(False)
def process_ims(self, postprocess, update_progress): self.update_progress = update_progress self.update_progress(0) if not postprocess: # Open selected images as imageseries self.parent_dir = HexrdConfig().images_dir det_names = HexrdConfig().detector_names if len(self.files[0]) > 1: for i, det in enumerate(det_names): dirs = self.parent_dir ims = ImageFileManager().open_directory(dirs, self.files[i]) HexrdConfig().imageseries_dict[det] = ims else: ImageFileManager().load_images(det_names, self.files) elif self.unaggregated_images is not None: HexrdConfig().imageseries_dict = copy.copy(self.unaggregated_images) self.reset_unagg_imgs() # Now that self.state is set, setup the progress variables self.setup_progress_variables() # Process the imageseries self.apply_operations(HexrdConfig().imageseries_dict) if self.data: if 'agg' in self.state and self.state['agg']: self.display_aggregation(HexrdConfig().imageseries_dict) else: self.add_omega_metadata(HexrdConfig().imageseries_dict) self.update_progress(100)
def load_image_data(self, selected_files): self.ext = os.path.splitext(selected_files[0])[1] has_omega = False # Select the path if the file(s) are HDF5 if (ImageFileManager().is_hdf5(self.ext) and not ImageFileManager().path_exists(selected_files[0])): if ImageFileManager().path_prompt(selected_files[0]) is not None: return fnames = [] tmp_ims = [] for img in selected_files: f = os.path.split(img)[1] name = os.path.splitext(f)[0] if not self.ui.subdirectories.isChecked(): name = name.rsplit('_', 1)[0] if self.ext != '.yml': tmp_ims.append(ImageFileManager().open_file(img)) fnames.append(name) self.find_images(fnames) if not self.files: return if self.ext == '.yml': for yf in self.yml_files[0]: ims = ImageFileManager().open_file(yf) self.total_frames.append(len(ims)) for f in self.files[0]: with open(f, 'r') as raw_file: data = yaml.safe_load(raw_file) if 'ostart' in data['meta'] or 'omega' in data['meta']: self.get_yaml_omega_data(data) else: self.omega_min = [''] * len(self.yml_files[0]) self.omega_max = [''] * len(self.yml_files[0]) self.delta = [''] * len(self.yml_files[0]) self.empty_frames = data['options']['empty-frames'] else: for ims in tmp_ims: has_omega = 'omega' in ims.metadata self.total_frames.append(len(ims)) if has_omega: self.get_omega_data(ims) else: self.omega_min.append('') self.omega_max.append('') self.delta.append('')
def load_image_data(self, selected_files): self.ext = Path(selected_files[0]).suffix has_omega = False # Select the path if the file(s) are HDF5 if (ImageFileManager().is_hdf(self.ext) and not ImageFileManager().path_exists(selected_files[0])): if ImageFileManager().path_prompt(selected_files[0]) is None: return tmp_ims = [] for img in selected_files: if self.ext not in YAML_EXTS: tmp_ims.append(ImageFileManager().open_file(img)) self.find_images(selected_files) if not self.files: return if self.ext in YAML_EXTS: for yf in self.yml_files[0]: ims = ImageFileManager().open_file(yf) self.total_frames.append(len(ims) if len(ims) > 0 else 1) for f in self.files[0]: with open(f, 'r') as raw_file: data = yaml.safe_load(raw_file) if 'ostart' in data['meta'] or 'omega' in data['meta']: self.get_yaml_omega_data(data) else: self.omega_min = [0] * len(self.yml_files[0]) self.omega_max = [0.25] * len(self.yml_files[0]) self.nsteps = [self.total_frames[0]] * len(self.yml_files[0]) options = data.get('options', {}) self.empty_frames = 0 if isinstance(options, dict): empty = options.get('empty-frames', 0) self.empty_frames = empty self.total_frames = [f-empty for f in self.total_frames] else: for ims in tmp_ims: has_omega = 'omega' in ims.metadata self.total_frames.append(len(ims) if len(ims) > 0 else 1) if has_omega: self.get_omega_data(ims) else: self.omega_min.append(0) self.omega_max.append(0.25) self.nsteps.append(len(ims))
def get_dark_aggr_op(self, ims, idx): """ Returns a tuple of the form (function, frames), where func is the function to be applied and frames is the number of frames to aggregate. """ i = self.data['idx'] if 'idx' in self.data else idx dark_idx = self.state['dark'][i] if dark_idx == UI_DARK_INDEX_FILE: ims = ImageFileManager().open_file(self.state['dark_files'][idx]) # Create or load the dark image if selected frames = len(ims) if dark_idx != UI_DARK_INDEX_FILE and frames > 120: frames = 120 if dark_idx == UI_DARK_INDEX_MEDIAN: f = imageseries.stats.median_iter elif dark_idx == UI_DARK_INDEX_EMPTY_FRAMES: f = imageseries.stats.average_iter frames = self.empty_frames elif dark_idx == UI_DARK_INDEX_AVERAGE: f = imageseries.stats.average_iter elif dark_idx == UI_DARK_INDEX_MAXIMUM: f = imageseries.stats.max_iter else: f = imageseries.stats.median_iter return (f, frames, ims)
def load_images(self): if self.instrument == 'PXRDIP': HexrdConfig().load_panel_state['trans'] = ( [UI_TRANS_INDEX_FLIP_HORIZONTALLY]) caption = HexrdConfig().images_dirtion = 'Select file(s)' selected_file, selected_filter = QFileDialog.getOpenFileName( self.ui, caption, dir=HexrdConfig().images_dir) if selected_file: HexrdConfig().set_images_dir(selected_file) files, manual = ImageLoadManager().load_images([selected_file]) dialog = LoadImagesDialog(files, manual, self.ui.parent()) if not dialog.exec_(): return # If it is a hdf5 file allow the user to select the path ext = os.path.splitext(selected_file)[1] if (ImageFileManager().is_hdf(ext) and not ImageFileManager().path_exists(selected_file)): path_selected = ImageFileManager().path_prompt(selected_file) if not path_selected: return if not self.canvas.raw_axes[0].get_autoscale_on(): self.canvas.raw_axes[0].set_autoscale_on(True) if self.completed_detectors: # Only reset the color map range for first detector processed self.cmap.block_updates(True) if self.ui.instrument.isEnabled(): # Only set the instrument config once success = self.get_instrument_defaults() if not success: return ImageLoadManager().read_data(files, parent=self.ui) self.cmap.block_updates(False) self.it = InteractiveTemplate(self.parent()) file_names = [os.path.split(f[0])[1] for f in files] self.ui.files_label.setText(', '.join(file_names)) self.enable_widgets(self.ui.transform_img, self.ui.association, self.ui.finalize, enabled=True) self.enable_widgets(self.ui.data, enabled=False)
def load_images(self): caption = HexrdConfig().images_dirtion = 'Select file(s)' selected_file, selected_filter = QFileDialog.getOpenFileName( self.ui, caption, dir=HexrdConfig().images_dir) if selected_file: HexrdConfig().set_images_dir(selected_file) files, manual = ImageLoadManager().load_images([selected_file]) dialog = LoadImagesDialog(files, manual, self.ui.parent()) if not dialog.exec_(): return # If it is a hdf5 file allow the user to select the path ext = os.path.splitext(selected_file)[1] if (ImageFileManager().is_hdf(ext) and not ImageFileManager().path_exists(selected_file)): path_selected = ImageFileManager().path_prompt(selected_file) if not path_selected: return if not self.canvas.raw_axes[0].get_autoscale_on(): self.canvas.raw_axes[0].set_autoscale_on(True) if hasattr(self, 'prev_extent'): self.canvas.axes_images[0].set_extent(self.prev_extent) if self.completed_detectors: # Only reset the color map range for first detector processed self.cmap.block_updates(True) ImageLoadManager().read_data(files, parent=self.ui) self.prev_extent = self.canvas.axes_images[0].get_extent() self.cmap.block_updates(False) file_names = [os.path.split(f[0])[1] for f in files] self.ui.files_label.setText(', '.join(file_names)) self.enable_widgets(self.ui.outline, self.ui.add_template, self.ui.transforms, self.ui.add_transform, enabled=True) self.enable_widgets(self.parent().action_show_toolbar, self.ui.save, enabled=False) self.parent().action_show_toolbar.setChecked(False)
def open_image_files(self): # Get the most recent images dir images_dir = HexrdConfig().images_dir selected_files, selected_filter = QFileDialog.getOpenFileNames( self.ui, dir=images_dir) if selected_files: # Save the chosen dir HexrdConfig().set_images_dir(selected_files[0]) files, manual = ImageLoadManager().load_images(selected_files) if not files: return if (any(len(f) != 1 for f in files) or len(files) < len(HexrdConfig().detector_names)): msg = ('Number of files must match number of detectors: ' + str(len(HexrdConfig().detector_names))) QMessageBox.warning(self.ui, 'HEXRD', msg) return # If it is a hdf5 file allow the user to select the path ext = os.path.splitext(selected_files[0])[1] if (ImageFileManager().is_hdf(ext) and not ImageFileManager().path_exists(selected_files[0])): selection = ImageFileManager().path_prompt(selected_files[0]) if not selection: return dialog = LoadImagesDialog(files, manual, self.ui) if dialog.exec_(): detector_names, image_files = dialog.results() image_files = [img for f in files for img in f] files = [[] for det in HexrdConfig().detector_names] for d, f in zip(detector_names, image_files): pos = HexrdConfig().detector_names.index(d) files[pos].append(f) ImageLoadManager().read_data(files, parent=self.ui) self.images_loaded()
def process_ims(self): # Open selected images as imageseries det_names = HexrdConfig().get_detector_names() if len(self.files[0]) > 1: for i, det in enumerate(det_names): if self.directories: dirs = self.directories[i] else: dirs = self.parent_dir ims = ImageFileManager().open_directory(dirs, self.files[i]) HexrdConfig().imageseries_dict[det] = ims else: ImageFileManager().load_images(det_names, self.files) # Process the imageseries self.apply_operations(HexrdConfig().imageseries_dict) if self.state['agg']: self.display_aggregation(HexrdConfig().imageseries_dict) elif '' not in self.omega_min: self.add_omega_metadata(HexrdConfig().imageseries_dict)
def process_ims(self, postprocess, update_progress): self.update_progress = update_progress self.update_progress(0) if not postprocess: # Open selected images as imageseries self.parent_dir = HexrdConfig().images_dir det_names = HexrdConfig().detector_names options = { 'empty-frames': self.data.get('empty_frames', 0), 'max-file-frames': self.data.get('max_file_frames', 0), 'max-total-frames': self.data.get( 'max_total_frames', 0), } if len(self.files[0]) > 1: for i, det in enumerate(det_names): dirs = os.path.dirname(self.files[i][0]) ims = ImageFileManager().open_directory(dirs, self.files[i], options) HexrdConfig().imageseries_dict[det] = ims else: ImageFileManager().load_images(det_names, self.files, options) HexrdConfig().reset_unagg_imgs(new_imgs=True) # Now that self.state is set, setup the progress variables self.setup_progress_variables() # Process the imageseries self.apply_operations(HexrdConfig().imageseries_dict) if self.data: self.add_omega_metadata(HexrdConfig().imageseries_dict) if 'agg' in self.state and self.state['agg']: self.display_aggregation(HexrdConfig().imageseries_dict) self.update_progress(100)
def select_files_manually(self, files): if not files: files, selected_filter = QFileDialog.getOpenFileNames( self.ui, 'Select file(s)', dir=self.state[self.detector]['directory']) self.state[self.detector]['files'] = files self.state[self.detector]['file_count'] = len(files) ims = ImageFileManager().open_file(str(files[0])) frames = len(ims) if len(ims) else 1 self.ui.total_frames.setText(str(frames)) self.ui.file_count.setText(str(len(files))) self.set_ranges(frames, len(files)) self.state['total_frames'] = frames self.total_frames()
def display_aggregation(self, ims_dict): self.update_progress_text('Aggregating images...') # Remember unaggregated images HexrdConfig().set_unagg_images() if self.state['agg'] == UI_AGG_INDEX_MAXIMUM: agg_func = imageseries.stats.max_iter elif self.state['agg'] == UI_AGG_INDEX_MEDIAN: agg_func = imageseries.stats.median_iter else: agg_func = imageseries.stats.average_iter f = functools.partial(self.aggregate_images, agg_func=agg_func) for (key, aggr_img) in zip(ims_dict.keys(), self.aggregate_images_multithread(f, ims_dict)): ims_dict[key] = ImageFileManager().open_file(aggr_img)
def find_previous_images(self, files): try: ims = ImageFileManager().open_file(files[0]) frames = len(ims) if len(ims) else 1 self.ui.total_frames.setText(str(frames)) self.set_ranges(frames, len(files)) self.state['total_frames'] = frames self.total_frames() except Exception as e: msg = ( f'Unable to open previously loaded images, please make sure ' f'directory path is correct and that images still exist.') QMessageBox.warning(self.parent(), 'HEXRD', msg) for det in self.detectors: self.state[det]['files'] = '' self.state[det]['file_count'] = 0
def get_dark_op(self, oplist, ims): # Create or load the dark image if selected if self.state['dark'] != 4: frames = len(ims) if self.state['dark'] == 0: darkimg = imageseries.stats.median(ims, frames) elif self.state['dark'] == 1: darkimg = imageseries.stats.average(ims, self.empty_frames) elif self.state['dark'] == 2: darkimg = imageseries.stats.average(ims, frames) else: darkimg = imageseries.stats.max(ims, frames) else: darkimg = imageseries.stats.median(ImageFileManager().open_file( self.dark_file)) oplist.append(('dark', darkimg))
def open_aps_imageseries(self): # Get the most recent images dir images_dir = HexrdConfig().images_dir detector_names = HexrdConfig().detector_names selected_dirs = [] for name in detector_names: caption = 'Select directory for detector: ' + name d = QFileDialog.getExistingDirectory(self.ui, caption, dir=images_dir) if not d: return selected_dirs.append(d) images_dir = os.path.dirname(d) ImageFileManager().load_aps_imageseries(detector_names, selected_dirs) self.update_all() self.new_images_loaded.emit()
class ImageStackDialog(QObject): # Emitted when images are cleared clear_images = Signal() def __init__(self, parent=None, load_panel=None): super(ImageStackDialog, self).__init__(parent) loader = UiLoader() self.ui = loader.load_file('image_stack_dialog.ui', parent) self.load_panel = load_panel self.detectors = HexrdConfig().detector_names self.detector = self.detectors[0] self.state = copy.copy(HexrdConfig().stack_state) self.setup_state() self.ui.detectors.addItems(self.detectors) self.setup_gui() self.setup_connections() def setup_connections(self): self.ui.select_directory.clicked.connect(self.select_directory) self.ui.omega_from_file.toggled.connect(self.load_omega_from_file) self.ui.load_omega_file.clicked.connect(self.select_omega_file) self.ui.search.clicked.connect(self.search) self.ui.empty_frames.valueChanged.connect(self.set_empty_frames) self.ui.max_file_frames.valueChanged.connect(self.set_max_file_frames) self.ui.max_total_frames.valueChanged.connect( self.set_max_total_frames) self.ui.detectors.currentTextChanged.connect(self.change_detector) self.ui.files_by_selection.toggled.connect(self.file_selection_changed) self.ui.select_files.clicked.connect(self.select_files_manually) self.ui.add_wedge.clicked.connect(self.add_wedge) self.ui.clear_wedges.clicked.connect(self.clear_wedges) self.ui.omega_wedges.cellChanged.connect(self.update_wedges) self.ui.all_detectors.toggled.connect(self.detector_selection) self.ui.search_directories.clicked.connect(self.search_directories) self.ui.clear_file_selections.clicked.connect( self.clear_selected_files) self.clear_images.connect(self.load_panel.clear_from_stack_dialog) def setup_gui(self): self.ui.current_directory.setText( self.state[self.detector]['directory']) self.ui.current_directory.setToolTip( self.state[self.detector]['directory']) self.ui.search_text.setText(self.state[self.detector]['search']) self.ui.empty_frames.setValue(self.state['empty_frames']) self.ui.max_file_frames.setValue(self.state['max_file_frames']) self.ui.max_total_frames.setValue(self.state['max_total_frames']) self.ui.omega_from_file.setChecked(self.state['omega_from_file']) if self.state['omega']: self.ui.omega_file.setText(self.state['omega'].split(' ')[-1]) self.ui.omega_from_file.setChecked(self.state['omega_from_file']) self.ui.files_by_selection.setChecked(self.state['manual_file']) self.ui.files_by_search.setChecked(not self.state['manual_file']) file_count = self.state[self.detector]['file_count'] self.ui.file_count.setText(str(file_count)) self.ui.apply_to_all.setChecked(self.state['apply_to_all']) self.ui.all_detectors.setChecked(self.state['all_detectors']) self.ui.total_frames.setText( str(self.state['total_frames'] * file_count)) self.set_ranges(self.state['total_frames'], int(self.state[self.detector]['file_count'])) if self.state['wedges']: self.set_wedges() self.total_frames() def setup_state(self): if (sorted(self.state.get('dets', [])) != sorted(self.detectors) or 'max_frame_file' in self.state.keys()): self.state.clear() if self.state: self.find_previous_images(self.state[self.detector]['files']) self.load_omega_from_file(self.state['omega_from_file']) self.file_selection_changed(self.state['manual_file']) self.detector_selection(self.state['all_detectors']) else: self.state.clear() self.state = { 'all_detectors': True, 'dets': self.detectors, 'empty_frames': 0, 'max_file_frames': 0, 'max_total_frames': 0, 'omega': '', 'omega_from_file': True, 'total_frames': 1, 'manual_file': True, 'apply_to_all': True, 'wedges': [] } for det in self.detectors: self.state[det] = { 'directory': '', 'files': '', 'search': '', 'file_count': 0, } def set_wedges(self): if self.ui.omega_wedges.rowCount() == 0: for i, wedge in enumerate(self.state['wedges']): self.ui.omega_wedges.insertRow(i) for j, value in enumerate(wedge): self.ui.omega_wedges.setItem(i, j, QTableWidgetItem(str(value))) def select_directory(self): d = QFileDialog.getExistingDirectory(self.ui, 'Select directory', HexrdConfig().working_dir) self.state[self.detector]['directory'] = d HexrdConfig().working_dir = d.rsplit('/', 1)[0] self.ui.current_directory.setText(d) self.ui.current_directory.setToolTip(d) if not self.state['manual_file'] and self.state['apply_to_all']: self.search_directory(self.detector) def search(self): if self.ui.apply_to_all.isChecked( ) and self.ui.files_by_search.isChecked(): for det in self.detectors: self.search_directory(det) else: self.search_directory(self.detector) def search_directory(self, det): self.state[det]['search'] = self.ui.search_text.text() if not (search := self.ui.search_text.text()): search = '*' if directory := self.state[det]['directory']: if files := list(Path(directory).glob(search)): files = [f for f in files if f.is_file()] self.state[det]['files'] = sorted([str(f) for f in files]) self.state[det]['file_count'] = len(files) ims = ImageFileManager().open_file(str(files[0])) frames = len(ims) if len(ims) else 1 self.ui.total_frames.setText(str(frames)) self.ui.file_count.setText(str(len(files))) self.set_ranges(frames, len(files)) self.state['total_frames'] = frames self.total_frames()
def __init__(self, parent=None, image_files=None): super(MainWindow, self).__init__(parent) loader = UiLoader() self.ui = loader.load_file('main_window.ui', parent) self.workflow_widgets = {'HEDM': [], 'LLNL': []} self.thread_pool = QThreadPool(self) self.progress_dialog = ProgressDialog(self.ui) self.progress_dialog.setWindowTitle('Calibration Running') # Let the left dock widget take up the whole left side self.ui.setCorner(Qt.TopLeftCorner, Qt.LeftDockWidgetArea) self.ui.setCorner(Qt.BottomLeftCorner, Qt.LeftDockWidgetArea) self.color_map_editor = ColorMapEditor(self.ui.image_tab_widget, self.ui.central_widget) self.ui.color_map_dock_widgets.layout().addWidget( self.color_map_editor.ui) self.image_mode = ViewType.raw self.image_mode_widget = ImageModeWidget(self.ui.central_widget) self.ui.image_mode_dock_widgets.layout().addWidget( self.image_mode_widget.ui) self.add_materials_panel() self.load_widget = LoadPanel(self.ui) self.ui.load_page.setLayout(QVBoxLayout()) self.ui.load_page.layout().addWidget(self.load_widget.ui) self.load_widget.ui.setVisible(False) self.workflow_widgets[WORKFLOW_HEDM].append(self.load_widget.ui) self.import_data_widget = ImportDataPanel(self.ui) self.ui.load_page.setLayout(QVBoxLayout()) self.ui.load_page.layout().addWidget(self.import_data_widget.ui) self.import_data_widget.ui.setVisible(False) self.workflow_widgets[WORKFLOW_LLNL].append(self.import_data_widget.ui) self.cal_tree_view = CalTreeView(self.ui) self.calibration_config_widget = CalibrationConfigWidget(self.ui) self.calibration_slider_widget = CalibrationSliderWidget(self.ui) tab_texts = ['Tree View', 'Form View', 'Slider View'] self.ui.calibration_tab_widget.clear() self.ui.calibration_tab_widget.addTab(self.cal_tree_view, tab_texts[0]) self.ui.calibration_tab_widget.addTab( self.calibration_config_widget.ui, tab_texts[1]) self.ui.calibration_tab_widget.addTab( self.calibration_slider_widget.ui, tab_texts[2]) self.mask_manager_dialog = MaskManagerDialog(self.ui) self.setup_connections() self.update_config_gui() self.add_workflow_widgets() self.ui.action_show_live_updates.setChecked(HexrdConfig().live_update) self.live_update(HexrdConfig().live_update) ImageFileManager().load_dummy_images(True) # In order to avoid both a not very nice looking black window, # and a bug with the tabbed view # (see https://github.com/HEXRD/hexrdgui/issues/261), # do not draw the images before the first paint event has # occurred. The images will be drawn automatically after # the first paint event has occurred (see MainWindow.eventFilter). self.workflow_selection_dialog = WorkflowSelectionDialog(self.ui)
def load_dummy_images(self): ImageFileManager().load_dummy_images() self.update_all(clear_canvases=True) self.ui.action_transform_detectors.setEnabled(False) self.new_images_loaded.emit()