File: obthermo.cpp

package info (click to toggle)
openbabel 3.1.1%2Bdfsg-9
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 259,620 kB
  • sloc: cpp: 361,957; python: 11,640; ansic: 6,470; perl: 6,010; pascal: 793; php: 529; sh: 226; xml: 97; ruby: 64; makefile: 45; java: 23
file content (247 lines) | stat: -rw-r--r-- 8,459 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/**********************************************************************
obthermo.cpp - extract the thermochemistry for a molecule

Copyright (C) 2015 David van der Spoel

This file is part of the Open Babel project.
For more information, see <http://openbabel.org/>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 2 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
***********************************************************************/

// used to set import/export for Cygwin DLLs
#ifdef WIN32
#define USING_OBDLL
#endif

#include <openbabel/babelconfig.h>
#include <openbabel/base.h>
#include <openbabel/mol.h>
#include <openbabel/obconversion.h>
#include <openbabel/data_utilities.h>
#include <openbabel/pointgroup.h>
#include <cstdlib>
#ifndef _MSC_VER
  #include <unistd.h>
#endif

using namespace std;
using namespace OpenBabel;

int main(int argc,char **argv)
{
  char  *program_name = argv[0];
  int    Nsymm = 0, Nrot = 0;
  bool   bKJ   = false;
  double dBdT  = 0;
  string filename, option;
  OBConversion conv;
  double unit_factor = 1;
  string e_unit("kcal/mol");
  string s_unit("cal/mol K");
  
  if (argc < 2) {
    cout << "Usage: obthermo [options] <filename>" << endl;
    cout << endl;
    cout << "options:      description:" << endl;
    cout << endl;
    cout << "  --symm N    override symmetry number used in input file" << endl;
    cout << endl;
    cout << "  --nrot N    number of rotatable bonds for conformational entropy" << endl;
    cout << endl;
    cout << "  --dbdt x    temperature derivative of second virial coefficient for cp calculation" << endl;
    cout << endl;
    cout << "  --kj        output kJ/mol related units (default kcal/mol)" << endl;
    cout << endl;
    exit(-1);
  } else {
    int i;
    for (i = 1; i < argc; ) {
      option = argv[i];

      if ((option == "--symm") && (argc > (i+1))) {
        Nsymm = atoi(argv[i+1]);
        if (Nsymm < 1) {
            cerr << program_name << ": the symmetry number should be >= 1!" << endl;
            exit(-1);
        }
        i += 2;
      }
      else if ((option == "--nrot") && (argc > (i+1))) {
        Nrot = atoi(argv[i+1]);
        if (Nrot < 0) {
            cerr << program_name << ": the number of rotatable bonds should be >= 0!" << endl;
            exit(-1);
        }
        i += 2;
      }
      else if ((option == "--dbdt") && (argc > (i+1))) {
        dBdT = atof(argv[i+1]);
        if (dBdT < 0) {
            cerr << program_name << ": the derivative of the second virial coefficient with respect to temperature should be >= 0!" << endl;
            exit(-1);
        }
        i += 2;
      }
      else if (option == "--kj") {
        bKJ          = true;
        unit_factor  = 4.184;
        e_unit.assign("kJ/mol");
        s_unit.assign("J/mol K");
        i += 1;
      }
      else {
        filename.assign(argv[i]);
        i += 1;
      }
    }
  }
  if (filename.size() == 0) {
    cerr << program_name << ": no filename specified" << endl;
    exit (-1);
  }
  // Find Input filetype
  OBFormat *format_in = conv.FormatFromExt(filename.c_str());

  if (!format_in || !conv.SetInFormat(format_in)) {
    cerr << program_name << ": cannot read input format in file \"" << filename << "\"" << endl;
    exit (-1);
  }

  ifstream ifs;

  // Read the file
  ifs.open(filename.c_str());
  if (!ifs) {
    cerr << program_name << ": cannot read input file!" << endl;
    exit (-1);
  }
  OBMol mol;
  if ((conv.Read(&mol, &ifs)) && ! mol.Empty())
  {
      OBPointGroup obPG;
      double temperature, DeltaHf0, DeltaHfT, DeltaGfT, DeltaSfT, S0T, CVT, CPT, ZPVE;
      std::vector<double> Scomponents;
      
      obPG.Setup(&mol);
      printf("obthermo - extract thermochemistry data from quantum chemistry logfiles\n");
      printf("Number of rotatable bonds: %d\n", Nrot);
      if (dBdT == 0)
      {
          printf("Please supply --dbdt option to get reliable heat capacity at constant pressure.\n");
      }
      printf("Point group according to OpenBabel: %s\n", 
             obPG.IdentifyPointGroup());
      bool bVerbose = true;
      if (extract_thermochemistry(mol, 
                                  bVerbose,
                                  &Nsymm,
                                  Nrot,
                                  dBdT,
                                  &temperature,
                                  &DeltaHf0,
                                  &DeltaHfT,
                                  &DeltaGfT,
                                  &DeltaSfT,
                                  &S0T,
                                  &CVT,
                                  &CPT,
                                  Scomponents,
                                  &ZPVE))
      {
          double Rgas  = 1.9872041; // cal/mol K
          printf("DeltaHform(0K)  %10g  %s\n", DeltaHf0*unit_factor, e_unit.c_str());
          printf("Temperature     %10g  K\n", temperature);
          printf("DeltaHform(T)   %10g  %s\n", DeltaHfT*unit_factor, e_unit.c_str());
          printf("DeltaGform(T)   %10g  %s\n", DeltaGfT*unit_factor, e_unit.c_str());
          printf("DeltaSform(T)   %10g  %s\n", DeltaSfT*unit_factor, s_unit.c_str());
          printf("cv(T)           %10g  %s\n", CVT*unit_factor, s_unit.c_str());
          printf("cp(T)           %10g  %s\n", CPT*unit_factor, s_unit.c_str());
          printf("Strans(T)       %10g  %s\n", Scomponents[0]*unit_factor, s_unit.c_str());
          printf("Srot(T)         %10g  %s\n", Scomponents[1]*unit_factor, s_unit.c_str());
          printf("Svib(T)         %10g  %s\n", Scomponents[2]*unit_factor, s_unit.c_str());
          if (Scomponents[3] != 0) 
          {
              printf("Ssymm           %10g  %s\n", Scomponents[3]*unit_factor, s_unit.c_str());
          }
          if (Scomponents[4] != 0) 
          {
              printf("Sconf           %10g  %s\n", Scomponents[4]*unit_factor, s_unit.c_str());
          }
          printf("S0(T)           %10g  %s\n", S0T*unit_factor, s_unit.c_str());
      }
      else
      {
          printf("Could not find all necessary information to determine thermochemistry values.\n");
      }
  }
  ifs.close();
  
  return 0;
}

