Example #1
0
def test_fail_index_dataset_with_template_rot(library):
    signal = create_dataset((3, 2, 4, 1, 2))
    with pytest.raises(ValueError):
        result = iutls.index_dataset_with_template_rotation(
            signal,
            library,
        )
Example #2
0
def test_index_dataset_with_template_rotation(library,sigdim, norim, nort, chu):
    signal = create_dataset(sigdim)
    result = iutls.index_dataset_with_template_rotation(
        signal,
        library,
        frac_keep=0.5,
        delta_r=0.5,
        delta_theta=36,
        max_r=None,
        intensity_transform_function=np.sqrt,
        normalize_images=norim,
        normalize_templates=nort,
        chunks=chu,
    )
Example #3
0
def test_index_dataset_with_template_rotation_gpu(library, sigdim, maxr,
                                                  n_best, frac_keep, norim,
                                                  nort, chu):
    signal = create_dataset(sigdim)
    result, dicto = iutls.index_dataset_with_template_rotation(
        signal,
        library,
        n_best=n_best,
        frac_keep=frac_keep,
        delta_r=0.5,
        delta_theta=36,
        max_r=maxr,
        intensity_transform_function=np.sqrt,
        normalize_images=norim,
        normalize_templates=nort,
        chunks=chu,
        target="gpu",
    )
