1 /* Copyright (C) 2000-2003 Damir Zucic */
2
3 /*=============================================================================
4
5 check_dist.c
6
7 Purpose:
8 Try to recognize the atomic pair. If pair is recognized, check
9 the distance between two atoms. If this distance fits into the
10 bond length range which corresponds to given atomic pair,
11 return positive value. Otherwise return negative value. See
12 bellow for a list of pairs this routine recognizes. This array
13 is called known_pairAA. Add more to the list, but don't forget
14 to update the array size. Changes in PDB format may require
15 the modification of this function. It is assumed that chemical
16 symbol is right justified and that exactly two characters are
17 used for representation. Pairs like " C N" and " N C" etc. are
18 treated as equivalent and thus should have equal ID's. The
19 array with pair ID's is called known_pairsIDA. Unrecognized
20 pairs are also checked, using generic bond length limits.
21
22 Input:
23 (1) Pointer to inter-atomic distance.
24 (2) Pointer to AtomS structure with data about one atom.
25 (3) Pointer to AtomS structure with data about another atom.
26 (4) Pointer to ConfigS structure, with configuration data,
27
28 Output:
29 (1) Bond length, if bond is recognized.
30 (2) Return value.
31
32 Return value:
33 (1) If atomic pair is recognized and the distance corresponds
34 to a valid bond length, atomic pair ID is returned.
35 (2) Negative if inter-atomic distance is bad.
36
37 Notes:
38 (1) The pair identifier value of zero is reserved for hydrogen
39 bonds.
40
41 ========includes:============================================================*/
42
43 #include <stdio.h>
44
45 #include <string.h>
46 #include <math.h>
47
48 #include <X11/Xlib.h>
49 #include <X11/Xutil.h>
50 #include <X11/Xos.h>
51 #include <X11/Xatom.h>
52
53 #include "defines.h"
54 #include "typedefs.h"
55
56 /*======check inter-atomic distance:=========================================*/
57
CheckDistance_(double * distanceP,AtomS * atom1SP,AtomS * atom2SP,ConfigS * configSP)58 int CheckDistance_ (double *distanceP,
59 AtomS *atom1SP, AtomS *atom2SP, ConfigS *configSP)
60 {
61 char atomic_pairA[40];
62 static char known_pairAA[KNOWNPAIRS][PAIRSIZE] =
63 {" C C", " C C", " C N", " N C", " C O", " O C",
64 " C S", " S C", " C H", " H C", " N O", " O N",
65 " N H", " H N", " O H", " H O", " S H", " H S",
66 " O P", " P O", " S S", " S S"};
67 static int known_pairIDA[KNOWNPAIRS] = {1, 1, 2, 2, 3, 3,
68 4, 4, 5, 5, 6, 6,
69 7, 7, 8, 8, 9, 9,
70 10, 10, 11, 11};
71 int pair_string_len;
72 int i;
73 int pairID;
74 double delta_x, delta_y, delta_z;
75 double distance_squared;
76
77 /* Auxiliary integer: */
78 pair_string_len = PAIRSIZE - 1;
79
80 /* Prepare the string which will contain both chemical symbols: */
81 strcpy (atomic_pairA, atom1SP->raw_atomS.chemical_symbolA);
82 strncat (atomic_pairA, atom2SP->raw_atomS.chemical_symbolA, 2);
83 atomic_pairA[pair_string_len] = '\0';
84
85 /* Hydrogen to hydrogen bond is not allowed in garlic: */
86 /* (Note: H_TO_H_BOND must be negative, see defines.h!) */
87 if (strncmp (" H H", atomic_pairA, pair_string_len) == 0) return H_TO_H_BOND;
88
89 /* Try to recognize the atomic pair: */
90 pairID = GENERICID; /* The initial value */
91
92 for (i = 0; i < KNOWNPAIRS; i++)
93 {
94 if (strncmp (known_pairAA[i], atomic_pairA, pair_string_len) == 0)
95 {
96 pairID = known_pairIDA[i];
97 break;
98 }
99 }
100
101 /* Calculate the squared distance: */
102 delta_x = atom1SP->raw_atomS.x[0] - atom2SP->raw_atomS.x[0];
103 delta_y = atom1SP->raw_atomS.y - atom2SP->raw_atomS.y;
104 delta_z = atom1SP->raw_atomS.z[0] - atom2SP->raw_atomS.z[0];
105 distance_squared = delta_x * delta_x + delta_y * delta_y + delta_z * delta_z;
106
107 /* Check the squared distance: if it doesn't fit into */
108 /* the range for a given pair, return negative value: */
109 switch (pairID)
110 {
111 /* C-C: */
112 case 1:
113 if (distance_squared > configSP->C_C_max_squared) return -1;
114 if (distance_squared < configSP->C_C_min_squared) return -2;
115 break;
116
117 /* C-N: */
118 case 2:
119 if (distance_squared > configSP->C_N_max_squared) return -3;
120 if (distance_squared < configSP->C_N_min_squared) return -4;
121 break;
122
123 /* C-O: */
124 case 3:
125 if (distance_squared > configSP->C_O_max_squared) return -5;
126 if (distance_squared < configSP->C_O_min_squared) return -6;
127 break;
128
129 /* C-S: */
130 case 4:
131 if (distance_squared > configSP->C_S_max_squared) return -7;
132 if (distance_squared < configSP->C_S_min_squared) return -8;
133 break;
134
135 /* C-H: */
136 case 5:
137 if (distance_squared > configSP->C_H_max_squared) return -9;
138 if (distance_squared < configSP->C_H_min_squared) return -10;
139 break;
140
141 /* N-O: */
142 case 6:
143 if (distance_squared > configSP->N_O_max_squared) return -11;
144 if (distance_squared < configSP->N_O_min_squared) return -12;
145
146 /* N-H: */
147 case 7:
148 if (distance_squared > configSP->N_H_max_squared) return -13;
149 if (distance_squared < configSP->N_H_min_squared) return -14;
150 break;
151
152 /* O-H: */
153 case 8:
154 if (distance_squared > configSP->O_H_max_squared) return -15;
155 if (distance_squared < configSP->O_H_min_squared) return -16;
156 break;
157
158 /* S-H: */
159 case 9:
160 if (distance_squared > configSP->S_H_max_squared) return -17;
161 if (distance_squared < configSP->S_H_min_squared) return -18;
162 break;
163
164 /* O-P: */
165 case 10:
166 if (distance_squared > configSP->O_P_max_squared) return -19;
167 if (distance_squared < configSP->O_P_min_squared) return -20;
168 break;
169
170 /* S-S (disulfide bond): */
171 case 11:
172 if (distance_squared > configSP->S_S_max_squared) return -21;
173 if (distance_squared < configSP->S_S_min_squared) return -22;
174 break;
175
176 /* If this happens, pair was not recognized: */
177 case GENERICID:
178 if (distance_squared > configSP->generic_max_squared)
179 return -23;
180 if (distance_squared < configSP->generic_min_squared)
181 return -24;
182 break;
183
184 /* The impossible option: */
185 default:
186 return -9999;
187
188 }
189
190 /* If this point is reached, the bond fits */
191 /* into the range; calculate the distance: */
192 *distanceP = sqrt (distance_squared);
193
194 /* Return pair ID on success: */
195 return pairID;
196 }
197
198 /*===========================================================================*/
199
200
201