Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: joelib/io/types/JCAMP.java


1   ///////////////////////////////////////////////////////////////////////////////
2   //  Filename: $RCSfile: JCAMP.java,v $
3   //  Purpose:  Reader/Writer for Undefined files.
4   //  Language: Java
5   //  Compiler: JDK 1.4
6   //  Authors:  Joerg K. Wegner
7   //  Version:  $Revision: 1.11 $
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.io.MoleculeFileType;
27  
28  import joelib.jcamp.JCAMPData;
29  import joelib.jcamp.JCAMPDataBlock;
30  
31  import joelib.molecule.JOEMol;
32  
33  /*
34   *  ==========================================================================*
35   *  IMPORTS
36   *  ==========================================================================
37   */
38  import java.io.IOException;
39  import java.io.InputStream;
40  import java.io.InputStreamReader;
41  import java.io.LineNumberReader;
42  import java.io.OutputStream;
43  
44  import org.apache.log4j.Category;
45  
46  
47  /*
48   *  ==========================================================================*
49   *  CLASS DECLARATION
50   *  ==========================================================================
51   */
52  
53  /**
54   *  A class to interpret JCAMP-DX data (JCAMP-CS is not implemented yet). The
55   *  supported data types are XYPAIRS, XYDATA=(X++(Y..Y)), PEAK TABLE and LINK.
56   *  <br>
57   *  If you want load a file with multiple blocks or inner blocks you must use
58   *  <code>JCampMultipleFile</code>.<br>
59   *  This class can only load separated single blocks with one TITLE and END
60   *  label !<br>
61   *  <br>
62   *
63   *  <ul>
64   *    <li> ... The International Union of Pure and Applied Chemistry (IUPAC)
65   *    took over responsibility from the Joint Commitee on Atomic and Molecular
66   *    Physical Data (JCAMP) in 1995 ...<br>
67   *    <a href="http://jcamp.isas-dortmund.de/">I U P A C<br>
68   *    Committee on Printed and Electronic Publications <br>
69   *    Working Party on Spectroscopic Data Standards (JCAMP-DX)</a> <br>
70   *    <br>
71   *
72   *    <li> <a href="http://wwwchem.uwimona.edu.jm:1104/software/jcampdx.html">
73   *    The Department of Chemistry at the University of the West Indies</a>
74   *  </ul>
75   *
76   * @author     wegnerj
77   * @license GPL
78   * @cvsversion    $Revision: 1.11 $, $Date: 2003/08/22 15:56:18 $
79   * @cite dl93
80   * @cite dw88
81   * @cite ghhjs91
82   * @cite lhdl94
83   * @cite dhl90
84   * @see joelib.jcamp.JCAMPParser
85   */
86  public class JCAMP implements MoleculeFileType
87  {
88      //~ Static fields/initializers /////////////////////////////////////////////
89  
90      /*
91       *  -------------------------------------------------------------------------*
92       *  private static member variables
93       *  -------------------------------------------------------------------------
94       */
95  
96      /**
97       *  Obtain a suitable logger.
98       */
99      private static Category logger = Category.getInstance(
100             "joelib.io.types.JCAMP");
101     private final static String description = new String(
102             "Joint Commitee on Atomic and Molecular Physical Data (JCAMP)");
103     private final static String[] extensions = new String[]{"jdx", "dx", "cs"};
104 
105     //~ Instance fields ////////////////////////////////////////////////////////
106 
107     // data type is chemical structure
108     private final String JCAMP_CHEMICAL_STRUCTURE = "JCAMP-CS";
109 
110     // data type is spectra
111     private final String JCAMP_SPECTRA = "JCAMP-DX";
112 
113     // marks start of data
114     private final String JCAMP_START = "TITLE";
115 
116     // marks end of data
117     private final String JCAMP_STOP = "END";
118 
119     // ... is link block
120     private final String LINK_TYPE = "LINK";
121 
122     // data type ...
123     private final String LINK_TYPE_DATA = "DATA TYPE";
124     private JCAMPData jcamp;
125 
126     //    private String textBlock;
127     //    private StringTokenizer textTokenizer = null;
128 
129     /*
130      *  -------------------------------------------------------------------------*
131      *  private member variables
132      *  -------------------------------------------------------------------------
133      */
134     private LineNumberReader lnr;
135     private PrintfStream ps;
136     private int jcampCount;
137 
138     //~ Constructors ///////////////////////////////////////////////////////////
139 
140     /*
141      *  -------------------------------------------------------------------------*
142      *  constructor
143      *  -------------------------------------------------------------------------
144      */
145 
146     /**
147      *  Constructor for the Undefined object
148      */
149     public JCAMP()
150     {
151     }
152 
153     //~ Methods ////////////////////////////////////////////////////////////////
154 
155     public String getJCAMPData()
156     {
157         return (String) jcamp.getDXEntry(0).getBlockData();
158     }
159 
160     /**
161      *  Description of the Method
162      *
163      *@exception  IOException  Description of the Exception
164      */
165     public void closeReader() throws IOException
166     {
167     }
168 
169     /**
170      *  Description of the Method
171      *
172      *@exception  IOException  Description of the Exception
173      */
174     public void closeWriter() throws IOException
175     {
176     }
177 
178     /**
179      *  Description of the Method
180      *
181      *@param  is               Description of the Parameter
182      *@exception  IOException  Description of the Exception
183      */
184     public void initReader(InputStream is) throws IOException
185     {
186         lnr = new LineNumberReader(new InputStreamReader(is));
187         jcampCount = 0;
188     }
189 
190     /**
191      *  Description of the Method
192      *
193      *@param  os               Description of the Parameter
194      *@exception  IOException  Description of the Exception
195      */
196     public void initWriter(OutputStream os) throws IOException
197     {
198         ps = new PrintfStream(os);
199     }
200 
201     /*
202      *  -------------------------------------------------------------------------*
203      *  public static methods
204      *  -------------------------------------------------------------------------
205      */
206 
207     /**
208      *  Description of the Method
209      *
210      *@return    Description of the Return Value
211      */
212     public String inputDescription()
213     {
214         return description;
215     }
216 
217     /**
218      *  Description of the Method
219      *
220      *@return    Description of the Return Value
221      */
222     public String[] inputFileExtensions()
223     {
224         return extensions;
225     }
226 
227     /**
228      *  Description of the Method
229      *
230      *@return    Description of the Return Value
231      */
232     public String outputDescription()
233     {
234         return description;
235     }
236 
237     /**
238      *  Description of the Method
239      *
240      *@return    Description of the Return Value
241      */
242     public String[] outputFileExtensions()
243     {
244         return extensions;
245     }
246 
247     /**
248      *  Reads an molecule entry as (unparsed) <tt>String</tt> representation.
249      *
250      * @return                  <tt>null</tt> if the reader contains no more
251      *      relevant data. Otherwise the <tt>String</tt> representation of the
252      *      whole molecule entry is returned.
253      * @exception  IOException  typical IOException
254      */
255     public String read() throws IOException
256     {
257         logger.error(
258             "Reading JCAMP data as String representation is not implemented yet !!!");
259 
260         return null;
261     }
262 
263     /**
264      *  Description of the Method
265      *
266      *@param  mol              Description of the Parameter
267      *@return                  Description of the Return Value
268      *@exception  IOException  Description of the Exception
269      */
270     public boolean read(JOEMol mol) throws IOException
271     {
272         return read(mol, null);
273     }
274 
275     /**
276      *  Description of the Method
277      *
278      *@param  mol              Description of the Parameter
279      *@param  title            Description of the Parameter
280      *@return                  Description of the Return Value
281      *@exception  IOException  Description of the Exception
282      */
283     public boolean read(JOEMol mol, String title) throws IOException
284     {
285         // start parsing
286         jcamp = new JCAMPData();
287 
288         JCAMPDataBlock dataBlock = null;
289 
290         do
291         {
292             jcampCount++;
293             dataBlock = resolveJCAMPBlocks(0, null, jcampCount);
294             addDataBlock(dataBlock);
295         }
296          while (dataBlock != null);
297 
298         return (false);
299     }
300 
301     /**
302      *  Description of the Method
303      *
304      *@return    Description of the Return Value
305      */
306     public boolean readable()
307     {
308         return true;
309     }
310 
311     public boolean skipReaderEntry() throws IOException
312     {
313         return skipReaderEntry(1);
314     }
315 
316     /**
317      *  Description of the Method
318      *
319      *@return                  Description of the Return Value
320      *@exception  IOException  Description of the Exception
321      */
322     public boolean skipReaderEntry(int actualDepth) throws IOException
323     {
324         String line;
325         int depth = 0;
326 
327         while ((line = lnr.readLine()) != null)
328         {
329             if ((line.length() > 0) && (line.charAt(0) == '#') &&
330                     (line.indexOf(JCAMP_STOP) != -1))
331             {
332                 depth++;
333             }
334 
335             if (depth == actualDepth)
336             {
337                 break;
338             }
339         }
340 
341         return true;
342     }
343 
344     /**
345      *  Description of the Method
346      *
347      *@param  mol              Description of the Parameter
348      *@return                  Description of the Return Value
349      *@exception  IOException  Description of the Exception
350      */
351     public boolean write(JOEMol mol) throws IOException
352     {
353         return write(mol, null);
354     }
355 
356     /**
357      *  Description of the Method
358      *
359      *@param  mol              Description of the Parameter
360      *@param  title            Description of the Parameter
361      *@return                  Description of the Return Value
362      *@exception  IOException  Description of the Exception
363      */
364     public boolean write(JOEMol mol, String title) throws IOException
365     {
366         return (false);
367     }
368 
369     /**
370      *  Description of the Method
371      *
372      *@return    Description of the Return Value
373      */
374     public boolean writeable()
375     {
376         return false;
377     }
378 
379     /**
380      *  Adds a JCAMP block.
381      *
382      *@param  block  The feature to be added to the DataBlock attribute
383      *@return        Description of the Return Value
384      */
385     private boolean addDataBlock(JCAMPDataBlock block)
386     {
387         if (block != null)
388         {
389             if (block.getBlockType() == JCAMPDataBlock.CS_TYPE)
390             {
391                 jcamp.addCSEntry(block);
392 
393                 //                System.out.println("CS_ID: " + block.getBlockID());
394                 //                System.out.println("CS:\n" + block.getBlockData());
395             }
396             else if (block.getBlockType() == JCAMPDataBlock.DX_TYPE)
397             {
398                 jcamp.addDXEntry(block);
399 
400                 //                System.out.println("DX_ID: " + block.getBlockID());
401                 //                System.out.println("DX:\n" + block.getBlockData());
402             }
403             else if (block.getBlockType() == JCAMPDataBlock.LINK_TYPE)
404             {
405                 jcamp.addLinkEntry(block);
406 
407                 //                System.out.println("LINK_ID: " + block.getBlockID());
408                 //                System.out.println("LINK:\n" + block.getBlockData());
409             }
410         }
411 
412         return true;
413     }
414 
415     /*
416      *  -------------------------------------------------------------------------*
417      *  private methods
418      *  -------------------------------------------------------------------------
419      */
420 
421     /**
422      *  Gets the single JCAMP data blocks.
423      *
424      *@param  _depth           Description of the Parameter
425      *@param  previousLine     Description of the Parameter
426      *@param  blockID          Description of the Parameter
427      *@return                  Description of the Return Value
428      *@exception  IOException  Description of the Exception
429      */
430     private JCAMPDataBlock resolveJCAMPBlocks(int _depth, String previousLine,
431         int blockID) throws IOException
432     {
433         // now parse the whole file contents
434         String label = null;
435         String data = null;
436         StringBuffer tempBuffer = new StringBuffer(20000);
437         int depth = _depth;
438         JCAMPDataBlock dataBlock = new JCAMPDataBlock();
439 
440         boolean firstLabelTreated = false;
441         String nextLine = null;
442         boolean goOn = true;
443 
444         //      while (textTokenizer.hasMoreTokens())
445         while (goOn)
446         {
447             if (firstLabelTreated || (previousLine == null))
448             {
449                 // get next line
450                 nextLine = lnr.readLine();
451 
452                 if (nextLine == null)
453                 {
454                     goOn = false;
455 
456                     continue;
457                 }
458 
459                 //          nextLine = textTokenizer.nextToken();
460                 // jump over empty lines
461                 if (nextLine.equals(""))
462                 {
463                     continue;
464                 }
465 
466                 nextLine = JCAMPDataBlock.removeCommentsInLine(nextLine);
467             }
468             else
469             {
470                 nextLine = previousLine;
471             }
472 
473             //is label line or data line?
474             if ((nextLine.charAt(0) == '#') && (nextLine.charAt(1) == '#'))
475             {
476                 // try to determine the data type of one TITLE ... END data set
477                 label = JCAMPDataBlock.getLabelInLine(nextLine);
478 
479                 if (label != null)
480                 {
481                     // is LINK type ?
482                     if (label.equals(LINK_TYPE_DATA))
483                     {
484                         data = JCAMPDataBlock.getDataInLine(nextLine);
485 
486                         if ((data != null) && data.equals(LINK_TYPE))
487                         {
488                             // overwrite DX or CS type already defined WITHOUT WARNING
489                             dataBlock.setBlockType(JCAMPDataBlock.LINK_TYPE);
490                         }
491                         else
492                         {
493                             // check for IR, MS, UV - spectra type ... if you want ...
494                             // and store it as 'DATA TYPE'
495                         }
496                     }
497 
498                     // is CS type ?
499                     else if (label.equals(JCAMP_CHEMICAL_STRUCTURE))
500                     {
501                         // set only if undefined
502                         if (dataBlock.getBlockType() == JCAMPDataBlock.UNDEFINED_TYPE)
503                         {
504                             dataBlock.setBlockType(JCAMPDataBlock.CS_TYPE);
505                         }
506                     }
507 
508                     // is DX type ?
509                     else if (label.equals(JCAMP_SPECTRA))
510                     {
511                         // set only if undefined
512                         if (dataBlock.getBlockType() == JCAMPDataBlock.UNDEFINED_TYPE)
513                         {
514                             dataBlock.setBlockType(JCAMPDataBlock.DX_TYPE);
515                         }
516                     }
517 
518                     // nested data block ?
519                     else if (label.equals(JCAMP_START))
520                     {
521                         depth++;
522 
523                         if (depth == 2)
524                         {
525                             JCAMPDataBlock nestedDataBlock;
526                             nestedDataBlock = resolveJCAMPBlocks(depth,
527                                     nextLine, blockID);
528                             addDataBlock(nestedDataBlock);
529                             depth--;
530 
531                             continue;
532                         }
533                         else if (depth > 3)
534                         {
535                             return null;
536                         }
537                     }
538 
539                     // finsh data block
540                     else if (label.equals(JCAMP_STOP))
541                     {
542                         // add uncommented data to buffer
543                         tempBuffer.append(nextLine + "\n");
544                         dataBlock.setBlockData(tempBuffer.toString(), depth);
545                         tempBuffer.delete(0, tempBuffer.length());
546                         dataBlock.setBlockID(blockID);
547 
548                         return dataBlock;
549                     }
550                 }
551             }
552 
553             // add uncommented data to buffer
554             tempBuffer.append(nextLine + "\n");
555 
556             firstLabelTreated = true;
557         }
558 
559         return null;
560     }
561 }
562 ///////////////////////////////////////////////////////////////////////////////
563 //  END OF FILE.
564 ///////////////////////////////////////////////////////////////////////////////