Esempio n. 1
0
    def do(self):
        for key, val in self.parameters.__dict__.iteritems():
            if isinstance(val, Expression):
                val.compile_as("<%s>" % key)
                val.variables = (key[7:11], )

        parent = context.application.cache.common_parent
        if parent is None:
            parent = context.application.model.universe
        angles = []
        graph = create_molecular_graph(context.application.cache.nodes)

        match_definition = BendingAnglePattern(criteria_sets=[
            CriteriaSet(
                thing_criteria={
                    0: IndexToAtoms(self.parameters.filter_atom1),
                    1: IndexToAtoms(self.parameters.filter_atom2),
                    2: IndexToAtoms(self.parameters.filter_atom3),
                },
                relation_criteria={
                    0: IndexToBonds(self.parameters.filter_bond12),
                    1: IndexToBonds(self.parameters.filter_bond23),
                },
            )
        ], )
        try:
            atoms = graph.molecule.atoms
            match_generator = GraphSearch(match_definition)
            for match in match_generator(graph):
                point1 = atoms[match.forward[0]].get_absolute_frame().t
                point2 = atoms[match.forward[1]].get_absolute_frame().t
                point3 = atoms[match.forward[2]].get_absolute_frame().t
                delta1 = parent.shortest_vector(point2 - point1)
                delta2 = parent.shortest_vector(point2 - point3)
                if numpy.linalg.norm(delta1) > 1e-8 and \
                    numpy.linalg.norm(delta2) > 1e-8:
                    angles.append(angle(delta1, delta2))
        except:
            raise UserError(
                "An error occured while sampling the bending angles.",
                "If this is an error in one of the filter expressions,\n" +
                "one should see the expression mentioned below as <filter_...>.\n\n"
            )

        comments = [
            "atom 1 filter expression: %s" % self.parameters.filter_atom1.code,
            "bond 1-2 filter expression: %s" %
            self.parameters.filter_bond12.code,
            "atom 2 filter expression: %s" % self.parameters.filter_atom2.code,
            "bond 2-3 filter expression: %s" %
            self.parameters.filter_bond23.code,
            "atom 3 filter expression: %s" % self.parameters.filter_atom3.code,
        ]

        if len(angles) > 0:
            distribution_dialog = DistributionDialog()
            distribution_dialog.run(numpy.array(angles), "Angle",
                                    "Bending angle", comments)
        else:
            raise UserError("No bending angles match the given criteria.")
Esempio n. 2
0
 def express_out_of_plane_angle(index1, index2, index3, index4):
     delta = self.vectors[index1] - self.vectors[index2]
     normal = numpy.cross(
         self.vectors[index4] - self.vectors[index3],
         self.vectors[index2] - self.vectors[index3]
     )
     return express_measure(0.5*numpy.pi - angle(normal, delta), measure="Angle")
Esempio n. 3
0
    def do(self):
        for key, val in self.parameters.__dict__.iteritems():
            if isinstance(val, Expression):
                val.compile_as("<%s>" % key)
                val.variables = (key[7:11],)

        parent = context.application.cache.common_parent
        if parent is None:
            parent = context.application.model.universe
        angles = []
        graph = create_molecular_graph(context.application.cache.nodes)

        match_definition = BendingAnglePattern(
            criteria_sets=[CriteriaSet(
                thing_criteria={
                    0: IndexToAtoms(self.parameters.filter_atom1),
                    1: IndexToAtoms(self.parameters.filter_atom2),
                    2: IndexToAtoms(self.parameters.filter_atom3),
                },
                relation_criteria={
                    0: IndexToBonds(self.parameters.filter_bond12),
                    1: IndexToBonds(self.parameters.filter_bond23),
                },
            )],
        )
        try:
            atoms = graph.molecule.atoms
            match_generator = GraphSearch(match_definition)
            for match in match_generator(graph):
                point1 = atoms[match.forward[0]].get_absolute_frame().t
                point2 = atoms[match.forward[1]].get_absolute_frame().t
                point3 = atoms[match.forward[2]].get_absolute_frame().t
                delta1 = parent.shortest_vector(point2 - point1)
                delta2 = parent.shortest_vector(point2 - point3)
                if numpy.linalg.norm(delta1) > 1e-8 and \
                    numpy.linalg.norm(delta2) > 1e-8:
                    angles.append(angle(delta1, delta2))
        except:
            raise UserError(
                "An error occured while sampling the bending angles.",
                "If this is an error in one of the filter expressions,\n" +
                "one should see the expression mentioned below as <filter_...>.\n\n"
            )

        comments = [
            "atom 1 filter expression: %s" % self.parameters.filter_atom1.code,
            "bond 1-2 filter expression: %s" % self.parameters.filter_bond12.code,
            "atom 2 filter expression: %s" % self.parameters.filter_atom2.code,
            "bond 2-3 filter expression: %s" % self.parameters.filter_bond23.code,
            "atom 3 filter expression: %s" % self.parameters.filter_atom3.code,
        ]

        if len(angles) > 0:
            distribution_dialog = DistributionDialog()
            distribution_dialog.run(numpy.array(angles), "Angle", "Bending angle", comments)
        else:
            raise UserError("No bending angles match the given criteria.")
Esempio n. 4
0
 def express_dihedral_angle(index1, index2, index3, index4):
     normal1 = numpy.cross(
         self.vectors[index1] - self.vectors[index2],
         self.vectors[index3] - self.vectors[index2]
     )
     normal2 = numpy.cross(
         self.vectors[index2] - self.vectors[index3],
         self.vectors[index4] - self.vectors[index3]
     )
     return express_measure(angle(normal1, normal2), measure="Angle")
Esempio n. 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
Esempio n. 6
0
 def express_out_of_plane_angle(index1, index2, index3, index4):
     delta = self.vectors[index1] - self.vectors[index2]
     normal = numpy.cross(self.vectors[index4] - self.vectors[index3],
                          self.vectors[index2] - self.vectors[index3])
     return express_measure(0.5 * numpy.pi - angle(normal, delta),
                            measure="Angle")
Esempio n. 7
0
 def express_dihedral_angle(index1, index2, index3, index4):
     normal1 = numpy.cross(self.vectors[index1] - self.vectors[index2],
                           self.vectors[index3] - self.vectors[index2])
     normal2 = numpy.cross(self.vectors[index2] - self.vectors[index3],
                           self.vectors[index4] - self.vectors[index3])
     return express_measure(angle(normal1, normal2), measure="Angle")
Esempio n. 8
0
 def express_angle(index1, index2, index3):
     delta1 = self.vectors[index1] - self.vectors[index2]
     delta2 = self.vectors[index3] - self.vectors[index2]
     return express_measure(angle(delta1, delta2), measure="Angle")
Esempio n. 9
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
Esempio n. 10
0
 def express_angle(index1, index2, index3):
     delta1 = self.vectors[index1] - self.vectors[index2]
     delta2 = self.vectors[index3] - self.vectors[index2]
     return express_measure(angle(delta1, delta2), measure="Angle")