package name.mjw.jamber.IO;
import name.mjw.jamber.IO.AMBER.Atom;
import name.mjw.jamber.IO.AMBER.Connection;
import name.mjw.jamber.IO.AMBER.Residue;
import name.mjw.jamber.util.ChemicalSymbol;
import org.apache.log4j.Logger;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.ParseException;
/**
* Support for reading a Mol2 file.
* <p>
* For more details, see the Mol2 file format specification <a
* href="http://www.tripos.com/data/support/mol2.pdf"> here </a>.
* <p>
* Its use within AMBER is generally to convey parameterised {@link Residue}
* information from AnteChamber to LEaP.
*
* @author mjw
*
*/
public class Mol2 {
private final Logger LOG = Logger.getLogger(Mol2.class);
//* TODO Add support for Mol2 files with multiple residues
private final Residue residue;
/** Name of the molecule */
private String molName;
/** Number of atoms in the molecule */
private Integer numAtoms;
/** Number of bonds in the molecule */
private Integer numBonds;
/** Number of substructures in the molecule */
private Integer numSubst;
// TODO Enumerate object here
/** The molecule type: SMALL, BIOPOLYMER, PROTEIN, NUCLEIC_ACID, SACCHARIDE */
private String molType;
/**
* The Charge type: NO_CHARGES, DEL_RE, GASTEIGER, GAST_HUCK, HUCKEL,
* PULLMAN, GAUSS80_CHARGES, AMPAC_CHARGES, MULLIKEN_CHARGES, DICT_ CHARGES,
* MMFF94_CHARGES, USER_CHARGES
*/
private String chargeType;
public Mol2(InputStream is) throws IOException {
if (is == null) {
throw new NullPointerException("Null argument: InputStream");
}
residue = new Residue("tmp");
try {
LOG.info("Reading Mol2 file");
read(is);
} catch (ParseException e) {
e.printStackTrace();
}
}
void read(InputStream is) throws ParseException, IOException {
String line;
// read it with BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
if (line.equals("@<TRIPOS>MOLECULE")) {
LOG.info("Reading MOLECULE section");
readMoleculeSection(br);
}
if (line.equals("@<TRIPOS>ATOM")) {
LOG.info("Reading ATOM section");
readAtomSection(br);
}
if (line.equals("@<TRIPOS>BOND")) {
LOG.info("Reading BOND section");
readBondSection(br);
}
if (line.equals("@<TRIPOS>SUBSTRUCTURE")) {
LOG.info("Reading SUBSTRUCTURE section");
readSubstructureSection(br);
}
}
br.close();
}
private void readMoleculeSection(BufferedReader br) throws IOException,
ParseException {
String line;
setMolName(br.readLine());
line = br.readLine();
LOG.info("Molecule section: " + line);
// Remove any leading white space
line = line.replaceAll("^\\s+", "").replaceAll("\\s+$", "");
String[] Tokens = line.split("\\s+");
LOG.info("Molecule section: " + Tokens[0]);
LOG.info("Molecule section: " + Tokens[1]);
LOG.info("Molecule section: " + Tokens[2]);
setNumAtoms(Integer.parseInt(Tokens[0]));
setNumBonds(Integer.parseInt(Tokens[1]));
numSubst = Integer.parseInt(Tokens[2]);
if (numSubst > 1) {
throw new ParseException(
"Multiple substructures are currently unsupported", 1);
}
setMolType(br.readLine());
setChargeType(br.readLine());
}
private void readAtomSection(BufferedReader br) throws IOException {
String line;
for (int i = 0; i < getNumAtoms(); i++) {
line = br.readLine().trim();
String[] tokens = line.split("\\s+");
LOG.debug("AtomSection line is :" + line);
LOG.debug(tokens[1]
+ "-->"
+ ChemicalSymbol.chemicalSymbolToZ(ChemicalSymbol
.amberAtomTypeToChemicalSymbol(tokens[5])));
Atom atom = new Atom(tokens[1], tokens[5],
ChemicalSymbol.chemicalSymbolToZ(ChemicalSymbol
.amberAtomTypeToChemicalSymbol(tokens[5])),
Double.parseDouble(tokens[8]));
residue.setName(tokens[7]);
residue.addAtom(atom);
}
}
private void readBondSection(BufferedReader br) throws IOException {
String line;
for (int i = 0; i < getNumBonds(); i++) {
line = br.readLine().trim();
String[] tokens = line.split("\\s+");
// bond_id origin_atom_id target_atom_id bond_type
// 1 1 2 1
/*
* Offset done because Atoms within lib start from 1, whereas
* internally here, they start from 0.
*/
Integer OffsettedIndexOfAtomA = Integer.parseInt((tokens[1])) - 1;
Integer OffsettedIndexOfAtomB = Integer.parseInt((tokens[2])) - 1;
Atom a = residue.getAtoms().get(OffsettedIndexOfAtomA);
Atom b = residue.getAtoms().get(OffsettedIndexOfAtomB);
a.setIndexWithinCurrentResidue(OffsettedIndexOfAtomA);
b.setIndexWithinCurrentResidue(OffsettedIndexOfAtomB);
Connection connection = new Connection(a, b);
residue.addConnection(connection);
}
}
private void readSubstructureSection(BufferedReader br) {
}
public String getMolName() {
return molName;
}
void setMolName(String molName) {
this.molName = molName;
}
Integer getNumAtoms() {
return numAtoms;
}
void setNumAtoms(Integer numAtoms) {
this.numAtoms = numAtoms;
}
Integer getNumBonds() {
return numBonds;
}
void setNumBonds(Integer numBonds) {
this.numBonds = numBonds;
}
public String getMolType() {
return molType;
}
void setMolType(String molType) {
this.molType = molType;
}
public String getChargeType() {
return chargeType;
}
void setChargeType(String chargeType) {
this.chargeType = chargeType;
}
public Residue getResidue() {
return residue;
}
}