Example #1
0
    def test_3d_array(self):
        """Multiplying higher dimensional arrays of quaternions"""
        num_reps = 20
        expanded_shape = (int(num_reps / 5), 5, 4)
        zeros = np.reshape(np.repeat(zero[np.newaxis, :], num_reps, axis=0),
                           expanded_shape)
        ones = np.reshape(np.repeat(one[np.newaxis, :], num_reps, axis=0),
                          expanded_shape)
        expected_product_zeros = np.reshape(
            np.repeat(np.array([0, 0, 0, 0])[np.newaxis, :], num_reps, axis=0),
            expanded_shape)
        expected_product_ones = np.reshape(
            np.repeat(np.array([1, 0, 0, 0])[np.newaxis, :], num_reps, axis=0),
            expanded_shape)

        # Zeros
        product = rowan.multiply(zeros, zeros)
        self.assertTrue(np.all(product == expected_product_zeros))

        # Ones
        product = rowan.multiply(ones, ones)
        self.assertTrue(np.all(product == expected_product_ones))

        # Complex random array
        num_reps = input1.shape[0]
        expanded_shape = (int(num_reps / 5), 5, 4)
        product = rowan.multiply(np.reshape(input1, expanded_shape),
                                 np.reshape(input2, expanded_shape))
        self.assertTrue(
            np.allclose(product, np.reshape(stored_product, expanded_shape)))
Example #2
0
    def test_single_quaternion(self):
        """Simplest case of quaternion multiplication"""
        # Multiply zeros
        product = rowan.multiply(zero, zero)
        self.assertTrue(np.all(product == np.array([0, 0, 0, 0])))

        # Multiply ones
        product = rowan.multiply(one, one)
        self.assertTrue(np.all(product == np.array([1, 0, 0, 0])))
Example #3
0
    def test_slerp_prime(self):
        """Test spherical linear interpolation derivative."""
        self.assertTrue(np.all(interpolate.slerp_prime(one, one, 0) == zero))
        self.assertTrue(np.all(interpolate.slerp_prime(one, one, 1) == zero))
        self.assertTrue(np.all(interpolate.slerp_prime(one, one, 0.5) == zero))

        self.assertTrue(
            np.allclose(
                interpolate.slerp_prime(root_two, one, 0.5),
                rowan.multiply(
                    interpolate.slerp(root_two, one, 0.5),
                    rowan.log(rowan.multiply(rowan.conjugate(root_two), one)),
                ),
            )
        )
Example #4
0
    def render(self, rotation=(1, 0, 0, 0), translation=(0, 0, 0), **kwargs):
        (positions, orientations, colors) = mesh.unfoldProperties(
            [self.positions, self.orientations, self.colors])
        positions = rowan.rotate(rotation, positions)
        positions += translation
        orientations = rowan.multiply(rotation, rowan.normalize(orientations))
        rotations = np.degrees(rowan.to_euler(orientations))

        lines = []
        for (pos, rot, col, alpha) in zip(positions, rotations, colors[:, :3],
                                          1 - colors[:, 3]):
            lines.append(
                'sphere {{ '
                '0, 1 scale<{a}, {b}, {c}> '
                'rotate <{rot[2]}, {rot[1]}, {rot[0]}> '
                'translate <{pos[0]}, {pos[1]}, {pos[2]}> '
                'pigment {{ color <{col[0]}, {col[1]}, {col[2]}> transmit {alpha} }} '
                '}}'.format(a=self.a,
                            b=self.b,
                            c=self.c,
                            pos=pos,
                            rot=rot,
                            col=col,
                            alpha=alpha))
        return lines
def return_correlation(l, initial_q, orientations):
    """Compute the rotational autocorrelation."""
    calc_quats = rowan.multiply(rowan.conjugate(initial_q), orientations)
    ref_quats = rowan.multiply(rowan.conjugate(initial_q), initial_q)

    ref_angles = quat_to_greek(ref_quats)
    calc_angles = quat_to_greek(calc_quats)

    f_of_t = 0

    for m1 in np.arange(-l / 2, l / 2 + 1):
        for m2 in np.arange(-l / 2, l / 2 + 1):
            ref_y = hypersphere_harmonic(ref_angles, l, m1, m2)
            calc_y = hypersphere_harmonic(calc_angles, l, m1, m2)
            f_of_t += (ref_y.conjugate() * calc_y)

    return f_of_t.real
Example #6
0
    def orbit(self, yaw=0, pitch=0, roll=0, factor=-0.0025, slight=False):
        """Orbit the camera about the look_at point."""
        if slight:
            factor = factor * 0.1

        basis = numpy.array(self._start_camera.basis)

        q1 = rowan.from_axis_angle(basis[1, :], factor * yaw)
        q2 = rowan.from_axis_angle(basis[0, :], factor * pitch)
        q3 = rowan.from_axis_angle(basis[2, :], factor * roll)
        q = rowan.multiply(q2, rowan.multiply(q1, q3))

        v = self._start_camera.position - self._start_camera.look_at
        v = rowan.rotate(q, v)

        self.camera.position = self._start_camera.look_at + v
        self.camera.up = rowan.rotate(q, basis[1, :])
Example #7
0
 def test_divide(self):
     """Ensure division works"""
     shapes = [(4, ), (5, 4), (5, 5, 4), (5, 5, 5, 4)]
     np.random.seed(0)
     for shape_i in shapes:
         x = np.random.random_sample(shape_i)
         for shape_j in shapes:
             y = np.random.random_sample(shape_j)
             self.assertTrue(
                 np.allclose(rowan.divide(x, y),
                             rowan.multiply(x, rowan.inverse(y))))
Example #8
0
    def test_2d_array(self):
        """Multiplying arrays of quaternions"""
        zeros = np.repeat(zero[np.newaxis, :], 10, axis=0)
        ones = np.repeat(one[np.newaxis, :], 10, axis=0)

        # Multiply zeros
        product = rowan.multiply(zeros, zeros)
        self.assertTrue(
            np.all(product == np.repeat(
                np.array([0, 0, 0, 0])[np.newaxis, :], 10, axis=0)))

        # Multiply ones
        product = rowan.multiply(ones, ones)
        self.assertTrue(
            np.all(product == np.repeat(
                np.array([1, 0, 0, 0])[np.newaxis, :], 10, axis=0)))

        # Complex random array
        product = rowan.multiply(input1, input2)
        self.assertTrue(np.allclose(product, stored_product))
Example #9
0
def gen_sym_quats(group):
    """Generate symmetric quaternions for a set of point groups."""
    operations = symgroups[group]
    quats = []
    for operation in operations:
        qtemp = rowan.from_axis_angle(axes=operation[1],
                                      angles=2 * np.pi / operation[0])
        quats.append(qtemp.tolist())
        quats.append(rowan.multiply([-1, 0, 0, 0], qtemp).tolist())

    return quats
