Bioplib
Protein Structure C Library
 All Data Structures Files Functions Variables Typedefs Macros Pages
OrderPDB.c
Go to the documentation of this file.
1 /************************************************************************/
2 /**
3 
4  \file OrderPDB.c
5 
6  \version V1.6
7  \date 05.03.15
8  \brief Functions to modify atom order in PDB linked list
9 
10  \copyright (c) UCL / Dr. Andrew C. R. Martin 1993-2015
11  \author Dr. Andrew C. R. Martin
12  \par
13  Institute of Structural & Molecular Biology,
14  University College London,
15  Gower Street,
16  London.
17  WC1E 6BT.
18  \par
19  andrew@bioinf.org.uk
20  andrew.martin@ucl.ac.uk
21 
22 **************************************************************************
23 
24  This code is NOT IN THE PUBLIC DOMAIN, but it may be copied
25  according to the conditions laid out in the accompanying file
26  COPYING.DOC.
27 
28  The code may be modified as required, but any modifications must be
29  documented so that the person responsible can be identified.
30 
31  The code may not be sold commercially or included as part of a
32  commercial product except as described in the file COPYING.DOC.
33 
34 **************************************************************************
35 
36  Description:
37  ============
38 
39 
40 **************************************************************************
41 
42  Usage:
43  ======
44 
45 **************************************************************************
46 
47  Revision History:
48  =================
49 - V1.0 22.02.04 Original
50 - V1.1 09.03.94 Bug fix in ShuffleResPDB(). Added PCA to sAtoms table
51 - V1.2 18.03.94 Bug fix in ShuffleResPDB().
52 - V1.3 22.06.08 Bug fix in ShuffleBB()
53 - V1.4 07.07.14 Use bl prefix for functions By: CTP
54 - V1.5 23.02.15 Modified for new blRenumAtomsPDB() which takes an
55  offset By: ACRM
56 - V1.6 05.03.15 Replaced blFindEndPDB() with blFindNextResidue()
57 
58 *************************************************************************/
59 /* Doxygen
60  -------
61  #GROUP Handling PDB Data
62  #SUBGROUP Manipulating the PDB linked list
63  #FUNCTION blFixOrderPDB()
64  Runs through a PDB linked list and corrects the atom order to match
65  the N,CA,C,O,s/c standard.
66 
67  #FUNCTION blShuffleResPDB()
68  Shuffle atoms within a residue into the standard order
69 
70  #FUNCTION blGetAtomTypes()
71  Obtain a list of the atom types for a given residue.
72 
73  #FUNCTION blShuffleBB()
74  Shuffles the PDB list to match the standard of N,CA,C,O,CB,other.
75 */
76 /************************************************************************/
77 /* Includes
78 */
79 #include <math.h>
80 #include <string.h>
81 #include <stdlib.h>
82 
83 #include "MathType.h"
84 #include "macros.h"
85 #include "pdb.h"
86 
87 /************************************************************************/
88 /* Defines and macros
89 */
90 
91 /************************************************************************/
92 /* Globals
93 */
94 static char sAtoms[MAXSTDAA][MAXATINRES+1][8] =
95 {{"ALA","N ","CA ","C ","O ","CB "," "," "," "," ",
96  " "," "," "," "," "},
97  {"ARG","N ","CA ","C ","O ","CB ","CG ","CD ","NE ","CZ ",
98  "NH1 ","NH2 "," "," "," "},
99  {"ASN","N ","CA ","C ","O ","CB ","CG ","OD1 ","ND2 "," ",
100  " "," "," "," "," "},
101  {"ASP","N ","CA ","C ","O ","CB ","CG ","OD1 ","OD2 "," ",
102  " "," "," "," "," "},
103  {"CYS","N ","CA ","C ","O ","CB ","SG "," "," "," ",
104  " "," "," "," "," "},
105  {"GLN","N ","CA ","C ","O ","CB ","CG ","OE1 ","NE2 "," ",
106  " "," "," "," "," "},
107  {"GLU","N ","CA ","C ","O ","CB ","CG ","CD ","OE1 ","OE2 ",
108  " "," "," "," "," "},
109  {"GLY","N ","CA ","C ","O "," "," "," "," "," ",
110  " "," "," "," "," "},
111  {"HIS","N ","CA ","C ","O ","CB ","CG ","ND1 ","CD2 ","CE1 ",
112  "NE2 "," "," "," "," "},
113  {"ILE","N ","CA ","C ","O ","CB ","CG1 ","CG2 ","CD "," ",
114  " "," "," "," "," "},
115  {"LEU","N ","CA ","C ","O ","CB ","CG ","CD1 ","CD2 "," ",
116  " "," "," "," "," "},
117  {"LYS","N ","CA ","C ","O ","CB ","CG ","CD ","CE ","NZ ",
118  " "," "," "," "," "},
119  {"MET","N ","CA ","C ","O ","CB ","CG ","SD ","CE "," ",
120  " "," "," "," "," "},
121  {"PHE","N ","CA ","C ","O ","CB ","CG ","CD1 ","CD2 ","CE1 ",
122  "CE2 ","CZ "," "," "," "},
123  {"PRO","N ","CA ","C ","O ","CB ","CG ","CD "," "," ",
124  " "," "," "," "," "},
125  {"SER","N ","CA ","C ","O ","CB ","OG "," "," "," ",
126  " "," "," "," "," "},
127  {"THR","N ","CA ","C ","O ","CB ","OG1 ","CG2 "," "," ",
128  " "," "," "," "," "},
129  {"TRP","N ","CA ","C ","O ","CB ","CG ","CD1 ","CD2 ", "NE1 ",
130  "CE2 ","CE3 ","CZ2 ","CZ3 ","CH2 "},
131  {"TYR","N ","CA ","C ","O ","CB ","CG ","CD1 ","CD2 ", "CE1 ",
132  "CE2 ","CZ ","OH "," "," "},
133  {"VAL","N ","CA ","C ","O ","CB ","CG1 ","CG2 "," "," ",
134  " "," "," "," "," "},
135  {"PCA","N ","CA ","C ","O ","CB ","CG ","CD ","OE "," ",
136  " "," "," "," "," "}
137 } ;
138 
139 
140 /************************************************************************/
141 /* Prototypes
142 */
143 
144 /************************************************************************/
145 /*>PDB *blFixOrderPDB(PDB *pdb, BOOL Pad, BOOL Renum)
146  --------------------------------------------------
147 *//**
148 
149  \param[in] *pdb PDB linked list to fix atom order
150  \param[in] Pad TRUE: Create dummy coordinate atoms for any
151  missing atoms in standard residues
152  \param[in] Renum TRUE: Renumber the atoms
153  \return Corrected PDB linked list
154 
155  Runs through a PDB linked list and corrects the atom order to match
156  the N,CA,C,O,s/c standard. Only standard amino acids are processed.
157  The input linked list is modified (i.e. a new list is not built),
158  but the return value from the routine should be used for the corrected
159  list rather than the input PDB pointer, since the start of the list
160  may have changed. i.e. the routine should be called with the form:
161 
162  pdb = FixOrderPDB(pdb,TRUE,TRUE);
163 
164 - 08.07.93 Original By: ACRM
165 - 07.07.14 Use bl prefix for functions By: CTP
166 - 23.02.15 Modified for new blRenumAtomsPDB() which takes an offset
167 - 05.03.15 Replaced blFindEndPDB() with blFindNextResidue()
168 */
169 PDB *blFixOrderPDB(PDB *pdb, BOOL Pad, BOOL Renum)
170 {
171  PDB *start = NULL,
172  *end = NULL,
173  *p = NULL,
174  *ret = NULL,
175  *current = NULL;
176 
177  for(start=pdb; start!=NULL; start=end)
178  {
179  /* Find a residue's limits */
180  end = blFindNextResidue(start);
181 
182  p = blShuffleResPDB(start, end, Pad);
183 
184  if(ret == NULL)
185  {
186  current = ret = p;
187  }
188  else
189  {
190  current->next = p;
191  }
192 
193  while(current->next != end)
194  NEXT(current);
195  }
196 
197  if(Renum) blRenumAtomsPDB(ret, 1);
198 
199  return(ret);
200 }
201 
202 
203 /************************************************************************/
204 /*>PDB *blShuffleResPDB(PDB *start, PDB *end, BOOL Pad)
205  --------------------------------------------------
206 *//**
207 
208  \param[in] *start Start of residue to be shuffled
209  \param[in] *end Start of next residue in linked list (NULL
210  for last residue)
211  \param[in] Pad TRUE: Create dummy records for missing atoms
212  \return Pointer to new start of linked list
213 
214  Shuffle atoms within a residue into the standard order. Returns a
215  pointer to the new first atom in the residue. Atoms not in the known
216  list are discarded.
217  If we fail to allocate memory for extra atom records, no action is
218  taken.
219 
220 - 08.07.93 Original By: ACRM
221 - 09.03.94 Correctly handles residues not found in the standard list
222  (i.e. returns them unmodified)
223 - 17.03.94 If no atoms are found, then we return start. This is
224  the case when partial occupancy atoms are named as "N A",
225  "N B", etc.
226 - 07.07.14 Use bl prefix for functions By: CTP
227 */
228 PDB *blShuffleResPDB(PDB *start, PDB *end, BOOL Pad)
229 {
230  int i,
231  j;
232  char atnam[8];
233  PDB *ret = NULL,
234  *p = NULL,
235  *extra = NULL;
236  BOOL found = FALSE;
237 
238  /* Search for atom table for this amino acid */
239  for(i=0; i<MAXSTDAA; i++)
240  {
241  if(!strncmp(start->resnam,sAtoms[i][0],3))
242  {
243  /* Found the data for this residue.
244  Get each atom name in turn
245  */
246  for(j=1; j<=MAXATINRES; j++)
247  {
248  /* Copy the current atom name (for convenience) */
249  strcpy(atnam,sAtoms[i][j]);
250 
251  /* Flag for atom found */
252  found = FALSE;
253 
254  /* Break out if we've run out of atom names */
255  if(atnam[0] == ' ') break;
256 
257  for(p=start; p!=end; NEXT(p))
258  {
259  if(!strncmp(p->atnam, atnam, 4) ||
260  (!strncmp(p->resnam,"ILE ",4) &&
261  !strncmp(p->atnam, "CD1 ",4) &&
262  !strncmp(atnam, "CD ",4)))
263  {
264  /* Atom found, move to return list */
265  blMovePDB(p, &start, &ret);
266  found = TRUE;
267  break;
268  }
269  }
270 
271  if(Pad && !found)
272  {
273  INIT(extra,PDB);
274 
275  if(extra != NULL)
276  {
277  /* Copy in information for this residue */
278  if(ret != NULL)
279  blCopyPDB(extra, ret);
280  else
281  blCopyPDB(extra, start);
282 
283  /* Set required atom name and NULL coordinates */
284  strcpy(extra->atnam,atnam);
285  extra->x = (REAL)9999.0;
286  extra->y = (REAL)9999.0;
287  extra->z = (REAL)9999.0;
288  extra->occ = (REAL)0.0;
289  extra->bval = (REAL)20.0;
290 
291  /* Now move this record into the return list */
292  blMovePDB(extra, &extra, &ret);
293  }
294  }
295  }
296  break;
297  }
298  }
299 
300  /* If we've searched the whole list without finding our residue type
301  simply return the start of the list
302  */
303  if(i==MAXSTDAA) return(start);
304 
305  /* If we found our residue type, but we didn't find any atoms, so
306  ret is NULL, again we return the start of the list
307  */
308  if(ret==NULL) return(start);
309 
310  /* Rejoin the shuffled return list to the rest of the list */
311  p=ret;
312  LAST(p);
313  p->next = end;
314 
315  /* Delete any atom records not transferred */
316  if(start != end)
317  {
318  /* Move to end of discard list */
319  for(p=start; p->next!=end; NEXT(p));
320  /* Terminate the list there */
321  p->next = NULL;
322  /* Free the discard list */
323  FREELIST(start, PDB);
324  }
325 
326  /* Return start of shuffled list */
327  return(ret);
328 }
329 
330 
331 /************************************************************************/
332 /*>BOOL blGetAtomTypes(char *resnam, char **AtomTypes)
333  ---------------------------------------------------
334 *//**
335 
336  \param[in] *resnam Residue name for which to search
337  \param[out] **AtomTypes Array of atom names contained in the
338  residue
339  \return Success
340 
341  Fill in atom types for a given residue. AtomTypes must be
342  pre-allocated and must be set up as an array of character pointers
343  using Array2D() (or equivalent) rather than being created as a simple
344  char types[][] - THIS WILL NOT WORK!
345 
346 - 08.07.93 Original By: ACRM
347 - 07.07.14 Use bl prefix for functions By: CTP
348 */
349 BOOL blGetAtomTypes(char *resnam, char **AtomTypes)
350 {
351  int i,
352  j;
353 
354  for(i=0; i<MAXSTDAA; i++)
355  {
356  if(!strncmp(resnam,sAtoms[i][0],3))
357  {
358  for(j=0; j<MAXATINRES; j++)
359  {
360  strcpy(AtomTypes[j],sAtoms[i][j+1]);
361  }
362  return(TRUE);
363  }
364  }
365 
366  return(FALSE);
367 }
368 
369 /************************************************************************/
370 /*>PDB *blShuffleBB(PDB *pdb)
371  ------------------------
372 *//**
373 
374  \param[in] *pdb Input PDB linked list
375  \return Start of shuffled PDB linked list
376 
377  Shuffles the PDB list to match the standard of N,CA,C,O,CB,other.
378  Basically designed to be used with backbones only since the sidechain
379  order is not modified. Returns the start of the shuffled PDB linked
380  list.
381 
382 - 13.05.92 Original
383 - 22.06.08 Fixed to use FindNextResidue(). It was continuing to search
384  out of the current residue, so if the same residue number in
385  a different chain was of the same type, it ended up changing
386  that instead!
387 - 07.07.14 Use bl prefix for functions By: CTP
388 */
390 {
391  PDB *N = NULL,
392  *CA = NULL,
393  *C = NULL,
394  *O = NULL,
395  *CB = NULL,
396  *ret = NULL,
397  *p,
398  *next = NULL;
399 
400  next = blFindNextResidue(pdb);
401 
402  for(p=pdb; p!=next; NEXT(p))
403  {
404  if(!strncmp(p->atnam,"N ",4))
405  N = p;
406  else if(!strncmp(p->atnam,"CA ",4))
407  CA = p;
408  else if(!strncmp(p->atnam,"C ",4))
409  C = p;
410  else if(!strncmp(p->atnam,"O ",4))
411  O = p;
412  else if(!strncmp(p->atnam,"CB ",4))
413  CB = p;
414  }
415 
416  /* If we didn't find N, just return */
417  if(N==NULL) return(pdb);
418 
419  /* Move atoms in order from the pdb list to the ret list */
420  blMovePDB(N, &pdb, &ret);
421  if(CA != NULL) blMovePDB(CA, &pdb, &ret);
422  if(C != NULL) blMovePDB(C, &pdb, &ret);
423  if(O != NULL) blMovePDB(O, &pdb, &ret);
424  if(CB != NULL) blMovePDB(CB, &pdb, &ret);
425 
426  /* Append the remains of pdb onto ret */
427  blAppendPDB(ret, pdb);
428 
429  return(ret);
430 }
Include file for PDB routines.
struct _hblist * next
Definition: hbond.h:80
short BOOL
Definition: SysDefs.h:64
#define LAST(x)
Definition: macros.h:259
#define NULL
Definition: array2.c:99
Definition: pdb.h:298
#define FALSE
Definition: macros.h:223
#define NEXT(x)
Definition: macros.h:249
#define MAXSTDAA
Definition: pdb.h:238
Useful macros.
char resnam[8]
Definition: pdb.h:319
double REAL
Definition: MathType.h:67
#define MAXATINRES
Definition: pdb.h:240
#define TRUE
Definition: macros.h:219
PDB * blShuffleBB(PDB *pdb)
Definition: OrderPDB.c:389
BOOL blMovePDB(PDB *move, PDB **from, PDB **to)
Definition: MovePDB.c:100
void blCopyPDB(PDB *out, PDB *in)
Definition: CopyPDB.c:108
PDB * blAppendPDB(PDB *first, PDB *second)
Definition: AppendPDB.c:109
PDB * blShuffleResPDB(PDB *start, PDB *end, BOOL Pad)
Definition: OrderPDB.c:228
#define FREELIST(y, z)
Definition: macros.h:264
#define INIT(x, y)
Definition: macros.h:244
PDB * blFindNextResidue(PDB *pdb)
Type definitions for maths.
struct pdb_entry * next
Definition: pdb.h:307
BOOL blGetAtomTypes(char *resnam, char **AtomTypes)
Definition: OrderPDB.c:349
PDB * blFixOrderPDB(PDB *pdb, BOOL Pad, BOOL Renum)
Definition: OrderPDB.c:169
void blRenumAtomsPDB(PDB *pdb, int offset)