/* $RCSfile$
* $Author$
* $Date$
* $Revision$
*
* Copyright (C) 2004-2007 The Chemistry Development Kit (CDK) project
*
* Contact: cdk-devel@lists.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
* All we ask is that proper credit is given for our work, which includes
* - but is not limited to - adding the above copyright notice to the beginning
* of your source code files, and to any copyright notice that you may distribute
* with programs based on this work.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
package org.openscience.cdk.modeling.builder3d;
import java.awt.Color;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;
import org.openscience.cdk.AtomType;
import org.openscience.cdk.interfaces.IAtomType;
/**
* AtomType list configurator that uses the ParameterSet originally
* defined in mmff94.prm from moe. This class was added to be able to port
* mmff94 to CDK.
*
* @author chhoppe
* @cdk.created 2004-09-07
* @cdk.module forcefield
* @cdk.githash
* @cdk.keyword atom type, mmff94
*/
public class MMFF94BasedParameterSetReader {
private String configFile = "org/openscience/cdk/modeling/forcefield/data/mmff94.prm";
private InputStream ins = null;
private Map<String,Object> parameterSet;
private List<IAtomType> atomTypes;
private StringTokenizer st;
private String key = "";
private String sid;
private String configFilevdW = "org/openscience/cdk/modeling/forcefield/data/mmffvdw.prm";
private InputStream insvdW = null;
private StringTokenizer stvdW;
private String sidvdW;
private String configFileDFSB = "org/openscience/cdk/modeling/forcefield/data/mmffdfsb.par";
private InputStream insDFSB;
private StringTokenizer stDFSB;
/**
*Constructor for the MM2BasedParameterSetReader object
*/
public MMFF94BasedParameterSetReader() {
parameterSet = new Hashtable<String,Object>();
atomTypes = new Vector<IAtomType>();
}
public Map<String,Object> getParamterSet(){
return parameterSet;
}
public List<IAtomType> getAtomTypes(){
return atomTypes;
}
/**
* Sets the file containing the config data
*
* @param ins The new inputStream type InputStream
*/
public void setInputStream(InputStream ins) {
this.ins = ins;
}
/**
* Read a text based configuration file out of the force field mm2 file
*
* @exception Exception Description of the Exception
*/
private void setAtomTypeData() throws Exception {
key = "data" + sid;
List data = new Vector();
String sradius = st.nextToken();
String swell = st.nextToken();
String sapol=st.nextToken();
String sNeff=st.nextToken();
//st.nextToken();
String sDA=st.nextToken();
String sq0=st.nextToken();
String spbci=st.nextToken();
String sfcadj=st.nextToken();
stvdW.nextToken();
stvdW.nextToken();
String sA = stvdW.nextToken();
String sG = stvdW.nextToken();
try {
double well = new Double(swell).doubleValue();
double apol = new Double(sapol).doubleValue();
double Neff = new Double(sNeff).doubleValue();
double fcadj = new Double(sfcadj).doubleValue();
//double pbci = new Double(spbci).doubleValue();
double a = new Double(sA).doubleValue();
double g = new Double(sG).doubleValue();
data.add(new Double(well));
data.add(new Double(apol));
data.add(new Double(Neff));
data.add(new String(sDA));
data.add(new Double(fcadj));
data.add(new Double(spbci));
data.add(new Double(a));
data.add(new Double(g));
} catch (NumberFormatException nfe) {
throw new IOException("Data: Malformed Number due to:"+nfe);
}
//logger.debug("data : " + data);
parameterSet.put(key, data);
key="vdw"+sid;
data = new Vector();
try{
double radius = new Double(sradius).doubleValue();
data.add(new Double(radius));
}catch (NumberFormatException nfe2) {
// logger.debug("vdwError: Malformed Number due to:"+nfe2);
}
parameterSet.put(key, data);
key="charge"+sid;
data = new Vector();
try{
double q0 = new Double(sq0).doubleValue();
data.add(new Double(q0));
}catch (NumberFormatException nfe3) {
System.out.println("Charge: Malformed Number due to:"+nfe3);
}
parameterSet.put(key, data);
}
/**
* Read and stores the atom types in a vector
*
* @exception Exception Description of the Exception
*/
private void setAtomTypes() throws Exception {
String name = "";
String rootType = "";
//int an = 0;
int rl = 255;
int gl = 20;
int bl = 147;
int maxbond = 0;
int atomNr=0;
double mass = 0.0;
st.nextToken();
String sid = st.nextToken();
rootType = st.nextToken();
String smaxbond = st.nextToken();
String satomNr=st.nextToken();
String smass=st.nextToken();
name = st.nextToken();
try {
maxbond = Integer.parseInt(smaxbond);
mass= Double.parseDouble(smass);
atomNr=Integer.parseInt(satomNr);
} catch (NumberFormatException nfe) {
throw new IOException("AtomTypeTable.ReadAtypes: " +
"Malformed Number");
}
AtomType atomType = new AtomType(name, rootType);
atomType.setAtomicNumber(atomNr);
atomType.setExactMass(mass);
atomType.setFormalNeighbourCount(maxbond);
atomType.setSymbol(rootType);
Color co = new Color(rl, gl, bl);
atomType.setProperty("org.openscience.cdk.renderer.color", co);
atomType.setAtomTypeName(sid);
atomTypes.add(atomType);
}
/**
* Sets the bond attribute stored into the parameter set
*
* @exception Exception Description of the Exception
*/
private void setBond() throws Exception {
List data = new Vector();
st.nextToken();
String scode = st.nextToken();
String sid1 = st.nextToken();
String sid2 = st.nextToken();
String slen = st.nextToken();
String sk2 = st.nextToken();
String sk3 = st.nextToken();
String sk4 = st.nextToken();
String sbci = st.nextToken();
try {
double len = new Double(slen).doubleValue();
double k2 = new Double(sk2).doubleValue();
double k3 = new Double(sk3).doubleValue();
double k4 = new Double(sk4).doubleValue();
double bci = new Double(sbci).doubleValue();
data.add(new Double(len));
data.add(new Double(k2));
data.add(new Double(k3));
data.add(new Double(k4));
data.add(new Double(bci));
} catch (NumberFormatException nfe) {
throw new IOException("setBond: Malformed Number due to:"+nfe);
}
key = "bond" + scode + ";" + sid1 + ";" + sid2;
parameterSet.put(key, data);
}
/**
* Sets the angle attribute stored into the parameter set
*
* @exception Exception Description of the Exception
*/
private void setAngle() throws Exception {
List data = new Vector();
st.nextToken();
String scode = st.nextToken(); // String scode
String sid1 = st.nextToken();
String sid2 = st.nextToken();
String sid3 = st.nextToken();
String value1 = st.nextToken();
String value2 = st.nextToken();
String value3 = st.nextToken();
String value4 = st.nextToken();
try {
//int code=new Integer(scode).intValue();
double va1 = new Double(value1).doubleValue();
double va2 = new Double(value2).doubleValue();
double va3 = new Double(value3).doubleValue();
double va4 = new Double(value4).doubleValue();
data.add(new Double(va1));
data.add(new Double(va2));
data.add(new Double(va3));
data.add(new Double(va4));
key = "angle" + scode + ";" + sid1 + ";" + sid2 + ";" + sid3;
if (parameterSet.containsKey(key)) {
data = (Vector) parameterSet.get(key);
data.add(new Double(va1));
data.add(new Double(va2));
data.add(new Double(va3));
data.add(new Double(va4));
}
parameterSet.put(key, data);
} catch (NumberFormatException nfe) {
throw new IOException("setAngle: Malformed Number due to:"+nfe);
}
}
/**
* Sets the strBnd attribute stored into the parameter set
*
* @exception Exception Description of the Exception
*/
private void setStrBnd() throws Exception {
List data = new Vector();
st.nextToken();
String scode = st.nextToken(); // String scode
String sid1 = st.nextToken();
String sid2 = st.nextToken();
String sid3 = st.nextToken();
String value1 = st.nextToken();
String value2 = st.nextToken();
try {
//int code=new Integer(scode).intValue();
double va1 = new Double(value1).doubleValue();
double va2 = new Double(value2).doubleValue();
data.add(new Double(va1));
data.add(new Double(va2));
} catch (NumberFormatException nfe) {
throw new IOException("setStrBnd: Malformed Number due to:"+nfe);
}
key = "strbnd" + scode + ";" + sid1 + ";" + sid2 + ";" + sid3;
//logger.debug("key =" + key);
parameterSet.put(key, data);
}
/**
* Sets the torsion attribute stored into the parameter set
*
* @exception Exception Description of the Exception
*/
private void setTorsion() throws Exception {
List data = null;
st.nextToken();
String scode = st.nextToken(); // String scode
String sid1 = st.nextToken();
String sid2 = st.nextToken();
String sid3 = st.nextToken();
String sid4 = st.nextToken();
String value1 = st.nextToken();
String value2 = st.nextToken();
String value3 = st.nextToken();
String value4 = st.nextToken();
String value5 = st.nextToken();
try {
double va1 = new Double(value1).doubleValue();
double va2 = new Double(value2).doubleValue();
double va3 = new Double(value3).doubleValue();
double va4 = new Double(value4).doubleValue();
double va5 = new Double(value5).doubleValue();
key = "torsion" + scode + ";" + sid1 + ";" + sid2 + ";" + sid3 + ";" + sid4;
//logger.debug("key = " + key);
if (parameterSet.containsKey(key)) {
data = (Vector) parameterSet.get(key);
data.add(new Double(va1));
data.add(new Double(va2));
data.add(new Double(va3));
data.add(new Double(va4));
data.add(new Double(va5));
//logger.debug("data = " + data);
}
else{
data = new Vector();
data.add(new Double(va1));
data.add(new Double(va2));
data.add(new Double(va3));
data.add(new Double(va4));
data.add(new Double(va5));
//logger.debug("data = " + data);
}
parameterSet.put(key, data);
} catch (NumberFormatException nfe) {
throw new IOException("setTorsion: Malformed Number due to:"+nfe);
}
}
/**
* Sets the opBend attribute stored into the parameter set
*
* @exception Exception Description of the Exception
*/
private void setOpBend() throws Exception {
List data = new Vector();
st.nextToken();
String sid1 = st.nextToken();
String sid2 = st.nextToken();
String sid3 = st.nextToken();
String sid4 = st.nextToken();
String value1 = st.nextToken();
try {
double va1 = new Double(value1).doubleValue();
data.add(new Double(va1));
key = "opbend" + sid1 + ";" + sid2 + ";" + sid3 + ";" + sid4;
if (parameterSet.containsKey(key)) {
data = (Vector) parameterSet.get(key);
data.add(new Double(va1));
}
parameterSet.put(key, data);
} catch (NumberFormatException nfe) {
throw new IOException("setOpBend: Malformed Number due to:"+nfe);
}
}
/**
* Sets the Default Stretch-Bend Parameters into the parameter set
*
* @exception Exception Description of the Exception
*/
private void setDefaultStrBnd() throws Exception {
//logger.debug("Sets the Default Stretch-Bend Parameters");
List data = new Vector();
stDFSB.nextToken();
String sIR = stDFSB.nextToken();
String sJR = stDFSB.nextToken();
String sKR = stDFSB.nextToken();
String skbaIJK = stDFSB.nextToken();
String skbaKJI = stDFSB.nextToken();
try {
key = "DFSB" + sIR + ";" + sJR + ";" + sKR;
double kbaIJK = new Double(skbaIJK).doubleValue();
double kbaKJI = new Double(skbaKJI).doubleValue();
data.add(new Double(kbaIJK));
data.add(new Double(kbaKJI));
parameterSet.put(key, data);
} catch (NumberFormatException nfe) {
throw new IOException("setDFSB: Malformed Number due to:"+nfe);
}
}
/**
* The main method which parses through the force field configuration file
*
* @exception Exception Description of the Exception
*/
public void readParameterSets() throws Exception {
//vdW,bond,angle,strbond,opbend,torsion,data
//logger.debug("------ Read MMFF94 ParameterSets ------");
if (ins == null) {
ClassLoader loader = this.getClass().getClassLoader();
System.out.println("loader.getClassName:" + loader.getClass().getName());
ins = loader.getResourceAsStream(configFile);
}
if (ins == null) {
throw new IOException("There was a problem getting the default stream: " + configFile);
}
BufferedReader r = new BufferedReader(new InputStreamReader(ins), 1024);
String s;
int[] a = {0, 0, 0, 0, 0, 0, 0, 0};
if (insvdW == null) {
insvdW = this.getClass().getClassLoader().getResourceAsStream(configFilevdW);
}
if (insvdW == null) {
throw new IOException("There was a problem getting the default stream: " + configFilevdW);
}
BufferedReader rvdW = new BufferedReader(new InputStreamReader(insvdW), 1024);
String svdW;
int ntvdW;
if (insDFSB == null) {
insDFSB = this.getClass().getClassLoader().getResourceAsStream(configFileDFSB);
}
if (insDFSB == null) {
throw new IOException("There was a problem getting the default stream: " + configFileDFSB);
}
BufferedReader rDFSB = new BufferedReader(new InputStreamReader(insDFSB), 1024);
String sDFSB;
int ntDFSB;
try {
while (true) {
s = r.readLine();
if (s == null) {
break;
}
st = new StringTokenizer(s,"\t; ");
int nt = st.countTokens();
if (s.startsWith("atom") & nt <= 8) {
setAtomTypes();
a[0]++;
} else if (s.startsWith("bond") & nt == 9) {
setBond();
a[1]++;
} else if (s.startsWith("angle") & nt <= 10) {
setAngle();
a[2]++;
} else if (s.startsWith("strbnd") & nt == 7) {
setStrBnd();
a[3]++;
} else if (s.startsWith("torsion") & nt == 11) {
setTorsion();
a[4]++;
} else if (s.startsWith("opbend") & nt == 6) {
setOpBend();
a[5]++;
} else if (s.startsWith("data") & nt == 10) {
readatmmffvdw:
while (true) {
svdW = rvdW.readLine();
if (svdW == null) {
break;
}
stvdW = new StringTokenizer(svdW,"\t; ");
ntvdW = stvdW.countTokens();
//logger.debug("ntvdW : " + ntvdW);
if (svdW.startsWith("vdw") & ntvdW == 9) {
st.nextToken();
sid = st.nextToken();
stvdW.nextToken();
sidvdW = stvdW.nextToken();
if (sid.equals(sidvdW)) {
setAtomTypeData();
a[6]++;
}
break readatmmffvdw;
}
}// end while
}
}// end while
ins.close();
insvdW.close();
} catch (IOException e) {
System.err.println(e.toString());
throw new IOException("There was a problem parsing the mmff94 forcefield");
}
try {
//logger.debug("Parses the Default Stretch-Bend Parameters");
while (true) {
sDFSB = rDFSB.readLine();
//logger.debug("sDFSB = " + sDFSB);
if (sDFSB == null) {
//logger.debug("sDFSB == null, break");
break;
}
stDFSB = new StringTokenizer(sDFSB,"\t; ");
ntDFSB = stDFSB.countTokens();
//logger.debug("ntDFSB : " + ntDFSB);
if (sDFSB.startsWith("DFSB") & ntDFSB == 6) {
setDefaultStrBnd();
}
}
insDFSB.close();
//logger.debug("insDFSB closed");
} catch (IOException e) {
System.err.println(e.toString());
throw new IOException("There was a problem parsing the Default Stretch-Bend Parameters (mmffdfsb.par)");
}
}
}