Example #10
0
    def test_broadcast(self):
        """Ensure broadcasting works"""
        # Multiply zeros, simple shape check
        shape = (45, 3, 13, 4)
        many_zeros = np.zeros(shape)
        product = rowan.multiply(many_zeros, zero)
        self.assertTrue(product.shape == shape)

        # Two nonconforming array sizes
        with self.assertRaises(ValueError):
            rowan.multiply(many_zeros, np.repeat(zero[np.newaxis, :],
                                                 2,
                                                 axis=0))

        # Require broadcasting in multiple dimensions
        zeros_A = np.zeros((1, 1, 3, 8, 1, 4))
        zeros_B = np.zeros((3, 5, 1, 1, 9, 4))
        shape = (3, 5, 3, 8, 9, 4)
        product = rowan.multiply(zeros_A, zeros_B)
        self.assertTrue(product.shape == shape)

        # Test some actual products
        num_first = 2
        num_second = 5
        i1 = input1[:num_first, np.newaxis, :]
        i2 = input1[np.newaxis, :num_second, :]
        product = rowan.multiply(i1, i2)
        for i in range(num_first):
            for j in range(num_second):
                single_prod = rowan.multiply(i1[i, 0, :], i2[0, j, :])
                self.assertTrue(np.all(product[i, j, :] == single_prod))
Example #11
0
def compute_rotational_ke(snapshot: Snapshot) -> float:
    """Compute the kinetic energy of the rotational degrees of freedom.

    Args:
        snapshot: (Snapshot): Simulation snapshot from which to compute the kinetic energy

    Returns: The total rotational kinetic energy of the snapshot.

    """
    num_mols = get_num_mols(snapshot)
    angmom = snapshot.particles.angmom[:num_mols]
    moment_inertia = snapshot.particles.moment_inertia[:num_mols]
    momentum = rowan.multiply(
        0.5 * rowan.conjugate(snapshot.particles.orientation[:num_mols]), angmom
    )[:, 1:]
    mask = moment_inertia > 0
    return np.sum(0.5 * np.square(momentum[mask]) / moment_inertia[mask])
Example #12
0
    def test_power(self):
        """Ensure that quaternion power behaves correctly."""
        self.assertTrue(np.all(rowan.power(one, 0) == one))
        self.assertTrue(np.all(rowan.power(one, 1) == one))
        self.assertTrue(np.all(rowan.power(one, 10) == one))
        self.assertTrue(np.all(rowan.power(zero, 0) == one))
        self.assertTrue(np.all(rowan.power(zero, 1) == zero))
        self.assertTrue(np.all(rowan.power(zero, 10) == zero))

        np.random.seed(0)
        shapes = [(4,), (1, 4), (3, 4, 4), (12, 7, 3, 4)]
        max_power = 8
        for shape in shapes:
            x = np.random.random_sample(shape)
            cur_ans = x
            for i in range(1, max_power + 1):
                self.assertTrue(
                    np.allclose(rowan.power(x, i), cur_ans),
                    msg="Failed for shape {}".format(shape),
                )
                cur_ans = rowan.multiply(cur_ans, x)
Example #13
0
def calcFibre(symHKL, yset, qgrid, phi, rad, tree, euc_rad, quatSymOps):

    cphi = np.cos(phi / 2)
    sphi = np.sin(phi / 2)

    q0 = {}
    q = {}
    qf = {}

    axis = {}
    omega = {}

    fibre_e = {}
    fibre_q = {}

    nn_gridPts = {}
    nn_gridDist = {}

    egrid_trun = {}

    for fi, fam in enumerate(tqdm(symHKL)):

        fibre_e[fi] = {}
        fibre_q[fi] = {}

        nn_gridPts[fi] = {}
        nn_gridDist[fi] = {}

        egrid_trun[fi] = {}

        q0[fi] = {}
        q[fi] = {}

        axis[fi] = {}
        omega[fi] = {}
        """ set proper iterator """
        if isinstance(yset, dict): it = yset[fi]
        else: it = yset

        for yi, y in enumerate(it):

            axis[fi][yi] = np.cross(fam, y)
            axis[fi][yi] = axis[fi][yi] / np.linalg.norm(axis[fi][yi], axis=-1)
            omega[fi][yi] = np.arccos(np.dot(fam, y))

            q0[fi][yi] = np.hstack([
                np.cos(omega[fi][yi] / 2),
                np.sin(omega[fi][yi] / 2) * axis[fi][yi]
            ])
            q[fi][yi] = np.hstack([
                cphi[:, np.newaxis],
                np.tile(y, (len(cphi), 1)) * sphi[:, np.newaxis]
            ])
            qf[yi] = quat.multiply(q[fi][yi], q0[fi][yi])
            # qfib = quat.multiply(quatSymOps, qf[yi])
            qfib = quat.multiply(qf[yi], quatSymOps)
            qfib = qfib.transpose((1, 0, 2))

            phi1, Phi, phi2 = quat2eu(qfib)
            """ old way """
            # axis[fi][yi] = np.cross(fam,y)
            # axis[fi][yi] = axis[fi][yi] / np.linalg.norm(axis[fi][yi],axis=1)[:,None]
            # omega[fi][yi] = np.arccos(np.dot(fam,y))

            # q0[fi][yi] = {}
            # q[fi][yi] = {}
            # qf[yi] = {}
            # qfib = np.zeros((len(phi),len(fam),4))

            # for hi,HxY in enumerate(axis[fi][yi]):

            #     q0[fi][yi][hi] = np.hstack( [ np.cos(omega[fi][yi][hi]/2), np.sin(omega[fi][yi][hi]/2) * HxY ] )
            #     q[fi][yi][hi]  = np.hstack( [ cphi[:, np.newaxis], np.tile( y, (len(cphi),1) ) * sphi[:, np.newaxis] ] )

            #     qf[yi][hi] = quat.multiply(q[fi][yi][hi], q0[fi][yi][hi])

            #     for qi in range(qf[yi][hi].shape[0]):

            #         qfib[qi,hi,:] = qf[yi][hi][qi,:]

            # phi1, Phi, phi2 = quat2eu(qfib)

            phi1 = np.where(phi1 < 0, phi1 + 2 * np.pi,
                            phi1)  #brnng back to 0 - 2pi
            Phi = np.where(Phi < 0, Phi + np.pi, Phi)  #brnng back to 0 - pi
            phi2 = np.where(phi2 < 0, phi2 + 2 * np.pi,
                            phi2)  #brnng back to 0 - 2pi

            eu_fib = np.stack((phi1, Phi, phi2), axis=2)
            eu_fib = np.reshape(eu_fib, (eu_fib.shape[0] * eu_fib.shape[1],
                                         eu_fib.shape[2]))  #new method

            fz = (eu_fib[:, 0] <= od._phi1max) & (
                eu_fib[:, 1] <= od._Phimax) & (eu_fib[:, 2] <= od._phi2max)
            fz_idx = np.nonzero(fz)

            #pull only unique points? - not sure why there are repeated points, something with symmetry for certain hkls
            #should only be ~73 points per path, but three fold symmetry is also present
            fibre_e[fi][yi], uni_path_idx = np.unique(eu_fib[fz],
                                                      return_index=True,
                                                      axis=0)
            fib_idx = np.unravel_index(fz_idx[0],
                                       (qfib.shape[0], qfib.shape[1]))
            fibre_q[fi][yi] = qfib[fib_idx][uni_path_idx]
            """ euclidean distance calculation - KDTree """

            qfib_pos = np.copy(qfib[fib_idx][uni_path_idx])
            qfib_pos[qfib_pos[:, 0] < 0] *= -1

            # returns tuple - first array are points, second array is distances
            query = tree.query_radius(qfib_pos, euc_rad, return_distance=True)

            # concatenate arrays
            query = np.column_stack([np.concatenate(ar) for ar in query])

            # round very small values
            query = np.round(query, decimals=7)

            # move values at zero to very small (1E-5)
            query[:, 1] = np.where(query[:, 1] == 0, 1E-5, query[:, 1])

            # sort by minimum distance - unique function takes first appearance of index
            query_sort = query[np.argsort(query[:, 1], axis=0)]

            # return unique points
            uni_pts = np.unique(query_sort[:, 0], return_index=True)

            nn_gridPts[fi][yi] = uni_pts[0].astype(int)
            nn_gridDist[fi][yi] = query_sort[uni_pts[1], 1]
            """ geodesic distance calculation - dot product """

            # """ reduce geodesic query size """
            # qfib_pos = np.copy(qfib[fib_idx])
            # qfib_pos[qfib_pos[:,0] < 0] *= -1

            # query = np.concatenate(tree.query_radius(qfib_pos,euc_rad))
            # query_uni = np.unique(query)
            # qgrid_trun = qgrid[query_uni]
            # qgrid_trun_idx = np.arange(len(qgrid))[query_uni] #store indexes to retrieve original grid pts later

            # """ distance calc """
            # temp = quatMetricNumba(qgrid_trun,qfib[fib_idx])
            # """ find tube """
            # tube = (temp <= rad)
            # temp = np.column_stack((np.argwhere(tube)[:,0],temp[tube]))

            # """ round very small values """
            # temp = np.round(temp, decimals=7)

            # """ move values at zero to very small (1E-5) """
            # temp[:,1] = np.where(temp[:,1] == 0, 1E-5, temp[:,1])

            # """ sort by min distance """
            # temp = temp[np.argsort(temp[:,1],axis=0)]
            # """ return unique pts (first in list) """
            # uni_pts = np.unique(temp[:,0],return_index=True)

            # nn_gridPts[fi][yi] = qgrid_trun_idx[uni_pts[0].astype(int)]
            # nn_gridDist[fi][yi] = temp[uni_pts[1],1]

            # egrid_trun[fi][yi] = bungeAngs[query_uni]

    return nn_gridPts, nn_gridDist, fibre_e, axis, omega
