| Bsoft 2.0.5 Bernard's software package

rwmolecule.cpp
Go to the documentation of this file.
1
9 #include "rwmolecule.h"
10 #include "rwatomprop.h"
11 #include "mol_transform.h"
12 #include "mol_util.h"
13 #include "seq_util.h"
14 #include "linked_list.h"
15 #include "utilities.h"
16
17 #include "rwmol_star.h"
18 #include "rwmol_text.h"
19 #include "rwClustal.h"
20 #include "rwEMBL.h"
21 #include "rwFASTA.h"
22 #include "rwGenBank.h"
23 #include "rwGROMACS.h"
24 #include "rwPDB.h"
25 #include "rwPhylip.h"
26 #include "rwPIR.h"
27 #include "rwWAH.h"
28
29 // Declaration of global variables
30 extern int verbose; // Level of output to the screen
31
32 // Internal function prototypes
33 int molgroup_sequence_check(Bmolgroup* molgroup);
34
45 Bmolgroup* molgroup_init()
46 {
47 Bmolgroup* molgroup = new Bmolgroup;
48 memset(molgroup, 0, sizeof(Bmolgroup));
49
50 if ( !molgroup ) return NULL;
51
52 molgroup->select = "all";
53 molgroup->sel = 1;
54
55 molgroup->spacegroup = 1;
56 molgroup->unitcell = UnitCell(1, 1, 1, M_PI_2, M_PI_2, M_PI_2);
57
58 molgroup->sgstring = "P 1";
59 molgroup->pointgroup = "C1";
60
61 return molgroup;
62 }
63
76 Bmolecule* molecule_add(Bmolecule** mol, char* name)
77 {
78 Bstring thename(name);
79 return molecule_add(mol, thename);
80 }
81
82 Bmolecule* molecule_add(Bmolecule** mol, Bstring& name)
83 {
84 Bmolecule* this_mol = *mol;
85 Bmolecule* new_mol = new Bmolecule;
86 memset(new_mol, 0, sizeof(Bmolecule));
87
88 if ( name.length() ) new_mol->id = name;
89 new_mol->sel = 1;
90
91 if ( !this_mol )
92 *mol = new_mol;
93 else {
94 while ( this_mol->next ) this_mol = this_mol->next;
95 this_mol->next = new_mol;
96 }
97
98 return new_mol;
99 }
100
113 Bresidue* residue_add(Bresidue** res, const char* type)
114 {
115 Bstring thetype(type);
116 return residue_add(res, thetype);
117 }
118
119 Bresidue* residue_add(Bresidue** res, Bstring& type)
120 {
121 Bresidue* this_res = *res;
122 Bresidue* new_res = new Bresidue;
123 memset(new_res, 0, sizeof(Bresidue));
124
125 if ( type.length() ) {
126 if ( type.contains("***") ) strcpy(new_res->type, "UNK");
127 else strncpy(new_res->type, type.c_str(), 6);
128 }
129
130 if ( !this_res )
131 *res = new_res;
132 else {
133 while ( this_res->next ) this_res = this_res->next;
134 this_res->next = new_res;
135 }
136
137 return new_res;
138 }
139
152 Batom* atom_add(Batom** atom, const char* type)
153 {
154 Bstring thetype(type);
155 return atom_add(atom, thetype);
156 }
157
158 Batom* atom_add(Batom** atom, Bstring& type)
159 {
160 Batom* this_atom = *atom;
161 Batom* new_atom = new Batom;
162 memset(new_atom, 0, sizeof(Batom));
163
164 atom_clean_type(new_atom, type.c_str());
165
166 new_atom->q = 1;
167 new_atom->mass = 1;
168 new_atom->sel = 1;
169
170 if ( verbose & VERB_DEBUG )
171 cout << "DEBUG atom_add: type=" << new_atom->type << " el=" << new_atom->el << endl;
172
173 if ( !this_atom )
174 *atom = new_atom;
175 else {
176 while ( this_atom->next ) this_atom = this_atom->next;
177 this_atom->next = new_atom;
178 }
179
180 return new_atom;
181 }
182
188 long residue_count(Bmolgroup* molgroup)
189 {
190 long nres(0);
191 Bmolecule* mol;
192 Bresidue* res;
193
194 for ( mol = molgroup->mol; mol; mol = mol->next )
195 for( res = mol->res; res; res = res->next ) nres++;
196
197 return nres;
198 }
199
205 long atom_count(Bmolgroup* molgroup)
206 {
207 long natom(0);
208 Bmolecule* mol;
209 Bresidue* res;
210 Batom* atom;
211
212 for ( mol = molgroup->mol; mol; mol = mol->next )
213 for( res = mol->res; res; res = res->next )
214 for ( atom = res->atom; atom; atom = atom->next ) natom++;
215
216 return natom;
217 }
218
229 int atom_clean_type(Batom* atom, const char* type)
230 {
231 if ( type ) {
232 while ( isspace(type[0]) ) type++;
233 strncpy(atom->type, type, 8);
234 // while ( type && !isalpha(type[0]) ) type++;
235 if ( isdigit(type[0]) ) {
236 if ( type[1] == 'H' ) atom->el[0] = 'H';
237 else atom->el[0] = 'C';
238 } else if ( isalpha(type[0]) ) {
239 atom->el[0] = toupper(type[0]);
240 if ( isalpha(type[1]) ) {
241 if ( islower(type[1]) ) atom->el[1] = type[1];
242 // Special cases
243 if ( atom->el[0] == 'M' )
244 atom->el[1] = tolower(type[1]);
245 }
246 } else {
247 cout << "Warning: No element assigned for atom " << atom->type << endl;
248 }
249 }
250
251 return 0;
252 }
253
269 Bbond* bond_add(Bbond** bond, Batom* atom1, Batom* atom2, double l, double k)
270 {
271 if ( l < 0.01 ) l = atom1->coord.distance(atom2->coord);
272 if ( k < 1e-10 ) k = 1;
273
274 Bbond* this_bond = *bond;
275 Bbond* new_bond = new Bbond;
276 memset(new_bond, 0, sizeof(Bbond));
277
278 new_bond->atom1 = atom1;
279 new_bond->atom2 = atom2;
280 new_bond->l = l;
281 new_bond->k = k;
282
283 if ( verbose & VERB_DEBUG )
284 cout << "DEBUG bond_add: strength=" << k << endl;
285
286 if ( !this_bond )
287 *bond = new_bond;
288 else {
289 while ( this_bond->next ) this_bond = this_bond->next;
290 this_bond->next = new_bond;
291 }
292
293 return new_bond;
294 }
295
312 Bangle* angle_add(Bangle** angle, Batom* atom1, Batom* atom2, Batom* atom3, double a, double k)
313 {
314 Bangle* this_angle = *angle;
315 Bangle* new_angle = new Bangle;
316 memset(new_angle, 0, sizeof(Bangle));
317
318 Vector3<double> d1 = atom1->coord - atom2->coord;
319 Vector3<double> d2 = atom3->coord - atom2->coord;
320
321 if ( a < 0.1 ) a = d1.angle(d2);
322
323 new_angle->atom1 = atom1;
324 new_angle->atom2 = atom2;
325 new_angle->atom3 = atom3;
326 new_angle->a = a;
327 new_angle->k = k;
328
329 if ( verbose & VERB_DEBUG )
330 cout << "DEBUG angle_add: size=" << a << " strength=" << k << endl;
331
332 if ( !this_angle )
333 *angle = new_angle;
334 else {
335 while ( this_angle->next ) this_angle = this_angle->next;
336 this_angle->next = new_angle;
337 }
338
339 return new_angle;
340 }
341
347 int molgroup_list_kill(Bmolgroup* molgroup)
348 {
349 if ( molgroup == NULL ) return 0;
350
351 if ( verbose & VERB_DEBUG ) {
352 cout << "DEBUG molgroup_list_kill: comment length = " <<
353 molgroup->comment.length() << endl;
354 cout << "DEBUG molgroup_list_kill: maxlen = " << molgroup->maxlen <<
355 " (" << molgroup->maxlen*sizeof(int) << ")" << endl;
356 }
357
358 Bmolgroup* molgroup2;
359
360 for ( ; molgroup; ) {
361 molgroup2 = molgroup->next;
362 molgroup_kill(molgroup);
363 molgroup = molgroup2;
364 }
365
366 return 0;
367 }
368
374 int molgroup_kill(Bmolgroup* molgroup)
375 {
376 if ( molgroup == NULL ) return 0;
377
378 if ( verbose & VERB_DEBUG ) {
379 cout << "DEBUG molgroup_kill: name = " << molgroup->id << endl;
380 cout << "DEBUG molgroup_kill: comment length = " <<
381 molgroup->comment.length() << endl;
382 cout << "DEBUG molgroup_kill: maxlen = " << molgroup->maxlen <<
383 " (" << molgroup->maxlen*sizeof(int) << ")" << endl;
384 }
385
386 Bmolecule *mol, *mol2;
387
388 for ( mol = molgroup->mol; mol; ) {
389 mol2 = mol->next;//cout << mol << " - " << mol2 << endl;
390 molecule_kill(mol);
391 mol = mol2;
392 }
393
394 if ( molgroup->seqflag )
395 delete[] molgroup->seqflag;
396
397 bond_kill(molgroup->bond);
398 angle_kill(molgroup->angle);
399
400 molgroup->id = 0;
401 molgroup->filename = 0;
402 molgroup->comment = 0;
403 molgroup->pointgroup = 0;
404 molgroup->sgstring = 0;
405 molgroup->select = 0;
406
407 delete molgroup;
408
409 return 0;
410 }
411
417 int molecule_kill(Bmolecule* mol)
418 {
419 if ( mol == NULL ) return 0;
420
421 Bresidue *res, *res2;
422
423 if ( verbose & VERB_DEBUG ) {
424 cout << "DEBUG molecule_kill: name = " << mol->id << endl;
425 if ( mol->seq.length() ) cout << "DEBUG molecule_kill: seq length = " <<
426 mol->seq.length() << endl;
427 if ( mol->naseq.length() ) cout << "DEBUG molecule_kill: naseq length = " <<
428 mol->naseq.length() << endl;
429 }
430
431 for ( res = mol->res; res; ) {
432 res2 = res->next;
433 residue_kill(res);
434 res = res2;
435 }
436
437 if ( mol->sec ) kill_list((char *) mol->sec, sizeof(Bsecondary));
438
439 mol->id = 0;
440 mol->seq = 0;
441 mol->naseq = 0;
442
443 delete mol;
444
445 return 0;
446 }
447
453 int residue_kill(Bresidue* res)
454 {
455 if ( res == NULL ) return 0;
456
457 // kill_list((char *) res->atom, sizeof(Batom));
458
459 Batom *atom, *atom2;
460
461 for ( atom = res->atom; atom; ) {
462 atom2 = atom->next;
463 delete atom;
464 atom = atom2;
465 }
466
467 delete res;
468
469 return 0;
470 }
471
480 int bond_kill(Bbond* bond)
481 {
482 Bbond* bond2;
483
484 while ( bond ) {
485 bond2 = bond->next;
486 delete bond;
487 bond = bond2;
488 }
489
490 return 0;
491 }
492
501 int angle_kill(Bangle* angle)
502 {
503 Bangle* angle2;
504
505 while ( angle ) {
506 angle2 = angle->next;
507 delete angle;
508 angle = angle2;
509 }
510
511 return 0;
512 }
513
522 Bmolgroup* molgroup_list_copy(Bmolgroup* molgroup)
523 {
524 Bmolgroup* molgroupcopy = NULL;
525 Bmolgroup* mgc = NULL;
526 Bmolgroup* mgc2 = NULL;
527
528 for ( ; molgroup; molgroup=molgroup->next ) {
529 mgc = molgroup_copy(molgroup);
530 if ( !molgroupcopy ) molgroupcopy = mgc;
531 else mgc2->next = mgc;
532 mgc2 = mgc;
533 }
534
535 return molgroupcopy;
536 }
537
547 Bmolgroup* molgroup_copy(Bmolgroup* molgroup)
548 {
549 Bmolgroup* molgroupcopy = molgroup_init();
550
551 Bmolecule* mol;
552 Bmolecule* molcopy = NULL, *newmol;
553
554 molgroupcopy->next = NULL;
555 molgroupcopy->num = molgroup->num;
556 molgroupcopy->id = molgroup->id;
557 molgroupcopy->filename = molgroup->filename;
558 molgroupcopy->comment = molgroup->comment;
559 molgroupcopy->spacegroup = molgroup->spacegroup;
560 molgroupcopy->pointgroup = molgroup->pointgroup;
561 molgroupcopy->sgstring = molgroup->sgstring;
562 molgroupcopy->unitcell = molgroup->unitcell;
563 molgroupcopy->maxlen = molgroup->maxlen;
564 molgroupcopy->maxnalen = molgroup->maxnalen;
565 molgroupcopy->min = molgroup->min;
566 molgroupcopy->max = molgroup->max;
567 molgroupcopy->box = molgroup->box;
568 molgroupcopy->select = molgroup->select;
569 molgroupcopy->sel = molgroup->sel;
570 molgroupcopy->fom = molgroup->fom;
571
572 if ( molgroup->seqflag ) {
573 molgroupcopy->seqflag = new int[molgroup->maxlen];
574 memcpy(molgroupcopy->seqflag, molgroup->seqflag, molgroup->maxlen*sizeof(int));
575 }
576 molgroupcopy->mol = NULL;
577 molgroupcopy->bond = NULL;
578
579 for ( mol = molgroup->mol; mol; mol = mol->next ) {
580 newmol = molecule_copy(mol);
581 if ( molcopy ) molcopy->next = newmol;
582 else molgroupcopy->mol = newmol;
583 molcopy = newmol;
584 }
585
586 molgroupcopy->bond = molgroup_bond_list_copy(molgroup, molgroupcopy);
587
588 return molgroupcopy;
589 }
590
599 Bmolecule* molecule_copy(Bmolecule* mol)
600 {
601 if ( mol == NULL ) return NULL;
602
603 Bmolecule* new_mol = new Bmolecule;
604 memset(new_mol, 0, sizeof(Bmolecule));
605
606 new_mol->num = mol->num; // Molecule number
607 new_mol->id = mol->id; // Molecule identifier
608 new_mol->nres = mol->nres; // Number of residues
609 new_mol->nbase = mol->nbase; // Number of bases
610 new_mol->first_codon = mol->first_codon; // First amino acid codon in NA sequence
611 new_mol->seq = mol->seq; // Protein sequence
612 new_mol->naseq = mol->naseq; // Nucleic acid sequence
613 new_mol->min = mol->min; // Coordinate minima
614 new_mol->max = mol->max; // Coordinate maxima
615 new_mol->Bmin = mol->Bmin; // B-factor statistics
616 new_mol->Bmax = mol->Bmax;
617 new_mol->Bave = mol->Bave;
618 new_mol->Bstd = mol->Bstd;
619 new_mol->sel = mol->sel; // Selection flag
620 new_mol->fom = mol->fom; // Figure-of-merit
621
622 Bsecondary *sec, *new_sec;
623 Bresidue *res, *new_res;
624 Batom *atom, *new_atom;
625
626 for ( res = mol->res; res; res = res->next ) {
627 new_res = residue_add(&new_mol->res, res->type);
628 new_res->num = res->num; // Residue number
629 strncpy(new_res->insert, res->insert, 2); // Insertion code
630 strncpy(new_res->type, res->type, 6); // Residue type
631 for ( atom = res->atom; atom; atom = atom->next ) {
632 new_atom = atom_add(&new_res->atom, atom->type);
633 memcpy(new_atom, atom, sizeof(Batom));
634 new_atom->next = NULL;
635 }
636 }
637
638 for ( sec = mol->sec; sec; sec = sec->next ) {
639 new_sec = (Bsecondary *) add_item((char **) &new_mol->sec, sizeof(Bsecondary));
640 memcpy(new_sec, sec, sizeof(Bsecondary));
641 new_sec->next = NULL;
642 for ( res=mol->res, new_res=new_mol->res; res; res=res->next, new_res=new_res->next ) {
643 if ( sec->first == res ) new_sec->first = new_res;
644 if ( sec->last == res ) new_sec->last = new_res;
645 }
646 }
647
648 if ( verbose & VERB_DEBUG )
649 cout << "DEBUG molecule_copy: new_mol->id = " << new_mol->id << endl;
650
651 return new_mol;
652 }
653
664 Bmolecule* mol_copy_and_add_to_molgroup(Bmolgroup* molgroup, Bmolecule* mol)
665 {
666 if ( molgroup == NULL ) return NULL;
667 if ( mol == NULL ) return NULL;
668
669 Bmolecule* new_mol = molecule_copy(mol);
670
671 char molid = 'A';
672 char notset(1);
673
674 if ( molgroup->mol ) {
675 for ( mol=molgroup->mol; mol->next; mol=mol->next ) ;
676 mol->next = new_mol;
677 if ( new_mol->id[0] != ' ' ) {
678 molid--;
679 while ( notset ) {
680 notset = 0;
681 molid++;
682 for ( mol=molgroup->mol; mol; mol=mol->next )
683 if ( mol->id[0] == molid ) notset = 1;
684 }
685 if ( molid < 'A' || molid > 'Z' ) molid = 'A';
686 new_mol->id[0] = molid;
687 }
688 } else
689 molgroup->mol = new_mol;
690
691 if ( verbose & VERB_DEBUG )
692 cout << "DEBUG mol_copy_and_add_to_molgroup: new_mol->id = " << new_mol->id << endl;
693
694 return new_mol;
695 }
696
706 Bbond* molgroup_bond_list_copy(Bmolgroup* molgroup, Bmolgroup* molgroupcopy)
707 {
708 long maxid;
709 Bmolecule* mol;
710 Bresidue* res;
711 Batom* atom;
712
713 Bbond* bond;
714 Bbond* bond_copy = NULL;
715 Bangle* angle;
716 Bangle* angle_copy = NULL;
717
718 molgroupcopy->bond = NULL;
719 molgroupcopy->angle = NULL;
720
721 for ( maxid=0, mol = molgroup->mol; mol; mol = mol->next )
722 for( res = mol->res; res; res = res->next )
723 for ( atom = res->atom; atom; atom = atom->next )
724 if ( maxid < atom->num ) maxid = atom->num;
725
726 maxid++;
727
728 Batom** acl = new Batom *[maxid];
729
730 for ( mol=molgroupcopy->mol; mol; mol=mol->next )
731 for( res=mol->res; res; res=res->next )
732 for ( atom=res->atom; atom; atom=atom->next )
733 acl[atom->num] = atom;
734
735 for ( bond = molgroup->bond; bond; bond = bond->next ) {
736 bond_copy = bond_add(&bond_copy, acl[bond->atom1->num],
737 acl[bond->atom2->num], bond->l, bond->k);
738 if ( !molgroupcopy->bond ) molgroupcopy->bond = bond_copy;
739 }
740
741 for ( angle = molgroup->angle; angle; angle = angle->next ) {
742 angle_copy = angle_add(&angle_copy, acl[angle->atom1->num],
743 acl[angle->atom2->num], acl[angle->atom3->num], angle->a, angle->k);
744 if ( !molgroupcopy->angle ) molgroupcopy->angle = angle_copy;
745 }
746
747 delete[] acl;
748
749 return molgroupcopy->bond;
750 }
751
760 int molgroup_from_molgroup_list(Bmolgroup* molgroup)
761 {
762 Bmolgroup* mg = molgroup;
763 Bmolecule* mol = molgroup->mol;
764 Bbond* bond = molgroup->bond;
765 Bangle* angle = molgroup->angle;
766
767 for ( mg = molgroup->next; mg; mg = mg->next ) {
768 if ( mol ) {
769 for ( ; mol->next; mol = mol->next ) ;
770 mol->next = mg->mol;
771 } else {
772 mol = molgroup->mol = mg->mol;
773 }
774 mg->mol = NULL;
775 if ( bond ) {
776 for ( ; bond->next; bond = bond->next ) ;
777 bond->next = mg->bond;
778 } else {
779 bond = molgroup->bond = mg->bond;
780 }
781 mg->bond = NULL;
782 if ( angle ) {
783 for ( ; angle->next; angle = angle->next ) ;
784 angle->next = mg->angle;
785 } else {
786 angle = molgroup->angle = mg->angle;
787 }
788 mg->angle = NULL;
789 }
790 molgroup_list_kill(molgroup->next);
791 molgroup->next = NULL;
792 molgroup_atom_renumber(molgroup, 1);
793
794 return 0;
795 }
796
818 Bmolgroup* read_molecule(const char *filename, const char *atom_select, const char* paramfile)
819 {
820 Bstring thefile(filename);
821 Bstring atomsel(atom_select);
822 Bstring theparam(paramfile);
823 return read_molecule(thefile, atomsel, theparam);
824 }
825
826 Bmolgroup* read_molecule(Bstring& filename, Bstring& atom_select, Bstring& paramfile)
827 {
828 if ( filename.empty() ) {
829 error_show("No molecule filename!", __FILE__, __LINE__);
830 return NULL;
831 }
832
833 Bstring ext = filename.extension();
834
835 if ( verbose & VERB_DEBUG )
836 cout << "DEBUG read_molecule: extension=" << ext << endl;
837
838 Bstring thefile = filename.pre(':');
839
840 if ( thefile.length() < 1 ) {
841 error_show("No molecule file given!", __FILE__, __LINE__);
842 return NULL;
843 }
844
845 long i, n(-1);
846
847 Bmolgroup* molgroup = molgroup_init();
848 molgroup->filename = thefile;
849 molgroup->select = atom_select.upper();
850
851 if ( verbose & VERB_LABEL ) {
852 cout << "Reading file: " << molgroup->filename << endl;
853 cout << "Selecting: " << molgroup->select << endl << endl;
854 }
855
856 // cout << thefile << "\t" << sizeof(Bmolgroup) << endl;
857
858 if ( ext.contains("star") || ext.contains("cif") )
859 n = read_mol_star(thefile, molgroup);
860 else if ( ext.contains("txt") )
861 n = read_mol_text(thefile, molgroup);
862 else if ( ext.contains("aln") )
863 n = readClustal(thefile, molgroup);
864 else if ( ext.contains("embl") )
865 n = readEMBL(thefile, molgroup);
866 else if ( ext.contains("fasta") )
867 n = readFASTA(thefile, molgroup);
868 else if ( ext.contains("gb") || ext.contains("gp") || ext.contains("gen") )
869 n = readGenBank(thefile, molgroup);
870 else if ( ext.contains("gro") )
871 n = readGROMACS(thefile, molgroup);
872 else if ( ext.contains("pdb") || ext.contains("ent") )
873 n = readPDB(thefile, molgroup);
874 else if ( ext.contains("phy") )
875 n = readPhylip(thefile, molgroup);
876 else if ( ext.contains("pir") )
877 n = readPIR(thefile, molgroup);
878 else if ( ext.contains("wh") || ext.contains("wah") )
879 n = readWAH(thefile, molgroup);
880 else {
881 cerr << "Error: File type not supported!" << endl;
882 n = -1;
883 }
884
885 if ( n < 0 ) {
886 error_show(thefile.c_str(), __FILE__, __LINE__);
887 molgroup_kill(molgroup);
888 return NULL;
889 }
890
891 if ( molgroup->id.length() < 1 ) molgroup->id = molgroup->mol->id;
892
893 molgroup_sequence_check(molgroup);
894
895 molecule_get_masses(molgroup, paramfile);
896
897 molgroup_stats(molgroup);
898
899 if ( molgroup->maxlen > 0 ) {
900 molgroup->seqflag = new int[molgroup->maxlen];
901 for ( i=0; i<molgroup->maxlen; i++ ) molgroup->seqflag[i] = 1;
902 }
903
904 return molgroup;
905 }
906
916 Bmolgroup* read_molecule(Bstring* file_list, int set_pbc, Vector3<double> box,
917 Bstring atom_select, Bstring paramfile)
918 {
919 Bstring* filename;
920 Bmolgroup* molgroup = NULL;
921 Bmolgroup* molgroup1 = NULL;
922 Bmolecule* mol = NULL;
923 Bbond* bond;
924 Bangle* angle;
925
926 for ( filename = file_list; filename; filename = filename->next ) {
927 molgroup1 = read_molecule(*filename, atom_select, paramfile);
928 if ( set_pbc ) {
929 if ( box[0] > 0 && box[1] > 0 && box[2] > 0 ) molgroup1->box = box;
930 molgroup_resolve_pbc(molgroup1);
931 }
932 if ( molgroup ) {
933 if ( mol ) {
934 for ( ; mol->next; mol = mol->next ) ;
935 mol->next = molgroup1->mol;
936 } else {
937 mol = molgroup->mol = molgroup1->mol;
938 }
939 molgroup1->mol = NULL;
940 if ( bond ) {
941 for ( ; bond->next; bond = bond->next ) ;
942 bond->next = molgroup1->bond;
943 } else {
944 bond = molgroup->bond = molgroup1->bond;
945 }
946 molgroup1->bond = NULL;
947 if ( angle ) {
948 for ( ; angle->next; angle = angle->next ) ;
949 angle->next = molgroup1->angle;
950 } else {
951 angle = molgroup->angle = molgroup1->angle;
952 }
953 molgroup1->angle = NULL;
954 molgroup_kill(molgroup1);
955 } else {
956 molgroup = molgroup1;
957 mol = molgroup->mol;
958 bond = molgroup->bond;
959 angle = molgroup->angle;
960 }
961 }
962
963 return molgroup;
964 }
965
975 int write_molecule(char *filename, Bmolgroup *molgroup)
976 {
977 Bstring thefile(filename);
978 return write_molecule(thefile, molgroup);
979 }
980
981 int write_molecule(Bstring& filename, Bmolgroup *molgroup)
982 {
983 if ( !filename.length() ) {
984 error_show("No output coordinate file given!", __FILE__, __LINE__);
985 return -1;
986 }
987
988 int n;
989
990 Bstring ext = filename.extension();
991
992 Bstring thefile(filename.pre(':'));
993
994 if ( verbose & VERB_LABEL )
995 cout << "Writing file: " << thefile << endl;
996
997 if ( ext.contains("star") || ext.contains("cif") )
998 n = write_mol_star(thefile, molgroup);
999 else if ( ext.contains("txt") )
1000 n = write_mol_text(thefile, molgroup);
1001 else if ( ext.contains("aln") )
1002 n = writeClustal(thefile, molgroup);
1003 else if ( ext.contains("embl") )
1004 n = writeEMBL(thefile, molgroup);
1005 else if ( ext.contains("fasta") )
1006 n = writeFASTA(thefile, molgroup);
1007 else if ( ext.contains("gb") || ext.contains("gp") || ext.contains("gen") )
1008 n = writeGenBank(thefile, molgroup);
1009 else if ( ext.contains("gro") )
1010 n = writeGROMACS(thefile, molgroup);
1011 else if ( ext.contains("pdb") || ext.contains("ent") )
1012 n = writePDB(thefile, molgroup);
1013 else if ( ext.contains("phy") )
1014 n = writePhylip(thefile, molgroup);
1015 else if ( ext.contains("pir") )
1016 n = writePIR(thefile, molgroup);
1017 else if ( ext.contains("wh") || ext.contains("wah") )
1018 n = writeWAH(thefile, molgroup);
1019 else {
1020 cerr << "Error: File type not supported!" << endl;
1021 n = -1;
1022 }
1023
1024 if ( n < 0 ) {
1025 error_show(thefile.c_str(), __FILE__, __LINE__);
1026 return n;
1027 }
1028
1029 molgroup->filename = filename;
1030
1031 if ( verbose & VERB_PROCESS )
1032 cout << "Molecules written: " << n << endl;
1033
1034 molgroup_stats(molgroup);
1035
1036 return n;
1037 }
1038
1048 int molgroup_list_write(Bstring& filename, Bmolgroup* molgroup)
1049 {
1050 int i, n(0);
1051 Bstring onename;
1052
1053 if ( molgroup->next ) {
1054 for ( i=1; molgroup; molgroup = molgroup->next, i++ ) {
1055 onename = filename.pre_rev('.') + Bstring(i, "_%04d.") + filename.post_rev('.');
1056 n += write_molecule(onename, molgroup);
1057 }
1058 } else {
1059 n = write_molecule(filename, molgroup);
1060 }
1061
1062 return n;
1063 }
1064
1070 long molgroup_count_molecules(Bmolgroup* molgroup)
1071 {
1072 long n(0);
1073 Bmolecule* mol;
1074
1075 for ( mol=molgroup->mol; mol; mol=mol->next ) n++;
1076
1077 return n;
1078 }
1079
1085 long molgroup_count_residues(Bmolgroup* molgroup)
1086 {
1087 long n(0);
1088 Bmolecule* mol;
1089
1090 for ( mol=molgroup->mol; mol; mol=mol->next )
1091 n += mol_count_residues(mol);
1092
1093 return n;
1094 }
1095
1101 long mol_count_residues(Bmolecule *mol)
1102 {
1103 long n(0);
1104 Bresidue* res;
1105
1106 if ( mol->res )
1107 for ( res=mol->res; res; res=res->next ) n++;
1108 else if ( mol->seq.length() )
1109 n = mol->seq.length();
1110
1111 return n;
1112 }
1113
1119 long molgroup_count_atoms(Bmolgroup* molgroup)
1120 {
1121 long n(0);
1122 Bmolecule* mol;
1123
1124 for ( mol=molgroup->mol; mol; mol=mol->next )
1125 n += mol_count_atoms(mol);
1126
1127 return n;
1128 }
1129
1135 long mol_count_atoms(Bmolecule *mol)
1136 {
1137 long n(0);
1138 Bresidue* res;
1139 Batom* atom;
1140
1141 for ( res=mol->res; res; res=res->next )
1142 for ( atom=res->atom; atom; atom=atom->next ) n++;
1143
1144 return n;
1145 }
1146
1147 /*
1148 @brief Checks the sequences in a molecule group, and generate them if needed.
1149
1150 The sequence is first converted to upper case and then checked to see
1151 if it is a nucleic acid or protein sequence. The nucleic acid and
1152 protein sequences are referenced through different pointers.
1153
1154 @param *molgroup the molecule group.
1155 @return int number of molecules (<0 if writing failed).
1156 **/
1157 int molgroup_sequence_check(Bmolgroup* molgroup)
1158 {
1159 if ( !molgroup ) return -1;
1160
1161 Bmolecule* mol;
1162 Bresidue* res;
1163
1164 char* temp;
1165 long i, j, n, nmol(0), gaps(1);
1166
1167 if ( molgroup->select.contains("NOGAP") ) gaps = 0;
1168
1169 if ( verbose & VERB_DEBUG )
1170 cout << "DEBUG molgroup_sequence_check: select=" << molgroup->select << " gaps=" << gaps << endl;
1171
1172 if ( verbose & VERB_PROCESS )
1173 cout << "Checking sequence" << endl << endl;
1174
1175 molgroup->maxlen = 0;
1176 for ( mol = molgroup->mol; mol; mol = mol->next, nmol++ ) {
1177 if ( verbose & VERB_DEBUG )
1178 cout << "DEBUG molgroup_sequence_check: sequence " << mol->seq << endl;
1179 res = mol->res;
1180 if ( ( n = mol->naseq.length() ) ) {
1181 temp = new char[n+1];
1182 if ( gaps ) {
1183 for ( i=0, j=0; i<n; i++ ) {
1184 if ( isalpha(mol->naseq[i]) ) temp[j++] = toupper(mol->naseq[i]);
1185 if ( mol->naseq[i] == '-' || mol->naseq[i] == '.' ) temp[j++] = '-';
1186 }
1187 } else {
1188 for ( i=0, j=0; i<n; i++ ) {
1189 if ( isalpha(mol->naseq[i]) ) temp[j++] = toupper(mol->naseq[i]);
1190 }
1191 }
1192 temp[j] = 0;
1193 mol->naseq = temp;
1194 delete[] temp;
1195 mol->nbase = j;
1196 }
1197 if ( ( n = mol->seq.length() ) ) {
1198 temp = new char[n+1];
1199 if ( gaps ) {
1200 for ( i=0, j=0; i<n; i++ ) {
1201 if ( isalpha(mol->seq[i]) ) temp[j++] = toupper(mol->seq[i]);
1202 else if ( mol->seq[i] == '-' || mol->seq[i] == '.' ) temp[j++] = '-';
1203 }
1204 } else {
1205 for ( i=0, j=0; i<n; i++ ) {
1206 if ( isalpha(mol->seq[i]) ) temp[j++] = toupper(mol->seq[i]);
1207 }
1208 }
1209 temp[j] = 0;
1210 mol->seq = temp;
1211 delete[] temp;
1212 mol->nres = j;
1213 } else if ( res ) {
1214 for ( n = 0, res = mol->res; res; res = res->next, n++);
1215 mol->nres = n;
1216 temp = new char[n+1];
1217 for ( n = 0, res = mol->res; res; res = res->next, n++ )
1218 temp[n] = getcode1(res->type);
1219 temp[n] = 0;
1220 mol->seq = temp;
1221 delete[] temp;
1222 mol->nres = n;
1223 }
1224 if ( molgroup->maxlen < mol->seq.length() )
1225 molgroup->maxlen = mol->seq.length();
1226 if ( verbose & VERB_DEBUG )
1227 cout << "DEBUG molgroup_sequence_check: length=" << mol->nres << " sequence " << mol->seq << endl;
1228 }
1229
1230 if ( verbose & VERB_DEBUG )
1231 cout << "DEBUG molgroup_sequence_check: maxlen=" << molgroup->maxlen << endl;
1232
1233 return nmol;
1234 }
1235
1244 int molgroup_consolidate_gaps(Bmolgroup* molgroup)
1245 {
1246 long nmol = molgroup_count_molecules(molgroup);
1247 long i, n, m;
1248 Bstring newseq;
1249 Bmolecule* mol;
1250
1251 for ( m=i=0; i<molgroup->maxlen; i++ ) {
1252 for ( n=0, mol=molgroup->mol; mol; mol=mol->next ) {
1253 if ( i >= mol->seq.length() ) n++;
1254 else if ( mol->seq[i] == '-' ) n++;
1255 }
1256 if ( n >= nmol ) {
1257 molgroup->seqflag[i] = 0;
1258 m++;
1259 }
1260 }
1261
1262 m = molgroup->maxlen - m;
1263
1264 for ( mol=molgroup->mol; mol; mol=mol->next ) {
1265 // newseq = Bstring(m, '\0');
1266 newseq = Bstring('\0', m);
1267 for ( n=i=0; i<molgroup->maxlen; i++ ) {
1268 if ( molgroup->seqflag[i] )
1269 newseq[n++] = mol->seq[i];
1270 }
1271 mol->seq = newseq;
1272 mol->nres = m;
1273 }
1274
1275 delete[] molgroup->seqflag;
1276
1277 molgroup->maxlen = m;
1278
1279 molgroup->seqflag = new int[m];
1280 for ( i=0; i<m; i++ ) molgroup->seqflag[i] = 1;
1281
1282 return 0;
1283 }
1284
1291 long molgroup_stats(Bmolgroup* molgroup, int show)
1292 {
1293 if ( !molgroup ) return -1;
1294
1295 if ( verbose & VERB_DEBUG )
1296 cout << "DEBUG molgroup_stats: Calculating molecule group statistics" << endl;
1297
1298 long nmol(0), natom_all(0), nres_all(0), nbase_all(0);
1299 Bmolecule* mol;
1300 double Bmin_all(1000), Bmax_all(-1000);
1301
1302 molgroup->min[0] = molgroup->min[1] = molgroup->min[2] = 1000;
1303 molgroup->max[0] = molgroup->max[1] = molgroup->max[2] = -1000;
1304
1305 for ( mol = molgroup->mol; mol; mol = mol->next ) {
1306 natom_all += mol_stats(mol);
1307 nres_all += mol->nres;
1308 nbase_all += mol->nbase;
1309 if ( Bmin_all > mol->Bmin ) Bmin_all = mol->Bmin;
1310 if ( Bmax_all < mol->Bmax ) Bmax_all = mol->Bmax;
1311 molgroup->min = molgroup->min.min(mol->min);
1312 molgroup->max = molgroup->max.max(mol->max);
1313 nmol++;
1314 }
1315
1316 long nbond = count_list((char *) molgroup->bond);
1317
1318 if ( molgroup->box.volume() < 0.1 )
1319 molgroup->box = molgroup->max - molgroup->min;
1320
1321 if ( show ) {
1322 cout << "Statistics for molecule group:" << endl;
1323 cout << "Molecules: " << nmol << endl;
1324 cout << "Maximum sequence length: " << molgroup->maxlen << endl;
1325 if ( nbase_all )
1326 cout << "Bases: " << nbase_all << endl;
1327 if ( nres_all )
1328 cout << "Residues: " << nres_all << endl;
1329 if ( natom_all )
1330 cout << "Atoms: " << natom_all << endl;
1331 if ( nbond )
1332 cout << "Bonds specfied: " << nbond << endl;
1333 if ( natom_all > 0 ) {
1334 cout << "Coordinate minima and maxima: " << molgroup->min << " " << molgroup->max << endl;
1335 cout << "Bounding box size: " << molgroup->box << endl;
1336 cout << "Bfactor min & max: " << Bmin_all << " " << Bmax_all << endl;
1337 }
1338 cout << endl;
1339 }
1340
1341 return nmol;
1342 }
1343
1344 long molgroup_stats(Bmolgroup* molgroup)
1345 {
1346 int show(0);
1347 if ( verbose & VERB_PROCESS ) show = 1;
1348 return molgroup_stats(molgroup, show);
1349 }
1350
1357 long mol_stats(Bmolecule* mol, int show)
1358 {
1359 if ( !mol ) return -1;
1360
1361 if ( verbose & VERB_DEBUG )
1362 cout << "DEBUG mol_stats: Calculating molecule statistics: " << mol->id << endl;
1363
1364 long natom(0), nres(0), nhelix(0), nstrand(0);
1365 Bsecondary* sec = NULL;
1366 Bresidue* res;
1367 Batom* atom;
1368 double Bsum(0), Bssum(0);
1369
1370 mol->Bave = mol->Bstd = 0;
1371 if ( mol->res ) {
1372 mol->min = Vector3<double>(1000, 1000, 1000);
1373 mol->max = Vector3<double>(-1000, -1000, -1000);
1374 mol->Bmin = 1000;
1375 mol->Bmax = -1000;
1376
1377 for ( res = mol->res; res; res = res->next ) {
1378 for ( atom = res->atom; atom; atom = atom->next ) {
1379 if ( atom->sel ) {
1380 mol->min = mol->min.min(atom->coord);
1381 mol->max = mol->max.max(atom->coord);
1382 if ( mol->Bmin > atom->b ) mol->Bmin = atom->b;
1383 if ( mol->Bmax < atom->b ) mol->Bmax = atom->b;
1384 Bsum += atom->b;
1385 Bssum += atom->b*atom->b;
1386 natom++;
1387 }
1388 }
1389 nres++;
1390 }
1391 if ( natom ) {
1392 mol->Bave = Bsum/natom;
1393 mol->Bstd = sqrt(Bssum/natom - mol->Bave*mol->Bave);
1394 }
1395 }
1396
1397 if ( mol->max[0] - mol->min[0] < 1 ) {
1398 mol->max[0] = mol->min[0] = (mol->max[0] + mol->min[0])/2;
1399 mol->max[0] += 0.5;
1400 mol->min[0] -= 0.5;
1401 }
1402 if ( mol->max[1] - mol->min[1] < 1 ) {
1403 mol->max[1] = mol->min[1] = (mol->max[1] + mol->min[1])/2;
1404 mol->max[1] += 0.5;
1405 mol->min[1] -= 0.5;
1406 }
1407 if ( mol->max[2] - mol->min[2] < 1 ) {
1408 mol->max[2] = mol->min[2] = (mol->max[2] + mol->min[2])/2;
1409 mol->max[2] += 0.5;
1410 mol->min[2] -= 0.5;
1411 }
1412
1413 if ( mol->sec ) {
1414 for ( sec=mol->sec; sec; sec=sec->next )
1415 if ( sec->type == Strand ) nstrand++;
1416 else nhelix++;
1417 }
1418
1419 if ( show ) {
1420 cout << "Statistics for molecule: " << mol->id << endl;
1421 if ( mol->nbase )
1422 cout << "Bases: " << mol->nbase << endl;
1423 if ( mol->nres )
1424 cout << "Sequence length: " << mol->nres << endl;
1425 if ( nres )
1426 cout << "Residues: " << nres << endl;
1427 if ( natom )
1428 cout << "Atoms: " << natom << endl;
1429 if ( nhelix )
1430 cout << "Helices: " << nhelix << endl;
1431 if ( nstrand )
1432 cout << "Strands: " << nstrand << endl;
1433 if ( natom > 0 ) {
1434 cout << "Coordinate minima and maxima: " << mol->min << " " << mol->max << endl;
1435 cout << "Bfactor min, max, avg, & std: " <<
1436 mol->Bmin << " " << mol->Bmax << " " << mol->Bave << " " << mol->Bstd << endl;
1437 }
1438 cout << endl;
1439 }
1440
1441 return natom;
1442 }
1443
1444 long mol_stats(Bmolecule* mol)
1445 {
1446 int show(0);
1447 if ( verbose & VERB_FULL ) show = 1;
1448 return mol_stats(mol, show);
1449 }
1450
1462 int molecule_update_comment(Bmolgroup* molgroup, int n, char** strings)
1463 {
1464 int i;
1465 Bstring new_comment("");
1466 Bmolgroup* mg;
1467
1468 for ( i=0; i<n; i++ )
1469 new_comment = new_comment + strings[i] + " ";
1470
1471 if ( verbose & VERB_DEBUG )
1472 cout << "DEBUG molecule_update_comment: " << new_comment << endl;
1473
1474 for ( mg = molgroup; mg; mg = mg->next )
1475 mg->comment = new_comment;
1476
1477 return molgroup->comment.length();
1478 }
1479
1486 int molecule_get_masses(Bmolgroup* molgroup, Bstring& paramfile)
1487 {
1488 Batomtype* atompar = get_atom_properties(paramfile);
1489
1490 Bmolecule* mol;
1491 Bresidue* res;
1492 Batom* atom;
1493 Batomtype* at;
1494
1495 int t;
1496
1497 for ( mol = molgroup->mol; mol; mol = mol->next ) {
1498 for( res = mol->res; res; res = res->next ) {
1499 for ( atom = res->atom; atom; atom = atom->next ) {
1500 atom->tnum = -1;
1501 for ( t=0, at = atompar; at && atom->tnum < 0; at = at->next, t++ ) {
1502 if ( strncmp(atom->el, at->el, 2) == 0 ) {
1503 // cout << "atom=" << atom->el << ", type=" << at->el << "." << endl;
1504 atom->tnum = t;
1505 atom->mass = at->mass;
1506 }
1507 }
1508 if ( atom->tnum < 0 ) { // Sometimes people use incorrect case
1509 for ( t=0, at = atompar; at && atom->tnum < 0; at = at->next, t++ ) {
1510 if ( strncasecmp(atom->el, at->el, 2) == 0 ) {
1511 // cout << "atom=" << atom->el << ", type=" << at->el << "." << endl;
1512 atom->tnum = t;
1513 atom->mass = at->mass;
1514 }
1515 }
1516 }
1517 if ( verbose ) {
1518 if ( atom->tnum < 0 )
1519 cerr << "Warning: No type asigned for atom " << atom->num
1520 << " (" << atom->type << ", " << atom->el << ")!" << endl;
1521 if ( atom->mass <= 0 )
1522 cerr << "Warning: No mass asigned for atom " << atom->num
1523 << " (" << atom->type << ", " << atom->el << ")!" << endl;
1524 }
1525 }
1526 }
1527 }
1528
1529 atom_type_kill(atompar);
1530
1531 return 0;
1532 }
1533
1534 int bond_exists(Bbond* bondlist, Batom* atom1, Batom* atom2)
1535 {
1536 if ( !bondlist ) return 0;
1537
1538 Bbond* bond = NULL;
1539
1540 for ( bond = bondlist; bond; bond = bond->next ) {
1541 if ( bond->atom1 == atom1 && bond->atom2 == atom2 ) return 1;
1542 if ( bond->atom1 == atom2 && bond->atom2 == atom1 ) return 1;
1543 }
1544
1545 return 0;
1546 }
1547
1555 Bbond* molgroup_bond_list_generate(Bmolgroup* molgroup, double maxlength, int wrap)
1556 {
1557 if ( molgroup->bond ) {
1558 if ( verbose ) cerr << "Warning: Bond list already defined!" << endl;
1559 return molgroup->bond;
1560 }
1561
1562 if ( verbose & VERB_PROCESS ) {
1563 cout << "Generating bonds:" << endl;
1564 cout << "Bond length cutoff: " << maxlength << " A" << endl;
1565 }
1566
1567 long natom(0);
1568 long i, ii, x, y, z, xx, yy, zz, ix, iy, iz, xs, ys, xe, ye, ze;
1569 long nbond(0);
1570 Vector3<double> box = molgroup->box;
1571 Vector3<double> d;
1572 double dist, reflength;
1573 Vector3<double> sampling(maxlength, maxlength, maxlength);
1574 Vector3<int> size((int) (box[0]/sampling[0] + 0.001),
1575 (int) (box[1]/sampling[1] + 0.001), (int) (box[2]/sampling[2] + 0.001));
1576 size = size.max(1);
1577 for ( i=0; i<3; i++ ) sampling[i] = box[i]/size[i] + 0.001;
1578 long boxsize = (long) size.volume();
1579 Bbond* bond = NULL;
1580 Bbond* bondlist = NULL;
1581 Batom *atom, *atom2;
1582 Latom *latom, *latom2;
1583
1584 if ( verbose & VERB_DEBUG ) {
1585 cout << "DEBUG molgroup_bond_list_generate: box=" << box << endl;
1586 cout << "DEBUG molgroup_bond_list_generate: size=" << size << endl;
1587 cout << "DEBUG molgroup_bond_list_generate: sampling=" << sampling << endl;
1588 }
1589
1590 Latom** alist = molgroup_atom_mesh_lists(molgroup, size, sampling);
1591
1592 for ( i=z=0; z<size[2]; z++ ) {
1593 for ( y=0; y<size[1]; y++ ) {
1594 for ( x=0; x<size[0]; x++,i++ ) {
1595 for ( latom = alist[i]; latom; latom = latom->next ) {
1596 natom++;
1597 ze = ( size[2] < 2 )? z: z+1;
1598 for ( zz=z; zz<=ze; zz++ ) {
1599 iz = zz;
1600 if ( iz < 0 ) iz += (long) size[2];
1601 if ( iz >= size[2]) iz -= (long) size[2];
1602 ys = ( z == zz )? y: y-1;
1603 ye = ( size[1] < 2 )? y: y+1;
1604 // for ( yy=y-1; yy<=y+1; yy++ ) {
1605 for ( yy=ys; yy<=ye; yy++ ) {
1606 iy = yy;
1607 if ( iy < 0 ) iy += (long) size[1];
1608 if ( iy >= size[1] ) iy -= (long) size[1];
1609 xs = ( z==zz && y==yy )? x: x-1;
1610 xe = ( size[0] < 2 )? x: x+1;
1611 // for ( xx=x-1; xx<=x+1; xx++ ) {
1612 for ( xx=xs; xx<=xe; xx++ ) {
1613 ix = xx;
1614 if ( ix < 0 ) ix += (long) size[0];
1615 if ( ix >= size[0] ) ix -= (long) size[0];
1616 ii = (iz*(long)size[1] + iy)*(long)size[0] + ix;
1617 if ( i == ii ) latom2 = latom->next;
1618 else latom2 = alist[ii];
1619 for ( ; latom2; latom2 = latom2->next ) {
1620 atom = latom->atom;
1621 atom2 = latom2->atom;
1622 if ( wrap )
1623 d = vector3_difference_PBC(atom->coord, atom2->coord, box);
1624 else
1625 d = atom->coord - atom2->coord;
1626 dist = d.length();
1627 if ( strncmp(atom->el, "H\0", 2) && strncmp(atom2->el, "H\0", 2) )
1628 reflength = maxlength;
1629 else
1630 reflength = 1.1;
1631 if ( dist > 0.1*reflength && dist <= reflength ) {
1632 if ( bond_exists(bondlist, atom, atom2) == 0 ) {
1633 bond = bond_add(&bond, atom, atom2, dist, 1);
1634 if ( !bondlist ) bondlist = bond;
1635 nbond++;
1636 if ( verbose & VERB_FULL )
1637 cout << "Bond " << nbond << ":\t"
1638 << atom->num << " - " << atom2->num << " = "
1639 << dist << endl;
1640 }
1641 }
1642 }
1643 }
1644 }
1645 }
1646 }
1647 }
1648 }
1649 }
1650
1651 for ( i=0; i<boxsize; i++ ) kill_list((char *) alist[i], sizeof(Latom));
1652 delete[] alist;
1653
1654 if ( verbose & VERB_PROCESS ) {
1655 cout << "Number of atoms: " << natom << endl;
1656 cout << "Number of bonds generated: " << nbond << endl << endl;
1657 }
1658
1659 molgroup->bond = bondlist;
1660
1661 return bondlist;
1662 }
1663
1675 Bbond* mol_bond_list_generate(Bmolgroup* molgroup, double bondlength, int wrap)
1676 {
1677 if ( molgroup->bond ) {
1678 if ( verbose ) cerr << "Warning: Bond list already defined!" << endl;
1679 return molgroup->bond;
1680 }
1681
1682 long natom(0), nbond(0);
1683 double dist;
1684 Bbond* bond = NULL;
1685 Bbond* bondlist = NULL;
1686
1687 Bmolecule* mol;
1688 Bresidue* res, *res2;
1689 Batom* atom, *atom2;
1690
1691 if ( verbose & VERB_PROCESS ) {
1692 cout << "Generating bonds:" << endl;
1693 cout << "Bond length cutoff: " << bondlength << " A" << endl;
1694 }
1695
1696 for ( natom=0, mol = molgroup->mol; mol; mol = mol->next ) {
1697 for( res = mol->res; res; res = res->next ) {
1698 for ( atom = res->atom; atom; atom = atom->next ) {
1699 natom++;
1700 for( res2 = res; res2; res2 = res2->next ) {
1701 for ( atom2 = res2->atom; atom2; atom2 = atom2->next ) {
1702 if ( atom < atom2 ) {
1703 if ( wrap )
1704 dist = (vector3_difference_PBC(atom->coord, atom2->coord, molgroup->box)).length();
1705 else
1706 dist = (atom->coord - atom2->coord).length();
1707 if ( dist > 0.1*bondlength && dist < 1.1*bondlength ) {
1708 if ( bond ) bond = bond_add(&bond, atom, atom2, bondlength, 1);
1709 else bond = bond_add(&bondlist, atom, atom2, bondlength, 1);
1710 if ( verbose & VERB_FULL )
1711 cout << "Bond " << nbond << ": " << dist << " "
1712 << atom->coord[2] << " " << atom2->coord[2] << endl;
1713 nbond++;
1714 }
1715 }
1716 }
1717 }
1718 }
1719 }
1720 }
1721
1722 if ( verbose & VERB_PROCESS )
1723 cout << "Number of bonds generated: " << nbond << endl << endl;
1724
1725 molgroup->bond = bondlist;
1726
1727 return bondlist;
1728 }
1729
1739 int molecules_to_molgroups(Bmolgroup* molgroup)
1740 {
1741 Bmolgroup* mg = molgroup;
1742 Bmolecule* mol;
1743
1744 for ( mol = molgroup->mol->next; mol; mol = mol->next ) {
1745 mg->next = molgroup_init();
1746 mg = mg->next;
1747 mg->comment = molgroup->comment;
1748 mg->id = mol->id;
1749 mg->pointgroup = molgroup->pointgroup;
1750 mg->mol = mol;
1751 }
1752
1753 for ( mg = molgroup; mg; mg = mg->next ) if ( mg->mol ) mg->mol->next = NULL;
1754
1755 return 0;
1756 }
1757
Bmolgroup::id
Bstring id
Definition: rwmolecule.h:174
Bmolgroup::angle
Bangle * angle
Definition: rwmolecule.h:191
molecule_get_masses
int molecule_get_masses(Bmolgroup *molgroup, Bstring &paramfile)
Gets atomic masses from a parameter file.
Definition: rwmolecule.cpp:1486
Bmolecule::id
Bstring id
Definition: rwmolecule.h:110
atom_add
Batom * atom_add(Batom **atom, const char *type)
Adds an atom to a linked list.
Definition: rwmolecule.cpp:152
molgroup_count_molecules
long molgroup_count_molecules(Bmolgroup *molgroup)
Counts the total number of molecules in a molecule group.
Definition: rwmolecule.cpp:1070
M_PI_2
#define M_PI_2
Definition: utilities.h:62
Bmolecule::num
int num
Definition: rwmolecule.h:109
UnitCell
Definition: UnitCell.h:22
Bmolgroup::mol
Bmolecule * mol
Definition: rwmolecule.h:189
bond_kill
int bond_kill(Bbond *bond)
Dealocates a list of bonds.
Definition: rwmolecule.cpp:480
seq_util.h
Header file for sequence utilities.
Latom::next
Latom * next
Definition: mol_util.h:22
Bmolgroup::sgstring
Bstring sgstring
Definition: rwmolecule.h:178
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
Vector3::length
double length()
Definition: Vector3.h:222
Latom
Definition: mol_util.h:21
rwWAH.h
Header file for reading and writing Wayne Hendrickson coordinate files.
Bmolecule::nres
long nres
Definition: rwmolecule.h:111
Latom::atom
Batom * atom
Definition: mol_util.h:23
verbose
int verbose
utilities.h
Header file for general utilities.
get_atom_properties
Batomtype * get_atom_properties(Bstring &filename)
Reading atomic properties from parameter files.
Definition: rwatomprop.cpp:47
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
Bmolgroup::seqflag
int * seqflag
Definition: rwmolecule.h:188
Batomtype::next
Batomtype * next
Definition: rwatomprop.h:20
Bmolecule::res
Bresidue * res
Definition: rwmolecule.h:122
Bmolgroup::unitcell
UnitCell unitcell
Definition: rwmolecule.h:179
Bmolecule::Bmin
double Bmin
Definition: rwmolecule.h:118
Bbond::k
double k
Definition: rwmolecule.h:139
rwmol_text.h
Read and write molecules in plain text.
rwmol_star.h
Read and write molecules in STAR format.
mol_copy_and_add_to_molgroup
Bmolecule * mol_copy_and_add_to_molgroup(Bmolgroup *molgroup, Bmolecule *mol)
Copies a molecule and assign to a new pointer in the molgroup.
Definition: rwmolecule.cpp:664
kill_list
long kill_list(char *list, unsigned long size)
Frees all the items in a linked list.
Definition: linked_list.cpp:214
Bangle::next
Bangle * next
Definition: rwmolecule.h:151
Bresidue::insert
char insert[2]
Definition: rwmolecule.h:52
molgroup_bond_list_generate
Bbond * molgroup_bond_list_generate(Bmolgroup *molgroup, double maxlength, int wrap)
Generates a bond list based on atom separation.
Definition: rwmolecule.cpp:1555
readWAH
int readWAH(Bstring &filename, Bmolgroup *molgroup)
Reads a Wayne Hendrickson coordinate file.
Definition: rwWAH.cpp:28
add_item
char * add_item(char **list, unsigned long size)
Adds an item to a linked list.
Definition: linked_list.cpp:26
Bstring::length
long length() const
Definition: Bstring.cpp:263
count_list
long count_list(char *list)
Counts the number of items in a linked list.
Definition: linked_list.cpp:235
rwPDB.h
Header file for reading and writing PDB coordinate files.
molgroup_consolidate_gaps
int molgroup_consolidate_gaps(Bmolgroup *molgroup)
Removes redundant gaps from an alignment.
Definition: rwmolecule.cpp:1244
mol_transform.h
Library routines used for atomic coordinate transformations.
Batomtype::mass
float mass
Definition: rwatomprop.h:24
Bmolecule::min
Vector3< double > min
Definition: rwmolecule.h:116
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
writePDB
int writePDB(Bstring &filename, Bmolgroup *molgroup)
Writes a PDB format coordinate file.
Definition: rwPDB.cpp:330
Bresidue::type
char type[6]
Definition: rwmolecule.h:53
Bmolgroup::select
Bstring select
Definition: rwmolecule.h:185
Bsecondary::next
Bsecondary * next
Definition: rwmolecule.h:88
Vector3::distance
double distance(const Vector3 &v)
Definition: Vector3.h:227
Bmolecule::Bave
double Bave
Definition: rwmolecule.h:119
Bangle
Definition: rwmolecule.h:150
molgroup_bond_list_copy
Bbond * molgroup_bond_list_copy(Bmolgroup *molgroup, Bmolgroup *molgroupcopy)
Copies a bond list.
Definition: rwmolecule.cpp:706
writeEMBL
int writeEMBL(Bstring &filename, Bmolgroup *molgroup)
Writes EMBL format sequence files.
Definition: rwEMBL.cpp:105
Batom::q
double q
Definition: rwmolecule.h:31
read_mol_star
long read_mol_star(Bstring &filename, Bmolgroup *molgroup)
Reads a molecule group from a STAR format file.
Definition: rwmol_star.cpp:25
molgroup_resolve_pbc
int molgroup_resolve_pbc(Bmolgroup *molgroup)
Recombines coordinates split across periodic box boundaries.
Definition: mol_transform.cpp:450
Bmolgroup::maxnalen
long maxnalen
Definition: rwmolecule.h:181
atom_count
long atom_count(Bmolgroup *molgroup)
Counts the number of atoms in a molecule group.
Definition: rwmolecule.cpp:205
angle_kill
int angle_kill(Bangle *angle)
Dealocates a list of angles.
Definition: rwmolecule.cpp:501
Batom::sel
int sel
Definition: rwmolecule.h:34
Bmolgroup::box
Vector3< double > box
Definition: rwmolecule.h:184
mol_stats
long mol_stats(Bmolecule *mol, int show)
Calculates the statistics of a molecule.
Definition: rwmolecule.cpp:1357
Bmolecule::sec
Bsecondary * sec
Definition: rwmolecule.h:123
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
readEMBL
int readEMBL(Bstring &filename, Bmolgroup *molgroup)
Reads EMBL format sequence files.
Definition: rwEMBL.cpp:29
molecules_to_molgroups
int molecules_to_molgroups(Bmolgroup *molgroup)
Converts molecules in a molecule group to individual molecule groups.
Definition: rwmolecule.cpp:1739
Bbond::atom2
Batom * atom2
Definition: rwmolecule.h:137
writePIR
int writePIR(Bstring &filename, Bmolgroup *molgroup)
Writes PIR format sequence files.
Definition: rwPIR.cpp:109
rwFASTA.h
Header file for reading and writing FASTA sequence files.
molgroup_sequence_check
int molgroup_sequence_check(Bmolgroup *molgroup)
Definition: rwmolecule.cpp:1157
Batom::num
int num
Definition: rwmolecule.h:26
Bmolgroup::sel
int sel
Definition: rwmolecule.h:186
writeGROMACS
int writeGROMACS(Bstring &filename, Bmolgroup *molgroup)
Writes a Gromacs coordinate file.
Definition: rwGROMACS.cpp:143
Bstring::contains
bool contains(const Bstring &s)
Definition: Bstring.cpp:584
Bmolecule::seq
Bstring seq
Definition: rwmolecule.h:114
linked_list.h
Header file for generalized linked list functions.
molgroup_from_molgroup_list
int molgroup_from_molgroup_list(Bmolgroup *molgroup)
Converts a molecule group list to a single molecule group.
Definition: rwmolecule.cpp:760
Bsecondary::last
Bresidue * last
Definition: rwmolecule.h:95
rwmolecule.h
Header file for reading reflection files.
Bmolgroup
Definition: rwmolecule.h:170
Bmolecule::nbase
long nbase
Definition: rwmolecule.h:112
Bmolecule::Bstd
double Bstd
Definition: rwmolecule.h:119
rwEMBL.h
Header file for reading and writing EMBL sequence files.
molecule_copy
Bmolecule * molecule_copy(Bmolecule *mol)
Copies a molecule.
Definition: rwmolecule.cpp:599
write_molecule
int write_molecule(char *filename, Bmolgroup *molgroup)
Writes a molecule group.
Definition: rwmolecule.cpp:975
Bstring::next
Bstring * next
Definition: Bstring.h:31
Bbond::l
double l
Definition: rwmolecule.h:138
Bmolgroup::comment
Bstring comment
Definition: rwmolecule.h:175
writePhylip
int writePhylip(Bstring &filename, Bmolgroup *molgroup)
Writes Phylip format sequence files.
Definition: rwPhylip.cpp:94
Bstring::pre
Bstring pre(char c)
Definition: Bstring.cpp:381
Vector3::angle
double angle(Vector3< T2 > &v)
Definition: Vector3.h:257
Batomtype
Definition: rwatomprop.h:19
residue_kill
int residue_kill(Bresidue *res)
Destroys a residue.
Definition: rwmolecule.cpp:453
Bstring::extension
Bstring extension()
Definition: Bstring.cpp:515
readPDB
int readPDB(Bstring &filename, Bmolgroup *molgroup)
Reads a PDB format coordinate file.
Definition: rwPDB.cpp:31
rwatomprop.h
Header file for reading atom property files.
length
double length(vector< T > v)
Definition: Vector3.h:528
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
writeGenBank
int writeGenBank(Bstring &filename, Bmolgroup *molgroup)
Writes GenBank format sequence files.
Definition: rwGenBank.cpp:123
read_mol_text
int read_mol_text(Bstring &filename, Bmolgroup *molgroup)
Reads a molecule group from a text file.
Definition: rwmol_text.cpp:22
Bmolecule::naseq
Bstring naseq
Definition: rwmolecule.h:115
readGenBank
int readGenBank(Bstring &filename, Bmolgroup *molgroup)
Reads GenBank format sequence files.
Definition: rwGenBank.cpp:33
Bmolgroup::maxlen
long maxlen
Definition: rwmolecule.h:180
Batom::b
double b
Definition: rwmolecule.h:31
Bmolgroup::max
Vector3< double > max
Definition: rwmolecule.h:183
residue_count
long residue_count(Bmolgroup *molgroup)
Counts the number of residues in a molecule group.
Definition: rwmolecule.cpp:188
Bmolgroup::filename
Bstring filename
Definition: rwmolecule.h:172
Bmolgroup::next
Bmolgroup * next
Definition: rwmolecule.h:171
Bstring::upper
Bstring upper()
Definition: Bstring.cpp:316
Bangle::atom2
Batom * atom2
Definition: rwmolecule.h:153
molgroup_list_copy
Bmolgroup * molgroup_list_copy(Bmolgroup *molgroup)
Copies a molecule group list.
Definition: rwmolecule.cpp:522
Bmolecule::Bmax
double Bmax
Definition: rwmolecule.h:118
readPIR
int readPIR(Bstring &filename, Bmolgroup *molgroup)
Reads PIR format sequence files.
Definition: rwPIR.cpp:29
read_molecule
Bmolgroup * read_molecule(const char *filename, const char *atom_select, const char *paramfile)
The generalized function for reading molecular files.
Definition: rwmolecule.cpp:818
angle_add
Bangle * angle_add(Bangle **angle, Batom *atom1, Batom *atom2, Batom *atom3, double a, double k)
Adds an angle to a linked list.
Definition: rwmolecule.cpp:312
Bresidue::atom
Batom * atom
Definition: rwmolecule.h:54
Bstring::c_str
const char * c_str()
Definition: Bstring.h:70
Bmolecule
Definition: rwmolecule.h:107
Bstring::post_rev
Bstring post_rev(char c)
Definition: Bstring.cpp:428
rwPhylip.h
Header file for reading and writing Phylip sequence files.
molgroup_kill
int molgroup_kill(Bmolgroup *molgroup)
Destroys a molecule group.
Definition: rwmolecule.cpp:374
mol_count_atoms
long mol_count_atoms(Bmolecule *mol)
Counts the total number of atoms in a molecule.
Definition: rwmolecule.cpp:1135
Bmolgroup::bond
Bbond * bond
Definition: rwmolecule.h:190
Bresidue::next
Bresidue * next
Definition: rwmolecule.h:50
Bresidue
Definition: rwmolecule.h:49
readPhylip
int readPhylip(Bstring &filename, Bmolgroup *molgroup)
Reads Phylip format sequence files.
Definition: rwPhylip.cpp:29
Bstring
Definition: Bstring.h:29
molecule_kill
int molecule_kill(Bmolecule *mol)
Destroys a molecule.
Definition: rwmolecule.cpp:417
Batom
Definition: rwmolecule.h:24
residue_add
Bresidue * residue_add(Bresidue **res, const char *type)
Adds a residue to a linked list.
Definition: rwmolecule.cpp:113
Bsecondary::first
Bresidue * first
Definition: rwmolecule.h:94
rwClustal.h
Header file for reading and writing Clustal sequence files.
writeFASTA
int writeFASTA(Bstring &filename, Bmolgroup *molgroup)
Writes FASTA format sequence files.
Definition: rwFASTA.cpp:100
readClustal
int readClustal(Bstring &filename, Bmolgroup *molgroup)
Reads Clustal format sequence files.
Definition: rwClustal.cpp:29
rwGenBank.h
Header file for reading and writing GenBank sequence files.
Batomtype::el
char el[4]
Definition: rwatomprop.h:22
Bbond::atom1
Batom * atom1
Definition: rwmolecule.h:136
Bmolecule::sel
int sel
Definition: rwmolecule.h:120
molecule_add
Bmolecule * molecule_add(Bmolecule **mol, char *name)
Adds a molecule to a linked list.
Definition: rwmolecule.cpp:76
Bmolecule::fom
double fom
Definition: rwmolecule.h:121
Vector3< double >
rwPIR.h
Header file for reading and writing PIR sequence files.
Bangle::a
double a
Definition: rwmolecule.h:155
molgroup_list_write
int molgroup_list_write(Bstring &filename, Bmolgroup *molgroup)
Writes a molecule group list.
Definition: rwmolecule.cpp:1048
readFASTA
int readFASTA(Bstring &filename, Bmolgroup *molgroup)
Reads FASTA format sequence files.
Definition: rwFASTA.cpp:28
Bresidue::num
int num
Definition: rwmolecule.h:51
writeClustal
int writeClustal(Bstring &filename, Bmolgroup *molgroup)
Writes Clustal format sequence files.
Definition: rwClustal.cpp:81
show
int show(0)
Bmolgroup::pointgroup
Bstring pointgroup
Definition: rwmolecule.h:177
Vector3::min
Type min()
Definition: Vector3.h:169
Batom::coord
Vector3< double > coord
Definition: rwmolecule.h:30
mol_bond_list_generate
Bbond * mol_bond_list_generate(Bmolgroup *molgroup, double bondlength, int wrap)
Generates an intramolecular distance-based bond list.
Definition: rwmolecule.cpp:1675
Bmolgroup::fom
double fom
Definition: rwmolecule.h:187
getcode1
char getcode1(char *acode)
Converts a three-letter amino acid designation to the one-letter equivalent.
Definition: seq_util.cpp:531
Bmolecule::max
Vector3< double > max
Definition: rwmolecule.h:117
Bbond
Definition: rwmolecule.h:134
Bbond::next
Bbond * next
Definition: rwmolecule.h:135
Batom::el
char el[4]
Definition: rwmolecule.h:27
molgroup_count_residues
long molgroup_count_residues(Bmolgroup *molgroup)
Counts the total number of residues in a molecule group.
Definition: rwmolecule.cpp:1085
readGROMACS
int readGROMACS(Bstring &filename, Bmolgroup *molgroup)
Reads a Gromacs coordinate file.
Definition: rwGROMACS.cpp:31
write_mol_text
int write_mol_text(Bstring &filename, Bmolgroup *molgroup)
Writes a molecule group to a text file.
Definition: rwmol_text.cpp:75
Bmolgroup::min
Vector3< double > min
Definition: rwmolecule.h:182
molgroup_stats
long molgroup_stats(Bmolgroup *molgroup, int show)
Calculates the statistics of a molecule group.
Definition: rwmolecule.cpp:1291
molgroup_list_kill
int molgroup_list_kill(Bmolgroup *molgroup)
Destroys a molecule group linked list.
Definition: rwmolecule.cpp:347
Bmolgroup::num
int num
Definition: rwmolecule.h:173
Bangle::atom1
Batom * atom1
Definition: rwmolecule.h:152
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_count_atoms
long molgroup_count_atoms(Bmolgroup *molgroup)
Counts the total number of atoms in a molecule group.
Definition: rwmolecule.cpp:1119
Bmolgroup::spacegroup
int spacegroup
Definition: rwmolecule.h:176
Bangle::k
double k
Definition: rwmolecule.h:156
mol_count_residues
long mol_count_residues(Bmolecule *mol)
Counts the total number of residues in a molecule.
Definition: rwmolecule.cpp:1101
Bangle::atom3
Batom * atom3
Definition: rwmolecule.h:154
Bstring::pre_rev
Bstring pre_rev(char c)
Definition: Bstring.cpp:413
Strand
Definition: rwmolecule.h:75
molgroup_copy
Bmolgroup * molgroup_copy(Bmolgroup *molgroup)
Copies a molecule group.
Definition: rwmolecule.cpp:547
bond_exists
int bond_exists(Bbond *bondlist, Batom *atom1, Batom *atom2)
Definition: rwmolecule.cpp:1534
Bstring::empty
bool empty()
Definition: Bstring.h:71
rwGROMACS.h
Header file for reading and writing GROMACS coordinate files.
Bsecondary::type
SecondaryType type
Definition: rwmolecule.h:89
Batom::tnum
int tnum
Definition: rwmolecule.h:29
atom_clean_type
int atom_clean_type(Batom *atom, const char *type)
Cleans up the type string and assigns an element code to an atom.
Definition: rwmolecule.cpp:229
Vector3::volume
double volume()
Definition: Vector3.h:235
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:106
Bmolecule::first_codon
long first_codon
Definition: rwmolecule.h:113
Batom::next
Batom * next
Definition: rwmolecule.h:25
Batom::mass
double mass
Definition: rwmolecule.h:32
write_mol_star
long write_mol_star(Bstring &filename, Bmolgroup *molgroup)
Writes a molecule group to a STAR format file.
Definition: rwmol_star.cpp:324
molecule_update_comment
int molecule_update_comment(Bmolgroup *molgroup, int n, char **strings)
Puts a set of strings and time in the main comment of a molecule group.
Definition: rwmolecule.cpp:1462
molgroup_atom_renumber
int molgroup_atom_renumber(Bmolgroup *molgroup, int first)
Renumbers all atoms, disregarding molecule distinction.
Definition: mol_util.cpp:211
error_show
int error_show(string message, string file, int line)
Displays the error with file and line reference.
Definition: utilities.cpp:755
Bsecondary
Definition: rwmolecule.h:87
molgroup_init
Bmolgroup * molgroup_init()
Initializes and allocates a new molecule group.
Definition: rwmolecule.cpp:45
writeWAH
int writeWAH(Bstring &filename, Bmolgroup *molgroup)
Writes a Wayne Hendrickson coordinate file.
Definition: rwWAH.cpp:99
atom_type_kill
int atom_type_kill(Batomtype *atype)
Destroys an atom type.
Definition: rwatomprop.cpp:177