Exemplo n.º 1
0
def h2():
    atom1 = mdt.Atom('H')
    atom1.x = 0.5 * u.angstrom
    atom2 = mdt.Atom(atnum=1)
    atom2.position = [-0.5, 0.0, 0.0] * u.angstrom
    h2 = mdt.Molecule([atom1, atom2], name='h2')
    atom1.bond_to(atom2, 1)
    return h2
Exemplo n.º 2
0
def test_create_atom_with_atomic_number():
    h = mdt.Atom('ca', atnum=1)
    assert h.atnum == 1
    assert h.element == 'H'
    assert h.name == 'ca'

    with pytest.raises(AssertionError):
        mdt.Atom('ca', atnum=1, element='He')
def linear():
    expected = {'C1': 1,
                'Cinf_v': 1}

    a1 = mdt.Atom(1)
    a1.position = [-1, 0, 0] * u.angstrom
    a2 = mdt.Atom(2)
    a2.position = [1, 0, 0] * u.angstrom

    return mdt.Molecule([a1, a2], name='linear_h2'), expected, True
def planar():
    expected = {'C1': 1,
                'Cs': 1}

    a1 = mdt.Atom(1)
    a1.position = [-1, 0, 0] * u.angstrom
    a2 = mdt.Atom(2)
    a2.position = [0.9, 0.2, 0] * u.angstrom
    a3 = mdt.Atom(3)
    a3.position = [-0.9, 3.2, 0] * u.angstrom

    return mdt.Molecule([a1, a2, a3], name='planar_h3'), expected, True
def test_set_hybridization_and_saturate():
    # Creates just the carbons of ethylene, expects the routine to figure out the rest
    atom1 = mdt.Atom(6)
    atom2 = mdt.Atom(6)
    atom2.x = 1.35 * u.angstrom
    atom1.bond_to(atom2, 1)
    mol = mdt.Molecule([atom1, atom2])
    newmol = mdt.set_hybridization_and_saturate(mol)
    pytest.xfail('This is apparently broken')
    assert newmol.num_atoms == 6
    assert newmol.atoms[0].bond_graph[atom1] == 2
    assert len(newmol.get_atoms(atnum=1)) == 4
Exemplo n.º 6
0
def create_link_atoms(mol, qmatoms):
    """ Create hydrogen caps for bonds between QM and MM regions.

    Each link atom will have ``metadata.mmatom``, ``metadata.mmpartner`` attributes to identify the
    atom it replaces and the atom it's bonded to in the MM system.

    Raises:
        ValueError: if any MM/QM atom is bonded to more than one QM/MM atom, or the bond
                    order is not one

    Returns:
        List[mdt.Atom]: list of link atoms
    """
    linkatoms = []
    qmset = set(qmatoms)
    for qmatom in qmatoms:
        mmatom = _get_mm_nbr(mol, qmatom, qmset)
        if mmatom is None:
            continue

        la = mdt.Atom(atnum=1, name='HL%d' % len(linkatoms),
                      metadata={'mmatom': mmatom, 'mmpartner': qmatom})
        linkatoms.append(la)

    set_link_atom_positions(linkatoms)
    return linkatoms
Exemplo n.º 7
0
def test_initialization_charges():
    a1 = mdt.Atom('Na', formal_charge=-1)
    mol = mdt.Molecule([a1])
    assert mol.charge == -1 * u.q_e

    with pytest.raises(TypeError):
        mdt.Atom(
            'H', charge=3
        )  # it needs to be "formal_charge" to distinguish from partial charge

    m2 = mdt.Molecule([a1], charge=-1)
    assert m2.charge == -1 * u.q_e

    m2 = mdt.Molecule([a1], charge=-3 * u.q_e)
    # TODO: test for warning
    assert m2.charge == -3 * u.q_e
Exemplo n.º 8
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])
Exemplo n.º 9
0
def test_add_atom(h2):
    newatom = mdt.Atom('Xe')
    h2.add_atom(newatom)
    assert newatom in h2.atoms
    assert h2.num_atoms == 3
    assert h2.num_residues == 1
    assert h2.num_chains == 1
    assert newatom.residue is h2.residues[0]
    assert newatom.chain is h2.chains[0]
Exemplo n.º 10
0
def test_create_atom_with_element_as_name():
    he_plus = mdt.Atom("He",
                       position=np.ones(3) * u.nm,
                       formal_charge=1 * u.q_e)
    assert he_plus.atomic_number == 2
    helpers.assert_almost_equal(he_plus.position, 10 * np.ones(3) * u.angstrom)
    assert he_plus.name == 'He'
    assert he_plus.element == 'He'
    assert he_plus.formal_charge == 1 * u.q_e
