Esempio n. 1
0
def from_parmed(structure, refer_type=True):
    """Convert a parmed.Structure to a gmso.Topology.

    Convert a parametrized or un-parametrized parmed.Structure object to a topology.Topology.
    Specifically, this method maps Structure to Topology and Atom to Site.
    At this point, this method can only convert AtomType, BondType and AngleType.
    Conversion of DihedralType will be implement in the near future.

    Parameters
    ----------
    structure : parmed.Structure
        parmed.Structure instance that need to be converted.
    refer_type : bool, optional, default=True
        Whether or not to transfer AtomType, BondType, AngleType,
        and DihedralType information

    Returns
    -------
    top : gmso.Topology
    """
    msg = "Provided argument is not a Parmed Structure"
    assert isinstance(structure, pmd.Structure), msg

    top = gmso.Topology(name=structure.title)
    site_map = dict()

    if np.all(structure.box):
        # This is if we choose for topology to have abox
        top.box = gmso.Box(
            (structure.box[0:3] * u.angstrom).in_units(u.nm),
            angles=u.degree * structure.box[3:6],
        )
    # TO DO: come up with a solution to deal with partially parametrized
    # Parmed Structure
    # Old code:
    # simple check if our pmd.Structure is fully parametrized
    # is_parametrized = True if (isinstance(structure.atoms[i].atom_type,
    #        pmd.AtomType) for i in range(len(structure.atoms))) else False

    # Consolidate parmed atomtypes and relate topology atomtypes
    if refer_type:
        pmd_top_atomtypes = _atom_types_from_pmd(structure)
        # Consolidate parmed bondtypes and relate to topology bondtypes
        bond_types_map = _get_types_map(structure, "bonds")
        pmd_top_bondtypes = _bond_types_from_pmd(
            structure, bond_types_members_map=bond_types_map
        )
        # Consolidate parmed angletypes and relate to topology angletypes
        angle_types_map = _get_types_map(structure, "angles")
        pmd_top_angletypes = _angle_types_from_pmd(
            structure, angle_types_member_map=angle_types_map
        )
        # Consolidate parmed dihedraltypes and relate to topology dihedraltypes
        dihedral_types_map = _get_types_map(structure, "dihedrals")
        dihedral_types_map.update(_get_types_map(structure, "rb_torsions"))
        pmd_top_dihedraltypes = _dihedral_types_from_pmd(
            structure, dihedral_types_member_map=dihedral_types_map
        )

    subtops = list()
    for residue in structure.residues:
        subtop_name = ("{}[{}]").format(residue.name, residue.idx)
        subtops.append(gmso.SubTopology(name=subtop_name, parent=top))
        for atom in residue.atoms:
            if refer_type and isinstance(atom.atom_type, pmd.AtomType):
                site = gmso.Atom(
                    name=atom.name,
                    charge=atom.charge * u.elementary_charge,
                    position=(
                        [atom.xx, atom.xy, atom.xz] * u.angstrom
                    ).in_units(u.nm),
                    atom_type=pmd_top_atomtypes[atom.atom_type],
                )
            else:
                site = gmso.Atom(
                    name=atom.name,
                    charge=atom.charge * u.elementary_charge,
                    position=(
                        [atom.xx, atom.xy, atom.xz] * u.angstrom
                    ).in_units(u.nm),
                    atom_type=None,
                )
            site_map[atom] = site
            subtops[-1].add_site(site)
        top.add_subtopology(subtops[-1])

    for bond in structure.bonds:
        # Generate bond parameters for BondType that gets passed
        # to Bond
        if refer_type and isinstance(bond.type, pmd.BondType):
            top_connection = gmso.Bond(
                connection_members=[site_map[bond.atom1], site_map[bond.atom2]],
                bond_type=pmd_top_bondtypes[bond.type],
            )

        # No bond parameters, make Connection with no connection_type
        else:
            top_connection = gmso.Bond(
                connection_members=[site_map[bond.atom1], site_map[bond.atom2]],
                bond_type=None,
            )

        top.add_connection(top_connection, update_types=False)
    top.update_topology()

    for angle in structure.angles:
        # Generate angle parameters for AngleType that gets passed
        # to Angle
        if refer_type and isinstance(angle.type, pmd.AngleType):
            top_connection = gmso.Angle(
                connection_members=[
                    site_map[angle.atom1],
                    site_map[angle.atom2],
                    site_map[angle.atom3],
                ],
                angle_type=pmd_top_angletypes[angle.type],
            )
        # No bond parameters, make Connection with no connection_type
        else:
            top_connection = gmso.Angle(
                connection_members=[
                    site_map[angle.atom1],
                    site_map[angle.atom2],
                    site_map[angle.atom3],
                ],
                angle_type=None,
            )
        top.add_connection(top_connection, update_types=False)

    for dihedral in structure.dihedrals:
        # Generate dihedral parameters for DihedralType that gets passed
        # to Dihedral
        # These all follow periodic torsions functions
        # (even if they are improper dihedrals)
        # Which are the default expression in top.DihedralType
        # These periodic torsion dihedrals get stored in top.dihedrals
        if dihedral.improper:
            warnings.warn(
                "ParmEd improper dihedral {} ".format(dihedral)
                + "following periodic torsion "
                + "expression detected, currently accounted for as "
                + "topology.Dihedral with a periodic torsion expression"
            )
        if refer_type and isinstance(dihedral.type, pmd.DihedralType):
            top_connection = gmso.Dihedral(
                connection_members=[
                    site_map[dihedral.atom1],
                    site_map[dihedral.atom2],
                    site_map[dihedral.atom3],
                    site_map[dihedral.atom4],
                ],
                dihedral_type=pmd_top_dihedraltypes[dihedral.type],
            )
        # No bond parameters, make Connection with no connection_type
        else:
            top_connection = gmso.Dihedral(
                connection_members=[
                    site_map[dihedral.atom1],
                    site_map[dihedral.atom2],
                    site_map[dihedral.atom3],
                    site_map[dihedral.atom4],
                ],
                dihedral_type=None,
            )
        top.add_connection(top_connection, update_types=False)

    for rb_torsion in structure.rb_torsions:
        # Generate dihedral parameters for DihedralType that gets passed
        # to Dihedral
        # These all follow RB torsion functions
        # These RB torsion dihedrals get stored in top.dihedrals
        if rb_torsion.improper:
            warnings.warn(
                "ParmEd improper dihedral {} ".format(rb_torsion)
                + "following RB torsion "
                + "expression detected, currently accounted for as "
                + "topology.Dihedral with a RB torsion expression"
            )
        if refer_type and isinstance(rb_torsion.type, pmd.RBTorsionType):
            top_connection = gmso.Dihedral(
                connection_members=[
                    site_map[rb_torsion.atom1],
                    site_map[rb_torsion.atom2],
                    site_map[rb_torsion.atom3],
                    site_map[rb_torsion.atom4],
                ],
                dihedral_type=pmd_top_dihedraltypes[rb_torsion.type],
            )
        # No bond parameters, make Connection with no connection_type
        else:
            top_connection = gmso.Dihedral(
                connection_members=[
                    site_map[rb_torsion.atom1],
                    site_map[rb_torsion.atom2],
                    site_map[rb_torsion.atom3],
                    site_map[rb_torsion.atom4],
                ],
                dihedral_type=None,
            )
        top.add_connection(top_connection, update_types=False)

    top.update_topology()

    top.combining_rule = structure.combining_rule
    return top
