コード例 #1
0
def get_beam_directions_grid(crystal_system,
                             resolution,
                             mesh="spherified_cube_edge"):
    """Produces an array of beam directions, within the stereographic
    triangle of the relevant crystal system. The way the array is
    constructed is based on different methods of meshing the sphere
    [Cajaravelli2015]_ and can be specified through the `mesh` argument.

    Parameters
    ----------
    crystal_system : str
        Allowed are: 'cubic','hexagonal','trigonal','tetragonal',
        'orthorhombic','monoclinic','triclinic'
    resolution : float
        An angle in degrees representing the worst-case angular
        distance to a first nearest neighbor grid point.
    mesh : str
        Type of meshing of the sphere that defines how the grid is
        created. Options are: uv_sphere, normalized_cube,
        spherified_cube_corner (default), spherified_cube_edge,
        icosahedral, random.

    Returns
    -------
    rotation_list : list of tuples
    """
    if mesh == "uv_sphere":
        points_in_cartesians = get_uv_sphere_mesh_vertices(resolution)
    elif mesh == "spherified_cube_corner":
        points_in_cartesians = get_cube_mesh_vertices(
            resolution, grid_type="spherified_corner")
    elif mesh == "icosahedral":
        points_in_cartesians = get_icosahedral_mesh_vertices(resolution)

    elif mesh == "normalized_cube" or mesh == "spherified_cube_edge":
        # special case: hexagon is a very small slice and 001 point can
        # be isolated. Hence we increase resolution to ensure minimum angle.
        if crystal_system == "hexagonal":
            resolution = resolution / np.sqrt(2)

        if mesh == "normalized_cube":
            points_in_cartesians = get_cube_mesh_vertices(
                resolution, grid_type="normalized")
        else:
            points_in_cartesians = get_cube_mesh_vertices(
                resolution, grid_type="spherified_edge")
    elif mesh == "random":
        points_in_cartesians = get_random_sphere_vertices(resolution)
    else:
        raise NotImplementedError(
            f"The mesh {mesh} is not recognized. "
            f"Please use: uv_sphere, normalized_cube, "
            f"spherified_cube_edge, "
            f"spherified_cube_corner, icosahedral, random")

    # crop to stereographic triangle which depends on crystal system
    epsilon = -1e-13
    if crystal_system == "triclinic":
        return beam_directions_grid_to_euler(points_in_cartesians)
    if crystal_system == "monoclinic":
        points_in_cartesian = points_in_cartesians[
            np.dot(np.array([0, 0, 1]), points_in_cartesians.T) >= epsilon]
        points_in_cartesian = points_in_cartesians[
            np.dot(np.array([1, 0, 0]), points_in_cartesians.T) >= epsilon]
        return beam_directions_grid_to_euler(points_in_cartesian)

    # for all other systems, determine it from the triangle vertices
    corners = crystal_system_dictionary[crystal_system]
    a, b, c = corners[0], corners[1], corners[2]
    if len(a) == 4:
        a, b, c = uvtw_to_uvw(a), uvtw_to_uvw(b), uvtw_to_uvw(c)

    # eliminates those points that lie outside of the stereographic triangle
    points_in_cartesians = points_in_cartesians[
        np.dot(np.cross(a, b), c) *
        np.dot(np.cross(a, b), points_in_cartesians.T) >= epsilon]
    points_in_cartesians = points_in_cartesians[
        np.dot(np.cross(b, c), a) *
        np.dot(np.cross(b, c), points_in_cartesians.T) >= epsilon]
    points_in_cartesians = points_in_cartesians[
        np.dot(np.cross(c, a), b) *
        np.dot(np.cross(c, a), points_in_cartesians.T) >= epsilon]

    angle_grid = beam_directions_grid_to_euler(points_in_cartesians)
    return angle_grid
コード例 #2
0
def test_uvtw_to_uvw(uvtw, uvw):
    val = uvtw_to_uvw(uvtw)
    np.testing.assert_almost_equal(val, uvw)