Exemple #1
0
    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
Exemple #2
0
    def _setup_distance_tools(self, atoms):
        a1, a2 = atoms
        self.viewer.shapes = []

        # creates a temp cylinder that will be overwritten in self.set_distance
        self._widgetshapes = {
            'bond':
            self.viewer.draw_cylinder(a1.position,
                                      a2.position,
                                      radius=0.3,
                                      opacity=0.65,
                                      color='red')
        }
        self.length_slider.value = a1.distance(a2).value_in(u.angstrom)
        self.length_slider.description = BONDDESCRIPTION.format(
            a1=a1, a2=a2, c1=self.viewer.HIGHLIGHT_COLOR)

        bond = mdt.Bond(a1, a2)
        if bond.exists and not bond.is_cyclic:
            self.tool_holder.children = (
                self.rigid_mol_selector,
                self.length_slider,
            )
        else:
            self.tool_holder.children = (self.length_slider, )
            self.rigid_mol_selector.value = False
def test_bond_alignment_on_axis(benzene):
    mol = benzene.copy()
    directions = [
        'x', 'y', 'z', [1, 2, 3.0], [0, 1, 0], [0.1, 0.1, 0.1] * u.angstrom
    ]

    for i, dir in enumerate(directions):
        bond = mdt.Bond(*random.sample(mol.atoms, 2))
        center = (i % 2) == 0.0
        bond.align(dir, centered=center)

        if center:
            np.testing.assert_allclose(bond.midpoint, np.zeros(3), atol=1.e-12)
            np.testing.assert_allclose(bond.a1.position.defunits_value(),
                                       -bond.a2.position.defunits_value(),
                                       atol=1e-10)
        if isinstance(dir, str):
            if dir == 'x':
                d = np.array([1.0, 0, 0])
            elif dir == 'y':
                d = np.array([0.0, 1.0, 0.0])
            elif dir == 'z':
                d = np.array([0.0, 0.0, 1.0])
            else:
                raise WtfError()
        else:
            d = normalized(u.array(dir))

        newvec = (bond.a2.position - bond.a1.position).normalized()
        assert abs(1.0 - d.dot(newvec)) < 1e-10
Exemple #4
0
 def bonds(self):
     """ Iterable[moldesign.Bond]: iterator over bonds from this object's atoms
     """
     bg = self.bond_graph
     for atom, nbrs in bg.iteritems():
         for nbr, order in nbrs.iteritems():
             if atom.index < nbr.index or nbr not in bg:
                 yield mdt.Bond(atom, nbr, order)
Exemple #5
0
 def internal_bonds(self):
     """ Iterable[moldesign.Bond]: iterator over bonds that connect two atoms in this object
     """
     bg = self.bond_graph
     for atom, nbrs in bg.iteritems():
         for nbr, order in nbrs.iteritems():
             if atom.index < nbr.index and nbr in bg:
                 yield mdt.Bond(atom, nbr, order)
Exemple #6
0
def test_set_dihedral_bond_no_adjust(four_particle_45_twist):
    mol = four_particle_45_twist
    bond = mdt.Bond(mol.atoms[1], mol.atoms[2])
    mdt.set_dihedral(bond, 10.0 * u.degrees, adjustmol=False)
    np.testing.assert_almost_equal(mdt.dihedral(*mol.atoms).value_in(
        u.degrees),
                                   10.0,
                                   decimal=8)
Exemple #7
0
def test_bond_object_for_unbonded_atoms(pdb3aid):
    mol = pdb3aid
    a1 = mol.atoms[1]
    a2 = mol.atoms[-10]
    bond = mdt.Bond(a1, a2)
    assert bond.order is None

    bond.order = 2
    assert_consistent_bond(mol, a1, a2, 2)
Exemple #8
0
 def external_bonds(self):
     """
     Iterable[moldesign.Bond]: iterator over bonds that bond these atoms to other atoms
     """
     bg = self.bond_graph
     for atom, nbrs in bg.iteritems():
         for nbr, order in nbrs.iteritems():
             if nbr not in bg:
                 yield mdt.Bond(atom, nbr, order)
