ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/openbabel/residue.cpp
Revision: 2450
Committed: Thu Nov 17 20:38:45 2005 UTC (18 years, 7 months ago) by gezelter
File size: 46032 byte(s)
Log Message:
Unifying config.h stuff and making sure the OpenBabel codes can find
our default (and environment variable) Force Field directories.

File Contents

# Content
1 /**********************************************************************
2 residue.cpp - Handle macromolecule residues.
3
4 Copyright (C) 2001, 2002 OpenEye Scientific Software, Inc.
5 Some portions Copyright (C) 2001-2005 by Geoffrey R. Hutchison
6
7 This file is part of the Open Babel project.
8 For more information, see <http://openbabel.sourceforge.net/>
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation version 2 of the License.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 ***********************************************************************/
19
20 /**********************************************************************
21 Global arrays Residue, ElemDesc and function GetResidueNumber were
22 obtained in part or whole from RasMol2 by Roger Sayle.
23 ***********************************************************************/
24
25 ///////////////////////////////////////////////////////////////////////////////
26 // File Includes
27 ///////////////////////////////////////////////////////////////////////////////
28
29 #include "config.h"
30
31 #if HAVE_IOSTREAM
32 #include <iostream>
33 #elif HAVE_IOSTREAM_H
34 #include <iostream.h>
35 #endif
36
37 #if HAVE_FSTREAM
38 #include <fstream>
39 #elif HAVE_FSTREAM_H
40 #include <fstream.h>
41 #endif
42
43 #include "mol.hpp"
44 #include "bitvec.hpp"
45
46 using namespace std;
47
48 namespace OpenBabel
49 {
50 /** \class OBResidue
51 \brief Residue information
52
53 The residue information is drawn from PDB or MOL2 files (or similar), which
54 track biomolecule information,
55 and are stored in the OBResidue class. OBResidues are stored inside the
56 OBAtom class and OBMol classes.
57 The residue information for an atom can be requested in
58 the following way:
59 \code
60 OBAtom *atom;
61 OBResidue *r;
62 atom = mol.GetAtom(1);
63 r = atom->GetResidue();
64 \endcode
65 The residue information for a molecule can be manipulated too:
66 \code
67 cout << "This molecule has " << mol.NumResidues() << " residues." << endl;
68 OBResidue *r;
69 r = mol.GetResidue(1);
70 \endcode
71 */
72
73 ///////////////////////////////////////////////////////////////////////////////
74 // Global Definitions
75 ///////////////////////////////////////////////////////////////////////////////
76
77 #define MAXSETNO 40
78 #define MAXELEM 1024
79 #define MINELEM 29
80 #define MAXRES 100
81 #define MINRES 54
82
83 ///////////////////////////////////////////////////////////////////////////////
84 // Amino Acid Definitions
85 ///////////////////////////////////////////////////////////////////////////////
86
87 #define AA_ALA (1<<1)
88 #define AA_GLY (1<<2)
89 #define AA_LEU (1<<3)
90 #define AA_SER (1<<4)
91 #define AA_VAL (1<<5)
92 #define AA_THR (1<<6)
93 #define AA_LYS (1<<7)
94 #define AA_ASP (1<<8)
95 #define AA_ILE (1<<9)
96 #define AA_ASN (1<<10)
97 #define AA_GLU (1<<11)
98 #define AA_PRO (1<<12)
99 #define AA_ARG (1<<13)
100 #define AA_PHE (1<<14)
101 #define AA_GLN (1<<15)
102 #define AA_TYR (1<<16)
103 #define AA_HIS (1<<17)
104 #define AA_CYS (1<<18)
105 #define AA_MET (1<<19)
106 #define AA_TRP (1<<20)
107
108 //! Residue property definitions
109 namespace OBAminoAcidProperty
110 {
111 static const unsigned int ACIDIC = 0;
112 static const unsigned int ACYCLIC = 1;
113 static const unsigned int ALIPHATIC = 2;
114 static const unsigned int AROMATIC = 3;
115 static const unsigned int BASIC = 4;
116 static const unsigned int BURIED = 5;
117 static const unsigned int CHARGED = 6;
118 static const unsigned int CYCLIC = 7;
119 static const unsigned int HYDROPHOBIC = 8;
120 static const unsigned int LARGE = 9;
121 static const unsigned int MEDIUM = 10;
122 static const unsigned int NEGATIVE = 11;
123 static const unsigned int NEUTRAL = 12;
124 static const unsigned int POLAR = 13;
125 static const unsigned int POSITIVE = 14;
126 static const unsigned int SMALL = 15;
127 static const unsigned int SURFACE = 16;
128 }
129
130 //! Residue atom properties
131 namespace OBResidueAtomProperty
132 {
133 static const unsigned int ALPHA_CARBON = 0;
134 static const unsigned int AMINO_BACKBONE = 1;
135 static const unsigned int BACKBONE = 2;
136 static const unsigned int CYSTEINE_SULPHUR = 3;
137 static const unsigned int LIGAND = 4;
138 static const unsigned int NUCLEIC_BACKBONE = 5;
139 static const unsigned int SHAPELY_BACKBONE = 6;
140 static const unsigned int SHAPELY_SPECIAL = 7;
141 static const unsigned int SIDECHAIN = 8;
142 static const unsigned int SUGAR_PHOSPHATE = 9;
143 }
144 /// Residue names
145 namespace OBResidueIndex
146 {
147 static const unsigned int ALA = 0;
148 static const unsigned int GLY = 1;
149 static const unsigned int LEU = 2;
150 static const unsigned int SER = 3;
151 static const unsigned int VAL = 4;
152 static const unsigned int THR = 5;
153 static const unsigned int LYS = 6;
154 static const unsigned int ASP = 7;
155 static const unsigned int ILE = 8;
156 static const unsigned int ASN = 9;
157 static const unsigned int GLU = 10;
158 static const unsigned int PRO = 11;
159 static const unsigned int ARG = 12;
160 static const unsigned int PHE = 13;
161 static const unsigned int GLN = 14;
162 static const unsigned int TYR = 15;
163 static const unsigned int HIS = 16;
164 static const unsigned int CYS = 17;
165 static const unsigned int MET = 18;
166 static const unsigned int TRP = 19;
167 static const unsigned int ASX = 20;
168 static const unsigned int GLX = 21;
169 static const unsigned int PCA = 22;
170 static const unsigned int HYP = 23;
171 static const unsigned int A = 24;
172 static const unsigned int C = 25;
173 static const unsigned int G = 26;
174 static const unsigned int T = 27;
175 static const unsigned int U = 28;
176 static const unsigned int UPLUS = 29;
177 static const unsigned int I = 30;
178 //static const unsigned int _1MA = 31;
179 //static const unsigned int _5MC = 32;
180 static const unsigned int OMC = 33;
181 //static const unsigned int _1MG = 34;
182 //static const unsigned int _2MG = 35;
183 static const unsigned int M2G = 36;
184 //static const unsigned int _7MG = 37;
185 static const unsigned int OMG = 38;
186 static const unsigned int YG = 39;
187 static const unsigned int H2U = 40;
188 //static const unsigned int _5MU = 41;
189 static const unsigned int PSU = 42;
190 static const unsigned int UNK = 43;
191 static const unsigned int ACE = 44;
192 static const unsigned int FOR = 45;
193 static const unsigned int HOH = 46;
194 static const unsigned int DOD = 47;
195 static const unsigned int SO4 = 48;
196 static const unsigned int PO4 = 49;
197 static const unsigned int NAD = 50;
198 static const unsigned int COA = 51;
199 static const unsigned int NAP = 52;
200 static const unsigned int NDP = 53;
201 }
202 /// Residue types.
203 namespace OBResidueProperty
204 {
205 static const unsigned int AMINO = 0;
206 static const unsigned int AMINO_NUCLEO = 1;
207 static const unsigned int COENZYME = 2;
208 static const unsigned int ION = 3;
209 static const unsigned int NUCLEO = 4;
210 static const unsigned int PROTEIN = 5;
211 static const unsigned int PURINE = 6;
212 static const unsigned int PYRIMIDINE = 7;
213 static const unsigned int SOLVENT = 8;
214 static const unsigned int WATER = 9;
215 }
216
217 ///////////////////////////////////////////////////////////////////////////////
218 // Amino Acid Property Definitions
219 ///////////////////////////////////////////////////////////////////////////////
220
221 #define IS_ACIDIC(x) ((x) & ((AA_ASP)|(AA_GLU)))
222 #define IS_ACYCLIC(x) ((x) & ((AA_ALA)|(AA_GLY)|(AA_LEU)|(AA_SER)| \
223 (AA_VAL)|(AA_THR)|(AA_LYS)|(AA_ASP)| \
224 (AA_ILE)|(AA_ASN)|(AA_GLU)|(AA_GLN)| \
225 (AA_CYS)|(AA_MET)))
226 #define IS_ALIPHATIC(x) ((x) & ((AA_ALA)|(AA_GLY)|(AA_ILE)|(AA_LEU)| \
227 (AA_VAL)))
228 #define IS_AROMATIC(x) ((x) & ((AA_HIS)|(AA_PHE)|(AA_TRP)|(AA_TYR)))
229 #define IS_BASIC(x) ((x) & ((AA_ARG)|(AA_HIS)|(AA_LYS)))
230 #define IS_BURIED(x) ((x) & ((AA_ALA)|(AA_CYS)|(AA_ILE)|(AA_LEU)| \
231 (AA_MET)|(AA_PHE)|(AA_TRP)|(AA_VAL)))
232 #define IS_CHARGED(x) ((x) & ((AA_ASP)|(AA_GLU)|(AA_ARG)|(AA_HIS)| \
233 (AA_LYS)))
234 #define IS_CYCLIC(x) ((x) & ((AA_HIS)|(AA_PHE)|(AA_PRO)|(AA_TRP)| \
235 (AA_TYR)))
236 #define IS_HYDROPHOBIC(x) ((x) & ((AA_ALA)|(AA_LEU)|(AA_VAL)|(AA_ILE)| \
237 (AA_PRO)|(AA_PHE)|(AA_MET)|(AA_TRP)))
238 #define IS_LARGE(x) ((x) & ((AA_ARG)|(AA_PHE)|(AA_GLN)|(AA_TYR)| \
239 (AA_HIS)|(AA_LEU)|(AA_LYS)|(AA_ILE)| \
240 (AA_GLU)|(AA_MET)|(AA_TRP)))
241 #define IS_MEDIUM(x) ((x) & ((AA_VAL)|(AA_THR)|(AA_ASP)|(AA_ASN)| \
242 (AA_PRO)|(AA_CYS)))
243 #define IS_NEGATIVE(x) ((x) & ((AA_ASP)|(AA_GLU)))
244 #define IS_NEUTRAL(x) ((x) & ((AA_ALA)|(AA_GLY)|(AA_LEU)|(AA_SER)| \
245 (AA_VAL)|(AA_THR)|(AA_PHE)|(AA_GLN)| \
246 (AA_TYR)|(AA_HIS)|(AA_CYS)|(AA_MET)| \
247 (AA_TRP)|(AA_ILE)|(AA_ASN)|(AA_PRO)))
248 #define IS_POLAR(x) ((x) & ((AA_ASP)|(AA_ILE)|(AA_ASN)|(AA_GLU)| \
249 (AA_SER)|(AA_THR)|(AA_ARG)|(AA_GLN)| \
250 (AA_CYS)|(AA_HIS)))
251 #define IS_POSITIVE(x) ((x) & ((AA_ARG)|(AA_HIS)|(AA_LYS)))
252 #define IS_SMALL(x) ((x) & ((AA_ALA)|(AA_GLY)|(AA_SER)))
253 #define IS_SURFACE(x) ((x) & ((AA_THR)|(AA_LYS)|(AA_ASP)|(AA_ILE)| \
254 (AA_ASN)|(AA_GLU)|(AA_PRO)|(AA_ARG)| \
255 (AA_GLY)|(AA_SER)|(AA_GLN)|(AA_TYR)| \
256 (AA_HIS)))
257
258 ////////////////////////////////////////////////////////////////////////////////
259 // Global Variables
260 ////////////////////////////////////////////////////////////////////////////////
261
262 static char Residue[MAXRES][4] = {
263 /*===============*/
264 /* Amino Acids */
265 /*===============*/
266
267 /* Ordered by Cumulative Frequency in Brookhaven *
268 * Protein Databank, December 1991 */
269
270 "ALA", /* 8.4% */ "GLY", /* 8.3% */
271 "LEU", /* 8.0% */ "SER", /* 7.5% */
272 "VAL", /* 7.1% */ "THR", /* 6.4% */
273 "LYS", /* 5.8% */ "ASP", /* 5.5% */
274 "ILE", /* 5.2% */ "ASN", /* 4.9% */
275 "GLU", /* 4.9% */ "PRO", /* 4.4% */
276 "ARG", /* 3.8% */ "PHE", /* 3.7% */
277 "GLN", /* 3.5% */ "TYR", /* 3.5% */
278 "HIS", /* 2.3% */ "CYS", /* 2.0% */
279 "MET", /* 1.8% */ "TRP", /* 1.4% */
280
281 "ASX", "GLX", "PCA", "HYP",
282
283 /*===================*/
284 /* DNA Nucleotides */
285 /*===================*/
286 " A", " C", " G", " T",
287
288 /*===================*/
289 /* RNA Nucleotides */
290 /*===================*/
291 " U", " +U", " I", "1MA",
292 "5MC", "OMC", "1MG", "2MG",
293 "M2G", "7MG", "OMG", " YG",
294 "H2U", "5MU", "PSU",
295
296 /*=================*/
297 /* Miscellaneous */
298 /*=================*/
299 "UNK", "ACE", "FOR", "HOH",
300 "DOD", "SO4", "PO4", "NAD",
301 "COA", "NAP", "NDP"
302 };
303
304 /* Avoid SGI Compiler Warnings! */
305 static char ElemDesc[MAXELEM][4] = {
306 { ' ', 'N', ' ', ' ' }, /* 0*/
307 { ' ', 'C', 'A', ' ' }, /* 1*/
308 { ' ', 'C', ' ', ' ' }, /* 2*/
309 { ' ', 'O', ' ', ' ' }, /* 3*/ /* 0-3 Amino Acid Backbone */
310 { ' ', 'C', '\'', ' ' }, /* 4*/
311 { ' ', 'O', 'T', ' ' }, /* 5*/
312 { ' ', 'S', ' ', ' ' }, /* 6*/
313 { ' ', 'P', ' ', ' ' }, /* 7*/ /* 4-7 Shapely Amino Backbone */
314 { ' ', 'O', '1', 'P' }, /* 8*/
315 { ' ', 'O', '2', 'P' }, /* 9*/
316 { ' ', 'O', '5', '*' }, /*10*/
317 { ' ', 'C', '5', '*' }, /*11*/
318 { ' ', 'C', '4', '*' }, /*12*/
319 { ' ', 'O', '4', '*' }, /*13*/
320 { ' ', 'C', '3', '*' }, /*14*/
321 { ' ', 'O', '3', '*' }, /*15*/
322 { ' ', 'C', '2', '*' }, /*16*/
323 { ' ', 'O', '2', '*' }, /*17*/
324 { ' ', 'C', '1', '*' }, /*18*/ /* 7-18 Nucleic Acid Backbone */
325 { ' ', 'C', 'A', '2' }, /*19*/ /* 19 Shapely Special */
326 { ' ', 'S', 'G', ' ' }, /*20*/ /* 20 Cysteine Sulphur */
327 { ' ', 'N', '1', ' ' }, /*21*/
328 { ' ', 'N', '2', ' ' }, /*22*/
329 { ' ', 'N', '3', ' ' }, /*23*/
330 { ' ', 'N', '4', ' ' }, /*24*/
331 { ' ', 'N', '6', ' ' }, /*25*/
332 { ' ', 'O', '2', ' ' }, /*26*/
333 { ' ', 'O', '4', ' ' }, /*27*/
334 { ' ', 'O', '6', ' ' } /*28*/ /* 21-28 Nucleic Acid H-Bonding */
335 };
336
337 static unsigned int ResNo = MINRES;
338 static unsigned int ElemNo = MINELEM;
339
340 ///////////////////////////////////////////////////////////////////////////////
341 // Residue Functions
342 ///////////////////////////////////////////////////////////////////////////////
343
344 static unsigned int GetAtomIDNumber(const char *atomid)
345 {
346 if (atomid != NULL)
347 {
348 int ch1 = toupper(atomid[0]);
349 int ch2 = toupper(atomid[1]);
350 int ch3 = toupper(atomid[2]);
351 int ch4 = toupper(atomid[3]);
352
353 if (ch1 == ' ')
354 {
355 switch(ch2)
356 {
357 case 'C':
358
359 switch(ch3)
360 {
361 case 'A':
362
363 if (ch4 == ' ')
364 return 1;
365 else if (ch4 == '2')
366 return 19;
367
368 break;
369
370 case ' ':
371 if (ch4 == ' ')
372 return 2;
373 break;
374
375 case '\'':
376 if (ch4 == ' ')
377 return 4;
378 break;
379
380 case '1':
381 if (ch4 == '*')
382 return 18;
383 break;
384
385 case '2':
386 if (ch4 == '*')
387 return 16;
388 break;
389
390 case '3':
391 if (ch4 == '*')
392 return 14;
393 break;
394
395 case '4':
396 if (ch4 == '*')
397 return 12;
398 break;
399
400 case '5':
401 if (ch4 == '*')
402 return 11;
403 break;
404
405 }
406
407 break;
408
409 case 'N':
410
411 if (ch4 == ' ')
412 {
413 switch (ch3)
414 {
415 case ' ':
416 return 0;
417 case '1':
418 return 21;
419 case '2':
420 return 22;
421 case '3':
422 return 23;
423 case '4':
424 return 24;
425 case '6':
426 return 25;
427 }
428 }
429
430 break;
431
432 case 'O':
433
434 switch(ch3)
435 {
436 case ' ':
437
438 if (ch4 == ' ')
439 return 3;
440
441 break;
442
443 case 'T':
444
445 if (ch4 == ' ')
446 return 5;
447
448 break;
449
450 case '1':
451
452 if (ch4 == 'P')
453 return 8;
454
455 break;
456
457 case '2':
458
459 if (ch4 == 'P')
460 return 9;
461 else if (ch4 == '*')
462 return 17;
463 else if (ch4 == ' ')
464 return 26;
465
466 break;
467
468 case '3':
469
470 if (ch4 == '*')
471 return 15;
472
473 break;
474
475 case '4':
476
477 if (ch4 == '*')
478 return 13;
479 else if (ch4 == ' ')
480 return 27;
481
482 break;
483
484 case '5':
485
486 if (ch4 == '*')
487 return 10;
488
489 break;
490
491 case '6':
492
493 if (ch4 == ' ')
494 return 28;
495
496 break;
497 }
498
499 break;
500
501 case 'P':
502
503 if ((ch3 == ' ') && (ch4 == ' '))
504 return 7;
505
506 break;
507
508 case 'S':
509
510 if (ch4 == ' ')
511 {
512 if (ch3 == ' ')
513 return 6;
514 else if (ch3 == 'G')
515 return 20;
516 }
517
518 break;
519 }
520 }
521
522 unsigned int refno;
523 for( refno = MINELEM ; refno < ElemNo ; refno++ )
524 if( !strncmp(ElemDesc[refno], atomid, 4) )
525 return refno;
526
527 if ( ElemNo < MAXELEM - 1 )
528 {
529 ElemNo++;
530 ElemDesc[refno][0] = (char) ch1;
531 ElemDesc[refno][1] = (char) ch2;
532 ElemDesc[refno][2] = (char) ch3;
533 ElemDesc[refno][3] = (char) ch4;
534 return refno;
535 }
536 else
537 {
538 obErrorLog.ThrowError(__FUNCTION__, "Maximum number of atom ids exceeded", obWarning);
539 return 0;
540 }
541 }
542 else
543 {
544 obErrorLog.ThrowError(__FUNCTION__, "NULL Atom IDs specified", obWarning);
545 return 0;
546 }
547 }
548
549 static unsigned int GetResidueNumber(const char *res)
550 {
551 if (res != NULL)
552 {
553 int ch1 = toupper(res[0]);
554 int ch2 = toupper(res[1]);
555 int ch3 = toupper(res[2]);
556
557 switch( ch1 )
558 {
559 case(' '):
560
561 if( ch2 == ' ' )
562 {
563 switch( ch3 )
564 {
565 case('A'): return( 24 );
566 case('C'): return( 25 );
567 case('G'): return( 26 );
568 case('T'): return( 27 );
569 case('U'): return( 28 );
570 case('I'): return( 30 );
571 }
572 }
573 else if( ch2 == '+' )
574 {
575 if( ch3 == 'U' )
576 return( 29 );
577 }
578 else if( ch2 == 'Y' )
579 {
580 if( ch3 == 'G' )
581 return( 39 );
582 }
583
584 break;
585
586 case('0'):
587
588 if( ch2 == 'M' )
589 {
590 if( ch3 == 'C' )
591 return( 33 );
592 else if( ch3 == 'G' )
593 return( 38 );
594 }
595
596 break;
597
598 case('1'):
599
600 if( ch2 == 'M' )
601 {
602 if( ch3 == 'A' )
603 return( 31 );
604 else if( ch3 == 'G' )
605 return( 34 );
606 }
607
608 break;
609
610 case('2'):
611
612 if( ch2 == 'M' )
613 if( ch3 == 'G' )
614 return( 35 );
615
616 break;
617
618 case('5'):
619
620 if( ch2 == 'M' )
621 {
622 if( ch3 == 'C' )
623 return( 32 );
624 else if( ch3 == 'U' )
625 return( 41 );
626 }
627
628 break;
629
630 case('7'):
631
632 if( ch2 == 'M' )
633 if( ch3 == 'G' )
634 return( 37 );
635
636 break;
637
638 case('A'):
639
640 if( ch2 == 'L' )
641 {
642 if( ch3 == 'A' )
643 return( 0 );
644 }
645 else if( ch2 == 'S' )
646 {
647 if( ch3 == 'P' )
648 return( 7 );
649 else if( ch3 == 'N' )
650 return( 9 );
651 else if( ch3 == 'X' )
652 return( 20 );
653 }
654 else if( ch2 == 'R' )
655 {
656 if( ch3 == 'G' )
657 return( 12 );
658 }
659 else if( ch2 == 'C' )
660 {
661 if( ch3 == 'E' )
662 return( 44 );
663 }
664 else if( ch2 == 'D' )
665 {
666 if( ch3 == 'E' )
667 return( 24 ); /* "ADE" -> " A" */
668 }
669
670 break;
671
672 case('C'):
673
674 if( ch2 == 'Y' )
675 {
676 if( ch3 == 'S' )
677 return( 17 );
678 else if( ch3 == 'H' )
679 return( 17 ); /* "CYH" -> "CYS" */
680 else if( ch3 == 'T' )
681 return( 25 ); /* "CYT" -> " C" */
682 }
683 else if( ch2 == 'O' )
684 {
685 if( ch3 == 'A' )
686 return( 51 );
687 }
688 else if( ch2 == 'P' )
689 {
690 if( ch3 == 'R' )
691 return( 11 ); /* "CPR" -> "PRO" */
692 }
693 else if( ch2 == 'S' )
694 {
695 if( ch3 == 'H' )
696 return( 17 ); /* "CSH" -> "CYS" */
697 else if( ch3 == 'M' )
698 return( 17 ); /* "CSM" -> "CYS" */
699 }
700
701 break;
702
703 case('D'):
704
705 if( ch2 == 'O' )
706 {
707 if( ch3 == 'D' )
708 return( 47 );
709 }
710 else if( ch2 == '2' )
711 {
712 if( ch3 == 'O' )
713 return( 47 ); /* "D2O" -> "DOD" */
714 }
715
716 break;
717
718 case('F'):
719
720 if( ch2 == 'O' )
721 if( ch3 == 'R' )
722 return( 45 );
723
724 break;
725
726 case('G'):
727
728 if( ch2 == 'L' )
729 {
730 if( ch3 == 'Y' )
731 return( 1 );
732 else if( ch3 == 'U' )
733 return( 10 );
734 else if( ch3 == 'N' )
735 return( 14 );
736 else if( ch3 == 'X' )
737 return( 21 );
738 }
739 else if( ch2 == 'U' )
740 {
741 if( ch3 == 'A' )
742 return( 26 ); /* "GUA" -> " G" */
743 }
744
745 break;
746
747 case('H'):
748
749 if( ch2 == 'I' )
750 {
751 if( ch3 == 'S' )
752 return( 16 );
753 }
754 else if( ch2 == 'O' )
755 {
756 if( ch3 == 'H' )
757 return( 46 );
758 }
759 else if( ch2 == 'Y' )
760 {
761 if( ch3 == 'P' )
762 return( 23 );
763 }
764 else if( ch2 == '2' )
765 {
766 if( ch3 == 'O' )
767 return( 46 ); /* "H20" -> "HOH" */
768 else if( ch3 == 'U' )
769 return( 40 );
770 }
771
772 break;
773
774 case('I'):
775
776 if( ch2 == 'L' )
777 if( ch3 == 'E' )
778 return( 8 );
779
780 break;
781
782 case('L'):
783
784 if( ch2 == 'E' )
785 {
786 if( ch3 == 'U' )
787 return( 2 );
788 }
789 else if( ch2 == 'Y' )
790 {
791 if( ch3 == 'S' )
792 return( 6 );
793 }
794
795 break;
796
797 case('M'):
798
799 if( ch2 == 'E' )
800 {
801 if( ch3 == 'T' )
802 return( 18 );
803 }
804 else if( ch2 == '2' )
805 {
806 if( ch3 == 'G' )
807 return( 36 );
808 }
809
810 break;
811
812 case('N'):
813
814 if( ch2 == 'A' )
815 {
816 if( ch3 == 'D' )
817 return( 50 );
818 else if( ch3 == 'P' )
819 return( 52 );
820 }
821 else if( ch2 == 'D' )
822 {
823 if( ch3 == 'P' )
824 return( 53 );
825 }
826
827 break;
828
829 case('P'):
830
831 if( ch2 == 'R' )
832 {
833 if( ch3 == 'O' )
834 return( 11 );
835 }
836 else if( ch2 == 'H' )
837 {
838 if( ch3 == 'E' )
839 return( 13 );
840 }
841 else if( ch2 == 'C' )
842 {
843 if( ch3 == 'A' )
844 return( 22 );
845 }
846 else if( ch2 == 'O' )
847 {
848 if( ch3 == '4' )
849 return( 49 );
850 }
851 else if( ch2 == 'S' )
852 {
853 if( ch3 == 'U' )
854 return( 42 );
855 }
856
857 break;
858
859 case('S'):
860
861 if( ch2 == 'E' )
862 {
863 if( ch3 == 'R' )
864 return( 3 );
865 }
866 else if( ch2 == 'O' )
867 {
868 if( ch3 == '4' )
869 return( 48 );
870 else if( ch3 == 'L' )
871 return( 46 ); /* "SOL" -> "HOH" */
872 }
873 else if( ch2 == 'U' )
874 {
875 if( ch3 == 'L' )
876 return( 48 ); /* "SUL" -> "SO4" */
877 }
878
879 break;
880
881 case('T'):
882
883 if( ch2 == 'H' )
884 {
885 if( ch3 == 'R' )
886 return( 5 );
887 else if( ch3 == 'Y' )
888 return( 27 ); /* "THY" -> " T" */
889 }
890 else if( ch2 == 'Y' )
891 {
892 if( ch3 == 'R' )
893 return( 15 );
894 }
895 else if( ch2 == 'R' )
896 {
897 if( ch3 == 'P' )
898 return( 19 );
899 else if( ch3 == 'Y' )
900 return( 19 ); /* "TRY" -> "TRP" */
901 }
902 else if( ch2 == 'I' )
903 {
904 if( ch3 == 'P' )
905 return( 46 ); /* "TIP" -> "HOH" */
906 }
907
908 break;
909
910 case('U'):
911
912 if( ch2 == 'N' )
913 {
914 if( ch3 == 'K' )
915 return( 43 );
916 }
917 else if( ch2 == 'R' )
918 {
919 if( ch3 == 'A' )
920 return( 28 ); /* "URA" -> " U" */
921 else if( ch3 == 'I' )
922 return( 28 ); /* "URI" -> " U" */
923 }
924
925 break;
926
927 case('V'):
928
929 if( ch2 == 'A' )
930 if( ch3 == 'L' )
931 return( 4 );
932
933 break;
934
935 case('W'):
936
937 if( ch2 == 'A' )
938 if( ch3 == 'T' )
939 return( 46 ); /* "WAT" -> "HOH" */
940
941 break;
942 }
943
944 unsigned int refno;
945 for( refno = MINRES; refno < ResNo ; refno++ )
946 if( !strncmp(Residue[refno],res,3) )
947 return refno;
948
949 if ( ResNo < MAXRES - 1 )
950 {
951 ResNo++;
952 Residue[refno][0] = (char) ch1;
953 Residue[refno][1] = (char) ch2;
954 Residue[refno][2] = (char) ch3;
955 return refno;
956 }
957 }
958
959 return OBResidueIndex::UNK;
960 }
961
962 static void SetResidueKeys(const char *residue,
963 unsigned int &reskey,
964 unsigned int &aakey)
965 {
966 reskey = GetResidueNumber(residue);
967 switch(reskey)
968 {
969 case OBResidueIndex::ALA:
970 aakey = AA_ALA;
971 break;
972 case OBResidueIndex::GLY:
973 aakey = AA_GLY;
974 break;
975 case OBResidueIndex::LEU:
976 aakey = AA_LEU;
977 break;
978 case OBResidueIndex::SER:
979 aakey = AA_SER;
980 break;
981 case OBResidueIndex::VAL:
982 aakey = AA_VAL;
983 break;
984 case OBResidueIndex::THR:
985 aakey = AA_THR;
986 break;
987 case OBResidueIndex::LYS:
988 aakey = AA_LYS;
989 break;
990 case OBResidueIndex::ASP:
991 aakey = AA_ASP;
992 break;
993 case OBResidueIndex::ILE:
994 aakey = AA_ILE;
995 break;
996 case OBResidueIndex::ASN:
997 aakey = AA_ASN;
998 break;
999 case OBResidueIndex::GLU:
1000 aakey = AA_GLU;
1001 break;
1002 case OBResidueIndex::PRO:
1003 aakey = AA_PRO;
1004 break;
1005 case OBResidueIndex::ARG:
1006 aakey = AA_ARG;
1007 break;
1008 case OBResidueIndex::PHE:
1009 aakey = AA_PHE;
1010 break;
1011 case OBResidueIndex::GLN:
1012 aakey = AA_GLN;
1013 break;
1014 case OBResidueIndex::TYR:
1015 aakey = AA_TYR;
1016 break;
1017 case OBResidueIndex::HIS:
1018 aakey = AA_HIS;
1019 break;
1020 case OBResidueIndex::CYS:
1021 aakey = AA_CYS;
1022 break;
1023 case OBResidueIndex::MET:
1024 aakey = AA_MET;
1025 break;
1026 case OBResidueIndex::TRP:
1027 aakey = AA_TRP;
1028 break;
1029 default:
1030 aakey = 0;
1031 break;
1032 }
1033 }
1034
1035 ///////////////////////////////////////////////////////////////////////////////
1036 // OBResidue: Constructors / Destructor
1037 ///////////////////////////////////////////////////////////////////////////////
1038
1039 OBResidue::OBResidue()
1040 {
1041 _chain = 'A';
1042 _idx = 0;
1043 _aakey = 0;
1044 _reskey = OBResidueIndex::UNK;
1045 _resnum = 0;
1046 _resname = "";
1047 _vdata.clear();
1048 }
1049
1050 OBResidue::OBResidue(const OBResidue &src)
1051 // Currently does not copy vdata information
1052 {
1053 _chain = src._chain;
1054 _aakey = src._aakey;
1055 _reskey = src._reskey;
1056 _resnum = src._resnum;
1057 _resname = src._resname;
1058 _atomid = src._atomid;
1059 _hetatm = src._hetatm;
1060 _sernum = src._sernum;
1061 }
1062
1063 OBResidue::~OBResidue()
1064 {
1065 vector<OBAtom*>::iterator a;
1066 for ( a = _atoms.begin() ; a != _atoms.end() ; a++ )
1067 (*a)->SetResidue(NULL);
1068 _atoms.clear();
1069 if (!_vdata.empty())
1070 {
1071 vector<OBGenericData*>::iterator m;
1072 for (m = _vdata.begin();m != _vdata.end();m++)
1073 delete *m;
1074 _vdata.clear();
1075 }
1076 }
1077
1078 ///////////////////////////////////////////////////////////////////////////////
1079 // OBResidue: Operator Overloads
1080 ///////////////////////////////////////////////////////////////////////////////
1081
1082 OBResidue &OBResidue::operator = (const OBResidue &src)
1083 //copy residue information
1084 // Currently does not copy vdata informtion
1085 {
1086 if (this != &src)
1087 {
1088 _chain = src._chain;
1089 _aakey = src._aakey;
1090 _reskey = src._reskey;
1091 _resnum = src._resnum;
1092 _resname = src._resname;
1093 _atomid = src._atomid;
1094 _hetatm = src._hetatm;
1095 _sernum = src._sernum;
1096 }
1097
1098 return(*this);
1099 }
1100
1101 ///////////////////////////////////////////////////////////////////////////////
1102 // OBResidue: Data Access / Manipulation
1103 ///////////////////////////////////////////////////////////////////////////////
1104
1105 void OBResidue::AddAtom(OBAtom *atom)
1106 {
1107 if (atom != NULL)
1108 {
1109 atom->SetResidue(this);
1110
1111 _atoms.push_back(atom);
1112 _atomid.push_back("");
1113 _hetatm.push_back(false);
1114 _sernum.push_back(0);
1115 }
1116 }
1117
1118 void OBResidue::InsertAtom(OBAtom *atom)
1119 {
1120 if (atom != NULL)
1121 {
1122 atom->SetResidue(this);
1123
1124 _atoms.push_back(atom);
1125 _atomid.push_back("");
1126 _hetatm.push_back(false);
1127 _sernum.push_back(0);
1128 }
1129 }
1130
1131 void OBResidue::RemoveAtom(OBAtom *atom)
1132 {
1133 if (atom != NULL)
1134 {
1135 for ( unsigned int i = 0 ; i < _atoms.size() ; i++ )
1136 {
1137 if (_atoms[i] == atom)
1138 {
1139 atom->SetResidue(NULL);
1140 _atoms.erase(_atoms.begin() + i);
1141 _atomid.erase(_atomid.begin() + i);
1142 _hetatm.erase(_hetatm.begin() + i);
1143 _sernum.erase(_sernum.begin() + i);
1144 }
1145 }
1146 }
1147 }
1148
1149 void OBResidue::Clear(void)
1150 {
1151 for (unsigned int i = 0 ; i < _atoms.size() ; i++ )
1152 _atoms[i]->SetResidue(NULL);
1153
1154 _chain = 'A';
1155 _idx = 0;
1156 _aakey = 0;
1157 _reskey = OBResidueIndex::UNK;
1158 _resnum = 0;
1159 _resname = "";
1160
1161 _atoms.clear();
1162 _atomid.clear();
1163 _hetatm.clear();
1164 _sernum.clear();
1165 }
1166
1167 void OBResidue::SetChain(char chain)
1168 {
1169 _chain = chain;
1170 }
1171
1172 void OBResidue::SetChainNum(unsigned int chainnum)
1173 {
1174 _chain = (char) ('A' + chainnum - 1);
1175 }
1176
1177 void OBResidue::SetIdx(unsigned int idx)
1178 {
1179 _idx = idx;
1180 }
1181
1182 void OBResidue::SetName(const string &name)
1183 {
1184 _resname = name;
1185 SetResidueKeys(_resname.c_str(), _reskey, _aakey);
1186 }
1187
1188 void OBResidue::SetNum(unsigned int resnum)
1189 {
1190 _resnum = resnum;
1191 }
1192
1193 void OBResidue::SetAtomID(OBAtom *atom, const string &id)
1194 {
1195 for ( unsigned int i = 0 ; i < _atoms.size() ; i++ )
1196 if (_atoms[i] == atom)
1197 _atomid[i] = id;
1198 }
1199
1200 void OBResidue::SetHetAtom(OBAtom *atom, bool hetatm)
1201 {
1202 for ( unsigned int i = 0 ; i < _atoms.size() ; i++ )
1203 if (_atoms[i] == atom)
1204 _hetatm[i] = hetatm;
1205 }
1206
1207 void OBResidue::SetSerialNum(OBAtom *atom, unsigned int sernum)
1208 {
1209 for ( unsigned int i = 0 ; i < _atoms.size() ; i++ )
1210 if (_atoms[i] == atom)
1211 _sernum[i] = sernum;
1212 }
1213
1214 vector<OBAtom*> OBResidue::GetAtoms(void) const
1215 {
1216 return _atoms;
1217 }
1218
1219 vector<OBBond*> OBResidue::GetBonds(bool exterior) const
1220 {
1221 OBAtom *atom;
1222 vector<OBBond*> bonds;
1223 OBBitVec idxs;
1224 unsigned int sz;
1225
1226 sz = (unsigned int) _atoms.size();
1227 for ( unsigned int i = 0 ; i < sz ; i++ )
1228 {
1229 atom = _atoms[i];
1230 OBBond *bond;
1231 vector<OBEdgeBase*>::iterator b;
1232 for (bond = atom->BeginBond(b) ; bond ; bond = atom->NextBond(b))
1233 {
1234 if (!idxs.BitIsOn(bond->GetIdx()))
1235 {
1236 if (!exterior)
1237 {
1238 if (bond->GetNbrAtom(atom)->GetResidue() == this)
1239 bonds.push_back(&(*bond));
1240 }
1241 else
1242 bonds.push_back(&(*bond));
1243
1244 idxs.SetBitOn(bond->GetIdx());
1245 }
1246 }
1247 }
1248
1249 return bonds;
1250 }
1251
1252 string OBResidue::GetName(void) const
1253 {
1254 return _resname;
1255 }
1256
1257 unsigned int OBResidue::GetNum(void) const
1258 {
1259 return _resnum;
1260 }
1261
1262 unsigned int OBResidue::GetNumAtoms(void) const
1263 {
1264 return (unsigned int)_atoms.size();
1265 }
1266
1267 char OBResidue::GetChain(void) const
1268 {
1269 return _chain;
1270 }
1271
1272 unsigned int OBResidue::GetChainNum(void) const
1273 {
1274 if (isdigit(_chain))
1275 return (_chain - '0');
1276 else
1277 return (_chain - 'A' + 1);
1278 }
1279
1280 unsigned int OBResidue::GetIdx(void) const
1281 {
1282 return(_idx);
1283 }
1284
1285 unsigned int OBResidue::GetResKey(void) const
1286 {
1287 return(_reskey);
1288 }
1289
1290 string OBResidue::GetAtomID(OBAtom *atom) const
1291 {
1292 for ( unsigned int i = 0 ; i < _atoms.size() ; i++ )
1293 if (_atoms[i] == atom)
1294 return _atomid[i];
1295 return "";
1296 }
1297
1298 unsigned int OBResidue::GetSerialNum(OBAtom *atom) const
1299 {
1300 for ( unsigned int i = 0 ; i < _atoms.size() ; i++ )
1301 if (_atoms[i] == atom)
1302 return _sernum[i];
1303 return 0;
1304 }
1305
1306 bool OBResidue::IsHetAtom(OBAtom *atom) const
1307 {
1308 for ( unsigned int i = 0 ; i < _atoms.size() ; i++ )
1309 if (_atoms[i] == atom)
1310 return _hetatm[i];
1311 return false;
1312 }
1313
1314 ///////////////////////////////////////////////////////////////////////////////
1315 // OBResidue: Iteration Utilities
1316 ///////////////////////////////////////////////////////////////////////////////
1317
1318 OBAtom *OBResidue::BeginAtom(vector<OBAtom*>::iterator &i)
1319 {
1320 i = _atoms.begin();
1321 return ((i == _atoms.end()) ? NULL : *i);
1322 }
1323
1324 OBAtom *OBResidue::NextAtom(vector<OBAtom*>::iterator &i)
1325 {
1326 i++;
1327 return ((i == _atoms.end()) ? NULL : *i);
1328 }
1329
1330 ///////////////////////////////////////////////////////////////////////////////
1331 // OBResidue: Information Functions
1332 ///////////////////////////////////////////////////////////////////////////////
1333
1334 bool OBResidue::GetAminoAcidProperty(int property) const
1335 {
1336 switch(property)
1337 {
1338 case OBAminoAcidProperty::ACIDIC:
1339 return IS_ACIDIC(_aakey) != 0;
1340 case OBAminoAcidProperty::ACYCLIC:
1341 return IS_ACYCLIC(_aakey) != 0;
1342 case OBAminoAcidProperty::ALIPHATIC:
1343 return IS_ALIPHATIC(_aakey) != 0;
1344 case OBAminoAcidProperty::AROMATIC:
1345 return IS_AROMATIC(_aakey) != 0;
1346 case OBAminoAcidProperty::BASIC:
1347 return IS_BASIC(_aakey) != 0;
1348 case OBAminoAcidProperty::BURIED:
1349 return IS_BURIED(_aakey) != 0;
1350 case OBAminoAcidProperty::CHARGED:
1351 return IS_CHARGED(_aakey) != 0;
1352 case OBAminoAcidProperty::CYCLIC:
1353 return IS_CYCLIC(_aakey) != 0;
1354 case OBAminoAcidProperty::HYDROPHOBIC:
1355 return IS_HYDROPHOBIC(_aakey) != 0;
1356 case OBAminoAcidProperty::LARGE:
1357 return IS_LARGE(_aakey) != 0;
1358 case OBAminoAcidProperty::MEDIUM:
1359 return IS_MEDIUM(_aakey) != 0;
1360 case OBAminoAcidProperty::NEGATIVE:
1361 return IS_NEGATIVE(_aakey) != 0;
1362 case OBAminoAcidProperty::NEUTRAL:
1363 return IS_NEUTRAL(_aakey) != 0;
1364 case OBAminoAcidProperty::POLAR:
1365 return IS_POLAR(_aakey) != 0;
1366 case OBAminoAcidProperty::POSITIVE:
1367 return IS_POSITIVE(_aakey) != 0;
1368 case OBAminoAcidProperty::SMALL:
1369 return IS_SMALL(_aakey) != 0;
1370 case OBAminoAcidProperty::SURFACE:
1371 return IS_SURFACE(_aakey) != 0;
1372 default:
1373 return false;
1374 }
1375 }
1376
1377 bool OBResidue::GetAtomProperty(OBAtom *atom, int property) const
1378 {
1379 if (atom != NULL)
1380 {
1381 unsigned int atomid = GetAtomIDNumber(GetAtomID(atom).c_str());
1382
1383 switch(property)
1384 {
1385 case OBResidueAtomProperty::ALPHA_CARBON:
1386 return (atomid == 1);
1387
1388 case OBResidueAtomProperty::AMINO_BACKBONE:
1389 return (atomid <= 3);
1390
1391 case OBResidueAtomProperty::BACKBONE:
1392 return (atomid <= 18);
1393
1394 case OBResidueAtomProperty::CYSTEINE_SULPHUR:
1395 return (atomid == 20);
1396
1397 case OBResidueAtomProperty::LIGAND:
1398 return IsHetAtom(atom) &&
1399 !GetResidueProperty(OBResidueProperty::SOLVENT);
1400
1401 case OBResidueAtomProperty::NUCLEIC_BACKBONE:
1402 return ((atomid >= 7) && (atomid <= 18));
1403
1404 case OBResidueAtomProperty::SHAPELY_BACKBONE:
1405 return (atomid <= 7);
1406
1407 case OBResidueAtomProperty::SHAPELY_SPECIAL:
1408 return (atomid == 19);
1409
1410 case OBResidueAtomProperty::SIDECHAIN:
1411 return GetResidueProperty(OBResidueProperty::AMINO_NUCLEO) &&
1412 (atomid > 18);
1413
1414 case OBResidueAtomProperty::SUGAR_PHOSPHATE:
1415 return (atomid == 7);
1416 }
1417 }
1418
1419 return false;
1420 }
1421
1422 bool OBResidue::GetResidueProperty(int property) const
1423 {
1424 switch(property)
1425 {
1426 case OBResidueProperty::AMINO:
1427 return (_reskey <= OBResidueIndex::HYP);
1428
1429 case OBResidueProperty::AMINO_NUCLEO:
1430 return (_reskey <= OBResidueIndex::PSU);
1431
1432 case OBResidueProperty::COENZYME:
1433 return (_reskey >= OBResidueIndex::NAD) &&
1434 (_reskey <= OBResidueIndex::NDP);
1435
1436 case OBResidueProperty::ION:
1437 return (_reskey == OBResidueIndex::SO4) ||
1438 (_reskey == OBResidueIndex::PO4);
1439
1440 case OBResidueProperty::NUCLEO:
1441 return (_reskey >= OBResidueIndex::A) &&
1442 (_reskey <= OBResidueIndex::PSU);
1443
1444 case OBResidueProperty::PROTEIN:
1445 return (_reskey <= OBResidueIndex::HYP) ||
1446 ((_reskey >= OBResidueIndex::UNK) &&
1447 (_reskey <= OBResidueIndex::FOR));
1448
1449 case OBResidueProperty::PURINE:
1450 return (_reskey == OBResidueIndex::A) ||
1451 (_reskey == OBResidueIndex::G);
1452
1453 case OBResidueProperty::PYRIMIDINE:
1454 return (_reskey == OBResidueIndex::C) ||
1455 (_reskey == OBResidueIndex::T);
1456
1457 case OBResidueProperty::SOLVENT:
1458 return (_reskey >= OBResidueIndex::HOH) &&
1459 (_reskey <= OBResidueIndex::PO4);
1460
1461 case OBResidueProperty::WATER:
1462 return (_reskey == OBResidueIndex::HOH) ||
1463 (_reskey == OBResidueIndex::DOD);
1464
1465 default:
1466 return false;
1467 }
1468 }
1469
1470 bool OBResidue::IsResidueType(int restype) const
1471 {
1472 return ((int)_reskey == restype);
1473 }
1474
1475 // OBGenericData methods
1476 bool OBResidue::HasData(string &s)
1477 //returns true if the generic attribute/value pair exists
1478 {
1479 if (_vdata.empty())
1480 return(false);
1481
1482 vector<OBGenericData*>::iterator i;
1483
1484 for (i = _vdata.begin();i != _vdata.end();i++)
1485 if ((*i)->GetAttribute() == s)
1486 return(true);
1487
1488 return(false);
1489 }
1490
1491 bool OBResidue::HasData(const char *s)
1492 //returns true if the generic attribute/value pair exists
1493 {
1494 if (_vdata.empty())
1495 return(false);
1496
1497 vector<OBGenericData*>::iterator i;
1498
1499 for (i = _vdata.begin();i != _vdata.end();i++)
1500 if ((*i)->GetAttribute() == s)
1501 return(true);
1502
1503 return(false);
1504 }
1505
1506 bool OBResidue::HasData(unsigned int dt)
1507 //returns true if the generic attribute/value pair exists
1508 {
1509 if (_vdata.empty())
1510 return(false);
1511
1512 vector<OBGenericData*>::iterator i;
1513
1514 for (i = _vdata.begin();i != _vdata.end();i++)
1515 if ((*i)->GetDataType() == dt)
1516 return(true);
1517
1518 return(false);
1519 }
1520
1521 OBGenericData *OBResidue::GetData(string &s)
1522 //returns the value given an attribute
1523 {
1524 vector<OBGenericData*>::iterator i;
1525
1526 for (i = _vdata.begin();i != _vdata.end();i++)
1527 if ((*i)->GetAttribute() == s)
1528 return(*i);
1529
1530 return(NULL);
1531 }
1532
1533 OBGenericData *OBResidue::GetData(const char *s)
1534 //returns the value given an attribute
1535 {
1536 vector<OBGenericData*>::iterator i;
1537
1538 for (i = _vdata.begin();i != _vdata.end();i++)
1539 if ((*i)->GetAttribute() == s)
1540 return(*i);
1541
1542 return(NULL);
1543 }
1544
1545 OBGenericData *OBResidue::GetData(unsigned int dt)
1546 {
1547 vector<OBGenericData*>::iterator i;
1548 for (i = _vdata.begin();i != _vdata.end();i++)
1549 if ((*i)->GetDataType() == dt)
1550 return(*i);
1551 return(NULL);
1552 }
1553
1554 void OBResidue::DeleteData(unsigned int dt)
1555 {
1556 vector<OBGenericData*> vdata;
1557 vector<OBGenericData*>::iterator i;
1558 for (i = _vdata.begin();i != _vdata.end();i++)
1559 if ((*i)->GetDataType() == dt)
1560 delete *i;
1561 else
1562 vdata.push_back(*i);
1563 _vdata = vdata;
1564 }
1565
1566 void OBResidue::DeleteData(vector<OBGenericData*> &vg)
1567 {
1568 vector<OBGenericData*> vdata;
1569 vector<OBGenericData*>::iterator i,j;
1570
1571 bool del;
1572 for (i = _vdata.begin();i != _vdata.end();i++)
1573 {
1574 del = false;
1575 for (j = vg.begin();j != vg.end();j++)
1576 if (*i == *j)
1577 {
1578 del = true;
1579 break;
1580 }
1581 if (del)
1582 delete *i;
1583 else
1584 vdata.push_back(*i);
1585 }
1586 _vdata = vdata;
1587 }
1588
1589 void OBResidue::DeleteData(OBGenericData *gd)
1590 {
1591 vector<OBGenericData*>::iterator i;
1592 for (i = _vdata.begin();i != _vdata.end();i++)
1593 if (*i == gd)
1594 {
1595 delete *i;
1596 _vdata.erase(i);
1597 }
1598
1599 }
1600
1601 } // end namespace OpenBabel
1602
1603 //! \file residue.cpp
1604 //! \brief Handle macromolecule residues.