Source code: joelib/io/types/cml/MoleculeHuge.java
1 ///////////////////////////////////////////////////////////////////////////////
2 // Filename: $RCSfile: MoleculeHuge.java,v $
3 // Purpose: Reader/Writer for CML files.
4 // Language: Java
5 // Compiler: JDK 1.4
6 // Authors: Joerg K. Wegner
7 // Version: $Revision: 1.17 $
8 // $Date: 2003/08/22 15:56:18 $
9 // $Author: wegner $
10 // Original Author: steinbeck@ice.mpg.de, gezelter@maul.chem.nd.edu, egonw@sci.kun.nl
11 // Original Version: Chemical Development Kit, http://sourceforge.net/projects/cdk
12 //
13 // Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
14 //
15 // This program is free software; you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation version 2 of the License.
18 //
19 // This program is distributed in the hope that it will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 // GNU General Public License for more details.
23 ///////////////////////////////////////////////////////////////////////////////
24 package joelib.io.types.cml;
25
26 import joelib.data.JOEDataType;
27 import joelib.data.JOEElementTable;
28 import joelib.data.JOEGenericData;
29 import joelib.data.JOEPairData;
30
31 import joelib.desc.result.AtomDoubleResult;
32
33 import joelib.math.XYZVector;
34
35 import joelib.molecule.JOEAtom;
36 import joelib.molecule.JOEBond;
37 import joelib.molecule.JOEMol;
38
39 import joelib.util.IsomerismDetection;
40 import joelib.util.JHM;
41
42 import joelib.util.iterator.AtomIterator;
43 import joelib.util.iterator.BondIterator;
44
45 /*==========================================================================*
46 * IMPORTS
47 *========================================================================== */
48 import java.io.PrintStream;
49
50 import java.util.Vector;
51
52 import org.apache.log4j.Category;
53
54
55 /*==========================================================================*
56 * CLASS DECLARATION
57 *========================================================================== */
58
59 /**
60 * CML molecule writing all informations explicitely.
61 *
62 * @author wegnerj
63 * @license GPL
64 * @cvsversion $Revision: 1.17 $, $Date: 2003/08/22 15:56:18 $
65 */
66 public class MoleculeHuge implements CMLMoleculeWriter
67 {
68 //~ Static fields/initializers /////////////////////////////////////////////
69
70 /*-------------------------------------------------------------------------*
71 * public static member variables
72 *------------------------------------------------------------------------- */
73
74 /**
75 * Obtain a suitable logger.
76 */
77 private static Category logger = Category.getInstance(
78 "joelib.io.types.cml.MoleculeHuge");
79
80 //~ Instance fields ////////////////////////////////////////////////////////
81
82 /*-------------------------------------------------------------------------*
83 * private member variables
84 *------------------------------------------------------------------------- */
85 private CMLWriterProperties writerProp = null;
86
87 //~ Constructors ///////////////////////////////////////////////////////////
88
89 /*-------------------------------------------------------------------------*
90 * constructor
91 *------------------------------------------------------------------------- */
92 public MoleculeHuge(CMLWriterProperties _writerProp)
93 {
94 if (logger.isDebugEnabled())
95 {
96 logger.debug("Initializing " + this.getClass().getName());
97 }
98
99 writerProp = _writerProp;
100 }
101
102 //~ Methods ////////////////////////////////////////////////////////////////
103
104 /*-------------------------------------------------------------------------*
105 * public methods
106 *------------------------------------------------------------------------- */
107 public synchronized void write(PrintStream ps, JOEMol mol,
108 boolean writePairData, Vector attribs2write)
109 {
110 ps.print("<molecule>" + JHM.eol);
111
112 boolean has3D = false;
113 boolean has2D = false;
114 AtomDoubleResult adrX = null;
115 AtomDoubleResult adrY = null;
116
117 if (mol.has2D())
118 {
119 has2D = true;
120 }
121
122 if (mol.hasData(CMLPropertyWriter.COORDINATES_2D_X) &&
123 mol.hasData(CMLPropertyWriter.COORDINATES_2D_Y))
124 {
125 JOEGenericData genericData = mol.getData(CMLPropertyWriter.COORDINATES_2D_X,
126 true);
127 JOEPairData pairData;
128
129 if (genericData.getDataType() == JOEDataType.JOE_PAIR_DATA)
130 {
131 pairData = (JOEPairData) genericData;
132
133 if (pairData.getValue() instanceof AtomDoubleResult)
134 {
135 adrX = (AtomDoubleResult) pairData.getValue();
136 genericData = mol.getData(CMLPropertyWriter.COORDINATES_2D_Y,
137 true);
138
139 if (genericData.getDataType() == JOEDataType.JOE_PAIR_DATA)
140 {
141 pairData = (JOEPairData) genericData;
142
143 if (pairData.getValue() instanceof AtomDoubleResult)
144 {
145 adrY = (AtomDoubleResult) pairData.getValue();
146 has2D = true;
147 }
148 }
149 }
150 }
151 }
152
153 if (mol.has3D())
154 {
155 has3D = true;
156 }
157
158 // assume 3D coordinates, if both are not available !;-)
159 // Any coordinates must be stored
160 if (!has3D && !has2D)
161 {
162 has3D = true;
163 }
164
165 JOEAtom atom;
166 AtomIterator ait = mol.atomIterator();
167
168 while (ait.hasNext())
169 {
170 atom = ait.nextAtom();
171 write(ps, atom, has2D, has3D, adrX, adrY);
172 }
173
174 BondIterator bit = mol.bondIterator();
175 JOEBond bond;
176
177 while (bit.hasNext())
178 {
179 bond = bit.nextBond();
180 write(ps, bond);
181 }
182
183 // write molecule title
184 if (mol.getTitle() != null)
185 {
186 ps.print(" <name convention=\"trivial\">" + mol.getTitle() +
187 "</name>" + JHM.eol);
188 }
189
190 // write symmetry informations
191 if (writerProp.writeSymmetryInformations())
192 {
193 CMLSymmetryWriter.writeSymmetry(ps, mol);
194 }
195
196 // write descriptor values
197 CMLPropertyWriter.writeProperties(writerProp, ps, mol, writePairData,
198 attribs2write);
199
200 ps.print("</molecule>" + JHM.eol);
201 }
202
203 /*-------------------------------------------------------------------------*
204 * private methods
205 *------------------------------------------------------------------------- */
206
207 /**
208 * Description of the Method
209 *
210 * @param atom Description of the Parameter
211 */
212 private synchronized void write(PrintStream ps, JOEAtom atom,
213 boolean write2D, boolean write3D, AtomDoubleResult x, AtomDoubleResult y)
214 {
215 ps.print(" <atom id=\"a" + atom.getIdx() + "\">" + JHM.eol);
216 ps.print(" <string builtin=\"elementType\">");
217 ps.print(JOEElementTable.instance().getSymbol(atom.getAtomicNum()));
218 ps.print("</string>" + JHM.eol);
219
220 // write(atom.getPoint2D());
221 if (write3D)
222 {
223 write3D(ps, atom.getVector());
224 }
225
226 if (write2D)
227 {
228 write2D(ps, atom.getVector(), x, y, atom.getIdx());
229 }
230
231 if (writerProp.forceWriteFormalCharge() ||
232 (atom.getFormalCharge() != 0))
233 {
234 ps.print(" <integer builtin=\"formalCharge\">");
235 ps.print(atom.getFormalCharge());
236 ps.print("</integer>" + JHM.eol);
237 }
238
239 if (writerProp.writePartialCharge())
240 {
241 //if (!atom.getParent().hasPartialChargesPerceived())
242 //{
243 // //seed partial charges are set in the atom typing procedure
244 // JOEPhModel.instance().assignSeedPartialCharge(atom.getParent());
245 // JOEGastChrg gc = new JOEGastChrg();
246 // gc.assignPartialCharges(atom.getParent());
247 //}
248 //CML1
249 ps.print(" <float builtin=\"partialCharge\">");
250 ps.print(atom.getPartialCharge());
251 ps.print("</float>" + JHM.eol);
252
253 // CML2
254 //<scalar dataType="xsd:float" dictRef="joelib:partialCharge" units="units:electron">.234</scalar>
255 }
256
257 if (writerProp.writeImpliciteHydrogens())
258 {
259 ps.print(" <integer builtin=\"hydrogenCount\">");
260 ps.print(atom.getImplicitValence() + atom.explicitHydrogenCount());
261 ps.print("</integer>" + JHM.eol);
262 }
263
264 if (atom.getIsotope() != 0)
265 {
266 ps.print(" <integer builtin=\"isotope\">");
267 ps.print(atom.getIsotope());
268 ps.print("</integer>" + JHM.eol);
269 }
270
271 ps.print(" </atom>" + JHM.eol);
272 }
273
274 /**
275 * Description of the Method
276 *
277 * @param bond Description of the Parameter
278 */
279 private synchronized void write(PrintStream ps, JOEBond bond)
280 {
281 ps.print(" <bond id=\"b" + bond.getIdx() + "\">" + JHM.eol);
282
283 JOEAtom beginAtom = bond.getBeginAtom();
284 JOEAtom endAtom = bond.getEndAtom();
285 ps.print(" <string builtin=\"atomRef\">a" + beginAtom.getIdx() +
286 "</string>" + JHM.eol);
287 ps.print(" <string builtin=\"atomRef\">a" + endAtom.getIdx() +
288 "</string>" + JHM.eol);
289
290 // JOEAtom nbr;
291 // NbrAtomIterator nait = beginAtom.nbrAtomIterator();
292 // int index=0;
293 // while (nait.hasNext() && index<2)
294 // {
295 // index++;
296 // nbr = nait.nextNbrAtom();
297 // ps.print(
298 // " <string builtin=\"atomRef\">a"
299 // + nbr.getIdx()
300 // + "</string>"
301 // + JHM.eol);
302 // }
303 // System.out.println("bond idx:"+bond.getIdx());
304 ps.print(" <string builtin=\"order\">");
305
306 // is aromatic bond ?
307 if (bond.getBondOrder() == 4)
308 {
309 ps.print("1.5");
310 }
311 else
312 {
313 ps.print(bond.getBO());
314 }
315
316 ps.print("</string>" + JHM.eol);
317
318 // check stereochemistry: up/down and cis/trans
319 int isomerism = isomerism = IsomerismDetection.isCisTransBond(bond);
320
321 if ((isomerism != IsomerismDetection.EZ_ISOMERISM_UNDEFINED) ||
322 ((bond.getFlags() & JOEBond.JOE_WEDGE_BOND) != 0) ||
323 ((bond.getFlags() & JOEBond.JOE_HASH_BOND) != 0))
324 {
325 // CML 2.1
326 // <bondStereo>C</bondStereo>
327 // CML 1.0
328 // convention=\"MDLMol\"
329 ps.print(" <string builtin=\"stereo\">");
330
331 if (bond.isWedge())
332 {
333 // wedge bond
334 ps.print("W");
335 }
336 else if (bond.isHash())
337 {
338 // hatch bond
339 ps.print("H");
340 }
341 else if (isomerism != IsomerismDetection.EZ_ISOMERISM_UNDEFINED)
342 {
343 if (isomerism == IsomerismDetection.Z_ISOMERISM)
344 {
345 // cis bond
346 ps.print("C");
347 }
348 else if (isomerism == IsomerismDetection.E_ISOMERISM)
349 {
350 // trans bond
351 ps.print("T");
352 }
353 }
354
355 // CML 2.1
356 // or, e.g. for cis
357 // <bondStereo convention="MDL" conventionValue="6"/>
358 ps.print("</string>" + JHM.eol);
359 }
360
361 ps.print(" </bond>" + JHM.eol);
362 }
363
364 private synchronized void write2D(PrintStream ps, XYZVector p,
365 AtomDoubleResult x, AtomDoubleResult y, int index)
366 {
367 if ((x != null) && (y != null))
368 {
369 ps.print(" <float builtin=\"x2\">");
370 ps.print(x.getStringValue(index));
371 ps.print("</float>" + JHM.eol);
372 ps.print(" <float builtin=\"y2\">");
373 ps.print(y.getStringValue(index));
374 ps.print("</float>" + JHM.eol);
375 }
376 else if (p != null)
377 {
378 ps.print(" <float builtin=\"x2\">");
379 ps.print(new Float(p.x()).toString());
380 ps.print("</float>" + JHM.eol);
381 ps.print(" <float builtin=\"y2\">");
382 ps.print(new Float(p.y()).toString());
383 ps.print("</float>" + JHM.eol);
384 }
385 }
386
387 /**
388 * Description of the Method
389 *
390 * @param p Description of the Parameter
391 */
392
393 // private static synchronized void write(PrintStream ps, Point2d p)
394 // {
395 // if (p != null)
396 // {
397 // ps.print("<float builtin=\"x2\">");
398 // ps.print(new Float(p.x).toString());
399 // ps.print("</float>"+JHM.eol);
400 // ps.print("<float builtin=\"y2\">");
401 // ps.print(new Float(p.y).toString());
402 // ps.print("</float>"+JHM.eol);
403 // }
404 // }
405
406 /**
407 * Description of the Method
408 *
409 * @param p Description of the Parameter
410 */
411 private synchronized void write3D(PrintStream ps, XYZVector p)
412 {
413 if (p != null)
414 {
415 ps.print(" <float builtin=\"x3\">");
416 ps.print(new Float(p.x()).toString());
417 ps.print("</float>" + JHM.eol);
418 ps.print(" <float builtin=\"y3\">");
419 ps.print(new Float(p.y()).toString());
420 ps.print("</float>" + JHM.eol);
421 ps.print(" <float builtin=\"z3\">");
422 ps.print(new Float(p.z()).toString());
423 ps.print("</float>" + JHM.eol);
424 }
425 }
426 }
427 ///////////////////////////////////////////////////////////////////////////////
428 // END OF FILE.
429 ///////////////////////////////////////////////////////////////////////////////