Exemple #9
0
    def _setup_dihedral_tools(self, atoms):
        a1, a2, a3, a4 = atoms
        bc = mdt.Bond(a2, a3)
        b_0 = mdt.Bond(a1, a2)
        b_f = mdt.Bond(a3, a4)

        self._widgetshapes = {
            'b1':
            self.viewer.draw_cylinder(a1.position,
                                      a2.position,
                                      radius=0.3,
                                      opacity=0.65,
                                      color='red'),
            'b3':
            self.viewer.draw_cylinder(a3.position,
                                      a4.position,
                                      radius=0.3,
                                      opacity=0.65,
                                      color='red'),
            'plane':
            self.viewer.draw_circle(center=bc.midpoint,
                                    normal=a3.position - a2.position,
                                    radius=1.5,
                                    color='blue',
                                    opacity=0.55)
        }

        self.dihedral_slider.description = DIHEDRALDESCRIPTION.format(
            a1=a1,
            a2=a2,
            a3=a3,
            a4=a4,
            c0=self.NBR1HIGHLIGHT,
            c1=self.viewer.HIGHLIGHT_COLOR,
            c2=self.NBR2HIGHLIGHT)
        if bc.exists and b_0.exists and b_f.exists and not b_0.is_cyclic:
            self.tool_holder.children = (
                self.rigid_mol_selector,
                self.dihedral_slider,
            )
        else:
            self.rigid_mol_selector = False
            self.tool_holder.children = (self.dihedral_slider, )
Exemple #10
0
def test_delete_bond(pdb3aid):
    mol = pdb3aid
    a1 = mol.atoms[89]  # arbitrary atom
    mol.ff = 'arglebargle'  # changing topology should reset this
    nbonds = mol.num_bonds
    a2 = a1.bonded_atoms[-1]
    bond = mdt.Bond(a1, a2)

    mol.delete_bond(bond)

    assert mol.num_bonds == nbonds - 1
    assert_not_bonded(mol, a1, a2)
Exemple #11
0
def test_bond_object_automatically_associates_with_molecule(pdb3aid):
    mol = pdb3aid
    a1 = mol.atoms[511]  # arbitrary atom
    bond_from_atom = a1.bonds[-1]
    a2 = bond_from_atom.partner(a1)

    created_bond = mdt.Bond(a2, a1)

    assert created_bond == bond_from_atom
    assert created_bond.order == mol.bond_graph[a1][a2]
    assert bond_from_atom.order == mol.bond_graph[a1][a2]
    assert created_bond.molecule is mol
    assert bond_from_atom.molecule is mol
Exemple #12
0
def add_orbitals(mol, wfn, orbdata, orbtype):
    orbs = []
    for i in range(len(orbdata.coeffs)):
        bond = None
        atoms = [mol.atoms[orbdata.iatom[i] - 1]]
        if orbdata.bond_names[i] == 'RY':
            bname = '%s Ryd*' % atoms[0].name
            nbotype = 'rydberg'
            utf_name = bname
        elif orbdata.bond_names[i] == 'LP':
            bname = '%s lone pair' % atoms[0].name
            nbotype = 'lone pair'
            utf_name = bname
        elif orbdata.bond_names[i] == 'LV':
            bname = '%s lone vacancy' % atoms[0].name
            nbotype = 'lone vacancy'
            utf_name = bname
        elif orbdata.num_bonded_atoms[i] == 1:
            bname = '%s Core' % atoms[0].name
            nbotype = 'core'
            utf_name = bname
        else:
            atoms.append(mol.atoms[orbdata.jatom[i] - 1])
            bond = mdt.Bond(*atoms)
            if orbdata.bondnums[i] == 1:  # THIS IS NOT CORRECT
                nbotype = 'sigma'
                utf_type = SIGMA_UTF
            else:
                nbotype = 'pi'
                utf_type = PI_UTF
            bname = '%s%s (%s - %s)' % (nbotype, orbdata.stars[i],
                                        atoms[0].name, atoms[1].name)
            utf_name = '%s%s (%s - %s)' % (utf_type, orbdata.stars[i],
                                           atoms[0].name, atoms[1].name)
        name = '%s %s' % (bname, orbtype)

        orbs.append(
            mdt.Orbital(orbdata.coeffs[i],
                        wfn=wfn,
                        occupation=orbdata.occupations[i],
                        atoms=atoms,
                        name=name,
                        nbotype=nbotype,
                        bond=bond,
                        unicode_name=utf_name,
                        _data=orbdata))
    return wfn.add_orbitals(orbs, orbtype=orbtype)
