def get_grid_around_beam_direction(beam_rotation,
                                   resolution,
                                   angular_range=(0, 360)):
    """
    Creates a rotation list of rotations for which the rotation is about given beam direction

    Parameters
    ----------
    beam_rotation : tuple
        A desired beam direction as a rotation (rzxz eulers), usually found via get_rotation_from_z_to_direction

    resolution : float
        The resolution of the grid (degrees)

    angular_range : tuple
        The minimum (included) and maximum (excluded) rotation around the beam direction to be included

    Returns
    -------
    rotation_list : list of tuples

    Example
    -------
    >>> from diffsims.generators.zap_map_generator import get_rotation_from_z_to_direction
    >>> beam_rotation = get_rotation_from_z_to_direction(structure,[1,1,1])
    >>> grid = get_grid_around_beam_direction(beam_rotation,1)
    """

    beam_rotation = np.deg2rad(beam_rotation)
    axangle = euler2axangle(beam_rotation[0], beam_rotation[1],
                            beam_rotation[2], "rzxz")
    rotation_list = None
    raise NotImplementedError("This functionality will be (re)added in future")
    return rotation_list
Esempio n. 2
0
def test_euler_axes():
    # Test there and back with all axis specs
    aba_perms = [(v[0], v[1], v[0]) for v in permutations('xyz', 2)]
    axis_perms = list(permutations('xyz', 3)) + aba_perms
    for (a, b, c), mat in zip(euler_tuples, euler_mats):
        for rs, axes in product('rs', axis_perms):
            ax_spec = rs + ''.join(axes)
            conventioned = [EulerFuncs(ax_spec)]
            if ax_spec in euler.__dict__:
                conventioned.append(euler.__dict__[ax_spec])
            mat = euler2mat(a, b, c, ax_spec)
            a1, b1, c1 = mat2euler(mat, ax_spec)
            mat_again = euler2mat(a1, b1, c1, ax_spec)
            assert_almost_equal(mat, mat_again)
            quat = euler2quat(a, b, c, ax_spec)
            a1, b1, c1 = quat2euler(quat, ax_spec)
            mat_again = euler2mat(a1, b1, c1, ax_spec)
            assert_almost_equal(mat, mat_again)
            ax, angle = euler2axangle(a, b, c, ax_spec)
            a1, b1, c1 = axangle2euler(ax, angle, ax_spec)
            mat_again = euler2mat(a1, b1, c1, ax_spec)
            assert_almost_equal(mat, mat_again)
            for obj in conventioned:
                mat = obj.euler2mat(a, b, c)
                a1, b1, c1 = obj.mat2euler(mat)
                mat_again = obj.euler2mat(a1, b1, c1)
                assert_almost_equal(mat, mat_again)
                quat = obj.euler2quat(a, b, c)
                a1, b1, c1 = obj.quat2euler(quat)
                mat_again = obj.euler2mat(a1, b1, c1)
                assert_almost_equal(mat, mat_again)
                ax, angle = obj.euler2axangle(a, b, c)
                a1, b1, c1 = obj.axangle2euler(ax, angle)
                mat_again = obj.euler2mat(a1, b1, c1)
                assert_almost_equal(mat, mat_again)
Esempio n. 3
0
    def to_AxAngle(self):
        """ Converts an Euler object to an AxAngle object

        Returns
        -------
        axangle : diffsims.AxAngle object
        """
        self._check_data()
        self.data = np.deg2rad(self.data)  # for the transform operation

        if self.axis_convention == 'rzxz' or self.axis_convention =='szxz':
            stored_axangle = vectorised_euler2axangle(self.data, axes=self.axis_convention)
            stored_axangle = vectorised_axangle_to_correct_range(stored_axangle)

        else:
            # This is very slow
            from transforms3d.euler import euler2axangle
            stored_axangle = np.ones((self.data.shape[0], 4))
            for i, row in enumerate(self.data):
                temp_vect, temp_angle = euler2axangle(row[0], row[1], row[2], self.axis_convention)
                temp_vect, temp_angle = convert_axangle_to_correct_range(temp_vect, temp_angle)
                for j in [0, 1, 2]:
                    stored_axangle[i, j] = temp_vect[j]
                    stored_axangle[i, 3] = temp_angle  # in radians!

        self.data = np.rad2deg(self.data)  # leaves our eulers safe and sound
        return AxAngle(stored_axangle)
