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, )
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, )
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", )
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
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())
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