Example #14
0
    def render(self,
               rotation=(1, 0, 0, 0),
               name_suffix='',
               illo_id='illo',
               ambient_light=0.4,
               directional_light=[],
               stroke=False,
               outline=False,
               **kwargs):

        # in the zdog coordinate system, x is to the right, y is down,
        # and z is toward you
        lines = []

        stroke = stroke or 'false'

        (vertices, faces) = geometry.convexHull(self.vertices)

        face_normals = []
        face_paths = []
        for face in faces:
            r01 = vertices[face[1]] - vertices[face[0]]
            r12 = vertices[face[2]] - vertices[face[1]]
            normal = np.cross(r01, r12)
            normal /= np.linalg.norm(normal)
            face_normals.append(normal)

            path = ', '.join('{{x: {}, y: {}, z: {}}}'.format(*v)
                             for v in vertices[face] * (1, -1, 1))
            face_paths.append(path)
        face_normals = np.array(face_normals, dtype=np.float32)

        orientations_euler = rowan.to_euler(self.orientations,
                                            convention='xyz',
                                            axis_type='intrinsic')

        particles = zip(*mesh.unfoldProperties([
            self.positions *
            (1, -1, 1), self.orientations, -orientations_euler, self.colors *
            255
        ]))
        for i, (position, orientation, eulers, color) in enumerate(particles):
            group_index = 'convexPoly_{}_{}'.format(name_suffix, i)

            # full rotation to apply to vectors from base orientation
            # to final scene orientation
            full_rotation = rowan.multiply(rotation, orientation)

            lines.append("""
            let {group_index} = new Zdog.Group({{
                addTo: {illo_id},
                rotate: {{x: {angle[0]}, y: {angle[1]}, z: {angle[2]}}},
                translate: {{x: {pos[0]}, y: {pos[1]}, z: {pos[2]}}},
                updateSort: true,
            }});""".format(group_index=group_index,
                           illo_id=illo_id,
                           angle=eulers,
                           pos=position))

            for (face_path, normal) in zip(face_paths, face_normals):
                rotated_normal = rowan.rotate(full_rotation, normal)

                light = ambient_light
                for direction in directional_light:
                    light += max(0, -np.dot(rotated_normal, direction))
                light = np.clip(light, 0, 1)

                (r, g, b) = map(int, light * color[:3])

                # RGB components are 0-255, A component is a float 0-1
                face_color = '"rgba({}, {}, {}, {})"'.format(
                    r, g, b, color[3] / 255)

                lines.append("""
                new Zdog.Shape({{
                    addTo: {group_index},
                    color: {face_color},
                    path: [{path}],
                    fill: true,
                    backface: true,
                    stroke: {stroke},
                }});
                """.format(group_index=group_index,
                           face_color=face_color,
                           path=face_path,
                           stroke=stroke))

                if outline:
                    outline_color = '"rgba(0, 0, 0, {})"'.format(color[3] /
                                                                 255)
                    lines.append("""
                    new Zdog.Shape({{
                        addTo: {group_index},
                        color: {color},
                        path: [{path}],
                        fill: false,
                        stroke: {stroke},
                    }});
                    """.format(group_index=group_index,
                               color=outline_color,
                               path=face_path,
                               stroke=outline))

        return lines
Example #15
0
 def check_orientation(central_orientation, constituent_orientation,
                       local_orientation):
     expected_orientation = rowan.normalize(
         rowan.multiply(central_orientation, local_orientation))
     assert np.allclose(expected_orientation, local_orientation)