Esempio n. 2
0
def from_parmed(structure):
    """Convert a parmed.Structure to a gmso.Topology

    Convert a parametrized or un-parametrized parmed.Structure object to a topology.Topology.
    Specifically, this method maps Structure to Topology and Atom to Site.
    At this point, this method can only convert AtomType, BondType and AngleType.
    Conversion of DihedralType will be implement in the near future.

    Parameters
    ----------
    structure : parmed.Structure
        parmed.Structure instance that need to be converted.

    Returns
    -------
    top : gmso.Topology
    """
    msg = ("Provided argument that is not a Parmed Structure")
    assert isinstance(structure, pmd.Structure), msg

    top = gmso.Topology(name=structure.title)
    site_map = dict()
    for atom in structure.atoms:
        if isinstance(atom.atom_type, pmd.AtomType):
            atom_type = gmso.AtomType(
                name=atom.atom_type.name,
                charge=atom.atom_type.charge * u.elementary_charge,
                parameters={
                    'sigma': (atom.sigma * u.angstrom).in_units(u.nm),
                    'epsilon': atom.epsilon * u.Unit('kcal / mol')
                })
            site = gmso.Site(
                name=atom.name,
                charge=atom.charge * u.elementary_charge,
                position=([atom.xx, atom.xy, atom.xz] * u.angstrom).in_units(
                    u.nm),
                atom_type=atom_type)
        else:
            site = gmso.Site(
                name=atom.name,
                charge=atom.charge * u.elementary_charge,
                position=([atom.xx, atom.xy, atom.xz] * u.angstrom).in_units(
                    u.nm),
                atom_type=None)
        site_map[atom] = site
        top.add_site(site)
    top.update_topology()

    if np.all(structure.box):
        # This is if we choose for topology to have abox
        top.box = gmso.Box(
            (structure.box[0:3] * u.angstrom).in_units(u.nm),
            angles=u.degree * structure.box[3:6])

    for bond in structure.bonds:
        # Generate bond parameters for BondType that gets passed
        # to Bond
        if isinstance(bond.type, pmd.BondType):
            bond_params = {
                'k': (2 * bond.type.k * u.Unit('kcal / (nm**2 * mol)')),
                'r_eq': (bond.type.req * u.angstrom).in_units(u.nm)
            }
            new_connection_type = gmso.BondType(parameters=bond_params)
            top_connection = gmso.Bond(connection_members=[site_map[bond.atom1],
                site_map[bond.atom2]],
                connection_type=new_connection_type)

        # No bond parameters, make Connection with no connection_type
        else:
            top_connection = gmso.Bond(connection_members=[site_map[bond.atom1],
                site_map[bond.atom2]],
                connection_type=None)

        top.add_connection(top_connection, update_types=False)
    top.update_topology()
    print(top.n_bonds)

    for angle in structure.angles:
        # Generate angle parameters for AngleType that gets passed
        # to Angle
        if isinstance(angle.type, pmd.AngleType):
            angle_params = {
                'k': (2 * angle.type.k * u.Unit('kcal / (rad**2 * mol)')),
                'theta_eq': (angle.type.theteq * u.degree)
            }
            new_connection_type = gmso.AngleType(parameters=angle_params)
            top_connection = gmso.Angle(connection_members=[site_map[angle.atom1],
                site_map[angle.atom2], site_map[angle.atom3]],
                connection_type=new_connection_type)

        # No bond parameters, make Connection with no connection_type
        else:
            top_connection = gmso.Angle(connection_members=[site_map[angle.atom1],
                site_map[angle.atom2], site_map[angle.atom3]],
                connection_type=None)

        top.add_connection(top_connection, update_types=False)
    top.update_topology()

    # TODO: Dihedrals


    return top