Exemple #1
0
def writeRTF(mol, parameters, netcharge, filename):
    from moleculekit.periodictable import periodictable_by_number

    f = open(filename, "w")
    print("* Charmm RTF built by HTMD parameterize version {}".format(
        version()),
          file=f)
    print("* ", file=f)
    print("  22     0", file=f)
    types = getSortedAndUniqueTypes(mol.atomtype, "atom_types")
    for type in types:
        val = parameters.atom_types[type]
        print(
            "MASS %5d %s %8.5f %s" % (
                val.number,
                type,
                val.mass,
                periodictable_by_number[val.atomic_number].symbol,
            ),
            file=f,
        )
    print("\nAUTO ANGLES DIHE\n", file=f)
    assert (np.unique(mol.resname).size == 1
            )  # Check if all atoms have the same residue name
    print("RESI %s %8.5f" % (mol.resname[0], netcharge), file=f)
    print("GROUP", file=f)

    maxnamelen = max(4,
                     np.max([len(na)
                             for na in mol.name]))  # Minimum field size of 4
    maxatomtypelen = max(6, np.max([len(at) for at in mol.atomtype
                                    ]))  # Minimum field size of 6
    for n, a, c in zip(mol.name, mol.atomtype, mol.charge):
        print(
            "ATOM {0:>{1}s} {2:>{3}s} {4:8.6f}".format(n, maxnamelen, a,
                                                       maxatomtypelen, c),
            file=f,
        )
    for a in mol.bonds:
        print(
            "BOND {:>4s} {:>4s}".format(
                *sorted([mol.name[a[0]], mol.name[a[1]]])),
            file=f,
        )
    for a in mol.impropers:
        print(
            "IMPR %4s %4s %4s %4s" %
            (mol.name[a[0]], mol.name[a[1]], mol.name[a[2]], mol.name[a[3]]),
            file=f,
        )
    print("PATCH FIRST NONE LAST NONE", file=f)
    print("\nEND", file=f)
    f.close()
Exemple #2
0
def getArgumentParser():

    parser = argparse.ArgumentParser(
        description="Acellera small molecule parameterization tool")

    parser.add_argument("filename", help="Molecule file in MOL2 format")
    parser.add_argument(
        "-c",
        "--charge",
        type=int,
        help="Total charge of the molecule (default: sum of partial charges)",
    )
    parser.add_argument("-l",
                        "--list",
                        action="store_true",
                        help="List parameterizable dihedral angles")
    parser.add_argument("--rtf-prm",
                        nargs=2,
                        metavar="<filename>",
                        help="CHARMM RTF and PRM files")
    parser.add_argument(
        "-ff",
        "--forcefield",
        default="GAFF2",
        choices=fftypemethods,
        help=
        "Initial atom type and parameter assignment (default: %(default)s)",
    )
    parser.add_argument(
        "--fix-charge",
        nargs="+",
        default=[],
        metavar="<atom name>",
        help="Fix atomic charge during charge fitting (default: none)",
    )
    parser.add_argument(
        "-d",
        "--dihedral",
        nargs="+",
        default=[],
        metavar="A1-A2-A3-A4",
        help=
        "Select dihedral angle to parameterize (default: all parameterizable dihedral angles)",
    )
    parser.add_argument(
        "--code",
        default="Psi4",
        choices=["Psi4", "Gaussian"],
        help="QM code (default: %(default)s)",
    )
    parser.add_argument(
        "--theory",
        default="wB97X-D",
        choices=["HF", "B3LYP", "wB97X-D"],
        help="QM level of theory (default: %(default)s)",
    )
    parser.add_argument(
        "--basis",
        default="6-311++G**",
        choices=[
            "6-31G*",
            "6-31+G*",
            "6-311G**",
            "6-311++G**",
            "cc-pVDZ",
            "aug-cc-pVDZ",
        ],
        help="QM basis set (default: %(default)s)",
    )
    parser.add_argument(
        "--environment",
        default="vacuum",
        choices=["vacuum", "PCM"],
        help="QM environment (default: %(default)s)",
    )
    parser.add_argument(
        "--min-type",
        default="mm",
        dest="min_type",
        choices=["None", "qm", "mm"],
        help="Type of initial structure optimization (default: %(default)s)",
    )
    parser.add_argument(
        "--charge-type",
        default="AM1-BCC",
        choices=["None", "Gasteiger", "AM1-BCC", "ESP"],
        help="Partial atomic charge type (default: %(default)s)",
    )
    parser.add_argument(
        "--no-dihed",
        action="store_false",
        dest="fit_dihedral",
        help="Do not perform QM scanning of dihedral angles",
    )
    parser.add_argument(
        "--scan-type",
        default="mm",
        dest="dihed_opt_type",
        choices=["None", "qm", "mm"],
        help=
        "Type of structure optimization when scanning dihedral angles (default: %(default)s)",
    )
    parser.add_argument(
        "--dihed-num-iterations",
        default=3,
        type=int,
        help="Number of iterations during the dihedral parameter fitting",
    )
    parser.add_argument(
        "--dihed-fit-type",
        default="iterative",
        choices=["iterative", "NRS"],
        help=
        "Dihedral fitting method. Can be either iterative or naive random search (NRS).",
    )
    parser.add_argument(
        "-q",
        "--queue",
        default="local",
        choices=["local", "Slurm", "LSF"],
        help="QM queue (default: %(default)s)",
    )
    parser.add_argument(
        "-n",
        "--ncpus",
        default=None,
        type=int,
        help="Number of CPU per QM job (default: queue defaults)",
    )
    parser.add_argument(
        "-m",
        "--memory",
        default=None,
        type=int,
        help="Maximum amount of memory in MB to use.",
    )
    parser.add_argument("--groupname", default=None, help=argparse.SUPPRESS)
    parser.add_argument("-o",
                        "--outdir",
                        default="./",
                        help="Output directory (default: %(default)s)")
    parser.add_argument(
        "--seed",
        default=20170920,
        type=int,
        help="Random number generator seed (default: %(default)s)",
    )
    parser.add_argument("--version", action="version", version=version())

    # Enable replacement of any real QM class with FakeQM.
    # This is intedended for debugging only and should be kept hidden.
    parser.add_argument(
        "--fake-qm",
        action="store_true",
        default=False,
        dest="fake_qm",
        help=argparse.SUPPRESS,
    )

    # NNP module name
    parser.add_argument("--nnp", help=argparse.SUPPRESS)

    # PlayQueue arguments
    parser.add_argument("--pm-token", help=argparse.SUPPRESS)
    parser.add_argument("--max-jobs",
                        type=int,
                        default=sys.maxsize,
                        help=argparse.SUPPRESS)

    # Debug mode
    parser.add_argument(
        "--debug",
        action="store_true",
        default=False,
        dest="debug",
        help=argparse.SUPPRESS,
    )

    return parser