Example #16
0
        axis = np.cross(fam, y)
        angle = np.arccos(np.dot(fam, y))

        q0 = quat.from_axis_angle(axis, angle)
        q0_n = quat.normalize(q0)

        q1_n = [quat.normalize(quat.from_axis_angle(h, omega)) for h in fam]

        # eu = np.zeros((len(omega),3,fam.shape[0]))
        eu2 = []

        qfib = np.zeros((len(q1_n[0]), len(q0_n), 4))

        for sym_eq, (qA, qB) in enumerate(zip(q0_n, q1_n)):

            temp = quat.multiply(qA, qB)

            qfib[:, sym_eq, :] = temp

        phi1, Phi, phi2 = quat2eu(qfib)

        phi1 = np.where(phi1 < 0, phi1 + 2 * np.pi,
                        phi1)  #brnng back to 0 - 2pi
        Phi = np.where(Phi < 0, Phi + np.pi, Phi)  #brnng back to 0 - pi
        phi2 = np.where(phi2 < 0, phi2 + 2 * np.pi,
                        phi2)  #brnng back to 0 - 2pi

        eu_fib = np.stack((phi1, Phi, phi2), axis=2)
        eu_fib = np.reshape(
            eu_fib,
            (eu_fib.shape[0] * eu_fib.shape[1], eu_fib.shape[2]))  #new method
Example #17
0
def calcFibre(symHKL, yset, qgrid, phi, rad, tree, euc_rad):

    cphi = np.cos(phi / 2)
    sphi = np.sin(phi / 2)

    q0 = {}
    q = {}
    qf = {}

    axis = {}
    omega = {}

    fibre_e = {}
    fibre_q = {}

    nn_gridPts = {}
    nn_gridDist = {}

    egrid_trun = {}

    for fi, fam in enumerate(tqdm(symHKL)):

        fibre_e[fi] = {}
        fibre_q[fi] = {}

        nn_gridPts[fi] = {}
        nn_gridDist[fi] = {}

        egrid_trun[fi] = {}

        q0[fi] = {}
        q[fi] = {}

        axis[fi] = {}
        omega[fi] = {}
        """ set proper iterator """
        if isinstance(yset, dict): it = yset[fi]
        else: it = yset

        for yi, y in enumerate(it):

            axis[fi][yi] = np.cross(fam, y)
            axis[fi][yi] = axis[fi][yi] / np.linalg.norm(axis[fi][yi],
                                                         axis=1)[:, None]
            omega[fi][yi] = np.arccos(np.dot(fam, y))

            q0[fi][yi] = {}
            q[fi][yi] = {}
            qf[yi] = {}
            qfib = np.zeros((len(phi), len(fam), 4))

            for hi, HxY in enumerate(axis[fi][yi]):

                q0[fi][yi][hi] = quat.normalize(
                    np.hstack([
                        np.cos(omega[fi][yi][hi] / 2),
                        np.sin(omega[fi][yi][hi] / 2) * HxY
                    ]))
                q[fi][yi][hi] = quat.normalize(
                    np.hstack([
                        cphi[:, np.newaxis],
                        np.tile(y, (len(cphi), 1)) * sphi[:, np.newaxis]
                    ]))

                qf[yi][hi] = quat.multiply(q[fi][yi][hi], q0[fi][yi][hi])

                for qi in range(qf[yi][hi].shape[0]):

                    qfib[qi, hi, :] = qf[yi][hi][qi, :]

            phi1, Phi, phi2 = quat2eu(qfib)

            phi1 = np.where(phi1 < 0, phi1 + 2 * np.pi,
                            phi1)  #brnng back to 0 - 2pi
            Phi = np.where(Phi < 0, Phi + np.pi, Phi)  #brnng back to 0 - pi
            phi2 = np.where(phi2 < 0, phi2 + 2 * np.pi,
                            phi2)  #brnng back to 0 - 2pi

            eu_fib = np.stack((phi1, Phi, phi2), axis=2)
            eu_fib = np.reshape(eu_fib, (eu_fib.shape[0] * eu_fib.shape[1],
                                         eu_fib.shape[2]))  #new method

            fz = (eu_fib[:, 0] <= od._phi1max) & (
                eu_fib[:, 1] <= od._Phimax) & (eu_fib[:, 2] <= od._phi2max)
            fz_idx = np.nonzero(fz)

            fibre_e[fi][yi] = eu_fib

            fib_idx = np.unravel_index(fz_idx[0],
                                       (qfib.shape[0], qfib.shape[1]))

            fibre_q[fi][yi] = qfib
            """ reduce geodesic query size """
            qfib_pos = np.copy(qfib[fib_idx])
            qfib_pos[qfib_pos[:, 0] < 0] *= -1

            query = np.concatenate(tree.query_radius(qfib_pos, euc_rad))
            query_uni = np.unique(query)
            qgrid_trun = qgrid[query_uni]
            qgrid_trun_idx = np.arange(len(qgrid))[
                query_uni]  #store indexes to retrieve original grid pts later
            """ distance calc """
            temp = quatMetricNumba(qgrid_trun, qfib[fib_idx])
            """ find tube """
            tube = (temp <= rad)
            temp = np.column_stack((np.argwhere(tube)[:, 0], temp[tube]))
            """ round very small values """
            temp = np.round(temp, decimals=7)
            """ move values at zero to very small (1E-5) """
            temp[:, 1] = np.where(temp[:, 1] == 0, 1E-5, temp[:, 1])
            """ sort by min distance """
            temp = temp[np.argsort(temp[:, 1], axis=0)]
            """ return unique pts (first in list) """
            uni_pts = np.unique(temp[:, 0], return_index=True)

            nn_gridPts[fi][yi] = qgrid_trun_idx[uni_pts[0].astype(int)]
            nn_gridDist[fi][yi] = temp[uni_pts[1], 1]

            # egrid_trun[fi][yi] = bungeAngs[query_uni]

    return nn_gridPts, nn_gridDist, fibre_e, axis, omega
