Bioplib
Protein Structure C Library
 All Data Structures Files Functions Variables Typedefs Macros Pages
StructurePDB.c
Go to the documentation of this file.
1 /************************************************************************/
2 /**
3 
4  \file StructurePDB.c
5 
6  \version V1.3
7  \date 07.07.14
8  \brief Build a structured PDB representation
9 
10  \copyright (c) UCL / Dr. Andrew C. R. Martin 2009-14
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 24.11.09 Original
50 - V1.1 19.05.10 PDBRESIDUE and PDBCHAIN are doubly linked lists
51 - V1.2 04.02.14 Use CHAINMATCH By: CTP
52 - V1.3 07.07.14 Use bl prefix for functions By: CTP
53 
54 *************************************************************************/
55 /* Doxygen
56  -------
57  #GROUP Handling PDB Data
58  #SUBGROUP Manipulating the PDB linked list
59  #FUNCTION blAllocPDBStructure()
60  Takes a PDB linked list and converts it into a hierarchical structure
61  of chains, residues and atoms
62 
63  #FUNCTION blFreePDBStructure()
64  Frees memory used by the hierarchical description of a PDB structure.
65  Note this does not free the underlying PDB linked list
66 
67  #FUNCTION blFindNextChain()
68  Takes a PDB linked list and find the start of the next chain. This is
69  similar to another Bioplib routine (blFindNextChainPDB()) which
70  terminates the first chain, but this routines doesn't terminate.
71 */
72 /************************************************************************/
73 /* Includes
74 */
75 #include <stdlib.h>
76 #include "pdb.h"
77 #include "macros.h"
78 
79 /************************************************************************/
80 /* Defines and macros
81 */
82 
83 /************************************************************************/
84 /* Globals
85 */
86 
87 /************************************************************************/
88 /* Prototypes
89 */
90 
91 
92 /************************************************************************/
93 /*>PDBSTRUCT *blAllocPDBStructure(PDB *pdb)
94  ----------------------------------------
95 *//**
96 
97  \param[in] *pdb PDB linked list
98  \return PDBSTRUCT structure containing chain
99  linked list
100 
101  Takes a PDB linked list and converts it into a hierarchical structure
102  of chains, residues and atoms
103 
104 - 24.11.09 Original By: ACRM
105 - 19.05.10 Correctly do doubly linked lists
106 - 02.06.10 Fixed some initializations!
107 - 07.07.14 Use bl prefix for functions By: CTP
108 */
110 {
111  PDB *pdbc, *pdbr;
112  PDB *nextchain, *nextres;
113  PDBSTRUCT *pdbstruct = NULL;
114  PDBCHAIN *chain = NULL;
115  PDBRESIDUE *residue = NULL;
116 
117 
118  /* Initialization */
119  if((pdbstruct = (PDBSTRUCT *)malloc(sizeof(PDBSTRUCT)))==NULL)
120  return(NULL);
121  pdbstruct->pdb = pdb;
122  pdbstruct->chains = NULL;
123  pdbstruct->extras = NULL; /* 02.06.10 */
124 
125  /* Build the chain list */
126  for(pdbc=pdb; pdbc!=NULL; pdbc=nextchain)
127  {
128  nextchain = blFindNextChain(pdbc);
129 
130  if(pdbstruct->chains == NULL)
131  {
132  INITPREV(pdbstruct->chains, PDBCHAIN);
133  chain = pdbstruct->chains;
134  }
135  else
136  {
137  ALLOCNEXTPREV(chain, PDBCHAIN);
138  }
139  if(chain == NULL)
140  {
141  blFreePDBStructure(pdbstruct);
142  return(NULL);
143  }
144 
145  chain->start = pdbc;
146  chain->stop = nextchain;
147  chain->residues = NULL; /* 02.06.10 */
148  chain->extras = NULL; /* 02.06.10 */
149  strcpy(chain->chain, pdbc->chain);
150  }
151 
152  /* Build the residue list for each chain */
153  for(chain = pdbstruct->chains; chain!=NULL; NEXT(chain))
154  {
155  for(pdbr = chain->start; pdbr != chain->stop; pdbr=nextres)
156  {
157  char resid[24];
158  int i, j;
159 
160  nextres = blFindNextResidue(pdbr);
161 
162  if(chain->residues == NULL)
163  {
164  INITPREV(chain->residues, PDBRESIDUE);
165  residue = chain->residues;
166  }
167  else
168  {
169  ALLOCNEXTPREV(residue, PDBRESIDUE);
170  }
171  if(residue == NULL)
172  {
173  blFreePDBStructure(pdbstruct);
174  return(NULL);
175  }
176 
177  residue->start = pdbr;
178  residue->stop = nextres;
179  strcpy(residue->chain, pdbr->chain);
180  strcpy(residue->insert, pdbr->insert);
181  strcpy(residue->resnam, pdbr->resnam);
182  residue->resnum = pdbr->resnum;
183  residue->extras = NULL; /* 02.06.10 */
184 
185  /* Build a residue label */
186  sprintf(resid, "%s.%d%s",
187  residue->chain, residue->resnum, residue->insert);
188  for(i=0, j=0; resid[i]; i++)
189  {
190  /* Copy the character if it's not a space, but only copy a
191  full stop if it's not going to be the first character
192  */
193  if(resid[i] != ' ' && (resid[i] != '.' || j>0))
194  {
195  residue->resid[j++] = resid[i];
196  }
197  }
198  residue->resid[j++] = '\0';
199  }
200  }
201 
202  return(pdbstruct);
203 }
204 
205 /************************************************************************/
206 /*>void blFreePDBStructure(PDBSTRUCT *pdbstruct)
207  ---------------------------------------------
208 *//**
209 
210  \param[in] *pdbstruct PDBSTRUCT structure containing chain
211  linked list
212 
213  Frees memory used by the hierarchical description of a PDB structure.
214  Note this does not free the underlying PDB linked list
215 
216 - 24.11.09 Original By: ACRM
217 - 07.07.14 Use bl prefix for functions By: CTP
218 */
220 {
221  PDBCHAIN *chain = NULL;
222 
223  if(pdbstruct == NULL)
224  return;
225 
226  for(chain = pdbstruct->chains; chain!=NULL; NEXT(chain))
227  {
228  FREELIST(chain->residues, PDBRESIDUE);
229  }
230 
231  FREELIST(pdbstruct->chains, PDBCHAIN);
232  free(pdbstruct);
233 }
234 
235 
236 /************************************************************************/
237 /*>PDB *blFindNextChain(PDB *pdb)
238  ------------------------------
239 *//**
240 
241  \param[in] *pdb PDB linked list
242  \return Pointer to start of next chain
243 
244  Takes a PDB linked list and find the start of the next chain. This is
245  similar to another Bioplib routine (blFindNextChainPDB()) which
246  terminates the first chain, but this routines doesn't terminate.
247 
248 - 24.11.09 Original By: ACRM
249 - 04.02.14 Use CHAINMATCH By: CTP
250 - 07.07.14 Use bl prefix for functions By: CTP
251 */
253 {
254  PDB *p, *ret = NULL;
255 
256  for(p=pdb; p!=NULL; NEXT(p))
257  {
258  if((p->next == NULL) || !CHAINMATCH(p->next->chain,pdb->chain))
259  {
260  ret = p->next;
261  break;
262  }
263  }
264 
265  return(ret);
266 }
267 
268 /************************************************************************/
269 #ifdef DEMO
270 #include <stdio.h>
271 int main(int argc, char **argv)
272 {
273  FILE *fp = NULL;
274  int natoms;
275  PDB *pdb, *p;
276  PDBSTRUCT *pdbs;
277  PDBCHAIN *chain;
278  PDBRESIDUE *residue;
279 
280 
281  fp = fopen(argv[1], "r");
282  pdb = blReadPDB(fp, &natoms);
283  pdbs = blAllocPDBStructure(pdb);
284 
285  for(chain=pdbs->chains; chain!=NULL; NEXT(chain))
286  {
287  fprintf(stdout,"COMMENT: Chain %s\n", chain->chain);
288  for(residue=chain->residues; residue!=NULL; NEXT(residue))
289  {
290  fprintf(stdout, "COMMENT: Residue %s\n", residue->resid);
291  for(p=residue->start; p!=residue->stop; NEXT(p))
292  {
293  blWritePDBRecord(stdout, p);
294  }
295  }
296  }
297 
298  for(chain=pdbs->chains; chain!=NULL; NEXT(chain))
299  {
300  fprintf(stdout,"COMMENT: Chain %s\n", chain->chain);
301  for(p=chain->start; p!=chain->stop; NEXT(p))
302  {
303  blWritePDBRecord(stdout, p);
304  }
305  }
306 
307  blFreePDBStructure(pdbs);
308 
309  return(0);
310 }
311 
312 #endif
313 
int main(int argc, char **argv)
Definition: test.c:4
Include file for PDB routines.
PDBSTRUCT * blAllocPDBStructure(PDB *pdb)
Definition: StructurePDB.c:109
PDBRESIDUE * residues
Definition: pdb.h:344
int resnum
Definition: pdb.h:310
#define ALLOCNEXTPREV(x, y)
Definition: macros.h:254
PDB * stop
Definition: pdb.h:343
#define NULL
Definition: array2.c:99
APTR * extras
Definition: pdb.h:332
char insert[8]
Definition: pdb.h:335
Definition: pdb.h:298
void blWritePDBRecord(FILE *fp, PDB *pdb)
Definition: WritePDB.c:415
PDB * stop
Definition: pdb.h:331
char resnam[8]
Definition: pdb.h:336
char chain[blMAXCHAINLABEL]
Definition: pdb.h:346
#define NEXT(x)
Definition: macros.h:249
Useful macros.
void blFreePDBStructure(PDBSTRUCT *pdbstruct)
Definition: StructurePDB.c:219
char resnam[8]
Definition: pdb.h:319
APTR * extras
Definition: pdb.h:345
Definition: pdb.h:340
PDB * blReadPDB(FILE *fp, int *natom)
Definition: ReadPDB.c:419
PDB * blFindNextChain(PDB *pdb)
Definition: StructurePDB.c:252
PDB * pdb
Definition: pdb.h:351
APTR * extras
Definition: pdb.h:353
char resid[8]
Definition: pdb.h:337
PDBCHAIN * chains
Definition: pdb.h:352
Definition: pdb.h:349
PDB * start
Definition: pdb.h:343
#define CHAINMATCH(chain1, chain2)
Definition: pdb.h:495
#define FREELIST(y, z)
Definition: macros.h:264
PDB * blFindNextResidue(PDB *pdb)
struct pdb_entry * next
Definition: pdb.h:307
int resnum
Definition: pdb.h:333
PDB * start
Definition: pdb.h:331
char chain[blMAXCHAINLABEL]
Definition: pdb.h:321
char chain[blMAXCHAINLABEL]
Definition: pdb.h:334
#define INITPREV(x, y)
Definition: macros.h:246
char insert[8]
Definition: pdb.h:320