コード例 #1
0
    def test_project_vector3d(self):
        """Works for Vector3d objects with single and multiple vectors"""

        vector_one = Vector3d((0.578, 0.578, 0.578))
        output_a = LambertProjection.project(vector_one)
        expected_a = np.array((0.81417, 0.81417))

        assert (output_a[..., 0, 0]) == pytest.approx(expected_a[0], abs=1e-3)
        assert output_a[..., 0, 1] == pytest.approx(expected_a[1], abs=1e-3)

        vector_two = Vector3d(
            np.array(
                [[0.578, 0.578, 0.578], [0, 0.707, 0.707], [0.707, 0, 0.707]]
            )
        )
        output_b = LambertProjection.project(vector_two)

        expected_x = np.array((0.81417, 0, 0.678))
        expected_y = np.array((0.81417, 0.678, 0))

        assert output_b[..., 0, 0] == pytest.approx(expected_x[0], abs=1e-3)
        assert output_b[..., 0, 1] == pytest.approx(expected_y[0], abs=1e-3)
        assert output_b[..., 1, 0] == pytest.approx(expected_x[1], abs=1e-3)
        assert output_b[..., 1, 1] == pytest.approx(expected_y[1], abs=1e-3)
        assert output_b[..., 2, 0] == pytest.approx(expected_x[2], abs=1e-3)
        assert output_b[..., 2, 1] == pytest.approx(expected_y[2], abs=1e-3)
コード例 #2
0
ファイル: test_orientation.py プロジェクト: onatlandsmyr/orix
def test_orientation_persistence(symmetry, vector):
    v = symmetry.outer(vector).flatten()
    o = Orientation.random()
    oc = o.set_symmetry(symmetry)
    v1 = o * v
    v1 = Vector3d(v1.data.round(4))
    v2 = oc * v
    v2 = Vector3d(v2.data.round(4))
    assert v1._tuples == v2._tuples
コード例 #3
0
def get_equivalent_hkl(hkl,
                       operations,
                       unique=False,
                       return_multiplicity=False):
    """Return symmetrically equivalent Miller indices.

    Parameters
    ----------
    hkl : orix.vector.Vector3d, np.ndarray, list or tuple of int
        Miller indices.
    operations : orix.quaternion.symmetry.Symmetry
        Point group describing allowed symmetry operations.
    unique : bool, optional
        Whether to return only unique Miller indices. Default is False.
    return_multiplicity : bool, optional
        Whether to return the multiplicity of the input indices. Default
        is False.

    Returns
    -------
    new_hkl : orix.vector.Vector3d
        The symmetrically equivalent Miller indices.
    multiplicity : np.ndarray
        Number of symmetrically equivalent indices. Only returned if
        `return_multiplicity` is True.
    """
    new_hkl = operations.outer(Vector3d(hkl))
    new_hkl = new_hkl.flatten().reshape(*new_hkl.shape[::-1])

    multiplicity = None
    if unique:
        n_families = new_hkl.shape[0]
        multiplicity = np.zeros(n_families, dtype=int)
        temp_hkl = new_hkl[0].unique().data
        multiplicity[0] = temp_hkl.shape[0]
        if n_families > 1:
            for i, hkl in enumerate(new_hkl[1:]):
                temp_hkl2 = hkl.unique()
                multiplicity[i + 1] = temp_hkl2.size
                temp_hkl = np.append(temp_hkl, temp_hkl2.data, axis=0)
        new_hkl = Vector3d(temp_hkl[:multiplicity.sum()])

    # Remove 1-dimensions
    new_hkl = new_hkl.squeeze()

    if unique and return_multiplicity:
        return new_hkl, multiplicity
    else:
        return new_hkl
