def on_action_save_config_yaml_triggered(self): selected_file, selected_filter = QFileDialog.getSaveFileName( self.ui, 'Save Configuration', HexrdConfig().working_dir, 'YAML files (*.yml)') if selected_file: HexrdConfig().working_dir = str(Path(selected_file).parent) return HexrdConfig().save_instrument_config(selected_file)
def live_update(self, enabled): previous = HexrdConfig().live_update HexrdConfig().set_live_update(enabled) if enabled: HexrdConfig().rerender_needed.connect(self.update_all) # Only disconnect if we were previously enabled. i.e. the signal was connected elif previous: HexrdConfig().rerender_needed.disconnect(self.update_all)
def on_action_save_imageseries_triggered(self): if not HexrdConfig().has_images(): msg = ('No ImageSeries available for saving.') QMessageBox.warning(self.ui, 'HEXRD', msg) return if ImageLoadManager().unaggregated_images: ims_dict = ImageLoadManager().unaggregated_images else: ims_dict = HexrdConfig().imageseries_dict if len(ims_dict) > 1: # Have the user choose an imageseries to save names = list(ims_dict.keys()) name, ok = QInputDialog.getItem(self.ui, 'HEXRD', 'Select ImageSeries', names, 0, False) if not ok: # User canceled... return else: name = list(ims_dict.keys())[0] selected_file, selected_filter = QFileDialog.getSaveFileName( self.ui, 'Save ImageSeries', HexrdConfig().working_dir, 'HDF5 files (*.h5 *.hdf5);; NPZ files (*.npz)') if selected_file: HexrdConfig().working_dir = os.path.dirname(selected_file) if selected_filter.startswith('HDF5'): selected_format = 'hdf5' elif selected_filter.startswith('NPZ'): selected_format = 'frame-cache' kwargs = {} if selected_format == 'hdf5': # A path must be specified. Set it ourselves for now. kwargs['path'] = 'imageseries' elif selected_format == 'frame-cache': # Get the user to pick a threshold result, ok = QInputDialog.getDouble(self.ui, 'HEXRD', 'Choose Threshold', 10, 0, 1e12, 3) if not ok: # User canceled... return kwargs['threshold'] = result # This needs to be specified, but I think it just needs # to be the same as the file name... kwargs['cache_file'] = selected_file HexrdConfig().save_imageseries(ims_dict.get(name), name, selected_file, selected_format, **kwargs)
def update_labels(self): # Make sure tilt labels reflect current euler convention if HexrdConfig().euler_angle_convention is None: a, b, c = 'xyz' else: a, b, c = HexrdConfig().euler_angle_convention['axes_order'] self.ui.label_tilt_2.setText(str.upper(a + ':')) self.ui.label_tilt_0.setText(str.upper(b + ':')) self.ui.label_tilt_1.setText(str.upper(c + ':'))
def on_action_export_polar_plot_triggered(self): selected_file, selected_filter = QFileDialog.getSaveFileName( self.ui, 'Save Polar Image', HexrdConfig().working_dir, 'HDF5 files (*.h5 *.hdf5);; NPZ files (*.npz)') if selected_file: HexrdConfig().working_dir = os.path.dirname(selected_file) return self.ui.image_tab_widget.export_polar_plot(selected_file)
def create_masks_list(self): self.masks = {} for v, i in enumerate(HexrdConfig().polar_masks_line_data): if not any(np.array_equal(m, v) for m in self.masks.values()): self.masks['mask_' + str(i)] = copy.copy(v) if HexrdConfig().threshold_mask_status: self.threshold_name = 'threshold' self.masks['threshold'] = HexrdConfig().threshold_mask self.visible = copy.copy(self.masks)
def setup_connections(self): HexrdConfig().overlay_config_changed.connect(self.update_overlays) HexrdConfig().show_saturation_level_changed.connect( self.show_saturation) HexrdConfig().detector_transform_modified.connect( self.on_detector_transform_modified) HexrdConfig().rerender_detector_borders.connect( self.draw_detector_borders) HexrdConfig().beam_vector_changed.connect(self.beam_vector_changed)
def setup_connections(self): self.ui.table.selectionModel().selectionChanged.connect( self.update_selections) HexrdConfig().active_material_modified.connect( self.active_material_modified) HexrdConfig().material_renamed.connect(self.update_material_name) HexrdConfig().update_reflections_tables.connect( self.update_table_if_name_matches)
def path_exists(self, f): try: imageseries.open(f, 'hdf5', path=HexrdConfig().hdf5_path[0], dataname=HexrdConfig().hdf5_path[1]) return True except: return False
def orientation(self): # This automatically converts from Euler angle conventions values = [x.value() for x in self.orientation_widgets] if HexrdConfig().euler_angle_convention is not None: values = np.radians(values) convention = HexrdConfig().euler_angle_convention self.convert_angle_convention(values, convention, None) return values
def run_apply_polar_mask(self, line_data): for line in line_data: name = create_unique_name( HexrdConfig().polar_masks_line_data, 'polar_mask_0') HexrdConfig().polar_masks_line_data[name] = line.copy() HexrdConfig().visible_masks.append(name) create_polar_mask([line.copy()], name) HexrdConfig().polar_masks_changed.emit() self.new_mask_added.emit(self.image_mode)
def orientation(self, v): # This automatically converts to Euler angle conventions if HexrdConfig().euler_angle_convention is not None: v = copy.deepcopy(v) convention = HexrdConfig().euler_angle_convention self.convert_angle_convention(v, None, convention) for i, w in enumerate(self.orientation_widgets): blocker = QSignalBlocker(w) # noqa: F841 w.setValue(v[i])
def load_instrument_config(self): temp = tempfile.NamedTemporaryFile(delete=False, suffix='.yml') self.config_file = temp.name HexrdConfig().save_instrument_config(self.config_file) fname = f'default_{self.instrument.lower()}_config.yml' with resource_loader.resource_path( hexrd.ui.resources.calibration, fname) as f: for overlay in HexrdConfig().overlays: overlay['visible'] = False HexrdConfig().load_instrument_config(f, import_raw=True)
def beam_vector_changed(self): if not self.iviewer or not hasattr(self.iviewer, 'instr'): return # Re-draw all overlays from scratch HexrdConfig().clear_overlay_data() bvec = HexrdConfig().instrument_config['beam']['vector'] self.iviewer.instr.beam_vector = (bvec['azimuth'], bvec['polar_angle']) self.update_overlays()
def on_action_open_config_triggered(self): selected_file, selected_filter = QFileDialog.getOpenFileName( self.ui, 'Load Configuration', HexrdConfig().working_dir, 'YAML files (*.yml)') if selected_file: HexrdConfig().load_instrument_config(selected_file) self.cal_tree_view.rebuild_tree() self.calibration_config_widget.update_gui_from_config() self.update_all(clear_canvases=True)
def tth_tol(self, v): v = np.radians(v) if self.material.planeData.tThWidth == v: # Just return... return self.material.planeData.tThWidth = v HexrdConfig().material_tth_width_modified.emit(self.material.name) HexrdConfig().flag_overlay_updates_for_material(self.material.name) HexrdConfig().overlay_config_changed.emit()
def on_action_open_materials_triggered(self): selected_file, selected_filter = QFileDialog.getOpenFileName( self.ui, 'Load Materials File', HexrdConfig().working_dir, 'HDF5 files (*.h5 *.hdf5)') if selected_file: HexrdConfig().working_dir = os.path.dirname(selected_file) HexrdConfig().load_materials(selected_file) self.materials_panel.update_gui_from_config() self.materials_panel.update_structure_tab()
def modify_material_name(self, new_name): names = HexrdConfig().materials.keys() if new_name in names: # Just ignore it return old_name = HexrdConfig().active_material_name() HexrdConfig().rename_material(old_name, new_name) self.update_gui_from_config()
def import_material(self): selected_file, selected_filter = QFileDialog.getOpenFileName( self.ui, 'Import Material', HexrdConfig().working_dir, 'CIF files (*.cif)') if selected_file: HexrdConfig().working_dir = os.path.dirname(selected_file) HexrdConfig().import_material(selected_file) self.update_gui_from_config() self.update_structure_tab()
def setup_processing_options(self): self.state = HexrdConfig().load_panel_state self.num_dets = len(HexrdConfig().detector_names) self.state.setdefault('agg', UI_AGG_INDEX_NONE) self.state.setdefault( 'trans', [UI_TRANS_INDEX_NONE for x in range(self.num_dets)]) self.state.setdefault( 'dark', [UI_DARK_INDEX_NONE for x in range(self.num_dets)]) self.state.setdefault( 'dark_files', [None for x in range(self.num_dets)])
def select_quaternion_grid_file(self): title = 'Select quaternion grid file' filters = 'NPY files (*.npy)' selected_file, selected_filter = QFileDialog.getOpenFileName( self.ui, title, HexrdConfig().working_dir, filters) if selected_file: HexrdConfig().working_dir = str(Path(selected_file).parent) self.quaternion_grid_file = selected_file
def snip_width_pixels(): from hexrd.ui.hexrd_config import HexrdConfig pixel_size_tth = HexrdConfig().polar_pixel_size_tth snip_width_deg = HexrdConfig().polar_snip1d_width # Convert the snip width into pixels using pixel_size_tth # Always round up return math.ceil(snip_width_deg / pixel_size_tth)
def load_aps_imageseries(self, detectors, directory_names): HexrdConfig().imageseries_dict.clear() for name, d in zip(detectors, directory_names): try: ims = self.open_directory(d) HexrdConfig().imageseries_dict[name] = ims except (Exception, IOError) as error: msg = ('ERROR - Could not read file: \n' + str(error)) QMessageBox.warning(None, 'HEXRD', msg) return
def write_instrument_to_hexrd_config(self, instr): iconfig = HexrdConfig().instrument_config_none_euler_convention # Add this so the calibration crystal gets written cal_crystal = iconfig.get('calibration_crystal') output_dict = instr.write_config(calibration_dict=cal_crystal) # Convert back to whatever convention we were using before eac = HexrdConfig().euler_angle_convention if eac is not None: convert_tilt_convention(output_dict, None, eac) # Add the saturation levels, as they seem to be missing sl = 'saturation_level' for det in output_dict['detectors'].keys(): output_dict['detectors'][det][sl] = iconfig['detectors'][det][sl] # Save the previous iconfig to restore the statuses prev_iconfig = HexrdConfig().config['instrument'] # Update the config HexrdConfig().config['instrument'] = output_dict # This adds in any missing keys. In particular, it is going to # add in any "None" detector distortions HexrdConfig().set_detector_defaults_if_missing() # Add status values HexrdConfig().add_status(output_dict) # Set the previous statuses to be the current statuses HexrdConfig().set_statuses_from_prev_iconfig(prev_iconfig)
def load_images(self, image_names): HexrdConfig().emit_update_status_bar('Loading image view...') if (self.mode != ViewType.raw or len(image_names) != len(self.axes_images)): # Either we weren't in image mode before, we have a different # number of images, or there are masks to apply. Clear and re-draw. self.clear() self.mode = ViewType.raw cols = 1 if len(image_names) > 1: cols = 2 rows = math.ceil(len(image_names) / cols) idx = HexrdConfig().current_imageseries_idx for i, name in enumerate(image_names): img = HexrdConfig().image(name, idx) # Apply any masks for mask_name, (det, mask) in HexrdConfig().raw_masks.items(): if (mask_name in HexrdConfig().visible_masks and det == name): img[~mask] = 0 axis = self.figure.add_subplot(rows, cols, i + 1) axis.set_title(name) self.axes_images.append( axis.imshow(img, cmap=self.cmap, norm=self.norm)) axis.autoscale(False) self.raw_axes.append(axis) self.figure.tight_layout() else: idx = HexrdConfig().current_imageseries_idx for i, name in enumerate(image_names): img = HexrdConfig().image(name, idx) # Apply any masks for mask_name, (det, mask) in HexrdConfig().raw_masks.items(): if (mask_name in HexrdConfig().visible_masks and det == name): img[~mask] = 0 self.axes_images[i].set_data(img) # This will call self.draw() self.show_saturation() # This will be used for drawing the rings self.iviewer = raw_iviewer() # Set the detectors to draw self.iviewer.detectors = [x.get_title() for x in self.raw_axes] self.update_overlays() msg = 'Image view loaded!' HexrdConfig().emit_update_status_bar(msg)
def remove_current_material(self): # Don't allow the user to remove all of the materials if len(HexrdConfig().materials.keys()) == 1: msg = 'Cannot remove all materials. Add another first.' QMessageBox.warning(self.ui, 'HEXRD', msg) return name = self.current_material() HexrdConfig().remove_material(name) self.material_editor_widget.material = HexrdConfig().active_material self.update_gui_from_config()
def _save_config(self, extension, filter): selected_file, selected_filter = QFileDialog.getSaveFileName( self.ui, 'Save Configuration', HexrdConfig().working_dir, filter) if selected_file: if Path(selected_file).suffix != extension: selected_file += extension HexrdConfig().working_dir = str(Path(selected_file).parent) return HexrdConfig().save_instrument_config(selected_file)
def on_action_open_config_file_triggered(self): selected_file, selected_filter = QFileDialog.getOpenFileName( self.ui, 'Load Configuration', HexrdConfig().working_dir, 'HEXRD files (*.hexrd *.yml)') if selected_file: path = Path(selected_file) HexrdConfig().working_dir = str(path.parent) HexrdConfig().load_instrument_config(str(path)) self.update_config_gui()
def change_directory(self): caption = HexrdConfig().images_dirtion = 'Select directory for images' new_dir = QFileDialog.getExistingDirectory(self.ui, caption, dir=self.parent_dir) if new_dir: HexrdConfig().working_dir = new_dir self.parent_dir = new_dir self.ui.pwd.setText(self.parent_dir) self.ui.pwd.setToolTip(self.parent_dir)
def load_dummy_images(self, initial=False): HexrdConfig().clear_images(initial) detectors = HexrdConfig().detector_names iconfig = HexrdConfig().instrument_config for det in detectors: cols = iconfig['detectors'][det]['pixels']['columns'] rows = iconfig['detectors'][det]['pixels']['rows'] shape = (rows, cols) data = np.ones(shape, dtype=np.uint8) ims = imageseries.open(None, 'array', data=data) HexrdConfig().imageseries_dict[det] = ims