Source code: joelib/io/types/ClearTextFormat.java
1 ///////////////////////////////////////////////////////////////////////////////
2 // Filename: $RCSfile: ClearTextFormat.java,v $
3 // Purpose: Reader/Writer for CTX files.
4 // Language: Java
5 // Compiler: JDK 1.4
6 // Authors: Joerg K. Wegner
7 // Version: $Revision: 1.24 $
8 // $Date: 2003/08/22 15:56:17 $
9 // $Author: wegner $
10 //
11 // Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
12 //
13 // This program is free software; you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation version 2 of the License.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License for more details.
21 ///////////////////////////////////////////////////////////////////////////////
22 package joelib.io.types;
23
24 import cformat.PrintfFormat;
25 import cformat.PrintfStream;
26
27 import joelib.data.JOECommentData;
28 import joelib.data.JOEElementTable;
29 import joelib.data.JOEPairData;
30
31 import joelib.desc.result.AtomDynamicResult;
32 import joelib.desc.result.BondDynamicResult;
33 import joelib.desc.result.DynamicArrayResult;
34
35 import joelib.io.MoleculeFileType;
36 import joelib.io.MoleculeIOException;
37
38 import joelib.molecule.JOEAtom;
39 import joelib.molecule.JOEBond;
40 import joelib.molecule.JOEMol;
41
42 import joelib.util.JHM;
43
44 import joelib.util.iterator.AtomIterator;
45 import joelib.util.iterator.NbrAtomIterator;
46
47 /*==========================================================================*
48 * IMPORTS
49 *========================================================================== */
50 import java.io.IOException;
51 import java.io.InputStream;
52 import java.io.InputStreamReader;
53 import java.io.LineNumberReader;
54 import java.io.OutputStream;
55
56 import java.util.Hashtable;
57 import java.util.Vector;
58
59 import org.apache.log4j.Category;
60
61
62 /*==========================================================================*
63 * CLASS DECLARATION
64 *==========================================================================*/
65
66 /**
67 * Reader/Writer for ClearTeXt (CTX) files.
68 *
69 * For speeding up descriptor molecule files have a look at the {@link joelib.desc.ResultFactory}.
70 *
71 * @author wegnerj
72 * @license GPL
73 * @cvsversion $Revision: 1.24 $, $Date: 2003/08/22 15:56:17 $
74 */
75 public class ClearTextFormat implements MoleculeFileType
76 {
77 //~ Static fields/initializers /////////////////////////////////////////////
78
79 /*-------------------------------------------------------------------------*
80 * public static member variables
81 *-------------------------------------------------------------------------*/
82
83 /**
84 * Obtain a suitable logger.
85 */
86 private static Category logger = Category.getInstance(
87 "joelib.io.types.ClearTextFormat");
88 private static final int ATOM_PROPERTY = 1;
89 private static final int BOND_PROPERTY = 2;
90 private static final int MOLECULE_PROPERTY = 3;
91 private static final int ENSEMBLE_PROPERTY = 4;
92
93 /**
94 * Data element for storing the access information for the asymmetric
95 * bond properties.
96 *
97 * index1=ctxID index2=idAtom1 index3=idAtom2 index4=singleEntryID
98 *
99 * The singleEntryID starts with 0. It's the internal id number which
100 * is used in JOELib.
101 */
102 public static final String ASYM_BOND_PROPERTY_INDEX = "ASYM_BOND_PROPERTY_INDEX";
103
104 /*-------------------------------------------------------------------------*
105 * private static member variables
106 *-------------------------------------------------------------------------*/
107 private final static String description = new String(
108 "CACTVS clear text format (CTX)");
109 private final static String[] extensions = new String[]{"ctx"};
110
111 //~ Instance fields ////////////////////////////////////////////////////////
112
113 /*-------------------------------------------------------------------------*
114 * private member variables
115 *-------------------------------------------------------------------------*/
116 private LineNumberReader lnr;
117 private PrintfStream ps;
118
119 //~ Methods ////////////////////////////////////////////////////////////////
120
121 public void closeReader() throws IOException
122 {
123 lnr.close();
124 }
125
126 public void closeWriter() throws IOException
127 {
128 }
129
130 /**
131 * Description of the Method
132 *
133 * @param is Description of the Parameter
134 * @exception IOException Description of the Exception
135 */
136 public void initReader(InputStream is) throws IOException
137 {
138 lnr = new LineNumberReader(new InputStreamReader(is));
139 }
140
141 /**
142 * Description of the Method
143 *
144 * @param os Description of the Parameter
145 * @exception IOException Description of the Exception
146 */
147 public void initWriter(OutputStream os) throws IOException
148 {
149 ps = new PrintfStream(os);
150 }
151
152 /*-------------------------------------------------------------------------*
153 * constructor
154 *-------------------------------------------------------------------------*/
155 /*-------------------------------------------------------------------------*
156 * public static methods
157 *-------------------------------------------------------------------------*/
158
159 /**
160 * Description of the Method
161 *
162 * @return Description of the Return Value
163 */
164 public String inputDescription()
165 {
166 return description;
167 }
168
169 /**
170 * Description of the Method
171 *
172 * @return Description of the Return Value
173 */
174 public String[] inputFileExtensions()
175 {
176 return extensions;
177 }
178
179 /**
180 * Description of the Method
181 *
182 * @return Description of the Return Value
183 */
184 public String outputDescription()
185 {
186 return description;
187 }
188
189 /**
190 * Description of the Method
191 *
192 * @return Description of the Return Value
193 */
194 public String[] outputFileExtensions()
195 {
196 return extensions;
197 }
198
199 /**
200 * Reads an molecule entry as (unparsed) <tt>String</tt> representation.
201 *
202 * @return <tt>null</tt> if the reader contains no more
203 * relevant data. Otherwise the <tt>String</tt> representation of the
204 * whole molecule entry is returned.
205 * @exception IOException typical IOException
206 */
207 public String read() throws IOException
208 {
209 StringBuffer molecule = new StringBuffer(10000);
210 String delimiter = " /END";
211 String line;
212
213 while ((line = lnr.readLine()) != null)
214 {
215 if ((line.length() > 0) && (line.charAt(1) == delimiter.charAt(1)) &&
216 (line.charAt(2) == delimiter.charAt(2)) &&
217 (line.indexOf(delimiter) != -1))
218 {
219 molecule.append(line);
220 molecule.append(JHM.eol);
221
222 break;
223 }
224
225 molecule.append(line);
226 molecule.append(JHM.eol);
227 }
228
229 if (line == null)
230 {
231 return null;
232 }
233 else
234 {
235 return molecule.toString();
236 }
237 }
238
239 /**
240 * Loads a ClearTextFile.
241 * Attention: bond properties can have the twice of the size of atoms.
242 * Use the CTX_BOND_INDEX data element to get the correct bond
243 * indices for this properties !!!
244 * This causes from circumstance, that in JOELib bonds are not stored twice !!!
245 *
246 * @param mol Description of the Parameter
247 * @return Description of the Return Value
248 * @exception IOException Description of the Exception
249 */
250 public synchronized boolean read(JOEMol mol)
251 throws IOException, MoleculeIOException
252 {
253 return read(mol, null);
254 }
255
256 /**
257 * Loads an molecule in ClearTextFile format and sets the title. If <tt>title
258 * </tt> is <tt>null</tt> the title line in the molecule file is used.
259 * Attention: bond properties can have the twice of the size of atoms.
260 * Use the CTX_BOND_INDEX data element to get the correct bond
261 * indices for this properties !!!
262 * This causes from circumstance, that in JOELib bonds are not stored twice !!!
263 *
264 * @param mol Description of the Parameter
265 * @param title Description of the Parameter
266 * @return Description of the Return Value
267 * @exception IOException Description of the Exception
268 */
269 public synchronized boolean read(JOEMol mol, String title)
270 throws IOException, MoleculeIOException
271 {
272 int i;
273
274 // int natoms;
275 // int nbonds;
276 String line;
277 String molName = "Undefined";
278 String comment;
279
280 // ScanfReader scanf;
281 // delete molecule data
282 mol.clear();
283
284 // start at reading
285 while (true)
286 {
287 line = lnr.readLine();
288
289 if (line == null)
290 {
291 return false;
292 }
293
294 if ((line.length() > 2) && (line.charAt(1) == '/'))
295 {
296 // System.out.println("line:"+line);
297 if (line.indexOf("IDENT", 2) != -1)
298 {
299 line = lnr.readLine();
300
301 if (line != null)
302 {
303 comment = line;
304 mol.beginModify();
305
306 break;
307 }
308 else
309 {
310 return false;
311 }
312 }
313 }
314 }
315
316 // cheak all properties
317 boolean exit = false;
318 int index;
319 Vector tv = new Vector();
320 int counter;
321 JOEAtom atom = new JOEAtom();
322
323 // JOEBond bond = new JOEBond();
324 int ti1;
325 int ti2;
326 int ti3;
327 int ti4;
328 double td1;
329 double td2;
330 double td3;
331
332 while (true)
333 {
334 line = lnr.readLine();
335
336 if (line == null)
337 {
338 return false;
339 }
340
341 if ((line.length() > 2) && (line.charAt(1) == '/'))
342 {
343 switch (line.charAt(2))
344 {
345 case '2':
346 case '3':
347
348 if (((index = line.indexOf("2DCOORD", 2)) != -1) ||
349 ((index = line.indexOf("3DCOORD", 2)) != -1))
350 {
351 boolean is2D = (line.charAt(2) == '2') ? true : false;
352
353 // read atoms coordinates
354 tv.clear();
355 JHM.tokenize(tv, line);
356
357 // check number of atoms
358 counter = Integer.parseInt((String) tv.get(1)) - 2;
359
360 if (mol.numAtoms() != counter)
361 {
362 logger.error(
363 "Wrong number of 3D coordinates. Should be " +
364 mol.numAtoms() + " but it's " + counter + ".");
365 skipReaderEntry();
366 throw new MoleculeIOException(
367 "Wrong number of 3D coordinates. Should be " +
368 mol.numAtoms() + " but it's " + counter + ".");
369
370 //return false;
371 }
372
373 // get 3D coords
374 //QUESTION: Do the following two lines contain necessary information?
375 line = lnr.readLine();
376 line = lnr.readLine();
377
378 for (i = 1; i <= counter; i++)
379 {
380 line = lnr.readLine();
381 tv.clear();
382 JHM.tokenize(tv, line);
383
384 atom = mol.getAtom(i);
385
386 // x
387 td1 = Double.parseDouble((String) tv.get(1));
388
389 // y
390 td2 = Double.parseDouble((String) tv.get(2));
391
392 // z
393 if (is2D)
394 {
395 td3 = 0;
396 }
397 else
398 {
399 td3 = Double.parseDouble((String) tv.get(3));
400 }
401
402 atom.setVector(td1, td2, td3);
403 }
404 }
405
406 break;
407
408 case 'A':
409
410 if ((index = line.indexOf("ATOMS", 2)) != -1)
411 {
412 // read atoms
413 tv.clear();
414 JHM.tokenize(tv, line);
415
416 // reserve space for atoms
417 counter = Integer.parseInt((String) tv.get(1));
418 mol.reserveAtoms(counter);
419
420 // get atoms
421 for (i = 0; i < counter; i++)
422 {
423 line = lnr.readLine();
424 tv.clear();
425 JHM.tokenize(tv, line);
426
427 atom.clear();
428 ti1 = Integer.parseInt((String) tv.get(1));
429 atom.setAtomicNum(ti1);
430 atom.setType(JOEElementTable.instance().getSymbol(ti1));
431
432 //free electrons
433 ti1 = Integer.parseInt((String) tv.get(2));
434 atom.setFreeElectrons(ti1);
435
436 if (!mol.addAtom(atom))
437 {
438 skipReaderEntry();
439 throw new MoleculeIOException(
440 "Could not add atom.");
441
442 //return (false);
443 }
444 }
445 }
446 else if ((index = line.indexOf("ATOPROP", 2)) != -1)
447 {
448 getProperty(mol, ATOM_PROPERTY);
449 }
450
451 break;
452
453 case 'B':
454
455 if ((index = line.indexOf("BONDS", 2)) != -1)
456 {
457 // read atoms
458 tv.clear();
459 JHM.tokenize(tv, line);
460
461 // reserve space for bonds
462 counter = Integer.parseInt((String) tv.get(1));
463
464 StringBuffer asymBondPropIndex = new StringBuffer(10 * counter);
465
466 // mol.reserveBonds(counter);
467 // get bonds
468 Hashtable bondChecker = new Hashtable(counter);
469 int bondNumber;
470 String tmp1;
471 String tmp2;
472 Integer intTmp;
473
474 for (i = 0; i < counter; i++)
475 {
476 line = lnr.readLine();
477 tv.clear();
478 JHM.tokenize(tv, line);
479
480 // bond.clear();
481 // atom 1 index
482 ti1 = Integer.parseInt((String) tv.get(1));
483
484 // atom 2 index
485 ti2 = Integer.parseInt((String) tv.get(2));
486
487 // bond order
488 ti3 = Integer.parseInt((String) tv.get(3));
489
490 // bond flags
491 ti4 = 0;
492
493 // don't get bonds twice !!!
494 tmp1 = tv.get(1) + "_" + tv.get(2);
495 tmp2 = tv.get(2) + "_" + tv.get(1);
496
497 if ((bondChecker.get(tmp1) == null) &&
498 (bondChecker.get(tmp2) == null))
499 {
500 if (!mol.addBond(ti1, ti2, ti3, ti4))
501 {
502 skipReaderEntry();
503 throw new MoleculeIOException(
504 "Could not add bond.");
505
506 //return (false);
507 }
508 else
509 {
510 bondChecker.put(tv.get(1) + "_" +
511 tv.get(2),
512 new Integer(mol.numBonds() - 1));
513 }
514
515 bondNumber = mol.numBonds() - 1;
516 }
517 else
518 {
519 intTmp = (Integer) bondChecker.get(tmp1);
520
521 if (intTmp != null)
522 {
523 bondNumber = intTmp.intValue();
524 }
525 else
526 {
527 intTmp = (Integer) bondChecker.get(tmp2);
528 bondNumber = intTmp.intValue();
529 }
530 }
531
532 // but save ctx information to enable bond property parsing
533 asymBondPropIndex.append((String) tv.get(0));
534 asymBondPropIndex.append(' ');
535 asymBondPropIndex.append((String) tv.get(1));
536 asymBondPropIndex.append(' ');
537 asymBondPropIndex.append((String) tv.get(2));
538 asymBondPropIndex.append(' ');
539 asymBondPropIndex.append(bondNumber);
540
541 if (i < (counter - 1))
542 {
543 asymBondPropIndex.append(JHM.eol);
544 }
545 }
546
547 bondChecker = null;
548
549 JOEPairData dp = new JOEPairData();
550 dp.setAttribute(ASYM_BOND_PROPERTY_INDEX);
551 dp.setValue(asymBondPropIndex);
552 mol.addData(dp);
553 }
554 else if ((index = line.indexOf("BONPROP", 2)) != -1)
555 {
556 getProperty(mol, BOND_PROPERTY);
557 }
558
559 break;
560
561 case 'E':
562
563 if ((index = line.indexOf("END", 2)) != -1)
564 {
565 // molecule successfull readed
566 exit = true;
567 }
568 else if ((index = line.indexOf("ENSPROP", 2)) != -1)
569 {
570 getProperty(mol, ENSEMBLE_PROPERTY);
571 }
572
573 break;
574
575 case 'M':
576
577 if ((index = line.indexOf("MOLPROP", 2)) != -1)
578 {
579 getProperty(mol, MOLECULE_PROPERTY);
580 }
581
582 break;
583
584 case 'N':
585
586 if ((index = line.indexOf("NAME", 2)) != -1)
587 {
588 line = lnr.readLine();
589
590 if (line != null)
591 {
592 molName = line;
593 }
594 else
595 {
596 logger.error("No molecule name defined.");
597 skipReaderEntry();
598 throw new MoleculeIOException(
599 "No molecule name defined.");
600
601 //return (false);
602 }
603 }
604
605 break;
606 }
607 }
608
609 if (exit)
610 {
611 break;
612 }
613 }
614
615 mol.endModify();
616
617 // set comment
618 if (comment != null)
619 {
620 JOECommentData cd = new JOECommentData();
621 cd.setData(comment);
622 mol.addData(cd);
623 }
624
625 // set molecule title
626 if (title == null)
627 {
628 mol.setTitle(molName);
629 }
630 else
631 {
632 mol.setTitle(title);
633 }
634
635 return (true);
636 }
637
638 /**
639 * Description of the Method
640 *
641 * @return Description of the Return Value
642 */
643 public boolean readable()
644 {
645 return true;
646 }
647
648 public boolean skipReaderEntry() throws IOException
649 {
650 String line;
651 boolean exit = false;
652
653 while (((line = lnr.readLine()) != null) || exit)
654 {
655 if ((line.length() > 2) && (line.charAt(1) == '/'))
656 {
657 switch (line.charAt(2))
658 {
659 case 'E':
660
661 if (line.indexOf("END", 2) != -1)
662 {
663 // molecule entry successfull skipped
664 exit = true;
665 }
666 }
667 }
668 }
669
670 return true;
671 }
672
673 /**
674 * Description of the Method
675 *
676 * @param mol Description of the Parameter
677 * @return Description of the Return Value
678 * @exception IOException Description of the Exception
679 */
680 public boolean write(JOEMol mol) throws IOException
681 {
682 return write(mol, null);
683 }
684
685 /**
686 * Description of the Method
687 *
688 * @param mol Description of the Parameter
689 * @param title Description of the Parameter
690 * @return Description of the Return Value
691 * @exception IOException Description of the Exception
692 */
693 public boolean write(JOEMol mol, String title) throws IOException
694 {
695 // PrintfFormat s15 = new PrintfFormat("%15s");
696 PrintfFormat d3 = new PrintfFormat("%3d");
697
698 // mol.addHydrogens();
699 String setTitle;
700
701 if (title == null)
702 {
703 setTitle = mol.getTitle();
704
705 if (setTitle == null)
706 {
707 setTitle = "Undefined";
708 }
709 }
710 else
711 {
712 setTitle = title;
713 }
714
715 ps.println(" /IDENT 1 1");
716 ps.println(setTitle);
717 ps.println(" /NAME 1 1");
718 ps.println(setTitle);
719
720 // check valences with CACTVS
721 ps.println(" /VALENCE 1 1");
722
723 // ps.println("0"); // don't check
724 ps.println("4"); // check all
725
726 ps.println(" /MOLECULS 1 1");
727 ps.println("1 1 " + mol.numAtoms());
728
729 // write atoms
730 ps.print(" /ATOMS ");
731 ps.printf(d3, mol.numAtoms());
732 ps.print(" ");
733 ps.printf(d3, mol.numAtoms());
734 ps.println();
735
736 JOEAtom atom;
737
738 // int charge;
739 AtomIterator ait = mol.atomIterator();
740 int bondCounter = 1;
741
742 while (ait.hasNext())
743 {
744 atom = ait.nextAtom();
745 ps.print(atom.getIdx());
746 ps.print(' ');
747 ps.print(atom.getAtomicNum());
748 ps.print(' ');
749 ps.print(atom.getFreeElectrons());
750 ps.print(' ');
751 ps.print(bondCounter);
752 ps.print(' ');
753 ps.print((bondCounter + atom.getValence()) - 1);
754 bondCounter += atom.getValence();
755 ps.println();
756 }
757
758 // write bond
759 ps.print(" /BONDS ");
760 ps.printf(d3, 2 * mol.numBonds());
761 ps.print(" ");
762 ps.printf(d3, 2 * mol.numBonds());
763 ps.println();
764
765 JOEAtom nbr;
766 JOEBond bond;
767 ait.reset();
768
769 // int bondType;
770 int first;
771
772 // int bondType;
773 int second;
774 int index = 1;
775 int atomNumber = 0;
776
777 while (ait.hasNext())
778 {
779 atom = ait.nextAtom();
780
781 NbrAtomIterator nait = atom.nbrAtomIterator();
782 atomNumber++;
783
784 while (nait.hasNext())
785 {
786 nbr = nait.nextNbrAtom();
787
788 bond = nait.actualBond();
789 ps.print(index++);
790 ps.print(' ');
791
792 if (bond.getBeginAtomIdx() == atomNumber)
793 {
794 first = bond.getBeginAtomIdx();
795 second = bond.getEndAtomIdx();
796 }
797 else
798 {
799 second = bond.getBeginAtomIdx();
800 first = bond.getEndAtomIdx();
801 }
802
803 ps.print(first);
804 ps.print(' ');
805 ps.print(second);
806 ps.print(' ');
807 ps.print(bond.getBondOrder());
808 ps.println();
809 }
810 }
811
812 // write 3D coordinates
813 ps.print(" /3DCOORD ");
814 ps.printf(d3, mol.numAtoms());
815 ps.print(" ");
816 ps.printf(d3, mol.numAtoms());
817 ps.println();
818 ait.reset();
819
820 while (ait.hasNext())
821 {
822 atom = ait.nextAtom();
823 ps.print(atom.getIdx());
824 ps.print(' ');
825 ps.print(atom.getX());
826 ps.print(' ');
827 ps.print(atom.getY());
828 ps.print(' ');
829 ps.print(atom.getZ());
830 ps.println();
831 }
832
833 // write additional descriptor data
834 // if (writePairData) {
835 // GenericDataIterator gdit = mol.genericDataIterator();
836 // JOEGenericData genericData;
837 // JOEPairData pairData;
838 // while (gdit.hasNext()) {
839 // genericData = gdit.nextGenericData();
840 //
841 // if (genericData.getDataType() == JOEDataType.JOE_PAIR_DATA) {
842 // ps.printf("> <%s>", genericData.getAttribute());
843 // ps.println();
844 // pairData = (JOEPairData) genericData;
845 // ps.println(pairData.toString(IOTypeHolder.instance().getIOType("SDF")));
846 // ps.println();
847 // }
848 // }
849 // }
850 ps.println(" /END 0 0");
851
852 return (true);
853 }
854
855 /**
856 * Description of the Method
857 *
858 * @return Description of the Return Value
859 */
860 public boolean writeable()
861 {
862 return true;
863 }
864
865 /**
866 * Gets the property attribute of the ClearTextFormat object.
867 * Attention: bond properties can have the twice of the size of atoms.
868 * Use the CTX_BOND_INDEX data element to get the correct bond
869 * indices for this properties !!!
870 * This causes from circumstance, that in JOELib bonds are not stored twice !!!
871 *
872 * @return The property value
873 * @exception IOException Description of the Exception
874 */
875 private synchronized boolean getProperty(JOEMol mol, int propType)
876 throws IOException
877 {
878 String line;
879 Vector tv = new Vector();
880 int i;
881 int counter;
882
883 // get property name
884 String propName = lnr.readLine();
885
886 // get property unit
887 String propUnit = lnr.readLine();
888
889 // get property description
890 String propDesc = lnr.readLine();
891
892 // get data type
893 String type = lnr.readLine();
894
895 if (type.equals("R"))
896 {
897 type = DynamicArrayResult.DOUBLE;
898 }
899 else if (propUnit.equalsIgnoreCase("[Boolean]") && type.equals("I"))
900 {
901 type = DynamicArrayResult.BOOLEAN;
902 }
903 else if (type.equals("I"))
904 {
905 type = DynamicArrayResult.INT;
906 }
907 else if (type.equals("S"))
908 {
909 // o.k., accept this data type
910 }
911 else
912 {
913 logger.error("data type " + type + " not supported in " + propName +
914 ".");
915
916 return false;
917 }
918
919 line = lnr.readLine();
920 tv.clear();
921 JHM.tokenize(tv, line);
922
923 // check number of properties
924 counter = Integer.parseInt((String) tv.get(1));
925
926 if (propType == this.ATOM_PROPERTY)
927 {
928 if (mol.numAtoms() != counter)
929 {
930 logger.error("Wrong number of atoms in atom property " +
931 propName + ". Should be " + mol.numAtoms() + " but it's " +
932 counter + ".");
933
934 return false;
935 }
936 }
937 else if (propType == this.BOND_PROPERTY)
938 {
939 if ((mol.numBonds() != counter) &&
940 ((mol.numBonds() * 2) != counter))
941 {
942 logger.error("Wrong number of bonds in bond property " +
943 propName + ". Should be " + mol.numBonds() + " but it's " +
944 counter + ".");
945
946 return false;
947 }
948 }
949
950 // get internal String representation for this properties
951 StringBuffer sb = new StringBuffer((20 * 3) + (counter * 20));
952
953 // store property type
954 if (propType == this.ATOM_PROPERTY)
955 {
956 sb.append(AtomDynamicResult.ATOM_PROPERTY);
957 sb.append(JHM.eol);
958 }
959 else if (propType == this.BOND_PROPERTY)
960 {
961 sb.append(BondDynamicResult.BOND_PROPERTY);
962 sb.append(JHM.eol);
963 }
964 else if (propType == this.MOLECULE_PROPERTY)
965 {
966 sb.append("molecule_property");
967 sb.append(JHM.eol);
968 }
969 else if (propType == this.ENSEMBLE_PROPERTY)
970 {
971 sb.append("ensemble_property");
972 sb.append(JHM.eol);
973 }
974 else
975 {
976 sb.append("undefined_property");
977 sb.append(JHM.eol);
978 }
979
980 // store property description and property unit
981 // empty lines are not allowed
982 if (propDesc.trim().length() == 0)
983 {
984 sb.append("?");
985 }
986 else
987 {
988 sb.append(propDesc);
989 }
990
991 sb.append(JHM.eol);
992
993 if (propUnit.trim().length() == 0)
994 {
995 sb.append("?");
996 }
997 else
998 {
999 sb.append(propUnit);
1000 }
1001
1002 sb.append(JHM.eol);
1003
1004 //store data type and data
1005 // if((propType==this.MOLECULE_PROPERTY || propType==this.ENSEMBLE_PROPERTY)&&
1006 // counter==1)
1007 // {
1008 // sb.append(lnr.readLine());
1009 // }
1010 // else{
1011 if (!type.equals("S"))
1012 {
1013 sb.append(type);
1014 sb.append(JHM.eol);
1015 }
1016
1017 sb.append(counter);
1018 sb.append(JHM.eol);
1019
1020 for (i = 0; i < counter; i++)
1021 {
1022 sb.append(lnr.readLine());
1023
1024 if (i != (counter - 1))
1025 {
1026 sb.append(JHM.eol);
1027 }
1028 }
1029
1030 // }
1031 JOEPairData dp = new JOEPairData();
1032 dp.setAttribute(propName);
1033 dp.setValue(sb.toString());
1034 mol.addData(dp);
1035
1036 if (logger.isDebugEnabled())
1037 {
1038 // check data parser and verbose parsed data
1039 dp = (JOEPairData) mol.getData(propName);
1040 logger.debug("get '" + propName + "' as " +
1041 dp.getValue().getClass().getName());
1042 }
1043
1044 return true;
1045 }
1046}
1047///////////////////////////////////////////////////////////////////////////////
1048// END OF FILE.
1049///////////////////////////////////////////////////////////////////////////////