Exemple #3
0
def writeFRCMOD(mol, parameters, filename, typemap=None):

    if typemap is not None:
        parameters = mapAtomTypesParameterSet(parameters, typemap)
        atomtypes = np.vectorize(typemap.get)(mol.atomtype)
    else:
        atomtypes = mol.atomtype

    f = open(filename, "w")
    f.write("Frcmod generated by HTMD parameterize version {}\n".format(
        version()))
    f.write("MASS\n")
    for at in np.unique(atomtypes):
        f.write("{:<2s}  {:>8.3f} {:>10.2f}\n".format(
            at, parameters.atom_types[at].mass, 0.0))

    f.write("\nBOND\n")
    types = getSortedAndUniqueTypes(atomtypes[mol.bonds], "bond_types")
    for type in types:
        val = getParameter(type, parameters.bond_types)
        f.write("{:<2s}-{:<2s} {:>10.3f}{:>8.3f}\n".format(
            type[0], type[1], val.k, val.req))

    f.write("\nANGL\n")
    types = getSortedAndUniqueTypes(atomtypes[mol.angles], "angle_types")
    for type in types:
        val = getParameter(type, parameters.angle_types)
        f.write("{:<2s}-{:<2s}-{:<2s} {:>10.3f}{:>9.3f}\n".format(
            type[0], type[1], type[2], val.k, val.theteq))

    f.write("\nDIHE\n")
    types = getSortedAndUniqueTypes(atomtypes[mol.dihedrals], "dihedral_types")
    for type in types:
        val = getParameter(type, parameters.dihedral_types)

        toprint = []
        for term in val:
            if term.phi_k < 1e-6:
                continue
            toprint.append(term)

        # HACK: print at least one dihedral, even if the force constant is 0, otherwise "tleap" is not happy!
        if len(toprint) == 0:
            toprint.append(val[0])

        for i, term in enumerate(toprint):
            # All terms of the same dihedral except the last one should be negative. http://ambermd.org/formats.html#frcmod
            per = term.per
            if i != len(toprint) - 1:
                per = -per
            fmt = "{:<2s}-{:<2s}-{:<2s}-{:<2s} {:>4d}{:>15.8f}{:>9.3f}{:>6.1f}    SCEE={:1.1f} SCNB={:1.1f}\n"
            f.write(
                fmt.format(
                    type[0],
                    type[1],
                    type[2],
                    type[3],
                    1,
                    term.phi_k,
                    term.phase,
                    per,
                    term.scee,
                    term.scnb,
                ))

    f.write("\nIMPR\n")
    types = getSortedAndUniqueTypes(atomtypes[mol.impropers], "improper_types")
    for type in types:
        type, field = findImproperType(type, parameters)
        val = parameters.__dict__[field][type]
        fmt = "{:<2s}-{:<2s}-{:<2s}-{:<2s}     {:>10.8f}{:>9.3f}{:>6.1f}\n"
        if field == "improper_periodic_types":
            if val.phi_k < 1e-6:
                continue
            f.write(
                fmt.format(type[0], type[1], type[2], type[3], val.phi_k,
                           val.phase, val.per))
        elif field == "improper_types":
            if val.psi_k < 1e-6:
                continue
            f.write(
                fmt.format(type[0], type[1], type[2], type[3], val.psi_k,
                           val.psi_eq, 1))

    f.write("\nNONB\n")
    # Have to iterate over the types in use, which include cloned types, and map them back
    # to original type (which has the same vdw params), because a copy of a copy won't be in self.nonbonded.
    types = getSortedAndUniqueTypes(atomtypes, "atom_types")
    for type in types:
        val = parameters.atom_types[type]
        f.write("{:<2s}    {:>10.8f}   {:>10.8f}\n".format(
            type, val.rmin, val.epsilon))
    f.write("\n")
    f.close()
