Пример #1
0
    def from_symmetry(cls, s1, s2=C1):
        """The set of unique (mis)orientations of a symmetrical object.

        Parameters
        ----------
        s1, s2 : Symmetry

        """
        s1, s2 = get_proper_groups(s1, s2)
        large_cell_normals = _get_large_cell_normals(s1, s2)
        disjoint = s1 & s2
        # if s1._tuples == s2._tuples:
        #     disjoint = disjoint.laue
        fundamental_sector = disjoint.fundamental_sector()
        fundamental_sector_normals = Rotation.from_neo_euler(
            AxAngle.from_axes_angles(fundamental_sector, np.pi))
        normals = Rotation(
            np.concatenate(
                [large_cell_normals.data, fundamental_sector_normals.data]))
        orientation_region = cls(normals)
        vertices = orientation_region.vertices()
        if vertices.size:
            orientation_region = orientation_region[np.any(np.isclose(
                orientation_region.dot_outer(vertices).data, 0),
                                                           axis=1)]
        return orientation_region
Пример #2
0
def test_antipodal(rotation, improper):
    rotation = Rotation(rotation)
    rotation.improper = improper
    a = rotation.antipodal
    assert np.allclose(a[0].data, rotation.data)
    assert np.allclose(a[1].data, -rotation.data)
    assert np.allclose(a[0].improper, rotation.improper)
    assert np.allclose(a[1].improper, rotation.improper)
Пример #3
0
    def rotate(self, axis=None, angle=0):
        """Convenience function for rotating this vector.

        Shapes of 'axis' and 'angle' must be compatible with shape of this
        vector for broadcasting.

        Parameters
        ----------
        axis : Vector3d or array_like, optional
            The axis of rotation. Defaults to the z-vector.
        angle : array_like, optional
            The angle of rotation, in radians.

        Returns
        -------
        Vector3d
            A new vector with entries rotated.

        Examples
        --------
        >>> from math import pi
        >>> v = Vector3d((0, 1, 0))
        >>> axis = Vector3d((0, 0, 1))
        >>> angles = [0, pi/4, pi/2, 3*pi/4, pi]
        >>> v.rotate(axis=axis, angle=angles)


        """
        from texpy.quaternion.rotation import Rotation
        from texpy.vector.neo_euler import AxAngle
        axis = Vector3d.zvector() if axis is None else axis
        angle = 0 if angle is None else angle
        q = Rotation.from_neo_euler(AxAngle.from_axes_angles(axis, angle))
        return q * self
Пример #4
0
 def get_plot_data(self):
     from texpy.vector import Vector3d
     theta = np.linspace(0, 2 * np.pi + 1e-9, 361)
     rho = np.linspace(0, np.pi, 181)
     theta, rho = np.meshgrid(theta, rho)
     g = Vector3d.from_polar(rho, theta)
     n = Rodrigues.from_rotation(self).norm.data[:, np.newaxis, np.newaxis]
     if n.size == 0:
         return Rotation.from_neo_euler(AxAngle.from_axes_angles(g, np.pi))
     d = (-self.axis).dot_outer(g.unit).data
     x = n * d
     x = 2 * np.arctan(x**-1)
     x[x < 0] = np.pi
     x = np.min(x, axis=0)
     r = Rotation.from_neo_euler(AxAngle.from_axes_angles(g.unit, x))
     return r
Пример #5
0
 def faces(self):
     normals = Rotation(self)
     vertices = self.vertices()
     faces = []
     for n in normals:
         faces.append(vertices[np.isclose(vertices.dot(n).data, 0)])
     faces = [f for f in faces if f.size > 2]
     return faces
Пример #6
0
    def vertices(self):
        """The vertices of the asymmetric domain.

        Returns
        -------
        Rotation

        """
        normal_combinations = list(itertools.combinations(self, 3))
        if len(normal_combinations) < 1:
            return Rotation.empty()
        c1, c2, c3 = zip(*normal_combinations)
        c1, c2, c3 = Rotation.stack(c1).flatten(), Rotation.stack(
            c2).flatten(), Rotation.stack(c3).flatten()
        v = Rotation.triple_cross(c1, c2, c3)
        v = v[~np.any(np.isnan(v.data), axis=-1)]
        v = v[v < self].unique()
        surface = np.any(np.isclose(v.dot_outer(self).data, 0), axis=1)
        return v[surface]
Пример #7
0
def _get_large_cell_normals(s1, s2):
    dp = get_distinguished_points(s1, s2)
    normals = Rodrigues.zero(dp.shape + (2, ))
    planes1 = dp.axis * np.tan(dp.angle.data / 4)
    planes2 = -dp.axis * np.tan(dp.angle.data / 4)**-1
    planes2.data[np.isnan(planes2.data)] = 0
    normals[:, 0] = planes1
    normals[:, 1] = planes2
    normals: Rotation = Rotation.from_neo_euler(normals).flatten().unique(
        antipodal=False)
    if not normals.size:
        return normals
    _, inv = normals.axis.unique(return_inverse=True)
    axes_unique = []
    angles_unique = []
    for i in np.unique(inv):
        n = normals[inv == i]
        axes_unique.append(n.axis.data[0])
        angles_unique.append(n.angle.data.max())
    normals = Rotation.from_neo_euler(
        AxAngle.from_axes_angles(np.array(axes_unique), angles_unique))
    return normals
