Example #1
0
    def on_action_export_polar_plot_triggered(self):
        selected_file, selected_filter = QFileDialog.getSaveFileName(
            self.ui, 'Save Polar Image',
            HexrdConfig().working_dir, 'NPZ files (*.npz)')

        if selected_file:
            return self.ui.image_tab_widget.export_polar_plot(selected_file)
Example #2
0
 def update_config(self):
     style = self.style
     style['marker'] = self.ui.marker.currentText()
     style['s'] = self.ui.marker_size.value()
     style['facecolors'] = self.ui.face_color.text()
     style['edgecolors'] = self.ui.edge_color.text()
     HexrdConfig().wppf_plot_style = copy.deepcopy(style)
Example #3
0
    def __init__(self, parent=None):
        super(MaterialsPanel, self).__init__(parent)

        loader = UiLoader()
        self.ui = loader.load_file('materials_panel.ui', parent)

        m = HexrdConfig().active_material
        self.material_editor_widget = MaterialEditorWidget(m, self.ui)
        self.materials_table = MaterialsTable(self.ui)

        self.ui.material_editor_layout.addWidget(
            self.material_editor_widget.ui)

        self.material_structure_editor = MaterialStructureEditor(self.ui)
        self.ui.material_structure_editor_layout.addWidget(
            self.material_structure_editor.ui)

        # Turn off autocomplete for the QComboBox
        self.ui.materials_combo.setCompleter(None)

        self.add_tool_button_actions()

        self.setup_connections()

        self.update_gui_from_config()
Example #4
0
 def update_position(self, instr, det):
     pos = HexrdConfig().boundary_position(instr, det)
     if pos is not None:
         self.shape.set_xy(pos)
         self.center = self.get_midpoint()
     elif instr == 'PXRDIP':
         self.rotate_shape(angle=90)
Example #5
0
    def preview_spectrum(self):
        had_object = self._wppf_object is not None

        obj = self.wppf_object
        try:
            obj.computespectrum()
            x, y = obj.spectrum_sim.x, obj.spectrum_sim.y

            fig, ax = plt.subplots()
            fig.canvas.manager.set_window_title('HEXRD')
            ax.set_xlabel(r'2$\theta$ (deg)')
            ax.set_ylabel(r'intensity')
            ax.set_title('Computed Spectrum')

            # Match the scaling used...
            ax.set_yscale(HexrdConfig().azimuthal_integral_axis_scale)

            ax.plot(x, y)
            ax.relim()
            ax.autoscale_view()
            ax.axis('auto')
            fig.tight_layout()

            fig.canvas.draw_idle()
            fig.show()
        finally:
            if not had_object:
                self.reset_object()
Example #6
0
 def update_config(self):
     # Set the new config options on the internal config
     indexing_config = HexrdConfig().indexing_config
     maps_config = indexing_config['find_orientations']['orientation_maps']
     maps_config['file'] = self.file_name
     maps_config['threshold'] = self.threshold
     maps_config['bin_frames'] = self.bin_frames
Example #7
0
    def create_masks_list(self):
        self.masks = {}
        polar_data = HexrdConfig().polar_masks_line_data
        raw_data = HexrdConfig().raw_masks_line_data

        for i, (key, val) in enumerate(polar_data.items()):
            if not any(np.array_equal(m, val) for m in self.masks.values()):
                self.masks[key] = ('polar', val)
        for i, (key, val) in enumerate(raw_data.items()):
            if not any(np.array_equal(m, val) for m in self.masks.values()):
                self.masks[key] = val
        if HexrdConfig().threshold_mask_status:
            self.threshold = True
            self.masks['threshold'] = ('threshold',
                                       HexrdConfig().threshold_mask)
        HexrdConfig().visible_masks = list(self.masks.keys())
Example #8
0
 def cart_to_angles(xys, panel, iviewer):
     ang_crds, _ = panel.cart_to_angles(xys, tvec_c=iviewer.instr.tvec)
     ang_crds = np.degrees(ang_crds)
     ang_crds[:, 1] = mapAngle(ang_crds[:, 1],
                               HexrdConfig().polar_res_eta_period,
                               units='degrees')
     return ang_crds