コード例 #4
0
ファイル: features.py プロジェクト: onatlandsmyr/kikuchipy
    def __init__(
        self,
        phase: Phase,
        uvw: Union[Vector3d, np.ndarray, list, tuple],
        uvw_detector: Union[Vector3d, np.ndarray, list, tuple],
        in_pattern: Union[np.ndarray, list, tuple],
        gnomonic_radius: Union[float, np.ndarray] = 10,
    ):
        """Positions of zone axes on the detector.

        Parameters
        ----------
        phase
            A phase container with a crystal structure and a space and
            point group describing the allowed symmetry operations.
        uvw
            Miller indices.
        uvw_detector
            Zone axes coordinates on the detector.
        in_pattern
            Boolean array of shape (n, n_hkl) indicating whether an hkl
            is visible in a pattern.
        gnomonic_radius
            Only plane trace coordinates of bands with Hesse normal
            form distances below this radius is returned when called
            for.
        """
        super().__init__(phase=phase, hkl=uvw)
        self._uvw_detector = Vector3d(uvw_detector)
        self._in_pattern = np.asarray(in_pattern)
        self.gnomonic_radius = gnomonic_radius
コード例 #5
0
ファイル: features.py プロジェクト: kvmani/kikuchipy
    def __init__(
        self,
        phase: Phase,
        hkl: Union[Vector3d, np.ndarray],
        hkl_detector: Union[Vector3d, np.ndarray],
        in_pattern: np.ndarray,
        gnomonic_radius: Union[float, np.ndarray] = 10,
    ):
        """Center positions of Kikuchi bands on the detector for n
        simulated patterns.

        Parameters
        ----------
        phase
            A phase container with a crystal structure and a space and
            point group describing the allowed symmetry operations.
        hkl
            All Miller indices present in any of the n patterns.
        hkl_detector
            Detector coordinates for all Miller indices per pattern, in
            the shape navigation_shape + (n_hkl, 3).
        in_pattern
            Boolean array of shape navigation_shape + (n_hkl,)
            indicating whether an hkl is visible in a pattern.
        gnomonic_radius
            Only plane trace coordinates of bands with Hesse normal
            form distances below this radius is returned when called
            for.
        """
        super().__init__(phase=phase, hkl=hkl)
        self._hkl_detector = Vector3d(hkl_detector)
        self._in_pattern = np.atleast_2d(in_pattern)
        self.gnomonic_radius = gnomonic_radius
コード例 #6
0
ファイル: symmetry.py プロジェクト: shogas/orix
    def fundamental_sector(self):
        from orix.vector.neo_euler import AxAngle
        from orix.vector.spherical_region import SphericalRegion
        symmetry = self.antipodal
        symmetry = symmetry[symmetry.angle > 0]
        axes, order = symmetry.get_highest_order_axis()
        if order > 6:
            return Vector3d.empty()
        axis = Vector3d.zvector().get_nearest(axes, inclusive=True)
        r = Rotation.from_neo_euler(
            AxAngle.from_axes_angles(axis, 2 * np.pi / order))

        diads = symmetry.diads
        nearest_diad = axis.get_nearest(diads)
        if nearest_diad.size == 0:
            nearest_diad = axis.perpendicular

        n1 = axis.cross(nearest_diad).unit
        n2 = -(r * n1)
        next_diad = r * nearest_diad
        n = Vector3d.stack((n1, n2)).flatten()
        sr = SphericalRegion(n.unique())
        inside = symmetry[symmetry.axis < sr]
        if inside.size == 0:
            return sr
        axes, order = inside.get_highest_order_axis()
        axis = axis.get_nearest(axes)
        r = Rotation.from_neo_euler(
            AxAngle.from_axes_angles(axis, 2 * np.pi / order))
        nearest_diad = next_diad
        n1 = axis.cross(nearest_diad).unit
        n2 = -(r * n1)
        n = Vector3d(np.concatenate((n.data, n1.data, n2.data)))
        sr = SphericalRegion(n.unique())
        return sr
