コード例 #1
0
ファイル: molecule.py プロジェクト: yuhangwang/zeobuilder
        def add_hydrogens(atom):
            existing_bonds = list(atom.iter_bonds())
            bond_length = bonds.get_length(atom.number, 1, BOND_SINGLE)
            num_hydrogens = self.parameters.num_hydrogens

            if len(existing_bonds) == 0:
                t = atom.transformation.t + numpy.array([0, bond_length, 0])
                H = Atom(name="auto H",
                         number=1,
                         transformation=Translation(t))
                primitive.Add(H, atom.parent)
                bond = Bond(name="aut H bond", targets=[atom, H])
                primitive.Add(bond, atom.parent)
                existing_bonds.append(bond)
                num_hydrogens -= 1

            main_direction = numpy.zeros(3, float)
            for bond in existing_bonds:
                shortest_vector = bond.shortest_vector_relative_to(atom.parent)
                if bond.children[1].target == atom:
                    shortest_vector *= -1
                main_direction += shortest_vector

            main_direction /= numpy.linalg.norm(main_direction)
            normal = random_orthonormal(main_direction)

            rotation = Rotation.from_properties(
                2 * numpy.pi / float(num_hydrogens), main_direction, False)

            h_pos = bond_length * (
                main_direction * numpy.cos(self.parameters.valence_angle) +
                normal * numpy.sin(self.parameters.valence_angle))

            for i in range(num_hydrogens):
                t = atom.transformation.t + h_pos
                H = Atom(name="auto H",
                         number=1,
                         transformation=Translation(t))
                primitive.Add(H, atom.parent)
                bond = Bond(name="aut H bond", targets=[atom, H])
                primitive.Add(bond, atom.parent)
                h_pos = rotation * h_pos
コード例 #2
0
ファイル: molecule.py プロジェクト: molmod/zeobuilder
        def add_hydrogens(atom):
            existing_bonds = list(atom.iter_bonds())
            bond_length = bonds.get_length(atom.number, 1, BOND_SINGLE)
            num_hydrogens = self.parameters.num_hydrogens

            if len(existing_bonds) == 0:
                t = atom.transformation.t + numpy.array([0,bond_length,0])
                H = Atom(name="auto H", number=1, transformation=Translation(t))
                primitive.Add(H, atom.parent)
                bond = Bond(name="aut H bond", targets=[atom, H])
                primitive.Add(bond, atom.parent)
                existing_bonds.append(bond)
                num_hydrogens -= 1

            main_direction = numpy.zeros(3, float)
            for bond in existing_bonds:
                shortest_vector = bond.shortest_vector_relative_to(atom.parent)
                if bond.children[1].target == atom:
                    shortest_vector *= -1
                main_direction += shortest_vector

            main_direction /= numpy.linalg.norm(main_direction)
            normal = random_orthonormal(main_direction)

            rotation = Rotation.from_properties(2*numpy.pi / float(num_hydrogens), main_direction, False)


            h_pos = bond_length*(
                main_direction*numpy.cos(self.parameters.valence_angle) +
                normal*numpy.sin(self.parameters.valence_angle)
            )

            for i in range(num_hydrogens):
                t = atom.transformation.t + h_pos
                H = Atom(name="auto H", number=1, transformation=Translation(t))
                primitive.Add(H, atom.parent)
                bond = Bond(name="aut H bond", targets=[atom, H])
                primitive.Add(bond, atom.parent)
                h_pos = rotation * h_pos
