Mercurial > repos > guerler > springsuite
comparison spring_package/pulchra/pulchra.c @ 37:0be0af9e695d draft
"planemo upload commit c716195a2cc1ed30ff8c4936621091296a93b2fc"
author | guerler |
---|---|
date | Wed, 25 Nov 2020 14:35:35 +0000 |
parents | c790d25086dc |
children |
comparison
equal
deleted
inserted
replaced
36:2fe8ffff530d | 37:0be0af9e695d |
---|---|
1 | |
2 // | |
3 // PULCHRA | |
4 // Protein Chain Restoration Algorithm | |
5 // | |
6 // Version 3.04 | |
7 // July 2007 | |
8 // Contact: Piotr Rotkiewicz, piotr -at- pirx -dot- com | |
9 // | |
10 // to compile: | |
11 // cc -O3 pulchra.c pulchra_data.c -lm -o pulchra | |
12 // | |
13 // to use: | |
14 // ./pulchra file.pdb | |
15 // | |
16 // to display available options: | |
17 // ./pulchra | |
18 // | |
19 | |
20 #define COMPILE_BB | |
21 #define COMPILE_ROT | |
22 | |
23 #include <math.h> | |
24 #include <stdio.h> | |
25 #include <stdlib.h> | |
26 #include <string.h> | |
27 #include <sys/timeb.h> | |
28 #include <time.h> | |
29 | |
30 #define uchar unsigned char | |
31 #define uint unsigned int | |
32 #define real double | |
33 | |
34 #include "pulchra_common.h" | |
35 | |
36 #define PULCHRA_VERSION 3.04 | |
37 #define MAX_BUF_SIZE 1000 | |
38 | |
39 #define FILE_SUCCESS 0 | |
40 #define FILE_NOT_FOUND -1 | |
41 #define FILE_WARNING -2 | |
42 | |
43 #define FATAL_MAE -1 | |
44 | |
45 #define FLAG_BACKBONE 1 | |
46 #define FLAG_CALPHA 2 | |
47 #define FLAG_SIDECHAIN 4 | |
48 #define FLAG_SCM 8 | |
49 | |
50 #define FLAG_PROTEIN 1 | |
51 #define FLAG_DNA 2 | |
52 #define FLAG_RNA 4 | |
53 #define FLAG_CHYDRO 8 | |
54 | |
55 #define RADDEG 180./M_PI | |
56 #define DEGRAD M_PI/180. | |
57 | |
58 int _VERBOSE = 0; | |
59 int _BB_REARRANGE = 1; | |
60 int _BB_OPTIMIZE = 0; | |
61 int _CA_OPTIMIZE = 1; | |
62 int _CA_RANDOM = 0; | |
63 int _CA_ITER = 100; | |
64 int _CA_TRAJECTORY = 0; | |
65 int _CISPRO = 0; | |
66 int _CHIRAL = 1; | |
67 int _CENTER_CHAIN = 0; | |
68 int _REBUILD_BB = 1; | |
69 int _REBUILD_SC = 1; | |
70 int _REBUILD_H = 0; | |
71 int _PDB_SG = 0; | |
72 int _TIME_SEED = 0; | |
73 int _XVOLUME = 1; | |
74 int _XVOL_ITER = 3; | |
75 real _CA_START_DIST = 3.0; | |
76 real _CA_XVOL_DIST = 3.5; | |
77 real _SG_XVOL_DIST = 1.6; | |
78 | |
79 #define CALC_C_ALPHA | |
80 #define CALC_C_ALPHA_ANGLES | |
81 #define CALC_C_ALPHA_START | |
82 #define CALC_C_ALPHA_XVOL | |
83 | |
84 real CA_K=10.0; | |
85 real CA_ANGLE_K=20.0; | |
86 real CA_START_K=0.01; | |
87 real CA_XVOL_K=10.00; | |
88 | |
89 #define CA_DIST 3.8 | |
90 #define CA_DIST_TOL 0.1 | |
91 #define CA_DIST_CISPRO 2.9 | |
92 #define CA_DIST_CISPRO_TOL 0.1 | |
93 #define E_EPS 1e-10 | |
94 | |
95 // grid resolution (used for fast clash detection) | |
96 #define GRID_RES 6.0 | |
97 | |
98 int chain_length = 0; | |
99 | |
100 char AA_NAMES[21][4] = | |
101 { "GLY", "ALA", "SER", "CYS", "VAL", | |
102 "THR", "ILE", "PRO", "MET", "ASP", | |
103 "ASN", "LEU", "LYS", "GLU", "GLN", | |
104 "ARG", "HIS", "PHE", "TYR", "TRP", | |
105 "UNK" }; | |
106 | |
107 char SHORT_AA_NAMES[22] = { "GASCVTIPMDNLKEQRHFYWX" }; | |
108 | |
109 int AA_NUMS[256]; | |
110 | |
111 int nheavy[20] = { 0, 1, 2, 2, 3, 3, 4, 3, 4, 4, 4, 4, 5, 5, 5, 7, 6, 7, 8, 10}; | |
112 | |
113 char *backbone_atoms[4] = { "N ", "CA ", "C ", "O " }; | |
114 | |
115 char *heavy_atoms[200]= { | |
116 /* GLY */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
117 /* ALA */ "CB ", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
118 /* SER */ "CB ", "OG ", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
119 /* CYS */ "CB ", "SG ", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
120 /* VAL */ "CB ", "CG1", "CG2", NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
121 /* THR */ "CB ", "OG1", "CG2", NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
122 /* ILE */ "CB ", "CG1", "CG2", "CD1", NULL, NULL, NULL, NULL, NULL, NULL, | |
123 /* PRO */ "CB ", "CG ", "CD ", NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
124 /* MET */ "CB ", "CG ", "SD ", "CE ", NULL, NULL, NULL, NULL, NULL, NULL, | |
125 /* ASP */ "CB ", "CG ", "OD1", "OD2", NULL, NULL, NULL, NULL, NULL, NULL, | |
126 /* ASN */ "CB ", "CG ", "OD1", "ND2", NULL, NULL, NULL, NULL, NULL, NULL, | |
127 /* LEU */ "CB ", "CG ", "CD1", "CD2", NULL, NULL, NULL, NULL, NULL, NULL, | |
128 /* LYS */ "CB ", "CG ", "CD ", "CE ", "NZ ", NULL, NULL, NULL, NULL, NULL, | |
129 /* GLU */ "CB ", "CG ", "CD ", "OE1", "OE2", NULL, NULL, NULL, NULL, NULL, | |
130 /* GLN */ "CB ", "CG ", "CD ", "OE1", "NE2", NULL, NULL, NULL, NULL, NULL, | |
131 /* ARG */ "CB ", "CG ", "CD ", "NE ", "CZ ", "NH1", "NH2", NULL, NULL, NULL, | |
132 /* HIS */ "CB ", "CG ", "ND1", "CD2", "CE1", "NE2", NULL, NULL, NULL, NULL, | |
133 /* PHE */ "CB ", "CG ", "CD1", "CD2", "CE1", "CE2", "CZ ", NULL, NULL, NULL, | |
134 /* TYR */ "CB ", "CG ", "CD1", "CD2", "CE1", "CE2", "CZ ", "OH ", NULL, NULL, | |
135 /* TRP */ "CB ", "CG ", "CD1", "CD2", "NE1", "CE2", "CE3", "CZ2", "CZ3", "CH2"}; | |
136 | |
137 /* reads full-atom pdb file */ | |
138 | |
139 struct _res_type; | |
140 | |
141 typedef struct _atom_type { | |
142 struct _atom_type *next; | |
143 real x, y, z; | |
144 char *name; | |
145 int num, locnum; | |
146 int flag; | |
147 char cispro; | |
148 int gx, gy, gz; | |
149 struct _res_type *res; | |
150 struct _atom_type *prev; | |
151 } atom_type; | |
152 | |
153 typedef struct _res_type { | |
154 struct _res_type *next; | |
155 atom_type *atoms; | |
156 int num, locnum, natoms; | |
157 int type; | |
158 char pdbsg; | |
159 char protein; | |
160 char *name; | |
161 char chain; | |
162 real sgx, sgy, sgz; | |
163 real cmx, cmy, cmz; | |
164 struct _res_type *prev; | |
165 } res_type; | |
166 | |
167 typedef struct _mol_type { | |
168 struct _mol_type *next; | |
169 res_type *residua; | |
170 int nres; | |
171 unsigned char *r14; | |
172 char *name; | |
173 uchar *seq; | |
174 char **contacts; | |
175 real **cutoffs; | |
176 struct _mol_type *prev; | |
177 } mol_type; | |
178 | |
179 #define MIN(a,b) (a<b?a:b) | |
180 #define MAX(a,b) (a>b?a:b) | |
181 | |
182 mol_type *chain = NULL; | |
183 | |
184 | |
185 real rnd(void) | |
186 { | |
187 return 0.001*(real)(rand()%1000); | |
188 } | |
189 | |
190 atom_type *new_atom(void) | |
191 { | |
192 atom_type *tmpatom; | |
193 | |
194 tmpatom = (atom_type*) calloc(sizeof(atom_type),1); | |
195 if (tmpatom) { | |
196 tmpatom->x=tmpatom->y=tmpatom->z=0.; | |
197 tmpatom->name=NULL; | |
198 tmpatom->num=tmpatom->locnum=tmpatom->flag=0; | |
199 tmpatom->next=tmpatom->prev=NULL; | |
200 } | |
201 | |
202 return tmpatom; | |
203 } | |
204 | |
205 res_type* new_res(void) | |
206 { | |
207 res_type *tmpres; | |
208 | |
209 tmpres = (res_type*) calloc(sizeof(res_type),1); | |
210 if (tmpres) { | |
211 tmpres->num=0; | |
212 tmpres->name=NULL; | |
213 tmpres->atoms=NULL; | |
214 tmpres->chain=' '; | |
215 tmpres->next=tmpres->prev=NULL; | |
216 } | |
217 | |
218 return tmpres; | |
219 } | |
220 | |
221 mol_type *new_mol(void) | |
222 { | |
223 mol_type *tmpmol; | |
224 | |
225 tmpmol = (mol_type*) calloc(sizeof(mol_type),1); | |
226 if (tmpmol) { | |
227 tmpmol->name=NULL; | |
228 tmpmol->residua=NULL; | |
229 tmpmol->next=tmpmol->prev=NULL; | |
230 } | |
231 | |
232 return tmpmol; | |
233 } | |
234 | |
235 void add_atom(atom_type* atomlist, atom_type* newatom) | |
236 { | |
237 atom_type *tmpatom; | |
238 | |
239 if (!atomlist) | |
240 atomlist=newatom; | |
241 else { | |
242 tmpatom=atomlist->next; | |
243 atomlist->next=newatom; | |
244 newatom->prev=atomlist; | |
245 newatom->next=tmpatom; | |
246 if (tmpatom) tmpatom->prev=newatom; | |
247 } | |
248 } | |
249 | |
250 void add_res(res_type* reslist, res_type* newres) | |
251 { | |
252 res_type *tmpres; | |
253 | |
254 if (!reslist) | |
255 reslist=newres; | |
256 else { | |
257 tmpres=reslist->next; | |
258 reslist->next=newres; | |
259 newres->prev=reslist; | |
260 newres->next=tmpres; | |
261 if (tmpres) tmpres->prev=newres; | |
262 } | |
263 } | |
264 | |
265 void add_mol(mol_type* mollist, mol_type* newmol) | |
266 { | |
267 mol_type *tmpmol; | |
268 | |
269 if (!mollist) | |
270 mollist=newmol; | |
271 else { | |
272 tmpmol=mollist->next; | |
273 mollist->next=newmol; | |
274 newmol->prev=mollist; | |
275 newmol->next=tmpmol; | |
276 if (tmpmol) tmpmol->prev=newmol; | |
277 } | |
278 } | |
279 | |
280 void delete_atom(atom_type* atom) | |
281 { | |
282 atom_type *tmpatom; | |
283 | |
284 if (atom->prev) atom->prev->next=atom->next; | |
285 if (atom->next) atom->next->prev=atom->prev; | |
286 if (atom->name) free(atom->name); | |
287 free(atom); | |
288 atom=NULL; | |
289 } | |
290 | |
291 void delete_res(res_type* res) | |
292 { | |
293 res_type *tmpres; | |
294 atom_type *tmpatom; | |
295 | |
296 if (res->prev) res->prev->next=res->next; | |
297 if (res->next) res->next->prev=res->prev; | |
298 if (res->name) free(res->name); | |
299 if (res->atoms) { | |
300 while (res->atoms) { | |
301 tmpatom = res->atoms->next; | |
302 delete_atom(res->atoms); | |
303 res->atoms=tmpatom; | |
304 } | |
305 } | |
306 free(res); | |
307 res=NULL; | |
308 } | |
309 | |
310 void delete_mol(mol_type* mol) | |
311 { | |
312 mol_type *tmpmol; | |
313 res_type *tmpres; | |
314 int i; | |
315 | |
316 if (mol->prev) mol->prev->next=mol->next; | |
317 if (mol->next) mol->next->prev=mol->prev; | |
318 if (mol->name) free(mol->name); | |
319 if (mol->residua) { | |
320 while (mol->residua) { | |
321 tmpres = mol->residua->next; | |
322 delete_res(mol->residua); | |
323 mol->residua=tmpres; | |
324 } | |
325 } | |
326 if (mol->contacts) { | |
327 for (i=0; i<mol->nres; i++) free(mol->contacts[i]); | |
328 free(mol->contacts); | |
329 } | |
330 if (mol->cutoffs) { | |
331 for (i=0; i<mol->nres; i++) free(mol->cutoffs[i]); | |
332 free(mol->cutoffs); | |
333 } | |
334 free(mol); | |
335 mol=NULL; | |
336 } | |
337 | |
338 | |
339 atom_type* get_last_atom(atom_type* atom) | |
340 { | |
341 while (atom->next) atom=atom->next; | |
342 | |
343 return atom; | |
344 } | |
345 | |
346 res_type* get_last_res(res_type* res) | |
347 { | |
348 while (res->next) res=res->next; | |
349 | |
350 return res; | |
351 } | |
352 | |
353 mol_type *get_last_mol(mol_type* mol) | |
354 { | |
355 while (mol->next) mol=mol->next; | |
356 | |
357 return mol; | |
358 } | |
359 | |
360 char setseq(char* aaname) | |
361 { | |
362 int i; | |
363 | |
364 for (i=0; i<21; i++) { | |
365 if ((aaname[0]==AA_NAMES[i][0]) && | |
366 (aaname[1]==AA_NAMES[i][1]) && | |
367 (aaname[2]==AA_NAMES[i][2])) | |
368 break; | |
369 } | |
370 | |
371 if (i==21) { | |
372 if (!strcmp(aaname, "GLX")) | |
373 return 'E'; | |
374 if (!strcmp(aaname, "ASX")) | |
375 return 'D'; | |
376 if (!strcmp(aaname, "HID")) | |
377 return 'H'; | |
378 if (!strcmp(aaname, "MSE")) | |
379 return 'M'; | |
380 if (!strcmp(aaname, "SEP")) | |
381 return 'S'; | |
382 if (!strcmp(aaname, "TPO")) | |
383 return 'T'; | |
384 if (!strcmp(aaname, "PTR")) | |
385 return 'Y'; | |
386 i--; | |
387 } | |
388 | |
389 return SHORT_AA_NAMES[i]; | |
390 } | |
391 | |
392 int orient(res_type *res1, res_type *res2) | |
393 { | |
394 real x1, y1, z1; | |
395 real x2, y2, z2; | |
396 real cax, cay, caz; | |
397 real len, vect, angle; | |
398 atom_type *atom; | |
399 | |
400 if (!res1 || !res2) return 0; | |
401 | |
402 atom=res1->atoms; | |
403 cax=cay=caz=0.; | |
404 while (atom) { | |
405 if (!strncmp(atom->name,"CA",2)) { | |
406 cax=atom->x; cay=atom->y; caz=atom->z; | |
407 } | |
408 atom=atom->next; | |
409 } | |
410 x1=res1->sgx-cax; y1=res1->sgy-cay; z1=res1->sgz-caz; | |
411 if (x1==0. && y1==0. && z1==0.) x1+=1.0; | |
412 | |
413 atom=res2->atoms; | |
414 cax=cay=caz=0.; | |
415 while (atom) { | |
416 if (!strncmp(atom->name,"CA",2)) { | |
417 cax=atom->x; cay=atom->y; caz=atom->z; | |
418 } | |
419 atom=atom->next; | |
420 } | |
421 x2=res2->sgx-cax; y2=res2->sgy-cay; z2=res2->sgz-caz; | |
422 if (x2==0. && y2==0. && z2==0.) x2+=1.0; | |
423 | |
424 vect = x1*x2+y1*y2+z1*z2; | |
425 len = sqrt(x1*x1+y1*y1+z1*z1)*sqrt(x2*x2+y2*y2+z2*z2); | |
426 if (len) vect /= len; | |
427 | |
428 angle=RADDEG*acos(vect); | |
429 | |
430 if (angle>120.) return 1; /*anti*/ | |
431 if (angle>60.) return 2; /*mid*/ | |
432 | |
433 return 3; /*par*/ | |
434 } | |
435 | |
436 int res_contact(res_type *res1, res_type *res2) { | |
437 atom_type *atoms1, *atoms2; | |
438 real dx, dy, dz; | |
439 | |
440 atoms1 = res1->atoms; | |
441 while (atoms1) { | |
442 atoms2 = res2->atoms; | |
443 while (atoms2) { | |
444 dx=atoms1->x-atoms2->x; | |
445 dy=atoms1->y-atoms2->y; | |
446 dz=atoms1->z-atoms2->z; | |
447 if ((atoms1->flag & FLAG_SIDECHAIN) && (atoms2->flag & FLAG_SIDECHAIN) && (dx*dx+dy*dy+dz*dz<20.25)) { | |
448 return 1; | |
449 } | |
450 atoms2=atoms2->next; | |
451 } | |
452 atoms1=atoms1->next; | |
453 } | |
454 | |
455 return 0; | |
456 } | |
457 | |
458 int read_pdb_file(char* filename, mol_type* molecules, char *realname) | |
459 { | |
460 FILE *inp; | |
461 char buffer[1000]; | |
462 char atmname[10]; | |
463 char resname[10]; | |
464 char version; | |
465 int prevresnum, resnum, atmnum, locatmnum, num, locnum=0, i, j; | |
466 atom_type *prevatom1, *prevatom2, *prevatom3, *prevatom4; | |
467 int sgnum, cc, nres, ok, natom; | |
468 real sgx, sgy, sgz; | |
469 res_type *res, *test1, *test2; | |
470 atom_type *atom; | |
471 real x, y, z; | |
472 real dist; | |
473 unsigned char bin; | |
474 int warn=0; | |
475 real cutoff; | |
476 | |
477 if (_VERBOSE) printf("Reading input file %s...\n", filename); | |
478 | |
479 inp = fopen(filename, "r"); | |
480 if (!inp) { | |
481 if (_VERBOSE) printf("ERROR: can't open %s !!!\n", filename); | |
482 return FILE_NOT_FOUND; | |
483 } | |
484 | |
485 molecules->nres=0; | |
486 molecules->name=(char*)calloc(strlen(realname)+1,1); | |
487 strcpy(molecules->name, realname); | |
488 | |
489 atmname[3]=0; | |
490 resname[3]=0; | |
491 prevresnum=-666; | |
492 locatmnum=0; | |
493 sgnum=0; | |
494 sgx=sgy=sgz=0.; | |
495 res=NULL; | |
496 while (!feof(inp)) { | |
497 if (fgets(buffer, 1000, inp)!=buffer) break; | |
498 if (!strncmp(buffer, "END", 3) || !strncmp(buffer, "TER", 3)) break; // end of file; only single molecule read | |
499 if (!strncmp(buffer, "ATOM", 4) || !strncmp(buffer, "HETATM", 6)) { | |
500 if (buffer[16]!=' ' && buffer[16]!='A') continue; | |
501 sscanf(&buffer[22], "%d", &resnum); | |
502 strncpy(resname, &buffer[17], 3); | |
503 strncpy(atmname, &buffer[13], 3); | |
504 if (resnum==prevresnum && !strncmp(atmname, "N ", 2)) { | |
505 if (_VERBOSE) printf("WARNING: fault in numeration at residuum %s[%d]\n", resname, resnum); | |
506 warn=1; | |
507 } | |
508 if (atmname[0]=='H') continue; | |
509 if (resnum!=prevresnum || !strncmp(atmname, "N ", 2)) { | |
510 prevresnum=resnum; | |
511 if (res) { | |
512 if (sgnum) { | |
513 res->sgx=sgx/(real)sgnum; | |
514 res->sgy=sgy/(real)sgnum; | |
515 res->sgz=sgz/(real)sgnum; | |
516 } else { | |
517 res->sgx=res->sgy=res->sgz=0.; | |
518 } | |
519 } | |
520 locatmnum=0; | |
521 version=' '; | |
522 res = new_res(); | |
523 sgnum=0; | |
524 sgx=sgy=sgz=0.; | |
525 molecules->nres++; | |
526 res->name = calloc(strlen(resname)+1, 1); | |
527 res->type = AA_NUMS[setseq(resname)]; | |
528 res->locnum=locnum++; | |
529 res->num = resnum; | |
530 res->natoms=0; | |
531 res->chain = buffer[21]; | |
532 strcpy(res->name, resname); | |
533 if (molecules->residua) { | |
534 add_res(get_last_res(molecules->residua), res); | |
535 } else { | |
536 molecules->residua = res; | |
537 } | |
538 } | |
539 atom = new_atom(); | |
540 atom->res = res; | |
541 res->natoms++; | |
542 locatmnum++; | |
543 sscanf(&buffer[7], "%d", &atmnum); | |
544 sscanf(&buffer[30], "%lf", &x); | |
545 sscanf(&buffer[38], "%lf", &y); | |
546 sscanf(&buffer[46], "%lf", &z); | |
547 version = buffer[16]; | |
548 atom->name = calloc(strlen(atmname)+1,1); | |
549 strcpy(atom->name, atmname); | |
550 atom->x=x; atom->y=y; atom->z=z; | |
551 atom->num = atmnum; | |
552 atom->locnum = locatmnum; | |
553 if ((atmname[0]=='S' && atmname[1]=='C')||(atmname[0]=='C' && atmname[1]=='M')) { | |
554 res->cmx = x; | |
555 res->cmy = y; | |
556 res->cmz = z; | |
557 res->pdbsg=1; | |
558 if (res->type<20) { | |
559 res->protein=1; | |
560 } | |
561 } else | |
562 if (!( ((atmname[0]=='C' || atmname[0]=='N' || atmname[0]=='O') && atmname[1]==' ') || | |
563 (atmname[0]=='H') || | |
564 (atmname[0]=='C' && atmname[1]=='A') || | |
565 (atmname[0]=='O' && atmname[1]=='X' && atmname[2]=='T') ) ) { | |
566 sgx+=x; | |
567 sgy+=y; | |
568 sgz+=z; | |
569 sgnum++; | |
570 atom->flag |= FLAG_SIDECHAIN; | |
571 } else | |
572 atom->flag |= FLAG_BACKBONE; | |
573 if (atmname[0]=='C' && atmname[1]=='A') { | |
574 atom->flag |= FLAG_BACKBONE; | |
575 if (res->type<20) { | |
576 res->protein=1; | |
577 } | |
578 if (!res->pdbsg) { | |
579 res->cmx = x; | |
580 res->cmy = y; | |
581 res->cmz = z; | |
582 } | |
583 } | |
584 if (atmname[0]=='C' && atmname[1]=='M') { | |
585 atom->flag |= FLAG_SCM; | |
586 } | |
587 if (atmname[0]=='S' && atmname[1]=='C') { | |
588 atom->flag |= FLAG_SCM; | |
589 } | |
590 if (res->atoms) { | |
591 add_atom(get_last_atom(res->atoms), atom); | |
592 } else { | |
593 res->atoms = atom; | |
594 } | |
595 } | |
596 } | |
597 | |
598 if (res) { | |
599 if (sgnum) { | |
600 res->sgx=sgx/(real)sgnum; | |
601 res->sgy=sgy/(real)sgnum; | |
602 res->sgz=sgz/(real)sgnum; | |
603 } else { | |
604 res->sgx=res->sgy=res->sgz=0.; | |
605 } | |
606 } | |
607 fclose(inp); | |
608 | |
609 molecules->seq = (uchar*)calloc(sizeof(uchar)*molecules->nres+1,1); | |
610 res=molecules->residua; i=0; | |
611 while (res) { | |
612 molecules->seq[i++]=(uchar)AA_NUMS[(int)setseq(res->name)]; | |
613 res=res->next; | |
614 } | |
615 | |
616 if (!warn) return FILE_SUCCESS; else return FILE_WARNING; | |
617 } | |
618 | |
619 #define bool int | |
620 #define true 1 | |
621 #define false 0 | |
622 | |
623 real calc_ca_energy(atom_type **c_alpha, real **new_c_alpha, real **init_c_alpha, real **gradient, real alpha, real *ene, bool calc_gradient) | |
624 { | |
625 int i, j; | |
626 real dx, dy, dz; | |
627 real dist, ddist, ddist2; | |
628 real new_e_pot; | |
629 real theta0, tdif, th, aa, bb, ab; | |
630 real ff0, ff2, dth, m0, m2, grad, f0[3], f2[3]; | |
631 real adiff[3], bdiff[3]; | |
632 real deriv, theta, dtheta, len1, len2, cos_theta, sin_theta; | |
633 real dx1, dy1, dz1; | |
634 real dx2, dy2, dz2; | |
635 real dx3, dy3, dz3; | |
636 real vx1, vy1, vz1; | |
637 real vx2, vy2, vz2; | |
638 real vx3, vy3, vz3; | |
639 | |
640 real r12x, r12y, r12z; | |
641 real r32x, r32y, r32z; | |
642 real d12, d32, d12inv, d32inv, c1, c2, diff; | |
643 real f1x, f1y, f1z; | |
644 real f2x, f2y, f2z; | |
645 real f3x, f3y, f3z; | |
646 | |
647 for (i=0; i<chain_length; i++) { | |
648 new_c_alpha[i][0]=c_alpha[i]->x+alpha*gradient[i][0]; | |
649 new_c_alpha[i][1]=c_alpha[i]->y+alpha*gradient[i][1]; | |
650 new_c_alpha[i][2]=c_alpha[i]->z+alpha*gradient[i][2]; | |
651 } | |
652 | |
653 new_e_pot = 0.0; | |
654 | |
655 ene[0]=ene[1]=ene[2]=ene[3]=0.0; | |
656 | |
657 for (i=0; i<chain_length; i++) { | |
658 #ifdef CALC_C_ALPHA_START | |
659 dx=new_c_alpha[i][0]-init_c_alpha[i][0]; | |
660 dy=new_c_alpha[i][1]-init_c_alpha[i][1]; | |
661 dz=new_c_alpha[i][2]-init_c_alpha[i][2]; | |
662 dist=sqrt(dx*dx+dy*dy+dz*dz); | |
663 ddist = -dist; | |
664 if (dist>_CA_START_DIST) { | |
665 ddist2=dist*dist; | |
666 new_e_pot+=CA_START_K*ddist2; | |
667 ene[1] += CA_START_K*ddist2; | |
668 if (calc_gradient) { | |
669 grad = ddist * (-2.0*CA_START_K)/dist; | |
670 gradient[i][0]-=grad*dx; | |
671 gradient[i][1]-=grad*dy; | |
672 gradient[i][2]-=grad*dz; | |
673 } | |
674 } | |
675 | |
676 #endif | |
677 | |
678 | |
679 #ifdef CALC_C_ALPHA | |
680 if (i>0) { | |
681 dx=new_c_alpha[i][0]-new_c_alpha[i-1][0]; | |
682 dy=new_c_alpha[i][1]-new_c_alpha[i-1][1]; | |
683 dz=new_c_alpha[i][2]-new_c_alpha[i-1][2]; | |
684 dist=sqrt(dx*dx+dy*dy+dz*dz); | |
685 if (c_alpha[i]->cispro) { | |
686 ddist=CA_DIST_CISPRO-dist; | |
687 // if (fabs(ddist)<CA_DIST_CISPRO_TOL) ddist=0.0; | |
688 } else { | |
689 ddist=CA_DIST-dist; | |
690 // if (fabs(ddist)<CA_DIST_TOL) ddist=0.0; | |
691 } | |
692 ddist2=ddist*ddist; | |
693 new_e_pot+=CA_K*ddist2; | |
694 ene[0] += CA_K*ddist2; | |
695 if (calc_gradient) { | |
696 grad = ddist * (-2.0*CA_K)/dist; | |
697 gradient[i][0]-=grad*dx; | |
698 gradient[i][1]-=grad*dy; | |
699 gradient[i][2]-=grad*dz; | |
700 gradient[i-1][0]+=grad*dx; | |
701 gradient[i-1][1]+=grad*dy; | |
702 gradient[i-1][2]+=grad*dz; | |
703 } | |
704 } | |
705 #endif | |
706 | |
707 #ifdef CALC_C_ALPHA_XVOL | |
708 for (j=0;j<i;j++) { | |
709 if (abs(i-j)>2) { | |
710 dx=new_c_alpha[i][0]-new_c_alpha[j][0]; | |
711 dy=new_c_alpha[i][1]-new_c_alpha[j][1]; | |
712 dz=new_c_alpha[i][2]-new_c_alpha[j][2]; | |
713 dist=sqrt(dx*dx+dy*dy+dz*dz); | |
714 ddist = dist-_CA_XVOL_DIST; | |
715 if (dist<_CA_XVOL_DIST) { | |
716 ddist2 = dist*dist; | |
717 new_e_pot+=CA_XVOL_K*ddist2; | |
718 ene[3] += CA_XVOL_K*ddist2; | |
719 if (calc_gradient) { | |
720 grad = ddist*(8.0*CA_XVOL_K)/dist; | |
721 gradient[i][0]-=grad*dx; | |
722 gradient[i][1]-=grad*dy; | |
723 gradient[i][2]-=grad*dz; | |
724 gradient[j][0]+=grad*dx; | |
725 gradient[j][1]+=grad*dy; | |
726 gradient[j][2]+=grad*dz; | |
727 } | |
728 } | |
729 } | |
730 } | |
731 #endif | |
732 | |
733 #ifdef CALC_C_ALPHA_ANGLES | |
734 | |
735 if (i>0 && i<chain_length-1) { | |
736 r12x=new_c_alpha[i-1][0]-new_c_alpha[i][0]; | |
737 r12y=new_c_alpha[i-1][1]-new_c_alpha[i][1]; | |
738 r12z=new_c_alpha[i-1][2]-new_c_alpha[i][2]; | |
739 r32x=new_c_alpha[i+1][0]-new_c_alpha[i][0]; | |
740 r32y=new_c_alpha[i+1][1]-new_c_alpha[i][1]; | |
741 r32z=new_c_alpha[i+1][2]-new_c_alpha[i][2]; | |
742 d12 = sqrt(r12x*r12x+r12y*r12y+r12z*r12z); | |
743 d32 = sqrt(r32x*r32x+r32y*r32y+r32z*r32z); | |
744 cos_theta = (r12x*r32x+r12y*r32y+r12z*r32z)/(d12*d32); | |
745 if (cos_theta>1.0) | |
746 cos_theta = 1.0; | |
747 else | |
748 if (cos_theta<-1.0) | |
749 cos_theta = -1.0; | |
750 sin_theta = sqrt(1.0-cos_theta*cos_theta); | |
751 theta = acos(cos_theta); | |
752 | |
753 if (RADDEG*theta<80.) | |
754 diff = theta-80.*DEGRAD; | |
755 else | |
756 if (RADDEG*theta>150.) | |
757 diff = theta-150.*DEGRAD; | |
758 else | |
759 diff = 0.0; | |
760 | |
761 new_e_pot += CA_ANGLE_K*diff*diff; | |
762 ene[2] += CA_ANGLE_K*diff*diff; | |
763 if (calc_gradient) { | |
764 d12inv = 1.0/d12; | |
765 d32inv = 1.0/d32; | |
766 diff *= (-2.0*CA_ANGLE_K)/sin_theta; | |
767 c1 = diff*d12inv; | |
768 c2 = diff*d32inv; | |
769 f1x = c1*(r12x*(d12inv*cos_theta)-r32x*d32inv); | |
770 f1y = c1*(r12y*(d12inv*cos_theta)-r32y*d32inv); | |
771 f1z = c1*(r12z*(d12inv*cos_theta)-r32z*d32inv); | |
772 f3x = c2*(r32x*(d32inv*cos_theta)-r12x*d12inv); | |
773 f3y = c2*(r32y*(d32inv*cos_theta)-r12y*d12inv); | |
774 f3z = c2*(r32z*(d32inv*cos_theta)-r12z*d12inv); | |
775 f2x = -f1x-f3x; | |
776 f2y = -f1y-f3y; | |
777 f2z = -f1z-f3z; | |
778 gradient[i-1][0]+=f1x; | |
779 gradient[i-1][1]+=f1y; | |
780 gradient[i-1][2]+=f1z; | |
781 gradient[i][0]+=f2x; | |
782 gradient[i][1]+=f2y; | |
783 gradient[i][2]+=f2z; | |
784 gradient[i+1][0]+=f3x; | |
785 gradient[i+1][1]+=f3y; | |
786 gradient[i+1][2]+=f3z; | |
787 } | |
788 } | |
789 | |
790 #endif | |
791 | |
792 } | |
793 | |
794 //printf("ene[3] = %f\n", ene[3]); | |
795 | |
796 return new_e_pot; | |
797 } | |
798 | |
799 /* | |
800 * Steepest gradient optimization using v=k*(r0-r)^2 | |
801 * k = CA_K, r0 = CA_DIST | |
802 */ | |
803 void ca_optimize(char *tname, char *iname) | |
804 { | |
805 char buf[1000]; | |
806 int i, j, hx, my_iter; | |
807 real dx, dy, dz, dd, dist, dist2, dist3, ddist, ddist2; | |
808 real e_pot, new_e_pot, grad, alpha, e_pot1, e_pot2, e_pot3; | |
809 real adiff[3], bdiff[3]; | |
810 real ff0, ff2, aa, ab, bb, th, tdif, dth, m0, m2; | |
811 real theta0, deg_th, maxgrad, sum; | |
812 real f0[3], f2[3]; | |
813 real x, y, z; | |
814 int numsteps, numsteps2, msteps; | |
815 int *sec; | |
816 real **new_c_alpha, **gradient, **init_c_alpha, last_alpha, tmp, last_good_alpha, d_alpha, last_e_pot; | |
817 atom_type *atom, **c_alpha; | |
818 res_type *res; | |
819 FILE *inp, *out; | |
820 int mnum, init, ok; | |
821 real alpha1, alpha2, alpha3, a0; | |
822 real ene1, ene2, ene3, e0; | |
823 real energies[4]; | |
824 real w1, w2, w3, eps; | |
825 real gnorm, last_gnorm; | |
826 int mode, fcnt; | |
827 | |
828 | |
829 if (_CA_TRAJECTORY) { | |
830 out = fopen(tname,"w"); | |
831 if (out) fclose(out); | |
832 } | |
833 | |
834 if (_VERBOSE) printf("Alpha carbons optimization...\n"); | |
835 | |
836 new_c_alpha = (real**)calloc(sizeof(real*)*(chain_length+1),1); | |
837 init_c_alpha = (real**)calloc(sizeof(real*)*(chain_length+1),1); | |
838 for (i=0;i<=chain_length;i++) { | |
839 new_c_alpha[i] = (real*)calloc(sizeof(real)*3,1); | |
840 init_c_alpha[i] = (real*)calloc(sizeof(real)*3,1); | |
841 } | |
842 gradient = (real**)calloc(sizeof(real*)*(chain_length+1),1); | |
843 for (i=0;i<=chain_length;i++) { | |
844 gradient[i] = (real*)calloc(sizeof(real)*3,1); | |
845 } | |
846 | |
847 c_alpha = (atom_type**)calloc(sizeof(atom_type*)*(chain_length+1),1); | |
848 | |
849 i = 0; | |
850 res = chain->residua; | |
851 while (res) { | |
852 atom = res->atoms; | |
853 while (atom) { | |
854 if (atom->name[0]=='C' && atom->name[1]=='A') { | |
855 if (i<chain_length) { | |
856 c_alpha[i] = atom; | |
857 i++; | |
858 break; | |
859 } else { | |
860 if (_VERBOSE) printf("WARNING: number of C-alpha atoms exceeds the chain length!\n"); | |
861 break; | |
862 } | |
863 } | |
864 atom = atom->next; | |
865 } | |
866 res = res->next; | |
867 } | |
868 | |
869 if (i<chain_length) chain_length = i; | |
870 | |
871 for (i=0; i<chain_length; i++) { | |
872 init_c_alpha[i][0] = c_alpha[i]->x; | |
873 init_c_alpha[i][1] = c_alpha[i]->y; | |
874 init_c_alpha[i][2] = c_alpha[i]->z; | |
875 } | |
876 | |
877 if (_CISPRO) { | |
878 for (i=1; i<chain_length; i++) { | |
879 dx = c_alpha[i]->x-c_alpha[i-1]->x; | |
880 dy = c_alpha[i]->y-c_alpha[i-1]->y; | |
881 dz = c_alpha[i]->z-c_alpha[i-1]->z; | |
882 dd = sqrt(dx*dx+dy*dy+dz*dz); | |
883 if ((setseq(c_alpha[i]->res->name)=='P') && (dd>CA_DIST_CISPRO-5*CA_DIST_CISPRO_TOL) && (dd<CA_DIST_CISPRO+5*CA_DIST_CISPRO_TOL)) { | |
884 if (_VERBOSE) printf("Probable cis-proline found at postion %d\n", c_alpha[i]->res->num); | |
885 c_alpha[i]->cispro = 1; | |
886 } | |
887 } | |
888 } | |
889 | |
890 if (_CA_RANDOM) { | |
891 if (_VERBOSE) printf("Generating random C-alpha coordinates...\n"); | |
892 c_alpha[0]->x = 0.0; | |
893 c_alpha[0]->y = 0.0; | |
894 c_alpha[0]->z = 0.0; | |
895 for (i=1;i<chain_length;i++) { | |
896 dx = 0.01*(100-rand()%200); | |
897 dy = 0.01*(100-rand()%200); | |
898 dz = 0.01*(100-rand()%200); | |
899 dd = 3.8/sqrt(dx*dx+dy*dy+dz*dz); | |
900 dx *= dd; | |
901 dy *= dd; | |
902 dz *= dd; | |
903 c_alpha[i]->x = c_alpha[i-1]->x+dx; | |
904 c_alpha[i]->y = c_alpha[i-1]->y+dy; | |
905 c_alpha[i]->z = c_alpha[i-1]->z+dz; | |
906 } | |
907 } | |
908 | |
909 if (iname) { | |
910 inp = fopen(iname,"r"); | |
911 if (inp) { | |
912 if (_VERBOSE) printf("Reading initial structure %s...\n", iname); | |
913 i = 0; | |
914 while (!feof(inp)) { | |
915 if (fgets(buf,1000,inp)==buf && buf[13]=='C' && buf[14]=='A') { | |
916 if (i<chain_length) { | |
917 if (sscanf(&buf[30],"%lf%lf%lf",&x,&y,&z)==3) { | |
918 c_alpha[i]->x = x; | |
919 c_alpha[i]->y = y; | |
920 c_alpha[i]->z = z; | |
921 i++; | |
922 } | |
923 } else { | |
924 if (_VERBOSE) printf("WARNING: number of ini-file C-alpha atoms exceeds the chain length!\n"); | |
925 break; | |
926 } | |
927 } | |
928 } | |
929 fclose(inp); | |
930 } else | |
931 if (_VERBOSE) printf("WARNING: can't read initial corrdinates %s\n", iname); | |
932 } | |
933 | |
934 mnum = 1; | |
935 mode = 0; | |
936 init = 0; | |
937 numsteps=numsteps2=0; | |
938 last_alpha = 0.0; | |
939 | |
940 | |
941 if (_VERBOSE) printf("Optimizing alpha carbons...\n"); | |
942 | |
943 eps = 0.5; | |
944 | |
945 fcnt=0; | |
946 | |
947 last_gnorm = 1000.; | |
948 | |
949 do { | |
950 last_e_pot = e_pot; | |
951 | |
952 if (_CA_TRAJECTORY) { | |
953 out = fopen(tname,"a"); | |
954 if (out) { | |
955 fprintf(out,"MODEL %d\n",mnum++); | |
956 for (i=0; i<chain_length; i++) { | |
957 fprintf(out, "ATOM %5d %-3s %3s %c%4d %8.3f%8.3f%8.3f\n", | |
958 i+1, "CA ", c_alpha[i]->res->name, ' ', c_alpha[i]->res->num, | |
959 c_alpha[i]->x, c_alpha[i]->y, c_alpha[i]->z); | |
960 | |
961 } | |
962 fprintf(out,"ENDMDL\n"); | |
963 fclose(out); | |
964 } | |
965 } | |
966 | |
967 // calculate gradients | |
968 | |
969 e_pot=e_pot1=e_pot2=e_pot3=0.; | |
970 | |
971 for (i=0; i<chain_length; i++) | |
972 gradient[i][0]=gradient[i][1]=gradient[i][2]=0.; | |
973 | |
974 e_pot = calc_ca_energy(c_alpha, new_c_alpha, init_c_alpha, gradient, 0.0, energies, true); | |
975 | |
976 if (_VERBOSE && !init) { | |
977 printf("Initial energy: bond=%.5lf angle=%.5f restraints=%.5f xvol=%.5f total=%.5f\n", energies[0], energies[2], energies[1], energies[3], e_pot); | |
978 } | |
979 | |
980 if (!init) init=1; | |
981 | |
982 // LINE SEARCH | |
983 | |
984 alpha1 = -1.0; | |
985 alpha2 = 0.0; | |
986 alpha3 = 1.0; | |
987 | |
988 ene1 = calc_ca_energy(c_alpha, new_c_alpha, init_c_alpha, gradient, alpha1, energies, false); | |
989 ene2 = calc_ca_energy(c_alpha, new_c_alpha, init_c_alpha, gradient, alpha2, energies, false); | |
990 ene3 = calc_ca_energy(c_alpha, new_c_alpha, init_c_alpha, gradient, alpha3, energies, false); | |
991 | |
992 msteps = 0; | |
993 while (ene2>MIN(ene1,ene3) && msteps<_CA_ITER) { | |
994 msteps++; | |
995 alpha1 *= 2.0; | |
996 alpha3 *= 2.0; | |
997 ene1 = calc_ca_energy(c_alpha, new_c_alpha, init_c_alpha, gradient, alpha1, energies, false); | |
998 ene3 = calc_ca_energy(c_alpha, new_c_alpha, init_c_alpha, gradient, alpha3, energies, false); | |
999 } | |
1000 | |
1001 msteps = 0; | |
1002 do { | |
1003 if (alpha3-alpha2>alpha2-alpha1) { | |
1004 a0 = 0.5*(alpha2+alpha3); | |
1005 e0 = calc_ca_energy(c_alpha, new_c_alpha, init_c_alpha, gradient, a0, energies, false); | |
1006 e0 = calc_ca_energy(c_alpha, new_c_alpha, init_c_alpha, gradient, a0-1e-5, energies, false); | |
1007 e0 = calc_ca_energy(c_alpha, new_c_alpha, init_c_alpha, gradient, a0+1e-5, energies, false); | |
1008 e0 = calc_ca_energy(c_alpha, new_c_alpha, init_c_alpha, gradient, a0, energies, false); | |
1009 if (e0<ene2) { | |
1010 alpha1 = alpha2; | |
1011 alpha2 = a0; | |
1012 ene1 = ene2; | |
1013 ene2 = e0; | |
1014 } else { | |
1015 alpha3 = a0; | |
1016 ene3 = e0; | |
1017 } | |
1018 } else { | |
1019 a0 = 0.5*(alpha1+alpha2); | |
1020 e0 = calc_ca_energy(c_alpha, new_c_alpha, init_c_alpha, gradient, a0, energies, false); | |
1021 e0 = calc_ca_energy(c_alpha, new_c_alpha, init_c_alpha, gradient, a0-1e-5, energies, false); | |
1022 e0 = calc_ca_energy(c_alpha, new_c_alpha, init_c_alpha, gradient, a0+1e-5, energies, false); | |
1023 e0 = calc_ca_energy(c_alpha, new_c_alpha, init_c_alpha, gradient, a0, energies, false); | |
1024 if (e0<ene2) { | |
1025 alpha3 = alpha2; | |
1026 alpha2 = a0; | |
1027 ene3 = ene2; | |
1028 ene2 = e0; | |
1029 } else { | |
1030 alpha1 = a0; | |
1031 ene1 = e0; | |
1032 } | |
1033 } | |
1034 msteps++; | |
1035 } while (alpha3-alpha1>1e-6 && msteps<20); | |
1036 | |
1037 last_alpha = alpha2; | |
1038 e_pot = ene2; | |
1039 | |
1040 for (i=0; i<chain_length; i++) { | |
1041 c_alpha[i]->x=c_alpha[i]->x+(last_alpha+last_alpha*(rnd()-0.5)*eps)*gradient[i][0]; | |
1042 c_alpha[i]->y=c_alpha[i]->y+(last_alpha+last_alpha*(rnd()-0.5)*eps)*gradient[i][1]; | |
1043 c_alpha[i]->z=c_alpha[i]->z+(last_alpha+last_alpha*(rnd()-0.5)*eps)*gradient[i][2]; | |
1044 } | |
1045 | |
1046 e_pot = calc_ca_energy(c_alpha, new_c_alpha, init_c_alpha, gradient, 0.0, energies, false); | |
1047 | |
1048 eps *= 0.75; | |
1049 if (eps<1e-3) eps=0.0; | |
1050 | |
1051 numsteps++; | |
1052 | |
1053 gnorm = 0.0; | |
1054 | |
1055 for (i=0; i<chain_length; i++) { | |
1056 gnorm += gradient[i][0]*gradient[i][0] + gradient[i][1]*gradient[i][1] + gradient[i][2]*gradient[i][2]; | |
1057 } | |
1058 | |
1059 gnorm = sqrt(gnorm/(double)chain_length); | |
1060 | |
1061 if (last_gnorm-gnorm<1e-3) fcnt++; | |
1062 | |
1063 last_gnorm = gnorm; | |
1064 | |
1065 } while ( (fcnt<3) && (gnorm>0.01) && (numsteps<_CA_ITER)); | |
1066 | |
1067 | |
1068 if (_VERBOSE) { | |
1069 for (i=0; i<chain_length; i++) { | |
1070 | |
1071 #ifdef CALC_C_ALPHA | |
1072 if (i>0) { | |
1073 dx=c_alpha[i]->x-c_alpha[i-1]->x; | |
1074 dy=c_alpha[i]->y-c_alpha[i-1]->y; | |
1075 dz=c_alpha[i]->z-c_alpha[i-1]->z; | |
1076 dist=sqrt(dx*dx+dy*dy+dz*dz); | |
1077 if (c_alpha[i]->cispro) { | |
1078 ddist=CA_DIST_CISPRO-dist; | |
1079 if (fabs(ddist)<CA_DIST_CISPRO_TOL) ddist=0.0; | |
1080 } else { | |
1081 ddist=CA_DIST-dist; | |
1082 if (fabs(ddist)<CA_DIST_TOL) ddist=0.0; | |
1083 } | |
1084 ddist2=ddist*ddist; | |
1085 if (fabs(ddist)>=CA_DIST_TOL) printf("WARNING: distance %d = %.3lf A\n", i, dist); | |
1086 } | |
1087 #endif | |
1088 } | |
1089 | |
1090 for (i=0; i<chain_length; i++) { | |
1091 #ifdef CALC_C_ALPHA_ANGLES | |
1092 if (i>0 && i<chain_length-1) { | |
1093 aa=ab=bb=0.0; | |
1094 adiff[0]=c_alpha[i-1]->x-c_alpha[i]->x; | |
1095 bdiff[0]=c_alpha[i+1]->x-c_alpha[i]->x; | |
1096 aa+=adiff[0]*adiff[0]; | |
1097 ab+=adiff[0]*bdiff[0]; | |
1098 bb+=bdiff[0]*bdiff[0]; | |
1099 adiff[1]=c_alpha[i-1]->y-c_alpha[i]->y; | |
1100 bdiff[1]=c_alpha[i+1]->y-c_alpha[i]->y; | |
1101 aa+=adiff[1]*adiff[1]; | |
1102 ab+=adiff[1]*bdiff[1]; | |
1103 bb+=bdiff[1]*bdiff[1]; | |
1104 adiff[2]=c_alpha[i-1]->z-c_alpha[i]->z; | |
1105 bdiff[2]=c_alpha[i+1]->z-c_alpha[i]->z; | |
1106 aa+=adiff[2]*adiff[2]; | |
1107 ab+=adiff[2]*bdiff[2]; | |
1108 bb+=bdiff[2]*bdiff[2]; | |
1109 | |
1110 th=ab/sqrt(aa*bb); | |
1111 if (th<-1.0) th=-1.0; | |
1112 if (th>1.0) th=1.0; | |
1113 th=acos(th); | |
1114 deg_th=RADDEG*th; | |
1115 if (deg_th>150.) theta0=DEGRAD*150.; else | |
1116 if (deg_th<75.) theta0=DEGRAD*75.; else | |
1117 theta0=th; | |
1118 if (fabs(deg_th-RADDEG*theta0)>1.0) printf("WARNING: angle %d = %.3lf degrees\n", i, deg_th); | |
1119 } | |
1120 #endif | |
1121 } | |
1122 } | |
1123 | |
1124 if (_VERBOSE) printf("Optimization done after %d step(s).\nFinal energy: bond=%.5lf angle=%.5f restraints=%.5f xvol=%.5f total=%.5f\n", numsteps, energies[0], energies[2], energies[1], energies[3], e_pot); | |
1125 | |
1126 if (_CA_TRAJECTORY) { | |
1127 out = fopen(tname,"a"); | |
1128 if (out) { | |
1129 fprintf(out,"END\n"); | |
1130 } | |
1131 } | |
1132 | |
1133 for (i=0;i<chain_length+1;i++) { | |
1134 free(init_c_alpha[i]); | |
1135 free(new_c_alpha[i]); | |
1136 free(gradient[i]); | |
1137 } | |
1138 free(new_c_alpha); | |
1139 free(gradient); | |
1140 free(c_alpha); | |
1141 free(init_c_alpha); | |
1142 } | |
1143 | |
1144 void center_chain(mol_type *mol) | |
1145 { | |
1146 real cx, cy, cz; | |
1147 int natom; | |
1148 res_type *res; | |
1149 atom_type *atom; | |
1150 | |
1151 cx = cy = cz = 0.0; | |
1152 natom = 0; | |
1153 | |
1154 res = mol->residua; | |
1155 while (res) { | |
1156 atom = res->atoms; | |
1157 while (atom) { | |
1158 cx += atom->x; | |
1159 cy += atom->y; | |
1160 cz += atom->z; | |
1161 natom++; | |
1162 atom=atom->next; | |
1163 } | |
1164 res = res->next; | |
1165 } | |
1166 | |
1167 cx /= (real)natom; | |
1168 cy /= (real)natom; | |
1169 cz /= (real)natom; | |
1170 | |
1171 if (_VERBOSE) printf("Molecule center: %8.3f %8.3f %8.3f -> 0.000 0.000 0.000\n", cx, cy, cz); | |
1172 | |
1173 res = mol->residua; | |
1174 while (res) { | |
1175 atom = res->atoms; | |
1176 while (atom) { | |
1177 atom->x -= cx; | |
1178 atom->y -= cy; | |
1179 atom->z -= cz; | |
1180 natom++; | |
1181 atom=atom->next; | |
1182 } | |
1183 res = res->next; | |
1184 } | |
1185 | |
1186 } | |
1187 | |
1188 void write_pdb(char *name, mol_type *mol) | |
1189 { | |
1190 FILE *out; | |
1191 res_type *res; | |
1192 atom_type *atom; | |
1193 int anum; | |
1194 | |
1195 out = fopen(name,"w"); | |
1196 if (!out) { | |
1197 if (_VERBOSE) printf("Can't open output file!\n"); | |
1198 return; | |
1199 } | |
1200 fprintf(out,"REMARK 999 REBUILT BY PULCHRA V.%.2f\n", PULCHRA_VERSION); | |
1201 anum=1; | |
1202 res = mol->residua; | |
1203 while (res) { | |
1204 if (res->protein) { | |
1205 if (!_BB_REARRANGE) { | |
1206 atom = res->atoms; | |
1207 while (atom) { | |
1208 if (!(atom->name[0]=='D' && atom->name[1]=='U') && | |
1209 !(atom->name[0]=='S' && atom->name[1]=='C') && | |
1210 !(atom->name[0]=='C' && atom->name[1]=='M') && | |
1211 !(atom->name[0]=='H' && !_REBUILD_H)) | |
1212 fprintf(out, "ATOM %5d %-3s %3s %c%4d %8.3f%8.3f%8.3f\n", | |
1213 anum++, atom->name, res->name, ' ', res->num, | |
1214 atom->x, atom->y, atom->z); | |
1215 atom=atom->next; | |
1216 } | |
1217 } else { | |
1218 atom = res->atoms; | |
1219 while (atom) { | |
1220 if (!(atom->name[0]=='D' && atom->name[1]=='U') && | |
1221 !(atom->name[0]=='S' && atom->name[1]=='C') && | |
1222 !(atom->name[0]=='C' && atom->name[1]==' ') && | |
1223 !(atom->name[0]=='O' && atom->name[1]==' ') && | |
1224 !(atom->name[0]=='C' && atom->name[1]=='M') && | |
1225 !(atom->name[0]=='H' && !_REBUILD_H)) | |
1226 fprintf(out, "ATOM %5d %-3s %3s %c%4d %8.3f%8.3f%8.3f\n", | |
1227 anum++, atom->name, res->name, ' ', res->num, | |
1228 atom->x, atom->y, atom->z); | |
1229 atom=atom->next; | |
1230 } | |
1231 atom = res->atoms; | |
1232 while (atom) { | |
1233 if (((atom->name[0]=='C' && atom->name[1]==' ') || | |
1234 (atom->name[0]=='O' && atom->name[1]==' ')) && | |
1235 !(atom->name[0]=='H' && !_REBUILD_H)) | |
1236 fprintf(out, "ATOM %5d %-3s %3s %c%4d %8.3f%8.3f%8.3f\n", | |
1237 anum++, atom->name, res->name, ' ', res->num, | |
1238 atom->x, atom->y, atom->z); | |
1239 atom=atom->next; | |
1240 } | |
1241 } | |
1242 } | |
1243 res = res->next; | |
1244 } | |
1245 fprintf(out,"TER\nEND\n"); | |
1246 fclose(out); | |
1247 } | |
1248 | |
1249 | |
1250 void write_pdb_sg(char *name, mol_type *mol) | |
1251 { | |
1252 FILE *out; | |
1253 res_type *res; | |
1254 atom_type *atom; | |
1255 int anum; | |
1256 | |
1257 out = fopen(name,"w"); | |
1258 if (!out) { | |
1259 if (_VERBOSE) printf("Can't open output file!\n"); | |
1260 return; | |
1261 } | |
1262 fprintf(out,"REMARK 999 REBUILT BY PULCHRA V.%.2f\n", PULCHRA_VERSION); | |
1263 anum=1; | |
1264 res = mol->residua; | |
1265 while (res) { | |
1266 if (res->protein) { | |
1267 atom = res->atoms; | |
1268 while (atom) { | |
1269 if ((atom->name[0]=='C' && atom->name[1]=='A')) | |
1270 fprintf(out, "ATOM %5d %-3s %3s %c%4d %8.3f%8.3f%8.3f\n", | |
1271 anum++, atom->name, res->name, ' ', res->num, | |
1272 atom->x, atom->y, atom->z); | |
1273 atom=atom->next; | |
1274 } | |
1275 fprintf(out, "ATOM %5d %-3s %3s %c%4d %8.3f%8.3f%8.3f\n", | |
1276 anum++, "CM ", res->name, ' ', res->num, | |
1277 res->cmx, res->cmy, res->cmz); | |
1278 } | |
1279 res = res->next; | |
1280 } | |
1281 fprintf(out,"TER\nEND\n"); | |
1282 fclose(out); | |
1283 } | |
1284 | |
1285 real calc_distance(real x1, real y1, real z1, | |
1286 real x2, real y2, real z2) | |
1287 { | |
1288 real dx,dy,dz; | |
1289 real dist2; | |
1290 | |
1291 dx = (x1) - (x2); | |
1292 dy = (y1) - (y2); | |
1293 dz = (z1) - (z2); | |
1294 if (dx || dy || dz ) { | |
1295 dist2 = dx*dx+dy*dy+dz*dz; | |
1296 return (sqrt(dist2)); | |
1297 } else | |
1298 return 0.0; | |
1299 } | |
1300 | |
1301 real calc_r14(real x1, real y1, real z1, | |
1302 real x2, real y2, real z2, | |
1303 real x3, real y3, real z3, | |
1304 real x4, real y4, real z4) | |
1305 { | |
1306 real r, dx, dy, dz; | |
1307 real vx1, vy1, vz1, vx2, vy2, vz2, vx3, vy3, vz3; | |
1308 real hand; | |
1309 | |
1310 dx = x4-x1; | |
1311 dy = y4-y1; | |
1312 dz = z4-z1; | |
1313 | |
1314 r = sqrt(dx*dx+dy*dy+dz*dz); | |
1315 | |
1316 vx1=x2-x1; | |
1317 vy1=y2-y1; | |
1318 vz1=z2-z1; | |
1319 vx2=x3-x2; | |
1320 vy2=y3-y2; | |
1321 vz2=z3-z2; | |
1322 vx3=x4-x3; | |
1323 vy3=y4-y3; | |
1324 vz3=z4-z3; | |
1325 | |
1326 hand = (vy1*vz2-vy2*vz1)*vx3+ | |
1327 (vz1*vx2-vz2*vx1)*vy3+ | |
1328 (vx1*vy2-vx2*vy1)*vz3; | |
1329 | |
1330 if (hand<0) r=-r; | |
1331 | |
1332 return r; | |
1333 } | |
1334 | |
1335 real superimpose2(real **coords1, real **coords2, int npoints, real **tpoints, int ntpoints) | |
1336 { | |
1337 real mat_s[3][3], mat_a[3][3], mat_b[3][3], mat_g[3][3]; | |
1338 real mat_u[3][3], tmp_mat[3][3]; | |
1339 real val, d, alpha, beta, gamma, x, y, z; | |
1340 real cx1, cy1, cz1, cx2, cy2, cz2, tmpx, tmpy, tmpz; | |
1341 int i, j, k, n; | |
1342 | |
1343 cx1=cy1=cz1=cx2=cy2=cz2=0.; | |
1344 | |
1345 for (i=0; i<npoints; i++) { | |
1346 cx1+=coords1[i][0]; | |
1347 cy1+=coords1[i][1]; | |
1348 cz1+=coords1[i][2]; | |
1349 cx2+=coords2[i][0]; | |
1350 cy2+=coords2[i][1]; | |
1351 cz2+=coords2[i][2]; | |
1352 } | |
1353 | |
1354 cx1/=(real)npoints; | |
1355 cy1/=(real)npoints; | |
1356 cz1/=(real)npoints; | |
1357 | |
1358 cx2/=(real)npoints; | |
1359 cy2/=(real)npoints; | |
1360 cz2/=(real)npoints; | |
1361 | |
1362 for (i=0; i<npoints; i++) { | |
1363 coords1[i][0]-=cx1; | |
1364 coords1[i][1]-=cy1; | |
1365 coords1[i][2]-=cz1; | |
1366 coords2[i][0]-=cx2; | |
1367 coords2[i][1]-=cy2; | |
1368 coords2[i][2]-=cz2; | |
1369 } | |
1370 | |
1371 for (i=0; i<ntpoints; i++) { | |
1372 tpoints[i][0]-=cx2; | |
1373 tpoints[i][1]-=cy2; | |
1374 tpoints[i][2]-=cz2; | |
1375 } | |
1376 | |
1377 for (i=0; i<3; i++) | |
1378 for (j=0; j<3; j++) { | |
1379 if (i==j) | |
1380 mat_s[i][j]=mat_a[i][j]=mat_b[i][j]=mat_g[i][j]=1.0; | |
1381 else | |
1382 mat_s[i][j]=mat_a[i][j]=mat_b[i][j]=mat_g[i][j]=0.0; | |
1383 mat_u[i][j]=0.; | |
1384 } | |
1385 | |
1386 for (n=0; n<npoints; n++) { | |
1387 mat_u[0][0]+=coords1[n][0]*coords2[n][0]; | |
1388 mat_u[0][1]+=coords1[n][0]*coords2[n][1]; | |
1389 mat_u[0][2]+=coords1[n][0]*coords2[n][2]; | |
1390 mat_u[1][0]+=coords1[n][1]*coords2[n][0]; | |
1391 mat_u[1][1]+=coords1[n][1]*coords2[n][1]; | |
1392 mat_u[1][2]+=coords1[n][1]*coords2[n][2]; | |
1393 mat_u[2][0]+=coords1[n][2]*coords2[n][0]; | |
1394 mat_u[2][1]+=coords1[n][2]*coords2[n][1]; | |
1395 mat_u[2][2]+=coords1[n][2]*coords2[n][2]; | |
1396 } | |
1397 | |
1398 for (i=0; i<3; i++) | |
1399 for (j=0; j<3; j++) | |
1400 tmp_mat[i][j]=0.; | |
1401 | |
1402 do { | |
1403 d=mat_u[2][1]-mat_u[1][2]; | |
1404 if (d==0) alpha=0; else alpha=atan(d/(mat_u[1][1]+mat_u[2][2])); | |
1405 if (cos(alpha)*(mat_u[1][1]+mat_u[2][2])+sin(alpha)*(mat_u[2][1]-mat_u[1][2])<0.0) alpha+=M_PI; | |
1406 mat_a[1][1]=mat_a[2][2]=cos(alpha); | |
1407 mat_a[2][1]=sin(alpha); | |
1408 mat_a[1][2]=-mat_a[2][1]; | |
1409 for (i=0; i<3; i++) | |
1410 for (j=0; j<3; j++) | |
1411 for (k=0; k<3; k++) | |
1412 tmp_mat[i][j]+=mat_u[i][k]*mat_a[j][k]; | |
1413 for (i=0; i<3; i++) | |
1414 for (j=0; j<3; j++) { | |
1415 mat_u[i][j]=tmp_mat[i][j]; | |
1416 tmp_mat[i][j]=0.; | |
1417 } | |
1418 for (i=0; i<3; i++) | |
1419 for (j=0; j<3; j++) | |
1420 for (k=0; k<3; k++) | |
1421 tmp_mat[i][j]+=mat_a[i][k]*mat_s[k][j]; | |
1422 for (i=0; i<3; i++) | |
1423 for (j=0; j<3; j++) { | |
1424 mat_s[i][j]=tmp_mat[i][j]; | |
1425 tmp_mat[i][j]=0.; | |
1426 } | |
1427 d=mat_u[0][2]-mat_u[2][0]; | |
1428 if (d==0) beta=0; else beta=atan(d/(mat_u[0][0]+mat_u[2][2])); | |
1429 if (cos(beta)*(mat_u[0][0]+mat_u[2][2])+sin(beta)*(mat_u[0][2]-mat_u[2][0])<0.0) beta+=M_PI; | |
1430 mat_b[0][0]=mat_b[2][2]=cos(beta); | |
1431 mat_b[0][2]=sin(beta); | |
1432 mat_b[2][0]=-mat_b[0][2]; | |
1433 for (i=0; i<3; i++) | |
1434 for (j=0; j<3; j++) | |
1435 for (k=0; k<3; k++) | |
1436 tmp_mat[i][j]+=mat_u[i][k]*mat_b[j][k]; | |
1437 for (i=0; i<3; i++) | |
1438 for (j=0; j<3; j++) { | |
1439 mat_u[i][j]=tmp_mat[i][j]; | |
1440 tmp_mat[i][j]=0.; | |
1441 } | |
1442 for (i=0; i<3; i++) | |
1443 for (j=0; j<3; j++) | |
1444 for (k=0; k<3; k++) | |
1445 tmp_mat[i][j]+=mat_b[i][k]*mat_s[k][j]; | |
1446 for (i=0; i<3; i++) | |
1447 for (j=0; j<3; j++) { | |
1448 mat_s[i][j]=tmp_mat[i][j]; | |
1449 tmp_mat[i][j]=0.; | |
1450 } | |
1451 d=mat_u[1][0]-mat_u[0][1]; | |
1452 if (d==0) gamma=0; else gamma=atan(d/(mat_u[0][0]+mat_u[1][1])); | |
1453 if (cos(gamma)*(mat_u[0][0]+mat_u[1][1])+sin(gamma)*(mat_u[1][0]-mat_u[0][1])<0.0) | |
1454 gamma+=M_PI; | |
1455 mat_g[0][0]=mat_g[1][1]=cos(gamma); | |
1456 mat_g[1][0]=sin(gamma); | |
1457 mat_g[0][1]=-mat_g[1][0]; | |
1458 for (i=0; i<3; i++) | |
1459 for (j=0; j<3; j++) | |
1460 for (k=0; k<3; k++) | |
1461 tmp_mat[i][j]+=mat_u[i][k]*mat_g[j][k]; | |
1462 for (i=0; i<3; i++) | |
1463 for (j=0; j<3; j++) { | |
1464 mat_u[i][j]=tmp_mat[i][j]; | |
1465 tmp_mat[i][j]=0.; | |
1466 } | |
1467 for (i=0; i<3; i++) | |
1468 for (j=0; j<3; j++) | |
1469 for (k=0; k<3; k++) | |
1470 tmp_mat[i][j]+=mat_g[i][k]*mat_s[k][j]; | |
1471 for (i=0; i<3; i++) | |
1472 for (j=0; j<3; j++) { | |
1473 mat_s[i][j]=tmp_mat[i][j]; | |
1474 tmp_mat[i][j]=0.; | |
1475 } | |
1476 val=fabs(alpha)+fabs(beta)+fabs(gamma); | |
1477 } while (val>0.001); | |
1478 | |
1479 val=0.; | |
1480 for (i=0; i<npoints; i++) { | |
1481 x=coords2[i][0]; | |
1482 y=coords2[i][1]; | |
1483 z=coords2[i][2]; | |
1484 tmpx=x*mat_s[0][0]+y*mat_s[0][1]+z*mat_s[0][2]; | |
1485 tmpy=x*mat_s[1][0]+y*mat_s[1][1]+z*mat_s[1][2]; | |
1486 tmpz=x*mat_s[2][0]+y*mat_s[2][1]+z*mat_s[2][2]; | |
1487 x=coords1[i][0]-tmpx; | |
1488 y=coords1[i][1]-tmpy; | |
1489 z=coords1[i][2]-tmpz; | |
1490 val+=x*x+y*y+z*z; | |
1491 } | |
1492 | |
1493 for (i=0; i<ntpoints; i++) { | |
1494 x=tpoints[i][0]; | |
1495 y=tpoints[i][1]; | |
1496 z=tpoints[i][2]; | |
1497 tpoints[i][0]=x*mat_s[0][0]+y*mat_s[0][1]+z*mat_s[0][2]; | |
1498 tpoints[i][1]=x*mat_s[1][0]+y*mat_s[1][1]+z*mat_s[1][2]; | |
1499 tpoints[i][2]=x*mat_s[2][0]+y*mat_s[2][1]+z*mat_s[2][2]; | |
1500 } | |
1501 | |
1502 for (i=0; i<npoints; i++) { | |
1503 coords1[i][0]+=cx1; | |
1504 coords1[i][1]+=cy1; | |
1505 coords1[i][2]+=cz1; | |
1506 coords2[i][0]+=cx2; | |
1507 coords2[i][1]+=cy2; | |
1508 coords2[i][2]+=cz2; | |
1509 } | |
1510 | |
1511 for (i=0; i<ntpoints; i++) { | |
1512 tpoints[i][0]+=cx1; | |
1513 tpoints[i][1]+=cy1; | |
1514 tpoints[i][2]+=cz1; | |
1515 } | |
1516 | |
1517 return sqrt(val/(real)npoints); | |
1518 } | |
1519 | |
1520 | |
1521 atom_type *find_atom(res_type *res, char *aname) | |
1522 { | |
1523 atom_type *atom; | |
1524 | |
1525 atom = res->atoms; | |
1526 while (atom) { | |
1527 if (atom->name[0]==aname[0] && atom->name[1]==aname[1] && atom->name[2]==aname[2]) { | |
1528 return atom; | |
1529 break; | |
1530 } | |
1531 atom = atom->next; | |
1532 } | |
1533 | |
1534 return NULL; | |
1535 } | |
1536 | |
1537 | |
1538 void add_replace(res_type *res, char *aname, real x, real y, real z, int flags) | |
1539 { | |
1540 atom_type *atom, *newatom; | |
1541 | |
1542 atom = res->atoms; | |
1543 while (atom) { | |
1544 if (atom->name[0]==aname[0] && atom->name[1]==aname[1] && atom->name[2]==aname[2]) { | |
1545 atom->x = x; atom->y = y; atom->z = z; | |
1546 atom->flag |= flags; | |
1547 break; | |
1548 } | |
1549 atom = atom->next; | |
1550 } | |
1551 | |
1552 if (!atom) { | |
1553 newatom = (atom_type*)calloc(sizeof(atom_type),1); | |
1554 newatom->x = x; | |
1555 newatom->y = y; | |
1556 newatom->z = z; | |
1557 newatom->flag |= flags; | |
1558 newatom->res = res; | |
1559 newatom->name = (char*)calloc(4,1); | |
1560 strcpy(newatom->name,aname); | |
1561 | |
1562 atom = res->atoms; | |
1563 while (atom) { | |
1564 if (atom->name[0]=='C' && atom->name[1]=='A') | |
1565 break; | |
1566 atom = atom->next; | |
1567 } | |
1568 if (aname[0]=='N' && aname[1]==' ') { | |
1569 newatom->next = res->atoms; | |
1570 res->atoms = newatom; | |
1571 } else { | |
1572 while (atom->next) atom=atom->next; | |
1573 atom->next = newatom; | |
1574 } | |
1575 } | |
1576 } | |
1577 | |
1578 | |
1579 int **RBINS; | |
1580 real **X_COORDS, **C_ALPHA; | |
1581 | |
1582 #ifdef COMPILE_BB | |
1583 | |
1584 void rebuild_backbone(void) | |
1585 { | |
1586 | |
1587 res_type *res, *prevres; | |
1588 atom_type *atom; | |
1589 real **cacoords, **tmpcoords, **tmpstat; | |
1590 real x1, y1, z1; | |
1591 real x2, y2, z2; | |
1592 real x3, y3, z3; | |
1593 real x4, y4, z4; | |
1594 real r13_1, r13_2, r14; | |
1595 real besthit, hit; | |
1596 int bestpos; | |
1597 int i, j, k, l, m, bin13_1, bin13_2, bin14, found, pro; | |
1598 int b13_1, b13_2, b14; | |
1599 real rmsd, total, maxrms; | |
1600 FILE *debug, *out; | |
1601 | |
1602 if (_VERBOSE) printf("Rebuilding backbone...\n"); | |
1603 | |
1604 RBINS = (int**)calloc(sizeof(int*)*(chain_length+1),1); | |
1605 for (i=0;i<chain_length+1;i++) | |
1606 RBINS[i] = (int*)calloc(sizeof(int)*3,1); | |
1607 | |
1608 X_COORDS = (real**)calloc(sizeof(real*)*(chain_length+10),1); | |
1609 for (i=0;i<chain_length+10;i++) | |
1610 X_COORDS[i] = (real*)calloc(sizeof(real)*3,1); | |
1611 | |
1612 i = 5; | |
1613 | |
1614 res = chain->residua; | |
1615 while (res) { | |
1616 atom = res->atoms; | |
1617 while (atom) { | |
1618 if (atom->name[0]=='C' && atom->name[1]=='A') { | |
1619 X_COORDS[i][0] = atom->x; | |
1620 X_COORDS[i][1] = atom->y; | |
1621 X_COORDS[i][2] = atom->z; | |
1622 i++; | |
1623 } | |
1624 atom = atom->next; | |
1625 } | |
1626 res = res->next; | |
1627 } | |
1628 | |
1629 cacoords = (real**)calloc(sizeof(real*)*(8),1); | |
1630 tmpcoords = (real**)calloc(sizeof(real*)*(8),1); | |
1631 tmpstat = (real**)calloc(sizeof(real*)*(8),1); | |
1632 for (i=0;i<8;i++) { | |
1633 cacoords[i] = (real*)calloc(sizeof(real)*3,1);; | |
1634 tmpcoords[i] = (real*)calloc(sizeof(real)*3,1);; | |
1635 tmpstat[i] = (real*)calloc(sizeof(real)*3,1);; | |
1636 } | |
1637 | |
1638 C_ALPHA = &X_COORDS[5]; | |
1639 | |
1640 // rebuild ends... | |
1641 | |
1642 for (i=0,j=0;i<5;i++,j++) | |
1643 for (k=0;k<3;k++) | |
1644 tmpcoords[j][k] = C_ALPHA[i][k]; | |
1645 for (i=2,j=0;i<5;i++,j++) | |
1646 for (k=0;k<3;k++) | |
1647 cacoords[j][k] = C_ALPHA[i][k]; | |
1648 for (i=0,j=0;i<3;i++,j++) | |
1649 for (k=0;k<3;k++) | |
1650 tmpstat[j][k] = C_ALPHA[i][k]; | |
1651 | |
1652 superimpose2(tmpstat,cacoords,3,tmpcoords,5); | |
1653 | |
1654 for (i=-2,j=0;i<0;i++,j++) | |
1655 for (k=0;k<3;k++) | |
1656 C_ALPHA[i][k] = tmpcoords[j][k]; | |
1657 | |
1658 for (i=chain_length-5,j=0;i<chain_length;i++,j++) | |
1659 for (k=0;k<3;k++) | |
1660 tmpcoords[j][k] = C_ALPHA[i][k]; | |
1661 for (i=chain_length-5,j=0;i<chain_length-2;i++,j++) | |
1662 for (k=0;k<3;k++) | |
1663 cacoords[j][k] = C_ALPHA[i][k]; | |
1664 for (i=chain_length-3,j=0;i<chain_length;i++,j++) | |
1665 for (k=0;k<3;k++) | |
1666 tmpstat[j][k] = C_ALPHA[i][k]; | |
1667 | |
1668 superimpose2(tmpstat,cacoords,3,tmpcoords,5); | |
1669 | |
1670 for (i=chain_length-3,j=0;i<chain_length;i++,j++) | |
1671 for (k=0;k<3;k++) | |
1672 C_ALPHA[i+3][k] = tmpcoords[j+3][k]; | |
1673 | |
1674 | |
1675 prevres = NULL; | |
1676 res = chain->residua; | |
1677 | |
1678 | |
1679 total = maxrms = 0.0; | |
1680 | |
1681 for (i=0;i<chain_length+1;i++) { | |
1682 x1 = C_ALPHA[i-2][0]; | |
1683 y1 = C_ALPHA[i-2][1]; | |
1684 z1 = C_ALPHA[i-2][2]; | |
1685 | |
1686 x2 = C_ALPHA[i-1][0]; | |
1687 y2 = C_ALPHA[i-1][1]; | |
1688 z2 = C_ALPHA[i-1][2]; | |
1689 | |
1690 x3 = C_ALPHA[i][0]; | |
1691 y3 = C_ALPHA[i][1]; | |
1692 z3 = C_ALPHA[i][2]; | |
1693 | |
1694 x4 = C_ALPHA[i+1][0]; | |
1695 y4 = C_ALPHA[i+1][1]; | |
1696 z4 = C_ALPHA[i+1][2]; | |
1697 | |
1698 r13_1 = calc_distance(x1, y1, z1, x3, y3, z3); | |
1699 r13_2 = calc_distance(x2, y2, z2, x4, y4, z4); | |
1700 r14 = calc_r14(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4); | |
1701 | |
1702 bin13_1 = (int)((r13_1-4.6)/0.3); | |
1703 bin13_2 = (int)((r13_2-4.6)/0.3); | |
1704 bin14 = (int)((r14+11.)/0.3); | |
1705 | |
1706 if (bin13_1<0) bin13_1=0; | |
1707 if (bin13_2<0) bin13_2=0; | |
1708 if (bin14<0) bin14=0; | |
1709 if (bin13_1>9) bin13_1=9; | |
1710 if (bin13_2>9) bin13_2=9; | |
1711 if (bin14>73) bin14=73; | |
1712 | |
1713 RBINS[i][0] = bin13_1; | |
1714 RBINS[i][1] = bin13_2; | |
1715 RBINS[i][2] = bin14; | |
1716 | |
1717 cacoords[0][0] = x1; | |
1718 cacoords[0][1] = y1; | |
1719 cacoords[0][2] = z1; | |
1720 | |
1721 cacoords[1][0] = x2; | |
1722 cacoords[1][1] = y2; | |
1723 cacoords[1][2] = z2; | |
1724 | |
1725 cacoords[2][0] = x3; | |
1726 cacoords[2][1] = y3; | |
1727 cacoords[2][2] = z3; | |
1728 | |
1729 cacoords[3][0] = x4; | |
1730 cacoords[3][1] = y4; | |
1731 cacoords[3][2] = z4; | |
1732 | |
1733 pro = 0; | |
1734 | |
1735 if (prevres && !strncmp(prevres->name,"PRO",3)) { | |
1736 j=0; | |
1737 besthit=1000.; | |
1738 bestpos=0; | |
1739 do { | |
1740 hit = abs(nco_stat_pro[j].bins[0]-bin13_1)+abs(nco_stat_pro[j].bins[1]-bin13_2)+0.2*abs(nco_stat_pro[j].bins[2]-bin14); | |
1741 if (hit<besthit) { | |
1742 besthit=hit; | |
1743 bestpos=j; | |
1744 } | |
1745 j++; | |
1746 } while (nco_stat_pro[j].bins[0]>=0 && hit>1e-3); | |
1747 for (j=0;j<4;j++) { | |
1748 for (k=0;k<3;k++) { | |
1749 tmpstat[j][k] = nco_stat_pro[bestpos].data[j][k]; | |
1750 } | |
1751 } | |
1752 for (j=0;j<8;j++) { | |
1753 for (k=0;k<3;k++) { | |
1754 tmpcoords[j][k] = nco_stat_pro[bestpos].data[j][k]; | |
1755 } | |
1756 } | |
1757 } else { | |
1758 j=0; | |
1759 besthit=1000.; | |
1760 bestpos=0; | |
1761 do { | |
1762 hit = abs(nco_stat[j].bins[0]-bin13_1)+abs(nco_stat[j].bins[1]-bin13_2)+0.2*abs(nco_stat[j].bins[2]-bin14); | |
1763 if (hit<besthit) { | |
1764 besthit=hit; | |
1765 bestpos=j; | |
1766 } | |
1767 j++; | |
1768 } while (nco_stat[j].bins[0]>=0 && hit>1e-3); | |
1769 for (j=0;j<4;j++) { | |
1770 for (k=0;k<3;k++) { | |
1771 tmpstat[j][k] = nco_stat[bestpos].data[j][k]; | |
1772 } | |
1773 } | |
1774 for (j=0;j<8;j++) { | |
1775 for (k=0;k<3;k++) { | |
1776 tmpcoords[j][k] = nco_stat[bestpos].data[j][k]; | |
1777 } | |
1778 } | |
1779 } | |
1780 | |
1781 rmsd=superimpose2(cacoords, tmpstat, 4, tmpcoords, 8); | |
1782 | |
1783 total += rmsd; | |
1784 if (rmsd>maxrms) maxrms=rmsd; | |
1785 | |
1786 // add-or-replace | |
1787 | |
1788 if (prevres) { | |
1789 add_replace(prevres, "C ", tmpcoords[4][0], tmpcoords[4][1], tmpcoords[4][2], FLAG_BACKBONE); | |
1790 add_replace(prevres, "O ", tmpcoords[5][0], tmpcoords[5][1], tmpcoords[5][2], FLAG_BACKBONE); | |
1791 } | |
1792 | |
1793 if (res) { | |
1794 add_replace(res, "N ", tmpcoords[6][0], tmpcoords[6][1], tmpcoords[6][2], FLAG_BACKBONE); | |
1795 } | |
1796 | |
1797 prevres = res; | |
1798 if (res) | |
1799 res = res->next; | |
1800 } | |
1801 | |
1802 if (_VERBOSE) printf("Backbone rebuilding deviation: average = %.3f, max = %.3f\n", total/(real)chain_length, maxrms); | |
1803 } | |
1804 | |
1805 #endif | |
1806 | |
1807 | |
1808 #ifdef COMPILE_ROT | |
1809 | |
1810 typedef struct _rot_struct { | |
1811 int r13_1, r13_2, r14; | |
1812 int nc; | |
1813 real ***coords; | |
1814 struct _rot_struct *next; | |
1815 } rot_struct; | |
1816 | |
1817 rot_struct *rotamers[20]; | |
1818 | |
1819 /* this is obsolete in a standalone version of PULCHRA */ | |
1820 void read_rotamers(void) | |
1821 { | |
1822 FILE *inp; | |
1823 char buf[1000]; | |
1824 char dum[100]; | |
1825 int aa, i, j, k, l, n; | |
1826 rot_struct *new_rot, *last_rot; | |
1827 real x, y, z; | |
1828 | |
1829 if (_VERBOSE) printf("Reading rotamer library...\n"); | |
1830 | |
1831 inp = fopen("NEWROT","r"); | |
1832 last_rot=NULL; | |
1833 while (!feof(inp)) { | |
1834 if (fgets(buf,1000,inp)==buf) { | |
1835 if (buf[0]=='A') { | |
1836 sscanf(buf,"%s %d", dum, &aa); | |
1837 if (last_rot) last_rot->next = NULL; | |
1838 last_rot = NULL; | |
1839 if (fgets(buf,1000,inp)!=buf) break; | |
1840 } | |
1841 // printf("aa: %d\n", aa); | |
1842 if (aa==20) break; | |
1843 sscanf(buf,"%d %d %d %s %d", &i, &j, &k, dum, &l); | |
1844 new_rot = (rot_struct*)calloc(sizeof(rot_struct),1); | |
1845 // printf("%d %d %d nc: %d\n", i, j, k, l); | |
1846 new_rot->r13_1 = i; | |
1847 new_rot->r13_2 = j; | |
1848 new_rot->r14 = k; | |
1849 new_rot->nc = l; | |
1850 new_rot->next = NULL; | |
1851 new_rot->coords = (real***)calloc(sizeof(real**)*l,1); | |
1852 for (i=0;i<l;i++) { | |
1853 new_rot->coords[i]=(real**)calloc(sizeof(real*)*(nheavy[aa]+1),1); | |
1854 for (j=0;j<(nheavy[aa]+1);j++) { | |
1855 new_rot->coords[i][j]=(real*)calloc(sizeof(real)*3,1); | |
1856 } | |
1857 } | |
1858 for (i=0;i<l;i++) { | |
1859 fgets(buf,1000,inp); | |
1860 for (j=0;j<(nheavy[aa]+1);j++) { | |
1861 fgets(buf,1000,inp); | |
1862 sscanf(buf,"%lf%lf%lf",&x, &y, &z); | |
1863 new_rot->coords[i][j][0]=x; | |
1864 new_rot->coords[i][j][1]=y; | |
1865 new_rot->coords[i][j][2]=z; | |
1866 } | |
1867 if (last_rot) { | |
1868 last_rot->next = new_rot; | |
1869 } else { | |
1870 rotamers[aa] = new_rot; | |
1871 } | |
1872 last_rot = new_rot; | |
1873 } | |
1874 } | |
1875 } | |
1876 fclose(inp); | |
1877 } | |
1878 | |
1879 | |
1880 void cross(real *v1, real *v2, real *v3) | |
1881 { | |
1882 v3[0] = v1[1]*v2[2]-v1[2]*v2[1]; | |
1883 v3[1] = v1[2]*v2[0]-v1[0]*v2[2]; | |
1884 v3[2] = v1[0]*v2[1]-v1[1]*v2[0]; | |
1885 } | |
1886 | |
1887 void norm(real *v) | |
1888 { | |
1889 real d; | |
1890 | |
1891 d = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); | |
1892 v[0] /= d; | |
1893 v[1] /= d; | |
1894 v[2] /= d; | |
1895 } | |
1896 | |
1897 | |
1898 int check_xvol(res_type *res) | |
1899 { | |
1900 res_type *res2; | |
1901 atom_type *atom1, *atom2; | |
1902 real dx, dy, dz, dd; | |
1903 | |
1904 res2 = chain->residua; | |
1905 | |
1906 while (res2) { | |
1907 atom2 = res2->atoms; | |
1908 if (res!=res2) { | |
1909 while (atom2) { | |
1910 atom1 = res->atoms; | |
1911 while (atom1) { | |
1912 if (atom1->flag & FLAG_SIDECHAIN) { | |
1913 dx = atom1->x-atom2->x; | |
1914 dy = atom1->y-atom2->y; | |
1915 dz = atom1->z-atom2->z; | |
1916 dd = dx*dx+dy*dy+dz*dz; | |
1917 if (dd<(1.7*1.7)) { | |
1918 return 1; | |
1919 } | |
1920 } | |
1921 atom1=atom1->next; | |
1922 } | |
1923 atom2=atom2->next; | |
1924 } | |
1925 } | |
1926 res2=res2->next; | |
1927 } | |
1928 | |
1929 return 0; | |
1930 } | |
1931 | |
1932 | |
1933 real ***SORTED_ROTAMERS; | |
1934 | |
1935 void rebuild_sidechains(void) | |
1936 { | |
1937 FILE *out; | |
1938 res_type *res, *prevres, *testres; | |
1939 atom_type *atom, *atom1, *atom2; | |
1940 real **cacoords, **tmpcoords, **tmpstat; | |
1941 real x1, y1, z1; | |
1942 real x2, y2, z2; | |
1943 real x3, y3, z3; | |
1944 real x4, y4, z4; | |
1945 real x5, y5, z5; | |
1946 real r14, r13_1, r13_2; | |
1947 real dx, dy, dz, dd; | |
1948 real hit, besthit; | |
1949 int exvol, bestpos; | |
1950 int i, j, k, l, m, bin13_1, bin13_2, bin14; | |
1951 real rmsd, total; | |
1952 real v1[3], v2a[3], v2b[3], v2[3], v3[3]; | |
1953 int nsc, nca; | |
1954 real cax, cay, caz; | |
1955 real **lsys, **vv, **sc; | |
1956 char scn[12][4]; | |
1957 rot_struct *rot; | |
1958 int ok, last_a, last_b, last_c, last_d, jpos; | |
1959 int jx, jy, jz, jxi, jyi, jzi, b13_1, b13_2, b14, jm; | |
1960 int crot, bestrot, minexvol, totexvol, rtried, pos, cpos; | |
1961 real cmx, cmy, cmz, ddx, ddy, ddz, ddd, bestdd; | |
1962 real sort_rot[100][2]; | |
1963 | |
1964 if (_VERBOSE) printf("Rebuilding side chains...\n"); | |
1965 | |
1966 lsys = (real**)calloc(sizeof(real*)*3,1); | |
1967 vv = (real**)calloc(sizeof(real*)*3,1); | |
1968 sc = (real**)calloc(sizeof(real*)*12,1); | |
1969 for (i=0;i<12;i++) | |
1970 sc[i] = (real*)calloc(sizeof(real)*3,1); | |
1971 for (i=0;i<3;i++) { | |
1972 lsys[i] = (real*)calloc(sizeof(real)*3,1); | |
1973 vv[i] = (real*)calloc(sizeof(real)*3,1); | |
1974 } | |
1975 | |
1976 SORTED_ROTAMERS = (real***)calloc(sizeof(real**)*(chain_length+1),1); | |
1977 for (i=0;i<chain_length+1;i++) { | |
1978 SORTED_ROTAMERS[i] = (real**)calloc(sizeof(real*)*10,1); | |
1979 for (j=0;j<10;j++) { | |
1980 SORTED_ROTAMERS[i][j] = (real*)calloc(sizeof(real)*2,1); | |
1981 } | |
1982 } | |
1983 | |
1984 prevres = NULL; | |
1985 res = chain->residua; | |
1986 totexvol = 0; | |
1987 | |
1988 for (i=0;i<chain_length;i++) { | |
1989 if (!strncmp(res->name,"GLY",3) || !res->protein) { | |
1990 if (res->next) res = res->next; | |
1991 continue; | |
1992 } | |
1993 | |
1994 x1 = C_ALPHA[i-2][0]; | |
1995 y1 = C_ALPHA[i-2][1]; | |
1996 z1 = C_ALPHA[i-2][2]; | |
1997 x2 = C_ALPHA[i-1][0]; | |
1998 y2 = C_ALPHA[i-1][1]; | |
1999 z2 = C_ALPHA[i-1][2]; | |
2000 x3 = C_ALPHA[i][0]; | |
2001 y3 = C_ALPHA[i][1]; | |
2002 z3 = C_ALPHA[i][2]; | |
2003 x4 = C_ALPHA[i+1][0]; | |
2004 y4 = C_ALPHA[i+1][1]; | |
2005 z4 = C_ALPHA[i+1][2]; | |
2006 | |
2007 bin13_1 = RBINS[i][0]; | |
2008 bin13_2 = RBINS[i][1]; | |
2009 bin14 = RBINS[i][2]; | |
2010 | |
2011 v1[0] = x4-x2; | |
2012 v1[1] = y4-y2; | |
2013 v1[2] = z4-z2; | |
2014 | |
2015 v2a[0] = x4-x3; | |
2016 v2a[1] = y4-y3; | |
2017 v2a[2] = z4-z3; | |
2018 | |
2019 v2b[0] = x3-x2; | |
2020 v2b[1] = y3-y2; | |
2021 v2b[2] = z3-z2; | |
2022 | |
2023 cross(v2a, v2b, v2); | |
2024 cross(v1, v2, v3); | |
2025 | |
2026 norm(v1); | |
2027 norm(v2); | |
2028 norm(v3); | |
2029 | |
2030 // gather 10 closest rotamer conformations... | |
2031 | |
2032 for (j=0;j<10;j++) | |
2033 SORTED_ROTAMERS[i][j][0] = 500.; | |
2034 | |
2035 j = 0; | |
2036 besthit = 1000.; | |
2037 bestpos = 0; | |
2038 do { | |
2039 if (rot_stat_idx[j][0]==res->type) { | |
2040 hit = abs(rot_stat_idx[j][1]-bin13_1)+abs(rot_stat_idx[j][2]-bin13_2)+0.2*abs(rot_stat_idx[j][3]-bin14); | |
2041 if (hit<SORTED_ROTAMERS[i][9][0]) { | |
2042 k = 9; | |
2043 while (k>=0 && hit<SORTED_ROTAMERS[i][k][0]) { | |
2044 k--; | |
2045 } | |
2046 k++; | |
2047 // k = hit | |
2048 for (l=9;l>k;l--) { | |
2049 SORTED_ROTAMERS[i][l][0]=SORTED_ROTAMERS[i][l-1][0]; | |
2050 SORTED_ROTAMERS[i][l][1]=SORTED_ROTAMERS[i][l-1][1]; | |
2051 } | |
2052 SORTED_ROTAMERS[i][k][0]=hit; | |
2053 SORTED_ROTAMERS[i][k][1]=j; | |
2054 } | |
2055 } | |
2056 j++; | |
2057 } while (rot_stat_idx[j][0]>=0); | |
2058 | |
2059 | |
2060 besthit = SORTED_ROTAMERS[i][0][0]; | |
2061 bestpos = SORTED_ROTAMERS[i][0][1]; | |
2062 | |
2063 | |
2064 // new rebuild... | |
2065 | |
2066 pos = rot_stat_idx[bestpos][5]; | |
2067 nsc = nheavy[res->type]+1; | |
2068 | |
2069 if (_PDB_SG) { // more than one rotamer - check SC | |
2070 bestdd = 100.; crot = 0; | |
2071 for (l=0;l<2;l++) { // check two closest conformations | |
2072 cpos = SORTED_ROTAMERS[i][l][1]; | |
2073 for (m=0;m<rot_stat_idx[cpos][4];m++) { | |
2074 for (j=0;j<3;j++) { | |
2075 vv[0][j] = v1[j]; vv[1][j] = v2[j]; vv[2][j] = v3[j]; | |
2076 for (k=0;k<3;k++) { | |
2077 if (j==k) lsys[j][k]=1.; else lsys[j][k]=0.; | |
2078 } | |
2079 } | |
2080 pos = rot_stat_idx[cpos][5]+nsc*m; | |
2081 for (j=0;j<nsc;j++) { | |
2082 for (k=0;k<3;k++) { | |
2083 sc[j][k] = rot_stat_coords[pos+j][k]; | |
2084 } | |
2085 } | |
2086 superimpose2(vv,lsys,3,sc,nsc); | |
2087 for (j=0;j<nsc;j++) { | |
2088 sc[j][0] += x3; | |
2089 sc[j][1] += y3; | |
2090 sc[j][2] += z3; | |
2091 } | |
2092 cmx = 0.; cmy = 0.; cmz = 0.; | |
2093 for (j=0;j<nsc;j++) { | |
2094 cmx += sc[j][0]; | |
2095 cmy += sc[j][1]; | |
2096 cmz += sc[j][2]; | |
2097 } | |
2098 cmx /= (real) nsc; | |
2099 cmy /= (real) nsc; | |
2100 cmz /= (real) nsc; | |
2101 ddx = res->cmx-cmx; | |
2102 ddy = res->cmy-cmy; | |
2103 ddz = res->cmz-cmz; | |
2104 ddx *= ddx; | |
2105 ddy *= ddy; | |
2106 ddz *= ddz; | |
2107 ddd = ddx+ddy+ddz; | |
2108 if (ddd<bestdd) { | |
2109 bestdd = ddd; | |
2110 crot = pos; // closest rotamer position | |
2111 } | |
2112 } | |
2113 } | |
2114 pos = crot; | |
2115 } // PDB_SG | |
2116 | |
2117 for (j=0;j<3;j++) { | |
2118 vv[0][j] = v1[j]; vv[1][j] = v2[j]; vv[2][j] = v3[j]; | |
2119 for (k=0;k<3;k++) { | |
2120 if (j==k) lsys[j][k]=1.; else lsys[j][k]=0.; | |
2121 } | |
2122 } | |
2123 | |
2124 for (j=0;j<nsc;j++) { | |
2125 for (k=0;k<3;k++) { | |
2126 sc[j][k] = rot_stat_coords[pos+j][k]; | |
2127 } | |
2128 } | |
2129 | |
2130 superimpose2(vv,lsys,3,sc,nsc); | |
2131 | |
2132 for (j=0;j<nsc;j++) { | |
2133 sc[j][0] += x3; | |
2134 sc[j][1] += y3; | |
2135 sc[j][2] += z3; | |
2136 } | |
2137 | |
2138 for (j=1;j<nsc;j++) { | |
2139 add_replace(res, heavy_atoms[10*res->type+j-1], sc[j][0], sc[j][1], sc[j][2], FLAG_SIDECHAIN); | |
2140 } | |
2141 | |
2142 if (res->next) res = res->next; | |
2143 | |
2144 } // i++, next res | |
2145 | |
2146 for (i=0;i<12;i++) | |
2147 free(sc[i]); | |
2148 for (i=0;i<3;i++) { | |
2149 free(lsys[i]); | |
2150 free(vv[i]); | |
2151 } | |
2152 free(sc); | |
2153 free(lsys); | |
2154 free(vv); | |
2155 } | |
2156 | |
2157 | |
2158 typedef struct _atom_list { | |
2159 atom_type *atom; | |
2160 struct _atom_list *next; | |
2161 } atom_list; | |
2162 | |
2163 int get_conflicts(res_type *res, atom_list ****grid, int xgrid, int ygrid, int zgrid) | |
2164 { | |
2165 atom_list *llist; | |
2166 atom_type *atom, *atom2; | |
2167 int i, j, k, x, y, z; | |
2168 int ii, jj, kk, con, iter, maxcon, merged; | |
2169 real dx, dy, dz, dd; | |
2170 | |
2171 con = 0; | |
2172 atom = res->atoms; | |
2173 while (atom) { | |
2174 i = atom->gx; | |
2175 j = atom->gy; | |
2176 k = atom->gz; | |
2177 for (ii=i-2;ii<=i+2;ii++) | |
2178 for (jj=j-2;jj<=j+2;jj++) | |
2179 for (kk=k-2;kk<=k+2;kk++) { | |
2180 if (ii>=0 && ii<xgrid && jj>=0 && jj<ygrid && kk>=0 && kk<zgrid) { | |
2181 llist = grid[ii][jj][kk]; | |
2182 while (llist) { | |
2183 atom2 = llist->atom; | |
2184 if (atom && atom2 && res && atom2->res) { | |
2185 merged=0; | |
2186 if (res==atom2->res) { // self-xvol | |
2187 if (atom->flag & FLAG_SIDECHAIN && atom2->flag & FLAG_SIDECHAIN) merged=1; | |
2188 if (atom->flag & FLAG_BACKBONE && atom2->flag & FLAG_BACKBONE) merged=1; | |
2189 if (atom->name[0]=='C' && atom->name[1]=='A' && atom2->name[0]=='C' && atom2->name[1]=='B') merged=1; | |
2190 if (atom->name[0]=='C' && atom->name[1]=='B' && atom2->name[0]=='C' && atom2->name[1]=='A') merged=1; | |
2191 if (res->name[0]=='P') { | |
2192 if (atom->name[0]=='C' && atom->name[1]=='D' && atom2->name[0]=='N' && atom2->name[1]==' ') merged=1; | |
2193 if (atom->name[0]=='N' && atom->name[1]==' ' && atom2->name[0]=='C' && atom2->name[1]=='D') merged=1; | |
2194 } | |
2195 | |
2196 if (!merged) { | |
2197 // printf("merged: %s[%d] %s-%s %d %d\n", res->name,res->num,atom->name,atom2->name,atom->flag,atom2->flag); | |
2198 } | |
2199 } else | |
2200 if (res->next==atom2->res || res==atom2->res->next) { | |
2201 if (atom->name[0]=='C' && atom->name[1]==' ' && atom2->name[0]=='N' && atom2->name[1]==' ') merged=1; | |
2202 if (atom->name[0]=='N' && atom->name[1]==' ' && atom2->name[0]=='C' && atom2->name[1]==' ') merged=1; | |
2203 } | |
2204 if (atom->flag & FLAG_BACKBONE && atom2->flag & FLAG_BACKBONE) merged=1; // for now | |
2205 if (atom->flag & FLAG_SCM || atom2->flag & FLAG_SCM) merged=1; // for now | |
2206 if (!merged) { | |
2207 dx = atom->x-atom2->x; | |
2208 dx*=dx; | |
2209 dy = atom->y-atom2->y; | |
2210 dy*=dy; | |
2211 dz = atom->z-atom2->z; | |
2212 dz*=dz; | |
2213 dd = dx+dy+dz; | |
2214 if (dd<_SG_XVOL_DIST*_SG_XVOL_DIST) { | |
2215 con++; | |
2216 } | |
2217 } | |
2218 } | |
2219 llist = llist->next; | |
2220 } | |
2221 } | |
2222 } | |
2223 atom = atom->next; | |
2224 } | |
2225 | |
2226 return con; | |
2227 } | |
2228 | |
2229 int display_conflicts(res_type *res, atom_list ****grid, int xgrid, int ygrid, int zgrid) | |
2230 { | |
2231 atom_list *llist; | |
2232 atom_type *atom, *atom2; | |
2233 int i, j, k, x, y, z; | |
2234 int ii, jj, kk, con, iter, maxcon, merged; | |
2235 real dx, dy, dz, dd; | |
2236 | |
2237 con = 0; | |
2238 atom = res->atoms; | |
2239 while (atom) { | |
2240 i = atom->gx; | |
2241 j = atom->gy; | |
2242 k = atom->gz; | |
2243 for (ii=i-2;ii<=i+2;ii++) | |
2244 for (jj=j-2;jj<=j+2;jj++) | |
2245 for (kk=k-2;kk<=k+2;kk++) { | |
2246 if (ii>=0 && ii<xgrid && jj>=0 && jj<ygrid && kk>=0 && kk<zgrid) { | |
2247 llist = grid[ii][jj][kk]; | |
2248 while (llist) { | |
2249 atom2 = llist->atom; | |
2250 if (atom && atom2 && res && atom2->res) { | |
2251 merged=0; | |
2252 if (res==atom2->res) { // self-xvol | |
2253 if (atom->flag & FLAG_SIDECHAIN && atom2->flag & FLAG_SIDECHAIN) merged=1; | |
2254 if (atom->flag & FLAG_BACKBONE && atom2->flag & FLAG_BACKBONE) merged=1; | |
2255 if (atom->name[0]=='C' && atom->name[1]=='A' && atom2->name[0]=='C' && atom2->name[1]=='B') merged=1; | |
2256 if (atom->name[0]=='C' && atom->name[1]=='B' && atom2->name[0]=='C' && atom2->name[1]=='A') merged=1; | |
2257 if (res->name[0]=='P') { | |
2258 if (atom->name[0]=='C' && atom->name[1]=='D' && atom2->name[0]=='N' && atom2->name[1]==' ') merged=1; | |
2259 if (atom->name[0]=='N' && atom->name[1]==' ' && atom2->name[0]=='C' && atom2->name[1]=='D') merged=1; | |
2260 } | |
2261 if (!merged) { | |
2262 // printf("merged: %s[%d] %s-%s %d %d\n", res->name,res->num,atom->name,atom2->name,atom->flag,atom2->flag); | |
2263 } | |
2264 } else | |
2265 if (res->next==atom2->res || res==atom2->res->next) { | |
2266 if (atom->name[0]=='C' && atom->name[1]==' ' && atom2->name[0]=='N' && atom2->name[1]==' ') merged=1; | |
2267 if (atom->name[0]=='N' && atom->name[1]==' ' && atom2->name[0]=='C' && atom2->name[1]==' ') merged=1; | |
2268 } | |
2269 if (atom->flag & FLAG_BACKBONE && atom2->flag & FLAG_BACKBONE) merged=1; // for now | |
2270 if (atom->flag & FLAG_SCM || atom2->flag & FLAG_SCM) merged=1; // for now | |
2271 if (!merged) { | |
2272 dx = atom->x-atom2->x; | |
2273 dx*=dx; | |
2274 dy = atom->y-atom2->y; | |
2275 dy*=dy; | |
2276 dz = atom->z-atom2->z; | |
2277 dz*=dz; | |
2278 dd = dx+dy+dz; | |
2279 if (dd<1.6*1.6) { | |
2280 printf("STERIC CONFLICT: %s[%d]%s-%s[%d]%s\n", atom->res->name,atom->res->num,atom->name,atom2->res->name,atom2->res->num,atom2->name); | |
2281 con++; | |
2282 } | |
2283 } | |
2284 } | |
2285 llist = llist->next; | |
2286 } | |
2287 } | |
2288 } | |
2289 atom = atom->next; | |
2290 } | |
2291 | |
2292 return con; | |
2293 } | |
2294 | |
2295 | |
2296 void allocate_grid(atom_list *****grid_, int *xgrid_, int *ygrid_, int *zgrid_) | |
2297 { | |
2298 static int xgrid, ygrid, zgrid; | |
2299 static atom_list ****grid = NULL; | |
2300 atom_list *llist, *alist; | |
2301 real min[3], max[3]; | |
2302 res_type *res, *worst; | |
2303 atom_type *atom, *atom2; | |
2304 int i, j, x, y, z; | |
2305 | |
2306 if (!grid && chain->residua && chain->residua->atoms) { | |
2307 res = chain->residua; | |
2308 min[0]=max[0]=res->atoms->x; | |
2309 min[1]=max[1]=res->atoms->y; | |
2310 min[2]=max[2]=res->atoms->z; | |
2311 while (res) { | |
2312 atom = res->atoms; | |
2313 while (atom) { | |
2314 if (atom->x<min[0]) min[0]=atom->x; | |
2315 if (atom->y<min[1]) min[1]=atom->y; | |
2316 if (atom->z<min[2]) min[2]=atom->z; | |
2317 if (atom->x>max[0]) max[0]=atom->x; | |
2318 if (atom->y>max[1]) max[1]=atom->y; | |
2319 if (atom->z>max[2]) max[2]=atom->z; | |
2320 atom = atom->next; | |
2321 } | |
2322 res = res->next; | |
2323 } | |
2324 | |
2325 xgrid = (max[0]-min[0])/GRID_RES; | |
2326 ygrid = (max[1]-min[1])/GRID_RES; | |
2327 zgrid = (max[2]-min[2])/GRID_RES; | |
2328 | |
2329 if (_VERBOSE) printf("Allocating grid (%d %d %d)...\n", xgrid, ygrid, zgrid); | |
2330 | |
2331 grid = (atom_list****)calloc(sizeof(atom_list***)*(xgrid+1),1); | |
2332 for (i=0;i<xgrid+1;i++) { | |
2333 grid[i] = (atom_list***)calloc(sizeof(atom_list**)*(ygrid+1),1); | |
2334 for (j=0;j<ygrid+1;j++) { | |
2335 grid[i][j] = (atom_list**)calloc(sizeof(atom_list*)*(zgrid+1),1); | |
2336 } | |
2337 } | |
2338 | |
2339 res = chain->residua; | |
2340 while (res) { | |
2341 atom = res->atoms; | |
2342 while (atom) { | |
2343 x = xgrid*(atom->x-min[0])/(max[0]-min[0]); | |
2344 y = ygrid*(atom->y-min[1])/(max[1]-min[1]); | |
2345 z = zgrid*(atom->z-min[2])/(max[2]-min[2]); | |
2346 alist = (atom_list*)calloc(sizeof(atom_list),1); | |
2347 alist->atom = atom; | |
2348 atom->gx = x; | |
2349 atom->gy = y; | |
2350 atom->gz = z; | |
2351 if (grid[x][y][z]!=NULL) { | |
2352 llist = grid[x][y][z]; | |
2353 while (llist->next) llist=llist->next; | |
2354 llist->next = alist; | |
2355 } else { | |
2356 grid[x][y][z]=alist; | |
2357 } | |
2358 atom = atom->next; | |
2359 } | |
2360 res = res->next; | |
2361 } | |
2362 } else { | |
2363 if (_VERBOSE) printf("Grid already allocated (%d %d %d)\n", xgrid, ygrid, zgrid); | |
2364 } | |
2365 | |
2366 *grid_ = grid; | |
2367 *xgrid_ = xgrid; | |
2368 *ygrid_ = ygrid; | |
2369 *zgrid_ = zgrid; | |
2370 } | |
2371 | |
2372 void optimize_exvol(void) | |
2373 { | |
2374 real min[3], max[3]; | |
2375 res_type *res, *worst; | |
2376 atom_type *atom, *atom2; | |
2377 int xgrid, ygrid, zgrid; | |
2378 atom_list ****grid, *llist, *alist; | |
2379 int i, j, k, l, m, x, y, z; | |
2380 int ii, jj, kk, con, iter, maxcon, totcon; | |
2381 int cpos, bestpos, pos, con0; | |
2382 real v1[3], v2a[3], v2b[3], v2[3], v3[3]; | |
2383 int nsc, nca; | |
2384 real cax, cay, caz; | |
2385 real **lsys, **vv, **sc; | |
2386 real x1, y1, z1; | |
2387 real x2, y2, z2; | |
2388 real x3, y3, z3; | |
2389 real x4, y4, z4; | |
2390 | |
2391 min[0]=1e5; | |
2392 min[1]=1e5; | |
2393 min[2]=1e5; | |
2394 max[0]=-1e5; | |
2395 max[1]=-1e5; | |
2396 max[2]=-1e5; | |
2397 | |
2398 lsys = (real**)calloc(sizeof(real*)*3,1); | |
2399 vv = (real**)calloc(sizeof(real*)*3,1); | |
2400 sc = (real**)calloc(sizeof(real*)*12,1); | |
2401 for (i=0;i<12;i++) | |
2402 sc[i] = (real*)calloc(sizeof(real)*3,1); | |
2403 for (i=0;i<3;i++) { | |
2404 lsys[i] = (real*)calloc(sizeof(real)*3,1); | |
2405 vv[i] = (real*)calloc(sizeof(real)*3,1); | |
2406 } | |
2407 | |
2408 allocate_grid(&grid, &xgrid, &ygrid, &zgrid); | |
2409 | |
2410 if (_VERBOSE) printf("Finding excluded volume conflicts...\n"); | |
2411 | |
2412 iter = 0; | |
2413 | |
2414 do { | |
2415 //printf("ITER: %d\n", iter); | |
2416 | |
2417 maxcon = 0; | |
2418 totcon=0; | |
2419 | |
2420 res = chain->residua; | |
2421 while (res) { | |
2422 if (res->protein) { | |
2423 con = get_conflicts(res, grid, xgrid, ygrid, zgrid); | |
2424 if (con>0) { | |
2425 totcon+=con; | |
2426 if (con>maxcon) { | |
2427 maxcon = con; | |
2428 worst = res; | |
2429 } | |
2430 } | |
2431 } | |
2432 res = res->next; | |
2433 } | |
2434 | |
2435 if (_VERBOSE && iter==0) { | |
2436 printf("Total number of conflicts: %d\n", totcon); | |
2437 } | |
2438 | |
2439 if (totcon==0) break; | |
2440 | |
2441 if (_VERBOSE && iter==0) { | |
2442 printf("Maximum number of conflicts: %s[%d] : %d\n", worst->name, worst->num, maxcon); | |
2443 } | |
2444 | |
2445 totcon=0; | |
2446 | |
2447 if (maxcon>0) { | |
2448 | |
2449 // try to fix... | |
2450 | |
2451 res = chain->residua; | |
2452 for (i=0;i<chain_length;i++) { | |
2453 if (!strncmp(res->name,"GLY",3) || !res->protein) { | |
2454 if (res->next) res = res->next; | |
2455 continue; | |
2456 } | |
2457 | |
2458 nsc = nheavy[res->type]+1; | |
2459 | |
2460 x1 = C_ALPHA[i-2][0]; | |
2461 y1 = C_ALPHA[i-2][1]; | |
2462 z1 = C_ALPHA[i-2][2]; | |
2463 x2 = C_ALPHA[i-1][0]; | |
2464 y2 = C_ALPHA[i-1][1]; | |
2465 z2 = C_ALPHA[i-1][2]; | |
2466 x3 = C_ALPHA[i][0]; | |
2467 y3 = C_ALPHA[i][1]; | |
2468 z3 = C_ALPHA[i][2]; | |
2469 x4 = C_ALPHA[i+1][0]; | |
2470 y4 = C_ALPHA[i+1][1]; | |
2471 z4 = C_ALPHA[i+1][2]; | |
2472 | |
2473 v1[0] = x4-x2; | |
2474 v1[1] = y4-y2; | |
2475 v1[2] = z4-z2; | |
2476 | |
2477 v2a[0] = x4-x3; | |
2478 v2a[1] = y4-y3; | |
2479 v2a[2] = z4-z3; | |
2480 | |
2481 v2b[0] = x3-x2; | |
2482 v2b[1] = y3-y2; | |
2483 v2b[2] = z3-z2; | |
2484 | |
2485 cross(v2a, v2b, v2); | |
2486 cross(v1, v2, v3); | |
2487 | |
2488 norm(v1); | |
2489 norm(v2); | |
2490 norm(v3); | |
2491 | |
2492 con = get_conflicts(res, grid, xgrid, ygrid, zgrid); | |
2493 | |
2494 if (con>0) { | |
2495 | |
2496 bestpos=0; | |
2497 con0 = 100; | |
2498 for (l=0;l<10;l++) { // check two closest conformations | |
2499 cpos = SORTED_ROTAMERS[i][l][1]; | |
2500 for (m=0;m<rot_stat_idx[cpos][4];m++) { | |
2501 for (j=0;j<3;j++) { | |
2502 vv[0][j] = v1[j]; vv[1][j] = v2[j]; vv[2][j] = v3[j]; | |
2503 for (k=0;k<3;k++) { | |
2504 if (j==k) lsys[j][k]=1.; else lsys[j][k]=0.; | |
2505 } | |
2506 } | |
2507 pos = rot_stat_idx[cpos][5]+nsc*m; | |
2508 for (j=0;j<nsc;j++) { | |
2509 for (k=0;k<3;k++) { | |
2510 sc[j][k] = rot_stat_coords[pos+j][k]; | |
2511 } | |
2512 } | |
2513 superimpose2(vv,lsys,3,sc,nsc); | |
2514 for (j=0;j<nsc;j++) { | |
2515 sc[j][0] += x3; | |
2516 sc[j][1] += y3; | |
2517 sc[j][2] += z3; | |
2518 } | |
2519 for (j=1;j<nsc;j++) { | |
2520 add_replace(res, heavy_atoms[10*res->type+j-1], sc[j][0], sc[j][1], sc[j][2], FLAG_SIDECHAIN); | |
2521 } | |
2522 con = get_conflicts(res, grid, xgrid, ygrid, zgrid); | |
2523 //printf("test: %d\n", con); | |
2524 | |
2525 if (con<con0) { | |
2526 con0 = con; | |
2527 bestpos = pos; | |
2528 } | |
2529 if (con==0) break; | |
2530 } | |
2531 if (con==0) break; | |
2532 } | |
2533 | |
2534 totcon += con0; | |
2535 | |
2536 for (j=0;j<3;j++) { | |
2537 vv[0][j] = v1[j]; vv[1][j] = v2[j]; vv[2][j] = v3[j]; | |
2538 for (k=0;k<3;k++) { | |
2539 if (j==k) lsys[j][k]=1.; else lsys[j][k]=0.; | |
2540 } | |
2541 } | |
2542 pos = bestpos; | |
2543 for (j=0;j<nsc;j++) { | |
2544 for (k=0;k<3;k++) { | |
2545 sc[j][k] = rot_stat_coords[pos+j][k]; | |
2546 } | |
2547 } | |
2548 superimpose2(vv,lsys,3,sc,nsc); | |
2549 for (j=0;j<nsc;j++) { | |
2550 sc[j][0] += x3; | |
2551 sc[j][1] += y3; | |
2552 sc[j][2] += z3; | |
2553 } | |
2554 for (j=1;j<nsc;j++) { | |
2555 add_replace(res, heavy_atoms[10*res->type+j-1], sc[j][0], sc[j][1], sc[j][2], FLAG_SIDECHAIN); | |
2556 } | |
2557 } | |
2558 | |
2559 | |
2560 | |
2561 res=res->next; | |
2562 | |
2563 } // i | |
2564 } | |
2565 | |
2566 iter++; | |
2567 | |
2568 } while (iter<_XVOL_ITER); | |
2569 | |
2570 | |
2571 if (_VERBOSE) { | |
2572 if (totcon>0) | |
2573 printf("WARNING: %d steric conflict(s) are still there.\n", totcon); | |
2574 else | |
2575 printf("All steric conflicts removed.\n"); | |
2576 } | |
2577 | |
2578 for (i=0;i<12;i++) | |
2579 free(sc[i]); | |
2580 for (i=0;i<3;i++) { | |
2581 free(lsys[i]); | |
2582 free(vv[i]); | |
2583 } | |
2584 free(sc); | |
2585 free(lsys); | |
2586 free(vv); | |
2587 | |
2588 | |
2589 } | |
2590 | |
2591 | |
2592 void vcross(real ax,real ay,real az,real bx,real by,real bz,real *cx,real *cy,real *cz) | |
2593 { | |
2594 *cx = ay * bz - by * az; | |
2595 *cy = az * bx - bz * ax; | |
2596 *cz = ax * by - bx * ay; | |
2597 } | |
2598 | |
2599 real vdot(real ax,real ay,real az,real bx,real by,real bz) | |
2600 { | |
2601 return ax*bx+ay*by+az*bz; | |
2602 } | |
2603 | |
2604 real calc_torsion(atom_type *a1, atom_type *a2, atom_type *a3, atom_type *a4) | |
2605 { | |
2606 real v12x, v12y, v12z; | |
2607 real v43x, v43y, v43z; | |
2608 real zx, zy, zz; | |
2609 real px, py, pz; | |
2610 real xx, xy, xz; | |
2611 real yx, yy, yz; | |
2612 real u, v, angle; | |
2613 | |
2614 v12x = a1->x-a2->x; | |
2615 v12y = a1->y-a2->y; | |
2616 v12z = a1->z-a2->z; | |
2617 | |
2618 v43x = a4->x-a3->x; | |
2619 v43y = a4->y-a3->y; | |
2620 v43z = a4->z-a3->z; | |
2621 | |
2622 zx = a2->x-a3->x; | |
2623 zy = a2->y-a3->y; | |
2624 zz = a2->z-a3->z; | |
2625 | |
2626 vcross(zx,zy,zz,v12x,v12y,v12z,&px,&py,&pz); | |
2627 vcross(zx,zy,zz,v43x,v43y,v43z,&xx,&xy,&xz); | |
2628 vcross(zx,zy,zz,xx,xy,xz,&yx,&yy,&yz); | |
2629 | |
2630 u = vdot(xx,xy,xz,xx,xy,xz); | |
2631 v = vdot(yx,yy,yz,yx,yy,yz); | |
2632 | |
2633 angle = 360.; | |
2634 | |
2635 if (u<0. || v<0.) return angle; | |
2636 | |
2637 u = vdot(px,py,pz,xx,xy,xz) / sqrt(u); | |
2638 v = vdot(px,py,pz,yx,yy,yz) / sqrt(v); | |
2639 | |
2640 if (u != 0.0 || v != 0.0) angle = atan2(v, u) * RADDEG; | |
2641 | |
2642 | |
2643 return angle; | |
2644 | |
2645 } | |
2646 | |
2647 | |
2648 // Ca-N-C-Cb angle should be close to 34 deg | |
2649 | |
2650 void chirality_check(void) | |
2651 { | |
2652 int i; | |
2653 atom_type *a_ca, *a_n, *a_c, *a_cb; | |
2654 atom_type *atom; | |
2655 res_type *res; | |
2656 real angle; | |
2657 real nx, ny, nz; | |
2658 real px, py, pz; | |
2659 real qx, qy, qz; | |
2660 real rx, ry, rz; | |
2661 real xx, xy, xz; | |
2662 real yx, yy, yz; | |
2663 real dd, costheta, sintheta; | |
2664 | |
2665 if (_VERBOSE) printf("Checking chirality...\n"); | |
2666 res = chain->residua; | |
2667 while (res) { | |
2668 a_ca = a_n = a_c = a_cb = NULL; | |
2669 a_ca = find_atom(res,"CA "); | |
2670 a_n = find_atom(res,"N "); | |
2671 a_c = find_atom(res,"C "); | |
2672 a_cb = find_atom(res,"CB "); | |
2673 if (a_ca && a_n && a_c && a_cb) { | |
2674 angle = calc_torsion(a_ca, a_n, a_c, a_cb); | |
2675 if (angle<0.) { | |
2676 if (_VERBOSE) printf("WARNING: D-aa detected at %s %3d : %5.2f", res->name, res->num, angle); | |
2677 xx = a_ca->x-a_n->x; | |
2678 xy = a_ca->y-a_n->y; | |
2679 xz = a_ca->z-a_n->z; | |
2680 yx = a_c->x-a_ca->x; | |
2681 yy = a_c->y-a_ca->y; | |
2682 yz = a_c->z-a_ca->z; | |
2683 vcross(xx,xy,xz,yx,yy,yz,&nx,&ny,&nz); | |
2684 dd = sqrt(nx*nx+ny*ny+nz*nz); | |
2685 nx /= dd; | |
2686 ny /= dd; | |
2687 nz /= dd; | |
2688 // nx, ny, nz = reflection plane normal | |
2689 rx = xx-yx; | |
2690 ry = xy-yy; | |
2691 rz = xz-yz; | |
2692 dd = sqrt(rx*rx+ry*ry+rz*rz); | |
2693 rx /= dd; | |
2694 ry /= dd; | |
2695 rz /= dd; | |
2696 costheta = -1.; | |
2697 sintheta = 0.; | |
2698 atom = res->atoms; | |
2699 while (atom) { | |
2700 if (atom->flag & FLAG_SIDECHAIN) { | |
2701 px = atom->x-a_ca->x; | |
2702 py = atom->y-a_ca->y; | |
2703 pz = atom->z-a_ca->z; | |
2704 qx = qy = qz = 0.; | |
2705 qx += (costheta + (1 - costheta) * rx * rx) * px; | |
2706 qx += ((1 - costheta) * rx * ry - rz * sintheta) * py; | |
2707 qx += ((1 - costheta) * rx * rz + ry * sintheta) * pz; | |
2708 qy += ((1 - costheta) * rx * ry + rz * sintheta) * px; | |
2709 qy += (costheta + (1 - costheta) * ry * ry) * py; | |
2710 qy += ((1 - costheta) * ry * rz - rx * sintheta) * pz; | |
2711 qz += ((1 - costheta) * rx * rz - ry * sintheta) * px; | |
2712 qz += ((1 - costheta) * ry * rz + rx * sintheta) * py; | |
2713 qz += (costheta + (1 - costheta) * rz * rz) * pz; | |
2714 qx += a_ca->x; | |
2715 qy += a_ca->y; | |
2716 qz += a_ca->z; | |
2717 atom->x = qx; | |
2718 atom->y = qy; | |
2719 atom->z = qz; | |
2720 } | |
2721 atom = atom->next; | |
2722 } | |
2723 angle = calc_torsion(a_ca, a_n, a_c, a_cb); | |
2724 if (_VERBOSE) printf(", fixed : %5.2f\n", angle); | |
2725 } | |
2726 } | |
2727 res = res->next; | |
2728 } | |
2729 } | |
2730 | |
2731 | |
2732 #endif | |
2733 | |
2734 real hb_energy(res_type *res, atom_list ****grid, int xgrid, int ygrid, int zgrid) | |
2735 { | |
2736 atom_type *atom, *c_atom1, *o_atom1, *n_atom1, *c_atom2, *o_atom2, *n_atom2, *tmp_atom; | |
2737 atom_type h_atom; | |
2738 int i, j, k, ii, jj, kk; | |
2739 atom_list *llist, *alist; | |
2740 real dx, dy, dz, dist, min_dist1, min_dist2; | |
2741 real hx1, hy1, hz1, dd; | |
2742 real dno, dnc, dho, dhc; | |
2743 real ene, Q; | |
2744 | |
2745 ene = 1e3; | |
2746 | |
2747 if (!res || !res->prev) return ene; | |
2748 | |
2749 Q = -27888.0; // DSSP h-bond energy constant | |
2750 | |
2751 c_atom1 = o_atom1 = n_atom1 = NULL; | |
2752 | |
2753 atom = res->prev->atoms; | |
2754 while (atom) { | |
2755 if (atom->name[0]=='C' && atom->name[1]==' ') c_atom1 = atom; | |
2756 if (atom->name[0]=='O' && atom->name[1]==' ') o_atom1 = atom; | |
2757 atom = atom->next; | |
2758 } | |
2759 | |
2760 atom = res->atoms; | |
2761 while (atom) { | |
2762 if (atom->name[0]=='N' && atom->name[1]==' ') { n_atom1 = atom; break; } | |
2763 atom = atom->next; | |
2764 } | |
2765 | |
2766 // first bond | |
2767 | |
2768 min_dist2 = 1e10; | |
2769 o_atom2 = c_atom2 = NULL; | |
2770 if (n_atom1) { | |
2771 i = n_atom1->gx; | |
2772 j = n_atom1->gy; | |
2773 k = n_atom1->gz; | |
2774 for (ii=i-1;ii<=i+1;ii++) { | |
2775 for (jj=j-1;jj<=j+1;jj++) { | |
2776 for (kk=k-1;kk<=k+1;kk++) { | |
2777 if (ii>=0 && ii<xgrid && jj>=0 && jj<ygrid && kk>=0 && kk<=zgrid) { | |
2778 llist = grid[ii][jj][kk]; | |
2779 while (llist) { | |
2780 if (llist->atom->name[0]=='O' && llist->atom->name[1]==' ' && abs(llist->atom->res->locnum-n_atom1->res->locnum)>2) { | |
2781 tmp_atom = llist->atom; | |
2782 dx = n_atom1->x-tmp_atom->x; | |
2783 dy = n_atom1->y-tmp_atom->y; | |
2784 dz = n_atom1->z-tmp_atom->z; | |
2785 dist = dx*dx+dy*dy+dz*dz; | |
2786 if (dist<min_dist2 && dist<25.0) { | |
2787 o_atom2=tmp_atom; | |
2788 min_dist2 = dist; | |
2789 } | |
2790 } | |
2791 llist = llist->next; | |
2792 } | |
2793 } | |
2794 } | |
2795 } | |
2796 } | |
2797 } | |
2798 | |
2799 if (o_atom2) { | |
2800 atom = o_atom2->res->atoms; | |
2801 while (atom) { | |
2802 if (atom->name[0]=='C' && atom->name[1]==' ') { c_atom2 = atom; break; } | |
2803 atom = atom->next; | |
2804 } | |
2805 if (c_atom2) { | |
2806 hx1 = o_atom1->x-c_atom1->x; | |
2807 hy1 = o_atom1->y-c_atom1->y; | |
2808 hz1 = o_atom1->z-c_atom1->z; | |
2809 dd = -1.081f/sqrt(hx1*hx1+hy1*hy1+hz1*hz1); | |
2810 hx1 *= dd; | |
2811 hy1 *= dd; | |
2812 hz1 *= dd; | |
2813 | |
2814 hx1 += n_atom1->x; | |
2815 hy1 += n_atom1->y; | |
2816 hz1 += n_atom1->z; | |
2817 | |
2818 add_replace(n_atom1->res, "H ", hx1, hy1, hz1, FLAG_BACKBONE); | |
2819 | |
2820 // dno | |
2821 dx = n_atom1->x-o_atom2->x; | |
2822 dy = n_atom1->y-o_atom2->y; | |
2823 dz = n_atom1->z-o_atom2->z; | |
2824 dno = sqrt(dx*dx+dy*dy+dz*dz); | |
2825 | |
2826 // dnc | |
2827 dx = n_atom1->x-c_atom2->x; | |
2828 dy = n_atom1->y-c_atom2->y; | |
2829 dz = n_atom1->z-c_atom2->z; | |
2830 dnc = sqrt(dx*dx+dy*dy+dz*dz); | |
2831 | |
2832 // dho | |
2833 dx = hx1-o_atom2->x; | |
2834 dy = hy1-o_atom2->y; | |
2835 dz = hz1-o_atom2->z; | |
2836 dho = sqrt(dx*dx+dy*dy+dz*dz); | |
2837 | |
2838 // dhc | |
2839 dx = hx1-c_atom2->x; | |
2840 dy = hy1-c_atom2->y; | |
2841 dz = hz1-c_atom2->z; | |
2842 dhc = sqrt(dx*dx+dy*dy+dz*dz); | |
2843 | |
2844 if (dho<0.01F || dhc<0.01F || dnc<0.01F || dno<0.01F) { | |
2845 ene = -10.0; | |
2846 } else { | |
2847 ene = 0.001*(Q/dho - Q/dhc + Q/dnc - Q/dno); | |
2848 } | |
2849 } | |
2850 } | |
2851 | |
2852 /****** | |
2853 // second bond | |
2854 | |
2855 min_dist2 = 1e10; | |
2856 n_atom2 = NULL; | |
2857 if (n_atom1) { | |
2858 i = o_atom1->gx; | |
2859 j = o_atom1->gy; | |
2860 k = o_atom1->gz; | |
2861 for (ii=i-1;ii<=i+1;ii++) { | |
2862 for (jj=j-1;jj<=j+1;jj++) { | |
2863 for (kk=k-1;kk<=k+1;kk++) { | |
2864 if (ii>=0 && ii<xgrid && jj>=0 && jj<ygrid && kk>=0 && kk<=zgrid) { | |
2865 llist = grid[ii][jj][kk]; | |
2866 while (llist) { | |
2867 if (llist->atom->name[0]=='N' && llist->atom->name[1]==' ' && (abs(llist->atom->res->locnum-n_atom1->res->locnum)>2)) { | |
2868 tmp_atom = llist->atom; | |
2869 if (tmp_atom->res!=c_atom2->res) { | |
2870 dx = o_atom1->x-tmp_atom->x; | |
2871 dy = o_atom1->y-tmp_atom->y; | |
2872 dz = o_atom1->z-tmp_atom->z; | |
2873 dist = dx*dx+dy*dy+dz*dz; | |
2874 if (dist<min_dist2 && dist<25.0) { | |
2875 n_atom2=tmp_atom; | |
2876 min_dist2 = dist; | |
2877 } | |
2878 } | |
2879 } | |
2880 llist = llist->next; | |
2881 } | |
2882 } | |
2883 } | |
2884 } | |
2885 } | |
2886 } | |
2887 | |
2888 if (n_atom2) { | |
2889 c_atom2 = o_atom2 = NULL; | |
2890 atom = n_atom2->res->atoms; | |
2891 while (atom) { | |
2892 if (atom->name[0]=='C' && atom->name[1]==' ') { c_atom2 = atom; } | |
2893 if (atom->name[0]=='O' && atom->name[1]==' ') { c_atom2 = atom; } | |
2894 atom = atom->next; | |
2895 } | |
2896 | |
2897 if (c_atom2) { | |
2898 hx1 = o_atom1->x-c_atom1->x; | |
2899 hy1 = o_atom1->y-c_atom1->y; | |
2900 hz1 = o_atom1->z-c_atom1->z; | |
2901 dd = -1.081f/sqrt(hx1*hx1+hy1*hy1+hz1*hz1); | |
2902 hx1 *= dd; | |
2903 hy1 *= dd; | |
2904 hz1 *= dd; | |
2905 | |
2906 hx1 += n_atom1->x; | |
2907 hy1 += n_atom1->y; | |
2908 hz1 += n_atom1->z; | |
2909 | |
2910 } | |
2911 *******/ | |
2912 | |
2913 | |
2914 return ene; | |
2915 } | |
2916 | |
2917 // rotates a point around a vector | |
2918 void rot_point_vector(real *x, real *y, real *z, real u, real v, real w, real angle) | |
2919 { | |
2920 real ux, uy, uz, vx, vy, vz, wx, wy, wz, sa, ca; | |
2921 | |
2922 sa = sinf(10.0*M_PI*angle/180.0); | |
2923 ca = cosf(10.0*M_PI*angle/180.0); | |
2924 | |
2925 ux = u**x; | |
2926 uy = u**y; | |
2927 uz = u**z; | |
2928 vx = v**x; | |
2929 vy = v**y; | |
2930 vz = v**z; | |
2931 wx = w**x; | |
2932 wy = w**y; | |
2933 wz = w**z; | |
2934 | |
2935 *x = u*(ux+vy+wz)+(*x*(v*v+w*w)-u*(vy+wz))*ca+(-wy+vz)*sa; | |
2936 *y = v*(ux+vy+wz)+(*y*(u*u+w*w)-v*(ux+wz))*ca+( wx-uz)*sa; | |
2937 *z = w*(ux+vy+wz)+(*z*(u*u+v*v)-w*(ux+vy))*ca+(-vx+uy)*sa; | |
2938 } | |
2939 | |
2940 | |
2941 // rotates a peptide plate | |
2942 | |
2943 void rot_peptide(res_type *res, real angle) | |
2944 { | |
2945 atom_type *atom, *c_atom, *o_atom, *n_atom, *ca_atom1, *ca_atom2; | |
2946 real u, v, w, x, y, z, dd; | |
2947 | |
2948 if (!res || !res->prev) return; | |
2949 | |
2950 c_atom = o_atom = n_atom = ca_atom1 = ca_atom2 = NULL; | |
2951 | |
2952 atom = res->prev->atoms; | |
2953 while (atom) { | |
2954 if (atom->name[0]=='C' && atom->name[1]=='A') ca_atom1 = atom; | |
2955 if (atom->name[0]=='C' && atom->name[1]==' ') c_atom = atom; | |
2956 if (atom->name[0]=='O' && atom->name[1]==' ') o_atom = atom; | |
2957 atom = atom->next; | |
2958 } | |
2959 | |
2960 atom = res->atoms; | |
2961 while (atom) { | |
2962 if (atom->name[0]=='C' && atom->name[1]=='A') ca_atom2 = atom; | |
2963 if (atom->name[0]=='N' && atom->name[1]==' ') n_atom = atom; | |
2964 atom = atom->next; | |
2965 } | |
2966 | |
2967 if (c_atom && o_atom && n_atom && ca_atom1 && ca_atom2) { | |
2968 u = ca_atom2->x-ca_atom1->x; | |
2969 v = ca_atom2->y-ca_atom1->y; | |
2970 w = ca_atom2->z-ca_atom1->z; | |
2971 dd = 1.0f/sqrt(u*u+v*v+w*w); | |
2972 u*=dd; v*=dd; w*=dd; // normalize ca-ca vector | |
2973 x = n_atom->x-ca_atom1->x; | |
2974 y = n_atom->y-ca_atom1->y; | |
2975 z = n_atom->z-ca_atom1->z; | |
2976 rot_point_vector(&x, &y, &z, u, v, w, angle); | |
2977 n_atom->x = x+ca_atom1->x; | |
2978 n_atom->y = y+ca_atom1->y; | |
2979 n_atom->z = z+ca_atom1->z; | |
2980 x = c_atom->x-ca_atom1->x; | |
2981 y = c_atom->y-ca_atom1->y; | |
2982 z = c_atom->z-ca_atom1->z; | |
2983 rot_point_vector(&x, &y, &z, u, v, w, angle); | |
2984 c_atom->x = x+ca_atom1->x; | |
2985 c_atom->y = y+ca_atom1->y; | |
2986 c_atom->z = z+ca_atom1->z; | |
2987 x = o_atom->x-ca_atom1->x; | |
2988 y = o_atom->y-ca_atom1->y; | |
2989 z = o_atom->z-ca_atom1->z; | |
2990 rot_point_vector(&x, &y, &z, u, v, w, angle); | |
2991 o_atom->x = x+ca_atom1->x; | |
2992 o_atom->y = y+ca_atom1->y; | |
2993 o_atom->z = z+ca_atom1->z; | |
2994 } | |
2995 | |
2996 } | |
2997 | |
2998 void optimize_backbone(mol_type *chain) | |
2999 { | |
3000 int xgrid, ygrid, zgrid; | |
3001 atom_list ****grid; | |
3002 atom_type *atom; | |
3003 res_type *res; | |
3004 real ene, min_ene, tot1, tot2; | |
3005 int i, k, best; | |
3006 FILE *out; | |
3007 | |
3008 if (_VERBOSE) printf("Optimizing backbone...\n"); | |
3009 | |
3010 allocate_grid(&grid, &xgrid, &ygrid, &zgrid); | |
3011 | |
3012 tot1 = tot2 = 0.0; | |
3013 | |
3014 res = chain->residua; | |
3015 while (res) { | |
3016 ene = hb_energy(res, grid, xgrid, ygrid, zgrid); | |
3017 if (ene<-0.5) tot1 += ene; | |
3018 res = res->next; | |
3019 } | |
3020 | |
3021 res = chain->residua; | |
3022 while (res) { | |
3023 if (res->type!=7) { | |
3024 ene = hb_energy(res, grid, xgrid, ygrid, zgrid); | |
3025 if (ene<1.0) { // try to optimize | |
3026 min_ene = ene; | |
3027 rot_peptide(res, -1.1); | |
3028 best = 0; | |
3029 for (i=-10;i<10;i++) { | |
3030 rot_peptide(res, 0.1); | |
3031 ene = hb_energy(res, grid, xgrid, ygrid, zgrid); | |
3032 if (ene<min_ene) { | |
3033 best = i; | |
3034 min_ene = ene; | |
3035 } | |
3036 } | |
3037 rot_peptide(res,-0.9); | |
3038 ene = hb_energy(res, grid, xgrid, ygrid, zgrid); | |
3039 if (min_ene<ene) { | |
3040 rot_peptide(res,0.1*best); | |
3041 ene = hb_energy(res, grid, xgrid, ygrid, zgrid); | |
3042 } | |
3043 } | |
3044 } | |
3045 res = res->next; | |
3046 } | |
3047 | |
3048 res = chain->residua; | |
3049 while (res) { | |
3050 ene = hb_energy(res, grid, xgrid, ygrid, zgrid); | |
3051 if (ene<-0.5) tot2 += ene; | |
3052 res = res->next; | |
3053 } | |
3054 | |
3055 if (_VERBOSE) printf("Backbone HB energy: before %g, after: %g, difference: %g\n", tot1, tot2, tot2-tot1); | |
3056 | |
3057 } | |
3058 | |
3059 int main(int argc, char **argv) | |
3060 { | |
3061 int i, j, next; | |
3062 char buf[100]; | |
3063 char *name=NULL, *ini_name=NULL; | |
3064 char *ptr, out_name[1000]; | |
3065 real f; | |
3066 mol_type *mol; | |
3067 struct timeb time0, time1; | |
3068 | |
3069 for (i=1; i<argc; i++) { | |
3070 if (argv[i][0]=='-') { | |
3071 next=0; | |
3072 for (j=1; j<(int)strlen(argv[i]); j++) { | |
3073 switch(argv[i][j]) { | |
3074 case 'v': _VERBOSE=1; break; | |
3075 case 'c': _CA_OPTIMIZE=0; break; | |
3076 case 'e': _BB_REARRANGE=1; break; | |
3077 case 'r': _CA_RANDOM=1; break; | |
3078 case 'z': _CHIRAL=0; break; | |
3079 case 't': _CA_TRAJECTORY=1; break; | |
3080 case 'n': _CENTER_CHAIN=1; break; | |
3081 case 'b': _REBUILD_BB=0; break; | |
3082 case 's': _REBUILD_SC=0; break; | |
3083 case 'i': ini_name = argv[++i]; next=1; break; | |
3084 case 'g': _PDB_SG=1; break; | |
3085 case 'x': _TIME_SEED=1; break; | |
3086 case 'o': _XVOLUME=0; break; | |
3087 case 'h': _REBUILD_H=0; break; | |
3088 case 'q': _BB_OPTIMIZE=1; break; | |
3089 case 'p': _CISPRO=1; break; | |
3090 case 'u': | |
3091 if (sscanf(argv[++i],"%lf",&f)==1) { | |
3092 _CA_START_DIST = f; | |
3093 } | |
3094 next=1; | |
3095 break; | |
3096 default: { | |
3097 printf("Unknown option: %c\n", argv[i][j]); | |
3098 return -1; | |
3099 } | |
3100 } | |
3101 if (next) break; | |
3102 } | |
3103 } else { | |
3104 if (!name) name=argv[i]; | |
3105 } | |
3106 } | |
3107 | |
3108 if (!name) { | |
3109 printf("PULCHRA Protein Chain Restoration Algorithm version %4.2f\n", PULCHRA_VERSION); | |
3110 printf("Usage: %s [options] <pdb_file>\n", argv[0]); | |
3111 printf("The program default input is a PDB file.\n"); | |
3112 printf("Output file <pdb_file.rebuild.pdb> will be created as a result.\n"); | |
3113 printf("Valid options are:\n\n"); | |
3114 printf(" -v : verbose output (default: off)\n"); | |
3115 printf(" -n : center chain (default: off)\n"); | |
3116 printf(" -x : time-seed random number generator (default: off)\n"); | |
3117 printf(" -g : use PDBSG as an input format (CA=C-alpha, SC or CM=side chain c.m.)\n\n"); | |
3118 printf(" -c : skip C-alpha positions optimization (default: on)\n"); | |
3119 printf(" -p : detect cis-prolins (default: off)\n"); | |
3120 printf(" -r : start from a random chain (default: off)\n"); | |
3121 printf(" -i pdbfile : read the initial C-alpha coordinates from a PDB file\n"); | |
3122 printf(" -t : save chain optimization trajectory to file <pdb_file.pdb.trajectory>\n"); | |
3123 printf(" -u value : maximum shift from the restraint coordinates (default: 0.5A)\n\n"); | |
3124 printf(" -e : rearrange backbone atoms (C, O are output after side chain) (default: off)\n"); | |
3125 | |
3126 #ifdef COMPILE_BB | |
3127 printf(" -b : skip backbone reconstruction (default: on)\n"); | |
3128 printf(" -q : optimize backbone hydrogen bonds pattern (default: off)\n"); | |
3129 printf(" -h : outputs hydrogen atoms (default: off)\n"); | |
3130 #endif | |
3131 | |
3132 #ifdef COMPILE_ROT | |
3133 printf(" -s : skip side chains reconstruction (default: on)\n"); | |
3134 printf(" -o : don't attempt to fix excluded volume conflicts (default: on)\n"); | |
3135 printf(" -z : don't check amino acid chirality (default: on)\n"); | |
3136 #endif | |
3137 printf("\n"); | |
3138 return -1; | |
3139 } | |
3140 | |
3141 for (i=0; i<255; i++) /* prepare hash table*/ | |
3142 AA_NUMS[i] = 20; /* dummy aa code */ | |
3143 for (i=0; i<20; i++) | |
3144 AA_NUMS[(int)SHORT_AA_NAMES[i]] = i; | |
3145 | |
3146 setbuf(stdout,0); | |
3147 | |
3148 if (_TIME_SEED) srand(time(NULL)); else srand(1234); | |
3149 | |
3150 if (_VERBOSE) printf("PULCHRA Protein Chain Restoration Algorithm version %4.2f\n", PULCHRA_VERSION); | |
3151 | |
3152 ftime(&time0); | |
3153 | |
3154 chain = new_mol(); | |
3155 | |
3156 if (read_pdb_file(name,chain,"chain")==FILE_NOT_FOUND) { | |
3157 if (_VERBOSE) printf("Can't read the input file!\n"); | |
3158 return -1; | |
3159 } | |
3160 | |
3161 if (_VERBOSE) printf("%d residua read.\n", chain->nres); | |
3162 | |
3163 chain_length = chain->nres; | |
3164 | |
3165 if (_CA_OPTIMIZE) { | |
3166 snprintf(out_name,1000,"%s.tra",name); | |
3167 ca_optimize(out_name, ini_name); | |
3168 } | |
3169 | |
3170 #ifdef COMPILE_BB | |
3171 if (_REBUILD_BB) { | |
3172 rebuild_backbone(); | |
3173 if (_BB_OPTIMIZE) { | |
3174 optimize_backbone(chain); | |
3175 } | |
3176 } | |
3177 #endif | |
3178 | |
3179 #ifdef COMPILE_ROT | |
3180 if (_REBUILD_BB && _REBUILD_SC) { | |
3181 rebuild_sidechains(); | |
3182 if (_XVOLUME) | |
3183 optimize_exvol(); | |
3184 if (_CHIRAL) | |
3185 chirality_check(); | |
3186 } | |
3187 #endif | |
3188 | |
3189 if (_CENTER_CHAIN) { | |
3190 center_chain(chain); | |
3191 } | |
3192 | |
3193 | |
3194 if (_BB_REARRANGE) { | |
3195 if (_VERBOSE) printf("Rearranging backbone atoms...\n"); | |
3196 } | |
3197 | |
3198 ptr = strstr(name,".pdb"); | |
3199 if (ptr) ptr[0]=0; | |
3200 | |
3201 snprintf(out_name,1000,"%s.rebuilt.pdb",name); | |
3202 | |
3203 if (_VERBOSE) printf("Writing output file %s...\n", out_name); | |
3204 write_pdb(out_name, chain); | |
3205 | |
3206 ftime(&time1); | |
3207 | |
3208 if (_VERBOSE) printf("Done. Reconstruction finished in %.3f s.\n", (real)0.001*(1000.*(time1.time-time0.time)+(time1.millitm-time0.millitm))); | |
3209 | |
3210 return 0; | |
3211 } | |
3212 |