def dp_vector_match_result(): res = np.empty(4, dtype="object") res[0] = OrientationResult(0, euler2mat(*np.deg2rad([90, 0, 0]), 'rzxz'), 0.6, np.array([0.1, 0.10, 0.2]), 0.3, 1.0, 0, 0) res[1] = OrientationResult(0, euler2mat(*np.deg2rad([0, 10, 20]), 'rzxz'), 0.5, np.array([0.1, 0.05, 0.2]), 0.4, 1.0, 0, 0) res[2] = OrientationResult(1, euler2mat(*np.deg2rad([0, 45, 45]), 'rzxz'), 0.8, np.array([0.1, 0.30, 0.2]), 0.1, 1.0, 0, 0) res[3] = OrientationResult(1, euler2mat(*np.deg2rad([0, 0, 90]), 'rzxz'), 0.7, np.array([0.1, 0.05, 0.1]), 0.2, 1.0, 0, 0) return res
def sp_vector_match_result(): # We require (total_error of row_1 > correlation row_2) res = np.empty(2, dtype="object") res[0] = OrientationResult(0, euler2mat(*np.deg2rad([0, 0, 90]), 'rzxz'), 0.5, np.array([0.1, 0.05, 0.2]), 0.1, 1.0, 0, 0) res[1] = OrientationResult(0, euler2mat(*np.deg2rad([0, 0, 90]), 'rzxz'), 0.6, np.array([0.1, 0.10, 0.2]), 0.2, 1.0, 0, 0) return res
def dp_vector_match_result(): res = np.empty(4, dtype="object") res = res.reshape(2,2) res[0,0] = OrientationResult( 0, euler2mat(*np.deg2rad([90, 0, 0]), "rzxz"), 0.6, np.array([0.1, 0.10, 0.2]), 0.3, 1.0, 0, 0, ) res[0,1] = OrientationResult( 0, euler2mat(*np.deg2rad([0, 10, 20]), "rzxz"), 0.5, np.array([0.1, 0.05, 0.2]), 0.4, 1.0, 0, 0, ) res[1,0] = OrientationResult( 1, euler2mat(*np.deg2rad([0, 45, 45]), "rzxz"), 0.8, np.array([0.1, 0.30, 0.2]), 0.1, 1.0, 0, 0, ) res[1,1] = OrientationResult( 1, euler2mat(*np.deg2rad([0, 0, 90]), "rzxz"), 0.7, np.array([0.1, 0.05, 0.1]), 0.2, 1.0, 0, 0, ) return VectorMatchingResults(res)
def _refine_orientation( solution, k_xy, structure_library, accelarating_voltage, camera_length, index_error_tol=0.2, method="leastsq", vary_angles=True, vary_center=False, vary_scale=False, verbose=False, ): """ Refine a single orientation agains the given cartesian vector coordinates. Parameters ---------- solution : OrientationResult Namedtuple containing the starting orientation k_xy : DiffractionVectors DiffractionVectors (x,y pixel format) to be indexed. structure_library : :obj:`diffsims:StructureLibrary` Object Dictionary of structures and associated orientations for which electron diffraction is to be simulated. index_error_tol : float Max allowed error in peak indexation for classifying it as indexed, calculated as :math:`|hkl_calculated - round(hkl_calculated)|`. method : str Minimization algorithm to use, choose from: 'leastsq', 'nelder', 'powell', 'cobyla', 'least-squares'. See `lmfit` documentation (https://lmfit.github.io/lmfit-py/fitting.html) for more information. vary_angles : bool, Free the euler angles (rotation matrix) during the refinement. vary_center : bool Free the center of the diffraction pattern (beam center) during the refinement. vary_scale : bool Free the scale (i.e. pixel size) of the diffraction vectors during refinement. verbose : bool Be more verbose Returns ------- result : OrientationResult Container for the orientation refinement results """ # prepare reciprocal_lattice structure = structure_library.structures[solution.phase_index] lattice_recip = structure.lattice.reciprocal() def objfunc(params, k_xy, lattice_recip, wavelength, camera_length): cx = params["center_x"].value cy = params["center_y"].value ai = params["ai"].value aj = params["aj"].value ak = params["ak"].value scale = params["scale"].value rotmat = euler2mat(ai, aj, ak) k_xy = k_xy + np.array((cx, cy)) * scale cart = detector_to_fourier(k_xy, wavelength, camera_length) intermediate = cart.dot(rotmat.T) # Must use the transpose here hklss = lattice_recip.fractional(intermediate) * scale rhklss = np.rint(hklss) ehklss = np.abs(hklss - rhklss) return ehklss ai, aj, ak = mat2euler(solution.rotation_matrix) params = lmfit.Parameters() params.add("center_x", value=solution.center_x, vary=vary_center) params.add("center_y", value=solution.center_y, vary=vary_center) params.add("ai", value=ai, vary=vary_angles) params.add("aj", value=aj, vary=vary_angles) params.add("ak", value=ak, vary=vary_angles) params.add("scale", value=solution.scale, vary=vary_scale, min=0.8, max=1.2) wavelength = get_electron_wavelength(accelarating_voltage) camera_length = camera_length * 1e10 args = k_xy, lattice_recip, wavelength, camera_length res = lmfit.minimize(objfunc, params, args=args, method=method) if verbose: # pragma: no cover lmfit.report_fit(res) p = res.params ai, aj, ak = p["ai"].value, p["aj"].value, p["ak"].value scale = p["scale"].value center_x = params["center_x"].value center_y = params["center_y"].value rotation_matrix = euler2mat(ai, aj, ak) k_xy = k_xy + np.array((center_x, center_y)) * scale cart = detector_to_fourier(k_xy, wavelength=wavelength, camera_length=camera_length) intermediate = cart.dot(rotation_matrix.T) # Must use the transpose here hklss = lattice_recip.fractional(intermediate) rhklss = np.rint(hklss) error_hkls = res.residual.reshape(-1, 3) error_mean = np.mean(error_hkls) valid_peak_mask = np.max(error_hkls, axis=-1) < index_error_tol valid_peak_count = np.count_nonzero(valid_peak_mask, axis=-1) num_peaks = len(k_xy) match_rate = (valid_peak_count * (1 / num_peaks)) if num_peaks else 0 orientation = OrientationResult( phase_index=solution.phase_index, rotation_matrix=rotation_matrix, match_rate=match_rate, error_hkls=error_hkls, total_error=error_mean, scale=scale, center_x=center_x, center_y=center_y, ) res = np.empty(2, dtype=np.object) res[0] = orientation res[1] = rhklss return res