Exemplo n.º 11
0
def precanned_trajectory():
    a1 = mdt.Atom(6)
    a2 = mdt.Atom(1)
    a3 = mdt.Atom(7)
    mol = mdt.Molecule([a1, a2, a3])
    traj = mdt.Trajectory(mol)

    a1.x = 1.0 * u.angstrom
    a3.y = 1.0 * u.angstrom
    traj.new_frame(somenumber=1, someletter='a')

    mol.time = 1.0 * u.fs
    a1.x = 2.0 * u.angstrom
    traj.new_frame(somenumber=2, someletter='b')

    mol.time = 2.0 * u.fs
    a2.x = -1.0 * u.angstrom
    a3.x = -1.0 * u.angstrom
    traj.new_frame(somenumber=3, someletter='c')

    return traj
def test_constrained_distance_minimization(minkey):
    minimizer = MINIMIZERS[minkey]

    mol = mdt.Molecule([mdt.Atom(1), mdt.Atom(2)])
    mol.atoms[0].x = 2.0 * u.angstrom
    mol.atoms[1].x = 3.0 * u.angstrom
    mol.atoms[1].y = 2.0 * u.angstrom
    mol.set_energy_model(mdt.models.HarmonicOscillator,
                         k=2.0 * u.kcalpermol / u.angstrom**2)

    e0 = mol.calculate_potential_energy()
    p0 = mol.positions.copy()

    mol.constrain_distance(mol.atoms[0], mol.atoms[1])

    if minkey == 'bfgs':  # BFGS expected to fail here
        with pytest.raises(mdt.exceptions.NotSupportedError):
            minimizer(mol)
        return

    traj = minimizer(mol)

    assert_something_resembling_minimization_happened(p0, e0, traj, mol)
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])
Exemplo n.º 15
0
def h2():
    mol = mdt.Molecule([mdt.Atom('H'),
                        mdt.Atom('H')])
    mol.atoms[1].z = 0.75 * u.angstrom
    return mol
Exemplo n.º 16
0
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
Exemplo n.º 17
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 harmonic_atom():
    mol = mdt.Molecule([mdt.Atom(1)])
    mol.atoms[0].x = 2.0 * u.angstrom
    mol.set_energy_model(mdt.models.HarmonicOscillator,
                         k=2.0 * u.kcalpermol / u.angstrom**2)
    return mol
def _make_mol_with_n_hydrogens(n):
    return mdt.Molecule([mdt.Atom('H') for i in range(n)])
Exemplo n.º 20
0
def heh_plus():
    mol = mdt.Molecule([mdt.Atom('H'), mdt.Atom('He')])
    mol.atoms[1].z = 1.0 * u.angstrom
    mol.charge = 1 * u.q_e
    mol.atoms[0].bond_to(mol.atoms[1], 1)
    return mol
Exemplo n.º 21
0
def h2():
    mol = mdt.Molecule([mdt.Atom('H1'), mdt.Atom('H2')])
    mol.atoms[0].x = 0.5 * u.angstrom
    mol.atoms[1].x = -0.25 * u.angstrom
    mol.atoms[0].bond_to(mol.atoms[1], 1)
    return mol
def almost_planar(planar):
    atoms = planar[0].atoms
    atoms.append(mdt.Atom(4))
    atoms[-1].position = [0, 0, 0.005] * u.angstrom
    return mdt.Molecule(atoms, name='almost_planar')
Exemplo n.º 23
0
def carbon_atom():
    atom1 = mdt.Atom('C')
    return atom1
Exemplo n.º 24
0
def test_create_atom_with_uppercase_element():
    cl_minus = mdt.Atom("CL2", element='CL', formal_charge=-1)
    assert cl_minus.formal_charge == -1 * u.q_e
    assert cl_minus.atnum == 17
    assert cl_minus.name == 'CL2'
    assert cl_minus.element == 'Cl'
Exemplo n.º 25
0
def test_create_atom_with_unrelated_name():
    carbon_named_bob = mdt.Atom("bob", element='c')
    assert carbon_named_bob.name == 'bob'
    assert carbon_named_bob.atnum == 6
    assert carbon_named_bob.element == 'C'
Exemplo n.º 26
0
def test_create_atom_with_element_name_as_first_char():
    carbon_alpha = mdt.Atom('ca')
    assert carbon_alpha.name == 'ca'
    assert carbon_alpha.atnum == 6
    assert carbon_alpha.element == 'C'