Exemple #1
0
    def start_powder_calibration(self):
        if not HexrdConfig().has_images():
            msg = ('No images available for calibration.')
            QMessageBox.warning(self.ui, 'HEXRD', msg)
            return

        d = PowderCalibrationDialog(self.ui)
        if not d.exec_():
            return

        HexrdConfig().emit_update_status_bar('Running powder calibration...')

        # Run the calibration in a background thread
        worker = AsyncWorker(run_powder_calibration)
        self.thread_pool.start(worker)

        # We currently don't have any progress updates, so make the
        # progress bar indeterminate.
        self.progress_dialog.setRange(0, 0)
        self.progress_dialog.setWindowTitle('Calibration Running')

        # Get the results and close the progress dialog when finished
        worker.signals.result.connect(self.finish_powder_calibration)
        worker.signals.finished.connect(self.progress_dialog.accept)
        msg = 'Powder calibration finished!'
        f = lambda: HexrdConfig().emit_update_status_bar(msg)
        worker.signals.finished.connect(f)
        self.progress_dialog.exec_()
Exemple #2
0
    def indexer_finished(self):
        # Compute number of orientations run_cluster() will use
        # to make sure there aren't too many
        config = create_indexing_config()
        min_compl = config.find_orientations.clustering.completeness
        num_orientations = (np.array(self.completeness) > min_compl).sum()

        num_orientations_warning_threshold = 1e6
        if num_orientations > num_orientations_warning_threshold:
            formatted = format_big_int(num_orientations)
            msg = (f'Over {formatted} orientations are staged for '
                   'clustering. This may use up too much memory.\n\n'
                   'Proceed anyways?')

            response = QMessageBox.question(self.parent, 'WARNING', msg)
            if response == QMessageBox.No:
                # Go back to the eta omega maps viewer
                self.accept_progress()
                self.view_ome_maps()
                return

        worker = AsyncWorker(self.run_cluster_functions)
        self.thread_pool.start(worker)

        worker.signals.result.connect(self.start_fit_grains_runner,
                                      Qt.QueuedConnection)
        worker.signals.finished.connect(self.accept_progress)
        worker.signals.error.connect(self.on_async_error)
Exemple #3
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_()
Exemple #4
0
    def fit_grains_options_accepted(self):
        # Setup to run in background
        self.progress_dialog.setWindowTitle('Running Fit Grains')
        self.progress_dialog.setRange(0, 0)  # no numerical updates

        worker = AsyncWorker(self.run_fit_grains)
        self.thread_pool.start(worker)

        worker.signals.result.connect(self.view_fit_grains_results)
        worker.signals.error.connect(self.on_async_error)
        worker.signals.finished.connect(self.accept_progress)
        self.progress_dialog.exec_()
Exemple #5
0
    def fit_grains_options_accepted(self):
        # Create a full indexing config
        config = create_indexing_config()

        # Setup to run in background
        self.progress_dialog.setWindowTitle('Fit Grains')
        self.progress_dialog.setRange(0, 0)  # no numerical updates

        worker = AsyncWorker(self.run_fit_grains, config)
        self.thread_pool.start(worker)

        worker.signals.result.connect(self.view_fit_grains_results)
        worker.signals.finished.connect(self.progress_dialog.accept)
        self.progress_dialog.exec_()
Exemple #6
0
    def run(self, f):
        worker = AsyncWorker(f)
        self.thread_pool.start(worker)

        if self.success_callback:
            worker.signals.result.connect(self.success_callback)

        if self.error_callback:
            worker.signals.error.connect(self.error_callback)
        else:
            worker.signals.error.connect(self.on_async_error)

        worker.signals.finished.connect(self.reset_callbacks)
        worker.signals.finished.connect(self.progress_dialog.accept)
        self.progress_dialog.exec_()
    def begin_processing(self, postprocess=False):
        # Create threads and loading dialog
        thread_pool = QThreadPool(self.parent)
        progress_dialog = ProgressDialog(self.parent)
        progress_dialog.setWindowTitle('Loading Processed Imageseries')
        self.progress_text.connect(progress_dialog.setLabelText)
        self.progress_dialog = progress_dialog

        # Start processing in background
        worker = AsyncWorker(self.process_ims, postprocess)
        thread_pool.start(worker)

        worker.signals.progress.connect(progress_dialog.setValue)
        # On completion load imageseries nd close loading dialog
        worker.signals.result.connect(self.finish_processing_ims)
        worker.signals.finished.connect(progress_dialog.accept)
        progress_dialog.exec_()
Exemple #8
0
    def read_data(self):
        # When this is pressed read in a complete set of data for all detectors.
        # Run the imageseries processing in a background thread and display a
        # loading dialog

        # Create threads and loading dialog
        thread_pool = QThreadPool(self.parent())
        progress_dialog = CalProgressDialog(self.parent())
        progress_dialog.setWindowTitle('Loading Processed Imageseries')

        # Start processing in background
        worker = AsyncWorker(self.process_ims)
        thread_pool.start(worker)

        # On completion load imageseries nd close loading dialog
        worker.signals.result.connect(self.finish_processing_ims)
        worker.signals.finished.connect(progress_dialog.accept)
        progress_dialog.exec_()
Exemple #9
0
    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_()
