[MMTK] GAFF parameters in MMTK

robjorissen at yahoo.com.au robjorissen at yahoo.com.au
Sat Feb 7 23:32:00 UTC 2009


G'day

A few people have made contributions to this list discussing the use of the GAFF forcefield. So, I wrote some code which might help. This Python script uses as input your small molecule of interest in MDL/SDF format and then uses the Antechamber suite of programs (from UCSF) to generate appropriate forcefield parameters and then store the resulting forcefield file (and a couple of other files) in a Molecules directory which is generated if it does not already exist.

A few more notes:
Obviously you need to get the Antechamber suite of programs (http://ambermd.org/antechamber/antechamber.html). From memory, if you compile in the PC/Cygwin environment, you should get the package bison which seems to used instead of YACC. It has been a while since I have compiled Antechamber.

And obviously you probably need to change the value of the ACHOME environmental variable (set in this script) to the location you have compiled Antechamber.

I hope people find this useful. I can't guarantee it is bug-free, but it seems to work for me.

Rob Jorissen
Ludwig Insitute for Cancer Research



#! /usr/bin/env python


import os, shutil, string, subprocess, sys

# add ACHOME environmental variable
ACHOME = "C:/Work_programs/antechamber-1.27"
os.environ["ACHOME"] = ACHOME

inFormat = "mdl"
outSuffix = ".prepin"
# atom_type = "amber"        # gaff, amber, bcc and sybyl
atom_type = "gaff"        # gaff, amber, bcc and sybyl

remove_files = "y"        # removes intermediate files
charge_method = 2        # corresponds to AM1-BCC

remove_prepin = "n"


def writeWithBreaks(out, list, startText, endText, perLine):
  out.write(startText)
  s = " " * (len(startText) - 1)
  n1 = len(list) - 1
  for i, l in enumerate(list):
    out.write(l)  # provisional
    if i == n1:
      pass
    elif perLine == 1:
      out.write(",\n%s" % s)
    elif (i+1) % perLine == 0 and i != 0:
      out..write(",\n%s" % s)
    else:
      out.write(", ")
  out..write(endText + "\n")



if len(sys.argv) > 2:
  netCharge = int(sys.argv[2])
else:
  netCharge = 0

# consider adding code to automatically determine the net formal
# charge from the input file


# 1. Run antechamber
exe = ACHOME + "/exe/antechamber"
prefix = (sys.argv[1].split("."))[0]
outName = prefix + "." + atom_type + ".prepin"
cmdList = [exe, "-i", sys.argv[1], "-fi", inFormat, "-o", outName, "-fo ac -c",
           str(charge_method), "-s 0 -pf", remove_files, "-at", atom_type,
           "-nc", str(netCharge)]
cmd = string.join(cmdList, " ")

subprocess.call(cmd, shell=True)
os.remove("mopac.in")
os.remove("mopac.out")


# 2. Run parmchk to find forcefield parameters not in the gaff.dat file

exe = ACHOME + "/exe/parmchk"
inParmchk = outName
outParmchk = prefix + "." + atom_type + ".parmout"

cmdList = [exe, "-i", inParmchk, "-o", outParmchk, "-f ac"]
cmd = string.join(cmdList, " ")

subprocess..call(cmd, shell=True)

# may need to add gaff.dat to this command...


# 3. Read in and process the prepin file
prepinList = open(outName, "r").readlines()
## os.remove(outName)

name = prefix
PDBname = "lig"

i0 = 2
i1 = -1
atomList = []
bondList = []
for i, line in enumerate(prepinList[2: ]):
  if line[0:4] == "ATOM":
    i1 = i
    atomname = line[12: 16].strip()
    ligname = line[17: 20].strip()
    xcoord= float(line[30: 38]..strip())
    ycoord= float(line[38: 46].strip())
    zcoord= float(line[46: 54].strip())
    pcharge = float(line[54: 64].strip())
    type = line[69: 74].strip()

    i = 0
    while atomname[i].isalpha():
      i += 1
    element = atomname[: i]

    atomList.append([element, atomname, pcharge, type,
                     xcoord, ycoord, zcoord])

  elif line[0:4] == "BOND":
    atom1 = line[8: 14].strip()
    atom2 = line[14: 19].strip()
    bType = line[19: 24].strip()
    aName1 = line[27: 32].strip()
    aName2 = line[32: 37].strip()
# still not working for all cases...   
    # print "_%s_%s...%s" % (aName1, aName2, line)
    bondList.append([aName1, aName2])


# 4. write out a parameter file to the Molecules subdirectory

thisDir = os.getcwd()
MoleculesDir = os.path.join(thisDir, "Molecules")
if not os.path.isdir(MoleculesDir):
  os.mkdir(MoleculesDir)


outFile = open(os.path.join(MoleculesDir, prefix), "w")

# title
outFile.write("name = \"%s\"\n\n" % prefix)

# atom names and elements
for atom in atomList:
  outFile.write("%s = Atom(\"%s\")\n" % (atom[1], atom[0]))
  # print atom




bondListWrite = []
for bond in bondList:
  bondListWrite.append("Bond(%s, %s)" %(bond[0], bond[1]))

writeWithBreaks(outFile, bondListWrite, "\nbonds = [", "]", 4)

typeListWrite = []
pdbListWrite = []
coordListWrite = []
for atom in atomList:
  typeListWrite.append("%s: \"%s\"" %(atom[1], atom[3]))
  pdbListWrite.append("\"%s\": %s" % (atom[1], atom[1]))
  coordListWrite.append("%s: (%.3f,  %.3f, %.3f)" %
                         (atom[1], atom[4], atom[5], atom[6]))

# write out the atom types
if atom_type == "gaff":
  atom_type = "GAFF"
thisStr = "\n" + atom_type + "_atom_type = {"
# thisStr = "\n" + "amber" + "_atom_type = {"
writeWithBreaks(outFile, typeListWrite, thisStr, "}", 4)


# write out the pdb names
startTxt = "\npdbmap = [(\"%s\", {" % ligname
writeWithBreaks(outFile, pdbListWrite, startTxt, "})]", 4)


# write out the partial charges
outFile.write("\n%s_charge = {\n" % atom_type)
for atom in atomList:
  outFile.write("    %-5s : %7.4f,\n" % (atom[1], atom[2]))
outFile.write("    }\n\n")


# write out a default set of coordinates to the parameter file
outFile.write("configurations = {\n")
writeWithBreaks(outFile, coordListWrite,
                "    \"default\": Cartesian({","})", 1)
outFile.write("    }\n")

outFile.close()



# move the parmout file into the Molecules subdirectory
parmName = "%s.%s.parmout" % (prefix, atom_type)
shutil.move(parmName, MoleculesDir)


# rename the prepin file, potentially overwriting previous version
newPDBfilename = os.path.join(MoleculesDir, (prefix + ".pdb"))
try:
  os.remove(newPDBfilename)
except:
  pass

os.rename(outName, newPDBfilename)







      Make Yahoo!7 your homepage and win a trip to the Quiksilver Pro. Find out more




More information about the mmtk mailing list