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