コード例 #3
0
ファイル: molecule.py プロジェクト: yuhangwang/zeobuilder
        def add_hydrogens(atom):
            existing_bonds = list(atom.iter_bonds())
            num_bonds = len(existing_bonds)
            bond_length = bonds.get_length(atom.number, 1, BOND_SINGLE)

            if num_bonds == 0:
                t = atom.transformation.t + numpy.array([0, bond_length, 0])
                H = Atom(name="auto H",
                         number=1,
                         transformation=Translation(t))
                primitive.Add(H, atom.parent)
                bond = Bond(name="aut H bond", targets=[atom, H])
                primitive.Add(bond, atom.parent)
                existing_bonds.append(bond)
                num_bonds = 1

            used_valence = 0
            oposite_direction = numpy.zeros(3, float)
            for bond in existing_bonds:
                shortest_vector = bond.shortest_vector_relative_to(atom.parent)
                if bond.children[1].target == atom:
                    shortest_vector *= -1
                oposite_direction -= shortest_vector

                if bond.bond_type == BOND_SINGLE:
                    used_valence += 1
                elif bond.bond_type == BOND_DOUBLE:
                    used_valence += 2
                elif bond.bond_type == BOND_TRIPLE:
                    used_valence += 3

            oposite_direction /= numpy.linalg.norm(oposite_direction)

            num_hydrogens = valence_el(
                atom.number) - 2 * lone_pairs(atom.number) - used_valence
            if num_hydrogens <= 0:
                return

            hybride_count = num_hydrogens + lone_pairs(
                atom.number) + num_bonds - (used_valence - num_bonds)
            num_sites = num_hydrogens + lone_pairs(atom.number)
            rotation = Rotation.from_properties(
                2 * numpy.pi / float(num_sites), oposite_direction, False)
            opening_key = (hybride_count, num_sites)
            opening_angle = self.opening_angles.get(opening_key)
            if opening_angle is None:
                return

            if num_bonds == 1:
                first_bond = existing_bonds[0]
                other_atom = first_bond.children[0].target
                if other_atom == atom:
                    other_atom = first_bond.children[1].target
                other_bonds = [
                    bond for bond in other_atom.iter_bonds()
                    if bond != first_bond
                ]
                if len(other_bonds) > 0:
                    normal = other_bonds[0].shortest_vector_relative_to(
                        atom.parent)
                    normal -= numpy.dot(normal,
                                        oposite_direction) * oposite_direction
                    normal /= numpy.linalg.norm(normal)
                    if other_bonds[0].children[0].target == other_atom:
                        normal *= -1
                else:
                    normal = random_orthonormal(oposite_direction)
            elif num_bonds == 2:
                normal = numpy.cross(
                    oposite_direction,
                    existing_bonds[0].shortest_vector_relative_to(atom.parent))
                normal /= numpy.linalg.norm(normal)
            elif num_bonds == 3:
                normal = random_orthonormal(oposite_direction)
            else:
                return

            h_pos = bond_length * (oposite_direction * numpy.cos(opening_angle)
                                   + normal * numpy.sin(opening_angle))

            for i in range(num_hydrogens):
                t = atom.transformation.t + h_pos
                H = Atom(name="auto H",
                         number=1,
                         transformation=Translation(t))
                primitive.Add(H, atom.parent)
                bond = Bond(name="aut H bond", targets=[atom, H])
                primitive.Add(bond, atom.parent)
                h_pos = rotation * h_pos
コード例 #4
0
ファイル: sketch.py プロジェクト: yuhangwang/zeobuilder
    def replace(self, gl_object):
        if not gl_object.get_fixed():
            new = self.get_new(gl_object.transformation.t)

            # select a target object, i.e. the one the will be connected with
            # the bonds/vectors/... of the replaced object
            if (self.current_object == "Fragment"):
                # fragments are inserted as frames
                # take atom with index 1 as target
                target_object = new.children[1]
            else:
                target_object = new
            # check if all connections to the replaced object are applicable
            # to the new object. if not, then do not perform the replacement
            # and return early.
            for reference in gl_object.references[::-1]:
                if not reference.check_target(target_object):
                    return
            # add the new object
            parent = gl_object.parent
            primitive.Add(new, parent)

            if (self.current_object == "Fragment"):
                # Fix the rotation and translation of the molecular fragment.
                # Rotation
                Bond = context.application.plugins.get_node("Bond")
                if len(gl_object.references) == 1 and isinstance(
                        gl_object.references[0].parent, Bond):
                    bond1 = gl_object.references[0].parent
                    direction1 = bond1.shortest_vector_relative_to(parent)
                    if bond1.children[0].target != gl_object:
                        direction1 *= -1
                    bond2 = new.children[0].references[0].parent
                    direction2 = bond2.shortest_vector_relative_to(parent)
                    if bond2.children[0].target != target_object:
                        direction2 *= -1
                    axis = numpy.cross(direction2, direction1)
                    if numpy.linalg.norm(axis) < 1e-8:
                        axis = random_orthonormal(direction1)
                    angle = compute_angle(direction1, direction2)
                    rotation = Rotation.from_properties(angle, axis, False)
                    primitive.Transform(new, rotation)
                else:
                    bond1 = None
                # Tranlsation
                pos_old = new.children[1].get_frame_relative_to(parent).t
                pos_new = gl_object.transformation.t
                translation = Translation(pos_new - pos_old)
                primitive.Transform(new, translation)
                if bond1 != None:
                    # bond length
                    old_length = numpy.linalg.norm(direction1)
                    new_length = bonds.get_length(
                        new.children[1].number,
                        bond1.get_neighbor(gl_object).number)
                    translation = Translation(-direction1 / old_length *
                                              (new_length - old_length))
                    primitive.Transform(new, translation)

            # let the references to the replaced object point to the new object
            for reference in gl_object.references[::-1]:
                try:
                    primitive.SetTarget(reference, target_object)
                except primitive.PrimitiveError:
                    primitive.Delete(reference.parent)
            # delete the replaced object
            primitive.Delete(gl_object)
            if (self.current_object == "Fragment"):
                # Delete the first atom in the fragment
                primitive.Delete(new.children[0])
                # Unframe the fragment
                UnframeAbsolute = context.application.plugins.get_action(
                    "UnframeAbsolute")
                UnframeAbsolute([new])
