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 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 ask_parameters(self): cache = context.application.cache nodes = cache.nodes last = cache.last next_to_last = cache.next_to_last if isinstance(last, Vector): if (len(nodes) >= 2) and isinstance(next_to_last, Vector): raise NotImplementedError("This part of the code is not supported yet.") b1 = last.children[0].translation_relative_to(parent) e1 = last.children[1].translation_relative_to(parent) b2 = next_to_last.children[0].translation_relative_to(parent) e2 = next_to_last.children[1].translation_relative_to(parent) if (b1 is not None) and (e1 is not None) and (b2 is not None) and (e2 is not None): if last.children[0].target == next_to_last.children[0].target: self.parameters.complete.t = copy.copy(b1) angle = angle(e1 - b1, e2 - b2) rotation_vector = numpy.cross(e1 - b1, e2 - b2) self.parameters.complete.set_rotation_properties(angle, rotation_vector, False) else: parent = next_to_last.parent b = last.children[0].translation_relative_to(parent) e = last.children[1].translation_relative_to(parent) if (b is not None) and (e is not None): self.parameters.complete.t = b self.parameters.complete.set_rotation_properties(math.pi*0.25, e - b, False) elif isinstance(last, GLTransformationMixin) and isinstance(last.transformation, Translation): parent = last.parent self.parameters.complete.t = last.get_frame_relative_to(parent).t else: self.parameters.complete.t = calculate_center(cache.translations) if self.parameters_dialog.run(self.parameters.complete) != gtk.RESPONSE_OK: self.parameters.clear() else: self.parameters.complete.t -= numpy.dot(self.parameters.complete.r, self.parameters.complete.t)
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 * math.pi - angle(normal, delta), 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")