def test_set_angle_noadjust(four_particle_45_twist): mol = four_particle_45_twist assert mdt.angle(*mol.atoms[:3]) == 90.0 * u.degrees final = 45 * u.degrees origpos = mol.positions.copy() mdt.set_angle(mol.atoms[0], mol.atoms[1], mol.atoms[2], final, adjustmol=False) assert abs(mdt.angle(*mol.atoms[:3]) - final) < 0.1 * u.degrees assert (mol.positions[-1] == origpos[-1]).all()
def _setup_angle_tools(self, atoms): a1, a2, a3 = atoms self.viewer.shapes = [] # creates a temp cylinder that will be overwritten in self.set_distance angle_normal = np.cross(a1.position-a2.position, a3.position-a2.position) self._widgetshapes = { 'plane': self.viewer.draw_circle(a2.position, normal=angle_normal, radius=max(a1.distance(a2), a3.distance(a2)), opacity=0.55, color='blue'), 'origin': self.viewer.draw_sphere(a2.position, radius=0.5, opacity=0.85, color='green'), 'b1': self.viewer.draw_cylinder(a1.position, a2.position, radius=0.3, opacity=0.65, color='red'), 'b2': self.viewer.draw_cylinder(a3.position, a2.position, radius=0.3, opacity=0.65, color='red')} self.angle_slider.value = mdt.angle(a1, a2, a3).value_in(u.degrees) self.angle_slider.description = ANGLEDESCRIPTION.format( a1=a1, a2=a2, a3=a3, c1=self.viewer.HIGHLIGHT_COLOR, c2=self.NBR2HIGHLIGHT) b1 = mdt.Bond(a1, a2) b2 = mdt.Bond(a3, a2) if b1.is_cyclic: b1, b2 = b2, b1 # try to find a b1 that is not cyclic if b1.exists and b2.exists and not b1.is_cyclic: self.tool_holder.children = (self.rigid_mol_selector, self.angle_slider,) else: self.tool_holder.children = (self.angle_slider,) self.rigid_mol_selector.value = False
def _setup_angle_tools(self, atoms): a1, a2, a3 = atoms self.viewer.shapes = [] # creates a temp cylinder that will be overwritten in self.set_distance angle_normal = np.cross(a1.position - a2.position, a3.position - a2.position) self._widgetshapes = { 'plane': self.viewer.draw_circle(a2.position, normal=angle_normal, radius=max(a1.distance(a2), a3.distance(a2)), opacity=0.55, color='blue'), 'origin': self.viewer.draw_sphere(a2.position, radius=0.5, opacity=0.85, color='green'), 'b1': self.viewer.draw_cylinder(a1.position, a2.position, radius=0.3, opacity=0.65, color='red'), 'b2': self.viewer.draw_cylinder(a3.position, a2.position, radius=0.3, opacity=0.65, color='red') } self.angle_slider.value = mdt.angle(a1, a2, a3).value_in(u.degrees) self.angle_slider.description = ANGLEDESCRIPTION.format( a1=a1, a2=a2, a3=a3, c1=self.viewer.HIGHLIGHT_COLOR, c2=self.NBR2HIGHLIGHT) b1 = mdt.Bond(a1, a2) b2 = mdt.Bond(a3, a2) if b1.is_cyclic: b1, b2 = b2, b1 # try to find a b1 that is not cyclic if b1.exists and b2.exists and not b1.is_cyclic: self.tool_holder.children = ( self.rigid_mol_selector, self.angle_slider, ) else: self.tool_holder.children = (self.angle_slider, ) self.rigid_mol_selector.value = False
def _get_tool_state(self, selectedAtomIndices): # start with everything disabled for tool in self.atom_tools.children + self.bond_tools.children: tool.disabled = True if len(selectedAtomIndices) <= 0: return (ipy.HTML('Please click on a bond or atom'), ) elif len(selectedAtomIndices) is 1: atom = self.get_selected_atom(self.mol.atoms, selectedAtomIndices) self.adjust_button.disabled = False x, y, z = atom.position.value_in(u.angstrom) self.x_slider.value = x self.x_slider.disabled = False # for now self.y_slider.value = y self.y_slider.disabled = False # for now self.z_slider.value = z self.z_slider.disabled = False # for now for tool in self.atom_tools.children: tool.disabled = True return (self.atom_tools, ) else: bonds = self.viewer.get_selected_bonds() bond = self.get_selected_bond(bonds) self.adjust_button.disabled = False # bond length self.length_slider.value = bond.a1.distance(bond.a2).value_in( u.angstrom) self.length_slider.disabled = False self.length_slider.description = '<b>Bond distance</b> <span style="color:{c1}">{a1.name}' \ ' - {a2.name}</span>'.format( a1=bond.a1, a2=bond.a2, c1=self.viewer.HIGHLIGHT_COLOR) a1_neighbors = set( [a for a in bond.a1.bond_graph if a is not bond.a2]) maxo = max(a1_neighbors, key=lambda x: x.mass) bond_neighbors = self.get_bond_neighbors(bonds, bond) # Bond angle if bond_neighbors['a2']: self.dihedral_slider.enable() self.angle_slider.enable() self.angle_slider.value = mdt.angle( bond.a1, bond.a2, bond_neighbors['a2']).value_in(u.degrees) # self.angle_slider.observe(self.set_angle, 'value') self.angle_slider.description = '<b>Bond angle</b> <span style="color:{c1}">{a1.name}' \ ' - {a2.name}</span> ' \ '- <span style="color:{c2}">{a3.name}</span>'.format( a1=bond.a1, a2=bond.a2, a3=bond_neighbors['a2'], c1=self.viewer.HIGHLIGHT_COLOR, c2=self.NBR2HIGHLIGHT) else: self.dihedral_slider.disable() self.angle_slider.disable() self.angle_slider.description = 'no angle associated with this bond' # self.angle_slider.unobserve(self.set_angle) # Dihedral twist if bond_neighbors['a2'] and bond_neighbors['a1']: self.dihedral_slider.value = mdt.dihedral( bond_neighbors['a1'], bond.a1, bond.a2, bond_neighbors['a2']).value_in(u.degrees) # self.dihedral_slider.observe(self.set_dihedral, 'value') self.dihedral_slider.description = '<b>Dihedral angle</b> <span style="color:{c0}">{a4.name}</span>' \ ' - <span style="color:{c1}">{a1.name}' \ ' - {a2.name}</span> ' \ '- <span style="color:{c2}">{a3.name}</span>'.format( a4=bond_neighbors['a1'], a1=bond.a1, a2=bond.a2, a3=bond_neighbors['a2'], c0=self.NBR1HIGHLIGHT, c1=self.viewer.HIGHLIGHT_COLOR, c2=self.NBR2HIGHLIGHT) else: self.dihedral_slider.description = 'not a torsion bond' # self.dihedral_slider.unobserve(self.set_dihedral) self.dihedral_slider.disabled = True return [self.bond_tools]
def test_angle_measure(three_particle_right_angle): mol = three_particle_right_angle np.testing.assert_almost_equal(mdt.angle(*mol.atoms).value_in(u.degrees), 90.0, decimal=8)
def angle(self, a1, a2, a3): a1, a2, a3 = list(map(self._get_traj_atom, (a1, a2, a3))) return mdt.angle(a1, a2, a3)
def _get_tool_state(self, selectedAtomIndices): # start with everything disabled for tool in self.atom_tools.children + self.bond_tools.children: tool.disabled = True if len(selectedAtomIndices) <= 0: return (ipy.HTML('Please click on a bond or atom'),) elif len(selectedAtomIndices) is 1: atom = self.get_selected_atom(self.mol.atoms, selectedAtomIndices) self.adjust_button.disabled = False x, y, z = atom.position.value_in(u.angstrom) self.x_slider.value = x self.x_slider.disabled = False # for now self.y_slider.value = y self.y_slider.disabled = False # for now self.z_slider.value = z self.z_slider.disabled = False # for now for tool in self.atom_tools.children: tool.disabled = True return (self.atom_tools,) else: bonds = self.viewer.get_selected_bonds() bond = self.get_selected_bond(bonds) self.adjust_button.disabled = False # bond length self.length_slider.value = bond.a1.distance(bond.a2).value_in(u.angstrom) self.length_slider.disabled = False self.length_slider.description = '<b>Bond distance</b> <span style="color:{c1}">{a1.name}' \ ' - {a2.name}</span>'.format( a1=bond.a1, a2=bond.a2, c1=self.viewer.HIGHLIGHT_COLOR) a1_neighbors = set([a for a in bond.a1.bond_graph if a is not bond.a2]) maxo = max(a1_neighbors, key=lambda x: x.mass) bond_neighbors = self.get_bond_neighbors(bonds, bond) # Bond angle if bond_neighbors['a2']: self.dihedral_slider.enable() self.angle_slider.enable() self.angle_slider.value = mdt.angle(bond.a1, bond.a2, bond_neighbors['a2']).value_in(u.degrees) # self.angle_slider.observe(self.set_angle, 'value') self.angle_slider.description = '<b>Bond angle</b> <span style="color:{c1}">{a1.name}' \ ' - {a2.name}</span> ' \ '- <span style="color:{c2}">{a3.name}</span>'.format( a1=bond.a1, a2=bond.a2, a3=bond_neighbors['a2'], c1=self.viewer.HIGHLIGHT_COLOR, c2=self.NBR2HIGHLIGHT) else: self.dihedral_slider.disable() self.angle_slider.disable() self.angle_slider.description = 'no angle associated with this bond' # self.angle_slider.unobserve(self.set_angle) # Dihedral twist if bond_neighbors['a2'] and bond_neighbors['a1']: self.dihedral_slider.value = mdt.dihedral(bond_neighbors['a1'], bond.a1, bond.a2, bond_neighbors['a2']).value_in(u.degrees) # self.dihedral_slider.observe(self.set_dihedral, 'value') self.dihedral_slider.description = '<b>Dihedral angle</b> <span style="color:{c0}">{a4.name}</span>' \ ' - <span style="color:{c1}">{a1.name}' \ ' - {a2.name}</span> ' \ '- <span style="color:{c2}">{a3.name}</span>'.format( a4=bond_neighbors['a1'], a1=bond.a1, a2=bond.a2, a3=bond_neighbors['a2'], c0=self.NBR1HIGHLIGHT, c1=self.viewer.HIGHLIGHT_COLOR, c2=self.NBR2HIGHLIGHT) else: self.dihedral_slider.description = 'not a torsion bond' # self.dihedral_slider.unobserve(self.set_dihedral) self.dihedral_slider.disabled = True return [self.bond_tools]
def test_set_angle_with_monitor(three_particle_right_angle): mol = three_particle_right_angle ang = mdt.AngleMonitor(*mol.atoms) ang.value = 45 * u.degrees assert abs(mdt.angle(*mol.atoms) - (45 * u.degrees)) < 0.1 * u.degrees