コード例 #5
0
    def compute_transformation(self, connection):
        #print connection.pairs
        triangle1 = connection.triangle1
        triangle2 = connection.triangle2

        triangles = [triangle1, triangle2]

        #print "BEFORE TRANSFORMING\n"
        #for triangle in triangles:
        #    #print "-------"
        #    for coordinate in triangle.coordinates:
        #        #print coordinate
        #print "---------"

        # *** t1: translation of triangle in geometry2 to origin
        t1 = Translation(-triangle2.center)
        #print triangle2.center
        triangle2.apply_to_coordinates(t1)
        # also move triangle1 to the origin
        t_tmp = Translation(-triangle1.center)  # was t0
        triangle1.apply_to_coordinates(t_tmp)
        #print "AFTER CENTERING (T1 and T0)"
        #for triangle in triangles:
        #    #print "-------"
        #    for coordinate in triangle.coordinates:
        #        #print coordinate

        # *** r2: make the two triangles coplanar
        #print "NORMALS"
        #print triangle1.normal
        #print triangle2.normal
        rotation_axis = numpy.cross(triangle2.normal, triangle1.normal)
        if numpy.dot(rotation_axis, rotation_axis) < 1e-8:
            rotation_axis = random_orthonormal(triangle2.normal)
        rotation_angle = angle(triangle2.normal, triangle1.normal)
        #print "R2 %s, %s" % (rotation_angle/numpy.pi*180, rotation_axis)
        r2 = Rotation.from_properties(rotation_angle, rotation_axis, False)
        triangle2.apply_to_coordinates(r2)
        #print "AFTER R2"
        #for triangle in triangles:
        #    #print "-------"
        #    for coordinate in triangle.coordinates:
        #        #print coordinate

        # bring both triangles in the x-y plane, by a rotation around an axis
        # orthogonal to the Z-axis.
        rotation_axis = numpy.array(
            [triangle1.normal[1], -triangle1.normal[0], 0.0], float)
        if numpy.dot(rotation_axis, rotation_axis) < 1e-8:
            rotation_axis = numpy.array([1.0, 0.0, 0.0], float)
        cos_angle = triangle1.normal[2]
        if cos_angle >= 1.0: rotation_angle = 0
        elif cos_angle <= -1.0: rotation_angle = numpy.pi
        else: rotation_angle = numpy.arccos(cos_angle)
        #print "RT %s, %s" % (rotation_angle/numpy.pi*180, rotation_axis)
        r_flat = Rotation.from_properties(rotation_angle, rotation_axis, False)
        triangle1.apply_to_coordinates(r_flat)
        triangle2.apply_to_coordinates(r_flat)

        #print "AFTER RT"
        #for triangle in triangles:
        #    #print "-------"
        #    for coordinate in triangle.coordinates:
        #        #print coordinate

        # *** r3: second rotation that makes both triangle coinced
        H = lambda a, b, c, d: a * c + b * d + (a + b) * (c + d)
        c = (H(triangle1.coordinates[0][0], triangle1.coordinates[1][0],
               triangle2.coordinates[0][0], triangle2.coordinates[1][0]) +
             H(triangle1.coordinates[0][1], triangle1.coordinates[1][1],
               triangle2.coordinates[0][1], triangle2.coordinates[1][1]))
        s = (H(triangle1.coordinates[0][1], triangle1.coordinates[1][1],
               triangle2.coordinates[0][0], triangle2.coordinates[1][0]) -
             H(triangle1.coordinates[0][0], triangle1.coordinates[1][0],
               triangle2.coordinates[0][1], triangle2.coordinates[1][1]))
        #if c > s: c, s = -c, -s
        #print "cos=%f sin=%f" % (c, s)
        rotation_angle = numpy.arctan2(s, c)
        #print "R3 %s, %s" % (rotation_angle/numpy.pi*180, triangle1.normal)
        r3 = Rotation.from_properties(rotation_angle, triangle1.normal, False)
        r_tmp = Rotation.from_properties(rotation_angle,
                                         numpy.array([0, 0, 1], float), False)
        triangle2.apply_to_coordinates(r_tmp)
        #print "AFTER R3"
        #for triangle in triangles:
        #    #print "-------"
        #    for coordinate in triangle.coordinates:
        #        #print coordinate

        # t4: translate the triangle to the definitive coordinate
        t4 = Translation(triangle1.center)
        #print "AFTER T4"
        #for triangle in triangles:
        #    #print "-------"
        #    for coordinate in triangle.coordinates:
        #        #print coordinate

        return t4 * r3 * r2 * t1