Example #4
0
def _create_check_diflib(images, calibration_guess, library_phases, lib_gen,
                         max_excitation_error, **kwargs):
    """For use in find_diffraction_calibration via _calibration_iteration.  Creates a new DiffractionLibrary from the inputs and then matches it the images.

    Parameters
    ----------
    images : hyperspy.signals.Signal2D
        Diffration patterns to be iteratively matched to find maximum correlation scores.
    calibration_guess : float
        Inital value for the diffraction calibration in inverse Angstoms per pixel
    library_phases : diffsims.libraries.StructureLibrary
        Dictionary of structures and associated orientations for which
        electron diffraction is to be simulated.
    lib_gen : diffsims.generators.DiffractionLibraryGenerator
        Computes a library of electron diffraction patterns for specified atomic
        structures and orientations.  Used to create the DiffractionLibrary.
    max_excitation_error : float
        Maximum exacitation error.  Default is 0.01.
    kwargs
        Keyword arguments passed to :meth:`index_dataset_with_template_rotation`.
        
    Returns
    -------
    correlations : numpy.ndarray
    """

    half_shape = (images.data.shape[-2] // 2, images.data.shape[-1] // 2)
    reciprocal_r = np.sqrt(half_shape[0]**2 +
                           half_shape[1]**2) * calibration_guess
    diff_lib = lib_gen.get_diffraction_library(
        library_phases,
        calibration=calibration_guess,
        reciprocal_radius=reciprocal_r,
        half_shape=half_shape,
        with_direct_beam=False,
        max_excitation_error=max_excitation_error,
    )

    result, phasedict = index_dataset_with_template_rotation(
        images, diff_lib, **kwargs)
    correlations = result["correlation"][:, :, 0].flatten()
    return correlations
Example #5
0
def test_results_dict_to_crystal_map(test_library_phases_multi, test_lib_gen):
    """Test getting a :class:`orix.crystal_map.CrystalMap` from returns
    from :func:`index_dataset_with_template_rotation`.
    """
    # Map and signal shapes
    nav_shape = (2, 3)
    sig_shape = (80, 80)
    test_set = np.zeros(nav_shape + sig_shape)

    # Diffraction conditions
    diff_lib = test_lib_gen.get_diffraction_library(
        test_library_phases_multi,
        calibration=0.015,
        reciprocal_radius=1.18,
        half_shape=tuple(np.array(sig_shape) // 2),
        with_direct_beam=False,
    )

    # Simulate multi-phase results
    phase_id = np.zeros(nav_shape, dtype=int)
    phase_id[:, [0, 2]] = 1
    phase_names = list(diff_lib.keys())

    # Simulate patterns
    sim_kwargs = dict(size=sig_shape[0], sigma=4)
    for idx in np.ndindex(*nav_shape):
        i = phase_id[idx]
        j = int(idx[1] / 2)
        test_pattern = diff_lib[phase_names[i]]["simulations"][j].\
            get_diffraction_pattern(**sim_kwargs)
        test_set[idx] = test_pattern

    # Perform template matching
    n_best = 3
    results, phase_dict = index_dataset_with_template_rotation(
        Signal2D(test_set),
        diff_lib,
        phases=phase_names,
        n_best=n_best,
    )

    # Extract various results once
    phase_id = results["phase_index"].reshape((-1, n_best))
    ori = np.deg2rad(results["orientation"].reshape((-1, n_best, 3)))

    # Property names in `results`
    prop_names = ["correlation", "mirrored_template", "template_index"]

    # Only get the bast match when multiple phases match best to some
    # patterns
    xmap = results_dict_to_crystal_map(results,
                                       phase_dict,
                                       diffraction_library=diff_lib)
    assert np.allclose(xmap.phase_id, phase_id[:, 0])
    assert xmap.rotations_per_point == 1
    assert xmap.phases.names == phase_names
    assert (xmap.phases.structures[0].lattice.abcABG() ==
            test_library_phases_multi.structures[0].lattice.abcABG())

    # Raise warning when a property is not present as expected
    del results[prop_names[0]]
    with pytest.warns(UserWarning,
                      match=f"Property '{prop_names[0]}' was expected"):
        xmap2 = results_dict_to_crystal_map(results,
                                            phase_dict,
                                            diffraction_library=diff_lib)
    assert list(xmap2.prop.keys()) == prop_names[1:]

    # Raise error when trying to access a best match which isn't
    # available
    with pytest.raises(ValueError, match="`index` cannot be higher than 2"):
        _ = results_dict_to_crystal_map(results, phase_dict, index=3)
    # Get second best match
    i = 1
    xmap3 = results_dict_to_crystal_map(results, phase_dict, index=i)
    assert xmap3.rotations_per_point == 1
    assert np.allclose(xmap3.phase_id, phase_id[:, i])
    assert np.allclose(xmap3.rotations.data,
                       Rotation.from_euler(ori[:, i]).data)
    assert np.allclose(xmap3.prop[prop_names[1]],
                       results[prop_names[1]][:, :, i].flatten())

    # Make map single-phase and get all matches per point
    results["phase_index"][..., 0] = 0
    xmap4 = results_dict_to_crystal_map(results, phase_dict)
    assert np.all(xmap4.phase_id == 0)
    assert xmap4.phases.names[0] == phase_names[0]
    assert xmap4.rotations_per_point == 3

    # Get only best match even though map is single-phase
    i = 0
    xmap5 = results_dict_to_crystal_map(results, phase_dict, index=i)
    assert xmap5.rotations_per_point == 1
    assert np.allclose(xmap5.rotations.data,
                       Rotation.from_euler(ori[:, i]).data)
    assert np.allclose(xmap5.prop[prop_names[1]],
                       results[prop_names[1]][:, :, i].flatten())
Example #6
0
    def correlate(
        self,
        n_largest=5,
        include_phases=None,
        **kwargs,
    ):
        """
        Correlates the library of simulated diffraction patterns with the
        electron diffraction signal.

        Parameters
        ----------
        n_largest : int, optional
            Number of best solutions to return, in order of descending match
        include_phases : list, optional
            Names of phases in the library to do an indexation for. By default this is
            all phases in the library.
        n_keep : int, optional
            Number of templates to do a full matching on in the second matching step
        frac_keep : float, optional
            Fraction (between 0-1) of templates to do a full matching on. When set
            n_keep will be ignored
        delta_r : float, optional
            The sampling interval of the radial coordinate in pixels
        delta_theta : float, optional
            The sampling interval of the azimuthal coordinate in degrees
        max_r : float, optional
            Maximum radius to consider in pixel units. By default it is the
            distance from the center of the image to a corner
        intensity_transform_function : Callable, optional
            Function to apply to both image and template intensities on an
            element by element basis prior to comparison
        find_direct_beam : bool, optional
            Whether to optimize the direct beam, otherwise the center of the image
            is chosen
        direct_beam_positions : 2-tuple of floats or 3D numpy array of shape (scan_x, scan_y, 2), optional
            (x, y) coordinates of the direct beam in pixel units. Overrides other
            settings for finding the direct beam
        normalize_images : bool, optional
            normalize the images to calculate the correlation coefficient
        normalize_templates : bool, optional
            normalize the templates to calculate the correlation coefficient
        parallelize_polar_conversion : bool, optional
            use multiple workers for converting the dataset to polar coordinates. Overhead
            could make this slower on some hardware and for some datasets.
        chunks : string or 4-tuple, optional
            internally the work is done on dask datasets and this parameter determines
            the chunking. If set to None then no re-chunking will happen if the dataset
            was loaded lazily. If set to "auto" then dask attempts to find the optimal
            chunk size. If None, no changes will be made to the chunking.
        parallel_workers: int, optional
            the number of workers to use in parallel. If set to "auto", the number
            will be determined from os.cpu_count()

        Returns
        -------
        result : dict

        Notes
        -----
        Internally, this code is compiled to LLVM machine code, so stack traces are often hard to follow on failure. As such it is
        important to be careful with your parameters selection.
        """
        result = index_dataset_with_template_rotation(self.signal,
                                                      self.library,
                                                      phases=include_phases,
                                                      n_best=n_largest,
                                                      **kwargs)
        return result