/* $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)"); } } }