コード例 #6
0
ファイル: sketch.py プロジェクト: molmod/zeobuilder
    def replace(self, gl_object):
        if not gl_object.get_fixed():
            new = self.get_new(gl_object.transformation.t)

            # select a target object, i.e. the one the will be connected with
            # the bonds/vectors/... of the replaced object
            if(self.current_object == "Fragment"):
                # fragments are inserted as frames
                # take atom with index 1 as target
                target_object = new.children[1]
            else:
                target_object = new
            # check if all connections to the replaced object are applicable
            # to the new object. if not, then do not perform the replacement
            # and return early.
            for reference in gl_object.references[::-1]:
                if not reference.check_target(target_object):
                    return
            # add the new object
            parent = gl_object.parent
            primitive.Add(new, parent)

            if(self.current_object == "Fragment"):
                # Fix the rotation and translation of the molecular fragment.
                # Rotation
                Bond = context.application.plugins.get_node("Bond")
                if len(gl_object.references) == 1 and isinstance(gl_object.references[0].parent, Bond):
                    bond1 = gl_object.references[0].parent
                    direction1 = bond1.shortest_vector_relative_to(parent)
                    if bond1.children[0].target != gl_object:
                        direction1 *= -1
                    bond2 = new.children[0].references[0].parent
                    direction2 = bond2.shortest_vector_relative_to(parent)
                    if bond2.children[0].target != target_object:
                        direction2 *= -1
                    axis = numpy.cross(direction2, direction1)
                    if numpy.linalg.norm(axis) < 1e-8:
                        axis = random_orthonormal(direction1)
                    angle = compute_angle(direction1, direction2)
                    rotation = Rotation.from_properties(angle, axis, False)
                    primitive.Transform(new, rotation)
                else:
                    bond1 = None
                # Tranlsation
                pos_old = new.children[1].get_frame_relative_to(parent).t
                pos_new = gl_object.transformation.t
                translation = Translation(pos_new - pos_old)
                primitive.Transform(new, translation)
                if bond1 != None:
                    # bond length
                    old_length = numpy.linalg.norm(direction1)
                    new_length = bonds.get_length(new.children[1].number, bond1.get_neighbor(gl_object).number)
                    translation = Translation(-direction1/old_length*(new_length-old_length))
                    primitive.Transform(new, translation)

            # let the references to the replaced object point to the new object
            for reference in gl_object.references[::-1]:
                try:
                    primitive.SetTarget(reference, target_object)
                except primitive.PrimitiveError:
                    primitive.Delete(reference.parent)
            # delete the replaced object
            primitive.Delete(gl_object)
            if(self.current_object == "Fragment"):
                # Delete the first atom in the fragment
                primitive.Delete(new.children[0])
                # Unframe the fragment
                UnframeAbsolute = context.application.plugins.get_action("UnframeAbsolute")
                UnframeAbsolute([new])