Пример #8
0
def test_mul_rotation(r1, i1, r2, i2, expected, expected_i):
    r1 = Rotation(r1)
    r1.improper = i1
    r2 = Rotation(r2)
    r2.improper = i2
    r = r1 * r2
    assert isinstance(r, Rotation)
    assert np.allclose(r.data, expected)
    assert np.all(r.improper == expected_i)
Пример #9
0
def loadang(file_string: str):
    """Load ``.ang`` files.

    Parameters
    ----------
    file_string : str
        Path to the ``.ang`` file. This file is assumed to list the Euler
        angles in the Bunge convention in the first three columns.

    Returns
    -------
    Rotation

    """
    from texpy.quaternion.rotation import Rotation
    data = np.loadtxt(file_string)
    euler = data[:, :3]
    rotation = Rotation.from_euler(euler)
    return rotation
Пример #10
0
def loadctf(file_string: str):
    """Load ``.ang`` files.

    Parameters
    ----------
    file_string : str
        Path to the ``.ctf`` file. This file is assumed to list the Euler
        angles in the Bunge convention in the columns 5, 6, and 7.

    Returns
    -------
    Rotation

    """

    from texpy.quaternion.rotation import Rotation
    data = np.loadtxt(file_string, skiprows=17)[:, 5:8]
    euler = np.radians(data)
    rotation = Rotation.from_euler(euler)
    return rotation
Пример #11
0
def test_random_vonmises(shape, reference):
    r = Rotation.random_vonmises(shape, 1., reference)
    assert r.shape == shape
    assert isinstance(r, Rotation)
Пример #12
0
def rotation(request):
    return Rotation(request.param)
Пример #13
0
from math import cos, sin, tan, pi
import numpy as np
import pytest
import itertools

from texpy.quaternion import Quaternion
from texpy.quaternion.rotation import Rotation
from texpy.vector import Vector3d

rotations = [(0.707, 0., 0., 0.707), (0.5, -0.5, -0.5, 0.5), (0., 0., 0., 1.),
             (1., 1., 1., 1.), (
                 (0.5, -0.5, -0.5, 0.5),
                 (0., 0., 0., 1.),
             ),
             Rotation([(2, 4, 6, 8), (-1, -2, -3, -4)]),
             np.array((4, 3, 2, 1))]

quaternions = [(0.881, 0.665, 0.123, 0.517), (0.111, 0.222, 0.333, 0.444),
               (
                   (1, 0, 0.5, 0),
                   (3, 1, -1, -2),
               ),
               [[
                   [0.343, 0.343, 0, -0.333],
                   [-7, -8, -9, -10],
               ], [[0.00001, -0.0001, 0.001, -0.01], [0, 0, 0, 0]]]]

vectors = [(1, 0, 0), (1, 1, 0), (0.7, 0.8, 0.9),
           [
               [1, 1, 1],
               [0.4, 0.5, -0.6],
Пример #14
0
@pytest.fixture(params=axangles[:100])
def axangle(request):
    return AxAngle(request.param.data)


def test_angle(axangle):
    assert np.allclose(axangle.angle.data, axangle.norm.data)


def test_axis(axangle):
    assert axangle.axis.shape == axangle.shape


@pytest.mark.parametrize('axis, angle, expected_axis',
                         [((2, 1, 1), np.pi / 4,
                           (0.816496, 0.408248, 0.408248)),
                          (Vector3d((2, 0, 0)), -2 * np.pi, (-1, 0, 0))])
def test_from_axes_angles(axis, angle, expected_axis):
    ax = AxAngle.from_axes_angles(axis, angle)
    assert np.allclose(ax.axis.data, expected_axis)
    assert np.allclose(ax.angle.data, abs(angle))


@pytest.mark.parametrize('rotation, expected',
                         [(Rotation([1, 0, 0, 0]), [0, 0, 0]),
                          (Rotation([0, 1, 0, 0]), [np.pi, 0, 0])])
def test_from_rotation(rotation, expected):
    axangle = AxAngle.from_rotation(rotation)
    assert np.allclose(axangle.data, expected)
Пример #15
0
import pytest
import numpy as np

from texpy.vector.neo_euler import Rodrigues
from texpy.quaternion.rotation import Rotation


@pytest.mark.parametrize('rotation, expected', [
    (Rotation([1, 0, 0, 0]), [0, 0, 0]),
    (Rotation([0.9239, 0.2209, 0.2209, 0.2209]), [0.2391, 0.2391, 0.2391]),
])
def test_from_rotation(rotation, expected):
    rodrigues = Rodrigues.from_rotation(rotation)
    assert np.allclose(rodrigues.data, expected, atol=1e-4)


@pytest.mark.parametrize('rodrigues, expected', [
    (Rodrigues([0.2391, 0.2391, 0.2391]), np.pi / 4),
])
def test_angle(rodrigues, expected):
    angle = rodrigues.angle
    assert np.allclose(angle.data, expected, atol=1e-3)