Example #9
0
    def update_gui(self):
        # Updates all of the widgets with their settings from the config
        self.update_hkl_options()
        blockers = [QSignalBlocker(x) for x in self.all_widgets]  # noqa: F841

        def setter(w):
            if isinstance(w, QComboBox):
                return lambda x: w.setCurrentIndex(w.findData(x))

            # Assume it is a spin box of some kind
            return w.setValue

        config = HexrdConfig().indexing_config

        def set_val(w, path):
            cur = config
            for x in path:
                if x not in cur:
                    # If it's not in the config, skip over it
                    return
                cur = cur[x]

            setter(w)(cur)

        for w, path in self.widget_paths.items():
            w = getattr(self.ui, w)
            set_val(w, path)

        # Update the method name
        method = config['find_orientations']['seed_search']['method']
        self.method_name = next(iter(method))
        self.update_method_tab()

        # Also set the color map minimum to the threshold value...
        self.threshold = config['find_orientations']['threshold']
Example #10
0
    def async_worker_error(self, error):
        QMessageBox.critical(self, 'HEXRD', str(error[1]))
        msg = f'{str(self.mode)} view error!'
        HexrdConfig().emit_update_status_bar(msg)

        self.clear_figure()
        self.draw_idle()
Example #11
0
    def update_azimuthal_integral_plot(self):
        if self.mode != ViewType.polar:
            # Nothing to do. Just return.
            return

        axis = self.azimuthal_integral_axis
        line = self.azimuthal_line_artist
        if any([x is None for x in [axis, line]]):
            # Nothing to do. Just return.
            return

        # Get the "tth" vector
        tth = np.degrees(self.iviewer.angular_grid[1][0])

        # Set the new data
        data = (tth, self.compute_azimuthal_integral_sum())
        line.set_data(*data)

        HexrdConfig().last_azimuthal_integral_data = data

        # Update the wppf data if applicable
        self.update_wppf_plot()

        # Rescale the axes for the new data
        axis.relim()
        axis.autoscale_view(scalex=False)
Example #12
0
 def update_masks_list(self):
     if not self.threshold_name and HexrdConfig().threshold_mask_status:
         name = self.create_unique_name('threshold')
         self.masks[name] = HexrdConfig().threshold_mask
         self.visible[name] = HexrdConfig().threshold_mask
         self.threshold_name = name
     else:
         data = HexrdConfig().polar_masks_line_data
         if not data:
             return
         if any(np.array_equal(data[-1], m) for m in self.masks.values()):
             return
         name = self.create_unique_name('mask_0')
         self.masks[name] = data[-1]
         self.visible[name] = data[-1]
     self.setup_table()
Example #13
0
    def load_images(self, detectors, file_names, options=None):
        HexrdConfig().imageseries_dict.clear()
        for name, f in zip(detectors, file_names):
            try:
                if isinstance(f, list):
                    f = f[0]
                ims = self.open_file(f, options)
                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

        # Save the path if it should be remembered
        if self.remember:
            HexrdConfig().hdf5_path = self.path
Example #14
0
    def update_all(self, clear_canvases=False):
        # If there are no images loaded, skip the request
        if not HexrdConfig().has_images():
            return

        prev_blocked = self.calibration_config_widget.block_all_signals()

        # Need to clear focus from current widget if enter is pressed or
        # else all clicks are emit an editingFinished signal and view is
        # constantly re-rendered
        if QApplication.focusWidget() is not None:
            QApplication.focusWidget().clearFocus()

        if clear_canvases:
            for canvas in self.ui.image_tab_widget.image_canvases:
                canvas.clear()

        if self.image_mode == 'cartesian':
            self.ui.image_tab_widget.show_cartesian()
        elif self.image_mode == 'polar':
            self.ui.image_tab_widget.show_polar()
        else:
            self.ui.image_tab_widget.load_images()

        self.calibration_config_widget.unblock_all_signals(prev_blocked)
