1 //  $Id: mmdb_atom.h $
2 //  =================================================================
3 //
4 //   CCP4 Coordinate Library: support of coordinate-related
5 //   functionality in protein crystallography applications.
6 //
7 //   Copyright (C) Eugene Krissinel 2000-2015.
8 //
9 //    This library is free software: you can redistribute it and/or
10 //    modify it under the terms of the GNU Lesser General Public
11 //    License version 3, modified in accordance with the provisions
12 //    of the license to address the requirements of UK law.
13 //
14 //    You should have received a copy of the modified GNU Lesser
15 //    General Public License along with this library. If not, copies
16 //    may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
17 //
18 //    This program is distributed in the hope that it will be useful,
19 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
20 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 //    GNU Lesser General Public License for more details.
22 //
23 //  =================================================================
24 //
25 //    09.03.16   <--  Date of Last Modification.
26 //                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 //  -----------------------------------------------------------------
28 //
29 //  **** Module  :  MMDB_Atom <interface>
30 //       ~~~~~~~~~
31 //  **** Project :  MacroMolecular Data Base (MMDB)
32 //       ~~~~~~~~~
33 //  **** Classes :  mmdb::Atom     ( atom class    )
34 //       ~~~~~~~~~  mmdb::Residue  ( residue class )
35 //  **** Functions: mmdb::BondAngle
36 //       ~~~~~~~~~~
37 //
38 //  Copyright (C) E. Krissinel 2000-2016
39 //
40 //  =================================================================
41 //
42 
43 #ifndef __MMDB_Atom__
44 #define __MMDB_Atom__
45 
46 #include "mmdb_io_stream.h"
47 #include "mmdb_uddata.h"
48 #include "mmdb_utils.h"
49 #include "mmdb_defs.h"
50 
51 
52 namespace mmdb  {
53 
54   //  ======================  Atom  ==========================
55 
56   // constants for the WhatIsSet field
57   enum ASET_FLAG  {
58     ASET_Coordinates  = 0x00000001,
59     ASET_Occupancy    = 0x00000002,
60     ASET_tempFactor   = 0x00000004,
61     ASET_CoordSigma   = 0x00000010,
62     ASET_OccSigma     = 0x00000020,
63     ASET_tFacSigma    = 0x00000040,
64     ASET_Anis_tFac    = 0x00000100,
65     ASET_Anis_tFSigma = 0x00001000,
66     ASET_Charge       = 0x00000080,
67     ASET_All          = 0x000FFFFF
68   };
69 
70   const int ATOM_NoSeqNum = MinInt4;
71 
72   extern bool  ignoreSegID;
73   extern bool  ignoreElement;
74   extern bool  ignoreCharge;
75   extern bool  ignoreNonCoorPDBErrors;
76   extern bool  ignoreUnmatch;
77 
78 
79   DefineStructure(AtomStat);
80 
81   struct AtomStat  {
82 
83     public :
84       int       nAtoms;          // number of atoms in statistics
85 
86       realtype  xmin,ymin,zmin;  // minimums of coordinates
87       realtype  xmax,ymax,zmax;  // maximums of coordinates
88       realtype  xm  ,ym  ,zm;    // mediums  of coordinates
89       realtype  xm2 ,ym2 ,zm2;   // square mediums of coordinates
90 
91       realtype  occ_min,occ_max; // minimum/maximum occupancy
92       realtype  occ_m  ,occ_m2;  // medium and square medium occupancy
93 
94       realtype  tFmin,tFmax;     // minimum/maximum temperature factor
95       realtype  tFm  ,tFm2;      // medium and sq. med. temp. factor
96 
97       realtype  u11_min,u11_max; // minimums and
98       realtype  u22_min,u22_max; //   maximums of
99       realtype  u33_min,u33_max; //     anisotropic
100       realtype  u12_min,u12_max; //       temperature
101       realtype  u13_min,u13_max; //         factors
102       realtype  u23_min,u23_max;
103 
104       realtype  u11_m,u11_m2;    // mediums and
105       realtype  u22_m,u22_m2;    //   square mediums of
106       realtype  u33_m,u33_m2;    //     anisotropic
107       realtype  u12_m,u12_m2;    //       temperature
108       realtype  u13_m,u13_m2;    //         factors
109       realtype  u23_m,u23_m2;
110 
111       word      WhatIsSet;       //   mask field
112 
113       void  Init  ();
114       void  Finish();
115 
116       realtype GetMaxSize();
117 
118     private :
119       bool finished;
120 
121   };
122 
123 
124   DefineStructure(AtomBondI);
125 
126   struct AtomBondI  {
127     int  index;  //!< bonded atom index
128     byte order;  //!< bond order
129   };
130 
131 
132   DefineStructure(AtomBond);
133 
134   struct AtomBond  {
135     PAtom atom;  //!< bonded atom pointer
136     byte  order;  //!< bond order
137   };
138 
139 
140   DefineFactoryFunctions(Atom);
141 
142   class Atom : public UDData  {
143 
144     friend class Residue;
145     friend class Model;
146     friend class Root;
147     friend class CoorManager;
148     friend class SelManager;
149 
150     public :
151       int        serNum;         //!< serial number
152       AtomName   name;           //!< atom name (ALIGNED)
153       AtomName   label_atom_id;  //!< assigned atom name (not aligned)
154       AltLoc     altLoc; //!< alternative location indicator ("" for none)
155       SegID      segID;          //!< segment identifier
156       Element    element;        //!< element symbol (ALIGNED TO RIGHT)
157       EnergyType energyType;     //!< energy type (without spaces)
158       PResidue   residue;        //!< reference to residue
159       realtype   x,y,z;          //!< orthogonal coordinates in angstroms
160       realtype   occupancy;      //!< occupancy
161       realtype   tempFactor;     //!< temperature factor
162       realtype   charge;         //!< charge on the atom
163       realtype   sigX,sigY,sigZ; //!< standard deviations of the coords
164       realtype   sigOcc;         //!< standard deviation of occupancy
165       realtype   sigTemp;        //!< standard deviation of temp. factor
166       realtype   u11,u22,u33;    //!< anisotropic temperature
167       realtype   u12,u13,u23;    ///    factors
168       realtype   su11,su22,su33; //!< standard deviations of
169       realtype   su12,su13,su23; ///    anisotropic temperature factors
170       bool       Het;            //!< indicator of het atom
171       bool       Ter;            //!< chain terminator
172 
173       word       WhatIsSet;      //!<   mask      field
174                          ///  0x0001   atomic coordinates
175                          ///  0x0002   occupancy
176                          ///  0x0004   temperature factor
177                          ///  0x0010   coordinate standard deviations
178                          ///  0x0020   deviation of occupancy
179                          ///  0x0040   deviation of temperature factor
180                          ///  0x0100   anisotropic temperature factors
181                          ///  0x1000   anis. temp. fact-s st-d deviations
182 
183       Atom ();
184       Atom ( PResidue     res    );
185       Atom ( io::RPStream Object );
186       ~Atom();
187 
188       void  SetResidue   ( PResidue     res );
189       void  PDBASCIIDump ( io::RFile    f   );
190       void  MakeCIF      ( mmcif::PData CIF );
191 
192       //    AddBond(...) adds a bond to the atom, that is a pointer
193       //  to the bonded atom and the bond order. nAdd_bonds allows
194       //  one to minimize the memory reallocations, if number of
195       //  bonds is known apriori: Atom adds space for nAdd_bonds
196       //  if currently allocated space is exchausted.
197       //    Return:  <=0  - error: bond_atom is already "bonded"
198       //              >0  - Ok, returns current number of bonds
199       int   AddBond  ( PAtom bond_atom, int bond_order,
200                                         int nAdd_bonds=1 );
201       int   GetNBonds();
202 
203       //    This GetBonds(..) returns pointer to the Atom's
204       //  internal Bond structure, IT MUST NOT BE DISPOSED.
205       void  GetBonds ( RPAtomBond atomBond, int & nAtomBonds );
206       void  FreeBonds();
207 
208       //    This GetBonds(..) disposes AtomBondI, if it was not set
209       //  to NULL, allocates AtomBondI[nAtomBonds] and returns its
210       //  pointer. AtomBondI MUST BE DISPOSED BY APPLICATION.
211       void  GetBonds ( RPAtomBondI atomBondI, int & nAtomBonds );
212 
213       //    This GetBonds(..) does not dispose or allocate AtomBondI.
214       //  It is assumed that length of AtomBondI is sufficient to
215       //  accomodate all bonded atoms.
216       void  GetBonds ( PAtomBondI atomBondI, int & nAtomBonds,
217                        int maxlength );
218 
219 
220       //   ConvertPDBxxxxxx() gets data from the PDB ASCII xxxxxx
221       // record (xxxxxx stands for ATOM, SIGATM, ANISOU, SIGUIJ,
222       // TER or HETATM).
223       //   These functions DO NOT check the xxxxxx keyword and
224       // do not decode the chain and residue parameters! These
225       // must be treated by the calling process, see
226       // CMMDBFile::ReadPDBAtom().
227       //   The atom reference is updated in the corresponding
228       // residue.
229       ERROR_CODE ConvertPDBATOM   ( int ix, cpstr S );
230       ERROR_CODE ConvertPDBSIGATM ( int ix, cpstr S );
231       ERROR_CODE ConvertPDBANISOU ( int ix, cpstr S );
232       ERROR_CODE ConvertPDBSIGUIJ ( int ix, cpstr S );
233       ERROR_CODE ConvertPDBTER    ( int ix, cpstr S );
234       ERROR_CODE ConvertPDBHETATM ( int ix, cpstr S );
235 
236       ERROR_CODE GetCIF           ( int ix, mmcif::PLoop Loop,
237                                      mmcif::PLoop LoopAnis );
238 
239       bool RestoreElementName();
240       bool MakePDBAtomName();
241 
242       void  SetAtomName    ( int            ix,      // index
243                              int            sN,      // serial number
244                              const AtomName aName,   // atom name
245                              const AltLoc   aLoc, // alternative location
246                              const SegID    sID,     // segment ID
247                              const Element  eName ); // element name
248 
249       //  This only renames the atom
250       void  SetAtomName    ( const AtomName atomName );
251       void  SetElementName ( const Element  elName   );
252       void  SetCharge      ( cpstr          chrg     );
253       void  SetCharge      ( realtype       chrg     );
254 
255       void  SetAtomIndex   ( int ix ); // don't use in your applications!
256 
257       void  MakeTer();  // converts atom into 'ter'
258 
259       void  SetCoordinates ( realtype xx,  realtype yy, realtype zz,
260                              realtype occ, realtype tFac );
261 
262       int   GetModelNum       ();
263       pstr  GetChainID        ();
264       pstr  GetLabelAsymID    ();
265       pstr  GetResName        ();
266       pstr  GetLabelCompID    ();
267       int   GetAASimilarity   ( const ResName resName );
268       int   GetAASimilarity   ( PAtom  A );
269       realtype GetAAHydropathy();
270       realtype GetOccupancy   ();
271       int   GetSeqNum         ();
272       int   GetLabelSeqID     ();
273       int   GetLabelEntityID  ();
274       pstr  GetInsCode        ();
275       int   GetSSEType        ();  // works only after SSE calculations
GetAtomName()276       pstr  GetAtomName       () { return name;    }
GetElementName()277       pstr  GetElementName    () { return element; }
278       pstr  GetAtomCharge     ( pstr chrg );
279 
280       //   GetChainCalphas(...) is a specialized function for quick
281       // access to C-alphas of chain which includes given atom.
282       // This function works faster than an equivalent implementation
283       // through MMDB's selection procedures.
284       //    Parameters:
285       //       Calphas   - array to accept pointers on C-alpha atoms
286       //                  If Calphas!=NULL, then the function will
287       //                  delete and re-allocate it. When the array
288       //                  is no longer needed, the application MUST
289       //                  delete it:  delete[] Calphas; Deleting
290       //                  Calphas does not delete atoms from MMDB.
291       //       nCalphas   - integer to accept number of C-alpha atoms
292       //                  and the length of Calphas array.
293       //       altLoc     - alternative location indicator. By default
294       //                  (""), maximum-occupancy locations are taken.
295       void  GetChainCalphas ( PPAtom & Calphas, int & nCalphas,
296                               cpstr altLoc = "" );
297 
isTer()298       bool isTer         () { return Ter; }
299       bool isMetal       ();
300       bool isSolvent     ();  // works only for atom in a residue!
301       bool isInSelection ( int selHnd );
302       bool isNTerminus   ();
303       bool isCTerminus   ();
304 
305       void  CalAtomStatistics ( RAtomStat AS );
306 
307       realtype GetDist2 ( PAtom a );
308       realtype GetDist2 ( PAtom a, mat44 & tm );  // tm applies to 'a'
309       realtype GetDist2 ( PAtom a, mat33 & r, vect3 & t );// tm applies to A
310       realtype GetDist2 ( realtype ax, realtype ay, realtype az );
311       realtype GetDist2 ( mat44 & tm,  // applies to 'this'
312                           realtype ax, realtype ay, realtype az  );
313       realtype GetDist2 ( vect3 & xyz );
314 
315       // GetCosine(a1,a2) calculates cosine of angle a1-this-a2,
316       // i.e. that between vectors [a1,this] and [this,a2].
317       realtype GetCosine ( PAtom a1, PAtom a2 );
318 
319       PResidue GetResidue  ();
320       PChain   GetChain    ();
321       PModel   GetModel    ();
322       int      GetResidueNo();
323       void *   GetCoordHierarchy();  // PRoot
324 
325       //  GetAtomID(..) generates atom ID in the form
326       //     /m/c/r(rn).i/n[e]:a
327       //  where  m  - model number
328       //         c  - chain ID
329       //         r  - residue sequence number
330       //         rn - residue name
331       //         i  - insertion code
332       //         n  - atom name
333       //         e  - chemical element specification
334       //         a  - alternate location indicator
335       //  If any of the fields is undefined, it is replaced by
336       //  hyphen  '-'.
337       //    No checks on the sufficiency of string buffer AtomID
338       //  is made.
339       //    GetAtomID returns AtomID.
340       pstr  GetAtomID ( pstr AtomID );
341 
342       pstr  GetAtomIDfmt ( pstr AtomID );
343 
344       // -------  checking atom ID
345       // CheckID(..) returns 1 if atom is identified, and 0 otherwise.
346       //   Parameters:
347       //     aname   - atom name. It may or may not be aligned (as in
348       //               a PDB file), only first word of the name will
349       //               be taken ("CA", " CA" and " CA B" are all
350       //               considered as "CA"). aname may be set to NULL
351       //               or '*', then this parameter is ignored.
352       //     elname  - element code. It will work only if element code
353       //               is supplied (which might not be the case if
354       //               the atom was created in a tricky way). elname
355       //               should be used to distinguih between, e.g.
356       //               "Ca" and "C_alpha"). elname may be set to NULL,
357       //               or '*', then this parameter is ignored.
358       //     aloc    - the alternate location code. aloc may be set to
359       //               NULL or '*', then this parameter is ignored.
360       //  IMPORTANT: comparison is case-sensitive.
361       //  The atom is considered as identified, if all non-NULL
362       //  parameters do match. If all parameters are set NULL, any atom
363       //  is identified.
364       //  DEFAULT values correspond to 'any element' and
365       //                 'no alternate location code'
366       //  NOTE that " " is not an empty item.
367       int   CheckID ( const AtomName aname, const Element elname=NULL,
368                       const AltLoc aloc=pstr("") );
369 
370       // CheckIDS(..) works exactly like CheckID(..), but it takes
371       // the only parameter, the atom ID, which is of the form:
372       //    {name} {[element]} {:altcode}
373       // Here {} means that the item may be omitted. Any item may be
374       // represented by a wildcard '*', which means 'any value'. Just
375       // absence of an item means 'empty', which makes sense only for
376       // alternate location code. Missing name or element therefore
377       // mean 'any name' or 'any element', correspondingly (same as a
378       // wildcard). There should be no spaces in ID except for leading
379       // spaces; any following space will terminate parsing.
380       // The followings are perfectly valid IDs:
381       //   CA[C]:A     (carbon C_alpha in location A)
382       //   CA[*]:A     (either C_alpha or Ca in location A)
383       //   CA:A        (same as above)
384       //   CA          (either C_alpha or Ca with no location indicator)
385       //   CA[]        (same as above)
386       //   CA[C]:      (C_alpha with no location indicator)
387       //   [C]         (any carbon with no location indicator)
388       //   [C]:*       (any carbon with any location indicator)
389       //   *[C]:*      (same as above)
390       //   :A          (any atom in location A)
391       //   *[*]:A      (same as above)
392       //   *[*]:*      (any atom)
393       //   *           (any atom with no alternate location indicator)
394       int   CheckIDS ( cpstr ID );
395 
396 
397       // -------  transform coordinates: x := m*x + v
398       void  Transform     ( const mat33 & tm, vect3 & v );
399       void  Transform     ( const mat44 & tm );
400       void  TransformCopy ( const mat44 & tm,
401                             realtype & xx, realtype & yy, realtype & zz );
402       void  TransformCopy ( const mat44 & tm, vect3 & xyz );
403       void  TransformSet  ( const mat44 & tm,
404                             realtype xx, realtype yy, realtype zz );
405 
406 
407       // -------  user-defined data handlers
408       int   PutUDData ( int UDDhandle, int      iudd );
409       int   PutUDData ( int UDDhandle, realtype rudd );
410       int   PutUDData ( int UDDhandle, cpstr    sudd );
411 
412       int   GetUDData ( int UDDhandle, int      & iudd );
413       int   GetUDData ( int UDDhandle, realtype & rudd );
414       int   GetUDData ( int UDDhandle, pstr sudd, int maxLen );
415       int   GetUDData ( int UDDhandle, pstr     & sudd );
416 
417 
GetIndex()418       int   GetIndex()  { return index; }
419 
420       virtual void Copy ( PAtom atom );  // without references in
421                                           // residues
422 
423       void  SetCompactBinary();  // leaves only coordinates in binary files
424       void  write ( io::RFile f );
425       void  read  ( io::RFile f );
426 
427     protected :
428       int       index;   // index in the file
429       int       nBonds;  // number of bonds in the lowest byte (!)
430       PAtomBond Bond;    // atom bonds
431 
432       void  InitAtom       ();
433       void  FreeMemory     ();
434       void  StandardPDBOut ( cpstr Record, pstr S );
435       void  GetData        ( cpstr S );
436       ERROR_CODE CheckData ( cpstr S );
437       void  GetStat        ( realtype   v,
438                              realtype & v_min, realtype & v_max,
439                              realtype & v_m,   realtype & v_m2 );
440       void  _setBonds      ( PPAtom A ); // used only in Residue
441 
442   };
443 
444 
445   //  ======================  Residue  ==========================
446 
447   enum ALTLOC_FLAG  {
448     ALF_NoAltCodes    = 0x00000000,
449     ALF_EmptyAltLoc   = 0x00000001,
450     ALF_NoEmptyAltLoc = 0x00000002,
451     ALF_Mess          = 0x00000004,
452     ALF_Occupancy     = 0x00000008
453   };
454 
455   enum SSE_FLAG  {
456     SSE_None   = 0,
457     SSE_Strand = 1,
458     SSE_Bulge  = 2,
459     SSE_3Turn  = 3,
460     SSE_4Turn  = 4,
461     SSE_5Turn  = 5,
462     SSE_Helix  = 6
463   };
464 
465   DefineFactoryFunctions(Residue);
466 
467   class Residue : public UDData  {
468 
469     friend class Atom;
470     friend class Chain;
471     friend class Root;
472 
473     public :
474 
475       ResName  name;            //!< residue name - all spaces cut
476       ResName  label_comp_id;   //!< assigned residue name
477       ChainID  label_asym_id;   //!< assigned chain Id
478       InsCode  insCode;         //!< residue insertion code
479       PChain   chain;           //!< reference to chain
480       PPAtom   atom;            //!< array of atoms
481       int      seqNum;          //!< residue sequence number
482       int      label_seq_id;    //!< assigned residue sequence number
483       int      label_entity_id; //!< assigned entity id
484       int      index;           //!< index in the chain
485       int      nAtoms;          //!< number of atoms in the residue
486       byte     SSE;             //!< SSE type
487 
488       Residue ();
489       Residue ( PChain Chain_Owner );
490       Residue ( PChain Chain_Owner, const ResName resName,
491                 int    sqNum,       const InsCode ins );
492       Residue ( io::RPStream Object    );
493       ~Residue();
494 
495       void  SetChain ( PChain Chain_Owner );
496       void  SetResID ( const ResName resName, int sqNum,
497                        const InsCode ins );
498       void  SetChainID ( const ChainID chID );
499 
500       void  PDBASCIIAtomDump ( io::RFile f      );
501       void  MakeAtomCIF      ( mmcif::PData CIF );
502 
503       PChain GetChain();
504       PModel GetModel();
505 
506       int   GetModelNum   ();
507       pstr  GetChainID    ();
508       pstr  GetLabelAsymID();
509       pstr  GetResName    ();
510 //      inline pstr  GetResName() { return name; }
511       pstr  GetLabelCompID();
512       int   GetAASimilarity ( const ResName resName );
513       int   GetAASimilarity ( PResidue res );
514       realtype GetAAHydropathy();
515       void  SetResName      ( const ResName resName );
516       int   GetSeqNum       ();
517       int   GetLabelSeqID   ();
518       int   GetLabelEntityID();
519       pstr  GetInsCode      ();
520       int   GetResidueNo    ();
521       int   GetCenter       ( realtype & x, realtype & y, realtype & z );
522       void * GetCoordHierarchy();  // PCMMDBFile
523 
524       void  GetAtomStatistics ( RAtomStat AS );
525       void  CalAtomStatistics ( RAtomStat AS );
526 
527       pstr  GetResidueID ( pstr ResidueID );
528 
529       //   GetAltLocations(..) returns the number of different
530       // alternative locations in nAltLocs, the locations themselves
531       // - in aLoc and the corresponding occupancies - in occupancy.
532       //   aLoc and occupancy are allocated dynamically; it is
533       // responsibility of the application to deallocate aLoc prior
534       // calling GetAltLocations(..) if they were previously allocated.
535       // Either, the application is responsible for deallocating aLoc and
536       // occupancy after use.
537       //   occupancy[i] may return -1.0 if occupancies were not read
538       // from coordinate file.
539       //   alflag returns ALF_NoAltCodes if no alt codes was found,
540       // otherwise the output is decoded according to bits:
541       //   ALF_EmptyAltLoc   alternative locations include the
542       //                     "no alt loc indicator" ("" for
543       //                     Atom::altLoc).
544       //                     This means that each atom that has alt locs
545       //                     different of "", also includes one marked as
546       //                     "".
547       //  ALF_NoEmptyAltLoc  alternative locations do not include the
548       //                     "no alt loc indicator" ("" for
549       //                     Atom::altLoc).
550       //                     This means that each atom has either ""
551       //                     alt loc or at least two alt locs different
552       //                     of "".
553       //  ALF_Mess           incorrect residue: it mixes both
554       //                     ""-including and not-""-including schemes
555       //  ALF_Occupancy      warning that sum of occupancies for alt
556       //                     located atoms differ from 1.0 by more
557       //                     than 0.01.
558       void  GetAltLocations   ( int & nAltLocs, PAltLoc & aLoc,
559                                 rvector & occupancy, int & alflag );
560       int   GetNofAltLocations();
561 
562       bool isAminoacid   ();
563       bool isNucleotide  ();
564       int  isDNARNA      (); // 0(neither),1(DNA),2(RNA)
565       bool isSugar       ();
566       bool isSolvent     ();
567       bool isModRes      ();
568       bool isInSelection ( int selHnd );
569       bool isNTerminus   ();
570       bool isCTerminus   ();
571 
572       // -------  checking residue ID
573       // CheckID(..) returns 1 if residue is identified, and 0 otherwise.
574       //   Parameters:
575       //     sname   - pointer to sequence number; if NULL then ignored.
576       //     inscode - insertion code; if NULL or '*' then ignored.
577       //     resname - residue name; if NULL or '*' then ignored.
578       //  IMPORTANT: comparison is case-sensitive.
579       //  The residue is considered as identified, if all non-NULL
580       //  parameters do match. If all parameters are set NULL, any
581       //  residue is identified.
582       //  DEFAULT values correspond to 'any residue name' and
583       //                 'no insertion code'
584       //  NOTE that " " is not an empty item.
585       int   CheckID ( int * snum, const InsCode inscode=pstr(""),
586                       const ResName resname=NULL );
587 
588       // CheckIDS(..) works exactly like CheckID(..), but it takes
589       // the only parameter, the residue ID, which is of the form:
590       //    {seqnum} {(name)} {.inscode}
591       // Here {} means that the item may be omitted. Any item may be
592       // represented by a wildcard '*', which means 'any value'. Just
593       // absence of a value means 'empty', which is meaningful only for
594       // the insertion code. Missing sequence number or residue name
595       // therefore mean 'any sequence number' or 'any residue name',
596       // correspondingly (same as a wildcard).  There should be no
597       // spaces in ID except for leading spaces; any following space will
598       // terminate parsing. The followings are perfectly valid IDs:
599       //        27(ALA).A   (residue 27A ALA)
600       //        27().A      (residue 27A)
601       //        27(*).A     (same as above)
602       //        27.A        (same as above)
603       //        27          (residue 27)
604       //        27().       (same as above)
605       //        (ALA)       (any ALA without insertion code)
606       //        (ALA).      (same as above)
607       //        (ALA).*     (any ALA)
608       //        *(ALA).*    (any ALA)
609       //        .A          (any residue with insertion code A)
610       //        *(*).A      (same as above)
611       //        *(*).*      (any residue)
612       //        *           (any residue with no insertion code)
613       int  CheckIDS ( cpstr ID );
614 
615 
616       //  --------------------  Extracting atoms  ----------------------
617 
618       int  GetNumberOfAtoms ();
619       int  GetNumberOfAtoms ( bool countTers );
620 
621       PAtom GetAtom ( const AtomName aname, const Element elname=NULL,
622                       const AltLoc aloc=cpstr("") );
623       PAtom GetAtom ( int atomNo );
624 
625       void GetAtomTable  ( PPAtom & atomTable, int & NumberOfAtoms );
626 
627       //   GetAtomTable1(..) returns atom table without TER atoms and
628       // without NULL atom pointers. NumberOfAtoms returns the actual
629       // number of atom pointers in atomTable.
630       //   atomTable is allocated withing the function. If it was
631       // not set to NULL before calling the function, the latter will
632       // attempt to deallocate it first.
633       //   The application is responsible for deleting atomTable,
634       // however it must not touch atom pointers, i.e. use simply
635       // "delete[] atomTable;". Never pass atomTable from GetAtomTable()
636       // into this function, unless you set it to NULL before doing that.
637       void GetAtomTable1 ( PPAtom & atomTable, int & NumberOfAtoms );
638 
639 
640       //  ---------------------  Deleting atoms  -----------------------
641 
642       int  DeleteAtom ( const AtomName aname, const Element elname=NULL,
643                         const AltLoc aloc=cpstr("") );
644       int  DeleteAtom ( int atomNo );
645       int  DeleteAllAtoms();
646 
647       //   DeleteAltLocs() leaves only alternative location with maximal
648       // occupancy, if those are equal or unspecified, the one with
649       // "least" alternative location indicator.
650       //   The function returns the number of deleted atoms. The atom
651       // table remains untrimmed, so that nAtoms are wrong until that
652       // is done. Tables are trimmed by FinishStructEdit() or
653       // explicitely.
654       int  DeleteAltLocs ();
655 
656       void TrimAtomTable ();
657 
658       //  ----------------------  Adding atoms  ------------------------
659 
660       //   AddAtom(..) adds atom to the residue. If residue is associated
661       // with a coordinate hierarchy, and atom 'atm' is not, the latter
662       // is checked in automatically. If atom 'atm' belongs to any
663       // coordinate hierarchy (even though that of the residue), it is
664       // *copied* rather than simply taken over, and is checked in.
665       //   If residue is not associated with a coordinate hierarchy, all
666       // added atoms will be checked in automatically once the residue
667       // is checked in.
668       int  AddAtom ( PAtom atm );
669 
670       //   InsertAtom(..) inserts atom into the specified position of
671       // the residue. If residue is associated with a coordinate
672       // hierarchy, and atom 'atm' is not, the latter is checked in
673       // automatically. If atom 'atm' belongs to any coordinate
674       // hierarchy (even though that of the residue), it is *copied*
675       // rather than simply taken over, and is checked in.
676       //   If residue is not associated with a coordinate hierarchy, all
677       // added atoms will be checked in automatically once the residue
678       // is checked in.
679       int  InsertAtom ( PAtom atm, int position );
680 
681       //   This version inserts before the atom with given name. If such
682       // name is not found, the atom is appended to the end.
683       int  InsertAtom ( PAtom atm, const AtomName aname );
684 
685       //  --------------------------------------------------------------
686 
687       void  ApplyTransform ( const mat44 & TMatrix );  // transforms all
688                                                  // coordinates by
689                                                  // multiplying with
690                                                  // matrix TMatrix
691 
692       void  MaskAtoms   ( PMask Mask );
693       void  UnmaskAtoms ( PMask Mask );
694 
695 
696       // -------  user-defined data handlers
697       int   PutUDData ( int UDDhandle, int      iudd );
698       int   PutUDData ( int UDDhandle, realtype rudd );
699       int   PutUDData ( int UDDhandle, cpstr    sudd );
700 
701       int   GetUDData ( int UDDhandle, int      & iudd );
702       int   GetUDData ( int UDDhandle, realtype & rudd );
703       int   GetUDData ( int UDDhandle, pstr sudd, int maxLen );
704       int   GetUDData ( int UDDhandle, pstr     & sudd );
705 
706 
707       bool isMainchainHBond ( PResidue res );
708 
709       void  Copy  ( PResidue res );
710 
711       void  write ( io::RFile f );
712       void  read  ( io::RFile f );
713 
714     protected :
715 
716       int   AtmLen;   // length of atom array
717       bool  Exclude;  // used internally
718 
719       void  InitResidue  ();
720       void  FreeMemory   ();
721       int   _AddAtom     ( PAtom atm );
722       int   _ExcludeAtom ( int  kndex );  // 1: residue gets empty,
723                                           // 0 otherwise
724       void  _copy ( PResidue res );
725       void  _copy ( PResidue res, PPAtom atm, int & atom_index );
726       void  ExpandAtomArray ( int nAdd );
727       void  CheckInAtoms ();
728 
729   };
730 
731 
732   extern realtype  BondAngle ( PAtom A, PAtom B, PAtom C );
733 
734 }  // namespace mmdb
735 
736 #endif
737 
738