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