Esempio n. 4
0
def test_euler_axes():
    # Test there and back with all axis specs
    aba_perms = [(v[0], v[1], v[0]) for v in permutations('xyz', 2)]
    axis_perms = list(permutations('xyz', 3)) + aba_perms
    for (a, b, c), mat in zip(euler_tuples, euler_mats):
        for rs, axes in product('rs', axis_perms):
            ax_spec = rs + ''.join(axes)
            conventioned = [EulerFuncs(ax_spec)]
            if ax_spec in euler.__dict__:
                conventioned.append(euler.__dict__[ax_spec])
            mat = euler2mat(a, b, c, ax_spec)
            a1, b1, c1 = mat2euler(mat, ax_spec)
            mat_again = euler2mat(a1, b1, c1, ax_spec)
            assert_almost_equal(mat, mat_again)
            quat = euler2quat(a, b, c, ax_spec)
            a1, b1, c1 = quat2euler(quat, ax_spec)
            mat_again = euler2mat(a1, b1, c1, ax_spec)
            assert_almost_equal(mat, mat_again)
            ax, angle = euler2axangle(a, b, c, ax_spec)
            a1, b1, c1 = axangle2euler(ax, angle, ax_spec)
            mat_again = euler2mat(a1, b1, c1, ax_spec)
            assert_almost_equal(mat, mat_again)
            for obj in conventioned:
                mat = obj.euler2mat(a, b, c)
                a1, b1, c1 = obj.mat2euler(mat)
                mat_again = obj.euler2mat(a1, b1, c1)
                assert_almost_equal(mat, mat_again)
                quat = obj.euler2quat(a, b, c)
                a1, b1, c1 = obj.quat2euler(quat)
                mat_again = obj.euler2mat(a1, b1, c1)
                assert_almost_equal(mat, mat_again)
                ax, angle = obj.euler2axangle(a, b, c)
                a1, b1, c1 = obj.axangle2euler(ax, angle)
                mat_again = obj.euler2mat(a1, b1, c1)
                assert_almost_equal(mat, mat_again)
Esempio n. 5
0
def euler2em(ea):
    '''

    :param ea: rotation in euler angles (3,)
    :return: rotation in expo-map (3,)
    '''
    from transforms3d.euler import euler2axangle
    axis, theta = euler2axangle(*ea)
    return np.array(axis * theta)
Esempio n. 6
0
def get_grid_around_beam_direction(beam_rotation,
                                   resolution,
                                   angular_range=(0, 360)):
    """
    Creates a rotation list of rotations for which the rotation is about given beam direction

    Parameters
    ----------
    beam_rotation : tuple
        A desired beam direction as a rotation (rzxz eulers), usually found via get_rotation_from_z_to_direction

    resolution : float
        The resolution of the grid (degrees)

    angular_range : tuple
        The minimum (included) and maximum (excluded) rotation around the beam direction to be included

    Returns
    -------
    rotation_list : list of tuples

    Example
    -------
    >>> from diffsims.generators.zap_map_generator import get_rotation_from_z_to_direction
    >>> beam_rotation = get_rotation_from_z_to_direction(structure,[1,1,1])
    >>> grid = get_grid_around_beam_direction(beam_rotation,1)
    """

    beam_rotation = np.deg2rad(beam_rotation)
    axangle = euler2axangle(beam_rotation[0], beam_rotation[1],
                            beam_rotation[2], 'rzxz')
    euler_szxz = axangle2euler(axangle[0], axangle[1],
                               'szxz')  # convert to szxz
    rotation_alpha, rotation_beta = np.rad2deg(euler_szxz[0]), np.rad2deg(
        euler_szxz[1])

    # see _create_advanced_linearly_spaced_array_in_rzxz for details
    steps_gamma = int(
        np.ceil((angular_range[1] - angular_range[0]) / resolution))
    alpha = np.asarray([rotation_alpha])
    beta = np.asarray([rotation_beta])
    gamma = np.linspace(angular_range[0],
                        angular_range[1],
                        num=steps_gamma,
                        endpoint=False)
    z = np.asarray(list(product(alpha, beta, gamma)))
    raw_grid = Euler(
        z, axis_convention='szxz'
    )  # we make use of an uncommon euler angle set here for speed
    grid_rzxz = raw_grid.to_AxAngle().to_Euler(axis_convention='rzxz')
    rotation_list = grid_rzxz.to_rotation_list(round_to=2)
    return rotation_list
 def test_axis_angle_from_rpy(self, roll, pitch, yaw):
     axis2, angle2 = euler2axangle(roll, pitch, yaw)
     assume(abs(angle2) > SMALL_NUMBER)
     axis, angle = spw.axis_angle_from_rpy(roll, pitch, yaw)
     angle = float(angle)
     axis = np.array(axis).astype(float).T[0]
     if angle < 0:
         angle = -angle
         axis = [-x for x in axis]
     if angle2 < 0:
         angle2 = -angle2
         axis2 *= -1
     compare_axis_angle(angle, axis, angle2, axis2)