Example #15
0
    def match_images(self, fnames):
        file_list = []
        dets = []
        for item in os.scandir(self.parent_dir):
            file_name = os.path.splitext(item.name)[0]
            instance = file_name.rsplit('_', 1)[0]
            if instance == file_name:
                continue
            det = file_name.rsplit('_', 1)[1]
            if os.path.isfile(item) and instance in fnames:
                file_list.append(item.path)
                if det and det not in dets:
                    dets.append(det)
                    self.files.append([])
        for f in file_list:
            det = f.rsplit('.', 1)[0].rsplit('_', 1)[1]
            if det in dets:
                i = dets.index(det)
                self.files[i].append(f)
        # Display error if equivalent files are not found for ea. detector
        files_per_det = all(
            len(self.files[0]) == len(elem) for elem in self.files)
        num_det = len(HexrdConfig().get_detector_names())
        if len(self.files) != num_det or not files_per_det:
            msg = (
                'ERROR - There must be the same number of files for each detector.'
            )
            QMessageBox.warning(None, 'HEXRD', msg)
            self.files = []
            return

        self.files = sorted(self.files)[:len(self.files)]
Example #16
0
 def load_config(self):
     selected_file, selected_filter = QFileDialog.getOpenFileName(
         self.ui, 'Load Configuration', HexrdConfig().working_dir,
         'HEXRD files (*.hexrd *.yml)')
     self.config_file = selected_file if selected_file else None
     self.ui.config_file_label.setText(os.path.basename(self.config_file))
     self.ui.config_file_label.setToolTip(self.config_file)
Example #17
0
    def update_config(self):
        # Set the new config options on the internal config
        config = HexrdConfig().config
        detector_config = config['instrument']['detectors'][self.detector]

        buffer_default = {'status': 0}
        buffer = detector_config.setdefault('buffer', buffer_default)
        if self.mode == CONFIG_MODE_BORDER:
            buffer['value'] = [self.x_border, self.y_border]
        else:
            array = np.load(self.file_name)

            # Must match the detector size
            detector_shape = (detector_config['pixels']['rows']['value'],
                              detector_config['pixels']['columns']['value'])

            if array.shape != detector_shape:
                msg = 'The NumPy array shape must match the detector'
                QMessageBox.critical(self.ui, 'HEXRD', msg)
                self.show()
                return False

            buffer['value'] = array

        return True
Example #18
0
    def ome_maps_viewed(self):
        # The dialog should have automatically updated our internal config
        # Let's go ahead and run the indexing!

        # Create a full indexing config
        config = create_indexing_config()

        # Hexrd normally applies filtering immediately after eta omega
        # maps are loaded. We will perform the user-selected filtering now.
        filter_maps_if_requested(self.ome_maps, config)

        # Setup to run indexing in background
        self.progress_dialog.setWindowTitle('Find Orientations')
        self.progress_dialog.setRange(0, 0)  # no numerical updates

        find_orientations = HexrdConfig().indexing_config['find_orientations']
        if find_orientations['use_quaternion_grid']:
            # Load qfib from a numpy file
            self.qfib = np.load(find_orientations['use_quaternion_grid'])
            self.orientation_fibers_generated()
        else:
            worker = AsyncWorker(self.generate_orientation_fibers, config)
            self.thread_pool.start(worker)

            worker.signals.result.connect(self.orientation_fibers_generated)
            worker.signals.error.connect(self.on_async_error)

        self.progress_dialog.exec_()
Example #19
0
    def recursive_add_tree_items(self, cur_config, cur_tree_item):
        if isinstance(cur_config, dict):
            keys = cur_config.keys()
        elif isinstance(cur_config, list):
            keys = range(len(cur_config))
        else:
            # This must be a value. Set it.
            cur_tree_item.set_data(STATUS_COL, cur_config)
            return

        for key in keys:
            if key == 'value':
                data = cur_config[key]
                if (cur_tree_item.data(KEY_COL) == 'tilt'
                        and HexrdConfig().rotation_matrix_euler() is not None):
                    data = [np.degrees(rad).item() for rad in cur_config[key]]
                self.set_value(key, data, cur_tree_item)
                continue
            elif key == 'status':
                tree_item = cur_tree_item
            else:
                tree_item = self.add_tree_item(key, None, REFINABLE,
                                               cur_tree_item)
            if tree_item is not None:
                self.recursive_add_tree_items(cur_config[key], tree_item)
