package name.mjw.jamber.IO.OpenMM;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import name.mjw.jamber.IO.Mol2;
import name.mjw.jamber.IO.AMBER.Lib;
import name.mjw.jamber.IO.AMBER.ParameterStore;
import org.apache.log4j.Logger;
/**
* Stand alone CLI tool for converting AnteChamber's GAFF output to OpenMM's
* XML. The CLI wrapping is enabled via the appassembler-maven-plugin.
*
* @author mjw
*
*/
public class AmberToOpenMM {
private final static Logger LOG = Logger.getLogger(AmberToOpenMM.class);
private final static String NAME = "amber2openmm";
private final static String AUTHOR = "Mark J. Williamson <mjw@mjw.name>";
private final static String TITLE = NAME
+ " - A tool for converting AnteChamber Mol2 output to OpenMM XML";
private final static String EXAMPLE = " "
+ NAME
+ " -i acetic_acid.mol2 -g $AMBERHOME/dat/leap/parm/gaff.dat -o acetic_acid"
+ "\n";
private static ParameterStore parameterStore;
private static Lib lib;
private static Mol2 inputMol2;
private static OpenMMXML openMMXML;
private static OptionParser optionParser = null;
/**
* Naming prefix applied to all OpenMM XML output files
*/
private static String outputPrefix = null;
public static void main(String[] args) {
// Populate the internal state of the object as directed by the command
// line options
parseArguments(args);
// Connectivity needs to be abstracted from the Mol2 file
lib = new Lib(inputMol2);
// Create the OpenMMXML object
openMMXML = new OpenMMXML(parameterStore, lib);
// Write the four bits of OpenMM XML
openAndWriteAllOpenMMXML();
}
private static void parseArguments(String[] args) {
optionParser = getOptionParser();
if (args.length == 0) {
printUsage();
System.exit(0);
}
try {
processArguments(args);
} catch (IllegalArgumentException e) {
System.out.println("IllegalArgumentException");
e.printStackTrace();
}
}
/**
* Wrapper for all OpenMM XML output writing methods
*/
private static void openAndWriteAllOpenMMXML() {
openAndWriteOpenMMXMLFF();
openAndWriteOpenMMXMLHydrogens();
openAndWriteOpenMMXMLResidues();
openAndWriteOpenMMXMLGBSA_OBC();
}
/**
* Writes the XML needed by simtk.openmm.app.forcefield.
*
* @see OpenMMXML#toFFXMLOutputStream
*/
private static void openAndWriteOpenMMXMLFF() {
String filePathFF = outputPrefix + "_ff.xml";
OutputStream outFF = null;
try {
outFF = new FileOutputStream(filePathFF);
} catch (FileNotFoundException e) {
System.out.println("Cannot open OpenMMXML output file: "
+ filePathFF);
e.printStackTrace();
}
LOG.debug("Writing OpenMMXMLFF to: " + filePathFF);
openMMXML.toFFXMLOutputStream(outFF);
try {
outFF.close();
} catch (IOException e) {
System.out.println("Cannot close OpenMMXML output file: "
+ filePathFF);
e.printStackTrace();
}
}
/**
* Writes the XML needed by simtk.openmm.app.modeller.addHydrogens().
*
* @see OpenMMXML#toHydrogensXMLOutputStream
*/
private static void openAndWriteOpenMMXMLHydrogens() {
String filePathHydrogens = outputPrefix + "_hydrogens.xml";
OutputStream outHydrogen = null;
try {
outHydrogen = new FileOutputStream(filePathHydrogens);
} catch (FileNotFoundException e) {
System.out.println("Cannot open OpenMMXML output file: "
+ filePathHydrogens);
e.printStackTrace();
}
LOG.debug("Writing OpenMMXMLHydrogens to: " + filePathHydrogens);
openMMXML.toHydrogensXMLOutputStream(outHydrogen);
try {
outHydrogen.close();
} catch (IOException e) {
System.out.println("Cannot close OpenMMXML output file: "
+ filePathHydrogens);
e.printStackTrace();
}
}
/**
* Writes the XML needed by simtk.openmm.app.modeller to parse a PDB file.
*
* @see OpenMMXML#toResiduesXMLOutputStream
*/
private static void openAndWriteOpenMMXMLResidues() {
String filePathResidues = outputPrefix + "_residues.xml";
OutputStream outResidues = null;
try {
outResidues = new FileOutputStream(filePathResidues);
} catch (FileNotFoundException e) {
System.out.println("Cannot open OpenMMXML output file: "
+ filePathResidues);
e.printStackTrace();
}
LOG.debug("Writing OpenMMXMLResidues to: " + filePathResidues);
openMMXML.toResiduesXMLOutputStream(outResidues);
try {
outResidues.close();
} catch (IOException e) {
System.out.println("Cannot close OpenMMXML output file: "
+ filePathResidues);
e.printStackTrace();
}
}
/**
* Writes the XML needed by simtk.openmm.app.modeller.GBSAOBCForce
*
* @see OpenMMXML#toGBSA_OBC_XMLOutputStream
*/
private static void openAndWriteOpenMMXMLGBSA_OBC() {
String filePathGBSA_OBC = outputPrefix + "_obc.xml";
OutputStream outResidues = null;
try {
outResidues = new FileOutputStream(filePathGBSA_OBC);
} catch (FileNotFoundException e) {
System.out.println("Cannot open OpenMMXML output file: "
+ filePathGBSA_OBC);
e.printStackTrace();
}
LOG.debug("Writing OpenMMXMLGBSA_OBC to: " + filePathGBSA_OBC);
openMMXML.toGBSA_OBC_XMLOutputStream(outResidues);
try {
outResidues.close();
} catch (IOException e) {
System.out.println("Cannot close OpenMMXML output file: "
+ filePathGBSA_OBC);
e.printStackTrace();
}
}
private static Mol2 openAndReadMol2File(String mol2FileName) {
InputStream inputStream = null;
Mol2 mol2 = null;
try {
inputStream = new FileInputStream(mol2FileName);
} catch (FileNotFoundException e) {
System.out.println("Cannot open file" + mol2FileName);
e.printStackTrace();
}
try {
mol2 = new Mol2(inputStream);
} catch (IOException e) {
System.out.println("Cannot parse mol2 file" + mol2FileName);
e.printStackTrace();
}
LOG.debug(mol2.getMolName());
return mol2;
}
private static ParameterStore openAndReadGaffFile(String gaffFileName) {
InputStream inputStream = null;
ParameterStore gaffParameterStore = null;
try {
inputStream = new FileInputStream(gaffFileName);
} catch (FileNotFoundException e) {
System.out.println("Cannot open file" + gaffFileName);
e.printStackTrace();
}
try {
gaffParameterStore = new ParameterStore();
gaffParameterStore.readParm(inputStream);
} catch (IOException e) {
System.out.println("Cannot parse ParameterStore file"
+ gaffFileName);
e.printStackTrace();
}
LOG.debug(gaffParameterStore.getTitle());
return gaffParameterStore;
}
/**
* Sets up all the valid options for this command
*
* @return OptionParser valid options
*/
private static OptionParser getOptionParser() {
return new OptionParser() {
{
acceptsAll(asList("i", "inputMol2File"),
"the input Mol2 that was generated by AnteChamber")
.withRequiredArg().ofType(String.class);
acceptsAll(
asList("g", "gaff"),
"the AMBER parameter file that contains the atomtype parameters in the Mol2 file (e.g. gaff.dat)")
.withRequiredArg().ofType(String.class);
acceptsAll(asList("o", "outputPrefix"),
"the prefix to use for the generated OpenMM XML files")
.withRequiredArg().ofType(String.class);
acceptsAll(asList("h", "?", "help"), "display this output");
}
};
}
/**
* Action the command line arguments
*
* @param args
* Command line arguments
*/
private static void processArguments(String[] args) {
OptionSet optionSet = optionParser.parse(args);
if (optionSet.has("h")) {
printUsage();
System.exit(0);
}
LOG.debug("supplied mol2 file name is: " + optionSet.valueOf("i"));
inputMol2 = openAndReadMol2File((String) optionSet.valueOf("i"));
LOG.debug("supplied gaff.dat file name is: " + optionSet.valueOf("g"));
parameterStore = openAndReadGaffFile((String) optionSet.valueOf("g"));
LOG.debug("supplied output prefix is: " + optionSet.valueOf("o"));
outputPrefix = (String) optionSet.valueOf("o");
}
@SafeVarargs
private static <T> List<T> asList(T... items) {
return Arrays.asList(items);
}
private static void printUsage() {
System.out.println("");
System.out.println(TITLE);
System.out.println(AUTHOR);
System.out.println("");
try {
optionParser.printHelpOn(System.out);
} catch (IOException e) {
System.out.println("Cannot print help options to System.out");
e.printStackTrace();
}
System.out.println("Example usage:");
System.out.println(EXAMPLE);
System.exit(0);
}
}