/* obthermo man page*/
/** \page extract thermochemistry data from a quantum chemistry calculation
*
* \n
* \par SYNOPSIS
*
* \b obthermo [options] \<filename\>
*
* \par DESCRIPTION
*
* The obthermo tool can be used to extract the thermochemistry, e.g. Delta H formation
* Delta G formation and the standard entropy from e.g. a Gaussian calculation.
*
* \par OPTIONS
*
* If no filename is given, obtherm will give all options
*
* \b --symm \<N\>:
*     Set the symmetry number manually and correct results if needed\n\n
*
* \b --nrot \<N\>:
*     Set the number of rotatable bond manually and correct results if needed\n\n
*
* \b --dbdt \<x\>:
*     Set the derivative of the second virial coefficient with temperature for cp calculation\n\n
*
* \b --kj:
*     Use Joules instead of Calories in the output\n\n
*
* \par EXAMPLES
*  - View the possible options:
*   obthermo
*  - Print thermochemistry for the molecule in file test.log:
*   obthermo test.log
*  - Id. but correct the symmetry number
*   obenergy --symm 12 test.log
*
* \par AUTHORS
*
* The obthermo program was contributed by \b David \b van \b der \b Spoel.
*
* Open Babel is currently maintained by \b Geoff \b Hutchison, \b Chris \b Morley and \b Michael \b Banck.
*
* For more contributors to Open Babel, see http://openbabel.org/THANKS.shtml
*
* \par COPYRIGHT
*  Copyright (C) 2015 by David van der Spoel. \n \n
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation version 2 of the License.\n \n
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
* \par SEE ALSO
*   The web pages for Open Babel can be found at: http://openbabel.org/ \n
**/