Source code: joelib/io/types/Flat.java
1 ///////////////////////////////////////////////////////////////////////////////
2 // Filename: $RCSfile: Flat.java,v $
3 // Purpose: Flat file format support.
4 // Language: Java
5 // Compiler: JDK 1.4
6 // Authors: Joerg K. Wegner
7 // Version: $Revision: 1.8 $
8 // $Date: 2003/08/22 15:56:18 $
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.PrintfStream;
25
26 import joelib.data.JOEDataType;
27 import joelib.data.JOEGenericData;
28 import joelib.data.JOEPairData;
29
30 import joelib.io.IOTypeHolder;
31 import joelib.io.MoleculeFileType;
32 import joelib.io.MoleculeIOException;
33
34 import joelib.molecule.JOEMol;
35
36 import joelib.util.JHM;
37
38 import wsi.ra.tool.PropertyHolder;
39
40 /*==========================================================================*
41 * IMPORTS
42 *========================================================================== */
43 import java.io.IOException;
44 import java.io.InputStream;
45 import java.io.InputStreamReader;
46 import java.io.LineNumberReader;
47 import java.io.OutputStream;
48
49 import java.util.Properties;
50 import java.util.Vector;
51
52 import org.apache.log4j.Category;
53
54
55 /*==========================================================================*
56 * CLASS DECLARATION
57 *========================================================================== */
58
59 /**
60 * Flat file format support.
61 *
62 * @author wegnerj
63 * @license GPL
64 * @cvsversion $Revision: 1.8 $, $Date: 2003/08/22 15:56:18 $
65 */
66 public class Flat implements MoleculeFileType
67 {
68 //~ Static fields/initializers /////////////////////////////////////////////
69
70 /*-------------------------------------------------------------------------*
71 * private static member variables
72 *------------------------------------------------------------------------- */
73
74 /**
75 * Obtain a suitable logger.
76 */
77 private static Category logger = Category.getInstance(
78 "joelib.io.types.Flat");
79 private final static String description = new String(
80 "Native descriptor flat file format");
81 private final static String[] extensions = new String[]{"flat", "dat", "txt"};
82
83 //~ Instance fields ////////////////////////////////////////////////////////
84
85 public boolean firstLineLoaded = false;
86
87 /*-------------------------------------------------------------------------*
88 * private member variables
89 *------------------------------------------------------------------------- */
90 private LineNumberReader lnr;
91 private PrintfStream ps;
92 private String delimiter;
93 private String inputDelim;
94 private String outputDelim;
95 private Vector lineStructure;
96 private boolean firstLineWritten = false;
97 private boolean storeLineInfo = true;
98 private int titlePosition;
99
100 //~ Constructors ///////////////////////////////////////////////////////////
101
102 /*-------------------------------------------------------------------------*
103 * constructor
104 *------------------------------------------------------------------------- */
105
106 /**
107 * Constructor for the Smiles object
108 */
109 public Flat()
110 {
111 lineStructure = new Vector();
112 }
113
114 //~ Methods ////////////////////////////////////////////////////////////////
115
116 /**
117 * Sets the storeLineInfo attribute of the Smiles object
118 *
119 * @param _flag The new storeLineInfo value
120 */
121 public void setStoreLineInfo(boolean _flag)
122 {
123 storeLineInfo = _flag;
124 }
125
126 /**
127 * Gets the storeLineInfo attribute of the Smiles object
128 *
129 * @return The storeLineInfo value
130 */
131 public boolean getStoreLineInfo()
132 {
133 return storeLineInfo;
134 }
135
136 /**
137 * Description of the Method
138 *
139 * @exception IOException Description of the Exception
140 */
141 public void closeReader() throws IOException
142 {
143 lnr.close();
144 }
145
146 /**
147 * Description of the Method
148 *
149 * @exception IOException Description of the Exception
150 */
151 public void closeWriter() throws IOException
152 {
153 ps.close();
154 }
155
156 /**
157 * Description of the Method
158 *
159 * @exception IOException Description of the Exception
160 */
161 public void initParser() throws IOException
162 {
163 Properties prop = PropertyHolder.instance().getProperties();
164 String className = this.getClass().getName();
165
166 // use system properties if available
167 String lineStructString = System.getProperty(className +
168 ".lineStructure");
169
170 if (lineStructString == null)
171 {
172 lineStructString = prop.getProperty(className + ".lineStructure",
173 "TITLE");
174 }
175
176 //System.out.println("pLINE:"+lineStructString);
177 delimiter = prop.getProperty(className + ".lineStructure.delimiter", "|");
178
179 //System.out.println("delimiter: '"+delimiter+"'");
180 inputDelim = prop.getProperty(className +
181 ".lineStructure.input.delimiter", " \t\n\r");
182
183 //System.out.println("inputDelim:"+inputDelim);
184 outputDelim = prop.getProperty(className +
185 ".lineStructure.output.delimiter", "\t");
186
187 //System.out.println("outputDelim:"+outputDelim);
188 lineStructure.clear();
189 JHM.tokenize(lineStructure, lineStructString, delimiter + "\n\r");
190
191 titlePosition = -1;
192
193 for (int i = 0; i < lineStructure.size(); i++)
194 {
195 if (((String) lineStructure.get(i)).equals("TITLE"))
196 {
197 titlePosition = i;
198 }
199
200 //System.out.println("pSTRUCT("+i+"):"+lineStructure.get(i));
201 }
202 }
203
204 /**
205 * Description of the Method
206 *
207 * @param is Description of the Parameter
208 * @exception IOException Description of the Exception
209 */
210 public synchronized void initReader(InputStream is)
211 throws IOException
212 {
213 lnr = new LineNumberReader(new InputStreamReader(is));
214 initParser();
215 firstLineLoaded = false;
216 }
217
218 public synchronized void initReader(InputStream is, boolean _firstLineLoaded)
219 throws IOException
220 {
221 lnr = new LineNumberReader(new InputStreamReader(is));
222 initParser();
223 firstLineLoaded = _firstLineLoaded;
224 }
225
226 /**
227 * Description of the Method
228 *
229 * @param os Description of the Parameter
230 * @exception IOException Description of the Exception
231 */
232 public void initWriter(OutputStream os) throws IOException
233 {
234 ps = new PrintfStream(os);
235 initParser();
236 }
237
238 /*-------------------------------------------------------------------------*
239 * public static methods
240 *------------------------------------------------------------------------- */
241
242 /**
243 * Description of the Method
244 *
245 * @return Description of the Return Value
246 */
247 public String inputDescription()
248 {
249 return description;
250 }
251
252 /**
253 * Description of the Method
254 *
255 * @return Description of the Return Value
256 */
257 public String[] inputFileExtensions()
258 {
259 return extensions;
260 }
261
262 /**
263 * Description of the Method
264 *
265 * @return Description of the Return Value
266 */
267 public String outputDescription()
268 {
269 return description;
270 }
271
272 /**
273 * Description of the Method
274 *
275 * @return Description of the Return Value
276 */
277 public String[] outputFileExtensions()
278 {
279 return extensions;
280 }
281
282 public String parseFirstLineReadNext(String line) throws IOException
283 {
284 String nextLine;
285 titlePosition = -1;
286 lineStructure.clear();
287 JHM.tokenize(lineStructure, line, inputDelim + "\n\r");
288 firstLineLoaded = true;
289
290 // read first data line
291 if ((nextLine = lnr.readLine()) == null)
292 {
293 logger.error("Flat file contains no data lines.");
294
295 return null;
296 }
297
298 StringBuffer sb = new StringBuffer(100);
299
300 for (int i = 0; i < lineStructure.size(); i++)
301 {
302 sb.append((String) lineStructure.get(i));
303
304 //System.out.println(lineStructure.get(i) + " ");
305 if (i < (lineStructure.size() - 1))
306 {
307 sb.append(delimiter);
308 }
309
310 if (((String) lineStructure.get(i)).equals("TITLE"))
311 {
312 titlePosition = i;
313 }
314 }
315
316 Properties prop = PropertyHolder.instance().getProperties();
317 String className = this.getClass().getName();
318 prop.setProperty(className + ".lineStructure", sb.toString());
319
320 logger.info("Set flat file line structure to: " + sb.toString());
321
322 return nextLine;
323 }
324
325 /**
326 * Reads an molecule entry as (unparsed) <tt>String</tt> representation.
327 *
328 * @param mol the molecule to store the data
329 * @return <tt>null</tt> if the reader contains no
330 * more relevant data. Otherwise the <tt>String</tt> representation
331 * of the whole molecule entry is returned.
332 * @exception IOException typical IOException
333 */
334 public String read() throws IOException
335 {
336 String line;
337
338 if ((line = lnr.readLine()) == null)
339 {
340 return null;
341 }
342
343 if (!firstLineLoaded)
344 {
345 line = parseFirstLineReadNext(line);
346 }
347
348 return line;
349 }
350
351 /**
352 * Description of the Method
353 *
354 * @param mol Description of the Parameter
355 * @return Description of the Return Value
356 * @exception IOException Description of the Exception
357 */
358 public boolean read(JOEMol mol) throws IOException, MoleculeIOException
359 {
360 return read(mol, null);
361 }
362
363 /**
364 * Loads an molecule in SMILES format and sets the title. If <tt>title</tt>
365 * is <tt>null</tt> the title line in the molecule file is used.
366 *
367 * @param mol Description of the Parameter
368 * @param title Description of the Parameter
369 * @return Description of the Return Value
370 * @exception IOException Description of the Exception
371 */
372 public synchronized boolean read(JOEMol mol, String title)
373 throws IOException, MoleculeIOException
374 {
375 String line = null;
376
377 if ((line = lnr.readLine()) == null)
378 {
379 return (false);
380 }
381
382 // the first line contains the descriptor data information
383 if (!firstLineLoaded)
384 {
385 line = parseFirstLineReadNext(line);
386 }
387
388 Vector data = new Vector();
389
390 // of type String
391 JHM.tokenize(data, line, inputDelim);
392
393 if (data.size() < lineStructure.size())
394 {
395 throw new MoleculeIOException("Line entry \"" + line +
396 "\" in line " + lnr.getLineNumber() + " could not be loaded." +
397 "Not enough arguments available.");
398 }
399
400 String setTitle;
401
402 if (titlePosition == -1)
403 {
404 if (title == null)
405 {
406 setTitle = "";
407 }
408 else
409 {
410 setTitle = title;
411 }
412 }
413 else
414 {
415 setTitle = (String) data.get(titlePosition);
416 }
417
418 for (int i = 0; i < lineStructure.size(); i++)
419 {
420 // System.out.println("");
421 if (i != titlePosition)
422 {
423 // System.out.println("i:"+lineStructure.get(i));
424 if (i < data.size())
425 {
426 JOEPairData dp = new JOEPairData();
427 dp.setAttribute((String) lineStructure.get(i));
428 dp.setValue((String) data.get(i));
429 mol.addData(dp);
430
431 //System.out.println("mol.add: "+lineStructure.get(i)+" "+data.get(i));
432 }
433 else
434 {
435 // logger.error("Entry \""+(String)lineStructure.get(i)+"\" does not exist in line "+lnr.getLineNumber()+".");
436 throw new IOException("Entry \"" +
437 (String) lineStructure.get(i) +
438 "\" does not exist in line " + lnr.getLineNumber() +
439 ".");
440 }
441 }
442 }
443
444 return (true);
445 }
446
447 /**
448 * Description of the Method
449 *
450 * @return Description of the Return Value
451 */
452 public boolean readable()
453 {
454 return true;
455 }
456
457 /**
458 * Description of the Method
459 *
460 * @return Description of the Return Value
461 * @exception IOException Description of the Exception
462 */
463 public boolean skipReaderEntry() throws IOException
464 {
465 //SMILES line was already readed.
466 return true;
467 }
468
469 /**
470 * Description of the Method
471 *
472 * @param mol Description of the Parameter
473 * @return Description of the Return Value
474 * @exception IOException Description of the Exception
475 */
476 public boolean write(JOEMol mol) throws IOException
477 {
478 return write(mol, null);
479 }
480
481 /**
482 * Description of the Method
483 *
484 * @param mol Description of the Parameter
485 * @param title Description of the Parameter
486 * @return Description of the Return Value
487 * @exception IOException Description of the Exception
488 */
489 public boolean write(JOEMol mol, String title) throws IOException
490 {
491 // save line structure information
492 if (storeLineInfo && !firstLineWritten)
493 {
494 //ps.print('#');
495 for (int i = 0; i < lineStructure.size(); i++)
496 {
497 if (i != 0)
498 {
499 ps.print(delimiter);
500 }
501
502 ps.print((String) lineStructure.get(i));
503 }
504
505 ps.println();
506 firstLineWritten = true;
507 }
508
509 // save SMILES line and properties
510 for (int i = 0; i < lineStructure.size(); i++)
511 {
512 if (i != 0)
513 {
514 ps.print(outputDelim);
515 }
516
517 if (i == titlePosition)
518 {
519 String printTitle = title;
520
521 if (printTitle == null)
522 {
523 printTitle = mol.getTitle();
524 }
525
526 if (printTitle.trim().equals(""))
527 {
528 printTitle = "Undefined";
529 }
530
531 ps.print(printTitle);
532 }
533 else
534 {
535 JOEGenericData genericData = (JOEGenericData) mol.getData((String) lineStructure.get(
536 i));
537 JOEPairData pairData;
538
539 if (genericData == null)
540 {
541 logger.warn("Descriptor entry '" + lineStructure.get(i) +
542 "' not found in " + mol.getTitle());
543 logger.warn("Writing NaN");
544 ps.print("NaN");
545 }
546 else
547 {
548 if (genericData.getDataType() == JOEDataType.JOE_PAIR_DATA)
549 {
550 // ps.print(genericData.getAttribute());
551 pairData = (JOEPairData) genericData;
552 ps.print(pairData.toString(IOTypeHolder.instance()
553 .getIOType("FLAT")));
554 }
555 }
556 }
557 }
558
559 ps.println();
560
561 return (true);
562 }
563
564 /**
565 * Description of the Method
566 *
567 * @return Description of the Return Value
568 */
569 public boolean writeable()
570 {
571 return true;
572 }
573 }
574 ///////////////////////////////////////////////////////////////////////////////
575 // END OF FILE.
576 ///////////////////////////////////////////////////////////////////////////////