~ubuntu-branches/ubuntu/maverick/cdk/maverick

« back to all changes in this revision

Viewing changes to src/org/openscience/cdk/io/GamessReader.java

  • Committer: Bazaar Package Importer
  • Author(s): Paul Cager
  • Date: 2008-04-09 21:17:53 UTC
  • Revision ID: james.westby@ubuntu.com-20080409211753-46lmjw5z8mx5pd8d
Tags: upstream-1.0.2
ImportĀ upstreamĀ versionĀ 1.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $RCSfile$
 
2
 * $Author: egonw $
 
3
 * $Date: 2007-01-04 18:46:10 +0100 (Thu, 04 Jan 2007) $
 
4
 * $Revision: 7636 $
 
5
 *
 
6
 * Copyright (C) 2003-2007  The Chemistry Development Kit (CDK) project
 
7
 *
 
8
 * Contact: cdk-devel@lists.sourceforge.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
package org.openscience.cdk.io;
 
25
 
 
26
import java.io.BufferedReader;
 
27
import java.io.IOException;
 
28
import java.io.InputStream;
 
29
import java.io.InputStreamReader;
 
30
import java.io.Reader;
 
31
import java.io.StreamTokenizer;
 
32
import java.io.StringReader;
 
33
 
 
34
import javax.vecmath.Point3d;
 
35
 
 
36
import org.openscience.cdk.interfaces.IAtom;
 
37
import org.openscience.cdk.interfaces.IChemFile;
 
38
import org.openscience.cdk.interfaces.IChemModel;
 
39
import org.openscience.cdk.interfaces.IChemObject;
 
40
import org.openscience.cdk.interfaces.IChemSequence;
 
41
import org.openscience.cdk.interfaces.IMolecule;
 
42
import org.openscience.cdk.PhysicalConstants;
 
43
import org.openscience.cdk.interfaces.IMoleculeSet;
 
44
import org.openscience.cdk.exception.CDKException;
 
45
import org.openscience.cdk.io.formats.GamessFormat;
 
46
import org.openscience.cdk.io.formats.IResourceFormat;
 
47
 
 
48
 
 
49
/**
 
50
 * A reader for GAMESS log file.
 
51
 * 
 
52
 * <p><b>Expected behaviour</b>: 
 
53
 * <br>The "GamessReader" object is able to read GAMESS output log file format. 
 
54
 * 
 
55
 * <p><b>Limitations</b>: <br>This reader was developed from a small set of 
 
56
 * example log files, and therefore, is not guaranteed to properly read all 
 
57
 * GAMESS output. If you have problems, please contact the author of this code, 
 
58
 * not the developers of GAMESS.
 
59
 * 
 
60
 * <!-- <p><b>State information</b>: <br> [] -->
 
61
 * <!-- <p><b>Dependencies</b>: <br> [all OS/Software/Hardware dependencies] -->
 
62
 * 
 
63
 * <p><b>Implementation</b>
 
64
 * <br>Available feature(s):
 
65
 * <ul>
 
66
 *      <li><b>Molecular coordinates</b>: Each set of coordinates is added to the ChemFile in the order they are found.</li>
 
67
 * </ul>
 
68
 * Unavailable feature(s):
 
69
 * <ul>
 
70
 * <!-- <li><b>GAMESS version number</b>: The version number can be retrieved.</li> -->
 
71
 * <!-- <li><b>Point group symetry information</b>: The point group is associated with the set of molecules.</li> -->
 
72
 * <!-- <li><b>MOPAC charges</b>: The point group is associated with the set of molecules.</li> -->
 
73
 *      <li><b>Energies</b>: They are associated with the previously read set of coordinates.</li>
 
74
 *      <li><b>Normal coordinates of vibrations</b>: They are associated with the previously read set of coordinates.</li>
 
75
 * </ul>
 
76
 * 
 
77
 * <!-- <p><b>Security:</b> -->
 
78
 * 
 
79
 * <p><b>References</b>: 
 
80
 * <br><a href="http://www.msg.ameslab.gov/GAMESS/GAMESS.html">GAMESS</a> is a 
 
81
 * quantum chemistry program by Gordon research group atIowa State University.
 
82
 * 
 
83
 * @cdk.module  experimental
 
84
 * @cdk.keyword Gamess
 
85
 * @cdk.keyword file format
 
86
 * @cdk.keyword output
 
87
 * @cdk.keyword log file
 
88
 * 
 
89
 * @author Bradley A. Smith
 
90
 * 
 
91
 * <!-- @see #GamessWriter(Reader) -->
 
92
 */
 