Example #18
0
 ## h onto y
 q0[fi][yi] = np.hstack( [ np.cos(omega/2), np.sin(omega/2) * axis ] )
 ## around y
 q[fi][yi]  = np.hstack( [ cphi[:, np.newaxis], np.tile( y, (len(cphi),1) ) * sphi[:, np.newaxis] ] )
 
 
 fibre_e[fi][yi] = {}
 fibre_q[fi][yi] = {}
 tube_e[fi][yi]  = {}
 qf[fi][yi]      = {}
 
 ## loop through 
 for oi,offset in enumerate(offset_rots):
     
     #q0 then offset
     q0_t = quat.multiply(offset[None,:], q0[fi][yi])
 
     ## full fiber
     qf[fi][yi][oi] = quat.multiply(q[fi][yi], q0_t)
     
     qfib = quat.multiply(qf[fi][yi][oi], quatSymOps)
     qfib = qfib.transpose((1,0,2))        
     phi1, Phi, phi2 = quat2eu(qfib)
     
     phi1 = np.where(phi1 < 0, phi1 + 2*np.pi, phi1) #brnng back to 0 - 2pi
     Phi = np.where(Phi < 0, Phi + np.pi, Phi) #brnng back to 0 - pi
     phi2 = np.where(phi2 < 0, phi2 + 2*np.pi, phi2) #brnng back to 0 - 2pi
     eu_fib = np.stack( (phi1, Phi, phi2), axis=2 )
         
     #unique values based on rectilinear bunge box
     eu_fib = np.reshape( eu_fib, (eu_fib.shape[0]*eu_fib.shape[1], eu_fib.shape[2]) ) #new method       
Example #19
0
def _calcFibreHDF5(hfam, yset, omega, qgrid, od, h5fname, h5gname):

    fibre_e = {}
    fibre_q = {}

    nn_gridPts = {}
    nn_gridDist = {}

    f = _h5.File(h5fname, 'r+')
    grp = f.create_group(h5gname)
    fib_grp = grp.create_group('fibre')
    dist_grp = grp.create_group('dist')

    for yi, y in enumerate(yset):

        axis = _np.cross(hfam, y)
        angle = _np.arccos(_np.dot(hfam, y))

        q0 = _quat.from_axis_angle(axis, angle)
        q1 = [_quat.from_axis_angle(h, omega) for h in hfam]

        qfib = _np.zeros((len(q1[0]), len(q0), 4))

        for sym_eq, (qA, qB) in enumerate(zip(q0, q1)):

            temp = _quat.multiply(qA, qB)
            qfib[:, sym_eq, :] = temp

        phi1, Phi, phi2 = _quat2eu(qfib)

        phi1 = _np.where(phi1 < 0, phi1 + 2 * _np.pi,
                         phi1)  #brnng back to 0 - 2pi
        Phi = _np.where(Phi < 0, Phi + _np.pi, Phi)  #brnng back to 0 - pi
        phi2 = _np.where(phi2 < 0, phi2 + 2 * _np.pi,
                         phi2)  #brnng back to 0 - 2pi

        eu_fib = _np.stack((phi1, Phi, phi2), axis=2)
        eu_fib = _np.reshape(
            eu_fib,
            (eu_fib.shape[0] * eu_fib.shape[1], eu_fib.shape[2]))  #new method

        fz = (eu_fib[:, 0] < od._phi1max) & (eu_fib[:, 1] < od._Phimax) & (
            eu_fib[:, 2] < od._phi2max)
        fz_idx = _np.nonzero(fz)

        fibre_e[yi] = eu_fib[fz]

        fib_idx = _np.unravel_index(fz_idx[0], (qfib.shape[0], qfib.shape[1]))

        fibre_q[yi] = qfib[fib_idx]
        """ distance calc """
        temp = quatMetricNumba(qgrid, qfib[fib_idx])

        fib_grp.create_dataset(str(yi),
                               data=fibre_q[yi],
                               compression="gzip",
                               compression_opts=9)
        dist_grp.create_dataset(str(yi),
                                data=temp,
                                compression="gzip",
                                compression_opts=9)

        # """ find tube """
        # tube = (temp <= rad)
        # temp = _np.column_stack((_np.argwhere(tube)[:,0],temp[tube]))

        # """ round very small values """
        # temp = _np.round(temp, decimals=7)

        # """ move values at zero to very small (1E-5) """
        # temp[:,1] = _np.where(temp[:,1] == 0, 1E-5, temp[:,1])

        # """ sort by min distance """
        # temp = temp[_np.argsort(temp[:,1],axis=0)]
        # """ return unique pts (first in list) """
        # uni_pts = _np.unique(temp[:,0],return_index=True)

        # nn_gridPts[yi] = uni_pts[0]
        # nn_gridDist[yi] = temp[uni_pts[1],1]

    # return nn_gridPts, nn_gridDist, fibre_e, fibre_q
    f.close()
    return
Example #20
0
    def write(self, trajectory, file=sys.stdout):
        """Serialize a trajectory into pos-format and write it to file.

        :param trajectory: The trajectory to serialize
        :type trajectory: :class:`~garnett.trajectory.Trajectory`
        :param file: A file-like object."""
        def _write(msg, end='\n'):
            file.write(msg + end)

        for i, frame in enumerate(trajectory):
            # data section
            if frame.data is not None:
                header_keys = frame.data_keys
                _write('#[data] ', end='')
                _write(' '.join(header_keys))
                columns = list()
                for key in header_keys:
                    columns.append(frame.data[key])
                rows = np.array(columns).transpose()
                for row in rows:
                    _write(' '.join(row))
                _write('#[done]')

            # boxMatrix and rotation
            box_matrix = np.array(frame.box.get_box_matrix())
            if self._rotate and frame.view_rotation is not None:
                for i in range(3):
                    box_matrix[:, i] = rowan.rotate(frame.view_rotation,
                                                    box_matrix[:, i])

            if frame.view_rotation is not None and not self._rotate:
                angles = rowan.to_euler(frame.view_rotation,
                                        axis_type='extrinsic',
                                        convention='xyz') * 180 / math.pi
                _write('rotation ' + ' '.join((str(_num(_)) for _ in angles)))

            _write('boxMatrix ', end='')
            _write(' '.join((str(_num(v)) for v in box_matrix.flatten())))

            # shape defs
            try:
                if len(frame.types) != len(frame.type_shapes):
                    raise ValueError(
                        "Unequal number of types and type_shapes.")
                for name, type_shape in zip(frame.types, frame.type_shapes):
                    _write('def {} "{}"'.format(name, type_shape.pos_string))
            except AttributeError:
                # If AttributeError is raised because the frame does not contain
                # shape information, fill them all with the default shape
                for name in frame.types:
                    logger.info("No shape defined for '{}'. "
                                "Using fallback definition.".format(name))
                    _write('def {} "{}"'.format(
                        name, DEFAULT_SHAPE_DEFINITION.pos_string))

            # Orientations must be provided for all particles
            # If the frame does not have orientations, identity quaternions are used
            orientation = getattr(frame, 'orientation',
                                  np.array([[1, 0, 0, 0]] * frame.N))

            for typeid, pos, rot in zip(frame.typeid, frame.position,
                                        orientation):
                name = frame.types[typeid]
                _write(name, end=' ')
                try:
                    shapedef = frame.shapedef.get(name)
                except AttributeError:
                    shapedef = DEFAULT_SHAPE_DEFINITION

                if self._rotate and frame.view_rotation is not None:
                    pos = rowan.rotate(frame.view_rotation, pos)
                    rot = rowan.multiply(frame.view_rotation, rot)

                if isinstance(shapedef, SphereShape):
                    _write(' '.join((str(_num(v)) for v in pos)))
                elif isinstance(shapedef, ArrowShape):
                    # The arrow shape actually has two position vectors of
                    # three elements since it has start.{x,y,z} and end.{x,y,z}.
                    # That is, "rot" is not an accurate variable name, since it
                    # does not represent a quaternion.
                    _write(' '.join(
                        (str(_num(v)) for v in chain(pos, rot[:3]))))
                else:
                    _write(' '.join((str(_num(v)) for v in chain(pos, rot))))
            _write('eof')
            logger.debug("Wrote frame {}.".format(i + 1))
        logger.info("Wrote {} frames.".format(i + 1))
