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