1 /* $RCSfile$ 2 * $Author: hansonr $ 3 * $Date: 2006-10-22 14:12:46 -0500 (Sun, 22 Oct 2006) $ 4 * $Revision: 5999 $ 5 * 6 * Copyright (C) 2003-2005 Miguel, Jmol Development, www.jmol.org 7 * 8 * Contact: jmol-developers@lists.sf.net 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2.1 of the License, or (at your option) any later version. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 23 */ 24 25 package org.jmol.adapter.readers.molxyz; 26 27 import java.util.Hashtable; 28 import java.util.Map; 29 30 import javajs.util.PT; 31 32 import org.jmol.adapter.smarter.Atom; 33 import org.jmol.adapter.smarter.AtomSetCollectionReader; 34 35 /** 36 * A reader for Accelrys V3000 files. 37 * <p> 38 * <a href='http://www.mdli.com/downloads/public/ctfile/ctfile.jsp'> 39 * http://www.mdli.com/downloads/public/ctfile/ctfile.jsp </a> 40 * <p> 41 */ 42 public class V3000Rdr { 43 private MolReader mr; 44 private String line; 45 V3000Rdr()46 public V3000Rdr() { 47 // for reflection 48 } 49 set(AtomSetCollectionReader mr)50 V3000Rdr set(AtomSetCollectionReader mr) { 51 this.mr = (MolReader) mr; 52 return this; 53 } 54 readAtomsAndBonds(String[] tokens)55 void readAtomsAndBonds(String[] tokens) throws Exception { 56 int ac = mr.parseIntStr(tokens[3]); 57 readAtoms(ac); 58 mr.asc.setModelInfoForSet("dimension", (mr.is2D ? "2D" : "3D"), mr.asc.iSet); 59 60 readBonds(mr.parseIntStr(tokens[4])); 61 readUserData(ac); 62 } 63 64 // 0 1 2 3 4 5 6 7 65 // 01234567890123456789012345678901234567890123456789012345678901234567890 66 // xxxxx.xxxxyyyyy.yyyyzzzzz.zzzz aaaddcccssshhhbbbvvvHHHrrriiimmmnnneee 67 readAtoms(int ac)68 private void readAtoms(int ac) throws Exception { 69 mr.discardLinesUntilContains("BEGIN ATOM"); 70 for (int i = 0; i < ac; ++i) { 71 rd(); 72 checkLineContinuation(); 73 String[] tokens = mr.getTokens(); 74 int iAtom = mr.parseIntStr(tokens[2]); 75 String elementSymbol = tokens[3]; 76 if (elementSymbol.equals("*")) 77 continue; 78 float x = mr.parseFloatStr(tokens[4]); 79 float y = mr.parseFloatStr(tokens[5]); 80 float z = mr.parseFloatStr(tokens[6]); 81 int charge = 0; 82 int isotope = 0; 83 if (mr.is2D && z != 0) 84 mr.is2D = mr.optimize2D = false; 85 86 for (int j = 7; j < tokens.length; j++) { 87 String s = tokens[j].toUpperCase(); 88 if (s.startsWith("CHG=")) 89 charge = mr.parseIntAt(tokens[j], 4); 90 else if (s.startsWith("MASS=")) 91 isotope = mr.parseIntAt(tokens[j], 5); 92 } 93 if (isotope > 1 && elementSymbol.equals("H")) 94 isotope = 1 - isotope; 95 mr.addMolAtom(iAtom, isotope, elementSymbol, charge, x, y, z); 96 } 97 mr.discardLinesUntilContains("END ATOM"); 98 } 99 readBonds(int bondCount)100 private void readBonds(int bondCount) throws Exception { 101 mr.discardLinesUntilContains("BEGIN BOND"); 102 if (bondCount == 0) 103 mr.asc.setNoAutoBond(); 104 for (int i = 0; i < bondCount; ++i) { 105 rd(); 106 int stereo = 0; 107 checkLineContinuation(); 108 String[] tokens = mr.getTokens(); 109 int order = mr.parseIntStr(tokens[3]); 110 String iAtom1 = tokens[4]; 111 String iAtom2 = tokens[5]; 112 String cfg = getField("CFG"); 113 if (cfg == null) { 114 String endpts = getField("ENDPTS"); 115 if (endpts != null && line.indexOf("ATTACH=ALL") >= 0) { 116 // not "ATTACH=ANY" 117 tokens = PT.getTokens(endpts); 118 int n = mr.parseIntStr(tokens[0]); 119 int o = mr.fixOrder(order, 0); 120 for (int k = 1; k <= n; k++) 121 mr.asc.addNewBondFromNames(iAtom1, tokens[k], o); 122 } 123 } else { 124 stereo = mr.parseIntStr(cfg); 125 } 126 mr.addMolBond(iAtom1, iAtom2, order, stereo); 127 } 128 mr.discardLinesUntilContains("END BOND"); 129 } 130 131 private Map<String, String[]> userData; 132 readUserData(int ac)133 private void readUserData(int ac) throws Exception { 134 userData = null; 135 String pc = null; 136 while (!rd().contains("END CTAB")) { 137 if (!line.contains("BEGIN SGROUP")) 138 continue; 139 String atoms, name, data; 140 while (!rd().contains("END SGROUP")) { 141 if (userData == null) 142 userData = new Hashtable<String, String[]>(); 143 if ((atoms = getField("ATOMS")) == null 144 || (name = getField("FIELDNAME")) == null 145 || (data = getField("FIELDDATA")) == null) 146 continue; 147 name = name.toLowerCase(); 148 boolean isPartial = (name.indexOf("partial") >= 0); 149 if (isPartial) { 150 if (pc == null) 151 pc = name; 152 else if (!pc.equals(name)) 153 isPartial = false; 154 } 155 if (isPartial) { 156 Atom[] at = mr.asc.atoms; 157 for (int i = mr.asc.getLastAtomSetAtomIndex(), n = mr.asc.ac; i < n; i++) 158 at[i].partialCharge = 0; 159 } 160 String[] a = null; 161 float f = 0; 162 if (isPartial) 163 f = mr.parseFloatStr(data); 164 else if ((a = userData.get(name)) == null) 165 userData.put(name, a = new String[ac]); 166 try { 167 String[] tokens = PT.getTokens(atoms); 168 for (int i = tokens.length; --i >= 1;) { 169 String atom = tokens[i]; 170 if (isPartial) 171 mr.asc.getAtomFromName(atom).partialCharge = f; 172 else 173 a[mr.parseIntStr(atom) - 1] = data; 174 } 175 } catch (Exception e) { 176 // ignore 177 } 178 } 179 } 180 if (userData == null) 181 return; 182 for (String key : userData.keySet()) { 183 String[] a = userData.get(key); 184 float[] f = new float[a.length]; 185 for (int i = 0; i < a.length; i++) 186 f[i] = (a[i] == null ? 0 : mr.parseFloatStr(a[i])); 187 mr.asc.setAtomProperties(key, f, -1, false); 188 } 189 } 190 getField(String key)191 private String getField(String key) { 192 int pt = line.indexOf(key + "="); 193 if (pt < 0) 194 return null; 195 pt += key.length() + 1; 196 char term = ' '; 197 switch (line.charAt(pt)) { 198 case '"': 199 term = '"'; 200 break; 201 case '(': 202 term = ')'; 203 break; 204 case '+': 205 break; 206 default: 207 pt--; 208 break; 209 } 210 return line.substring(pt + 1, (line + term).indexOf(term, pt + 1)); 211 } 212 rd()213 private String rd() throws Exception { 214 return (line = mr.rd()); 215 } 216 checkLineContinuation()217 private void checkLineContinuation() throws Exception { 218 while (line.endsWith("-")) { 219 String s = line; 220 rd(); 221 line = s + line; 222 } 223 } 224 225 } 226