Example #21
0
def calcFibre(h, pf_y, omega):
    
    fibre_e = {}
    fibre_q = {}
    
    nn_gridPts = {}
    nn_gridDist = {}
    
    h_y = np.cross(h, pf_y)
    h_yAng = np.arccos(np.dot(pf_y, h))
    qh_y = np.column_stack((np.cos(h_yAng/2),np.sin(h_yAng/2)[:,None]*h_y))
    qh_y = quat.normalize(qh_y)
    
    qy_om = np.column_stack((np.cos(omega/2), np.sin(omega/2)))
    
#    qh_y = quat.vector_vector_rotation(h,pf_y)
#    qh_om = quat.from_axis_angle(h,omega)
    
    for yi,y in enumerate(pf_y):
        
        qy_om = np.column_stack((np.cos(omega/2), np.sin(omega/2)[:,None]*np.tile(y,(len(omega),1))))
        qy_om = quat.normalize(qy_om)
    
        qfib = quat.multiply(qy_om,qh_y[yi,:])
        
        """  reshape for tiling, simplify?? """
        
        qfib = qfib.T.reshape((1,4,len(omega)),order='F')
        qfib = np.tile(qfib,(quatSymOps.shape[1],1,1))
        qfib = qfib.transpose((2,0,1))
    
        """ apply symmetry """
    
        qfib = quat.multiply(quatSymOps,qfib)
        
        """ symmetry ops, then filter by given maximum bunge angles """
        
        phi1, Phi, phi2 = quat2eu(qfib)
            
        phi1 = np.where(phi1 < 0, phi1 + 2*np.pi, phi1) #brnng back to 0 - 2pi
        Phi = np.where(Phi < 0, Phi + np.pi, Phi) #brnng back to 0 - pi
        phi2 = np.where(phi2 < 0, phi2 + 2*np.pi, phi2) #brnng back to 0 - 2pi
        
        eu_fib = np.stack( (phi1, Phi, phi2), axis=2 )
        eu_fib = np.reshape( eu_fib, (eu_fib.shape[0]*eu_fib.shape[1], eu_fib.shape[2]) )
        
        fz = (eu_fib[:,0] < od._phi1max) & (eu_fib[:,1] < od._Phimax) & (eu_fib[:,2] < od._phi2max)
        fz_idx = np.nonzero(fz)
        
        fibre_e[yi] = eu_fib[fz]

        fib_idx = np.unravel_index(fz_idx[0], (qfib.shape[0],qfib.shape[1]))
        
        fibre_q[yi] = qfib[fib_idx].reshape((len(fz_idx[0]),4))
        
        """ distance calc """
        temp = quatMetricNumba(qgrid,qfib[fib_idx])
        """ find tube """
        tube = (temp <= rad)
        temp = np.column_stack((np.argwhere(tube)[:,0],temp[tube]))
        """ sort by min distance """
        temp = temp[np.argsort(temp[:,1],axis=0)]
        """ return unique pts (first in list) """
        uni_pts = np.unique(temp[:,0],return_index=True)

        nn_gridPts[yi] = uni_pts[0]
        nn_gridDist[yi] = temp[uni_pts[1],1]
        
    return nn_gridPts, nn_gridDist, fibre_e
Example #22
0
 axis[fi] = {}
 omega[fi] = {}
 
 """ set proper iterator """
 if isinstance(xyz_pf,dict): it = xyz_pf[fi]
 else: it = xyz_pf
 
 for yi,y in enumerate(it): 
     
     axis[fi][yi] = np.cross(fam,y)
     axis[fi][yi] = axis[fi][yi] / np.linalg.norm(axis[fi][yi],axis=-1)
     omega[fi][yi] = np.arccos(np.dot(fam,y))
     
     q0[fi][yi] = np.hstack( [ np.cos(omega[fi][yi]/2), np.sin(omega[fi][yi]/2) * axis[fi][yi] ] )
     q[fi][yi]  = np.hstack( [ cphi[:, np.newaxis], np.tile( y, (len(cphi),1) ) * sphi[:, np.newaxis] ] )
     qf[fi][yi] = quat.multiply(q[fi][yi], q0[fi][yi])
     
     q_tubeTest[fi][yi] = quat.multiply(qf[fi][yi],quat.from_axis_angle((1,1,0), theta))
     # qfib = quat.multiply(quatSymOps, qf[yi])
     qfib = quat.multiply(qf[fi][yi], quatSymOps)
     qfib = qfib.transpose((1,0,2))
     
     phi1, Phi, phi2 = quat2eu(qfib)
     
     qtube = quat.multiply(q_tubeTest[fi][yi], quatSymOps)
     qtube = qtube.transpose((1,0,2))
     
     phi1_t, Phi_t, phi2_t = quat2eu(qtube)
     
     # q0[fi][yi] = {}
     # q[fi][yi] = {}