93
//TODO Update class comments with appropriate information.
 
94
//TODO Update "see" tag with reference to GamessWriter when it will be implemented.
 
95
//TODO Update "author" tag with appropriate information. 
 
96
public class GamessReader extends DefaultChemObjectReader {
 
97
        
 
98
        /**
 
99
         * Boolean constant used to specify that the coordinates are given in Bohr units.
 
100
         */
 
101
        public static final boolean BOHR_UNIT = true;
 
102
        
 
103
        /**
 
104
         * Double constant that contains the convertion factor from Bohr unit to 
 
105
         * &Aring;ngstrom unit.
 
106
         */
 
107
        //TODO Check the accuracy of this comment.
 
108
        public static final double BOHR_TO_ANGSTROM = 0.529177249;
 
109
        
 
110
        /**
 
111
         * Boolean constant used to specify that the coordinates are given in &Aring;ngstrom units.
 
112
         */
 
113
        public static final boolean ANGSTROM_UNIT = false;
 
114
        
 
115
        /**
 
116
         * The "BufferedReader" object used to read data from the "file system" file.
 
117
         * 
 
118
         * @see org.openscience.cdk.io.GamessReader#GamessReader(Reader)
 
119
         */
 
120
        //TODO Improve field comment.
 
121
        //TODO Answer the question : When is it opened and when is it closed?
 
122
        private BufferedReader input;
 
123
        
 
124
        /**
 
125
         * Constructs a new "GamessReader" object given a "Reader" object as input.
 
126
         * 
 
127
         * <p>The "Reader" object may be an instantiable object from the "Reader" 
 
128
         * hierarchy.
 
129
         * <br>For more detail about the "Reader" objects that are really accepted 
 
130
         * by this "GamessReader" see <code>accepts(IChemObject)</code> method
 
131
         * documentation.
 
132
         * 
 
133
         * @param       inputReader             The "Reader" object given as input parameter.
 
134
         * 
 
135
         * @see #accepts(Class)
 
136
         * @see java.io.Reader
 
137
         *  
 
138
         */
 
139
    public GamessReader(Reader inputReader) {
 
140
                this.input = new BufferedReader(inputReader);
 
141
    }
 
142
        
 
143
    public GamessReader(InputStream input) {
 
144
        this(new InputStreamReader(input));
 
145
    }
 
146
    
 
147
    public GamessReader() {
 
148
        this(new StringReader(""));
 
149
    }
 
150
    
 
151
        /* (non-Javadoc) (Javadoc is automaticly inherited from the link below)
 
152
         * @see org.openscience.cdk.io.ChemObjectIO#accepts(org.openscience.cdk.ChemObject)
 
153
         */
 
154
        //TODO Update comment with appropriate information to comply Constructor's documentation. 
 
155
        
 
156
    public IResourceFormat getFormat() {
 
157
        return GamessFormat.getInstance();
 
158
    }
 
159
    
 
160
    public void setReader(Reader reader) throws CDKException {
 
161
        this.input = new BufferedReader(input);
 
162
    }
 
163
 
 
164
    public void setReader(InputStream input) throws CDKException {
 
165
        setReader(new InputStreamReader(input));
 
166
    }
 
167
 
 
168
        public boolean accepts(Class classObject) {
 
169
                Class[] interfaces = classObject.getInterfaces();
 
170
                for (int i=0; i<interfaces.length; i++) {
 
171
                        if (IChemFile.class.equals(interfaces[i])) return true;
 
172
                }
 
173
                return false;
 
174
        }
 
175
 
 
176
        /* (non-Javadoc) (Javadoc is automaticly inherited from the link below)
 
177
         * @see org.openscience.cdk.io.ChemObjectReader#read(org.openscience.cdk.ChemObject)
 
178
         */
 
179
        public IChemObject read(IChemObject object) throws CDKException {
 
180
                if (object instanceof IChemFile) {
 
181
                        try {
 
182
                                return (IChemObject) readChemFile((IChemFile)object);
 
183
                        } catch (IOException e) {
 
184
                                return null;
 
185
                        }
 
186
                } else {
 
187
                        throw new CDKException("Only supported is reading of ChemFile objects.");
 
188
                }
 
189
        }
 
190
        
 
191
        /**
 
192
         * Reads data from the "file system" file through the use of the "input" 
 
193
         * field, parses data and feeds the ChemFile object with the extracted data.
 
194
         * 
 
195
         * @return A ChemFile containing the data parsed from input.
 
196
         * 
 
197
         * @throws      IOException     may be thrown buy the <code>this.input.readLine()</code> instruction.
 
198
         * 
 
199
         * @see org.openscience.cdk.io.GamessReader#input
 
200
         */
 
201
        //TODO Answer the question : Is this method's name appropriate (given the fact that it do not read a ChemFile object, but return it)? 
 
202
        private IChemFile readChemFile(IChemFile file) throws IOException {
 
203
                IChemSequence sequence = file.getBuilder().newChemSequence(); // TODO Answer the question : Is this line needed ?
 
204
                IChemModel model = file.getBuilder().newChemModel(); // TODO Answer the question : Is this line needed ?
 
205
                IMoleculeSet moleculeSet = file.getBuilder().newMoleculeSet();
 
206
                
 
207
                model.setMoleculeSet(moleculeSet); //TODO Answer the question : Should I do this?
 
208
                sequence.addChemModel(model); //TODO Answer the question : Should I do this?
 
209
                file.addChemSequence(sequence); //TODO Answer the question : Should I do this?
 
210
                
 
211
                String currentReadLine = this.input.readLine();
 
212
                while (this.input.ready() == true && (currentReadLine != null)) {
 
213
                        
 
214
                        /*
 
215
                         * There are 2 types of coordinate sets: 
 
216
                         * - bohr coordinates sets              (if statement)
 
217
                         * - angstr???m coordinates sets        (else statement)
 
218
                         */
 
219
                        if (currentReadLine.indexOf("COORDINATES (BOHR)") >= 0) {
 
220
                                
 
221
                                /* 
 
222
                                 * The following line do no contain data, so it is ignored.
 
223
                                 */
 
224
                                this.input.readLine();
 
225
                                moleculeSet.addMolecule(this.readCoordinates(
 
226
                                        file.getBuilder().newMolecule(), GamessReader.BOHR_UNIT
 
227
                            ));
 
228
                                //break; //<- stops when the first set of coordinates is found.
 
229
                        } else if (currentReadLine.indexOf(" COORDINATES OF ALL ATOMS ARE (ANGS)") >= 0) {
 
230
 
 
231
                                /* 
 
232
                                 * The following 2 lines do no contain data, so it are ignored.
 
233
                                 */
 
234
                                this.input.readLine();
 
235
                                this.input.readLine();
 
236
 
 
237
                                moleculeSet.addMolecule(this.readCoordinates(
 
238
                                        file.getBuilder().newMolecule(), GamessReader.ANGSTROM_UNIT
 
239
                                ));
 
240
                                //break; //<- stops when the first set of coordinates is found.
 
241
                        }
 
242
                        currentReadLine = this.input.readLine();
 
243
                }
 
244
                return file;
 
245
        }
 
246
        
 
247
        /**
 
248
         * Reads a set of coordinates from the "file system" file through the use of 
 
249
         * the "input" field, scales coordinate to angstr???m unit, builds each atom with 
 
250
         * the right associated coordinates, builds a new molecule with these atoms
 
251
         * and returns the complete molecule.
 
252
         * 
 
253
         * <p><b>Implementation</b>:
 
254
         * <br>Dummy atoms are ignored.
 
255
         * 
 
256
         * @param       coordinatesUnits        The unit in which coordinates are given.
 
257
         * 
 
258
         * @throws      IOException     may be thrown by the "input" object.
 
259
         * 
 
260
         * @see org.openscience.cdk.io.GamessReader#input
 
261
         */
 
262
        //TODO Update method comments with appropriate information.
 
263
        private IMolecule readCoordinates(IMolecule molecule, boolean coordinatesUnits) throws IOException {
 
264
                
 
265
                /*
 
266
                 * Coordinates must all be given in angstr???ms.
 
267
                 */ 
 
268
                double unitScaling = GamessReader.scalesCoordinatesUnits(coordinatesUnits);
 
269
                
 
270
                String retrievedLineFromFile;
 
271
                
 
272
                while (this.input.ready() == true) {
 
273
                        retrievedLineFromFile = this.input.readLine();
 
274
                        /* 
 
275
                         * A coordinate set is followed by an empty line, so when this line 
 
276
                         * is reached, there are no more coordinates to add to the current set.
 
277
                         */ 
 
278
                        if ((retrievedLineFromFile == null) || (retrievedLineFromFile.trim().length() == 0)) {
 
279
                                break;
 
280
                        }
 
281
                        
 
282
                        int atomicNumber;
 
283
                        String atomicSymbol;
 
284
                        
 
285
                        //StringReader sr = new StringReader(retrievedLineFromFile);
 
286
                        StreamTokenizer token = new StreamTokenizer(new StringReader(retrievedLineFromFile));
 
287
                        
 
288
                        /*
 
289
                         * The first token is ignored. It contains the atomic symbol and may 
 
290
                         * be concatenated with a number.
 
291
                         */
 
292
                        token.nextToken();
 
293
                        
 
294
                        if (token.nextToken() == StreamTokenizer.TT_NUMBER) {
 
295
                                atomicNumber = (int) token.nval;
 
296
                                atomicSymbol = this.identifyAtomicSymbol(atomicNumber);
 
297
                                /* 
 
298
                                 * Dummy atoms are assumed to be given with an atomic number set
 
299
                                 * to zero. We will do not add them to the molecule.
 
300
                                 */
 
301
                                if (atomicNumber == 0) {
 
302
                                        continue;
 
303
                                }
 
304
                        } else {
 
305
                                throw new IOException("Error reading coordinates");
 
306
                        }
 
307
                        
 
308
                        /*
 
309
                         * Atom's coordinates are stored in an array.
 
310
                         */
 
311
                        double[] coordinates = new double[3]; 
 
312
                        for (int i = 0; i < coordinates.length; i++) {
 
313
                                if (token.nextToken() == StreamTokenizer.TT_NUMBER) {
 
314
                                        coordinates[i] = token.nval * unitScaling;
 
315
                                } else {
 
316
                                        throw new IOException("Error reading coordinates");
 
317
                                }
 
318
                        }
 
319
                        IAtom atom = molecule.getBuilder().newAtom(atomicSymbol, new Point3d(coordinates[0],coordinates[1],coordinates[2]));
 
320
                        molecule.addAtom(atom);
 
321
                }
 
322
                return molecule;
 
323
        }
 
324
        
 
325
        /**
 
326
         * Identifies the atomic symbol of an atom given its default atomic number.
 
327
         * 
 
328
         * <p><b>Implementation</b>:
 
329
         * <br>This is not a definitive method. It will probably be replaced with a 
 
330
         * more appropriate one. Be advised that as it is not a definitive version, 
 
331
         * it only recognise atoms from Hydrogen (1) to Argon (18).
 
332
         * 
 
333
         * @param       atomicNumber    The atomic number of an atom.
 
334
         * 
 
335
         * @return      The Symbol corresponding to the atom or "null" is the atom was not recognised.
 
336
         */
 
337
        //TODO Update method comments with appropriate information.
 
338
        private String identifyAtomicSymbol(int atomicNumber) {
 
339
                String symbol;
 
340
                switch (atomicNumber) {
 
341
                        case 1:
 
342
                                symbol = "H";
 
343
                                break;
 
344
                        case 2:
 
345
                                symbol = "He";
 
346
                                break;
 
347
                        case 3:
 
348
                                symbol = "Li";
 
349
                                break;
 
350
                        case 4:
 
351
                                symbol = "Be";
 
352
                                break;
 
353
                        case 5:
 
354
                                symbol = "B";
 
355
                                break;
 
356
                        case 6:
 
357
                                symbol = "C";
 
358
                                break;
 
359
                        case 7:
 
360
                                symbol = "N";
 
361
                                break;
 
362
                        case 8:
 
363
                                symbol = "O";
 
364
                                break;
 
365
                        case 9:
 
366
                                symbol = "F";
 
367
                                break;
 
368
                        case 10:
 
369
                                symbol = "Ne";
 
370
                                break;
 
371
                        case 11:
 
372
                                symbol = "Na";
 
373
                                break;
 
374
                        case 12:
 
375
                                symbol = "Mg";
 
376
                                break;
 
377
                        case 13:
 
378
                                symbol = "Al";
 
379
                                break;
 
380
                        case 14:
 
381
                                symbol = "Si";
 
382
                                break;
 
383
                        case 15:
 
384
                                symbol = "P";
 
385
                                break;
 
386
                        case 16:
 
387
                                symbol = "S";
 
388
                                break;
 
389
                        case 17:
 
390
                                symbol = "Cl";
 
391
                                break;
 
392
                        case 18:
 
393
                                symbol = "Ar";
 
394
                                break;
 
395
                        default:
 
396
                                symbol = null;
 
397
                                break; 
 
398
                }
 
399
                return symbol;
 
400
        }
 
401
        
 
402
        /**
 
403
         * Scales coordinates to &Aring;ngstr&ouml;m unit if they are given in Bohr unit. 
 
404
         * If coordinates are already given in &Aring;ngstr&ouml;m unit, then no modifications
 
405
         * are performed.
 
406
         * 
 
407
         * @param       coordinatesUnits        <code>BOHR_UNIT</code> if coordinates are given in Bohr unit and <code>ANGSTROM_UNIT</code> 
 
408
     *                              if they are given in &Aring;ngstr&ouml;m unit.
 
409
         * 
 
410
         * @return      The scaling convertion factor: 1 if no scaling is needed and <code>BOHR_TO_ANGSTROM</code> if scaling has to be performed.
 
411
         * 
 
412
         * @see org.openscience.cdk.PhysicalConstants#BOHR_TO_ANGSTROM
 
413
         * @see org.openscience.cdk.io.GamessReader#BOHR_UNIT
 
414
         * @see org.openscience.cdk.io.GamessReader#ANGSTROM_UNIT
 
415
         */
 
416
        //TODO Update method comments with appropriate information.
 
417
        private static double scalesCoordinatesUnits(boolean coordinatesUnits) {
 
418
                if (coordinatesUnits == GamessReader.BOHR_UNIT) {
 
419
                        return PhysicalConstants.BOHR_TO_ANGSTROM;
 
420
                } else { //condition is: (coordinatesUnits == GamessReader.ANGTROM_UNIT)
 
421
                        return (double) 1;
 
422
                }
 
423
        }
 
424
        
 
425
        /* (non-Javadoc) (Javadoc is automaticly inherited from the link below)
 
426
         * @see org.openscience.cdk.io.ChemObjectIO#close()
 
427
         */
 
428
        //TODO Answer the question : What are all concerned ressources ? 
 
429
        public void close() throws IOException {
 
430
                /* 
 
431
                 * Closes the BufferedReader used to read the file content.
 
432
                 */ 
 
433
                input.close();
 
434
        }    
 
435
}
 
 
b'\\ No newline at end of file'