Exemple #4
0
def writePRM(mol, parameters, filename):
    from parameterize.util import ensurelist

    # for type, val in parameters.atom_types.items():
    #     if val.epsilon_14 != 1.0:
    #         raise ValueError("Can't express 1-4 electrostatic scaling in Charmm file format")

    f = open(filename, "w")
    print("* prm file built by HTMD parameterize version {}".format(version()),
          file=f)
    print("*\n", file=f)

    print("BONDS", file=f)
    types = getSortedAndUniqueTypes(mol.atomtype[mol.bonds], "bond_types")
    for type in types:
        val = getParameter(type, parameters.bond_types)
        print("%-6s %-6s %8.2f %8.4f" % (type[0], type[1], val.k, val.req),
              file=f)

    print("\nANGLES", file=f)
    types = getSortedAndUniqueTypes(mol.atomtype[mol.angles], "angle_types")
    for type in types:
        val = getParameter(type, parameters.angle_types)
        print(
            "%-6s %-6s %-6s %8.2f %8.2f" %
            (type[0], type[1], type[2], val.k, val.theteq),
            file=f,
        )

    print("\nDIHEDRALS", file=f)
    types = getSortedAndUniqueTypes(mol.atomtype[mol.dihedrals],
                                    "dihedral_types")
    for type in types:
        val = getParameter(type, parameters.dihedral_types)
        for term in val:
            print(
                "%-6s %-6s %-6s %-6s %12.8f %d %12.8f" % (
                    type[0],
                    type[1],
                    type[2],
                    type[3],
                    term.phi_k,
                    term.per,
                    term.phase,
                ),
                file=f,
            )

    print("\nIMPROPER", file=f)
    types = getSortedAndUniqueTypes(mol.atomtype[mol.impropers],
                                    "improper_types")
    for type in types:
        type, field = findImproperType(type, parameters)
        val = parameters.__dict__[field][type]
        if field == "improper_periodic_types":
            for term in ensurelist(val):
                print(
                    "%-6s %-6s %-6s %-6s %12.8f %d %12.8f" % (
                        type[0],
                        type[1],
                        type[2],
                        type[3],
                        term.phi_k,
                        term.per,
                        term.phase,
                    ),
                    file=f,
                )
        elif field == "improper_types":
            print(
                "%-6s %-6s %-6s %-6s %12.8f %d %12.8f" %
                (type[0], type[1], type[2], type[3], val.psi_k, 0, val.psi_eq),
                file=f,
            )

    print("\nNONBONDED nbxmod  5 atom cdiel shift vatom vdistance vswitch -",
          file=f)
    print("cutnb 14.0 ctofnb 12.0 ctonnb 10.0 eps 1.0 e14fac 1.0 wmin 1.5",
          file=f)
    types = getSortedAndUniqueTypes(mol.atomtype, "atom_types")
    for type in types:
        val = parameters.atom_types[type]
        if val.epsilon_14 != val.epsilon:
            print(
                "%-6s 0.0000 %8.4f %8.4f 0.0000 %8.4f %8.4f" %
                (type, val.epsilon, val.rmin, val.epsilon_14, val.rmin_14),
                file=f,
            )
        else:
            print("%-6s 0.0000 %8.4f %8.4f" % (type, val.epsilon, val.rmin),
                  file=f)
    f.close()