コード例 #7
0
ファイル: triangle.py プロジェクト: mszep/zeobuilder
    def compute_transformation(self, connection):
        # print connection.pairs
        triangle1 = connection.triangle1
        triangle2 = connection.triangle2

        triangles = [triangle1, triangle2]

        # print "BEFORE TRANSFORMING\n"
        # for triangle in triangles:
        #    #print "-------"
        #    for coordinate in triangle.coordinates:
        #        #print coordinate
        # print "---------"

        # *** t1: translation of triangle in geometry2 to origin
        t1 = Translation(-triangle2.center)
        # print triangle2.center
        triangle2.apply_to_coordinates(t1)
        # also move triangle1 to the origin
        t_tmp = Translation(-triangle1.center)  # was t0
        triangle1.apply_to_coordinates(t_tmp)
        # print "AFTER CENTERING (T1 and T0)"
        # for triangle in triangles:
        #    #print "-------"
        #    for coordinate in triangle.coordinates:
        #        #print coordinate

        # *** r2: make the two triangles coplanar
        # print "NORMALS"
        # print triangle1.normal
        # print triangle2.normal
        rotation_axis = numpy.cross(triangle2.normal, triangle1.normal)
        if numpy.dot(rotation_axis, rotation_axis) < 1e-8:
            rotation_axis = random_orthonormal(triangle2.normal)
        rotation_angle = angle(triangle2.normal, triangle1.normal)
        # print "R2 %s, %s" % (rotation_angle/numpy.pi*180, rotation_axis)
        r2 = Rotation.from_properties(rotation_angle, rotation_axis, False)
        triangle2.apply_to_coordinates(r2)
        # print "AFTER R2"
        # for triangle in triangles:
        #    #print "-------"
        #    for coordinate in triangle.coordinates:
        #        #print coordinate

        # bring both triangles in the x-y plane, by a rotation around an axis
        # orthogonal to the Z-axis.
        rotation_axis = numpy.array([triangle1.normal[1], -triangle1.normal[0], 0.0], float)
        if numpy.dot(rotation_axis, rotation_axis) < 1e-8:
            rotation_axis = numpy.array([1.0, 0.0, 0.0], float)
        cos_angle = triangle1.normal[2]
        if cos_angle >= 1.0:
            rotation_angle = 0
        elif cos_angle <= -1.0:
            rotation_angle = numpy.pi
        else:
            rotation_angle = numpy.arccos(cos_angle)
        # print "RT %s, %s" % (rotation_angle/numpy.pi*180, rotation_axis)
        r_flat = Rotation.from_properties(rotation_angle, rotation_axis, False)
        triangle1.apply_to_coordinates(r_flat)
        triangle2.apply_to_coordinates(r_flat)

        # print "AFTER RT"
        # for triangle in triangles:
        #    #print "-------"
        #    for coordinate in triangle.coordinates:
        #        #print coordinate

        # *** r3: second rotation that makes both triangle coinced
        H = lambda a, b, c, d: a * c + b * d + (a + b) * (c + d)
        c = H(
            triangle1.coordinates[0][0],
            triangle1.coordinates[1][0],
            triangle2.coordinates[0][0],
            triangle2.coordinates[1][0],
        ) + H(
            triangle1.coordinates[0][1],
            triangle1.coordinates[1][1],
            triangle2.coordinates[0][1],
            triangle2.coordinates[1][1],
        )
        s = H(
            triangle1.coordinates[0][1],
            triangle1.coordinates[1][1],
            triangle2.coordinates[0][0],
            triangle2.coordinates[1][0],
        ) - H(
            triangle1.coordinates[0][0],
            triangle1.coordinates[1][0],
            triangle2.coordinates[0][1],
            triangle2.coordinates[1][1],
        )
        # if c > s: c, s = -c, -s
        # print "cos=%f sin=%f" % (c, s)
        rotation_angle = numpy.arctan2(s, c)
        # print "R3 %s, %s" % (rotation_angle/numpy.pi*180, triangle1.normal)
        r3 = Rotation.from_properties(rotation_angle, triangle1.normal, False)
        r_tmp = Rotation.from_properties(rotation_angle, numpy.array([0, 0, 1], float), False)
        triangle2.apply_to_coordinates(r_tmp)
        # print "AFTER R3"
        # for triangle in triangles:
        #    #print "-------"
        #    for coordinate in triangle.coordinates:
        #        #print coordinate

        # t4: translate the triangle to the definitive coordinate
        t4 = Translation(triangle1.center)
        # print "AFTER T4"
        # for triangle in triangles:
        #    #print "-------"
        #    for coordinate in triangle.coordinates:
        #        #print coordinate

        return t4 * r3 * r2 * t1