コード例 #7
0
    def iproject(xy: np.ndarray) -> Vector3d:
        """Convert (n, 2) array from Lambert to Cartesian coordinates."""
        X = xy[..., 0]
        Y = xy[..., 1]

        # Arrays used in setting x and y
        true_term = Y * np.pi / (4 * X)
        false_term = X * np.pi / (4 * Y)
        abs_yx = abs(Y) <= abs(X)
        c_x = _eq_c(X)
        c_y = _eq_c(Y)

        cart = np.zeros(X.shape + (3, ), dtype=X.dtype)

        # Equations 8a and 8b from Callahan and De Graef (2013)
        cart[..., 0] = np.where(abs_yx, c_x * np.cos(true_term),
                                c_y * np.sin(false_term))
        cart[..., 1] = np.where(abs_yx, c_x * np.sin(true_term),
                                c_y * np.cos(false_term))
        cart[..., 2] = np.where(
            abs_yx,
            1 - (2 * (X**2)) / np.pi,
            1 - (2 * (Y**2)) / np.pi,
        )

        return Vector3d(cart)
コード例 #8
0
def _get_direction_cosines(detector: EBSDDetector) -> Vector3d:
    """Get the direction cosines between the detector and sample as done
    in EMsoft and :cite:`callahan2013dynamical`.

    Parameters
    ----------
    detector : EBSDDetector
        EBSDDetector object with a certain detector geometry and one
        projection center.

    Returns
    -------
    Vector3d
        Direction cosines for each detector pixel.
    """
    pc = detector.pc_emsoft()
    xpc = pc[..., 0]
    ypc = pc[..., 1]
    L = pc[..., 2]

    # Detector coordinates in microns
    det_x = (
        -((-xpc - (1.0 - detector.ncols) * 0.5) - np.arange(0, detector.ncols))
        * detector.px_size
    )
    det_y = (
        (ypc - (1.0 - detector.nrows) * 0.5) - np.arange(0, detector.nrows)
    ) * detector.px_size

    # Auxilliary angle to rotate between reference frames
    theta_c = np.radians(detector.tilt)
    sigma = np.radians(detector.sample_tilt)

    alpha = (np.pi / 2) - sigma + theta_c
    ca = np.cos(alpha)
    sa = np.sin(alpha)

    # TODO: Enable detector azimuthal angle
    omega = np.radians(0)  # angle between normal of sample and detector
    cw = np.cos(omega)
    sw = np.sin(omega)

    r_g_array = np.zeros((detector.nrows, detector.ncols, 3))

    Ls = -sw * det_x + L * cw
    Lc = cw * det_x + L * sw

    i, j = np.meshgrid(
        np.arange(detector.nrows - 1, -1, -1),
        np.arange(detector.ncols),
        indexing="ij",
    )

    r_g_array[..., 0] = det_y[i] * ca + sa * Ls[j]
    r_g_array[..., 1] = Lc[j]
    r_g_array[..., 2] = -sa * det_y[i] + ca * Ls[j]
    r_g = Vector3d(r_g_array)

    return r_g.unit
コード例 #9
0
ファイル: symmetry.py プロジェクト: bceh/orix
 def get_axis_orders(self):
     s = self[self.angle > 0]
     if s.size == 0:
         return {}
     return {
         Vector3d(a): b + 1
         for a, b in zip(*np.unique(s.axis.data, axis=0, return_counts=True))
     }
コード例 #10
0
 def axis(self):
     """Vector3d : the axis of rotation."""
     axis = Vector3d(
         np.stack((self.b.data, self.c.data, self.d.data), axis=-1))
     axis[self.a.data < -1e-6] = -axis[self.a.data < -1e-6]
     axis[axis.norm.data == 0] = Vector3d.zvector() * np.sign(
         self.a[axis.norm.data == 0].data)
     axis.data = axis.data / axis.norm.data[..., np.newaxis]
     return axis
コード例 #11
0
ファイル: test_vector3d.py プロジェクト: haal9751/orix
    def test_get_circle(self):
        v = Vector3d([0, 0, 1])
        oa = 0.5 * np.pi
        c = v.get_circle(opening_angle=oa, steps=101)

        assert c.size == 101
        assert np.allclose(c.z.data, 0)
        assert np.allclose(v.angle_with(c).data, oa)
        assert np.allclose(c.mean().data, [0, 0, 0], atol=1e-2)
        assert np.allclose(v.cross(c[0, 0]).data, [1, 0, 0])
