chemruby 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (241) hide show
  1. data/README +120 -0
  2. data/Rakefile +195 -0
  3. data/ext/extconf.rb +4 -0
  4. data/ext/subcomp.c +416 -0
  5. data/lib/chem.rb +130 -0
  6. data/lib/chem/appl.rb +1 -0
  7. data/lib/chem/appl/chem3dole.rb +36 -0
  8. data/lib/chem/appl/tinker/nucleic.rb +40 -0
  9. data/lib/chem/appl/tinker/tinker_reader.rb +43 -0
  10. data/lib/chem/data.rb +4 -0
  11. data/lib/chem/data/atomic_weight.rb +124 -0
  12. data/lib/chem/data/character.rb +2 -0
  13. data/lib/chem/data/electronegativity.rb +14 -0
  14. data/lib/chem/data/periodic_table.rb +6 -0
  15. data/lib/chem/data/prime_numbers.rb +1 -0
  16. data/lib/chem/data/vdw_radii.rb +1 -0
  17. data/lib/chem/db.rb +64 -0
  18. data/lib/chem/db/cansmi.rb +234 -0
  19. data/lib/chem/db/cdx.rb +1525 -0
  20. data/lib/chem/db/eps.rb +164 -0
  21. data/lib/chem/db/g98.rb +909 -0
  22. data/lib/chem/db/gspan.rb +130 -0
  23. data/lib/chem/db/iupac.rb +5 -0
  24. data/lib/chem/db/iupac/a_1.rb +46 -0
  25. data/lib/chem/db/iupac/iuparser.rb +226 -0
  26. data/lib/chem/db/iupac/iuparser.ry +97 -0
  27. data/lib/chem/db/iupac/postfix.rb +2 -0
  28. data/lib/chem/db/kcf.rb +390 -0
  29. data/lib/chem/db/kcf_glycan.rb +19 -0
  30. data/lib/chem/db/kegg.rb +516 -0
  31. data/lib/chem/db/linucs/linparser.rb +144 -0
  32. data/lib/chem/db/linucs/linucs.ry +53 -0
  33. data/lib/chem/db/mdl.rb +379 -0
  34. data/lib/chem/db/molconnz.rb +12 -0
  35. data/lib/chem/db/mopac.rb +88 -0
  36. data/lib/chem/db/msi.rb +107 -0
  37. data/lib/chem/db/pdb_dic.rb +115 -0
  38. data/lib/chem/db/pdf.rb +131 -0
  39. data/lib/chem/db/pubchem.rb +113 -0
  40. data/lib/chem/db/rmagick.rb +70 -0
  41. data/lib/chem/db/sdf.rb +37 -0
  42. data/lib/chem/db/smbl.rb +88 -0
  43. data/lib/chem/db/smiles.rb +2 -0
  44. data/lib/chem/db/smiles/smiles.ry +203 -0
  45. data/lib/chem/db/smiles/smiparser.rb +375 -0
  46. data/lib/chem/db/swf.rb +74 -0
  47. data/lib/chem/db/sybyl.rb +150 -0
  48. data/lib/chem/db/tinker.rb +77 -0
  49. data/lib/chem/db/types/type_cansmi.rb +9 -0
  50. data/lib/chem/db/types/type_cdx.rb +24 -0
  51. data/lib/chem/db/types/type_gspan.rb +31 -0
  52. data/lib/chem/db/types/type_kcf.rb +28 -0
  53. data/lib/chem/db/types/type_kcf_glycan.rb +26 -0
  54. data/lib/chem/db/types/type_kegg.rb +92 -0
  55. data/lib/chem/db/types/type_mdl.rb +31 -0
  56. data/lib/chem/db/types/type_pdf.rb +33 -0
  57. data/lib/chem/db/types/type_png.rb +31 -0
  58. data/lib/chem/db/types/type_rxn.rb +25 -0
  59. data/lib/chem/db/types/type_sdf.rb +25 -0
  60. data/lib/chem/db/types/type_sybyl.rb +30 -0
  61. data/lib/chem/db/types/type_xyz.rb +26 -0
  62. data/lib/chem/db/vector.rb +128 -0
  63. data/lib/chem/db/xyz.rb +39 -0
  64. data/lib/chem/model.rb +119 -0
  65. data/lib/chem/model/skeleton.rb +37 -0
  66. data/lib/chem/utils.rb +11 -0
  67. data/lib/chem/utils/geometry.rb +27 -0
  68. data/lib/chem/utils/graph_db.rb +146 -0
  69. data/lib/chem/utils/math.rb +17 -0
  70. data/lib/chem/utils/prop.rb +123 -0
  71. data/lib/chem/utils/sssr.rb +101 -0
  72. data/lib/chem/utils/sub.rb +78 -0
  73. data/lib/chem/utils/transform.rb +110 -0
  74. data/lib/chem/utils/traverse.rb +37 -0
  75. data/lib/chem/utils/ullmann.rb +134 -0
  76. data/lib/graph.rb +41 -0
  77. data/lib/graph/cluster.rb +20 -0
  78. data/lib/graph/morgan.rb +38 -0
  79. data/sample/frequent_subgraph.rb +46 -0
  80. data/sample/images/ex1.rb +11 -0
  81. data/sample/images/ex2.rb +4 -0
  82. data/sample/images/ex3.rb +5 -0
  83. data/sample/images/ex4.rb +17 -0
  84. data/sample/images/ex5.rb +10 -0
  85. data/sample/images/mol/adenine.mol +26 -0
  86. data/sample/images/mol/atp.mol +69 -0
  87. data/sample/images/temp/ex5.mol +344 -0
  88. data/sample/kegg_db.rb +116 -0
  89. data/setup.rb +1551 -0
  90. data/test/all.rb +6 -0
  91. data/test/coord_test.rb +17 -0
  92. data/test/ctab_test.rb +31 -0
  93. data/test/data/A_21.tar.gz +0 -0
  94. data/test/data/A_21/aceanthrylene.cdx +0 -0
  95. data/test/data/A_21/aceanthrylene.mol +40 -0
  96. data/test/data/A_21/acenaphthylene.cdx +0 -0
  97. data/test/data/A_21/acenaphthylene.mol +31 -0
  98. data/test/data/A_21/acephenanthrylene.cdx +0 -0
  99. data/test/data/A_21/acephenanthrylene.mol +40 -0
  100. data/test/data/A_21/anthracene.cdx +0 -0
  101. data/test/data/A_21/anthracene.mol +35 -0
  102. data/test/data/A_21/as-indacene.cdx +0 -0
  103. data/test/data/A_21/as-indacene.mol +31 -0
  104. data/test/data/A_21/azulene.cdx +0 -0
  105. data/test/data/A_21/azulene.mol +26 -0
  106. data/test/data/A_21/biphenylene.cdx +0 -0
  107. data/test/data/A_21/biphenylene.mol +31 -0
  108. data/test/data/A_21/chrysene.cdx +0 -0
  109. data/test/data/A_21/chrysene.mol +44 -0
  110. data/test/data/A_21/coronen.cdx +0 -0
  111. data/test/data/A_21/coronen.mol +59 -0
  112. data/test/data/A_21/fluoranthene.cdx +0 -0
  113. data/test/data/A_21/fluoranthene.mol +40 -0
  114. data/test/data/A_21/fluorene.cdx +0 -0
  115. data/test/data/A_21/fluorene.mol +33 -0
  116. data/test/data/A_21/heptacene.cdx +0 -0
  117. data/test/data/A_21/heptacene.mol +71 -0
  118. data/test/data/A_21/heptalene.cdx +0 -0
  119. data/test/data/A_21/heptalene.mol +30 -0
  120. data/test/data/A_21/heptaphene.cdx +0 -0
  121. data/test/data/A_21/heptaphene.mol +71 -0
  122. data/test/data/A_21/hexacene.cdx +0 -0
  123. data/test/data/A_21/hexacene.mol +62 -0
  124. data/test/data/A_21/hexaphene.cdx +0 -0
  125. data/test/data/A_21/hexaphene.mol +62 -0
  126. data/test/data/A_21/indene.cdx +0 -0
  127. data/test/data/A_21/indene.mol +24 -0
  128. data/test/data/A_21/iupac.txt +41 -0
  129. data/test/data/A_21/naphthacene.cdx +0 -0
  130. data/test/data/A_21/naphthacene.mol +44 -0
  131. data/test/data/A_21/naphthalene.cdx +0 -0
  132. data/test/data/A_21/naphthalene.mol +26 -0
  133. data/test/data/A_21/ovalene.cdx +0 -0
  134. data/test/data/A_21/ovalene.mol +78 -0
  135. data/test/data/A_21/pentacene.cdx +0 -0
  136. data/test/data/A_21/pentacene.mol +53 -0
  137. data/test/data/A_21/pentalene.cdx +0 -0
  138. data/test/data/A_21/pentalene.mol +22 -0
  139. data/test/data/A_21/pentaphene.cdx +0 -0
  140. data/test/data/A_21/pentaphene.mol +53 -0
  141. data/test/data/A_21/perylene.cdx +0 -0
  142. data/test/data/A_21/perylene.mol +49 -0
  143. data/test/data/A_21/phenalene.cdx +0 -0
  144. data/test/data/A_21/phenalene.mol +33 -0
  145. data/test/data/A_21/phenanthrene.cdx +0 -0
  146. data/test/data/A_21/phenanthrene.mol +35 -0
  147. data/test/data/A_21/picene.cdx +0 -0
  148. data/test/data/A_21/picene.mol +53 -0
  149. data/test/data/A_21/pleiadene.cdx +0 -0
  150. data/test/data/A_21/pleiadene.mol +44 -0
  151. data/test/data/A_21/pyranthrene.cdx +0 -0
  152. data/test/data/A_21/pyranthrene.mol +72 -0
  153. data/test/data/A_21/pyrene.cdx +0 -0
  154. data/test/data/A_21/pyrene.mol +40 -0
  155. data/test/data/A_21/rubicene.cdx +0 -0
  156. data/test/data/A_21/rubicene.mol +63 -0
  157. data/test/data/A_21/s-indacene.cdx +0 -0
  158. data/test/data/A_21/s-indacene.mol +31 -0
  159. data/test/data/A_21/tetraphenylene.cdx +0 -0
  160. data/test/data/A_21/tetraphenylene.mol +57 -0
  161. data/test/data/A_21/trinaphthylene.cdx +0 -0
  162. data/test/data/A_21/trinaphthylene.mol +71 -0
  163. data/test/data/A_21/triphenylene.cdx +0 -0
  164. data/test/data/A_21/triphenylene.mol +44 -0
  165. data/test/data/C00147.kcf +25 -0
  166. data/test/data/G00147.kcf +13 -0
  167. data/test/data/atp.mol +69 -0
  168. data/test/data/cyclohexane.mol +17 -0
  169. data/test/data/cyclohexane.ps +485 -0
  170. data/test/data/fullerene.mol +155 -0
  171. data/test/data/glycan +33 -0
  172. data/test/data/hypericin.cdx +0 -0
  173. data/test/data/hypericin.cdxml +596 -0
  174. data/test/data/hypericin.chm +0 -0
  175. data/test/data/hypericin.ct +85 -0
  176. data/test/data/hypericin.f1d +0 -0
  177. data/test/data/hypericin.f1q +0 -0
  178. data/test/data/hypericin.gif +0 -0
  179. data/test/data/hypericin.mol +88 -0
  180. data/test/data/hypericin.mol2 +159 -0
  181. data/test/data/hypericin.msm +123 -0
  182. data/test/data/hypericin.pdf +359 -0
  183. data/test/data/hypericin.png +0 -0
  184. data/test/data/hypericin.ps +0 -0
  185. data/test/data/hypericin.skc +0 -0
  186. data/test/data/hypericin2.gif +0 -0
  187. data/test/data/hypericin2.ps +0 -0
  188. data/test/data/kegg/genomes/hsa/hsa_enzyme.list +4 -0
  189. data/test/data/kegg/genomes/hsa/hsa_pfam.list +4 -0
  190. data/test/data/kegg/ligand/mol/C00147.mol +26 -0
  191. data/test/data/kegg/ligand/reaction +14 -0
  192. data/test/data/kegg/ligand/reaction.lst +1 -0
  193. data/test/data/kegg/ligand/reaction_mapformula.lst +3 -0
  194. data/test/data/reaction +14 -0
  195. data/test/data/reaction.lst +1 -0
  196. data/test/data/reaction_mapformula.lst +3 -0
  197. data/test/data/rxn/C00001.mol +6 -0
  198. data/test/data/rxn/C00011.mol +10 -0
  199. data/test/data/rxn/C00014.mol +6 -0
  200. data/test/data/rxn/C01010.mol +18 -0
  201. data/test/data/rxn/sample.rxn +50 -0
  202. data/test/data/rxn/substitution.rxn +45 -0
  203. data/test/data/test.eps +0 -0
  204. data/test/data/test.mol +28 -0
  205. data/test/data/test.sdf +143 -0
  206. data/test/data/test.skc +0 -0
  207. data/test/data/test.xyz +4 -0
  208. data/test/data/test_lf.sdf +143 -0
  209. data/test/heavy_test_pubchem.rb +16 -0
  210. data/test/multiple_test.rb +22 -0
  211. data/test/test_adj.rb +54 -0
  212. data/test/test_canonical_smiles.rb +46 -0
  213. data/test/test_cdx.rb +32 -0
  214. data/test/test_chem.rb +18 -0
  215. data/test/test_cluster.rb +19 -0
  216. data/test/test_db.rb +11 -0
  217. data/test/test_eps.rb +24 -0
  218. data/test/test_geometry.rb +11 -0
  219. data/test/test_gspan.rb +28 -0
  220. data/test/test_iupac.rb +36 -0
  221. data/test/test_kcf.rb +24 -0
  222. data/test/test_kcf_glycan.rb +10 -0
  223. data/test/test_kegg.rb +118 -0
  224. data/test/test_linucs.rb +21 -0
  225. data/test/test_mdl.rb +45 -0
  226. data/test/test_mol2.rb +62 -0
  227. data/test/test_morgan.rb +21 -0
  228. data/test/test_pdf.rb +12 -0
  229. data/test/test_prop.rb +86 -0
  230. data/test/test_rmagick.rb +15 -0
  231. data/test/test_sbdb.rb +23 -0
  232. data/test/test_sdf.rb +30 -0
  233. data/test/test_smiles.rb +84 -0
  234. data/test/test_sssr.rb +18 -0
  235. data/test/test_sub.rb +47 -0
  236. data/test/test_subcomp.rb +37 -0
  237. data/test/test_traverse.rb +29 -0
  238. data/test/test_writer.rb +13 -0
  239. data/test/test_xyz.rb +15 -0
  240. data/test/type_test.rb +25 -0
  241. metadata +290 -0
