def apply_transforms(self): num_dets = len(HexrdConfig().detector_names) trans = [] if self.ui.update_all.isChecked(): idx = self.ui.transform_all_menu.currentIndex() trans = [idx for x in range(num_dets)] else: for combo in self.det_cboxes: trans.append(combo.currentIndex()) ilm = ImageLoadManager() state = HexrdConfig().load_panel_state state['trans'] = trans new_state = { 'trans': trans, 'agg': state.get('agg', 0), } if self.ui.subtract_minimum.isChecked(): new_state['zero-min'] = None state['zero-min'] = None ilm.set_state(new_state) ilm.begin_processing(postprocess=True)
def run_indexer(self): config = create_indexing_config() # Find orientations self.update_progress_text('Running indexer (paintGrid)') ncpus = config.multiprocessing self.completeness = indexer.paintGrid( self.qfib, self.ome_maps, etaRange=np.radians(config.find_orientations.eta.range), omeTol=np.radians(config.find_orientations.omega.tolerance), etaTol=np.radians(config.find_orientations.eta.tolerance), omePeriod=np.radians(config.find_orientations.omega.period), threshold=config.find_orientations.threshold, doMultiProc=ncpus > 1, nCPUs=ncpus) print('paintGrid complete') orientations_cfg = HexrdConfig().indexing_config['find_orientations'] if orientations_cfg.get('_write_scored_orientations'): # Write out the scored orientations results = {} results['scored_orientations'] = { 'test_quaternions': self.qfib, 'score': self.completeness } print(f'Writing scored orientations in {config.working_dir} ...') write_scored_orientations(results, config)
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 run_powder_calibration(): # Set up the tilt calibration mapping rme = HexrdConfig().rotation_matrix_euler() # Set up the instrument iconfig = HexrdConfig().instrument_config instr = instrument.HEDMInstrument(instrument_config=iconfig, tilt_calibration_mapping=rme) flags = HexrdConfig().get_statuses_instrument_format() if len(flags) != len(instr.calibration_flags): msg = 'Length of internal flags does not match instr.calibration_flags' raise Exception(msg) instr.calibration_flags = flags # Plane data and images plane_data = HexrdConfig().active_material.planeData img_dict = HexrdConfig().current_images_dict() # tolerances for patches tth_tol = HexrdConfig().config['calibration']['powder']['tth_tol'] eta_tol = HexrdConfig().config['calibration']['powder']['eta_tol'] pktype = HexrdConfig().config['calibration']['powder']['pk_type'] # powder calibrator pc = PowderCalibrator(instr, plane_data, img_dict, tth_tol=tth_tol, eta_tol=eta_tol, pktype=pktype) # make instrument calibrator ic = InstrumentCalibrator(pc) use_robust_optimization = False ic.run_calibration(use_robust_optimization) # We might need to use this at some point # data_dict = pc._extract_powder_lines() # Add this so the calibration crystal gets written cal_crystal = iconfig.get('calibration_crystal') output_dict = instr.write_config(calibration_dict=cal_crystal) # 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] # Add status values HexrdConfig().add_status(output_dict) # Update the config HexrdConfig().config['instrument'] = output_dict # Set the previous statuses to be the current statuses HexrdConfig().set_statuses_from_instrument_format(flags)
def update_gui_from_config(self, config): blocked = [QSignalBlocker(x) for x in self.all_widgets()] self.ui.npdiv.setValue(config.get('npdiv')) self.ui.refit_pixel_scale.setValue(config.get('refit')[0]) self.ui.refit_ome_step_scale.setValue(config.get('refit')[1]) self.ui.threshold.setValue(config.get('threshold')) tth_max = config.get('tth_max') if isinstance(tth_max, bool): enabled = tth_max instrument = tth_max value = 0.0 else: enabled = True instrument = False value = tth_max self.ui.tth_max_enable.setChecked(enabled) self.ui.tth_max_instrument.setEnabled(enabled) self.ui.tth_max_instrument.setChecked(instrument) self.ui.tth_max_specify.setEnabled(enabled) self.ui.tth_max_specify.setChecked(not instrument) self.ui.tth_max_value.setEnabled(enabled and (not instrument)) self.ui.tth_max_value.setValue(value) tolerances = config.get('tolerance') self.tolerances_model.update_from_config(tolerances) indexing_config = HexrdConfig().indexing_config self.selected_material = indexing_config.get('_selected_material') working_dir = indexing_config.get( 'working_dir', str(Path(HexrdConfig().working_dir).parent)) analysis_name = indexing_config.get( 'analysis_name', Path(HexrdConfig().working_dir).stem) self.spots_path = str(Path(working_dir) / analysis_name) write_spots = indexing_config.get('_write_spots', False) self.ui.write_out_spots.setChecked(write_spots) self.update_num_hkls()
def __init__(self, parent=None): super().__init__(parent) config = HexrdConfig().indexing_config['fit_grains'] if config.get('do_fit') is False: return loader = UiLoader() self.ui = loader.load_file('fit_grains_options_dialog.ui', parent) flags = self.ui.windowFlags() self.ui.setWindowFlags(flags | Qt.Tool) self.setup_material_options() ok_button = self.ui.button_box.button(QDialogButtonBox.Ok) ok_button.setText('Fit Grains') self.tolerances_model = FitGrainsToleranceModel(self.ui) self.update_gui_from_config(config) self.ui.tolerances_view.setModel(self.tolerances_model) # Stretch columns to fill the available horizontal space num_cols = self.tolerances_model.columnCount() for i in range(num_cols): self.ui.tolerances_view.horizontalHeader().setSectionResizeMode( i, QHeaderView.Stretch) # Setup connections self.ui.accepted.connect(self.on_accepted) self.ui.rejected.connect(self.rejected) self.ui.tth_max_enable.toggled.connect(self.on_tth_max_toggled) self.ui.tth_max_specify.toggled.connect(self.on_tth_specify_toggled) self.ui.tolerances_view.selectionModel().selectionChanged.connect( self.on_tolerances_select) self.ui.add_row.clicked.connect(self.on_tolerances_add_row) self.ui.delete_row.clicked.connect(self.on_tolerances_delete_row) self.ui.move_up.clicked.connect(self.on_tolerances_move_up) self.ui.move_down.clicked.connect(self.on_tolerances_move_down) self.ui.material.currentIndexChanged.connect( self.selected_material_changed) self.ui.choose_hkls.pressed.connect(self.choose_hkls) self.ui.set_spots_directory.clicked.connect(self.set_working_dir) HexrdConfig().overlay_config_changed.connect(self.update_num_hkls)
def update_gui(self): blockers = [QSignalBlocker(x) for x in self.widgets] # noqa: F841 indexing_config = HexrdConfig().indexing_config maps_config = indexing_config['find_orientations']['orientation_maps'] file_name = maps_config['file'] if maps_config['file'] else '' self.ui.file_name.setText(file_name) self.threshold = maps_config['threshold'] self.ui.bin_frames.setValue(maps_config['bin_frames']) self.selected_material = indexing_config.get('_selected_material') self.update_method_tab() self.update_num_hkls()
def save_images(self): if self.ui.ignore_agg.isChecked(): ims_dict = HexrdConfig().unagg_images else: ims_dict = HexrdConfig().imageseries_dict dets = HexrdConfig().detector_names if self.ui.single_detector.isChecked(): dets = [self.ui.detectors.currentText()] for det in dets: selected_format = self.ui.format.currentText().lower() filename = f'{self.ui.file_stem.text()}_{det}.{selected_format}' path = f'{self.parent_dir}/{filename}' if selected_format.startswith('hdf5'): selected_format = 'hdf5' elif selected_format.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'] = path worker = AsyncWorker(HexrdConfig().save_imageseries, ims_dict.get(det), det, path, selected_format, **kwargs) self.thread_pool.start(worker) self.progress_dialog.setWindowTitle(f'Saving {filename}') self.progress_dialog.setRange(0, 0) worker.signals.finished.connect(self.progress_dialog.accept) self.progress_dialog.exec_()
def create_fit_grains_results_dialog(fit_grains_results, parent=None): # Build grains table num_grains = len(fit_grains_results) shape = (num_grains, 21) grains_table = np.empty(shape) gw = instrument.GrainDataWriter(array=grains_table) for result in fit_grains_results: gw.dump_grain(*result) gw.close() # Use the material to compute stress from strain indexing_config = HexrdConfig().indexing_config name = indexing_config.get('_selected_material') if name not in HexrdConfig().materials: name = HexrdConfig().active_material_name material = HexrdConfig().material(name) # Create the dialog dialog = FitGrainsResultsDialog(grains_table, material, parent) dialog.ui.resize(1200, 800) return dialog
def update_wppf_plot(self): self.clear_wppf_plot() if not HexrdConfig().display_wppf_plot: return wppf_data = HexrdConfig().wppf_data axis = self.azimuthal_integral_axis line = self.azimuthal_line_artist if any(x is None for x in (wppf_data, axis, line)): return style = HexrdConfig().wppf_plot_style if style.get('marker', 'o') not in Line2D.filled_markers: # Marker is unfilled if 'edgecolors' in style: # Unfilled markers can't have edge colors. # Remove this to avoid a matplotlib warning. style = copy.deepcopy(style) del style['edgecolors'] self.wppf_plot = axis.scatter(*wppf_data, **style)
class LoadPanel(QObject): # Emitted when images are loaded images_loaded = Signal() def __init__(self, parent=None): super(LoadPanel, self).__init__(parent) loader = UiLoader() self.ui = loader.load_file('load_panel.ui', parent) self.ims = HexrdConfig().imageseries_dict self.parent_dir = HexrdConfig().images_dir self.state = HexrdConfig().load_panel_state self.files = [] self.omega_min = [] self.omega_max = [] self.idx = 0 self.ext = '' self.frame_data = None self.progress_dialog = None self.current_progress_step = 0 self.progress_macro_steps = 0 self.update_allowed = False self.setup_gui() self.detectors_changed() self.setup_connections() # Setup GUI def setup_gui(self): self.setup_processing_options() self.ui.all_detectors.setChecked(self.state.get('apply_to_all', False)) self.ui.aggregation.setCurrentIndex(self.state['agg']) self.ui.transform.setCurrentIndex( self.state['trans'][self.ui.detector.currentIndex()]) self.ui.darkMode.setCurrentIndex( self.state['dark'][self.ui.detector.currentIndex()]) self.dark_files = self.state['dark_files'] self.dark_mode_changed() if not self.parent_dir: self.ui.img_directory.setText('No directory set') else: directory = self.parent_dir if Path(directory).is_file(): directory = str(Path(directory).parent) self.ui.img_directory.setText(directory) self.ui.file_options.resizeColumnsToContents() def setup_connections(self): HexrdConfig().detectors_changed.connect(self.config_changed) HexrdConfig().load_panel_state_reset.connect(self.config_changed) self.ui.image_folder.clicked.connect(self.select_folder) self.ui.image_files.clicked.connect(self.select_images) self.ui.selectDark.clicked.connect(self.select_dark_img) self.ui.read.clicked.connect(self.read_data) self.ui.image_stack.clicked.connect(self.load_image_stacks) self.ui.darkMode.currentIndexChanged.connect(self.dark_mode_changed) self.ui.detector.currentIndexChanged.connect(self.switch_detector) self.ui.aggregation.currentIndexChanged.connect(self.agg_changed) self.ui.transform.currentIndexChanged.connect(self.trans_changed) self.ui.all_detectors.toggled.connect(self.apply_to_all_changed) self.ui.file_options.customContextMenuRequested.connect( self.contextMenuEvent) self.ui.file_options.cellChanged.connect(self.omega_data_changed) self.ui.file_options.cellChanged.connect(self.enable_aggregations) self.ui.update_img_data.clicked.connect(self.update_image_data) 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)]) # Handle GUI changes def dark_mode_changed(self): self.state['dark'][self.idx] = self.ui.darkMode.currentIndex() if self.state['dark'][self.idx] == UI_DARK_INDEX_FILE: self.ui.selectDark.setEnabled(True) if self.dark_files[self.idx]: self.ui.dark_file.setText(self.dark_files[self.idx]) else: self.ui.dark_file.setText('(No File Selected)') self.enable_read() else: self.ui.selectDark.setEnabled(False) self.ui.dark_file.setText( '(Using ' + str(self.ui.darkMode.currentText()) + ')') self.enable_read() self.state['dark_files'][self.idx] = None def detectors_changed(self): self.ui.detector.clear() self.dets = HexrdConfig().detector_names self.ui.detector.addItems(HexrdConfig().detector_names) def agg_changed(self): self.state['agg'] = self.ui.aggregation.currentIndex() if self.ui.aggregation.currentIndex() == UI_AGG_INDEX_NONE: HexrdConfig().reset_unagg_imgs() def trans_changed(self): self.state['trans'][self.idx] = self.ui.transform.currentIndex() def dir_changed(self): new_dir = str(Path(self.files[0][0]).parent) HexrdConfig().set_images_dir(new_dir) self.parent_dir = new_dir self.ui.img_directory.setText(str(Path(self.parent_dir).parent)) def config_changed(self): self.setup_gui() self.detectors_changed() self.ui.file_options.setRowCount(0) self.reset_data() self.enable_read() def switch_detector(self): self.idx = self.ui.detector.currentIndex() if not self.ui.all_detectors.isChecked(): self.ui.transform.setCurrentIndex(self.state['trans'][self.idx]) if self.ui.darkMode.isEnabled(): self.ui.darkMode.setCurrentIndex(self.state['dark'][self.idx]) self.dark_mode_changed() self.create_table() def apply_to_all_changed(self, checked): HexrdConfig().load_panel_state['apply_to_all'] = checked if not checked: self.switch_detector() elif self.state['dark'][self.idx] == UI_DARK_INDEX_FILE: self.select_dark_img(self.dark_files[self.idx]) def select_folder(self, new_dir=None): # This expects to define the root image folder. if not new_dir: caption = HexrdConfig().images_dirtion = 'Select directory for images' new_dir = QFileDialog.getExistingDirectory( self.ui, caption, dir=self.parent_dir) # Only update if a new directory is selected if new_dir and new_dir != HexrdConfig().images_dir: self.ui.image_files.setEnabled(True) HexrdConfig().set_images_dir(new_dir) self.parent_dir = new_dir self.dir_changed() def select_dark_img(self, selected_file=False): if not selected_file: # This takes one image to use for dark subtraction. caption = HexrdConfig().images_dirtion = 'Select image file' selected_file, selected_filter = QFileDialog.getOpenFileName( self.ui, caption, dir=self.parent_dir) if selected_file: if self.ui.all_detectors.isChecked(): files = ImageLoadManager().match_files([selected_file]) if files and all(len(f) for f in files): files.sort() for i, f in enumerate(files): self.dark_files[i] = files[i][0] self.state['dark_files'][i] = files[i][0] else: self.dark_files = [selected_file] * self.num_dets self.state['dark_files'] = [selected_file] * self.num_dets msg = ( f'Unable to match files - using the same dark file' f'for each detector.\nIf this is incorrect please ' f'de-select \"Apply Selections to All Detectors\" and ' f'select the dark file manually for each detector.') QMessageBox.warning(self.ui, 'HEXRD', msg) else: self.dark_files[self.idx] = selected_file self.state['dark_files'][self.idx] = selected_file self.dark_mode_changed() self.enable_read() def select_images(self): # This takes one or more images for a single detector. if self.ui.aps_imageseries.isChecked(): files = QDir(self.parent_dir).entryInfoList(QDir.Files) selected_files = [] for file in files: selected_files.append(file.absoluteFilePath()) else: caption = HexrdConfig().images_dirtion = 'Select image file(s)' selected_files, selected_filter = QFileDialog.getOpenFileNames( self.ui, caption, dir=self.parent_dir) if selected_files: self.update_allowed = False self.reset_data() self.load_image_data(selected_files) self.create_table() self.setup_gui() self.enable_read() def reset_data(self): self.empty_frames = 0 self.total_frames = [] self.omega_min = [] self.omega_max = [] self.nsteps = [] self.files = [] self.frame_data = None def clear_from_stack_dialog(self): self.reset_data() self.ui.file_options.setRowCount(0) self.enable_read() def enable_aggregations(self, row, column): if not (column == 1 or column == 2): return enable = True total_frames = np.sum(self.total_frames) / len(self.dets) if total_frames - self.empty_frames < 2: enable = False self.ui.aggregation.setEnabled(enable) for i in [1, 2, 3]: self.ui.darkMode.model().item(i).setEnabled(enable) if not enable: # Update dark mode settings if self.ui.darkMode.currentIndex() != UI_DARK_INDEX_FILE: num_dets = len(HexrdConfig().detector_names) self.state['dark'] = ( [UI_DARK_INDEX_NONE for x in range(num_dets)]) self.ui.darkMode.setCurrentIndex(UI_DARK_INDEX_NONE) # Update aggregation settings self.state['agg'] = UI_AGG_INDEX_NONE self.ui.aggregation.setCurrentIndex(0) 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_omega_data(self, ims): minimum = ims.metadata['omega'][0][0] maximum = ims.metadata['omega'][-1][1] self.omega_min.append(minimum) self.omega_max.append(maximum) def get_yaml_omega_data(self, data): if 'ostart' in data['meta']: self.omega_min.append(data['meta']['ostart']) self.omega_max.append(data['meta']['ostop']) else: if isinstance(data['meta']['omega'], str): words = data['meta']['omega'].split() fname = Path(self.parent_dir, words[-1]) nparray = np.load(fname) else: nparray = data['meta']['omega'] for idx, vals in enumerate(nparray): self.omega_min.append(vals[0]) self.omega_max.append(vals[1]) def find_images(self, fnames): self.files, manual = ImageLoadManager().load_images(fnames) if len(self.files) % len(HexrdConfig().detector_names) != 0: msg = ('Please select at least one file for each detector.') QMessageBox.warning(self.ui, 'HEXRD', msg) self.files = [] return if manual: dialog = LoadImagesDialog(self.files, manual, self.ui.parent()) if not dialog.exec_(): self.reset_data() return detector_names, files = dialog.results() image_files = [img for f in self.files for img in f] # Make sure files are matched to selected detector self.files = [[] for det in HexrdConfig().detector_names] for d, f in zip(detector_names, image_files): pos = HexrdConfig().detector_names.index(d) self.files[pos].append(f) self.dir_changed() if self.files and self.ext in YAML_EXTS: self.get_yml_files() def get_yml_files(self): self.yml_files = [] for det in self.files: files = [] for f in det: with open(f, 'r') as yml_file: data = yaml.safe_load(yml_file)['image-files'] raw_images = data['files'].split() for raw_image in raw_images: path = Path(self.parent_dir, data['directory']) files.extend([str(p) for p in path.glob(raw_image)]) self.yml_files.append(files) def enable_read(self): files = self.yml_files if self.ext in YAML_EXTS else self.files enabled = len(files) > 0 if len(files) and all(len(f) for f in files): if (self.state['dark'][self.idx] == UI_DARK_INDEX_FILE and self.dark_files[self.idx] is None): enabled = False self.ui.read.setEnabled(enabled) # Handle table setup and changes def create_table(self): # Create the table if files have successfully been selected if not len(self.files): return if self.ext in YAML_EXTS: table_files = self.yml_files else: table_files = self.files self.ui.file_options.setRowCount( len(table_files[self.idx])) # Create the rows for row in range(self.ui.file_options.rowCount()): for column in range(self.ui.file_options.columnCount()): item = QTableWidgetItem() item.setTextAlignment(Qt.AlignCenter) self.ui.file_options.setItem(row, column, item) self.ui.file_options.blockSignals(True) # Populate the rows for i in range(self.ui.file_options.rowCount()): curr = table_files[self.idx][i] self.ui.file_options.item(i, 0).setText(Path(curr).name) self.ui.file_options.item(i, 1).setText(str(self.empty_frames)) self.ui.file_options.item(i, 2).setText(str(self.total_frames[i])) self.ui.file_options.item(i, 3).setText(str(self.omega_min[i])) self.ui.file_options.item(i, 4).setText(str(self.omega_max[i])) self.ui.file_options.item(i, 5).setText( str(self.total_frames[i] - self.empty_frames)) # Set tooltips self.ui.file_options.item(i, 0).setToolTip(Path(curr).name) self.ui.file_options.item(i, 3).setToolTip('Start must be set') self.ui.file_options.item(i, 4).setToolTip('Stop must be set') self.ui.file_options.item(i, 5).setToolTip('Number of steps') # Don't allow editing of file name or total frames self.ui.file_options.item(i, 0).setFlags(Qt.ItemIsEnabled) self.ui.file_options.item(i, 2).setFlags(Qt.ItemIsEnabled) self.ui.file_options.item(i, 5).setFlags(Qt.ItemIsEnabled) # If raw data offset can only be changed in YAML file if self.ext in YAML_EXTS: self.ui.file_options.item(i, 1).setFlags(Qt.ItemIsEnabled) self.ui.file_options.blockSignals(False) self.ui.file_options.resizeColumnsToContents() self.ui.file_options.sortByColumn(0, Qt.AscendingOrder) def contextMenuEvent(self, event): # Allow user to delete selected file(s) menu = QMenu(self.ui) remove = menu.addAction('Remove Selected Files') action = menu.exec_(QCursor.pos()) # Re-selects the current row if context menu is called on disabled cell i = self.ui.file_options.indexAt(event) self.ui.file_options.selectRow(i.row()) indices = [] if action == remove: for index in self.ui.file_options.selectedIndexes(): indices.append(QPersistentModelIndex(index)) for idx in indices: self.ui.file_options.removeRow(idx.row()) if self.ui.file_options.rowCount(): for i in range(len(self.files)): self.files[i] = [] for row in range(self.ui.file_options.rowCount()): f = self.ui.file_options.item(row, 0).text() else: self.files = [] self.enable_read() def omega_data_changed(self, row, column): # Update the values for equivalent files when the data is changed self.ui.file_options.blockSignals(True) curr_val = self.ui.file_options.item(row, column).text() total_frames = self.total_frames[row] - self.empty_frames if curr_val != '': if column == 1: self.empty_frames = int(curr_val) for r in range(self.ui.file_options.rowCount()): self.ui.file_options.item(r, column).setText(str(curr_val)) new_total = str(self.total_frames[r] - self.empty_frames) self.nsteps[r] = int(new_total) self.ui.file_options.item(r, 5).setText(new_total) elif column == 3: self.omega_min[row] = float(curr_val) elif column == 4: self.omega_max[row] = float(curr_val) self.ui.update_img_data.setEnabled(self.update_allowed) self.enable_read() self.ui.file_options.blockSignals(False) def confirm_omega_range(self): files = self.yml_files if self.ext in YAML_EXTS else self.files omega_range = abs(max(self.omega_max) - min(self.omega_min)) within_range = omega_range <= MAXIMUM_OMEGA_RANGE if not within_range: msg = ( f'All omegas must be set and the ' f'range must be no greater than 360°.') QMessageBox.warning(self.ui, 'HEXRD', msg) return within_range # Process files def read_data(self): if not self.confirm_omega_range(): return data = { 'omega_min': self.omega_min, 'omega_max': self.omega_max, 'nsteps': self.nsteps, 'empty_frames': self.empty_frames, 'total_frames': self.total_frames, } if self.ui.all_detectors.isChecked(): data['idx'] = self.idx if self.ext in YAML_EXTS: data['yml_files'] = self.yml_files if self.frame_data is not None: data.update(self.frame_data) HexrdConfig().load_panel_state.update(copy.copy(self.state)) ImageLoadManager().read_data(self.files, data, self.parent()) self.update_allowed = True def load_image_stacks(self): if data := ImageStackDialog(self.parent(), self).exec_(): self.files = data['files'] self.omega_min = data['omega_min'] self.omega_max = data['omega_max'] self.nsteps = data['nsteps'] self.empty_frames = data['empty_frames'] self.total_frames = data['total_frames'] self.frame_data = data['frame_data'] self.create_table() self.enable_read() self.update_allowed = False self.ui.update_img_data.setEnabled(self.update_allowed)
def run_line_picked_calibration(line_data): # Set up the tilt calibration mapping rme = HexrdConfig().rotation_matrix_euler() print('Setting up the instrument...') # Set up the instrument iconfig = HexrdConfig().instrument_config_none_euler_convention instr = instrument.HEDMInstrument(instrument_config=iconfig, tilt_calibration_mapping=rme) flags = HexrdConfig().get_statuses_instrument_format() if np.count_nonzero(flags) == 0: msg = 'There are no refinable parameters' raise Exception(msg) if len(flags) != len(instr.calibration_flags): msg = 'Length of internal flags does not match instr.calibration_flags' raise Exception(msg) print('Running optimization...') # Run calibration opt_result = calibrate_instrument_from_picks(instr, line_data, param_flags=flags, xtol=1e-4, ftol=1e-4) if not opt_result.success: print('Optimization failed!') return False print('Optimization succeeded!') # 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] print('Updating the config') # 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) return True
def params(self): conf = HexrdConfig().config['calibration'] return conf.get('wppf', {}).get('params')