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
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]
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
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
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)
def r_tsl2bruker(): """A rotation from the TSL to Bruker crystal reference frame.""" return Rotation.from_neo_euler( neo_euler.AxAngle.from_axes_angles(Vector3d.zvector(), np.pi / 2))
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)
def test_rotate(vector, rotation, expected): r = Vector3d(vector).rotate(Vector3d.zvector(), rotation) assert isinstance(r, Vector3d) assert np.allclose(r.data, expected)