Exemple #13
0
def test_change_bond_order_with_bond_object(pdb3aid):
    mol = pdb3aid
    a1 = mol.atoms[511]  # arbitrary atom
    bond = a1.bonds[-1]
    a2 = bond.partner(a1)

    other_bond_object = mdt.Bond(a1, a2)
    oldorder = bond.order
    assert oldorder == other_bond_object.order
    assert a1.bond_graph[a2] == oldorder

    # First raise the order
    bond.order += 1
    assert_consistent_bond(mol, a1, a2, oldorder + 1)

    # Now delete the bond by setting it to None
    bond.order = None
    assert_not_bonded(mol, a1, a2)
Exemple #14
0
    def get_bond_term(self, bond_or_atom1, atom2=None):
        if atom2 is None:
            bond = bond_or_atom1
        else:
            bond = mdt.Bond(bond_or_atom1, atom2)

        pmdatom = self.parmed_obj.atoms[bond.a1.index]
        indices = [bond.a1.index, bond.a2.index]

        for pmdbond in pmdatom.bonds:
            pmdindices = sorted((pmdbond.atom1.idx, pmdbond.atom2.idx))
            if pmdindices == indices:
                assert self.parmed_obj.atoms[
                    pmdindices[0]].element == bond.a1.atnum
                assert self.parmed_obj.atoms[
                    pmdindices[1]].element == bond.a2.atnum

                return BondTerm(bond, pmdbond)
        else:
            raise ValueError("No ForceField term found for bond: %s" % bond)
Exemple #15
0
def pybel_to_mol(pbmol,
                 reorder_atoms_by_residue=False,
                 primary_structure=True,
                 **kwargs):
    """ Translate a pybel molecule object into a moldesign object.

    Note:
        The focus is on translating topology and biomolecular structure - we don't translate any metadata.

    Args:
        pbmol (pybel.Molecule): molecule to translate
        reorder_atoms_by_residue (bool): change atom order so that all atoms in a residue are stored
            contiguously
        primary_structure (bool): translate primary structure data as well as atomic data
        **kwargs (dict): keyword arguments to  moldesign.Molecule __init__ method

    Returns:
        moldesign.Molecule: translated molecule
    """
    newatom_map = {}
    newresidues = {}
    newchains = {}
    newatoms = mdt.AtomList([])
    backup_chain_names = list(string.ascii_uppercase)

    for pybatom in pbmol.atoms:
        obres = pybatom.OBAtom.GetResidue()
        name = obres.GetAtomID(pybatom.OBAtom).strip()

        if pybatom.atomicnum == 67:
            print((
                "WARNING: openbabel parsed atom serial %d (name:%s) as Holmium; "
                "correcting to hydrogen. ") % (pybatom.OBAtom.GetIdx(), name))
            atnum = 1

        elif pybatom.atomicnum == 0:
            print(
                "WARNING: openbabel failed to parse atom serial %d (name:%s); guessing %s. "
                % (pybatom.OBAtom.GetIdx(), name, name[0]))
            atnum = mdt.data.ATOMIC_NUMBERS[name[0]]
        else:
            atnum = pybatom.atomicnum
        mdtatom = mdt.Atom(atnum=atnum,
                           name=name,
                           formal_charge=pybatom.formalcharge * u.q_e,
                           pdbname=name,
                           pdbindex=pybatom.OBAtom.GetIdx())
        newatom_map[pybatom.OBAtom.GetIdx()] = mdtatom
        mdtatom.position = pybatom.coords * u.angstrom

        if primary_structure:
            obres = pybatom.OBAtom.GetResidue()
            resname = obres.GetName()
            residx = obres.GetIdx()
            chain_id = obres.GetChain()
            chain_id_num = obres.GetChainNum()

            if chain_id_num not in newchains:
                # create new chain
                if not mdt.utils.is_printable(
                        chain_id.strip()) or not chain_id.strip():
                    chain_id = backup_chain_names.pop()
                    print(
                        'WARNING: assigned name %s to unnamed chain object @ %s'
                        % (chain_id, hex(chain_id_num)))
                chn = mdt.Chain(pdbname=str(chain_id))
                newchains[chain_id_num] = chn
            else:
                chn = newchains[chain_id_num]

            if residx not in newresidues:
                # Create new residue
                pdb_idx = obres.GetNum()
                res = mdt.Residue(pdbname=resname, pdbindex=pdb_idx)
                newresidues[residx] = res
                chn.add(res)
                res.chain = chn
            else:
                res = newresidues[residx]

            res.add(mdtatom)

        newatoms.append(mdtatom)

    for ibond in range(pbmol.OBMol.NumBonds()):
        obbond = pbmol.OBMol.GetBond(ibond)
        a1 = newatom_map[obbond.GetBeginAtomIdx()]
        a2 = newatom_map[obbond.GetEndAtomIdx()]
        order = obbond.GetBondOrder()
        bond = mdt.Bond(a1, a2)
        bond.order = order

    if reorder_atoms_by_residue and primary_structure:
        resorder = {}
        for atom in newatoms:
            resorder.setdefault(atom.residue, len(resorder))
        newatoms.sort(key=lambda a: resorder[a.residue])

    return mdt.Molecule(newatoms, **kwargs)