Exemple #10
0
    def start_line_picked_calibration(self, line_data):
        HexrdConfig().emit_update_status_bar('Running powder calibration...')

        # Run the calibration in a background thread
        worker = AsyncWorker(run_line_picked_calibration, line_data)
        self.thread_pool.start(worker)

        # We currently don't have any progress updates, so make the
        # progress bar indeterminate.
        self.progress_dialog.setRange(0, 0)
        self.progress_dialog.setWindowTitle('Calibration Running')

        # Get the results and close the progress dialog when finished
        worker.signals.result.connect(self.finish_line_picked_calibration)
        worker.signals.finished.connect(self.progress_dialog.accept)
        msg = 'Powder calibration finished!'
        f = lambda: HexrdConfig().emit_update_status_bar(msg)
        worker.signals.finished.connect(f)
        self.progress_dialog.exec_()
Exemple #11
0
    def show_polar(self):
        HexrdConfig().emit_update_status_bar('Loading polar view...')
        if self.mode != ViewType.polar:
            self.clear()
            self.mode = ViewType.polar

        polar_res_config = HexrdConfig().config['image']['polar']
        if self._polar_reset_needed(polar_res_config):
            # Reset the whole image when certain config items change
            self.clear()
            self.mode = ViewType.polar

        self.polar_res_config = polar_res_config.copy()

        # Run the calibration in a background thread
        worker = AsyncWorker(polar_viewer)
        self.thread_pool.start(worker)

        # Get the results and close the progress dialog when finished
        worker.signals.result.connect(self.finish_show_polar)
Exemple #12
0
    def show_cartesian(self):
        HexrdConfig().emit_update_status_bar('Loading Cartesian view...')
        if self.mode != ViewType.cartesian:
            self.clear()
            self.mode = ViewType.cartesian

        # Force a redraw when the pixel size changes.
        if (self.cartesian_res_config !=
                HexrdConfig().config['image']['cartesian']):
            self.cartesian_res_config = (
                HexrdConfig().config['image']['cartesian'].copy())
            self.figure.clear()
            self.axes_images.clear()

        # Run the calibration in a background thread
        worker = AsyncWorker(cartesian_viewer)
        self.thread_pool.start(worker)

        # Get the results and close the progress dialog when finished
        worker.signals.result.connect(self.finish_show_cartesian)
Exemple #13
0
    def orientation_fibers_generated(self):
        # Perform some validation
        qfib_warning_threshold = 5e7
        if self.qfib.shape[1] > qfib_warning_threshold:
            formatted = format_big_int(self.qfib.shape[1])
            msg = (f'Over {formatted} test orientations were '
                   'generated. This may use up too much memory.\n\n'
                   'Proceed anyways?')

            response = QMessageBox.question(self.parent, 'WARNING', msg)
            if response == QMessageBox.No:
                # Go back to the eta omega maps viewer
                self.accept_progress()
                self.view_ome_maps()
                return

        worker = AsyncWorker(self.run_indexer)
        self.thread_pool.start(worker)

        worker.signals.result.connect(self.indexer_finished)
        worker.signals.error.connect(self.on_async_error)
Exemple #14
0
    def ome_maps_viewed(self):
        # The dialog should have automatically updated our internal config
        # Let's go ahead and run the indexing!

        # For now, always use all hkls from eta omega maps
        hkls = list(range(len(self.ome_maps.iHKLList)))
        indexing_config = HexrdConfig().indexing_config
        indexing_config['find_orientations']['seed_search']['hkl_seeds'] = hkls

        # Create a full indexing config
        config = create_indexing_config()

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

        worker = AsyncWorker(self.run_indexer, config)
        self.thread_pool.start(worker)

        worker.signals.result.connect(self.view_fit_grains_options)
        worker.signals.finished.connect(self.progress_dialog.accept)
        self.progress_dialog.exec_()
Exemple #15
0
    def ome_maps_selected(self):
        dialog = self.ome_maps_select_dialog
        if dialog is None:
            return

        if dialog.method_name == 'load':
            self.ome_maps = EtaOmeMaps(dialog.file_name)
            self.ome_maps_select_dialog = None
            self.view_ome_maps()
        else:
            # Create a full indexing config
            config = create_indexing_config()

            # Setup to generate maps in background
            self.progress_dialog.setWindowTitle('Generating Eta Omega Maps')
            self.progress_dialog.setRange(0, 0)  # no numerical updates

            worker = AsyncWorker(self.run_eta_ome_maps, config)
            self.thread_pool.start(worker)

            worker.signals.result.connect(self.view_ome_maps)
            worker.signals.finished.connect(self.progress_dialog.accept)
            self.progress_dialog.exec_()
Exemple #16
0
    def on_action_open_config_dir_triggered(self):
        dialog = QFileDialog(self.ui, 'Load Configuration',
                             HexrdConfig().working_dir,
                             'HEXRD directories (*)')
        dialog.setFileMode(QFileDialog.Directory)

        selected_files = []
        if dialog.exec_():
            selected_files = dialog.selectedFiles()

        if len(selected_files) == 0:
            return
        else:
            selected_file = selected_files[0]

        path = Path(selected_file)

        def _load():
            path = Path(selected_file)
            HexrdConfig().working_dir = str(path.parent)

            # Opening a .hexrd directory, so point to config.yml
            path = path / 'config.yml'

            HexrdConfig().load_instrument_config(str(path))

        # Check we have the config.yml
        if not (path / 'config.yml').exists():
            msg = 'Invalid HEXRD directory, config.yml missing.'
            QMessageBox.critical(self.ui, 'HEXRD', msg)
            return

        # We do this in a worker thread so the UI can refresh.
        worker = AsyncWorker(_load)
        worker.signals.finished.connect(self.update_config_gui)

        self.thread_pool.start(worker)