@@ -0,0 +1,164 @@
1
+ # Encapsulated Postscript writer.
2
+
3
+ module Chem
4
+
5
+ module Molecule
6
+
7
+ EpsHeader = "%%!PS-Adobe-3.0 EPSF-3.0\n" +
8
+ "%%Creator: ChemRuby n.tanaka\n" +
9
+ "%%For: Scientists\n" +
10
+ "%%Title: Molecular compound\n" +
11
+ "%%CreationDate: %d/%d/%d %d:%d \n"
12
+
13
+ def to_eps(para = EpsParameter.new)
14
+ # What should I do to ensure 2D features?
15
+
16
+ str = ''
17
+ if block_given?
18
+ yield para
19
+ end
20
+
21
+ ratio, min = para.calc_bounding_box_size(@nodes)
22
+
23
+ str = header(para)
24
+
25
+ pos = {}
26
+
27
+ @nodes.each do |atom|
28
+ pos[atom] = Vector[atom.x, atom.y]
29
+ pos[atom] -= min
30
+
31
+ #diff = diff == 0 ? 1 : diff
32
+ pos[atom] *= para.diff * 100
33
+ pos[atom] += para.orig_pt + Vector[para.margin, para.margin] + ratio * 0.5
34
+
35
+ # if para.has_atom_yield
36
+ # str += eps.atom_yield.call(atom)
37
+ # end
38
+ # str += atom.eps_header if atom.eps_header
39
+ # if(atom.visible)
40
+ str += "%5f %5f moveto\n" % [pos[atom][0], pos[atom][1]]
41
+ str += "(" + atom.element.to_s + ") dup stringwidth pop 2 div neg -1.5 rmoveto show\n"
42
+
43
+ # end
44
+ # str += atom.eps_footer if atom.eps_footer
45
+ end
46
+ # @nodes.each do ||
47
+
48
+ @edges.each do |bond, atom1, atom2|
49
+ #str += bond.eps_header if bond.eps_header
50
+ beginX = pos[atom1][0]
51
+ beginY = pos[atom1][1]
52
+ endX = pos[atom2][0]
53
+ endY = pos[atom2][1]
54
+ dx = (endX - beginX) / ((endX - beginX)**2 + (endY - beginY)**2)**0.5
55
+ dx = dx.nan? ? 0 : dx / 2.0
56
+ dy = (endY - beginY) / ((endX - beginX)**2 + (endY - beginY)**2)**0.5
57
+ dy = dy.nan? ? 0 : dy / 2.0
58
+ if(atom2.visible)
59
+ endX = endX - char_height * dx
60
+ endY = endY - char_height * dy
61
+ end
62
+ if(atom1.visible)
63
+ beginX = beginX + char_size * dx
64
+ beginY = beginY + char_size * dy
65
+ end
66
+ transition = bond.respond_to?('i') ? bond.i : 0
67
+ multi_bond_ratio = 1.0
68
+ beginX = beginX - dy * (bond.v - 1 + transition.abs) * multi_bond_ratio
69
+ beginY = beginY + dx * (bond.v - 1 + transition.abs) * multi_bond_ratio
70
+ endX = endX - dy * (bond.v - 1 + transition.abs) * multi_bond_ratio
71
+ endY = endY + dx * (bond.v - 1 + transition.abs) * multi_bond_ratio
72
+ valence = bond.v
73
+ # 1.upto(bond.v + transition.abs) do |n|
74
+ (bond.v + transition.abs).times do |n|
75
+ # if(color)
76
+ # if(transition < 0)
77
+ # str += "1 0 0 setrgbcolor\n"
78
+ # elsif(transition > 0)
79
+ # str += "0 0 1 setrgbcolor\n"
80
+ # else
81
+ # str += "0 0 0 setrgbcolor\n"
82
+ # end
83
+ # end
84
+ str += "newpath %f %f moveto %f %f lineto stroke\n" % [beginX, beginY, endX, endY]
85
+ centerX = (endX + beginX) /2
86
+ centerY = (endY + beginY) /2
87
+ if(transition >0)
88
+ str += centerX.to_s + " " + centerY.to_s + " " + inbond.to_s + " 0 360 arc stroke\n"
89
+ elsif(transition <0)
90
+ str += "newpath %f %f moveto %f %f lineto stroke\n" %
91
+ [centerX + dy - dx*outbond, centerY - dx - outbond * dy,
92
+ centerX - dy - outbond * dx, dx - outbond * dy + centerY]
93
+ str += "newpath %f %f moveto %f %f lineto stroke\n" %
94
+ [centerX + dy + dx*outbond, centerY - dx + outbond * dy,
95
+ centerX - dy + outbond * dx, dy * outbond + dx + centerY]
96
+ end
97
+ transition = transition + 1 if(transition < 0)
98
+ transition = transition - 1 if(transition > 0)
99
+ valence = valence - 1
100
+ beginX = beginX + dy * multi_bond_ratio * 2
101
+ beginY = beginY - dx * multi_bond_ratio * 2
102
+ endX = endX + dy * multi_bond_ratio * 2
103
+ endY = endY - dx * multi_bond_ratio * 2
104
+ end
105
+ end
106
+ # str += "0 0 0 setrgbcolor\n"
107
+ # str += " #{@size / 2.0} #{@size / 2.0} #{@size / 2.0 + @margin} 0 360 arc stroke\n"
108
+
109
+ #open("test.eps", "w").puts str
110
+ str
111
+ end
112
+
113
+ private
114
+ def header para
115
+ now = Time.new
116
+ str = EpsHeader % [now.day, now.month, now.year, now.hour, now.min]
117
+ # str += "%%%%BoundingBox: %d %d %d %d\n" % [@orig_pt[0], @orig_pt[1], @orig_pt[0] + @width, @orig_pt[1] + @height]
118
+ str += "/Arial findfont 5 scalefont setfont\n"
119
+ # str += "#{@line_width} setlinewidth\n"
120
+ str
121
+ end
122
+
123
+ class EpsParameter
124
+ attr_accessor :width, :height, :min, :x_max, :y_max, :fit_box, :diff, :orig_pt,:margin
125
+
126
+ def initialize
127
+ @size = Vector[100.0, 100.0]
128
+ @diff = 1.0
129
+ @orig_pt = Vector[0.0, 0.0]
130
+ @margin = 10.0
131
+ end
132
+
133
+ def calc_bounding_box_size nodes
134
+ # Shocking code :P
135
+ min = Vector[ 1.0 / 0, 1.0 / 0]
136
+ max = Vector[-1.0 / 0, -1.0 / 0]
137
+ nodes.each do |atom|
138
+ min[0] = min[0] > atom.x ? atom.x : min[0]
139
+ max[0] = max[0] < atom.x ? atom.x : max[0]
140
+ min[1] = min[1] > atom.y ? atom.y : min[1]
141
+ max[1] = max[1] < atom.y ? atom.y : max[1]
142
+ end
143
+
144
+ diff = 1.0
145
+
146
+ ratio = Vector[1.0, 1.0]
147
+
148
+ if @fit_box
149
+ if ((max[0] - min[0]) / (max[1] - min[1])) >
150
+ (@size[0] - @margin * 2)/ (@size[1] - @margin * 2)
151
+ diff = (@size[0] - @margin * 2) / (max[0] - min[0])
152
+ ratio[1] = @size[1] - @margin * 2 - (max[1] - min[1]) * diff
153
+ else
154
+ diff = (@size[1] - @margin * 2) / (max[1] - min[1])
155
+ ratio[0] = @size[0] - @margin * 2 - (max[0] - min[1]) * diff
156
+ end
157
+ end
158
+ [ratio, min]
159
+ end
160
+
161
+ end
162
+
163
+ end
164
+ end
@@ -0,0 +1,909 @@
1
+ # Gaussian98 parser
2
+
3
+ module Chem
4
+
5
+ module G98
6
+
7
+ class Lines
8
+ def initialize lines_array
9
+ @lines = lines_array
10
+ @line_ptr = 0
11
+ end
12
+ def next_line
13
+ @lines[@line_ptr + 1]
14
+ end
15
+ def proceed num = 1
16
+ @line_ptr = @line_ptr + num
17
+ raise if @line_ptr > @lines.length
18
+ end
19
+ def now
20
+ @lines[@line_ptr]
21
+ end
22
+ def eof?
23
+ @lines.length == @line_ptr
24
+ end
25
+ end
26
+
27
+ class Link
28
+ attr_accessor :next_link, :jump_link, :stop
29
+ attr_reader :major_number, :minor_number, :parameters, :default_link, :goto
30
+ def initialize major, minor, parameters, goto, gr
31
+ @major_number = major
32
+ @minor_number = minor
33
+ @parameters = parameters
34
+ @goto = goto
35
+ @gaussian_result = gr
36
+ end
37
+ def default_link=(l)
38
+ @default_link = l
39
+ @next_link = l
40
+ end
41
+ def to_s
42
+ sprintf("%2d%02d %2s ", @major_number, @minor_number, @goto.to_s) + parameter_to_s
43
+ end
44
+ def parameter_to_s
45
+ s = ''
46
+ @parameters.each do |key, value|
47
+ s = s + key.to_s + '(' + value.to_s + ') '
48
+ end
49
+ return s
50
+ end
51
+ def process lines
52
+ case (@major_number * 100 + @minor_number)
53
+ when 101 # Initializes program and controls overlaying
54
+ lines.proceed 3
55
+ n_atoms = 0
56
+ @gaussian_result.atoms = atoms = Hash.new
57
+ if lines.next_line.split.length < 2 # Z-Matrix
58
+ @gaussian_result.has_z_matrix_coordinate = true
59
+ var = Hash.new
60
+ atoms_tmp = Array.new
61
+ while /^ \w+/ =~ lines.next_line
62
+ lines.proceed
63
+ atoms_tmp.push lines.now
64
+ n_atoms = n_atoms + 1 if lines.now.split[0] != 'X'
65
+ end
66
+ lines.proceed
67
+ if /Variables:/ =~ lines.now
68
+ lines.proceed
69
+ while /^ \w+/ =~ lines.now
70
+ sp = lines.now.split
71
+ var[sp[0]] = sp[1].to_f
72
+ lines.proceed
73
+ end
74
+ end
75
+ n = 1
76
+ atoms_tmp.each do |atom_line|
77
+ atom = G98Atom.new n_atoms, @gaussian_result
78
+ atom_array = atom_line.split
79
+ atom.element = atom_array[0]
80
+ if atom_array.length >= 2
81
+ if /\d/ !~ atom_array[2]
82
+ length = var[atom_array[2]]
83
+ else
84
+ length = atom_array[2].to_f
85
+ end
86
+ atom.distance(atoms[atom_array[1].to_i], length)
87
+ end
88
+ if atom_array.length >= 4
89
+ if /\d/ !~ atom_array[4]
90
+ angle = var[atom_array[4]]
91
+ else
92
+ angle = atom_array[4].to_f
93
+ end
94
+ atom.angle(atoms[atom_array[3].to_i], angle)
95
+ end
96
+ if atom_array.length >= 7
97
+ if /\d/ !~ atom_array[6]
98
+ angle_a = var[atom_array[6]]
99
+ else
100
+ angle_a = atom_array[6].to_f
101
+ end
102
+ if /\d/ !~ atom_array[7]
103
+ angle_b = var[atom_array[7]]
104
+ else
105
+ angle_b = atom_array[7].to_f
106
+ end
107
+ atom.dihedral(atoms[atom_array[5].to_i], angle_a, angle_b)
108
+ end
109
+ atoms[n] = atom
110
+ n = n + 1
111
+ end
112
+ else # Cartessian Matrix
113
+ @gaussian_result.has_cartessian_coordinate = true
114
+ while /^ \w+/ =~ lines.next_line && / The following ModRedundant/ !~ lines.next_line
115
+ lines.proceed
116
+ atom_array = lines.now.split
117
+ atom = G98Atom.new n_atoms + 1, @gaussian_result
118
+ atom.element, atom.x, atom.y, atom.z = atom_array
119
+ atoms[n_atoms + 1] = atom
120
+ n_atoms = n_atoms + 1 if lines.now.split[0] != 'X'
121
+ end
122
+ end
123
+ @gaussian_result.n_atoms = n_atoms
124
+ @gaussian_result.atoms = atoms
125
+ lines.proceed
126
+ # @stop = true
127
+ when 103 # Berny optimization to minima and TS, STQN transition state searches
128
+ @next_link = @jump_link if @jump_link
129
+ lines.proceed 2
130
+ while /GradGradGrad/ !~ lines.now
131
+ if(/ Optimization completed./ =~ lines.now)
132
+ # if(/ Predicted change in Energy=/ =~ lines.now && / Optimization completed./ =~ lines.next_line)
133
+ @next_link = @default_link
134
+ end
135
+ lines.proceed
136
+ end
137
+ # lines.proceed 2
138
+ # lines.proceed while / Predicted change in Energy=/ !~ lines.now
139
+ # puts lines.now
140
+ # is_loop = true if / Optimization completed./ =~ lines.now
141
+ # # lines.proceed while /^ Predicted change in Energy=/ !~ lines.now
142
+ # # lines.proceed
143
+ # # is_loop = true if / Optimization completed./ =~ lines.now
144
+ # lines.proceed while /GradGradGrad/ !~ lines.now
145
+ lines.proceed
146
+ when 105 # MS optimization
147
+ when 106 # Numerical differentiation of forces/dipoles to obtain polarizability/hyperpolarizability
148
+ when 107 # Linear-synchronous-transit (LST) transition state search
149
+ when 108 # Potential energy surface scan
150
+ when 109 # Newton-Raphson optimization
151
+ when 110 # Double numerical differentiation of energies to produce frequencies
152
+ when 111 # Double num. diff. of energies to compute polarizabilities & hyperpolarizabilities
153
+ when 113 # EF optimization using analytic gradients
154
+ when 114 # EF numerical optimization (using only energies)
155
+ when 115 # Follows reaction path using the intrinsic reaction coordinate (IRC)
156
+ when 116 # Numerical self-consistent reaction field (SCRF)
157
+ when 117 # Post-SCF SCRF
158
+ when 118 # Trajectory calculations
159
+ when 120 # Controls ONIOM calculations
160
+ when 202 # Reorients coordinates, calculates symmetry, and checks variable
161
+ # IOp(15) : Symmetry control.
162
+ # 1: Unconditionally turn symmetry off. Note that Symm is still called, and will determine the
163
+ # framework group. However, the molecule is not oriented.
164
+ while / Stoichiometry/ !~ lines.now && /Error/ !~ lines.now
165
+ lines.proceed
166
+ end
167
+ if /Error/ =~ lines.now
168
+ lines.proceed 6
169
+ return
170
+ end
171
+ @gaussian_result.stoichiometry = lines.now.split[1]
172
+ lines.proceed
173
+ @gaussian_result.symmetricity = lines.now.split[2]
174
+ if /KH/ !~ @gaussian_result.symmetricity
175
+ unless @parameters.has_key?(15) && @parameters[15] == 1
176
+ lines.proceed while /Standard orientation:/ !~ lines.now
177
+ lines.proceed 5
178
+ 1.upto @gaussian_result.n_atoms do |num|
179
+ o_array = lines.now.split
180
+ @gaussian_result.atoms[o_array[0].to_i].x = o_array[3].to_f
181
+ @gaussian_result.atoms[o_array[0].to_i].y = o_array[4].to_f
182
+ @gaussian_result.atoms[o_array[0].to_i].z = o_array[5].to_f
183
+ lines.proceed
184
+ end
185
+ lines.proceed
186
+ end
187
+ while(/^ Isotopes:/ !~ lines.now)
188
+ lines.proceed
189
+ end
190
+ while /-$/ =~ lines.now || /,\D+-\d/ =~ lines.next_line
191
+ lines.proceed
192
+ end
193
+ lines.proceed
194
+ else
195
+ lines.proceed 3
196
+ end
197
+ when 301 # Generate basis set information
198
+ @gaussian_result.standard_basis = lines.now.split(':')[1].chop # Standard basis: VSTO-3G (5D, 7F)
199
+ lines.proceed
200
+ if / Basis set in the form of general basis input:/ =~ lines.now # with GFINPUT Keyword (24=10)
201
+ while /^$/ !~ lines.next_line
202
+ lines.proceed # 1 0
203
+ end
204
+ lines.proceed 2#^$
205
+ end
206
+ while / There are/ =~ lines.now
207
+ lines.proceed
208
+ end
209
+ lines.proceed while /\d+ basis functions/ !~ lines.now
210
+ @gaussian_result.n_orbitals = lines.now.split[0].to_i
211
+ lines.proceed
212
+ @gaussian_result.n_electron = lines.now.split[0].to_i
213
+ lines.proceed
214
+ @gaussian_result.nuclear_repulsion_energy = lines.now.split[3].to_f
215
+ lines.proceed
216
+ when 302 # Calculates overlap, kinetic, and potential integrals
217
+ lines.proceed 3 # No discrimination between 302 and 303. More Gaussian results needed!
218
+ when 303 # Calculates multipole integrals
219
+ ;
220
+ when 308 # Computes dipole velocity and RxD integrals
221
+ when 309 # Computes ECP integrals
222
+ when 310 # Computes spdf 2-electron integrals in a primitive fashion
223
+ when 311 # Computes sp 2-electron integrals
224
+ when 314 # Computes spdf 2-electron integrals
225
+ when 316 # Prints 2-electron integrals
226
+ when 319 # Computes 1-electron integrals for approximate spin orbital coupling
227
+ when 401 # Forms the initial MO guess
228
+ @gaussian_result.guess = lines.now.chop if @gaussian_result.guess == nil# Projected INDO Guess.
229
+ lines.proceed
230
+ if / Initial guess orbital symmetries:/ =~ lines.now
231
+ lines.proceed 2
232
+ while /\(A.\)/ =~ lines.now
233
+ lines.proceed
234
+ end
235
+ end
236
+ when 402 # Performs semi-empirical and molecular mechanics calculations
237
+ while / Dipole moment=/ !~ lines.now
238
+ lines.proceed
239
+ end
240
+ lines.now.split[4].to_f# Assertive Programming
241
+ lines.proceed
242
+ when 405 # Initializes an MCSCF calculation
243
+ when 502 # Iteratively solves the SCF equations (conven. UHF & ROHF, all direct methods, SCRF)
244
+ lines.proceed while / SCF Done:/ !~ lines.now
245
+ @gaussian_result.energy = lines.now.split[4].to_f
246
+ lines.proceed
247
+ lines.now.split[5].to_f
248
+ lines.proceed 2
249
+ # lines.proceed if / Axes restored/ =~ lines.now
250
+ if / Annihilation of the first spin contaminant:/ =~ lines.now
251
+ lines.proceed 2
252
+ end
253
+ if / Final SCRF E-Field is:/ =~ lines.now
254
+ lines.proceed 15
255
+ end
256
+ if /---------/ =~ lines.now && /DeltaG/ =~ lines.next_line
257
+ # if /---------/ =~ lines.now
258
+ while /DeltaG/ !~ lines.now
259
+ lines.proceed
260
+ end
261
+ @gaussian_result.scrf_delta_g = lines.now.split[4].to_f
262
+ lines.proceed 2
263
+ end
264
+ # lines.proceed
265
+ when 503 # Iteratively solves the SCF equations using direct minimization
266
+ when 506 # Performs an ROHF or GVB-PP calculation
267
+ when 508 # Quadratically convergent SCF program
268
+ when 510 # MC-SCF
269
+ when 601 # Population and related analyses (including multipole moments)
270
+ # puts 'l601 : '+ lines.now
271
+ # lines.proceed
272
+ # puts 'l601 : '+ lines.now
273
+ # lines.proceed
274
+ # puts 'l601 : '+ lines.now
275
+ # lines.proceed
276
+ # puts 'l601 : '+ lines.now
277
+ # lines.proceed 4
278
+ lines.proceed 7
279
+ if / Orbital Symmetries:/ =~ lines.now
280
+ lines.proceed while / electronic state/ !~ lines.now
281
+ lines.proceed
282
+ end
283
+ lines.proceed while / Alpha / =~ lines.now || / Beta / =~ lines.now
284
+ if / Molecular Orbital Coefficients/ =~ lines.now
285
+ if(@parameters.has_key?(7))# Population = Full
286
+ n = @gaussian_result.n_orbitals / 5.0
287
+ n_orbital_col = n.ceil
288
+ else
289
+ n_orbital_col = 2
290
+ end
291
+ lines.proceed # Molecular Orbital Coefficients
292
+ last_occupy_or_virtual = ''
293
+ 1.upto(n_orbital_col) do |cycle|
294
+ lines.proceed # 1 2 3 4 5
295
+ mo_array = lines.now.split
296
+ 0.upto( mo_array.length - 1 ) do |n_mo|
297
+ /\((.+)\)/ =~ mo_array[n_mo] ; sym = $+
298
+ /\)--(.)/ =~ mo_array[n_mo]
299
+ occupy_or_virtual = ($+ != nil ? $+ : mo_array[n_mo])
300
+ @gaussian_result.mo[(cycle - 1) * 5 + n_mo] =
301
+ MolecularOrbital.new(((cycle - 1) * 5 + n_mo), sym, occupy_or_virtual)
302
+ if last_occupy_or_virtual == 'O' && occupy_or_virtual == 'V'
303
+ @gaussian_result.homo = @gaussian_result.mo[(cycle - 1) * 5 + n_mo - 1]
304
+ @gaussian_result.lumo = @gaussian_result.mo[(cycle - 1) * 5 + n_mo]
305
+ elsif(@gaussian_result.homo == nil && n_orbital_col == cycle && mo_array.length - 1 == n_mo)
306
+ # No LUMO ! Example Br-
307
+ @gaussian_result.homo = @gaussian_result.mo[(cycle - 1) * 5 + n_mo - 1]
308
+ @gaussian_result.lumo = nil
309
+ end
310
+ last_occupy_or_virtual = occupy_or_virtual
311
+ end
312
+ lines.proceed
313
+ ev_array = lines.now.split
314
+ 0.upto (ev_array.length - 3) do |n_ev|
315
+ @gaussian_result.mo[(cycle - 1) * 5 + n_ev].eigen_value = ev_array[n_ev + 2].to_f
316
+ end
317
+ lines.proceed
318
+ 1.upto(@gaussian_result.n_orbitals) do | num |
319
+ coef_array = [lines.now[0..3].strip, lines.now[5..8].strip, lines.now[9..10].strip,
320
+ lines.now[11..21].strip]
321
+ 0.upto (mo_array.length - 1) do |n_mo|
322
+ coef_array << lines.now[(21 + n_mo*10)..(31 + n_mo*10)]
323
+ end
324
+ plus = 0
325
+ # if /^[[:alpha:]]+/ =~ coef_array[2]
326
+ if coef_array[1] != ''
327
+ atom = @gaussian_result.atoms[coef_array[1].to_i]
328
+ end
329
+ 1.upto( mo_array.length ) do |n_ao|
330
+ atom.ao(coef_array[3]).push(coef_array[n_ao + 2].to_i)
331
+ @gaussian_result.mo[(cycle - 1) * 5 + n_ao - 1].push([atom.index, coef_array[3]], coef_array[3 + n_ao].to_f)
332
+ # @gaussian_result.mo[(cycle - 1) * 5 + n_ao].push(coef_array[n_ao + plus + 2].to_f)
333
+ end
334
+ lines.proceed
335
+ end
336
+ end
337
+ lines.proceed # DENSITY MATRIX.
338
+ density_time = @gaussian_result.n_orbitals
339
+ while(density_time >0)
340
+ lines.proceed # 1 2 3 4 5
341
+ lines.proceed density_time
342
+ density_time = density_time - 5
343
+ end
344
+ lines.proceed # Full Mulliken population analysis:
345
+ mulliken_time = @gaussian_result.n_orbitals
346
+ while(mulliken_time > 0)
347
+ lines.proceed # 1 2 3 4 5
348
+ lines.proceed mulliken_time
349
+ mulliken_time = mulliken_time - 5
350
+ end
351
+ lines.proceed # Gross orbital populations:
352
+ 1.upto(@gaussian_result.n_orbitals) do |num|
353
+ lines.proceed
354
+ end
355
+ lines.proceed # Condensed to atoms (all electrons):
356
+ end
357
+ n = (@gaussian_result.n_atoms) / 6.0
358
+ if /Condensed to / =~ lines.now
359
+ lines.proceed
360
+ if / 1/ =~ lines.now # BUG of Gaussian98 !?
361
+ 1.upto(n.ceil) do |num|
362
+ @gaussian_result.exist_condensed_to_atom = true
363
+ lines.proceed
364
+ 1.upto(@gaussian_result.n_atoms) do |nn|
365
+ array = lines.now.split
366
+ 1.upto(array.length - 2) do |col|
367
+ @gaussian_result.atoms[array[0].to_i].density[(num - 1)* 6 + col] = array[col + 1].to_f
368
+ end
369
+ lines.proceed
370
+ end
371
+ end
372
+ end
373
+ end
374
+ lines.proceed 2
375
+ 1.upto(@gaussian_result.n_atoms) do | num |
376
+ @gaussian_result.atoms[lines.now.split[0].to_i].total_atomic_charge = lines.now.split[2].to_f
377
+ lines.proceed
378
+ end
379
+ @gaussian_result.sum_of_mulliken_charge = lines.now.split[4].to_f
380
+ lines.proceed
381
+ lines.proceed # Atomic charges with hydrogens summed into heavy atoms:
382
+ lines.proceed # 1
383
+ 1.upto(@gaussian_result.n_atoms) do |num|
384
+ @gaussian_result.atoms[lines.now.split[0].to_i].heavy_charge = lines.now.split[2].to_f
385
+ lines.proceed
386
+ end
387
+ lines.proceed
388
+ if /Atomic-Atomic Spin Densities./ =~ lines.now
389
+ lines.proceed
390
+ n = @gaussian_result.n_atoms / 6.0
391
+ 1.upto n.ceil do |num|
392
+ lines.proceed @gaussian_result.n_atoms
393
+ end
394
+ lines.proceed
395
+ lines.proceed # Total atomic spin densities:
396
+ lines.proceed # 1
397
+ lines.proceed @gaussian_result.n_atoms
398
+ lines.proceed
399
+ if /Isotropic Fermi / =~ lines.now
400
+ lines.proceed
401
+ 1.upto(@gaussian_result.n_atoms) do |num|
402
+ lines.proceed
403
+ end
404
+ end
405
+ lines.proceed
406
+ end
407
+ # if(@parameters.has_key?(7) && (@parameters[7] == 3 || @parameters[7] == 2))
408
+ if/ Electronic spatial extent/ =~ lines.now
409
+ # if(@parameters.has_key?(28))
410
+ @gaussian_result.electronic_spatial_extent = lines.now.split[5].to_f
411
+ lines.proceed 3
412
+ @gaussian_result.dipole_moment_total = lines.now.split[7].to_f
413
+ lines.proceed while / N-N=/ !~ lines.now
414
+ lines.proceed
415
+ if / Symmetry/ =~ lines.now
416
+ lines.proceed while / Symmetry/ =~ lines.now
417
+ end
418
+ end
419
+ if /Exact polarizability/ =~ lines.now
420
+ lines.now.split[7].to_f #Assertive programming ;)
421
+ lines.proceed while /Thermochemistry/ != lines.now
422
+ lines.proceed while / TOTAL BOT/ !~ lines.now
423
+ lines.proceed while / ROTATIONAL/ !~ lines.now
424
+ lines.proceed
425
+ end
426
+ # @stop = true
427
+ when 602 # 1-electron properties (potential, field, and field gradient)
428
+ when 604 # Evaluates MOs or density over a grid of points
429
+ lines.proceed while / LenV=/ !~ lines.now
430
+ when 607 # Performs NBO analyses
431
+ when 608 # Non-iterative DFT energies
432
+ when 609 # Atoms in Molecules properties
433
+ when 701 # 1-electron integral first or second derivatives
434
+ lines.proceed if /solvent charges in/ =~ lines.now
435
+ when 702 # 2-electron integral first or second derivatives (sp)
436
+ lines.proceed if /Density matrix is not symmetric/ =~ lines.now
437
+ when 703 # 2-electron integral first or second derivatives (spdf)
438
+ when 709 # Forms the ECP integral derivative contribution to gradients
439
+ when 716 # Processes information for optimizations and frequencies
440
+ # ***** Axes restored to original set *****
441
+ lines.proceed if /Axes restored/ =~ lines.now
442
+ if /Rotating electric field/ =~ lines.now
443
+ lines.proceed while /Axes restored/ !~ lines.now
444
+ lines.proceed
445
+ end
446
+ lines.proceed # -------------------------------------------------------------------
447
+ lines.proceed # Center Atomic Forces (Hartrees/Bohr)
448
+ lines.proceed # Number Number X Y Z
449
+ lines.proceed # -------------------------------------------------------------------
450
+ 1.upto(@gaussian_result.n_atoms) do |num|
451
+ lines.now.split[4].to_f #Assertive Programming ;)
452
+ lines.proceed
453
+ end
454
+ lines.proceed # -------------------------------------------------------------------
455
+ lines.proceed # Cartesian Forces: Max 2.919256220 RMS 1.058248881
456
+ when 801 # Initializes transformation of 2-electron integrals
457
+ lines.proceed 2
458
+ when 802 # Performs integral transformation (N3 in-core)
459
+ when 803 # Complete basis set (CBS) extrapolation
460
+ when 804 # Integral transformation
461
+ # if /^$/ =~ lines.now
462
+ # lines.proceed 3 # **** Warning!!: The largest alpha MO coefficient is 0.39613240D+02
463
+ # else
464
+ # lines.proceed # Estimate disk for full transformation 8758468 words.
465
+ # end
466
+ while !(/ANorm/ =~ lines.now && /^ E2=/ =~ lines.next_line)
467
+ lines.proceed
468
+ end
469
+ lines.proceed 2
470
+ when 811 # Transforms integral derivatives & computes their contributions to MP2 2nd derivatives
471
+ lines.proceed # Form MO integral derivatives with frozen-active canonical formalism.
472
+ lines.proceed # MDV= 6291456.
473
+ lines.proceed # Discarding MO integrals.
474
+ lines.proceed # Reordered first order wavefunction length = 176418
475
+ lines.proceed if /In DefCFB/ =~ lines.now
476
+ lines.proceed if /Large arrays: / =~ lines.now
477
+ when 901 # Anti-symmetrizes 2-electron integrals
478
+ when 902 # Determines the stability of the Hartree-Fock wavefunction
479
+ when 903 # Old in-core MP2
480
+ when 905 # Complex MP2
481
+ when 906 # Semi-direct MP2
482
+ # puts 'l906 : ' + lines.now
483
+ # lines.proceed 12
484
+ lines.proceed while / E2 =/ !~ lines.now
485
+ lines.proceed
486
+ when 908 # OVGF (closed shell)
487
+ when 909 # OVGF (open shell)
488
+ when 913 # Calculates post-SCF energies and gradient terms
489
+ while /^ QCISD\(T\)=/ !~ lines.now
490
+ lines.proceed
491
+ end
492
+ lines.proceed 1
493
+ when 914 # CI-Single, RPA and Zindo excited states; SCF stability
494
+ lines.proceed while / state/ !~ lines.now
495
+ lines.proceed
496
+ n_state = 0
497
+ while / Ground to excited state/ !~ lines.now
498
+ n_state = n_state + 1
499
+ lines.proceed
500
+ end
501
+ while / Excitation energies and oscillator strengths:/ !~ lines.now
502
+ lines.proceed
503
+ end
504
+ 1.upto n_state do |num|
505
+ lines.proceed while / Excited State / !~ lines.now
506
+ lines.proceed
507
+ lines.proceed while /\d+ ->/ =~ lines.now
508
+ end
509
+ when 915 # Computes fifth order quantities (for MP5, QCISD (TQ) and BD (TQ))
510
+ when 918 # Reoptimizes the wavefunction
511
+ when 1002 # Iteratively solves the CPHF equations; computes various properteis
512
+ # lines.proceed while /degrees of freedom in the / !~ lines.now
513
+ # lines.proceed # Petite list used in FoFDir.
514
+ # lines.proceed #MinBra= 0 MaxBra= 2 Meth= 1.
515
+ # lines.proceed #IRaf= 0 NMat= 1 IRICut= 1 DoRegI=T DoRafI=F ISym2E= 1 JSym2E=1.
516
+ # lines.proceed while /vectors were produced by pass/ =~ lines.now
517
+ while /Inverted reduced A of dimension/ !~ lines.now
518
+ lines.proceed
519
+ end
520
+ lines.proceed
521
+ if / Calculating GIAO nuclear magnetic shielding tensors./ =~ lines.now
522
+ 1.upto @gaussian_result.n_atoms do |num|
523
+ lines.proceed while /Eigenvalues:/ !~ lines.now
524
+ lines.proceed
525
+ end
526
+ end
527
+ # while /^$/ !~ lines.now
528
+ # lines.proceed
529
+ # end
530
+ # end
531
+ # lines.proceed
532
+ when 1003 # Iteratively solves the CP-MCSCF equations
533
+ when 1014 # Computes analytic CI-Single second derivatives
534
+ when 1101 # Computes 1-electron integral derivatives
535
+ when 1102 # Computes dipole derivative integrals
536
+ when 1110 # 2-electron integral derivative condition to F
537
+ lines.proceed if /G2DrvN: will do/ =~ lines.now
538
+ lines.proceed if /FoFDir used for/ =~ lines.now
539
+ when 1111 # 2 PDM and post-SCF derivatives
540
+ when 1112 # MP2 second derivatives
541
+ lines.proceed if /R2 and R3 integrals will be/ =~ lines.now
542
+ lines.proceed while / Incrementing Polarizabilities/ !~ lines.now
543
+ lines.proceed 2
544
+ when 9999 # Finalizes calculation and output
545
+ while !lines.eof?
546
+ if / Normal termination/ =~ lines.now
547
+ # puts ' ****** Normal termination ****** '
548
+ end
549
+ lines.proceed
550
+ end
551
+ @stop = true
552
+ else
553
+ puts 'Not implemented Link Number!!'
554
+ printf " major : %d minor : %d\n", @major_number, @minor_number,to_s
555
+ end
556
+ rescue
557
+ puts 'exception at ' + (@major_number * 100 + @minor_number).to_s
558
+ raise
559
+ end
560
+ end
561
+
562
+ class MolecularOrbital
563
+ attr_accessor :eigen_value, :index
564
+ def initialize index, sym, occupy_or_virtual
565
+ @index = index
566
+ @sym = sym
567
+ @occupy_or_virtual = occupy_or_virtual
568
+ @coefficient = Hash.new
569
+ end
570
+ def each_ao
571
+ @coefficient.each do |key, ao|
572
+ yield key, ao
573
+ end
574
+ end
575
+ def push ao, coef
576
+ @coefficient[ao] = coef
577
+ # puts index.to_s + ' : ' + @sym.to_s + ':' + ' : ' + @occupy_or_virtual + ':' + ao + ' : ' +coef.to_s + ' '
578
+ end
579
+ def to_s
580
+ s = sprintf(" %3d %s %s", @index, @sym, @occupy_or_virtual)
581
+ if @coefficient.length < 1
582
+ puts '@coefficient == 0!'
583
+ end
584
+ @coefficient.each do |key, coef|
585
+ s = s + sprintf(" %1.1f", coef)
586
+ end
587
+ s
588
+ end
589
+ end
590
+
591
+ class AtomicOrbital
592
+ def initialize type
593
+ @type = type
594
+ @coefficient = Array.new
595
+ end
596
+ def push coef
597
+ @coefficient.push coef
598
+ end
599
+ def to_s
600
+ s = sprintf("%5s ", @type)
601
+ @coefficient.each do |coef|
602
+ s = s + sprintf("%2.2f ", coef)
603
+ end
604
+ return s
605
+ end
606
+ end
607
+
608
+ class G98Atom
609
+
610
+ #include Atom
611
+
612
+ attr_accessor :element, :density,
613
+ :distance_atom, :distance_length, :angle_atom, :angle, :dihedral_angle_atom, :diheral_angle_a, :dihedral_angle_b,
614
+ :x, :y, :z, :total_atomic_charge, :heavy_charge
615
+ attr_reader :index
616
+ VALENCY = {'C'=>4, 'N'=>3, 'H'=>1, 'F'=>1, 'CL'=>1, 'I'=>1, 'O'=>2, 'BR'=>1}
617
+ VALENCY2 = {'C'=>2, 'H'=>-1, 'O'=>0, 'F'=>-1, 'CL'=>-1, 'BR'=>-1}
618
+ WEIGHT = {'O'=>15.9999, 'BR'=>79.904, 'H'=>1.00794, 'C'=>12.001, 'F'=>18.9984032, 'CL'=>35.4527, 'N'=>14.00674}
619
+ def initialize index, molecule
620
+ @index = index
621
+ @molecule = molecule
622
+ @density = Hash.new
623
+ @orbital = Hash.new
624
+ end
625
+ def get_distance atom
626
+ Math.sqrt((@x - atom.x)*(@x - atom.x) + (@y - atom.y)*(@y - atom.y) + (@z - atom.z)*(@z - atom.z))
627
+ end
628
+ def neighbor? atom, length
629
+ return (get_distance(atom) < length)
630
+ end
631
+ def element= el
632
+ @element = el.upcase
633
+ end
634
+ def weight
635
+ puts('@element : ' + @element + 'is not defined weight!!') if WEIGHT[@element] == nil
636
+ return WEIGHT[@element]
637
+ end
638
+ def valency
639
+ puts('@element : ' + @element + 'is not defined valency!!') if VALENCY[@element] == nil
640
+ VALENCY[@element]
641
+ end
642
+ def valency2
643
+ puts('@element : ' + @element + 'is not defined valency2!!') if VALENCY2[@element] == nil
644
+ VALENCY2[@element]
645
+ end
646
+ def each_ao
647
+ @orbital.each_value do |atomic_orbital|
648
+ yield atomic_orbital
649
+ end
650
+ end
651
+ def ao hash
652
+ if @orbital[hash] == nil
653
+ return @orbital[hash] = AtomicOrbital.new(hash)
654
+ else
655
+ return @orbital[hash]
656
+ end
657
+ end
658
+ def distance atom, length
659
+ @distance_atom = atom
660
+ @distance_length = length
661
+ end
662
+ def angle atom, angle
663
+ @angle_atom = atom
664
+ @angle = angle
665
+ end
666
+ def dihedral atom, angle_a, angle_b
667
+ @dihedral_atom = atom
668
+ @dihedral_angle_a = angle_a
669
+ @dihedral_angle_b = angle_b
670
+ end
671
+ def to_s
672
+ if @molecule.has_cartessian_coordinate
673
+ return to_cartessian_coodinate
674
+ elsif @molecule.has_z_matrix
675
+ return to_z_matrix
676
+ end
677
+ end
678
+ def to_condensed_density
679
+ s = sprintf("%2s ", @element)
680
+ 1.upto @molecule.atoms.length do |num|
681
+ s = s + sprintf("% f ", @density[num].to_s)
682
+ end
683
+ return s
684
+ end
685
+ def to_cartessian_coodinate
686
+ sprintf(" %2s % f % f % f", @element, @x, @y, @z)
687
+ end
688
+ def to_mol
689
+ sprintf("%10.4f%10.4f%10.4f %-2s 0 0 0 0 0", @x, @y, @z, @element)
690
+ end
691
+ def to_xyz
692
+ sprintf("%2s% 8.3f% 8.3f% 8.3f\n", @element, @x, @y, @z)
693
+ end
694
+ def to_z_matrix
695
+ s = sprintf("%d %s ", @molecule.atoms.index(self), @element)
696
+ if @distance_atom != nil
697
+ s = s + sprintf("%2d %f ", @molecule.atoms.index(@distance_atom), @distance_length)
698
+ end
699
+ if @angle_atom != nil
700
+ s = s + sprintf("%2d %f ", @molecule.atoms.index(@angle_atom), @angle)
701
+ end
702
+ if @dihedral_atom != nil
703
+ s = s + sprintf("%2d %f %f", @molecule.atoms.index(@dihedral_atom), @dihedral_angle_a, @dihedral_angle_b)
704
+ end
705
+ return s
706
+ end
707
+ end
708
+
709
+ class GaussianResult
710
+ attr_accessor :guess, :standard_basis, :energy, :n_orbitals, :n_electron, :nuclear_repulsion_energy, :n_atoms,
711
+ :sum_of_mulliken_charge, :electronic_spatial_extent, :scrf_delta_g, :dipole_moment_total, :atoms,
712
+ :has_cartessian_coordinate, :has_z_matrix_coordinate, :exist_condensed_to_atom, :mo, :homo, :lumo,
713
+ :stoichiometry, :symmetricity
714
+ def initialize input, view=false
715
+ @mo = Hash.new
716
+ @has_cartessian_coordinate = false
717
+ @has_z_matrix_coordinate = false
718
+ @input = input
719
+ read_link
720
+ lines = Lines.new input.readlines
721
+ link = @links[0].first
722
+ puts_links if view
723
+ while ! lines.eof?
724
+ link.process lines
725
+ break if link.stop
726
+ link = link.next_link
727
+ end
728
+ # link.process lines
729
+ end
730
+ def weight
731
+ total_weight = 0
732
+ @atoms.each do |key, atom|
733
+ total_weight = total_weight + atom.weight
734
+ end
735
+ total_weight
736
+ end
737
+ def moment
738
+ total_moment_x = 0
739
+ total_moment_y = 0
740
+ total_moment_z = 0
741
+ @atoms.each do |key, atom|
742
+ total_moment_x = total_moment_x + atom.weight * atom.x * atom.x
743
+ total_moment_y = total_moment_y + atom.weight * atom.y * atom.y
744
+ total_moment_z = total_moment_z + atom.weight * atom.z * atom.z
745
+ end
746
+ return total_moment_x * total_moment_y * total_moment_z
747
+ end
748
+ def entropy_trans temperature
749
+ return 76.57 + 12.47 * Math.log10(weight) + 20.79 * Math.log10(temperature)
750
+ end
751
+ def entropy_rotate temperature, sigma
752
+ return 877.37 + 8.3144 * (Math.log10(moment) + Math.log10(temperature) - Math.log10(sigma))
753
+ end
754
+ def entropy temperature
755
+ return entropy_trans(temperature)
756
+ end
757
+ def valency
758
+ total_valency = 0
759
+ @atoms.each do |key, atom|
760
+ total_valency = total_valency + atom.valency
761
+ end
762
+ total_valency
763
+ end
764
+ def valency2
765
+ total_valency2 = 0
766
+ @atoms.each do |key, atom|
767
+ total_valency2 = total_valency2 + atom.valency2
768
+ end
769
+ total_valency2 / 2 + 1
770
+ end
771
+ def near one, distance
772
+ @atoms.each do |key, another|
773
+ puts '.'
774
+ puts ((another.x - one.x) * (another.x - one.x) +
775
+ (another.y - one.y) * (another.y - one.y) +
776
+ (another.z + one.z) * (another.z - one.z)).to_s
777
+ if ((another.x - one.x) * (another.x - one.x) +
778
+ (another.y - one.y) * (another.y - one.y) +
779
+ (another.z + one.z) * (another.z - one.z)) < distance * distance
780
+ yield another
781
+ end
782
+ end
783
+ end
784
+ def to_xyz
785
+ s = @atoms.length.to_s + "\n"
786
+ s = s + "*\n"
787
+ @atoms.each do |key, atom|
788
+ s = s + sprintf("%2s% 8.3f% 8.3f% 8.3f\n", atom.element, atom.x, atom.y, atom.z)
789
+ end
790
+ s
791
+ end
792
+ def process_link_line line, last_link
793
+ /\// =~ line
794
+ major_no = $`.to_i
795
+ /\// =~ $'
796
+ parameters = Hash.new
797
+ minor_no = $'.chop.chop.split ','
798
+ $`.split(',').each do |p|
799
+ /=/ =~ p
800
+ parameters[$`.to_i] = $'.to_i
801
+ end
802
+ goto = 0
803
+ if /\((-?\d+)/ =~ minor_no.last
804
+ minor_no[-1] = $`
805
+ goto = $+.to_i
806
+ end
807
+ stop = false
808
+ major_links = Array.new
809
+ minor_no.each do |minor|
810
+ link = Link.new(major_no, minor.to_i, parameters, goto, self)# if(major_no == 1 && minor == '1')
811
+ major_links.push link
812
+ end
813
+ major_links
814
+ end
815
+ def read_link
816
+ @links = Array.new
817
+ while(/[*]{10}/ !~ @input.readline)
818
+ ;
819
+ end
820
+ while(/[*]{10}/ !~ @input.readline)
821
+ ;
822
+ end
823
+ while /[%]/ =~ @input.readline
824
+ ;
825
+ end
826
+ @input.readline if / Will use up to/ =~ $_
827
+ @input.readline# # RHF/6-31G(d) Pop=Full Test
828
+ @input.readline# ----------------------------
829
+ while(/(--+)|( Leave Link)/ !~ @input.readline)
830
+ if /^$/ =~ $_
831
+ @input.readline
832
+ @input.readline
833
+ @input.readline
834
+ @input.readline
835
+ end
836
+ if(@links.last != nil)
837
+ last = @links.last.last
838
+ else
839
+ last = nil
840
+ end
841
+ link = process_link_line $_, last
842
+ @links.push link
843
+ # puts link
844
+ end
845
+ last_link = nil
846
+ @links.each do |link|
847
+ link.each do |minor_link|
848
+ if (last_link != nil)
849
+ last_link.default_link = minor_link
850
+ if minor_link.goto > 0
851
+ minor_link.jump_link = @links[@links.index(link) + minor_link.goto + 1].first
852
+ elsif minor_link.goto < 0
853
+ minor_link.jump_link = @links[@links.index(link) + minor_link.goto].first
854
+ end
855
+ end
856
+ last_link = minor_link
857
+ end
858
+ end
859
+ end
860
+ def include? major, minor, parameter
861
+ @links.each do | link |
862
+ link.each do |minor_link|
863
+ if parameter
864
+ if(minor_link.major_number == major &&
865
+ minor_link.minor_number == minor &&
866
+ minor_link.parameters.has_key?(parameter))
867
+ return true
868
+ end
869
+ else
870
+ if(minor_link.major_number == major && minor_link.minor_number == minor)
871
+ return true
872
+ end
873
+ end
874
+ end
875
+ end
876
+ false
877
+ end
878
+ def puts_links
879
+ @links.each do | link |
880
+ puts link
881
+ end
882
+ end
883
+ end
884
+
885
+ if __FILE__ == $0
886
+ gr = GaussianResult.new(File.open(ARGV.shift), false)
887
+ puts gr.entropy 256
888
+ valency = 0
889
+ puts 'entropy : ' + gr.entropy(276).to_s
890
+ puts 'eigen_value : ' + gr.homo.eigen_value.to_s
891
+ gr.atoms.keys.sort.each do |atom_num|
892
+ # puts gr.atoms[atom_num].to_condensed_density
893
+ # gr.atoms[atom_num].each_ao do |ao|
894
+ # puts ao
895
+ # end
896
+ end
897
+ puts '--------------- Print Out Molecular Orbitals---------------'
898
+ # gr.mo.keys.sort.each do |mo_key|
899
+ # puts gr.mo[mo_key].to_s
900
+ # end
901
+ # puts gr.homo
902
+ # puts gr.lumo
903
+ # printf "energy : %f\n", gr.energy
904
+ # puts gr.valency
905
+ # puts gr.valency2
906
+ File.open("test.xyz", "w").puts gr.to_xyz
907
+ end
908
+ end # end of G98 module
909
+ end