コード例 #8
0
ファイル: molecule.py プロジェクト: molmod/zeobuilder
        def add_hydrogens(atom):
            existing_bonds = list(atom.iter_bonds())
            num_bonds = len(existing_bonds)
            bond_length = bonds.get_length(atom.number, 1, BOND_SINGLE)

            if num_bonds == 0:
                t = atom.transformation.t + numpy.array([0,bond_length,0])
                H = Atom(name="auto H", number=1, transformation=Translation(t))
                primitive.Add(H, atom.parent)
                bond = Bond(name="aut H bond", targets=[atom, H])
                primitive.Add(bond, atom.parent)
                existing_bonds.append(bond)
                num_bonds = 1

            used_valence = 0
            oposite_direction = numpy.zeros(3, float)
            for bond in existing_bonds:
                shortest_vector = bond.shortest_vector_relative_to(atom.parent)
                if bond.children[1].target == atom:
                    shortest_vector *= -1
                oposite_direction -= shortest_vector

                if bond.bond_type == BOND_SINGLE:
                    used_valence += 1
                elif bond.bond_type == BOND_DOUBLE:
                    used_valence += 2
                elif bond.bond_type == BOND_TRIPLE:
                    used_valence += 3

            oposite_direction /= numpy.linalg.norm(oposite_direction)

            num_hydrogens = valence_el(atom.number) - 2*lone_pairs(atom.number) - used_valence
            if num_hydrogens <= 0:
                return

            hybride_count = num_hydrogens + lone_pairs(atom.number) + num_bonds - (used_valence - num_bonds)
            num_sites = num_hydrogens + lone_pairs(atom.number)
            rotation = Rotation.from_properties(2*numpy.pi / float(num_sites), oposite_direction, False)
            opening_key = (hybride_count, num_sites)
            opening_angle = self.opening_angles.get(opening_key)
            if opening_angle is None:
                return

            if num_bonds == 1:
                first_bond = existing_bonds[0]
                other_atom = first_bond.children[0].target
                if other_atom == atom:
                    other_atom = first_bond.children[1].target
                other_bonds = [bond for bond in other_atom.iter_bonds() if bond != first_bond]
                if len(other_bonds) > 0:
                    normal = other_bonds[0].shortest_vector_relative_to(atom.parent)
                    normal -= numpy.dot(normal, oposite_direction) * oposite_direction
                    normal /= numpy.linalg.norm(normal)
                    if other_bonds[0].children[0].target == other_atom:
                        normal *= -1
                else:
                    normal = random_orthonormal(oposite_direction)
            elif num_bonds == 2:
                normal = numpy.cross(oposite_direction, existing_bonds[0].shortest_vector_relative_to(atom.parent))
                normal /= numpy.linalg.norm(normal)
            elif num_bonds == 3:
                normal = random_orthonormal(oposite_direction)
            else:
                return

            h_pos = bond_length*(oposite_direction*numpy.cos(opening_angle) + normal*numpy.sin(opening_angle))

            for i in range(num_hydrogens):
                t = atom.transformation.t + h_pos
                H = Atom(name="auto H", number=1, transformation=Translation(t))
                primitive.Add(H, atom.parent)
                bond = Bond(name="aut H bond", targets=[atom, H])
                primitive.Add(bond, atom.parent)
                h_pos = rotation * h_pos