1 /*****
2 This file is part of the Babel Program
3 Copyright (C) 1992-96 W. Patrick Walters and Matthew T. Stahl
4 All Rights Reserved
5 All Rights Reserved
6 All Rights Reserved
7 All Rights Reserved
8
9 For more information please contact :
10
11 babel@mercury.aichem.arizona.edu
12 --------------------------------------------------------------------------------
13 FILE : addh.c
14 AUTHOR(S) : Pat Walters
15 DATE : 5-18-93
16 PURPOSE : Routines to add hydrogen to a structure
17 Techniques based on
18 M. Nardelli
19 Computers in Chemistry
20 Vol 6., No. 3, pp 139-152, 1982
21
22 Modified 6-18-93 to include Matt's
23 routines from vectors.h
24 ******/
25
26 #include "bbltyp.h"
27
28 static warning wstr;
29
add_hydrogens(ums_type * mol)30 void add_hydrogens(ums_type *mol)
31 {
32 int old_count, num_H_to_add;
33 int result;
34
35 old_count = Atoms;
36
37 if ((Bond_order(1) == 0) || (BO(0,0) == -1))
38 {
39 num_H_to_add = count_missing_hydrogens(mol);
40 place_hydrogens1(mol,old_count,num_H_to_add);
41 }
42 else
43 {
44 num_H_to_add = count_missing_bo_hydrogens(mol);
45 place_hydrogens2(mol,old_count,num_H_to_add);
46 }
47
48 #if 0
49 if ((mol->control) && (Verbose))
50 {
51 sprintf(wstr,"the structure is missing %d hydrogens",to_add);
52 show_warning(wstr);
53 }
54 #endif
55 }
56
place_hydrogens1(ums_type * mol,int old_count,int num_H_to_add)57 void place_hydrogens1(ums_type *mol, int old_count, int num_H_to_add)
58 {
59 int h_count, result;
60 int i;
61 char temp_title[BUFF_SIZE];
62
63 Atoms += num_H_to_add;
64 h_count = old_count + 1;
65 strcpy(temp_title,Title);
66 result = reinitialize_ums(&mol);
67 zero_out_ums(mol,old_count + 1);
68 strcpy(Title,temp_title);
69
70 for (i = 1; i <= old_count; i++)
71 {
72 if EQ(Type(i),"C3")
73 switch(Valence(i))
74 {
75 case 3 :
76 add_tertiary_hydrogen(mol,i,h_count,SP3_C_H_DIST);
77 h_count += 1;
78 break;
79 case 2 :
80 add_methylene_hydrogens(mol,i,h_count,SP3_C_H_DIST);
81 h_count += 2;
82 break;
83 case 1 :
84 add_methyl_hydrogen(mol,i,h_count,SP3_C_H_DIST);
85 h_count += 1;
86 add_methylene_hydrogens(mol,i,h_count,SP3_C_H_DIST);
87 h_count += 2;
88 break;
89 }
90 else
91 if EQ(Type(i),"N3+")
92 switch(Valence(i))
93 {
94 case 2 :
95 add_methylene_hydrogens(mol,i,h_count,SP3_N_H_DIST);
96 h_count += 2;
97 break;
98 case 1 :
99 add_methyl_hydrogen(mol,i,h_count,SP3_N_H_DIST);
100 h_count += 1;
101 add_methylene_hydrogens(mol,i,h_count,SP3_N_H_DIST);
102 h_count += 2;
103 break;
104 }
105 else
106 if (EQ(Type(i),"C2") || EQ(Type(i),"Car"))
107 switch(Valence(i))
108 {
109 case 2 :
110 add_sp2_hydrogen(mol,i,h_count,SP2_C_H_DIST);
111 h_count += 1;
112 break;
113 }
114 else
115 if (EQ(Type(i),"Npl") || EQ(Type(i),"Nam") || EQ(Type(i),"Ng+"))
116 switch(Valence(i))
117 {
118 case 2 :
119 add_sp2_hydrogen(mol,i,h_count,SP2_N_H_DIST);
120 h_count += 1;
121 break;
122 }
123 else
124 if EQ(Type(i),"C1")
125 {
126 if (Valence(i) == 1)
127 {
128 add_sp_hydrogen(mol,i,h_count,SP_C_H_DIST);
129 h_count++;
130 }
131 }
132 else
133 if EQ(Type(i),"O3")
134 {
135 if (Valence(i) == 1)
136 {
137 add_methyl_hydrogen(mol,i,h_count,SP3_O_H_DIST);
138 h_count++;
139 }
140 }
141 }
142
143 for (i = 1; i <= old_count; i++)
144 {
145 if EQ(Type(i),"C2")
146 switch(Valence(i))
147 {
148 case 1 :
149 add_vinyl_hydrogens(mol,i,h_count,SP2_C_H_DIST);
150 h_count += 2;
151 break;
152 }
153 if (EQ(Type(i),"Npl") || EQ(Type(i),"Nam") || EQ(Type(i),"Ng+"))
154 switch(Valence(i))
155 {
156 case 1 :
157 add_vinyl_hydrogens(mol,i,h_count,SP2_C_H_DIST);
158 h_count += 2;
159 break;
160 }
161 }
162 Atoms = h_count - 1;
163 build_connection_table(mol);
164 }
165
add_methyl_hydrogen(ums_type * mol,int c_num,int h_num,double b_length)166 void add_methyl_hydrogen(ums_type *mol, int c_num, int h_num, double b_length)
167 {
168 int c1,c2,c3;
169 vect_type v;
170
171 c1 = c_num;
172 c2 = Connection(c1,0);
173 if (Connection(c2,0) != c1)
174 c3 = Connection(c2,0);
175 else
176 c3 = Connection(c2,1);
177
178 pts_2_vect(mol,&v,c2,c3);
179 normalize_vect(&v);
180 scal_x_vect(&v,(float) b_length);
181 Point(h_num) = point_plus_vector(&Point(c1),&v);
182
183 type_added_hydrogen(mol,c1,h_num);
184 }
185
186
add_sp_hydrogen(ums_type * mol,int c_num,int h_num,double b_length)187 void add_sp_hydrogen(ums_type *mol, int c_num, int h_num, double b_length)
188 {
189 int c1, c2;
190 vect_type v;
191
192 c1 = c_num;
193 c2 = Connection(c1,0);
194 pts_2_vect(mol,&v,c1,c2);
195 normalize_vect(&v);
196 scal_x_vect(&v,(float) b_length);
197 Point(h_num) = point_plus_vector(&Point(c1),&v);
198
199 type_added_hydrogen(mol,c1,h_num);
200 }
201
add_sp2_hydrogen(ums_type * mol,int c_num,int h_num,double b_length)202 void add_sp2_hydrogen(ums_type *mol, int c_num, int h_num, double b_length)
203 {
204 int c1, c2, c3;
205 vect_type v,v1,s;
206
207
208 c1 = c_num;
209 c2 = Connection(c1,0);
210 c3 = Connection(c1,1);
211
212 pts_2_vect(mol,&v,c1,c2);
213 normalize_vect(&v);
214 pts_2_vect(mol,&v1,c1,c3);
215 normalize_vect(&v1);
216 vect_sum(&v,&v1,&s);
217 normalize_vect(&s);
218 scal_x_vect(&s,(float) b_length);
219 Point(h_num) = point_plus_vector(&Point(c1),&s);
220
221 type_added_hydrogen(mol,c1,h_num);
222 }
223
add_vinyl_hydrogens(ums_type * mol,int c_num,int h_num,double b_length)224 void add_vinyl_hydrogens(ums_type *mol, int c_num, int h_num, double b_length)
225 {
226 int c1,c2,c3,c4;
227 int h1,h2;
228 vect_type v,v1;
229
230 h1 = h_num;
231 h2 = h1 + 1;
232
233 c1 = c_num;
234 c2 = Connection(c1,0);
235 if (Connection(c2,0) != c1)
236 c3 = Connection(c2,0);
237 else
238 c3 = Connection(c2,1);
239 if ((Connection(c2,0) != c1) && (Connection(c2,0) != c3))
240 c4 = Connection(c2,0);
241 else
242 if ((Connection(c2,1) != c1) && (Connection(c2,1) != c3))
243 c4 = Connection(c2,1);
244 else
245 c4 = Connection(c2,2);
246
247 pts_2_vect(mol,&v,c2,c3);
248 normalize_vect(&v);
249 pts_2_vect(mol,&v1,c2,c4);
250 normalize_vect(&v1);
251 scal_x_vect(&v,(float) b_length);
252 Point(h1) = point_plus_vector(&Point(c1),&v);
253 scal_x_vect(&v1,(float) b_length);
254 Point(h2) = point_plus_vector(&Point(c1),&v1);
255
256 type_added_hydrogen(mol,c1,h1);
257 type_added_hydrogen(mol,c1,h2);
258 }
259
add_sp3_N_hydrogen(ums_type * mol,int n_num,int h_num,double b_length)260 void add_sp3_N_hydrogen(ums_type *mol, int n_num, int h_num, double b_length)
261 {
262 int c1, c2, c3;
263 int h1;
264 vect_type v,v1,n,s,h1vect;
265
266 c1 = n_num;
267 c2 = Connection(c1,0);
268 c3 = Connection(c1,1);
269 h1 = h_num;
270
271 pts_2_vect(mol,&v,c1,c2);
272 normalize_vect(&v);
273 pts_2_vect(mol,&v1,c1,c3);
274 normalize_vect(&v1);
275 vect_sum(&v,&v1,&s);
276 cross_prod(&v,&v1,&n);
277 scal_x_vect(&s,(float) ONE_OVER_SQRT3);
278 scal_x_vect(&n,(float) SQRT_TWO_THIRDS);
279 vect_sum(&s,&n,&h1vect);
280 normalize_vect(&h1vect);
281 scal_x_vect(&h1vect,(float) b_length);
282 Point(h1) = point_plus_vector(&Point(c1),&h1vect);
283
284 type_added_hydrogen(mol,c1,h1);
285 }
286
add_methylene_hydrogens(ums_type * mol,int c_num,int h_num,double b_length)287 void add_methylene_hydrogens(ums_type *mol, int c_num, int h_num, double b_length)
288 {
289 int c1, c2, c3;
290 int h1, h2;
291 vect_type v,v1,n,s,h1vect,h2vect;
292
293 c1 = c_num;
294 c2 = Connection(c1,0);
295 c3 = Connection(c1,1);
296 h1 = h_num;
297 h2 = h_num+1;
298
299 pts_2_vect(mol,&v,c1,c2);
300 normalize_vect(&v);
301 pts_2_vect(mol,&v1,c1,c3);
302 normalize_vect(&v1);
303 vect_sum(&v,&v1,&s);
304 cross_prod(&v,&v1,&n);
305 scal_x_vect(&s,(float) ONE_OVER_SQRT3);
306 scal_x_vect(&n,(float) SQRT_TWO_THIRDS);
307 vect_sum(&s,&n,&h1vect);
308 normalize_vect(&h1vect);
309 scal_x_vect(&h1vect,(float) b_length);
310 Point(h1) = point_plus_vector(&Point(c1),&h1vect);
311
312 scal_x_vect(&n,-1.0);
313 vect_sum(&s,&n,&h2vect);
314 normalize_vect(&h2vect);
315 scal_x_vect(&h2vect,(float) b_length);
316 Point(h2) = point_plus_vector(&Point(c1),&h2vect);
317
318 type_added_hydrogen(mol,c1,h1);
319 type_added_hydrogen(mol,c1,h2);
320 }
321
add_tertiary_hydrogen(ums_type * mol,int c_num,int h_num,double b_length)322 void add_tertiary_hydrogen(ums_type *mol, int c_num, int h_num, double b_length)
323 {
324 vect_type v1,v2,v3,s;
325 int c1,c2,c3,c4,h1;
326 matrix_3x3 m;
327
328 c1 = c_num;
329 c2 = Connection(c1,0);
330 c3 = Connection(c1,1);
331 c4 = Connection(c1,2);
332 h1 = h_num;
333
334
335 pts_2_vect(mol,&v1,c1,c2);
336 normalize_vect(&v1);
337 pts_2_vect(mol,&v2,c1,c3);
338 normalize_vect(&v2);
339 pts_2_vect(mol,&v3,c1,c4);
340 normalize_vect(&v3);
341
342 m.a1 = v1.x; m.b1 = v1.y; m.c1 = v1.z;
343 m.a2 = v2.x; m.b2 = v2.y; m.c2 = v2.z;
344 m.a3 = v3.x; m.b3 = v3.y; m.c3 = v3.z;
345
346 invert_3x3(&m);
347
348 s.x = m.a1 + m.b1 + m.c1;
349 s.y = m.a2 + m.b2 + m.c2;
350 s.z = m.a3 + m.b3 + m.c3;
351
352 normalize_vect(&s);
353 scal_x_vect(&s,(float) b_length);
354 Point(h1) = point_plus_vector(&Point(c1),&s);
355 type_added_hydrogen(mol,c1,h1);
356 }
357
358 int
type_added_hydrogen(ums_type * mol,int c1,int h1)359 type_added_hydrogen(ums_type *mol,int c1, int h1)
360 {
361
362 Atomic_number(h1) = 1;
363 if (Atomic_number(c1) == 6)
364 strcpy(Type(h1),"HC");
365 else
366 strcpy(Type(h1),"H");
367
368 if (HasResidues)
369 {
370 strcpy(AtmId(h1),"H");
371 strcpy(ResName(h1),ResName(c1));
372 ResNum(h1) = ResNum(c1);
373 }
374
375 Valence(h1) = 1;
376 Connection(c1,Valence(c1)) = h1;
377 BO(c1,Valence(c1)) = 1;
378 Valence(c1)++;
379 Connection(h1,0) = c1;
380 BO(h1,0) = 1;
381 return(TRUE);
382 }
383
384
385 int
count_missing_hydrogens(ums_type * mol)386 count_missing_hydrogens(ums_type *mol)
387 {
388 int missing = 0;
389 int i;
390 char temp_type[5];
391 int type_valence;
392 int result;
393
394 for (i = 1; i <= Atoms; i++)
395 {
396 result = xlate_std_type("HAD",Type(i),temp_type);
397 if (result == 0)
398 {
399 sprintf(wstr,"Unable to assign valence to atom %d type = %s",
400 i,Type(i));
401 show_warning(wstr);
402 strcpy(temp_type,"0");
403 }
404 type_valence = atoi(temp_type);
405 if ((Valence(i) < type_valence) && (Valence(i) > 0))
406 {
407 missing += type_valence - Valence(i);
408 }
409 #if 0
410 printf("num = %d type = %s val = %d type_valence = %d\n",
411 i,Type(i),Valence(i),type_valence);
412 #endif
413 }
414 return(missing);
415 }
416
417
418 void
add_2d_hydrogens(ums_type * mol)419 add_2d_hydrogens(ums_type *mol)
420 {
421
422 int old_count, to_add, h_count;
423 int type_valence;
424 char temp_type[10];
425 int result;
426 int i,j;
427
428 old_count = Atoms;
429 to_add = count_missing_hydrogens(mol);
430
431 Atoms += to_add;
432 h_count = old_count + 1;
433 result = reinitialize_ums(&mol);
434 zero_out_ums(mol,old_count + 1);
435
436 for (i = 1; i <= old_count; i++)
437 {
438 to_add = 0;
439
440 result = xlate_std_type("HAD",Type(i),temp_type);
441 if (result == 0)
442 {
443 sprintf(wstr,"Unable to assign valence to atom %d type = %s",
444 i,Type(i));
445 show_warning(wstr);
446 strcpy(temp_type,"0");
447 }
448 type_valence = atoi(temp_type);
449 if ((Valence(i) < type_valence) && (Valence(i) > 0))
450 {
451 to_add = type_valence - Valence(i);
452 /* printf("num = %d type = %s val = %d \n",i,Type(i),Valence(i)); */
453 }
454
455
456 for(j = 0;j < to_add;j++)
457 {
458 Connection(i,Valence(i)) = h_count;
459 Valence(i)++;
460 Start(Bonds) = i;
461 End(Bonds) = h_count;
462 Bond_order(Bonds) = 1;
463 Bonds++;
464 sprintf(Type(h_count),"H%c",Type(i)[0]);
465 Connection(h_count,0) = i;
466 Valence(h_count)++;
467 h_count++;
468 }
469 }
470
471 }
472
473
474
475
476
477
478
479
480
481
482
483
484