Bioplib
Protein Structure C Library
 All Data Structures Files Functions Variables Typedefs Macros Pages
FixCterPDB.c
Go to the documentation of this file.
1 /************************************************************************/
2 /**
3 
4  \file FixCterPDB.c
5 
6  \version V1.10
7  \date 05.03.15
8  \brief Routine to add C-terminal oxygens.
9 
10  \copyright (c) UCL / Dr. Andrew C. R. Martin 1994-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  BOOL FixCterPDB(PDB *pdb, int style)
46 
47  Renames Cter oxygens in the required style (CTER_STYLE_STD,
48  CTER_STYLE_GROMOS or CTER_STYLE_CHARMM) and generates a second
49  oxygen if required. If the style is CHARMM an extra CTER residue
50  will be created. Input may be in any of the 3 styles.
51 
52 **************************************************************************
53 
54  Revision History:
55  =================
56 - V1.0 24.08.94 Original By: ACRM
57 - V1.1 05.10.94 Removed unused variables
58 - V1.2 12.11.96 If any of the antecedant coordinates are undefined, set
59  the terminal oxygen to NULL coordinates
60 - V1.3 13.11.96 Also checks for missing CA,C and O1 records
61 - V1.4 06.02.03 Handles atnam_raw
62 - V1.5 03.06.05 Handles altpos
63 - V1.6 04.02.14 Use CHAINMATCH By: CTP
64 - V1.7 07.07.14 Use bl prefix for functions By: CTP
65 - V1.8 17.02.15 Added check on memory allocation By: ACRM
66 - V1.9 25.02.15 Ensures terminal oxygens are only added to amino acids
67  not HETATM groups
68 - V1.10 05.03.15 Replaced blFindEndPDB() with blFindNextResidue()
69 
70 *************************************************************************/
71 /* Doxygen
72  -------
73  #GROUP Handling PDB Data
74  #SUBGROUP Modifying the structure
75  #FUNCTION blFixCterPDB()
76  Renames C-ter atoms in required style and calls CalcCterCoords()
77  as required to calculate coordinates ans splices them in.
78  The input PDB linked list may have standard, CHARMM or GROMOS
79  style.
80 */
81 /************************************************************************/
82 /* Includes
83 */
84 #include <stdio.h>
85 #include <stdlib.h>
86 #include <math.h>
87 
88 #include "SysDefs.h"
89 #include "MathType.h"
90 #include "pdb.h"
91 #include "macros.h"
92 
93 /************************************************************************/
94 /* Defines and macros
95 */
96 #define MAXBUFF 160
97 
98 /************************************************************************/
99 /* Globals
100 */
101 
102 /************************************************************************/
103 /* Prototypes
104 */
105 static void StandardiseCTers(PDB *pdb);
106 static BOOL SetCterStyle(PDB *start, PDB *end, int style);
107 
108 /************************************************************************/
109 /*>BOOL blFixCterPDB(PDB *pdb, int style)
110  --------------------------------------
111 *//**
112 
113  \param[in,out] *pdb PDB linked list to modify
114  \param[in] style CTER_STYLE_STD, CTER_STYLE_GROMOS or
115  CTER_STYLE_CHARMM
116  \return Memory allocation OK?
117 
118  Renames C-ter atoms in required style and calls CalcCterCoords()
119  as required to calculate coordinates ans splices them in.
120  The input PDB linked list may have standard, CHARMM or GROMOS
121  style.
122 
123 - 24.08.94 Original By: ACRM
124 - 05.10.94 Removed unused variables
125 - 12.11.96 If any of the antecedant coordinates are undefined, set
126  the terminal oxygen to NULL coordinates
127 - 13.11.96 Added check on finding CA,C and O1
128  If no C or O1 present, OXT not added
129 - 06.02.03 Handles atnam_raw
130 - 03.06.05 Handles altpos
131 - 04.02.14 Use CHAINMATCH By: CTP
132 - 07.07.14 Use bl prefix for functions By: CTP
133 - 17.02.15 Checks INIT() succeeded By: ACRM
134 - 25.02.15 Ensures terminal oxygens are only added to amino acids not
135  HETATM groups
136 - 05.03.15 Replaced blFindEndPDB() with blFindNextResidue()
137 */
138 BOOL blFixCterPDB(PDB *pdb, int style)
139 {
140  PDB *p,
141  *start,
142  *end,
143  *CA = NULL,
144  *C = NULL,
145  *O1 = NULL,
146  *O2 = NULL;
147 
148  /* Remove CTERs - we'll add them back later if required */
149  StandardiseCTers(pdb);
150 
151  /* Step through the linked list */
152  start = pdb;
153  while(start != NULL)
154  {
155  end = blFindNextResidue(start);
156 
157  /* Skip if this is not an amino acid */
158  if(strncmp(start->record_type, "ATOM ", 6))
159  {
160  start = end;
161  continue;
162  }
163 
164  if(end==NULL || !CHAINMATCH(end->chain,start->chain))
165  {
166  /* We're in a c-ter residue; find the atoms */
167  CA = C = O1 = O2 = NULL;
168 
169  for(p=start; p!=end; NEXT(p))
170  {
171  if(!strncmp(p->atnam,"CA ",4))
172  CA = p;
173  if(!strncmp(p->atnam,"C ",4))
174  C = p;
175  if(!strncmp(p->atnam,"O ",4))
176  O1 = p;
177  if(!strncmp(p->atnam,"OXT ",4))
178  O2 = p;
179  }
180 
181  /* If C and O1 are missing, return */
182  if(C==NULL && O1==NULL)
183  return(TRUE);
184 
185  /* If O2 is missing, generate coordinates */
186  if(O2 == NULL)
187  {
188  INIT(O2, PDB);
189  if(O2==NULL) /* 17.02.15 */
190  return(FALSE);
191 
192  CLEAR_PDB(O2);
193  if(O1 != NULL)
194  blCopyPDB(O2, O1);
195  else if(CA != NULL)
196  blCopyPDB(O2, CA);
197  else if(C != NULL)
198  blCopyPDB(O2, C);
199 
200  O2->bval = 20.0;
201  strcpy(O2->atnam,"OXT ");
202  strcpy(O2->atnam_raw," OXT");
203  O2->altpos = ' '; /* 03.06.05 */
204 
205  if(CA==NULL || C==NULL || O1==NULL ||
206  ((CA->x == (REAL)9999.0) &&
207  (CA->y == (REAL)9999.0) &&
208  (CA->z == (REAL)9999.0)) ||
209  ((C->x == (REAL)9999.0) &&
210  (C->y == (REAL)9999.0) &&
211  (C->z == (REAL)9999.0)) ||
212  ((O1->x == (REAL)9999.0) &&
213  (O1->y == (REAL)9999.0) &&
214  (O1->z == (REAL)9999.0)))
215  {
216  O2->x = O2->y = O2->z = (REAL)9999.0;
217  O2->occ = O2->bval = (REAL)0.0;
218  }
219  else
220  {
221  if(!blCalcCterCoords(O2,CA,C,O1))
222  return(FALSE);
223  }
224 
225  /* Splice O2 into the PDB linked list after O1 */
226  if(O1 != NULL)
227  {
228  O2->next = O1->next;
229  O1->next = O2;
230  }
231  else if(C != NULL)
232  {
233  O2->next = C->next;
234  C->next = O2;
235  }
236  else if(CA != NULL)
237  {
238  O2->next = CA->next;
239  CA->next = O2;
240  }
241  }
242 
243  /* Now set the required style */
244  SetCterStyle(start, end, style);
245  }
246 
247  start = end;
248  }
249 
250  return(TRUE);
251 }
252 
253 /************************************************************************/
254 /*>static void StandardiseCTers(PDB *pdb)
255  --------------------------------------
256 *//**
257 
258  \param[in,out] *pdb PDB linked list to standardise
259 
260  Runs through a PDB linked list and corrects the C-terminal residues
261  to the standard PDB style. Removes CTER residue names, but does
262  not generate any missing Oxygens.
263 
264 - 24.08.94 Original By: ACRM
265 - 06.02.03 Handles atnam_raw
266 - 03.06.05 Handles altpos
267 - 04.02.14 Use CHAINMATCH By: CTP
268 - 07.07.14 Use bl prefix for functions By: CTP
269 - 05.03.15 Replaced blFindEndPDB() with blFindNextResidue()
270 */
271 static void StandardiseCTers(PDB *pdb)
272 {
273  PDB *start,
274  *end,
275  *O1,
276  *O2,
277  *p,
278  *prev = NULL;
279 
280  start = pdb;
281  while(start != NULL)
282  {
283  end = blFindNextResidue(start);
284 
285  /* If it's a c-terminal residue or the one before CTER,
286  fix the names of the oxygens
287  */
288  if(end==NULL ||
289  !CHAINMATCH(end->chain,start->chain) ||
290  !strncmp(end->resnam,"CTER",4))
291  {
292  O1 = O2 = NULL;
293 
294  for(p=start; p!=end; NEXT(p))
295  {
296  if(!strncmp(p->atnam,"O ",4) ||
297  !strncmp(p->atnam,"O1 ",4) ||
298  !strncmp(p->atnam,"OT1 ",4))
299  O1 = p;
300  if(!strncmp(p->atnam,"OXT ",4) ||
301  !strncmp(p->atnam,"O2 ",4) ||
302  !strncmp(p->atnam,"OT2 ",4))
303  O2 = p;
304  }
305 
306  if(O1 != NULL)
307  {
308  strcpy(O1->atnam,"O ");
309  strcpy(O1->atnam_raw," O ");
310  O1->altpos = ' '; /* 03.06.05 */
311  }
312 
313  if(O2 != NULL)
314  {
315  strcpy(O2->atnam,"OXT ");
316  strcpy(O2->atnam_raw," OXT");
317  O2->altpos = ' '; /* 03.06.05 */
318  }
319 
320  }
321 
322  /* If it's a CTER residue, change it's name and number to that
323  of the previous residue
324  */
325  if(!strncmp(start->resnam,"CTER",4))
326  {
327  if(prev != NULL)
328  {
329  for(p=start; p!=end; NEXT(p))
330  {
331  strcpy(p->resnam, prev->resnam);
332  strcpy(p->insert, prev->insert);
333  p->resnum = prev->resnum;
334  }
335  }
336  }
337 
338  prev = start;
339  start = end;
340  }
341 
342 }
343 
344 /************************************************************************/
345 /*>static BOOL SetCterStyle(PDB *start, PDB *end, int style)
346  ---------------------------------------------------------
347 *//**
348 
349  \param[in,out] *start Start of PDB linked list for c-ter residue
350  \param[in] *end End of PDB linked list for c-ter residue
351  \param[in] style CTER_STYLE_STD, CTER_STYLE_GROMOS or
352  CTER_STYLE_CHARMM
353  \return Success?
354 
355  For a c-terminal or CTER residue, sets the required style for the
356  two oxygens.
357 
358 - 24.08.94 Original By: ACRM
359 - 06.02.03 Handles atnam_raw
360 - 03.06.05 Handles altpos
361 */
362 static BOOL SetCterStyle(PDB *start, PDB *end, int style)
363 {
364  PDB *O1,
365  *O2,
366  *O2prev,
367  *p;
368 
369  O1 = O2 = O2prev = NULL;
370 
371  for(p=start; p!=end; NEXT(p))
372  {
373  if(!strncmp(p->atnam,"O ",4))
374  O1 = p;
375  if(!strncmp(p->atnam,"OXT ",4))
376  O2 = p;
377  if(p->next != NULL && !strncmp(p->next->atnam,"OXT ",4))
378  O2prev = p;
379  }
380 
381  /* If necessary, move O2 to the end of the residue */
382  if(O2->next != end)
383  {
384  /* Unlink O2 */
385  if(O2prev == NULL) return(FALSE);
386  O2prev->next = O2->next;
387 
388  /* Link O2 to end of residue */
389  for(p=start; p->next!=end; NEXT(p)) ;
390  O2->next = p->next;
391  p->next = O2;
392  }
393 
394  if(style == CTER_STYLE_GROMOS)
395  {
396  /* Correct the names */
397  if(O1 != NULL)
398  {
399  strcpy(O1->atnam,"O1 ");
400  strcpy(O1->atnam_raw," O1 ");
401  O1->altpos = ' '; /* 03.06.05 */
402  }
403  if(O2 != NULL)
404  {
405  strcpy(O2->atnam,"O2 ");
406  strcpy(O2->atnam_raw," O2 ");
407  O2->altpos = ' '; /* 03.06.05 */
408  }
409 
410  }
411  else if(style == CTER_STYLE_CHARMM)
412  {
413  /* Correct the names */
414  if(O1 != NULL)
415  {
416  strcpy(O1->atnam,"OT1 ");
417  strcpy(O1->atnam_raw," OT1");
418  O1->altpos = ' '; /* 03.06.05 */
419  }
420  if(O2 != NULL)
421  {
422  strcpy(O2->atnam,"OT2 ");
423  strcpy(O2->atnam_raw," OT2");
424  O2->altpos = ' '; /* 03.06.05 */
425  }
426 
427  /* Change the name and number for O2 */
428  strcpy(O2->resnam,"CTER");
429  strcpy(O2->insert," ");
430  O2->resnum = start->resnum + 1;
431  }
432 
433  return(TRUE);
434 }
Include file for PDB routines.
int resnum
Definition: pdb.h:310
short BOOL
Definition: SysDefs.h:64
#define NULL
Definition: array2.c:99
Definition: pdb.h:298
#define CLEAR_PDB(p)
Definition: pdb.h:460
#define FALSE
Definition: macros.h:223
#define NEXT(x)
Definition: macros.h:249
char altpos
Definition: pdb.h:324
char record_type[8]
Definition: pdb.h:315
Useful macros.
char atnam[8]
Definition: pdb.h:316
char resnam[8]
Definition: pdb.h:319
double REAL
Definition: MathType.h:67
REAL z
Definition: pdb.h:300
#define CTER_STYLE_CHARMM
Definition: pdb.h:573
#define TRUE
Definition: macros.h:219
#define CTER_STYLE_GROMOS
Definition: pdb.h:572
char atnam_raw[8]
Definition: pdb.h:317
void blCopyPDB(PDB *out, PDB *in)
Definition: CopyPDB.c:108
#define CHAINMATCH(chain1, chain2)
Definition: pdb.h:495
#define INIT(x, y)
Definition: macros.h:244
System-type variable type definitions.
PDB * blFindNextResidue(PDB *pdb)
BOOL blFixCterPDB(PDB *pdb, int style)
Definition: FixCterPDB.c:138
Type definitions for maths.
struct pdb_entry * next
Definition: pdb.h:307
char chain[blMAXCHAINLABEL]
Definition: pdb.h:321
BOOL blCalcCterCoords(PDB *p, PDB *ca_p, PDB *c_p, PDB *o_p)
REAL x
Definition: pdb.h:300
REAL y
Definition: pdb.h:300
char insert[8]
Definition: pdb.h:320