| Bsoft 2.0.5 Bernard's software package

mol_edit.cpp
Go to the documentation of this file.
1
9 #include "rwmolecule.h"
10 #include "rwatomprop.h"
11 #include "rwresprop.h"
12 #include "mol_transform.h"
13 #include "mol_edit.h"
14 #include "mol_util.h"
15 #include "seq_util.h"
16 #include "linked_list.h"
17 #include "Matrix3.h"
18 #include "random_numbers.h"
19 #include "utilities.h"
20
21 // Declaration of global variables
22 extern int verbose; // Level of output to the screen
23
29 long molgroup_set_atom_types_to_elements(Bmolgroup* molgroup)
30 {
31 long n(0);
32 Bmolecule* mol;
33 Bresidue* res;
34 Batom* atom;
35
36 for ( mol = molgroup->mol; mol; mol = mol->next )
37 for( res = mol->res; res; res = res->next )
38 for ( atom = res->atom; atom; atom = atom->next )
39 strcpy(atom->type, atom->el);
40
41 if ( verbose & VERB_PROCESS )
42 cout << "Atoms renamed : " << n << endl << endl;
43
44 return n;
45 }
46
52 int molgroup_remove_hydrogens(Bmolgroup* molgroup)
53 {
54 long n(0);
55 Bmolecule* mol;
56 Bresidue* res;
57 Batom *atom, *atom2;
58
59 for ( mol = molgroup->mol; mol; mol = mol->next )
60 for( res = mol->res; res; res = res->next )
61 for ( atom = atom2 = res->atom; atom; ) {
62 if ( atom->tnum == 0 ) {
63 if ( atom == atom2 ) {
64 atom2 = res->atom = atom->next;
65 delete atom;
66 atom = atom2;
67 } else {
68 atom2->next = atom->next;
69 delete atom;
70 atom = atom2->next;
71 }
72 n++;
73 } else {
74 atom2 = atom;
75 atom = atom2->next;
76 }
77 }
78
79 if ( verbose & VERB_PROCESS )
80 cout << "Hydrogens removed: " << n << endl << endl;
81
82 return n;
83 }
84
85 bool bond_find(Bmolgroup* molgroup, Batom* atom1, Batom* atom2)
86 {
87 Bbond* bond;
88
89 for ( bond = molgroup->bond; bond; bond = bond->next )
90 if ( bond->atom1 == atom1 && bond->atom2 == atom2 ) return 1;
91
92 return 0;
93 }
94
101 int molgroup_add_disulfides(Bmolgroup* molgroup, double distance)
102 {
103 long n(0);
104 double d;
105 Bmolecule* mol;
106 Bresidue* res;
107 Batom* atom;
108 Latom* alist = NULL;
109 Latom* la = NULL;
110 Latom* la2 = NULL;
111
112 if ( verbose )
113 cout << "Adding disulfide bonds:" << endl;
114
115 for ( mol = molgroup->mol; mol; mol = mol->next ) {
116 for( res = mol->res; res; res = res->next ) if ( strstr(res->type, "CYS") ) {
117 for ( atom = res->atom; atom; atom = atom->next ) if ( strstr(atom->type, "SG" ) ) {
118 la = (Latom *) add_item((char **) &la, sizeof(Latom));
119 if ( !alist ) alist = la;
120 la->atom = atom;
121 n++;
122 }
123 }
124 }
125
126 if ( verbose )
127 cout << "Cysteine sulfurs found: " << n << endl;
128
129 for ( n=0, la = alist; la->next; la = la->next ) {
130 for ( la2 = la->next; la2; la2 = la2->next ) {
131 d = la->atom->coord.distance(la2->atom->coord);
132 if ( d <= distance ) {
133 if ( !bond_find(molgroup, la->atom, la2->atom) ) {
134 bond_add(&molgroup->bond, la->atom, la2->atom, d, 1);
135 if ( verbose )
136 cout << la->atom->num << tab << la2->atom->num << tab << d << endl;
137 n++;
138 }
139 }
140 }
141 }
142
143 kill_list((char *) alist, sizeof(Latom));
144
145 if ( verbose & VERB_PROCESS )
146 cout << "Disulfide bonds created: " << n << endl << endl;
147
148 return n;
149 }
150
158 Bmolgroup** molgroup_split_into_slices(Bmolgroup* molgroup, double slice_thickness, int& nslices)
159 {
160 molgroup_stats(molgroup);
161
162 int i;
163 double min = molgroup->min[2];
164 char molname[20] = "";
165 char restype[20] = "UNK";
166
167 Bmolecule* mol;
168 Bresidue* res;
169 Batom* atom;
170
171 nslices = 1;
172 if ( slice_thickness < molgroup->max[2] - molgroup->min[2] ) {
173 min = slice_thickness*floor(molgroup->min[2]/slice_thickness);
174 nslices = (int) ((molgroup->max[2] - min)/slice_thickness + 1);
175 }
176
177 Bmolgroup** slice_molgroup = new Bmolgroup*[nslices];
178 Bmolecule* slice_mol;
179 Bresidue** slice_res = new Bresidue*[nslices];
180 Batom** slice_atom = new Batom*[nslices];
181
182 for ( i=0; i<nslices; i++ ) {
183 slice_molgroup[i] = NULL;
184 slice_res[i] = NULL;
185 slice_atom[i] = NULL;
186 }
187
188 if ( verbose )
189 cout << "System split into " << nslices << " slices" << endl << endl;
190
191 for ( i=0; i<nslices; i++ ) {
192 snprintf(molname, 20, "%d", i+1);
193 slice_molgroup[i] = molgroup_init();
194 slice_mol = molecule_add(&slice_molgroup[i]->mol, molname);
195 slice_res[i] = residue_add(&slice_mol->res, restype);
196 slice_molgroup[i]->comment += molgroup->comment;
197 }
198
199 for ( mol = molgroup->mol; mol; mol = mol->next ) {
200 for( res = mol->res; res; res = res->next ) {
201 for ( atom = res->atom; atom; atom = atom->next ) {
202 i = (int) ((atom->coord[2] - min)/slice_thickness);
203 if ( i < 0 || i >= nslices ) {
204 error_show("Error in molgroup_split_into_slices", __FILE__, __LINE__);
205 cerr << "Index out of range: " << i << endl;
206 return NULL;
207 }
208 if ( slice_atom[i] )
209 slice_atom[i] = atom_add(&slice_atom[i], atom->type);
210 else
211 slice_atom[i] = atom_add(&slice_res[i]->atom, atom->type);
212 memcpy(slice_atom[i], atom, sizeof(Batom));
213 slice_atom[i]->next = NULL;
214 }
215 }
216 }
217
218 delete[] slice_res;
219 delete[] slice_atom;
220
221 for ( i=0; i<nslices; i++ ) {
222 if ( verbose & VERB_PROCESS )
223 cout << "Slice " << i+1 << ":" << endl;
224 molgroup_stats(slice_molgroup[i]);
225 }
226
227 return slice_molgroup;
228 }
229
244 int molgroup_insert(Bmolgroup* molgroup, Bmolgroup* molinsert, double distance)
245 {
246 if ( distance <= 0 ) distance = 2; // Default
247 if ( distance < 1 ) distance = 1; // Limits on cutoff distance in angstrom
248 if ( distance > 5 ) distance = 5;
249
250 long i;
251 int delete_res, nresdel(0), nmoldel(0);
252 long ii, x, y, z, xx, yy, zz, ix, iy, iz;
253 Vector3<double> sampling(distance, distance, distance);
254 Bmolecule* mol, *prevmol;
255 Bresidue* res, *prevres;
256 Batom* atom;
257 Vector3<double> box = molgroup->box;
258 Vector3<int> gridsize((int) (box[0]/sampling[0] + 0.001),
259 (int) (box[1]/sampling[1] + 0.001), (int) (box[2]/sampling[2] + 0.001));
260 gridsize = gridsize.max(1);
261 for ( i=0; i<3; i++ ) sampling[i] = box[i]/gridsize[i] + 0.001;
262 long gridvol = (long) gridsize.volume();
263
264 if ( verbose )
265 cout << "Inserting a molecule group and deleting overlapping residues" << endl;
266
267 if ( verbose & VERB_PROCESS )
268 cout << "Distance cutoff: " << distance << " A" << endl;
269
270 Latom* latom;
271 Latom** alist = molgroup_atom_mesh_lists(molinsert, gridsize, sampling);
272
273 // Find the atoms under the footprint to be deleted
274 for ( mol = prevmol = molgroup->mol; mol; ) {
275 for( res = prevres = mol->res; res; ) {
276 delete_res = 0;
277 for ( atom = res->atom; atom; atom = atom->next ) {
278 x = (long) ((atom->coord[0] - molgroup->min[0])/sampling[0]);
279 y = (long) ((atom->coord[1] - molgroup->min[1])/sampling[1]);
280 z = (long) ((atom->coord[2] - molgroup->min[2])/sampling[2]);
281 if ( x >=0 && x < gridsize[0] && y >= 0 && y < gridsize[1] && z >= 0 && z < gridsize[2] ) {
282 i = (z*gridsize[1] + y)*gridsize[0] + x;
283 for ( zz=z-1; zz<=z+1; zz++ ) {
284 iz = zz;
285 if ( iz < 0 ) iz += gridsize[2];
286 if ( iz >= gridsize[2]) iz -= gridsize[2];
287 for ( yy=y-1; yy<=y+1; yy++ ) {
288 iy = yy;
289 if ( iy < 0 ) iy += gridsize[1];
290 if ( iy >= gridsize[1] ) iy -= gridsize[1];
291 for ( xx=x-1; xx<=x+1; xx++ ) {
292 ix = xx;
293 if ( ix < 0 ) ix += gridsize[0];
294 if ( ix >= gridsize[0] ) ix -= gridsize[0];
295 ii = (iz*gridsize[1] + iy)*gridsize[0] + ix;
296 for ( latom = alist[ii]; latom; latom = latom->next ) {
297 if ( atom->coord.distance(latom->atom->coord) < distance )
298 delete_res = 1;
299 }
300 }
301 }
302 }
303 }
304 }
305 if ( delete_res ) {
306 if ( verbose & VERB_FULL )
307 cout << "Removing a residue" << endl;
308 if ( res == mol->res ) {
309 mol->res = prevres = res->next;
310 residue_kill(res);
311 res = mol->res;
312 } else {
313 prevres->next = res->next;
314 residue_kill(res);
315 res = prevres->next;
316 }
317 nresdel++;
318 } else {
319 prevres = res;
320 if ( res ) res = res->next;
321 }
322 }
323 if ( !mol->res ) {
324 if ( verbose & VERB_FULL )
325 cout << "Removing a molecule" << endl;
326 if ( molgroup->mol == mol ) {
327 molgroup->mol = prevmol = mol->next;
328 molecule_kill(mol);
329 mol = molgroup->mol;
330 } else {
331 prevmol->next = mol->next;
332 molecule_kill(mol);
333 mol = prevmol->next;
334 }
335 nmoldel++;
336 } else {
337 prevmol = mol;
338 if ( mol ) mol = mol->next;
339 }
340 }
341
342 for ( i=0; i<gridvol; i++ ) kill_list((char *) alist[i], sizeof(Latom));
343 delete[] alist;
344
345 if ( verbose & VERB_PROCESS )
346 cout << "Molecules and residues deleted: " << nmoldel << " " << nresdel << endl;
347
348 // Add the new molecules
349 if ( molgroup->mol ) {
350 for ( mol = molgroup->mol; mol->next; mol = mol->next ) ;
351 mol->next = molinsert->mol;
352 } else molgroup->mol = molinsert->mol;
353 molinsert->mol = NULL;
354
355 if ( verbose & VERB_PROCESS )
356 molgroup_density(molgroup) ;
357
358 molgroup_stats(molgroup);
359
360 return 0;
361 }
362
369 int molgroup_randomize(Bmolgroup* molgroup, double random_max)
370 {
371 if ( random_max < 1e-30 ) return 0;
372
373 Bmolecule* mol;
374 Bresidue* res;
375 Batom* atom;
376
377 double irm = random_max*2.0/get_rand_max();
378
379 if ( verbose & VERB_PROCESS )
380 cout << "Randomizing coordinates to maximum: " << random_max << " angstrom" << endl << endl;
381
382 for ( mol = molgroup->mol; mol; mol = mol->next ) {
383 for( res = mol->res; res; res = res->next ) {
384 for ( atom = res->atom; atom; atom = atom->next ) {
385 atom->coord[0] += irm*random() - random_max;
386 atom->coord[1] += irm*random() - random_max;
387 atom->coord[2] += irm*random() - random_max;
388 }
389 }
390 }
391
392 return 0;
393 }
394
407 int molgroup_remove_overlapping_atoms(Bmolgroup* molgroup, double mindist)
408 {
409 if ( mindist < 0.001 ) return 0;
410
411 int nrem(0);
412 double dist;
413 Bmolecule *mol, *mol2, *mol3;
414 Bresidue *res, *res2, *res3;
415 Batom *atom, *atom2, *atom3;
416
417 if ( verbose & VERB_DEBUG )
418 cout << "DEBUG molgroup_remove_overlapping_atoms: mindist=" << mindist << endl;
419
420 for ( mol = molgroup->mol; mol && mol->next; mol = mol->next ) {
421 for( res = mol->res; res; res = res->next ) {
422 for ( atom = res->atom; atom; atom = atom->next ) {
423 for ( mol2 = mol3 = mol; mol2; mol2 = mol2 ? mol2->next : NULL ) {
424 for( res2 = res3 = mol2->res; res2; res2 = res2 ? res2->next : NULL ) {
425 for ( atom2 = atom3 = res2->atom; atom2; atom2 = atom2 ? atom2->next : NULL ) {
426 if ( atom != atom2 ) {
427 dist = atom->coord.distance(atom2->coord);
428 if ( dist < mindist ) {
429 if ( atom2 == res2->atom ) {
430 res2->atom = atom2->next;
431 delete atom2;
432 atom2 = res2->atom;
433 } else {
434 atom3->next = atom2->next;
435 delete atom2;
436 atom2 = atom3;
437 }
438 nrem++;
439 }
440 }
441 atom3 = atom2;
442 }
443 if ( !res2->atom ) {
444 if ( res2 == mol2->res ) {
445 mol2->res = res2->next;
446 residue_kill(res2);
447 res2 = mol2->res;
448 } else {
449 res3->next = res2->next;
450 residue_kill(res2);
451 res2 = res3;
452 }
453 }
454 res3 = res2;
455 }
456 if ( !mol2->res ) {
457 if ( mol2 == molgroup->mol ) {
458 molgroup->mol = mol2->next;
459 molecule_kill(mol2);
460 mol2 = molgroup->mol;
461 } else {
462 mol3->next = mol2->next;
463 molecule_kill(mol2);
464 mol2 = mol3;
465 }
466 }
467 mol3 = mol2;
468 }
469 }
470 }
471 }
472
473 if ( molgroup->mol == NULL ) {
474 error_show("Error in molgroup_remove_overlapping_atoms: All molecules deleted!", __FILE__, __LINE__);
475 return -1;
476 }
477
478 if ( verbose & VERB_PROCESS )
479 cout << "Overlapping atoms removed: " << nrem << endl << endl;
480
481 molgroup_stats(molgroup);
482
483 return nrem;
484 }
485
496 int molgroup_bond_pseudo_atoms(Bmolgroup* molgroup, int atoms_per_bond, int wrap)
497 {
498 int i;
499 Vector3<double> v;
500 Bresidue* res = residue_add(&molgroup->mol->res, "PSD");
501 Batom* atom;
502 Bbond* bond;
503
504 for ( bond=molgroup->bond; bond; bond=bond->next ) {
505 if ( wrap ) v = vector3_difference_PBC(bond->atom2->coord, bond->atom1->coord, molgroup->box);
506 else v = bond->atom2->coord - bond->atom1->coord;
507 for ( i=1; i<=atoms_per_bond; i++ ) {
508 atom = atom_add(&res->atom, "A");
509 atom->coord = bond->atom1->coord + (v * (i*1.0L/(atoms_per_bond+1)));
510 if ( wrap ) atom->coord = vector3_set_PBC(atom->coord, molgroup->box);
511 }
512 }
513
514 return 0;
515 }
516
517 char* grid_from_molgroup(Bmolgroup* molgroup, Vector3<double> min, double sampling, Vector3<int> size)
518 {
519 Bmolecule* mol;
520 Bresidue* res;
521 Batom* atom;
522 long x, y, z;
523 long i, vol = (long)size.volume();
524
525 char* grid = new char[vol];
526 for ( i=0; i<vol; i++ ) grid[i] = 0;
527
528 for ( mol = molgroup->mol; mol; mol = mol->next ) {
529 for( res = mol->res; res; res = res->next ) {
530 for ( atom = res->atom; atom; atom = atom->next ) {
531 x = (long) ((atom->coord[0] - min[0])/sampling);
532 y = (long) ((atom->coord[1] - min[1])/sampling);
533 z = (long) ((atom->coord[2] - min[2])/sampling);
534 grid[(z*size[1] + y)*size[0] + x] = 1;
535 }
536 }
537 }
538
539 return grid;
540 }
541
542 char* grid_from_molecule(Bmolecule* mol, Vector3<double> min, double sampling, Vector3<int> size)
543 {
544 Bresidue* res;
545 Batom* atom;
546 long x, y, z;
547 long i, vol = (long)size.volume();
548
549 char* grid = new char[vol];
550 for ( i=0; i<vol; i++ ) grid[i] = 0;
551
552 for( res = mol->res; res; res = res->next ) {
553 for ( atom = res->atom; atom; atom = atom->next ) {
554 x = (long) ((atom->coord[0] - min[0])/sampling);
555 y = (long) ((atom->coord[1] - min[1])/sampling);
556 z = (long) ((atom->coord[2] - min[2])/sampling);
557 grid[(z*size[1] + y)*size[0] + x] = 1;
558 }
559 }
560
561 return grid;
562 }
563
569 int molgroup_prune_molecules(Bmolgroup* molgroup)
570 {
571 Bmolecule* mol;
572
573 long i;
574 double sampling = 4;
575 Vector3<int> size;
576 size[0] = (int) (molgroup->box[0]/sampling + 1);
577 size[1] = (int) (molgroup->box[1]/sampling + 1);
578 size[2] = (int) (molgroup->box[2]/sampling + 1);
579 long vol = (long)size.volume();
580
581 char* grid1 = NULL;
582 char* grid = grid_from_molecule(molgroup->mol, molgroup->min, sampling, size);
583 molgroup->mol->sel = 1;
584
585 for ( mol = molgroup->mol->next; mol; mol = mol->next ) {
586 mol->sel = 0;
587 grid1 = grid_from_molecule(mol, molgroup->min, sampling, size);
588 for ( i=0; i<vol; i++ ) {
589 if ( grid1[i] ) {
590 if ( grid[i] ) mol->sel++;
591 else grid[i] = 1;
592 }
593 }
594 delete[] grid1;
595 if ( mol->sel ) mol->sel = 0;
596 else mol->sel = 1;
597 }
598
599 delete[] grid;
600
601 molgroup_delete_deselected_molecules(molgroup);
602
603 return 0;
604 }
605
611 long molgroup_delete_deselected_molecules(Bmolgroup* molgroup)
612 {
613 long nmol(0), ndel(0);
614 Bmolecule* mol, *mol2;
615
616 for ( mol = mol2 = molgroup->mol; mol; ) {
617 if ( mol->sel < 1 ) {
618 if ( verbose & VERB_FULL )
619 cout << "Deleting molecule " << mol->id << endl;
620 if ( mol == molgroup->mol ) {
621 molgroup->mol = mol->next;
622 molecule_kill(mol);
623 mol = mol2 = molgroup->mol;
624 } else {
625 mol2->next = mol->next;
626 molecule_kill(mol);
627 mol = mol2->next;
628 }
629 ndel++;
630 } else {
631 mol2 = mol;
632 mol = mol->next;
633 }
634 nmol++;
635 }
636
637 if ( verbose )
638 cout << "Molecules deleted: " << ndel << " (" << ndel*100.0/nmol << " %)" << endl << endl;
639
640 return ndel;
641 }
642
652 long molgroup_prune_overlapping_atoms(Bmolgroup* molgroup, double mindist)
653 {
654 long i, j, natom, ndel(0);
655
656 Batom** atomarray = atom_get_array(molgroup, &natom);
657
658 for ( i=0; i<natom-1; i++ ) atomarray[i]->sel = 1;
659
660 for ( i=0; i<natom-1; i++ ) if ( atomarray[i]->sel ) {
661 for ( j=i+1; j<natom; j++ ) if ( atomarray[j]->sel ) {
662 if ( atomarray[i]->coord.distance(atomarray[j]->coord) < mindist ) {
663 atomarray[j]->sel = 0;
664 ndel++;
665 }
666 }
667 }
668
669 delete[] atomarray;
670
671 if ( verbose )
672 cout << "Atoms marked for deletion: " << ndel << " (" << ndel*100.0/natom << ")" << endl << endl;
673
674 ndel = molgroup_delete_deselected_atoms(molgroup);
675
676 return natom - ndel;
677 }
678
684 long molgroup_delete_deselected_atoms(Bmolgroup* molgroup)
685 {
686 long natom(0), ndel(0);
687 Bmolecule* mol, *mol2;
688 Bresidue* res, *res2;
689 Batom* atom, *atom2;
690
691 for ( mol = mol2 = molgroup->mol; mol; ) {
692 for( res = res2 = mol->res; res; ) {
693 for ( atom = atom2 = res->atom; atom; ) {
694 if ( atom->sel < 1 ) {
695 if ( verbose & VERB_FULL )
696 cout << "Deleting atom " << atom->num << endl;
697 if ( atom == res->atom ) {
698 res->atom = atom->next;
699 delete atom;
700 atom = atom2 = res->atom;
701 } else {
702 atom2->next = atom->next;
703 delete atom;
704 atom = atom2->next;
705 }
706 ndel++;
707 } else {
708 atom2 = atom;
709 atom = atom->next;
710 }
711 natom++;
712 }
713 if ( !res->atom ) {
714 if ( verbose & VERB_FULL )
715 cout << "Deleting residue " << res->num << endl;
716 if ( res == mol->res ) {
717 mol->res = res->next;
718 residue_kill(res);
719 res = res2 = mol->res;
720 } else {
721 res2->next = res->next;
722 residue_kill(res);
723 res = res2->next;
724 }
725 } else {
726 res2 = res;
727 res = res->next;
728 }
729 }
730 if ( !mol->res ) {
731 if ( verbose & VERB_FULL )
732 cout << "Deleting molecule " << mol->id << endl;
733 if ( mol == molgroup->mol ) {
734 molgroup->mol = mol->next;
735 molecule_kill(mol);
736 mol = mol2 = molgroup->mol;
737 } else {
738 mol2->next = mol->next;
739 molecule_kill(mol);
740 mol = mol2->next;
741 }
742 } else {
743 mol2 = mol;
744 mol = mol->next;
745 }
746 }
747
748 if ( verbose )
749 cout << "Atoms deleted: " << ndel << " (" << ndel*100.0/natom << ")" << endl << endl;
750
751 return ndel;
752 }
753
766 int molgroup_untangle_molecules(Bmolgroup* molgroup, double sampling, double lambda)
767 {
768 Bmolecule *mol, *mol2;
769
770 long iter, i, x, y, z, m, m2, nmol;
771 double d, dmax, all_shift = 1;
772 Vector3<int> size;
773 Vector3<double> com, com2, u, c, v;
774 char *grid, *grid2;
775
776 for ( nmol=0, mol = molgroup->mol; mol; mol = mol->next ) nmol++;
777
778 if ( verbose )
779 cout << "Untangling " << nmol << " molecules" << endl;
780
781 Vector3<double>* F = new Vector3<double>[nmol];
782
783 for ( iter=1; all_shift > 0 && iter < 100; iter++ ) {
784 all_shift = 0;
785 size[0] = (int) (molgroup->box[0]/sampling + 1);
786 size[1] = (int) (molgroup->box[1]/sampling + 1);
787 size[2] = (int) (molgroup->box[2]/sampling + 1);
788 for ( m=0, mol = molgroup->mol; mol->next; mol = mol->next, m++ ) {
789 com = mol_center_of_mass(mol);
790 grid = grid_from_molecule(mol, molgroup->min, sampling, size);
791 for ( m2=m+1, mol2 = mol->next; mol2; mol2 = mol2->next, m2++ ) {
792 com2 = mol_center_of_mass(mol2);
793 grid2 = grid_from_molecule(mol2, molgroup->min, sampling, size);
794 u = com2 - com;
795 u.normalize();
796 c = (com + com2)/2;
797 dmax = 0;
798 for ( i=z=0; z<size[2]; z++ ) {
799 for ( y=0; y<size[1]; y++ ) {
800 for ( x=0; x<size[0]; x++, i++ ) {
801 if ( grid[i] & grid2[i] ) {
802 v = Vector3<double>(x, y, z);
803 v = (v * sampling + molgroup->min - c);
804 d = v.scalar(u);
805 // d = fabs(v.scalar(u));
806 if ( dmax < d ) dmax = d;
807 }
808 }
809 }
810 }
811 delete[] grid2;
812 if ( dmax ) {
813 dmax *= lambda;
814 v = u * dmax;
815 F[m] -= v;
816 F[m2] += v;
817 all_shift += dmax;
818 }
819 }
820 delete[] grid;
821 }
822 for ( m=0, mol = molgroup->mol; mol; mol = mol->next, m++ ) {
823 mol_coor_shift(mol, F[m]);
824 F[m] = 0;
825 }
826 molgroup_stats(molgroup);
827 molgroup->box = molgroup->max - molgroup->min;
828 if ( verbose )
829 cout << iter << tab << all_shift << endl;
830 }
831
832 delete[] F;
833
834 return 0;
835 }
836
849 int molgroup_untangle_groups(Bmolgroup* molgroup, double sampling, double lambda)
850 {
851 Bmolgroup *mg, *mg2;
852
853 long iter, i, x, y, z, m, m2, nmg;
854 double d, dmax, all_shift = 1;
855 Vector3<int> size;
856 Vector3<double> min, max, box, com, com2, u, c, v;
857 char *grid, *grid2;
858
859 for ( nmg=0, mg = molgroup; mg; mg = mg->next ) nmg++;
860
861 if ( verbose ) {
862 cout << "Untangling " << nmg << " molecule groups" << endl;
863 cout << "Sampling: " << sampling << " A" << endl;
864 cout << "Damping factor: " << lambda << endl;
865 }
866
867 Vector3<double>* F = new Vector3<double>[nmg];
868
869 if ( verbose )
870 cout << "Iter\tShift" << endl;
871 for ( iter=1; all_shift > 0 && iter < 100; iter++ ) {
872 all_shift = 0;
873 min = molgroup->min;
874 max = molgroup->max;
875 for ( mg = molgroup; mg; mg = mg->next ) {
876 min = min.min(mg->min);
877 max = max.max(mg->max);
878 }
879 box = max - min;
880 size[0] = (int) (box[0]/sampling + 1);
881 size[1] = (int) (box[1]/sampling + 1);
882 size[2] = (int) (box[2]/sampling + 1);
883 for ( m=0, mg = molgroup; mg->next; mg = mg->next, m++ ) {
884 com = molgroup_center_of_mass(mg);
885 grid = grid_from_molgroup(mg, min, sampling, size);
886 for ( m2=m+1, mg2 = mg->next; mg2; mg2 = mg2->next, m2++ ) {
887 com2 = molgroup_center_of_mass(mg2);
888 grid2 = grid_from_molgroup(mg2, min, sampling, size);
889 u = com2 - com;
890 u.normalize();
891 c = (com + com2)/2;
892 dmax = 0;
893 for ( i=z=0; z<size[2]; z++ ) {
894 for ( y=0; y<size[1]; y++ ) {
895 for ( x=0; x<size[0]; x++, i++ ) {
896 if ( grid[i] & grid2[i] ) {
897 v = Vector3<double>(x, y, z);
898 v = (v * sampling + min - c);
899 d = v.scalar(u);
900 // d = fabs(v.scalar(u));
901 if ( dmax < d ) dmax = d;
902 }
903 }
904 }
905 }
906 delete[] grid2;
907 if ( dmax ) {
908 dmax *= lambda;
909 v = u * dmax;
910 F[m] -= v;
911 F[m2] += v;
912 all_shift += dmax;
913 }
914 }
915 delete[] grid;
916 }
917 for ( m=0, mg = molgroup; mg; mg = mg->next, m++ ) {
918 if ( F[m].length() ) molgroup_coor_shift(mg, F[m]);
919 F[m] = 0;
920 molgroup_stats(mg);
921 mg->box = mg->max - mg->min;
922 }
923 if ( verbose )
924 cout << iter << tab << all_shift << endl;
925 }
926
927 delete[] F;
928
929 return 0;
930 }
molgroup_remove_overlapping_atoms
int molgroup_remove_overlapping_atoms(Bmolgroup *molgroup, double mindist)
Removes overlapping atoms.
Definition: mol_edit.cpp:407
distance
double distance(vector< T1 > &v1, vector< T2 > &v2)
Definition: Vector3.h:536
Bmolecule::id
Bstring id
Definition: rwmolecule.h:110
Bmolgroup::mol
Bmolecule * mol
Definition: rwmolecule.h:189
rwresprop.h
Header file for reading residue property files.
seq_util.h
Header file for sequence utilities.
Latom::next
Latom * next
Definition: mol_util.h:22
Vector3::normalize
double normalize()
Definition: Vector3.h:236
molgroup_atom_mesh_lists
Latom ** molgroup_atom_mesh_lists(Bmolgroup *molgroup, Vector3< int > size, Vector3< double > sampling)
Generates lists of atoms based on a grid.
Definition: mol_util.cpp:882
Latom
Definition: mol_util.h:21
vector3_set_PBC
Vector3< T1 > vector3_set_PBC(Vector3< T1 > coord, Vector3< T2 > box)
Definition: Vector3.h:682
grid_from_molecule
char * grid_from_molecule(Bmolecule *mol, Vector3< double > min, double sampling, Vector3< int > size)
Definition: mol_edit.cpp:542
Latom::atom
Batom * atom
Definition: mol_util.h:23
utilities.h
Header file for general utilities.
mol_coor_shift
int mol_coor_shift(Bmolecule *mol, Vector3< double > shift)
Translates a molecule.
Definition: mol_transform.cpp:56
molecule_kill
int molecule_kill(Bmolecule *mol)
Destroys a molecule.
Definition: rwmolecule.cpp:417
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
Bmolecule::res
Bresidue * res
Definition: rwmolecule.h:122
kill_list
long kill_list(char *list, unsigned long size)
Frees all the items in a linked list.
Definition: linked_list.cpp:214
add_item
char * add_item(char **list, unsigned long size)
Adds an item to a linked list.
Definition: linked_list.cpp:26
molgroup_randomize
int molgroup_randomize(Bmolgroup *molgroup, double random_max)
Applies random displacements to coordinates.
Definition: mol_edit.cpp:369
mol_transform.h
Library routines used for atomic coordinate transformations.
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
Bresidue::type
char type[6]
Definition: rwmolecule.h:53
Vector3::distance
double distance(const Vector3 &v)
Definition: Vector3.h:227
bond_add
Bbond * bond_add(Bbond **bond, Batom *atom1, Batom *atom2, double l, double k)
Adds a bond to a linked list.
Definition: rwmolecule.cpp:269
molgroup_prune_molecules
int molgroup_prune_molecules(Bmolgroup *molgroup)
Deletes overlapping molecules.
Definition: mol_edit.cpp:569
Matrix3.h
3x3 Matrix manipulation functions
residue_add
Bresidue * residue_add(Bresidue **res, const char *type)
Adds a residue to a linked list.
Definition: rwmolecule.cpp:113
Batom::sel
int sel
Definition: rwmolecule.h:34
Bmolgroup::box
Vector3< double > box
Definition: rwmolecule.h:184
molgroup_center_of_mass
Vector3< double > molgroup_center_of_mass(Bmolgroup *molgroup)
Calculates the center of mass of a molecule group.
Definition: mol_util.cpp:307
mol_util.h
Library routines used for atomic coordinates.
Batom::type
char type[8]
Definition: rwmolecule.h:28
Vector3::max
Type max()
Definition: Vector3.h:175
Bbond::atom2
Batom * atom2
Definition: rwmolecule.h:137
molgroup_untangle_groups
int molgroup_untangle_groups(Bmolgroup *molgroup, double sampling, double lambda)
Moves overlapping molecules away from each other.
Definition: mol_edit.cpp:849
verbose
int verbose
Batom::num
int num
Definition: rwmolecule.h:26
molgroup_untangle_molecules
int molgroup_untangle_molecules(Bmolgroup *molgroup, double sampling, double lambda)
Moves overlapping molecules away from each other.
Definition: mol_edit.cpp:766
linked_list.h
Header file for generalized linked list functions.
rwmolecule.h
Header file for reading reflection files.
Bmolgroup
Definition: rwmolecule.h:170
molgroup_stats
long molgroup_stats(Bmolgroup *molgroup, int show)
Calculates the statistics of a molecule group.
Definition: rwmolecule.cpp:1291
Vector3::scalar
double scalar(const Vector3 &v) const
Definition: Vector3.h:247
molgroup_delete_deselected_molecules
long molgroup_delete_deselected_molecules(Bmolgroup *molgroup)
Deletes deselected molecules.
Definition: mol_edit.cpp:611
Bmolgroup::comment
Bstring comment
Definition: rwmolecule.h:175
molgroup_remove_hydrogens
int molgroup_remove_hydrogens(Bmolgroup *molgroup)
Removes all hydrogens from a molecular system.
Definition: mol_edit.cpp:52
rwatomprop.h
Header file for reading atom property files.
molgroup_add_disulfides
int molgroup_add_disulfides(Bmolgroup *molgroup, double distance)
Adds disulfide bonds when sulfur atoms are close to each other.
Definition: mol_edit.cpp:101
length
double length(vector< T > v)
Definition: Vector3.h:528
molgroup_init
Bmolgroup * molgroup_init()
Initializes and allocates a new molecule group.
Definition: rwmolecule.cpp:45
vector3_difference_PBC
Vector3< T1 > vector3_difference_PBC(Vector3< T1 > &v1, Vector3< T1 > &v2, Vector3< T2 > &box)
Definition: Vector3.h:695
Bmolecule::next
Bmolecule * next
Definition: rwmolecule.h:108
molecule_add
Bmolecule * molecule_add(Bmolecule **mol, char *name)
Adds a molecule to a linked list.
Definition: rwmolecule.cpp:76
molgroup_density
double molgroup_density(Bmolgroup *molgroup)
Calculates the number and mass density of a molecular system.
Definition: mol_util.cpp:548
Bmolgroup::max
Vector3< double > max
Definition: rwmolecule.h:183
irm
double irm(1.0L/get_rand_max())
molgroup_prune_overlapping_atoms
long molgroup_prune_overlapping_atoms(Bmolgroup *molgroup, double mindist)
Prunes overlapping atoms based on a distance criterion.
Definition: mol_edit.cpp:652
Bmolgroup::next
Bmolgroup * next
Definition: rwmolecule.h:171
residue_kill
int residue_kill(Bresidue *res)
Destroys a residue.
Definition: rwmolecule.cpp:453
Bresidue::atom
Batom * atom
Definition: rwmolecule.h:54
get_rand_max
long get_rand_max()
Finds the maximum random number for a system.
Definition: random_numbers.cpp:22
Bmolecule
Definition: rwmolecule.h:107
atom_add
Batom * atom_add(Batom **atom, const char *type)
Adds an atom to a linked list.
Definition: rwmolecule.cpp:152
Bmolgroup::bond
Bbond * bond
Definition: rwmolecule.h:190
Bresidue::next
Bresidue * next
Definition: rwmolecule.h:50
Bresidue
Definition: rwmolecule.h:49
random_numbers.h
Header file for functions for creating random images.
Batom
Definition: rwmolecule.h:24
atom_get_array
Batom ** atom_get_array(Bmolgroup *molgroup, long *natom)
Generates an array of pointers to atom structures.
Definition: mol_util.cpp:931
Bbond::atom1
Batom * atom1
Definition: rwmolecule.h:136
Bmolecule::sel
int sel
Definition: rwmolecule.h:120
molgroup_insert
int molgroup_insert(Bmolgroup *molgroup, Bmolgroup *molinsert, double distance)
Inserts one set of molecules into another.
Definition: mol_edit.cpp:244
Vector3< double >
Bresidue::num
int num
Definition: rwmolecule.h:51
Vector3::min
Type min()
Definition: Vector3.h:169
molgroup_coor_shift
int molgroup_coor_shift(Bmolgroup *molgroup, Vector3< double > shift)
Translates a molecule group.
Definition: mol_transform.cpp:28
Batom::coord
Vector3< double > coord
Definition: rwmolecule.h:30
molgroup_delete_deselected_atoms
long molgroup_delete_deselected_atoms(Bmolgroup *molgroup)
Deletes deselected atoms.
Definition: mol_edit.cpp:684
Bbond
Definition: rwmolecule.h:134
Bbond::next
Bbond * next
Definition: rwmolecule.h:135
Batom::el
char el[4]
Definition: rwmolecule.h:27
Bmolgroup::min
Vector3< double > min
Definition: rwmolecule.h:182
molgroup_bond_pseudo_atoms
int molgroup_bond_pseudo_atoms(Bmolgroup *molgroup, int atoms_per_bond, int wrap)
Places pseudo-atoms on bonds.
Definition: mol_edit.cpp:496
Batom::tnum
int tnum
Definition: rwmolecule.h:29
Vector3::volume
double volume()
Definition: Vector3.h:235
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
bond_find
bool bond_find(Bmolgroup *molgroup, Batom *atom1, Batom *atom2)
Definition: mol_edit.cpp:85
mol_center_of_mass
Vector3< double > mol_center_of_mass(Bmolecule *mol)
Calculates the center of mass of a molecule.
Definition: mol_util.cpp:401
molgroup_set_atom_types_to_elements
long molgroup_set_atom_types_to_elements(Bmolgroup *molgroup)
Sets atom types to element names.
Definition: mol_edit.cpp:29
Batom::next
Batom * next
Definition: rwmolecule.h:25
molgroup_split_into_slices
Bmolgroup ** molgroup_split_into_slices(Bmolgroup *molgroup, double slice_thickness, int &nslices)
Splits a set of coordinates into slices with a given thickness.
Definition: mol_edit.cpp:158
mol_edit.h
Library routines used for atomic coordinates.
error_show
int error_show(string message, string file, int line)
Displays the error with file and line reference.
Definition: utilities.cpp:755
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
grid_from_molgroup
char * grid_from_molgroup(Bmolgroup *molgroup, Vector3< double > min, double sampling, Vector3< int > size)
Definition: mol_edit.cpp:517