コード例 #12
0
class TestSphericalCoordinates:
    @pytest.mark.parametrize(
        "vector, theta_desired, phi_desired, r_desired",
        [
            (Vector3d((0.5, 0.5, 0.707107)), np.pi / 4, np.pi / 4, 1),
            (Vector3d(
                (-0.75, -0.433013, -0.5)), 2 * np.pi / 3, 7 * np.pi / 6, 1),
        ],
    )
    def test_to_polar(self, vector, theta_desired, phi_desired, r_desired):
        theta, phi, r = vector.to_polar()
        assert np.allclose(theta.data, theta_desired)
        assert np.allclose(phi.data, phi_desired)
        assert np.allclose(r.data, r_desired)

    def test_polar_loop(self, vector):
        theta, phi, r = vector.to_polar()
        vector2 = Vector3d.from_polar(theta=theta.data, phi=phi.data, r=r.data)
        assert np.allclose(vector.data, vector2.data)
コード例 #13
0
ファイル: test_vector3d.py プロジェクト: haal9751/orix
class TestSphericalCoordinates:
    @pytest.mark.parametrize(
        "v, polar_desired, azimuth_desired, radial_desired",
        [
            (Vector3d((0.5, 0.5, 0.707107)), np.pi / 4, np.pi / 4, 1),
            (Vector3d(
                (-0.75, -0.433013, -0.5)), 2 * np.pi / 3, 7 * np.pi / 6, 1),
        ],
    )
    def test_to_polar(self, v, polar_desired, azimuth_desired, radial_desired):
        azimuth, polar, radial = v.to_polar()
        assert np.allclose(polar.data, polar_desired)
        assert np.allclose(azimuth.data, azimuth_desired)
        assert np.allclose(radial.data, radial_desired)

    def test_polar_loop(self, vector):
        azimuth, polar, radial = vector.to_polar()
        vector2 = Vector3d.from_polar(azimuth=azimuth.data,
                                      polar=polar.data,
                                      radial=radial.data)
        assert np.allclose(vector.data, vector2.data)
コード例 #14
0
 def test_iproject(self):
     """Conversion from Lambert to Cartesian coordinates works"""
     vec = np.array((0.81417, 0.81417))
     expected = Vector3d((0.5770240896680434, 0.5770240896680434,
                          0.5780020760218183))  # Vector3d(1,)
     output = LambertProjection.iproject(vec)  # Vector3d(1,1)
     assert output[0].x.data[0] == pytest.approx(expected.x.data[0],
                                                 rel=1e-3)
     assert output[0].y.data[0] == pytest.approx(expected.y.data[0],
                                                 rel=1e-3)
     assert output[0].z.data[0] == pytest.approx(expected.z.data[0],
                                                 rel=1e-3)
コード例 #15
0
    def test_vector2xy_vector(self):
        """Works for Vector3d objects with single and multiple vectors"""

        vector_one = Vector3d((0.578, 0.578, 0.578))
        output_a = LambertProjection.vector2xy(vector_one)
        expected_a = np.array((0.81417, 0.81417))

        assert np.allclose(output_a[..., 0, 0], expected_a[0], atol=1e-3)
        assert np.allclose(output_a[..., 0, 1], expected_a[1], atol=1e-3)

        vector_two = Vector3d([[0.578, 0.578, 0.578], [0, 0.707, 0.707],
                               [0.707, 0, 0.707]])
        output_b = LambertProjection.vector2xy(vector_two)

        expected_x = np.array((0.81417, 0, 0.678))
        expected_y = np.array((0.81417, 0.678, 0))

        assert np.allclose(output_b[..., 0, 0], expected_x[0], atol=1e-3)
        assert np.allclose(output_b[..., 0, 1], expected_y[0], atol=1e-3)
        assert np.allclose(output_b[..., 1, 0], expected_x[1], atol=1e-3)
        assert np.allclose(output_b[..., 1, 1], expected_y[1], atol=1e-3)
        assert np.allclose(output_b[..., 2, 0], expected_x[2], atol=1e-3)
        assert np.allclose(output_b[..., 2, 1], expected_y[2], atol=1e-3)