Example #23
0
def _regularize_box(position,
                    velocity,
                    orientation,
                    angmom,
                    box_matrix,
                    dtype=None,
                    dimensions=3):
    """Convert box into a right-handed coordinate frame with
    only upper triangular entries. Also convert corresponding
    positions and orientations."""
    # First use QR decomposition to compute the new basis
    Q, R = np.linalg.qr(box_matrix)
    Q = Q.astype(dtype)
    R = R.astype(dtype)

    if not np.allclose(Q[:dimensions, :dimensions], np.eye(dimensions)):
        # If Q is not the identity matrix, then we will be
        # changing data, so we have to copy. This only causes
        # actual failures for non-writeable GSD frames, but could
        # cause unexpected data corruption for other cases
        position = np.copy(position)
        if orientation is not None:
            orientation = np.copy(orientation)
        if velocity is not None:
            velocity = np.copy(velocity)
        if angmom is not None:
            angmom = np.copy(angmom)

        # Since we'll be performing a quaternion operation,
        # we have to ensure that Q is a pure rotation
        sign = np.linalg.det(Q)
        Q = Q * sign
        R = R * sign

        # First rotate positions, velocities.
        # Since they are vectors, we can use the matrix directly.
        # Conveniently, instead of transposing Q we can just reverse
        # the order of multiplication here
        position = position.dot(Q)
        if velocity is not None:
            velocity = velocity.dot(Q)

        # For orientations and angular momenta, we use the quaternion
        quat = rowan.from_matrix(Q.T)
        if orientation is not None:
            for i in range(orientation.shape[0]):
                orientation[i, :] = rowan.multiply(quat, orientation[i, :])
        if angmom is not None:
            for i in range(angmom.shape[0]):
                angmom[i, :] = rowan.multiply(quat, angmom[i, :])

        # Now we have to ensure that the box is right-handed. We
        # do this as a second step to avoid introducing reflections
        # into the rotation matrix before making the quaternion
        signs = np.diag(
            np.diag(np.where(R < 0, -np.ones(R.shape), np.ones(R.shape))))
        box = R.dot(signs)
        position = position.dot(signs)
        if velocity is not None:
            velocity = velocity.dot(signs)
    else:
        box = box_matrix

    # Construct the box
    Lx, Ly, Lz = np.diag(box).flatten().tolist()
    xy = box[0, 1] / Ly
    xz = box[0, 2] / Lz
    yz = box[1, 2] / Lz
    box = Box(Lx=Lx, Ly=Ly, Lz=Lz, xy=xy, xz=xz, yz=yz, dimensions=dimensions)
    return position, velocity, orientation, angmom, box
Example #24
0
def quatquat(qi, qj):
    """Multiplies the quaternions in the array qi by those in qj"""
    return rowan.multiply(qi, qj)
Example #25
0
    print("Diagonal Inertia Inverse:\n ", DiagonalInertiaInverse)
    #Frame changes
    print("To Body COM Frame", ToBodyFrame(ToCOM(Position[0])))
    print("Original Position[0]",
          ToOrigin(ToLabFrame(ToBodyFrame(ToCOM(
              Position[0])))))  #note correct order of frame changes
    #Solve for OmegaDot and Omega
    Omega = [0, 0, 1]
    #Torque = [0,0,1] #gets confused with "Torque" function later
    #Rotation with quaternions
    print("Omega as Quat:\n", l_m.VectorToQuat(Omega))
    print("New Principal Basis:\n", RungeKuttaOrient(Omega, PrincipalBasis))
    print("Multiply:\n",
          l_m.QuatMultiply(l_m.VectorToQuat(Omega), np.array([1, 2, 3, 4])))
    print("Alternate Multiply:\n",
          quat.multiply(l_m.VectorToQuat(Omega), np.array([1, 2, 3, 4])))

#actual sim stuff
Step = 0

#QUESTION all this initializatios stuff should be in a function
#Initial Conditions; data to be stored through simulation
InitialOmega = np.array(
    [0, 0, 0]
)  #This seems to be a good inital condition so that things don't weirdly drift off in y direction (about 10^-9m scale)
#[0,0,0.01] was used because in an earlier version of the simulation, they would just annihilate
AllOmegas = np.zeros((TotalSteps + 1, 3))
AllOmegas[0] = InitialOmega
#print("All Omegas:\n", AllOmegas)
AllHCPositions = []
AllHCPositions.append(1 * HydrodymanicCenter)
Example #26
0
    for fi,fam in enumerate(pf.symHKL):
        
        axis = np.cross(fam,v)
        angle = np.arccos(np.dot(fam,v))
        
        q0 = rowan.from_axis_angle(axis, angle)
        q0_n = rowan.normalize(q0) 
        
        q1_n = [rowan.normalize(rowan.from_axis_angle(h, omega)) for h in fam]
        
         # eu = np.zeros((len(omega),3,fam.shape[0]))
        eu = []
        
        for i,(qA,qB) in enumerate(zip(q0_n,q1_n)):
            
            qF = rowan.multiply(qA, qB)
            
            with np.errstate(divide='ignore'):

                temp = np.array((qF[:,1]/qF[:,0],qF[:,2]/qF[:,0],qF[:,3]/qF[:,0])).T
                ax = ro2ax(temp)
                om = ax2om(ax)
                eu.append(om2eu(om))
                
        ro_h[fi] = np.vstack(eu)
        
    ro_y[yi] = ro_h
    yi += 1
    
# %% 
            
Example #27
0
def calcFibre(symHKL, yset, qgrid, omega, rad, tree, euc_rad):

    fibre_e = {}
    fibre_q = {}

    nn_gridPts = {}
    nn_gridDist = {}

    egrid_trun = {}

    for fi, fam in enumerate(tqdm(symHKL)):

        fibre_e[fi] = {}
        fibre_q[fi] = {}

        nn_gridPts[fi] = {}
        nn_gridDist[fi] = {}

        egrid_trun[fi] = {}
        """ set proper iterator """
        if isinstance(yset, dict): it = yset[fi]
        else: it = yset

        q1_n = [quat.from_axis_angle(h, omega) for h in fam]

        for yi, y in enumerate(it):

            axis = np.cross(fam, y)
            angle = np.arccos(np.dot(fam, y))

            q0_n = quat.from_axis_angle(axis, angle)
            # q0_n = quat.normalize(q0)

            qfib = np.zeros((len(q1_n[0]), len(q0_n), 4))

            for sym_eq, (qA, qB) in enumerate(zip(q0_n, q1_n)):

                temp = quat.multiply(qA, qB)

                qfib[:, sym_eq, :] = temp

            phi1, Phi, phi2 = quat2eu(qfib)

            phi1 = np.where(phi1 < 0, phi1 + 2 * np.pi,
                            phi1)  #brnng back to 0 - 2pi
            Phi = np.where(Phi < 0, Phi + np.pi, Phi)  #brnng back to 0 - pi
            phi2 = np.where(phi2 < 0, phi2 + 2 * np.pi,
                            phi2)  #brnng back to 0 - 2pi

            eu_fib = np.stack((phi1, Phi, phi2), axis=2)
            eu_fib = np.reshape(eu_fib, (eu_fib.shape[0] * eu_fib.shape[1],
                                         eu_fib.shape[2]))  #new method

            fz = (eu_fib[:, 0] <= od._phi1max) & (
                eu_fib[:, 1] <= od._Phimax) & (eu_fib[:, 2] <= od._phi2max)
            fz_idx = np.nonzero(fz)

            fibre_e[fi][yi] = eu_fib[fz]

            fib_idx = np.unravel_index(fz_idx[0],
                                       (qfib.shape[0], qfib.shape[1]))

            fibre_q[fi][yi] = qfib[fib_idx]

            # """ reduce geodesic query size """
            # qfib_pos = np.copy(qfib[fib_idx])
            # qfib_pos[qfib_pos[:,0] < 0] *= -1

            # query = np.concatenate(tree.query_radius(qfib_pos,euc_rad))
            # query_uni = np.unique(query)
            # qgrid_trun = qgrid[query_uni]
            # qgrid_trun_idx = np.arange(len(qgrid))[query_uni] #store indexes to retrieve original grid pts later
            """ distance calc """
            temp = quatMetricNumba(qgrid, qfib[fib_idx])
            """ find tube """
            tube = (temp <= rad)
            temp = np.column_stack((np.argwhere(tube)[:, 0], temp[tube]))
            """ round very small values """
            temp = np.round(temp, decimals=7)
            """ move values at zero to very small (1E-5) """
            temp[:, 1] = np.where(temp[:, 1] == 0, 1E-5, temp[:, 1])
            """ sort by min distance """
            temp = temp[np.argsort(temp[:, 1], axis=0)]
            """ return unique pts (first in list) """
            uni_pts = np.unique(temp[:, 0], return_index=True)

            nn_gridPts[fi][yi] = uni_pts[0].astype(int)
            nn_gridDist[fi][yi] = temp[uni_pts[1], 1]

            # egrid_trun[fi][yi] = bungeAngs[query_uni]

    return nn_gridPts, nn_gridDist, fibre_e
