chemruby 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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