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.")
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")
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.")
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")
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
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")
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")
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")
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