def topology_to_mol(topo,
                    name=None,
                    positions=None,
                    velocities=None,
                    assign_bond_orders=True):
    """ Convert an OpenMM topology object into an MDT molecule.

    Args:
        topo (simtk.openmm.app.topology.Topology): topology to convert
        name (str): name to assign to molecule
        positions (list): simtk list of atomic positions
        velocities (list): simtk list of atomic velocities
        assign_bond_orders (bool): assign bond orders from templates (simtk topologies
             do not store bond orders)

    """
    from simtk import unit as stku

    # Atoms
    atommap = {}
    newatoms = []
    masses = u.amu * [
        atom.element.mass.value_in_unit(stku.amu) for atom in topo.atoms()
    ]
    for atom, mass in zip(topo.atoms(), masses):
        newatom = mdt.Atom(atnum=atom.element.atomic_number,
                           name=atom.name,
                           mass=mass)
        atommap[atom] = newatom
        newatoms.append(newatom)

    # Coordinates
    if positions is not None:
        poslist = np.array(
            [p.value_in_unit(stku.nanometer) for p in positions]) * u.nm
        poslist.ito(u.default.length)
        for newatom, position in zip(newatoms, poslist):
            newatom.position = position
    if velocities is not None:
        velolist = np.array([
            v.value_in_unit(stku.nanometer / stku.femtosecond)
            for v in velocities
        ]) * u.nm / u.fs
        velolist = u.default.convert(velolist)
        for newatom, velocity in zip(newatoms, velolist):
            newatom.momentum = newatom.mass * simtk2pint(velocity)

    # Biounits
    chains = {}
    for chain in topo.chains():
        if chain.id not in chains:
            chains[chain.id] = mdt.Chain(name=chain.id, index=chain.index)
        newchain = chains[chain.id]
        for residue in chain.residues():
            newresidue = mdt.Residue(name='%s%d' %
                                     (residue.name, residue.index),
                                     chain=newchain,
                                     pdbindex=int(residue.id),
                                     pdbname=residue.name)
            newchain.add(newresidue)
            for atom in residue.atoms():
                newatom = atommap[atom]
                newatom.residue = newresidue
                newresidue.add(newatom)

    # Bonds
    bonds = {}
    for bond in topo.bonds():
        a1, a2 = bond
        na1, na2 = atommap[a1], atommap[a2]
        if na1 not in bonds:
            bonds[na1] = {}
        if na2 not in bonds:
            bonds[na2] = {}
        b = mdt.Bond(na1, na2)
        b.order = 1

    if name is None:
        name = 'Unnamed molecule from OpenMM'

    newmol = mdt.Molecule(newatoms, name=name)

    if assign_bond_orders:
        for residue in newmol.residues:
            try:
                residue.assign_template_bonds()
            except (KeyError, ValueError):
                pass

    return newmol
Exemple #17
0
 def get_bond(self, a1, a2):
     return mdt.Bond(a1, a2)