Example #20
0
    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)
Example #21
0
    def setup_table(self, status=True):
        self.ui.masks_table.setRowCount(0)
        for i, key in enumerate(self.masks.keys()):
            # Add label
            self.ui.masks_table.insertRow(i)
            self.ui.masks_table.setItem(i, 0, QTableWidgetItem(key))

            # Add checkbox to toggle visibility
            cb = QCheckBox()
            status = key in HexrdConfig().visible_masks
            cb.setChecked(status)
            cb.setStyleSheet('margin-left:50%; margin-right:50%;')
            cb.toggled.connect(self.toggle_visibility)
            self.ui.masks_table.setCellWidget(i, 1, cb)

            # Add push button to remove mask
            pb = QPushButton('Remove Mask')
            pb.clicked.connect(self.remove_mask)
            self.ui.masks_table.setCellWidget(i, 2, pb)

            # Connect manager to raw image mode tab settings
            # for threshold mask
            mtype, data = self.masks[key]
            if mtype == 'threshold':
                self.setup_threshold_connections(cb, pb)
Example #22
0
 def clustering_needs_min_samples(self):
     # Determine whether we need the min_samples for clustering
     find_orientations = HexrdConfig().indexing_config['find_orientations']
     return all((
         find_orientations['use_quaternion_grid'] is None,
         find_orientations['clustering']['algorithm'] != 'fclusterdata',
     ))
Example #23
0
 def match_files(self, fnames):
     dets = HexrdConfig().detector_names
     # Look for files that match everything except detector name
     # ex: /home/user/images/Ruby_line_ff_000017_ge1.npz becomes
     # /home/user/images/Ruby_line_ff_000017_*.npz
     search = []
     for f in fnames:
         path, fname = os.path.split(f)
         files = [det for det in dets if det in fname]
         if not files:
             search.append('/'.join([path, fname]))
         else:
             for d in dets:
                 next_file = d.join(fname.rsplit(files[0]))
                 search.append('/'.join([path, next_file]))
     files = self.match_selected_files(fnames, search)
     if not self.check_success(files):
         # Look in sibling directories if the matching files were not
         # found in the current directory.
         revised_search = []
         for f in fnames:
             directory = os.path.basename(os.path.dirname(f))
             for d in dets:
                 revised_search.append(d.join(f.split(directory)))
         files = self.match_selected_files(fnames, revised_search)
     return files
Example #24
0
    def finish_show_cartesian(self, iviewer):
        self.iviewer = iviewer
        img = self.iviewer.img

        # It is important to persist the plot so that we don't reset the scale.
        rescale_image = True
        if len(self.axes_images) == 0:
            self.axis = self.figure.add_subplot(111)
            self.axes_images.append(
                self.axis.imshow(img,
                                 cmap=self.cmap,
                                 norm=self.norm,
                                 vmin=None,
                                 vmax=None,
                                 interpolation="none"))
            self.axis.set_xlabel(r'x (mm)')
            self.axis.set_ylabel(r'y (mm)')
        else:
            rescale_image = False
            self.axes_images[0].set_data(img)

        # We must adjust the extent of the image
        if rescale_image:
            self.axes_images[0].set_extent(iviewer.extent)
            self.axis.relim()
            self.axis.autoscale_view()
            self.axis.autoscale(False)
            self.figure.tight_layout()

        self.update_overlays()
        self.draw_detector_borders()

        msg = 'Cartesian view loaded!'
        HexrdConfig().emit_update_status_bar(msg)
Example #25
0
    def results(self):
        table = self.ui.match_detectors_table
        detectors = []
        image_files = []
        for i in range(table.rowCount()):
            try:
                detectors.append(table.cellWidget(i, 0).currentText())
            except Exception:
                detectors.append(table.item(i, 0).text())
            image_files.append(table.item(i, 2).text())
            idx = table.cellWidget(i, 1).currentIndex()
            imgs_per_det = (
                len(self.image_files)/len(HexrdConfig().detector_names))
            HexrdConfig().load_panel_state['trans'][int(i/imgs_per_det)] = idx

        return detectors, image_files
