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

« back to all changes in this revision

Viewing changes to src/org/openscience/cdk/io/program/GaussianInputWriter.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.program;
 
25
 
 
26
import java.io.BufferedWriter;
 
27
import java.io.IOException;
 
28
import java.io.OutputStream;
 
29
import java.io.OutputStreamWriter;
 
30
import java.io.StringWriter;
 
31
import java.io.Writer;
 
32
import java.util.Vector;
 
33
 
 
34
import javax.vecmath.Point3d;
 
35
 
 
36
import org.openscience.cdk.exception.CDKException;
 
37
import org.openscience.cdk.interfaces.IAtom;
 
38
import org.openscience.cdk.interfaces.IChemObject;
 
39
import org.openscience.cdk.interfaces.IMolecule;
 
40
import org.openscience.cdk.io.DefaultChemObjectWriter;
 
41
import org.openscience.cdk.io.formats.GaussianInputFormat;
 
42
import org.openscience.cdk.io.formats.IResourceFormat;
 
43
import org.openscience.cdk.io.setting.BooleanIOSetting;
 
44
import org.openscience.cdk.io.setting.IOSetting;
 
45
import org.openscience.cdk.io.setting.IntegerIOSetting;
 
46
import org.openscience.cdk.io.setting.OptionIOSetting;
 
47
import org.openscience.cdk.io.setting.StringIOSetting;
 
48
 
 
49
/**
 
50
 * File writer thats generates input files for Gaussian calculation
 
51
 * jobs. It was tested with Gaussian98.
 
52
 *
 
53
 * @cdk.module io
 
54
 *
 
55
 * @author  Egon Willighagen <egonw@sci.kun.nl>
 
56
 *
 
57
 * @cdk.keyword Gaussian (tm), input file
 
58
 */
 
