1 /**********************************************************************
2 mdlvalence.h - Implement MDL valence model.
3
4 Copyright (C) 2012 by NextMove Software
5
6 This file is part of the Open Babel project.
7 For more information, see <http://openbabel.org/>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation version 2 of the License.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17 ***********************************************************************/
18
19 /* Return the implicit MDL valence for element "elem" with charge "q". */
MDLValence(unsigned int elem,int q,unsigned int val)20 static unsigned int MDLValence(unsigned int elem, int q, unsigned int val)
21 {
22 switch (elem) {
23 case 1: // H
24 case 3: // Li
25 case 11: // Na
26 case 19: // K
27 case 37: // Rb
28 case 55: // Cs
29 case 87: // Fr
30 if (q == 0 && val <= 1)
31 return 1;
32 break;
33
34 case 4: // Be
35 case 12: // Mg
36 case 20: // Ca
37 case 38: // Sr
38 case 56: // Ba
39 case 88: // Ra
40 switch (q) {
41 case 0: if (val <= 2) return 2; break;
42 case 1: if (val <= 1) return 1; break;
43 }
44 break;
45
46 case 5: // B
47 switch (q) {
48 case -4: if (val <= 1) return 1; break;
49 case -3: if (val <= 2) return 2; break;
50 case -2: if (val <= 3) return 3;
51 if (val <= 5) return 5; break;
52 case -1: if (val <= 4) return 4; break;
53 case 0: if (val <= 3) return 3; break;
54 case 1: if (val <= 2) return 2; break;
55 case 2: if (val <= 1) return 1; break;
56 }
57 break;
58
59 case 6: // C
60 switch (q) {
61 case -3: if (val <= 1) return 1; break;
62 case -2: if (val <= 2) return 2; break;
63 case -1: if (val <= 3) return 3;
64 if (val <= 5) return 5; break;
65 case 0: if (val <= 4) return 4; break;
66 case 1: if (val <= 3) return 3; break;
67 case 2: if (val <= 2) return 2; break;
68 case 3: if (val <= 1) return 1; break;
69 }
70 break;
71
72 case 7: // N
73 switch (q) {
74 case -2: if (val <= 1) return 1; break;
75 case -1: if (val <= 2) return 2; break;
76 case 0: if (val <= 3) return 3;
77 if (val <= 5) return 5; break;
78 case 1: if (val <= 4) return 4; break;
79 case 2: if (val <= 3) return 3; break;
80 case 3: if (val <= 2) return 2; break;
81 case 4: if (val <= 1) return 1; break;
82 }
83 break;
84
85 case 8: // O
86 switch (q) {
87 case -1: if (val <= 1) return 1; break;
88 case 0: if (val <= 2) return 2; break;
89 case 1: if (val <= 3) return 3;
90 if (val <= 5) return 5; break;
91 case 2: if (val <= 4) return 4; break;
92 case 3: if (val <= 3) return 3; break;
93 case 4: if (val <= 2) return 2; break;
94 case 5: if (val <= 1) return 1; break;
95 }
96 break;
97
98 case 9: // F
99 switch (q) {
100 case 0: if (val <= 1) return 1; break;
101 case 1: if (val <= 2) return 2; break;
102 case 2: if (val <= 3) return 3;
103 if (val <= 5) return 5; break;
104 case 3: if (val <= 4) return 4; break;
105 case 4: if (val <= 3) return 3; break;
106 case 5: if (val <= 2) return 2; break;
107 case 6: if (val <= 1) return 1; break;
108 }
109 break;
110
111 case 13: // Al
112 switch (q) {
113 case -4: if (val <= 1) return 1;
114 if (val <= 3) return 3;
115 if (val <= 5) return 5;
116 if (val <= 7) return 7; break;
117 case -3: if (val <= 2) return 2;
118 if (val <= 4) return 4;
119 if (val <= 6) return 6; break;
120 case -2: if (val <= 3) return 3;
121 if (val <= 5) return 5; break;
122 case -1: if (val <= 4) return 4; break;
123 case 0: if (val <= 3) return 3; break;
124 case 1: if (val <= 2) return 2; break;
125 case 2: if (val <= 1) return 1; break;
126 }
127 break;
128
129 case 14: // Si
130 switch (q) {
131 case -3: if (val <= 1) return 1;
132 if (val <= 3) return 3;
133 if (val <= 5) return 5;
134 if (val <= 7) return 7; break;
135 case -2: if (val <= 2) return 2;
136 if (val <= 4) return 4;
137 if (val <= 6) return 6; break;
138 case -1: if (val <= 3) return 3;
139 if (val <= 5) return 5; break;
140 case 0: if (val <= 4) return 4; break;
141 case 1: if (val <= 3) return 3; break;
142 case 2: if (val <= 2) return 2; break;
143 case 3: if (val <= 1) return 1; break;
144 }
145 break;
146
147 case 15: // P
148 switch (q) {
149 case -2: if (val <= 1) return 1;
150 if (val <= 3) return 3;
151 if (val <= 5) return 5;
152 if (val <= 7) return 7; break;
153 case -1: if (val <= 2) return 2;
154 if (val <= 4) return 4;
155 if (val <= 6) return 6; break;
156 case 0: if (val <= 3) return 3;
157 if (val <= 5) return 5; break;
158 case 1: if (val <= 4) return 4; break;
159 case 2: if (val <= 3) return 3; break;
160 case 3: if (val <= 2) return 2; break;
161 case 4: if (val <= 1) return 1; break;
162 }
163 break;
164
165 case 16: // S
166 switch (q) {
167 case -1: if (val <= 1) return 1;
168 if (val <= 3) return 3;
169 if (val <= 5) return 5;
170 if (val <= 7) return 7; break;
171 case 0: if (val <= 2) return 2;
172 if (val <= 4) return 4;
173 if (val <= 6) return 6; break;
174 case 1: if (val <= 3) return 3;
175 if (val <= 5) return 5; break;
176 case 2: if (val <= 4) return 4; break;
177 case 3: if (val <= 3) return 3; break;
178 case 4: if (val <= 2) return 2; break;
179 case 5: if (val <= 1) return 1; break;
180 }
181 break;
182
183 case 17: // Cl
184 switch (q) {
185 case 0: if (val <= 1) return 1;
186 if (val <= 3) return 3;
187 if (val <= 5) return 5;
188 if (val <= 7) return 7; break;
189 case 1: if (val <= 2) return 2;
190 if (val <= 4) return 4;
191 if (val <= 6) return 6; break;
192 case 2: if (val <= 3) return 3;
193 if (val <= 5) return 5; break;
194 case 3: if (val <= 4) return 4; break;
195 case 4: if (val <= 3) return 3; break;
196 case 5: if (val <= 2) return 2; break;
197 case 6: if (val <= 1) return 1; break;
198 }
199 break;
200
201 case 31: // Ga
202 switch (q) {
203 case -4: if (val <= 1) return 1;
204 if (val <= 3) return 3;
205 if (val <= 5) return 5;
206 if (val <= 7) return 7; break;
207 case -3: if (val <= 2) return 2;
208 if (val <= 4) return 4;
209 if (val <= 6) return 6; break;
210 case -2: if (val <= 3) return 3;
211 if (val <= 5) return 5; break;
212 case -1: if (val <= 4) return 4; break;
213 case 0: if (val <= 3) return 3; break;
214 case 2: if (val <= 1) return 1; break;
215 }
216 break;
217
218 case 32: // Ge
219 switch (q) {
220 case -3: if (val <= 1) return 1;
221 if (val <= 3) return 3;
222 if (val <= 5) return 5;
223 if (val <= 7) return 7; break;
224 case -2: if (val <= 2) return 2;
225 if (val <= 4) return 4;
226 if (val <= 6) return 6; break;
227 case -1: if (val <= 3) return 3;
228 if (val <= 5) return 5; break;
229 case 0: if (val <= 4) return 4; break;
230 case 1: if (val <= 3) return 3; break;
231 case 3: if (val <= 1) return 1; break;
232 }
233 break;
234
235 case 33: // As
236 switch (q) {
237 case -2: if (val <= 1) return 1;
238 if (val <= 3) return 3;
239 if (val <= 5) return 5;
240 if (val <= 7) return 7; break;
241 case -1: if (val <= 2) return 2;
242 if (val <= 4) return 4;
243 if (val <= 6) return 6; break;
244 case 0: if (val <= 3) return 3;
245 if (val <= 5) return 5; break;
246 case 1: if (val <= 4) return 4; break;
247 case 2: if (val <= 3) return 3; break;
248 case 4: if (val <= 1) return 1; break;
249 }
250 break;
251
252 case 34: // Se
253 switch (q) {
254 case -1: if (val <= 1) return 1;
255 if (val <= 3) return 3;
256 if (val <= 5) return 5;
257 if (val <= 7) return 7; break;
258 case 0: if (val <= 2) return 2;
259 if (val <= 4) return 4;
260 if (val <= 6) return 6; break;
261 case 1: if (val <= 3) return 3;
262 if (val <= 5) return 5; break;
263 case 2: if (val <= 4) return 4; break;
264 case 3: if (val <= 3) return 3; break;
265 case 5: if (val <= 1) return 1; break;
266 }
267 break;
268
269 case 35: // Br
270 switch (q) {
271 case 0: if (val <= 1) return 1;
272 if (val <= 3) return 3;
273 if (val <= 5) return 5;
274 if (val <= 7) return 7; break;
275 case 1: if (val <= 2) return 2;
276 if (val <= 4) return 4;
277 if (val <= 6) return 6; break;
278 case 2: if (val <= 3) return 3;
279 if (val <= 5) return 5; break;
280 case 3: if (val <= 4) return 4; break;
281 case 4: if (val <= 3) return 3; break;
282 case 6: if (val <= 1) return 1; break;
283 }
284 break;
285
286 case 49: // In
287 switch (q) {
288 case -4: if (val <= 1) return 1;
289 if (val <= 3) return 3;
290 if (val <= 5) return 5;
291 if (val <= 7) return 7; break;
292 case -3: if (val <= 2) return 2;
293 if (val <= 4) return 4;
294 if (val <= 6) return 6; break;
295 case -2: if (val <= 3) return 3;
296 if (val <= 5) return 5; break;
297 case -1: if (val <= 2) return 2;
298 if (val <= 4) return 4; break;
299 case 0: if (val <= 3) return 3; break;
300 case 2: if (val <= 1) return 1; break;
301 }
302 break;
303
304 case 50: // Sn
305 case 82: // Pb
306 switch (q) {
307 case -3: if (val <= 1) return 1;
308 if (val <= 3) return 3;
309 if (val <= 5) return 5;
310 if (val <= 7) return 7; break;
311 case -2: if (val <= 2) return 2;
312 if (val <= 4) return 4;
313 if (val <= 6) return 6; break;
314 case -1: if (val <= 3) return 3;
315 if (val <= 5) return 5; break;
316 case 0: if (val <= 2) return 2;
317 if (val <= 4) return 4; break;
318 case 1: if (val <= 3) return 3; break;
319 case 3: if (val <= 1) return 1; break;
320 }
321 break;
322
323 case 51: // Sb
324 case 83: // Bi
325 switch (q) {
326 case -2: if (val <= 1) return 1;
327 if (val <= 3) return 3;
328 if (val <= 5) return 5;
329 if (val <= 7) return 7; break;
330 case -1: if (val <= 2) return 2;
331 if (val <= 4) return 4;
332 if (val <= 6) return 6; break;
333 case 0: if (val <= 3) return 3;
334 if (val <= 5) return 5; break;
335 case 1: if (val <= 2) return 2;
336 if (val <= 4) return 4; break;
337 case 2: if (val <= 3) return 3; break;
338 case 4: if (val <= 1) return 1; break;
339 }
340 break;
341
342 case 52: // Te
343 case 84: // Po
344 switch (q) {
345 case -1: if (val <= 1) return 1;
346 if (val <= 3) return 3;
347 if (val <= 5) return 5;
348 if (val <= 7) return 7; break;
349 case 0: if (val <= 2) return 2;
350 if (val <= 4) return 4;
351 if (val <= 6) return 6; break;
352 case 1: if (val <= 3) return 3;
353 if (val <= 5) return 5; break;
354 case 2: if (val <= 2) return 2;
355 if (val <= 4) return 4; break;
356 case 3: if (val <= 3) return 3; break;
357 case 5: if (val <= 1) return 1; break;
358 }
359 break;
360
361 case 53: // I
362 case 85: // At
363 switch (q) {
364 case 0: if (val <= 1) return 1;
365 if (val <= 3) return 3;
366 if (val <= 5) return 5;
367 if (val <= 7) return 7; break;
368 case 1: if (val <= 2) return 2;
369 if (val <= 4) return 4;
370 if (val <= 6) return 6; break;
371 case 2: if (val <= 3) return 3;
372 if (val <= 5) return 5; break;
373 case 3: if (val <= 2) return 2;
374 if (val <= 4) return 4; break;
375 case 4: if (val <= 3) return 3; break;
376 case 6: if (val <= 1) return 1; break;
377 }
378 break;
379
380 case 81: // Tl
381 switch (q) {
382 case -4: if (val <= 1) return 1;
383 if (val <= 3) return 3;
384 if (val <= 5) return 5;
385 if (val <= 7) return 7; break;
386 case -3: if (val <= 2) return 2;
387 if (val <= 4) return 4;
388 if (val <= 6) return 6; break;
389 case -2: if (val <= 3) return 3;
390 if (val <= 5) return 5; break;
391 case -1: if (val <= 2) return 2;
392 if (val <= 4) return 4; break;
393 case 0: if (val <= 1) return 1;
394 if (val <= 3) return 3; break;
395 }
396 break;
397
398 }
399 return val;
400 }
401
402 /* Return the implicit valence for element "elem" with charge "q" when using HYD extension */
HYDValence(unsigned int elem,int q,unsigned int val)403 static unsigned int HYDValence(unsigned int elem, int q, unsigned int val)
404 {
405 int impval = 0;
406 if (elem == 6) { // C
407 impval = 4 - abs(q);
408 } else if (elem == 7 || elem == 15) { // N or P
409 impval = 3 + q;
410 } else if (elem == 8 || elem == 16) { // O or S
411 impval = 2 + q;
412 }
413 if (impval < 0) {
414 impval = 0;
415 }
416 if (val > impval) {
417 impval = val;
418 }
419 return impval;
420 }
421
422