Example #26
0
    def add_template(self):
        self.it = InteractiveTemplate(HexrdConfig().image(self.detector, 0),
                                      self.parent())
        self.it.create_shape(
            module=hexrd_resources,
            file_name=f'{self.instrument}_{self.detector}_bnd.txt',
            det=self.detector)
        if self.instrument == 'PXRDIP':
            self.it.rotate_shape(angle=-90)

        self.display_bounds()
        self.enable_widgets(self.ui.trans,
                            self.ui.rotate,
                            self.ui.button_box,
                            self.ui.complete,
                            enabled=True)
        self.enable_widgets(self.ui.detectors,
                            self.ui.add_template,
                            self.ui.load,
                            enabled=False)
        if self.ui.instruments.currentText() != 'TARDIS':
            self.enable_widgets(self.ui.height_label,
                                self.ui.bb_height,
                                self.ui.bb_width,
                                self.ui.width_label,
                                self.ui.bb_label,
                                enabled=True)
        self.ui.trans.setChecked(True)
Example #27
0
    def on_min_d_spacing_changed(self):
        min_d = self.ui.min_d_spacing.value()
        wavelength = HexrdConfig().beam_wavelength

        w = self.ui.max_tth
        block_signals = w.blockSignals(True)
        try:
            # Bragg's law
            theta = math.degrees(math.asin(wavelength / 2.0 / min_d))
            w.setValue(theta * 2.0)
        finally:
            w.blockSignals(block_signals)

        # Update the config
        HexrdConfig().active_material_tth_max = math.radians(theta * 2.0)
        self.update_table()
Example #28
0
    def finalize(self):
        self.it.cropped_image
        img = self.it.masked_image

        ilm = ImageLoadManager()
        self.cmap.block_updates(True)
        ilm.read_data([[img]], parent=self.ui)
        if self.instrument == 'PXRDIP':
            ilm.set_state({'trans': [UI_TRANS_INDEX_ROTATE_90]})
            ilm.begin_processing(postprocess=True)
            img = HexrdConfig().image(self.detector, 0)
        self.cmap.block_updates(False)

        self.it.update_image(img)
        self.edited_images[self.detector] = {
            'img': img,
            'height': img.shape[0],
            'width': img.shape[1],
            'tilt': self.it.rotation
        }
        self.canvas.axes_images[0].set_extent(
            (0, img.shape[1], img.shape[0], 0))

        self.it.redraw()
        self.clear_boundry()
Example #29
0
    def update_table(self):
        block_list = [self.ui.table, self.ui.table.selectionModel()]
        blockers = [QSignalBlocker(x) for x in block_list]  # noqa: F841

        prev_selected = self.selected_row

        overlays = HexrdConfig().overlays
        self.clear_table()
        self.ui.table.setRowCount(len(overlays))
        for i, overlay in enumerate(overlays):
            w = self.create_materials_combo(overlay['material'])
            self.ui.table.setCellWidget(i, COLUMNS['material'], w)

            w = self.create_type_combo(overlay['type'])
            self.ui.table.setCellWidget(i, COLUMNS['type'], w)

            w = self.create_visibility_checkbox(overlay['visible'])
            self.ui.table.setCellWidget(i, COLUMNS['visible'], w)

        if prev_selected is not None:
            select_row = (prev_selected if prev_selected < len(overlays) else
                          len(overlays) - 1)
            self.select_row(select_row)

        self.ui.table.resizeColumnsToContents()
        # Just in case the selection actually changed...
        self.selection_changed()
Example #30
0
 def setup_ui_connections(self):
     self.ui.button_box.accepted.connect(self.apply_masks)
     self.ui.button_box.rejected.connect(self.cancel)
     self.ui.rejected.connect(self.cancel)
     self.ui.shape.currentIndexChanged.connect(self.select_shape)
     self.ui.undo.clicked.connect(self.undo_selection)
     HexrdConfig().tab_images_changed.connect(self.tabbed_view_changed)