コード例 #16
0
 def test_shape_respect(self):
     """Check that LambertProjection.project() respects navigation axes"""
     sx = 60
     a = np.arange(1, sx**2 + 1).reshape((sx, sx))
     v = Vector3d(np.dstack([a, a, a]))
     assert v.shape == (sx, sx)
     assert v.data.shape == (sx, sx, 3)
     # Forward
     xy_lambert = LambertProjection.project(v)
     assert xy_lambert.shape == (sx, sx, 2)
     # and back
     xyz_frm_lambert = LambertProjection.iproject(xy_lambert)
     assert xyz_frm_lambert.shape == v.shape
     assert xyz_frm_lambert.data.shape == v.data.shape
コード例 #17
0
    def __init__(self, phase, hkl):
        """A container for Miller indices, structure factors and related
        parameters for crystal planes (reciprocal lattice points,
        reflectors, g, etc.).

        Parameters
        ----------
        phase : orix.crystal_map.phase_list.Phase
            A phase container with a crystal structure and a space and
            point group describing the allowed symmetry operations.
        hkl : orix.vector.Vector3d, np.ndarray, list, or tuple
            Miller indices.
        """
        self.phase = phase
        self._raise_if_no_point_group()
        self._hkl = Vector3d(hkl)
        self._structure_factor = [None] * self.size
        self._theta = [None] * self.size
コード例 #18
0
ファイル: neo_euler.py プロジェクト: shogas/orix
    def from_axes_angles(cls, axes, angles):
        """Create new AxAngle object explicitly from the given axes and angles.

        Parameters
        ----------
        axes : Vector3d or array_like
            The axis of rotation.
        angles : array_like
            The angle of rotation, in radians.

        Returns
        -------
        AxAngle

        """
        axes = Vector3d(axes).unit
        angles = np.array(angles)
        axangle_data = angles[..., np.newaxis] * axes.data
        return cls(axangle_data)
コード例 #19
0
    def test_project(self):
        """Projecting cartesian coordinates to Gnomonic coordinates
        yields expected result.
        """
        v = np.array([
            [0.5901, 0.8439, 0.4139],
            [0.4994, 0.744, 0.6386],
            [0.8895, 0.7788, 0.5597],
            [0.6673, 0.8619, 0.6433],
            [0.7605, 0.0647, 0.9849],
            [0.5852, 0.3946, 0.5447],
            [0.4647, 0.7181, 0.6571],
            [0.8806, 0.5106, 0.6244],
            [0.0816, 0.4489, 0.0296],
            [0.7585, 0.1885, 0.2678],
        ])
        xy = GnomonicProjection.vector2xy(v)

        # Desired project result?
        assert np.allclose(
            xy,
            np.array([
                [1.42, 2.03],
                [0.78, 1.16],
                [1.58, 1.39],
                [1.03, 1.33],
                [0.77, 0.06],
                [1.07, 0.72],
                [0.70, 1.09],
                [1.41, 0.81],
                [2.75, 15.14],
                [2.83, 0.70],
            ]),
            atol=1e-1,
        )

        # Same result passing Vector3d
        assert np.allclose(xy, GnomonicProjection.vector2xy(Vector3d(v)))
コード例 #20
0
def test_spherical_projection():
    """Compared against tests in orix."""
    n = 10
    v_arr = np.random.random_sample(n * 3).reshape((n, 3))
    v = Vector3d(v_arr)

    # Vector3d
    polar = SphericalProjection.project(v_arr)
    assert np.allclose(polar[..., 0], v.theta.data)
    assert np.allclose(polar[..., 1], v.phi.data)
    assert np.allclose(polar[..., 2], v.r.data)
    assert np.allclose(get_theta(v), v.theta.data)
    assert np.allclose(get_phi(v), v.phi.data)
    assert np.allclose(get_r(v), v.r.data)

    # NumPy array
    polar2 = SphericalProjection.project(v)
    assert np.allclose(polar2[..., 0], v.theta.data)
    assert np.allclose(polar2[..., 1], v.phi.data)
    assert np.allclose(polar2[..., 2], v.r.data)
    assert np.allclose(get_theta(v_arr), v.theta.data)
    assert np.allclose(get_phi(v_arr), v.phi.data)
    assert np.allclose(get_r(v_arr), v.r.data)