Example #28
0
    def get_basis_vectors(self,
                          base_positions,
                          base_type=[],
                          base_quaternions=None,
                          is_complete=False,
                          apply_orientation=False):
        """Get the basis vectors for the defined crystall structure.

        :param base_positions:
            N by 3 np array of the Wyckoff postions
        :type base_positions:
            np.ndarray
        :param base_type:
            a list of string for particle type name
        :type base_type:
            list
        :param base_quaternions:
            N by 4 np array of quaternions, default None
        :type base_quaternions:
            np.ndarray
        :param is_complete:
            bool value to indicate if the positions are complete postions in a unitcell
        :type is_complete:
            bool
        :param apply_orientations:
            bool value to indicate if the space group symmetry should be applied to orientatioin
        :type apply_orientations:
            bool
        :return:
            basis_vectors
        :rtype:
            np.ndarray
        """

        # check input accuracy
        if not isinstance(base_positions, np.ndarray) or len(base_positions.shape) == 1 \
           or base_positions.shape[1] != 3:
            raise ValueError(
                'base_positions must be an numpy array of shape Nx3')
        if apply_orientation:
            if not isinstance(base_quaternions, np.ndarray) or len(base_quaternions.shape) == 1 \
               or base_quaternions.shape[1] != 4:
                raise ValueError(
                    'base_quaternions must be an numpy array of shape Nx4')
        if len(base_type):
            if not isinstance(base_type, list) or len(base_type) != base_positions.shape[0] \
               or not all(isinstance(i, str) for i in base_type):
                raise ValueError(
                    'base_type must contain a list of type name the same length'
                    'as the number of basis positions')
        else:
            base_type = ['A'] * base_positions.shape[0]

        threshold = 1e-6
        reflection_exist = False
        for i in range(0, len(self.rotations)):
            # Generate the new set of positions from the base
            pos = wrap(self.rotations[i].dot(base_positions.T).T +
                       self.translations[i])
            if apply_orientation:
                if np.linalg.det(self.rotations[i]) == 1:
                    quat_rotate = rowan.from_matrix(self.rotations[i],
                                                    require_orthogonal=False)
                    quat = rowan.multiply(quat_rotate, base_quaternions)
                else:
                    quat = base_quaternions
                    reflection_exist = True

            if i == 0:
                positions = pos
                type_list = copy.deepcopy(base_type)
                if apply_orientation:
                    quaternions = quat
            else:
                pos_comparisons = pos - positions[:, np.newaxis, :]
                norms = np.linalg.norm(pos_comparisons, axis=2)
                comps = np.all(norms > threshold, axis=0)
                positions = np.append(positions, pos[comps], axis=0)
                type_list += [x for x, y in zip(base_type, comps) if y]
                if apply_orientation:
                    quaternions = np.append(quaternions, quat[comps], axis=0)
                    if norms.min() < threshold:
                        print(
                            'Orientation quaterions may have multiple values for the same '
                            'particle postion under the symmetry operation for this space group '
                            'and is not well defined, only the first occurance is used.'
                        )
        if reflection_exist:
            print(
                'Warning: reflection operation is included in this space group, '
                'and is ignored for quaternion calculation.')

        if is_complete and len(positions) != len(base_positions):
            raise ValueError(
                'the complete basis postions vector does not match the space group '
                'chosen. More positions are generated based on the symmetry operation '
                'within the provided space group')

        if apply_orientation:
            return wrap(positions), type_list, quaternions
        else:
            return wrap(positions), type_list
Example #29
0
 # brass_y2[:,:,yi] = by
 HxY[yi] = np.cross(symHKL[0],by)
 HxY[yi] = HxY[yi] / np.linalg.norm(HxY[yi],axis=1)[:,None]
 ome[yi] = np.arccos(np.dot(symHKL[0],by))
 
 q0[yi] = {}
 q[yi] = {}
 qf[yi] = {}
 fibre_marc[yi] = np.zeros_like(brassFibre[yi])
 
 for hi,h in enumerate(HxY[yi]):
     
     q0[yi][hi] = quat.normalize(np.hstack( [ np.cos(ome[yi][hi]/2), np.sin(ome[yi][hi]/2) * h ] ))
     q[yi][hi]  = quat.normalize(np.hstack( [ cphi[:, np.newaxis], np.tile( by, (len(cphi),1) ) * sphi[:, np.newaxis] ] ))
     
     qf[yi][hi] = quat.multiply(q[yi][hi], q0[yi][hi])
 
     for qi in range(qf[yi][hi].shape[0]):
         
         fibre_marc[yi][qi,hi,:] = qf[yi][hi][qi,:]
         
 phi1, Phi, phi2 = quat2eu(fibre_marc[yi])
 
 phi1 = np.where(phi1 < 0, phi1 + 2*np.pi, phi1) #brnng back to 0 - 2pi
 Phi = np.where(Phi < 0, Phi + np.pi, Phi) #brnng back to 0 - pi
 phi2 = np.where(phi2 < 0, phi2 + 2*np.pi, phi2) #brnng back to 0 - 2pi
 
 eu_fib = np.stack( (phi1, Phi, phi2), axis=2 )
 fibre_marc_e[yi] = np.reshape( eu_fib, (eu_fib.shape[0]*eu_fib.shape[1], eu_fib.shape[2]) ) #new method    
 
 eu_fib = np.reshape( eu_fib, (eu_fib.shape[0]*eu_fib.shape[1], eu_fib.shape[2]) ) #new method