Esempio n. 8
0
def create_sample(edc, structure, angle_start, angle_change):
    dps = []
    for orientation in create_pair(angle_start, angle_change):
        axis, angle = euler2axangle(orientation[0], orientation[1],
                                    orientation[2], 'rzxz')
        rotation = RotationTransformation(axis, angle, angle_in_radians=True)
        rotated_structure = rotation.apply_transformation(structure)
        data = edc.calculate_ed_data(
            rotated_structure,
            reciprocal_radius=0.9,  #avoiding a reflection issue
            with_direct_beam=False)
        dps.append(data.as_signal(2 * half_side_length, 0.025, 1).data)
    dp = pxm.ElectronDiffraction([dps[0:2], dps[2:]])
    dp.set_diffraction_calibration(1 / half_side_length)
    return dp
Esempio n. 9
0
 def test_axis_angle_from_rpy(self, roll, pitch, yaw):
     axis2, angle2 = euler2axangle(roll, pitch, yaw)
     assume(abs(angle2) > SMALL_NUMBER)
     axis = w.compile_and_execute(
         lambda r, p, y: w.axis_angle_from_rpy(r, p, y)[0],
         [roll, pitch, yaw])
     angle = w.compile_and_execute(
         lambda r, p, y: w.axis_angle_from_rpy(r, p, y)[1],
         [roll, pitch, yaw])
     if angle < 0:
         angle = -angle
         axis = [-x for x in axis]
     if angle2 < 0:
         angle2 = -angle2
         axis2 *= -1
     compare_axis_angle(angle, axis, angle2, axis2)
Esempio n. 10
0
 def draw(self):
     axis, theta = _euler.euler2axangle(self.pqr.x, self.pqr.y, self.pqr.z)
     axis = _vp.vector(axis[0], axis[1], axis[2])
     up = _vp.rotate(_vp.vector(0,1,0), theta, axis)
     self.body.pos   = self.xyz
     self.top.pos    = self.xyz + up*_size
     self.prop1.pos  = self.xyz + _vp.rotate(_vp.vector(1.3*_size,0,0), theta, axis)
     self.prop2.pos  = self.xyz + _vp.rotate(_vp.vector(0,0,1.3*_size), theta, axis)
     self.prop3.pos  = self.xyz + _vp.rotate(_vp.vector(-1.3*_size,0,0), theta, axis)
     self.prop4.pos  = self.xyz + _vp.rotate(_vp.vector(0,0,-1.3*_size), theta, axis)
     self.prop1.axis = up
     self.prop2.axis = up
     self.prop3.axis = up
     self.prop4.axis = up
     if _follow_drone:
         canvas.center = self.xyz
     canvas.caption = 'time = %0.1f, pos = (%0.1f, %0.1f, %0.1f), energy = %0.1f' % (time, self.xyz.x, self.xyz.y, self.xyz.z, self.energy)
Esempio n. 11
0
def _euler2axangle_signal(euler):
    """Converts an Euler triple into the axis-angle representation.

    Parameters
    ----------
    euler : np.array()
        Euler angles for a rotation.

    Returns
    -------
    asangle : np.array()
        Axis-angle representation of the rotation.

    """
    euler = euler[
        0]  # TODO: euler is a 1-element ndarray(dtype=object) with a tuple
    return np.rad2deg(euler2axangle(euler[0], euler[1], euler[2])[1])
