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