Example #1
0
    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
Example #2
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)
Example #3
0
def detector2sample(
    sample_tilt: float,
    detector_tilt: float,
    convention: Optional[str] = None,
) -> Rotation:
    """Rotation U_S to align detector frame D with sample frame S.

    Parameters
    ----------
    sample_tilt
        Sample tilt in degrees.
    detector_tilt
        Detector tilt in degrees.
    convention
        Which sample reference frame to use, either the one used by EDAX
        TSL (default), "tsl", or the one used by Bruker, "bruker".

    Returns
    -------
    Rotation
    """
    # Rotation about sample (microscope) X axis
    tilt = -np.deg2rad((sample_tilt - 90) - detector_tilt)
    ax_angle = neo_euler.AxAngle.from_axes_angles(Vector3d.xvector(), tilt)
    r = Rotation.from_neo_euler(ax_angle)

    if convention != "bruker":
        # Followed by a 90 degree rotation about the sample Z axis,
        # if the TSL sample reference frame is used
        ax_angle_bruker2tsl = neo_euler.AxAngle.from_axes_angles(
            Vector3d.zvector(), np.pi / 2)
        r = Rotation.from_neo_euler(ax_angle_bruker2tsl) * r

    return r.to_matrix()[0]
Example #4
0
 def get_highest_order_axis(self):
     axis_orders = self.get_axis_orders()
     if len(axis_orders) == 0:
         return Vector3d.zvector(), np.infty
     highest_order = max(axis_orders.values())
     axes = Vector3d.stack([ao for ao in axis_orders if
                            axis_orders[ao] == highest_order]).flatten()
     return axes, highest_order
Example #5
0
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
Example #6
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
Example #7
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
Example #8
0
    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
Example #9
0
    def iproject(xy: np.ndarray) -> Vector3d:
        """Convert from 2D Gnomonic coordinates (x_g, y_g) to 3D
        cartesian coordiantes (x, y, z).

        Parameters
        ----------
        xy
            2D coordinates on the form
            [[x_g0, y_g0], [x_g1, y_g1], ...].

        Returns
        -------
        cartesian_coordinates
            Cartesian coordinates (x, y, z) on the form
            [[x0, y0, z0], [x1, y1, z1], ...].

        Examples
        --------
        >>> import numpy as np
        >>> from kikuchipy.projections.gnomonic_projection import (
        ...     GnomonicProjection
        ... )
        >>> xy_g = np.random.random_sample(20).reshape((10, 2))
        >>> xyz = GnomonicProjection.iproject(xy_g)
        """
        x, y = xy[..., 0], xy[..., 1]
        theta = np.arctan(np.sqrt(x**2 + y**2))
        phi = np.arctan2(y, x)
        return Vector3d.from_polar(theta=theta, phi=phi)
Example #10
0
    def get_plot_data(self):
        """
        Produces suitable Rotations for the construction of a wireframe for self
        """
        from orix.vector import Vector3d

        # gets a grid of vector directions
        theta = np.linspace(0, 2 * np.pi - EPSILON, 361)
        rho = np.linspace(0, np.pi - EPSILON, 181)
        theta, rho = np.meshgrid(theta, rho)
        g = Vector3d.from_polar(rho, theta)

        # get the cell vector normal norms
        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
        omega = 2 * np.arctan(np.where(x != 0, x**-1, np.pi))

        # keeps the smallest allowed angle
        omega[omega < 0] = np.pi
        omega = np.min(omega, axis=0)
        r = Rotation.from_neo_euler(AxAngle.from_axes_angles(g.unit, omega))
        return r
    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)
Example #12
0
    def spherical2xy(self, azimuth, polar):
        r"""Return stereographic coordinates (X, Y) from 3D unit vectors
        created from spherical coordinates, azimuth :math:`\phi` and
        polar :math:`\theta`, defined as in the ISO 31-11 standard
        [SphericalWolfram]_.

        Parameters
        ----------
        azimuth : float or numpy.ndarray
            Spherical azimuth coordinate.
        polar : float or numpy.ndarray
            Spherical polar coordinate.

        Returns
        -------
        x : numpy.ndarray
            Stereographic coordinate X of shape same shape as the input
            vector shape. Only the vectors with :math:`z` coordinate
            positive (`pole` = -1) or negative (`pole` = 1) are
            returned.
        y : numpy.ndarray
            Stereographic coordinate Y of shape same shape as the input
            vector shape. Only the vectors with :math:`z` coordinate
            positive (`pole` = -1) or negative (`pole` = 1) are
            returned.

        See Also
        --------
        vector2xy
        """
        v = Vector3d.from_polar(azimuth=azimuth, polar=polar)
        return self.vector2xy(v)
Example #13
0
    def spherical2xy_split(self, azimuth, polar):
        r"""Return two sets of stereographic coordinates (X, Y) from 3D
        unit vectors created from spherical coordinates, azimuth
        :math:`\phi` and polar :math:`\theta`, defined as in the
        ISO 31-11 standard [SphericalWolfram]_: one set for vectors in
        the upper hemisphere, and one for the lower.

        Parameters
        ----------
        azimuth : float or numpy.ndarray
            Spherical azimuth coordinate.
        polar : float or numpy.ndarray
            Spherical polar coordinate.

        Returns
        -------
        x_upper : numpy.ndarray
            Stereographic coordinate X of upper hemisphere vectors, of
            shape same shape as the input vector shape.
        y_upper : numpy.ndarray
            Stereographic coordinate Y of upper hemisphere vectors, of
            shape same shape as the input vector shape.
        x_lower : numpy.ndarray
            Stereographic coordinate X of lower hemisphere vectors, of
            shape same shape as the input vector shape.
        y_lower : numpy.ndarray
            Stereographic coordinate Y of lower hemisphere vectors, of
            shape same shape as the input vector shape.

        See Also
        --------
        vector2xy
        """
        v = Vector3d.from_polar(azimuth=azimuth, polar=polar)
        return self.vector2xy_split(v)
Example #14
0
    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
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
Example #16
0
 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))
     }
Example #17
0
 def test_from_neo_euler_symmetry(self):
     v = AxAngle.from_axes_angles(axes=Vector3d.zvector(), angles=np.pi / 2)
     o1 = Orientation.from_neo_euler(v)
     assert np.allclose(o1.data, [0.7071, 0, 0, 0.7071])
     assert o1.symmetry.name == "1"
     o2 = Orientation.from_neo_euler(v, symmetry=Oh)
     assert np.allclose(o2.data, [-1, 0, 0, 0])
     assert o2.symmetry.name == "m-3m"
     o3 = o1.set_symmetry(Oh)
     assert np.allclose(o3.data, o2.data)
Example #18
0
    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])
Example #19
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)
Example #20
0
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)
 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)
 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
    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)
Example #24
0
 def get_plot_data(self):
     from orix.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
Example #25
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
def detector2sample(sample_tilt: float, detector_tilt: float) -> Rotation:
    """Rotation U_S to align detector frame D with sample frame S.

    Parameters
    ----------
    sample_tilt
        Sample tilt in degrees.
    detector_tilt
        Detector tilt in degrees.

    Returns
    -------
    Rotation
    """
    x_axis = Vector3d.xvector()
    tilt = -np.deg2rad((sample_tilt - 90) - detector_tilt)
    ax_angle = neo_euler.AxAngle.from_axes_angles(x_axis, tilt)
    return Rotation.from_neo_euler(ax_angle).to_matrix()[0]
Example #27
0
    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)
Example #28
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)))
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)
Example #30
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)