コード例 #21
0
def test_spherical_projection():
    """Compared against tests in orix."""
    n = 10
    v_arr = np.random.random_sample(n * 3).reshape((n, 3))
    v = Vector3d(v_arr)

    # Vector3d
    polar = SphericalProjection.vector2xy(v_arr)
    assert np.allclose(polar[..., 0], v.polar.data)
    assert np.allclose(polar[..., 1], v.azimuth.data)
    assert np.allclose(polar[..., 2], v.radial.data)
    assert np.allclose(get_polar(v), v.polar.data)
    assert np.allclose(get_azimuth(v), v.azimuth.data)
    assert np.allclose(get_radial(v), v.radial.data)

    # NumPy array
    polar2 = SphericalProjection.vector2xy(v)
    assert np.allclose(polar2[..., 0], v.polar.data)
    assert np.allclose(polar2[..., 1], v.azimuth.data)
    assert np.allclose(polar2[..., 2], v.radial.data)
    assert np.allclose(get_polar(v_arr), v.polar.data)
    assert np.allclose(get_azimuth(v_arr), v.azimuth.data)
    assert np.allclose(get_radial(v_arr), v.radial.data)
コード例 #22
0
ファイル: stereographic.py プロジェクト: haal9751/orix
    def xy2vector(self, x, y):
        r"""Return 3D unit vectors from stereographic coordinates
        (X, Y).

        Parameters
        ----------
        x : float or numpy.ndarray
        y : float or numpy.ndarray

        Returns
        -------
        Vector3d
            Unit vectors corresponding to the stereographic coordinates.
            Whether the upper or lower hemisphere points are returned is
            controlled by `pole` (-1 = upper, 1 = lower).

        Notes
        -----
        The 3D unit vectors :math:`(x, y, z)` are calculated from the
        stereographic coordinates :math:`(X, Y)` as

        .. math::
            (x, y, z) = \left(
                \frac{2x}{1 + x^2 + y^2},
                \frac{2y}{1 + x^2 + y^2},
                \frac{-p(1 - x^2 - y^2)}{1 + x^2 + y^2}
            \right),

        where :math:`p` is either 1 (north pole as projection point) or
        -1 (south pole as projection point).
        """
        denom = 1 + x**2 + y**2
        vx = 2 * x / denom
        vy = 2 * y / denom
        vz = -self.pole * (1 - x**2 - y**2) / denom
        return Vector3d(np.column_stack([vx, vy, vz]))
コード例 #23
0
 def hkl(self):
     """Return :class:`~orix.vector.Vector3d` of Miller indices."""
     return Vector3d(self._hkl.data.astype(int))
コード例 #24
0
def test_mean_xyz():
    x = Vector3d.xvector()
    y = Vector3d.yvector()
    z = Vector3d.zvector()
    t = Vector3d([3 * x.data, 3 * y.data, 3 * z.data])
    np.allclose(t.mean().data, 1)
コード例 #25
0
def test_rotate(vector, rotation, expected):
    r = Vector3d(vector).rotate(Vector3d.zvector(), rotation)
    assert isinstance(r, Vector3d)
    assert np.allclose(r.data, expected)
コード例 #26
0
ファイル: neo_euler.py プロジェクト: shogas/orix
 def axis(self):
     """Vector3d : the axis of rotation."""
     return Vector3d(self.unit)
コード例 #27
0
def test_zero_perpendicular():
    t = Vector3d(np.asarray([0, 0, 0]))
    tperp = t.perpendicular()
コード例 #28
0
def vector(request):
    return Vector3d(request.param)
コード例 #29
0
def test_check_vector():
    vector3 = Vector3d([2, 2, 2])
    assert np.allclose(vector3.data, check_vector(vector3).data)
コード例 #30
0
def something(request):
    return Vector3d(request.param)