59
public class GaussianInputWriter extends DefaultChemObjectWriter {
 
60
  
 
61
    static BufferedWriter writer;
 
62
    
 
63
    IOSetting method;
 
64
    IOSetting basis;
 
65
    IOSetting comment;
 
66
    IOSetting command;
 
67
    IOSetting memory;
 
68
    BooleanIOSetting shell;
 
69
    IntegerIOSetting proccount;
 
70
    BooleanIOSetting usecheckpoint;
 
71
    
 
72
    /**
 
73
    * Constructs a new writer that produces input files to run a
 
74
    * Gaussian QM job.
 
75
    */
 
76
    public GaussianInputWriter(Writer out) {
 
77
        try {
 
78
                if (out instanceof BufferedWriter) {
 
79
                writer = (BufferedWriter)out;
 
80
            } else {
 
81
                writer = new BufferedWriter(out);
 
82
            }
 
83
        } catch (Exception exc) {
 
84
        }
 
85
        initIOSettings();
 
86
    }
 
87
    
 
88
    public GaussianInputWriter(OutputStream output) {
 
89
        this(new OutputStreamWriter(output));
 
90
    }
 
91
    
 
92
    public GaussianInputWriter() {
 
93
        this(new StringWriter());
 
94
    }
 
95
 
 
96
    public IResourceFormat getFormat() {
 
97
        return GaussianInputFormat.getInstance();
 
98
    }
 
99
    
 
100
    public void setWriter(Writer out) throws CDKException {
 
101
        if (out instanceof BufferedWriter) {
 
102
            writer = (BufferedWriter)out;
 
103
        } else {
 
104
            writer = new BufferedWriter(out);
 
105
        }
 
106
    }
 
107
 
 
108
    public void setWriter(OutputStream output) throws CDKException {
 
109
        setWriter(new OutputStreamWriter(output));
 
110
    }
 
111
 
 
112
    public void close() throws IOException {
 
113
        writer.close();
 
114
    }
 
115
    
 
116
        public boolean accepts(Class classObject) {
 
117
                if (IMolecule.class.isInstance(classObject)) return true;
 
118
                return false;
 
119
        }
 
120
 
 
121
    public void write(IChemObject object) throws CDKException {
 
122
        if (object instanceof IMolecule) {
 
123
            try {
 
124
                writeMolecule((IMolecule)object);
 
125
            } catch(Exception ex) {
 
126
                throw new CDKException("Error while writing Gaussian input file: " + ex.getMessage(), ex);
 
127
            }
 
128
        } else {
 
129
            throw new CDKException("GaussianInputWriter only supports output of Molecule classes.");
 
130
        }
 
131
    }
 
132
    
 
133
    /**
 
134
     * Writes a molecule for input for Gaussian.
 
135
     */
 
136
    public void writeMolecule(IMolecule mol) throws IOException {
 
137
        
 
138
        customizeJob();
 
139
        
 
140
        // write extra statements
 
141
        if (proccount.getSettingValue() > 1) {
 
142
            writer.write("%nprocl=" + proccount.getSettingValue());
 
143
            writer.newLine();
 
144
        }
 
145
        if (!memory.getSetting().equals("unset")) {
 
146
            writer.write("%Mem=" + memory.getSetting());
 
147
            writer.newLine();
 
148
        }
 
149
        if (usecheckpoint.isSet()) {
 
150
            if (mol.getID() != null && mol.getID().length() > 0) {
 
151
                writer.write("%chk=" + mol.getID() + ".chk");
 
152
            } else {
 
153
                // force different file names
 
154
                writer.write("%chk=" + System.currentTimeMillis() + ".chk");
 
155
            }
 
156
            writer.newLine();
 
157
        }
 
158
        
 
159
        // write the command line
 
160
        writer.write("# " + method.getSetting() + 
 
161
                     "/" + basis.getSetting() +  
 
162
                     " ");
 
163
        String commandString = command.getSetting();
 
164
        if (commandString.equals("energy calculation")) {
 
165
            // ok, no special command needed
 
166
        } else if (commandString.equals("geometry optimization")) {
 
167
            writer.write("opt");
 
168
        } else if (commandString.equals("IR frequency calculation")) {
 
169
            writer.write("freq");
 
170
        } else if (commandString.equals("IR frequency calculation (with Raman)")) {
 
171
            writer.write("freq=noraman");
 
172
        } else {
 
173
            // assume that user knows what he's doing
 
174
            writer.write(commandString);
 
175
        }
 
176
        writer.newLine();
 
177
        
 
178
        // next line is empty
 
179
        writer.newLine();
 
180
        
 
181
        // next line is comment
 
182
        writer.write(comment.getSetting() + "\n");
 
183
        
 
184
        // next line is empty
 
185
        writer.newLine();
 
186
 
 
187
        /* next line contains two digits
 
188
         * the first is the total charge
 
189
         * the second is boolean indicating:
 
190
         *   0 = open shell
 
191
         *   1 = closed shell
 
192
         */
 
193
        writer.write("0 "); // FIXME: should write total charge of molecule
 
194
        if (shell.isSet()) {
 
195
            writer.write("0");
 
196
        } else {
 
197
            writer.write("1");
 
198
        }
 
199
        writer.newLine();
 
200
        
 
201
        // then come all the atoms. 
 
202
        // Loop through the atoms and write them out:
 
203
        java.util.Iterator atoms = mol.atoms();
 
204
        while (atoms.hasNext()) {
 
205
                IAtom a = (IAtom)atoms.next();
 
206
            String st = a.getSymbol();
 
207
            
 
208
            // export Eucledian coordinates (indicated by the 0)
 
209
            st = st + " 0 ";
 
210
            
 
211
            // export the 3D coordinates
 
212
            Point3d p3 = a.getPoint3d();
 
213
            if (p3 != null) {
 
214
                st = st + new Double(p3.x).toString() + " "
 
215
                        + new Double(p3.y).toString() + " "
 
216
                        + new Double(p3.z).toString();
 
217
            }
 
218
            
 
219
            writer.write(st, 0, st.length());
 
220
            writer.newLine();
 
221
        }
 
222
        
 
223
        // G98 expects an empty line at the end
 
224
        writer.newLine();
 
225
    }
 
226
    
 
227
    private void initIOSettings() {
 
228
        Vector basisOptions = new Vector();
 
229
        basisOptions.add("6-31g");
 
230
        basisOptions.add("6-31g*");
 
231
        basisOptions.add("6-31g(d)");
 
232
        basisOptions.add("6-311g");
 
233
        basisOptions.add("6-311+g**");
 
234
        basis = new OptionIOSetting("Basis", IOSetting.MEDIUM,
 
235
          "Which basis set do you want to use?", basisOptions, "6-31g");
 
236
 
 
237
        Vector methodOptions = new Vector();
 
238
        methodOptions.add("rb3lyp");
 
239
        methodOptions.add("b3lyp");
 
240
        methodOptions.add("rhf");
 
241
        method = new OptionIOSetting("Method", IOSetting.MEDIUM,
 
242
          "Which method do you want to use?", methodOptions, "b3lyp");
 
243
        
 
244
        Vector commandOptions = new Vector();
 
245
        commandOptions.add("energy calculation");
 
246
        commandOptions.add("geometry optimization");
 
247
        commandOptions.add("IR frequency calculation");
 
248
        commandOptions.add("IR frequency calculation (with Raman)");
 
249
        command = new OptionIOSetting("Command", IOSetting.HIGH,
 
250
          "What kind of job do you want to perform?", commandOptions, 
 
251
          "energy calculation");
 
252
        
 
253
        comment = new StringIOSetting("Comment", IOSetting.LOW,
 
254
          "What comment should be put in the file?", 
 
255
          "Created with CDK (http://cdk.sf.net/)");
 
256
        
 
257
        memory = new StringIOSetting("Memory", IOSetting.LOW,
 
258
          "How much memory do you want to use?", 
 
259
          "unset");
 
260
        
 
261
        shell = new BooleanIOSetting("OpenShell", IOSetting.MEDIUM,
 
262
          "Should the calculation be open shell?", 
 
263
          "false");
 
264
 
 
265
        proccount = new IntegerIOSetting("ProcessorCount", IOSetting.LOW,
 
266
          "How many processors should be used by Gaussian?", 
 
267
          "1");
 
268
 
 
269
        usecheckpoint = new BooleanIOSetting("UseCheckPointFile", IOSetting.LOW,
 
270
          "Should a check point file be saved?", 
 
271
          "false");
 
272
    }
 
273
    
 
274
    private void customizeJob() {
 
275
        fireIOSettingQuestion(basis);
 
276
        fireIOSettingQuestion(method);
 
277
        fireIOSettingQuestion(command);
 
278
        fireIOSettingQuestion(comment);
 
279
        fireIOSettingQuestion(shell);
 
280
        fireIOSettingQuestion(proccount);
 
281
        fireIOSettingQuestion(memory);
 
282
        fireIOSettingQuestion(usecheckpoint);
 
283
    }
 
284
    
 
285
    public IOSetting[] getIOSettings() {
 
286
        IOSetting[] settings = new IOSetting[8];
 
287
        settings[0] = basis;
 
288
        settings[1] = method;
 
289
        settings[2] = command;
 
290
        settings[3] = comment;
 
291
        settings[4] = shell;
 
292
        settings[5] = proccount;
 
293
        settings[6] = usecheckpoint;
 
294
        settings[7] = memory;
 
295
        return settings;
 
296
    }
 
297
}
 
298
 
 
299