Esempio n. 12
0
 def update(self, dt):
     # forces
     axis, theta = _euler.euler2axangle(self.pqr.x, self.pqr.y, self.pqr.z)
     axis = _vp.vector(axis[0], axis[1], axis[2])
     up = _vp.rotate(_vp.vector(0,1,0), theta, axis)
     a = _vp.vector(0, -_gravity, 0)
     a = a + (self.thrust1+self.thrust2+self.thrust3+self.thrust4)/self.mass * up + self.wind/self.mass
     a = a - (_lin_drag_coef * _vp.mag(self.xyz_dot)**2)/self.mass * self.xyz_dot
     self.xyz_dot = self.xyz_dot + a * dt
     # torques (ignoring propeller torques)
     cg = self.cgpos * up
     tpos1 = _vp.rotate(_vp.vector(1.3*_size,0,0), theta, axis)
     tpos2 = _vp.rotate(_vp.vector(0,0,1.3*_size), theta, axis)
     tpos3 = _vp.rotate(_vp.vector(-1.3*_size,0,0), theta, axis)
     tpos4 = _vp.rotate(_vp.vector(0,0,-1.3*_size), theta, axis)
     torque = _vp.cross(cg, _vp.vector(0, -_gravity, 0))
     torque = torque + _vp.cross(tpos1, self.thrust1 * up)
     torque = torque + _vp.cross(tpos2, self.thrust2 * up)
     torque = torque + _vp.cross(tpos3, self.thrust3 * up)
     torque = torque + _vp.cross(tpos4, self.thrust4 * up)
     torque = torque - _rot_drag_coef * self.pqr_dot
     aa = torque/self.inertia
     if _vp.mag(aa) > 0:
         aai, aaj, aak = _euler.axangle2euler((aa.x, aa.y, aa.z), _vp.mag(aa))
         aa = _vp.vector(aai, aaj, aak)
         self.pqr_dot = self.pqr_dot + aa * dt
     else:
         self.pqr_dot = _vp.vector(0,0,0)
     # ground interaction
     if self.xyz.y <= 0:
         self.xyz.y = 0
         if self.xyz_dot.y <= 0:
             self.xyz_dot.x = self.xyz_dot.x * _ground_friction
             self.xyz_dot.y = 0
             self.xyz_dot.z = self.xyz_dot.z * _ground_friction
             self.pqr_dot = self.pqr_dot * _ground_friction
     # energy update
     self.energy += _power_coef * (self.thrust1**1.5 + self.thrust2**1.5 + self.thrust3**1.5 + self.thrust4**1.5) * dt
     # time update
     self.xyz += self.xyz_dot * dt
     self.pqr += self.pqr_dot * dt
     # callback
     if self.updated is not None:
         self.updated(self)
     self.draw()
Esempio n. 13
0
def _euler2axangle_signal(euler):
    """ Find the magnitude of a rotation"""
    return np.array(euler2axangle(euler[0], euler[1], euler[2])[1])
Esempio n. 14
0
def euler2axangle_signal(euler):
    return np.array(euler2axangle(euler[0], euler[1], euler[2])[1])
Esempio n. 15
0
    def get_diffraction_library(self,
                                structure_library,
                                calibration,
                                reciprocal_radius,
                                representation='euler'):
        """Calculates a dictionary of diffraction data for a library of crystal
        structures and orientations.

        Each structure in the structure library is rotated to each associated
        orientation and the diffraction pattern is calculated each time.

        Parameters
        ----------
        structure_library : dict
            Dictionary of structures and associated orientations (represented as
            Euler angles or axis-angle pairs) for which electron diffraction is
            to be simulated.

        calibration : float
            The calibration of experimental data to be correlated with the
            library, in reciprocal Angstroms per pixel.

        reciprocal_radius : float
            The maximum g-vector magnitude to be included in the simulations.

        representation : 'euler' or 'axis-angle'
            The representation in which the orientations are provided.
            If 'euler' the zxz convention is taken and values are in radians, if
            'axis-angle' the rotational angle is in degrees.

        Returns
        -------
        diffraction_library : dict of :class:`DiffractionSimulation`
            Mapping of crystal structure and orientation to diffraction data
            objects.

        """
        # Define DiffractionLibrary object to contain results
        diffraction_library = DiffractionLibrary()
        # The electron diffraction calculator to do simulations
        diffractor = self.electron_diffraction_calculator
        # Iterate through phases in library.
        for key in structure_library.keys():
            phase_diffraction_library = dict()
            structure = structure_library[key][0]
            orientations = structure_library[key][1]
            # Iterate through orientations of each phase.
            for orientation in tqdm(orientations, leave=False):
                if representation=='axis-angle':
                    axis = [orientation[0], orientation[1], orientation[2]]
                    angle = orientation[3] / 180 * pi
                if representation=='euler':
                    axis, angle = euler2axangle(orientation[0], orientation[1],
                                                orientation[2], 'rzxz')
                # Apply rotation to the structure
                rotation = RotationTransformation(axis, angle,
                                                  angle_in_radians=True)
                rotated_structure = rotation.apply_transformation(structure)
                # Calculate electron diffraction for rotated structure
                data = diffractor.calculate_ed_data(rotated_structure,
                                                    reciprocal_radius)
                # Calibrate simulation
                data.calibration = calibration
                # Construct diffraction simulation library.
                phase_diffraction_library[tuple(orientation)] = data
            diffraction_library[key] = phase_diffraction_library
        return diffraction_library
