예제 #1
0
def biopy_to_mol(struc):
    """Convert a biopython PDB structure to an MDT molecule.
    Because Biopython doesn't assign bonds, assign connectivity using templates.

    Args:
        struc (Bio.PDB.Structure.Structure): Biopython PDB structure to convert

    Returns:
        moldesign.Molecule: converted molecule
    """
    # TODO: assign bonds using 1) CONECT records, 2) residue templates, 3) distance
    newatoms = []

    for chain in struc.get_chains():
        tmp, pdbidx, pdbid = chain.get_full_id()
        newchain = mdt.Chain(pdbname=pdbid.strip())

        for residue in chain.get_residues():
            newresidue = mdt.Residue(pdbname=residue.resname.strip(),
                                     pdbindex=residue.id[1])

            newchain.add(newresidue)

            for atom in residue.get_atom():
                newatom = mdt.Atom(element=atom.element,
                                   name=atom.get_name(),
                                   pdbname=atom.get_name(),
                                   pdbindex=atom.get_serial_number())
                newatom.position = atom.coord * u.angstrom
                newresidue.add(newatom)

                newatoms.append(newatom)

    return mdt.Molecule(newatoms, name=struc.get_full_id()[0])
def parmed_to_mdt(pmdmol):
    """ Convert parmed Structure to MDT Structure

    Args:
        pmdmol (parmed.Structure): parmed structure to convert

    Returns:
        mdt.Molecule: converted molecule
    """
    atoms = collections.OrderedDict()
    residues = {}
    chains = {}

    masses = [pa.mass for pa in pmdmol.atoms] * u.dalton
    positions = [[pa.xx, pa.xy, pa.xz] for pa in pmdmol.atoms] * u.angstrom

    for iatom, patm in enumerate(pmdmol.atoms):
        if patm.residue.chain not in chains:
            chains[patm.residue.chain] = mdt.Chain(pdbname=patm.residue.chain)
        chain = chains[patm.residue.chain]

        if patm.residue not in residues:
            residues[patm.residue] = mdt.Residue(resname=patm.residue.name,
                                                 pdbindex=patm.residue.number)
            residues[patm.residue].chain = chain
            chain.add(residues[patm.residue])
        residue = residues[patm.residue]

        atom = mdt.Atom(name=patm.name,
                        atnum=patm.atomic_number,
                        pdbindex=patm.number,
                        mass=masses[iatom])
        atom.position = positions[iatom]

        atom.residue = residue
        residue.add(atom)
        assert patm not in atoms
        atoms[patm] = atom

    for pbnd in pmdmol.bonds:
        atoms[pbnd.atom1].bond_to(atoms[pbnd.atom2], int(pbnd.order))

    mol = mdt.Molecule(list(atoms.values()),
                       metadata=_get_pdb_metadata(pmdmol))
    return mol
def biopy_to_mol(struc):
    """Convert a biopython PDB structure to an MDT molecule.

    Note:
        Biopython doesn't deal with bond data, so no bonds will be present
        in the Molecule

    Args:
        struc (Bio.PDB.Structure.Structure): Biopython PDB structure to convert

    Returns:
        moldesign.Molecule: converted molecule
    """
    # TODO: assign bonds using 1) CONECT records, 2) residue templates, 3) distance
    newatoms = []
    backup_chain_names = list(string.ascii_uppercase)

    for chain in struc.get_chains():
        tmp, pdbidx, pdbid = chain.get_full_id()
        if not pdbid.strip():
            pdbid = backup_chain_names.pop()
        newchain = mdt.Chain(pdbname=pdbid.strip())

        for residue in chain.get_residues():
            newresidue = mdt.Residue(pdbname=residue.resname.strip(),
                                     pdbindex=residue.id[1])

            newchain.add(newresidue)

            for atom in residue.get_atom():
                elem = atom.element
                if len(elem) == 2:
                    elem = elem[0] + elem[1].lower()
                newatom = mdt.Atom(element=elem,
                                   name=atom.get_name(),
                                   pdbname=atom.get_name(),
                                   pdbindex=atom.get_serial_number())
                newatom.position = atom.coord * u.angstrom
                newresidue.add(newatom)

                newatoms.append(newatom)

    return mdt.Molecule(newatoms,
                        name=struc.get_full_id()[0])
예제 #4
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