Esempio n. 16
0
 def euler_from_as(self, roll, pitch, yaw):
     rot_vec_as, theta = euler.euler2axangle(roll, pitch, yaw)
     rot_vec = self.vel3d_from_as(rot_vec_as)
     r, p, y = euler.axangle2euler(rot_vec, theta)
     return r, p, y
Esempio n. 17
0
    def get_diffraction_library(self,
                                structure_library,
                                calibration,
                                reciprocal_radius,
                                half_shape,
                                representation='euler',
                                with_direct_beam=True):
        """Calculates a dictionary of diffraction data for a library of crystal
        structures and orientations.

        Each structure in the structure library is rotated to each associated
        orientation and the diffraction pattern is calculated each time.

        Parameters
        ----------
        structure_library : dict
            Dictionary of structures and associated orientations (represented as
            Euler angles or axis-angle pairs) for which electron diffraction is
            to be simulated.

        calibration : float
            The calibration of experimental data to be correlated with the
            library, in reciprocal Angstroms per pixel.

        reciprocal_radius : float
            The maximum g-vector magnitude to be included in the simulations.

        representation : 'euler' or 'axis-angle'
            The representation in which the orientations are provided.
            If 'euler' the zxz convention is taken and values are in radians, if
            'axis-angle' the rotational angle is in degrees.

        half_shape: tuple
            The half shape of the target patterns, for 144x144 use (72,72) etc

        Returns
        -------
        diffraction_library : dict of :class:`DiffractionSimulation`
            Mapping of crystal structure and orientation to diffraction data
            objects.

        """
        # Define DiffractionLibrary object to contain results
        diffraction_library = DiffractionLibrary()
        # The electron diffraction calculator to do simulations
        diffractor = self.electron_diffraction_calculator
        # Iterate through phases in library.
        for key in structure_library.keys():
            phase_diffraction_library = dict()
            structure = structure_library[key][0]
            orientations = structure_library[key][1]
            # Iterate through orientations of each phase.
            for orientation in tqdm(orientations, leave=False):
                if representation == 'axis-angle':
                    axis = [orientation[0], orientation[1], orientation[2]]
                    angle = orientation[3] / 180 * pi
                if representation == 'euler':
                    axis, angle = euler2axangle(orientation[0], orientation[1],
                                                orientation[2], 'rzxz')
                # Apply rotation to the structure
                rotation = RotationTransformation(axis,
                                                  angle,
                                                  angle_in_radians=True)
                rotated_structure = rotation.apply_transformation(structure)
                # Calculate electron diffraction for rotated structure
                data = diffractor.calculate_ed_data(rotated_structure,
                                                    reciprocal_radius,
                                                    with_direct_beam)
                # Calibrate simulation
                data.calibration = calibration
                pattern_intensities = data.intensities
                pixel_coordinates = np.rint(
                    data.calibrated_coordinates[:, :2] +
                    half_shape).astype(int)
                # Construct diffraction simulation library, removing those that contain no peaks
                if len(pattern_intensities) > 0:
                    phase_diffraction_library[tuple(orientation)] = \
                    {'Sim':data,'intensities':pattern_intensities, \
                     'pixel_coords':pixel_coordinates, \
                     'pattern_norm': np.sqrt(np.dot(pattern_intensities,pattern_intensities))}
                    diffraction_library[key] = phase_diffraction_library
        return diffraction_library
Esempio n. 18
0
# This file is part of diffsims.
#
# diffsims is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# diffsims is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with diffsims.  If not, see <http://www.gnu.org/licenses/>.

"""

These utils provide vectorised implementations of conversions as described in the package transforms3d.

Currently avaliable are:

euler2quat
quat2axangle
euler2axangle (via chaining of the above)

axangle2mat
mat2euler
axangle2euler (via chaining of the above)

It also provides two implementations (one vectorised) that convert axis-angles pairs to the correct
angular ranges
Esempio n. 19
0
def exp_map(v):
    vec, angle = euler.euler2axangle(*map(convert, v))
    return angle * vec