Bioplib
Protein Structure C Library
 All Data Structures Files Functions Variables Typedefs Macros Pages
rsc.c
Go to the documentation of this file.
1 /************************************************************************/
2 /**
3 
4  \file rsc.c
5 
6  \version V1.17
7  \date 23.03.17
8  \brief Modify sequence of a PDB linked list
9 
10  \copyright (c) UCL / Dr. Andrew C. R. Martin 1992-2017
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  Takes a PDB linked list and replaces sidechains
40 
41 **************************************************************************
42 
43  Usage:
44  ======
45  The main entry point is RepSChain() which takes a PDB linked list,
46  the sequence, and names of the equivalent chi table and the reference
47  coordinate file. These files are only opened on the first call.
48 
49 **************************************************************************
50 
51  Revision History:
52  =================
53 - V1.0 12.05.92 Original
54 - V1.1 09.07.93 Simplified and improved memory allocation checking
55 - V1.2 11.03.94 RepSChain() now returns BOOL
56 - V1.3 14.03.94 RepSChain() now returns TRUE for success and FALSE for
57  failure. THIS IS INCOMPATIBLE WITH PREVIOUS VERSIONS
58  which returned 0 for success.
59  Error messages are now placed in gRSCError rather than
60  being printed.
61 - V1.4 19.05.94 Fixed bug resulting from change in RotatePDB(); now
62  calls ApplyMatrixPDB() instead
63 - V1.5 05.10.94 Modified for KillSidechain() returning BOOL
64 - V1.6 09.11.94 Modified to use OpenFile() fo open the data files
65 - V1.7 12.08.96 Added RepOneSChain() and EndRepSChain() and a few
66  internal changes to RepSChain()
67 - V1.8 15.08.96 Removed unused variables from RepOneSChain()
68 - V1.9 30.05.02 Changed PDB field from 'junk' to 'record_type'
69 - V1.10 09.02.05 Fixed to handle atnam_raw and sensible defaults for
70  occ/bval
71 - V1.11 03.06.05 Added altpos
72 - V1.12 07.07.14 Use bl prefix for functions By: CTP
73 - V1.13 15.08.14 Updated ReadRefCoords() to use CLEAR_PDB() By: CTP
74 - V1.14 23.02.15 Modified for new blRenumAtomsPDB() which takes an
75  offset By: ACRM
76 - V1.15 25.02.15 Sets the element type for new atoms
77 - V1.16 14.12.16 FixTorsions() checks return from blCalcChi()
78 - V1.17 23.03.17 Better handling of missing atoms in the PDB file
79 
80 *************************************************************************/
81 /* Defines required for includes
82 */
83 #define RSC_MAIN
84 
85 /************************************************************************/
86 /* Doxygen
87  -------
88  #GROUP Handling PDB Data
89  #SUBGROUP Modifying the structure
90  #FUNCTION blRepSChain()
91  Replace sidechains.
92 
93  #FUNCTION blRepOneSChain()
94  Replace a single sidechain.
95 
96  #FUNCTION blRepOneSChainForce()
97  Replace a single sidechain - even if the sidechain was correct
98  already.
99 
100  #FUNCTION blEndRepSChain()
101  Cleans up open files and memory used by the sidechain replacement
102  routines.
103 */
104 /************************************************************************/
105 /* Includes
106 */
107 #include <math.h>
108 #include <stdio.h>
109 #include <string.h>
110 #include <stdlib.h>
111 
112 #include "SysDefs.h"
113 #include "MathType.h"
114 #include "seq.h"
115 #include "pdb.h" /* Defines gRSCError */
116 #include "macros.h"
117 #include "array.h"
118 #include "angle.h"
119 #include "general.h"
120 
121 
122 /************************************************************************/
123 /* Defines and macros
124 */
125 #define NUMAAKNOWN 20
126 #define MAXBUFF 80 /* Used by ReadRefCoords() */
127 #define ERROR_OK 0
128 #define ERROR_NOMEM 1
129 #define ERROR_ATOMS 2
130 #define ERROR_UNKNOWNAA 3
131 
132 /************************************************************************/
133 /* Globals
134 */
135 static int sFirstCall = TRUE; /* Flag for things done first time */
136 static FILE *sFp_RefCoords; /* The reference coordinates file */
137 static int **sChiTab = NULL; /* Equivalent torsions */
138 
139 /************************************************************************/
140 /* Prototypes
141 */
142 static PDB *DoReplace(PDB *ResStart, PDB *NextRes, char seq, int **chitab,
143  FILE *fp_RefCoords);
144 static int ReplaceWithGly(PDB *ResStart, PDB *NextRes);
145 static int ReplaceWithAla(PDB *ResStart, PDB *NextRes);
146 static int ReplaceGly(PDB *ResStart, PDB *NextRes, char seq,
147  FILE *fp_RefCoords);
148 static int FitByFragment(PDB *destination, PDB *fragment, PDB *mobile);
149 static int InsertSC(PDB *insert, PDB *ResStart, PDB *NextRes, BOOL doCB);
150 static int Replace(PDB *ResStart, PDB *NextRes, char seq, int **chitab,
151  FILE *fp_RefCoords);
152 static PDB *ReadRefCoords(FILE *fp, char seq);
153 static void ReadChiTable(FILE *fp, int **chitab);
154 static int FindChiIndex(char *resnam);
155 static PDB *FixTorsions(PDB *pdb, PDB *ResStart, PDB *NextRes,
156  int **chitab);
157 static BOOL doRepOneSChain(PDB *pdb, char *ResSpec, char aa,
158  char *ChiTable, char *RefCoords, BOOL force);
159 static BOOL gotCBeta(PDB *ResStart, PDB *NextRes);
160 
161 
162 /************************************************************************/
163 /*>BOOL blRepSChain(PDB *pdb, char *sequence, char *ChiTable,
164  char *RefCoords)
165  ----------------------------------------------------------
166 *//**
167 
168  \param[in,out] *pdb PDB linked list to modify
169  \param[in] *sequence The 1-letter code required for the structure
170  \param[in] *ChiTable The equivalent Chi table
171  \param[in] *RefCoords The reference coordinates file
172  \return Success?
173 
174  Replace sidechains. Takes a PDB linked list and a 1-letter code
175  sequence and replaces the sidechains. Also requires filenames of the
176  two datafiles. DEL residues in the pdb linked list will be skipped
177  as will -'s in the sequence
178 
179 - 12.05.92 Original
180 - 14.05.92 Corrected handling of matching DEL and -
181 - 21.06.93 Changed to allocate chitab using Array2D
182 - 14.03.94 Changed logic of return value. Now places error messages in
183  gRSCError.
184 - 09.11.94 Uses OpenFile() to look in $(DATADIR) is the file wasn't
185  found as specified.
186 - 12.08.96 Made static variables external to this routine as they are
187  shared by RepOneSChain(). sChiTab was being allocated on every
188  call instead of just the first one.
189 - 07.07.14 Use bl prefix for functions By: CTP
190 - 23.02.15 Modified for new blRenumAtomsPDB() which takes an offset
191 
192 */
193 BOOL blRepSChain(PDB *pdb, /* PDB linked list */
194  char *sequence, /* Sequence 1-letter code */
195  char *ChiTable, /* Equivalent torsion table filename*/
196  char *RefCoords) /* Reference coordinate filename */
197 {
198  int resnum; /* Current residue number */
199  char insert[8], /* Current insert code */
200  *seq; /* Pointer to aa in sequence */
201  PDB *p, /* General PDB pointer */
202  *ResStart, /* Start of residue */
203  *NextRes; /* Start of next residue */
204  BOOL noenv = FALSE; /* Flag for no env. var. found */
205 
206  if(sFirstCall)
207  {
208  FILE *fp_ChiTable;
209 
210  /* Allocate 2D array for equivalent torsions */
211  if((sChiTab = (int **)blArray2D(sizeof(int), NUMAAKNOWN, NUMAAKNOWN))
212  == NULL)
213  return(FALSE);
214 
215  /* Open files */
216  if((fp_ChiTable = blOpenFile(ChiTable,"DATADIR","r",&noenv)) == NULL)
217  {
218  if(noenv)
219  {
220  sprintf(gRSCError,"DATADIR environment variable not set\n");
221  }
222  else
223  {
224  sprintf(gRSCError,"Unable to open chi link table: %s\n",
225  ChiTable);
226  }
227  return(FALSE);
228  }
229 
230  if((sFp_RefCoords = blOpenFile(RefCoords,"DATADIR","r",&noenv)) ==
231  NULL)
232  {
233  if(noenv)
234  {
235  sprintf(gRSCError,"DATADIR environment variable not set\n");
236  }
237  else
238  {
239  sprintf(gRSCError,"Unable to open reference coordinates: \
240 %s\n", RefCoords);
241  }
242  return(FALSE);
243  }
244 
245  /* Read the equivalent chi table and the atom table */
246  ReadChiTable(fp_ChiTable, sChiTab);
247 
248  /* Close the table files */
249  fclose(fp_ChiTable);
250 
251  sFirstCall = FALSE;
252  }
253 
254  /* Step along the PDB linked list isolating a residue at a time and
255  replacing it if necessary. The loop also steps along the sequence
256  and will end if the sequence string ends.
257  */
258  for(p=pdb, seq = sequence; p && *seq != '\0'; NEXT(p))
259  {
260  ResStart = p; /* Start of residue */
261  resnum = p->resnum;
262  strcpy(insert,p->insert);
263 
264  /* Move to end of residue and store pointer to next residue */
265  while(p->next && p->next->resnum == resnum
266  && !strcmp(p->next->insert, insert))
267  NEXT(p);
268  NextRes = p->next;
269 
270  /* If its a DEL, step over any - in required sequence */
271  if(!strncmp(ResStart->resnam,"DEL",3))
272  {
273  while(*seq == '-') seq++;
274  }
275  else /* Not a DEL, see if it needs replacing */
276  {
277  /* If there is a sequence mismatch, replace the residue */
278  if(*seq != blThrone(p->resnam))
279  p = DoReplace(ResStart,NextRes,*seq,sChiTab,sFp_RefCoords);
280  if(p == NULL) return(FALSE);
281 
282  /* Step to the next sequence item which isn't a - */
283  while(*(++seq) == '-') ;
284  }
285  }
286 
287  blRenumAtomsPDB(pdb, 1);
288 
289  return(TRUE);
290 }
291 
292 /************************************************************************/
293 /*>BOOL blRepOneSChain(PDB *pdb, char *ResSpec, char aa,
294  char *ChiTable, char *RefCoords)
295  -----------------------------------------------------------------------
296 *//**
297 
298  \param[in,out] *pdb PDB linked list to modify
299  \param[in] *ResSpec Residue spec for residue to replace in the
300  format [c]nnn[i]
301  \param[in] aa The 1-letter code for the new sidechain
302  \param[in] *ChiTable The equivalent Chi table
303  \param[in] *RefCoords The reference coordinates file
304  \return Success?
305 
306  Replace a single sidechain. Takes a PDB linked list, a residues
307  specfication (in the form [c]nnn[i] where [c] is an optional chain
308  name, nnn is a residue number and [i] is an optional insert code)
309  and a 1-letter code of the required sidechain and does a simple
310  maximum overlap replacement of the sidechain. Also requires filenames
311  of the two datafiles.
312 
313 - 12.08.96 Original based on RepSChain()
314 - 15.08.96 Removed unused variables
315 - 07.07.14 Use bl prefix for functions By: CTP
316 - 23.02.15 Modified for new blRenumAtomsPDB() which takes an offset
317 - 29.09.15 Now just a wrapper to doRepOneSChain()
318 */
319 BOOL blRepOneSChain(PDB *pdb, char *ResSpec, char aa, char *ChiTable,
320  char *RefCoords)
321 {
322  return(doRepOneSChain(pdb, ResSpec, aa, ChiTable, RefCoords, FALSE));
323 }
324 
325 /************************************************************************/
326 /*>BOOL blRepOneSChainForce(PDB *pdb, char *ResSpec, char aa,
327  char *ChiTable, char *RefCoords)
328  -----------------------------------------------------------------------
329 *//**
330 
331  \param[in,out] *pdb PDB linked list to modify
332  \param[in] *ResSpec Residue spec for residue to replace in the
333  format [c]nnn[i]
334  \param[in] aa The 1-letter code for the new sidechain
335  \param[in] *ChiTable The equivalent Chi table
336  \param[in] *RefCoords The reference coordinates file
337  \return Success?
338 
339  Replace a single sidechain. Takes a PDB linked list, a residues
340  specfication (in the form [c]nnn[i] where [c] is an optional chain
341  name, nnn is a residue number and [i] is an optional insert code)
342  and a 1-letter code of the required sidechain and does a simple
343  maximum overlap replacement of the sidechain. Also requires filenames
344  of the two datafiles.
345 
346  Replaces even if the sidechain was coorect already
347 
348 - 29.09.15 Original - wrapper to doRepOneSChain()
349 */
350 BOOL blRepOneSChainForce(PDB *pdb, char *ResSpec, char aa,
351  char *ChiTable, char *RefCoords)
352 {
353  return(doRepOneSChain(pdb, ResSpec, aa, ChiTable, RefCoords, TRUE));
354 }
355 
356 
357 
358 /************************************************************************/
359 /*>static BOOL doRepOneSChain(PDB *pdb, char *ResSpec, char aa,
360  char *ChiTable, char *RefCoords, BOOL force)
361  -----------------------------------------------------------------------
362 *//**
363 
364  \param[in,out] *pdb PDB linked list to modify
365  \param[in] *ResSpec Residue spec for residue to replace in the
366  format [c]nnn[i]
367  \param[in] aa The 1-letter code for the new sidechain
368  \param[in] *ChiTable The equivalent Chi table
369  \param[in] *RefCoords The reference coordinates file
370  \param[in] force Replace even if it's the right AA already
371  \return Success?
372 
373  Replace a single sidechain. Takes a PDB linked list, a residues
374  specfication (in the form [c]nnn[i] where [c] is an optional chain
375  name, nnn is a residue number and [i] is an optional insert code)
376  and a 1-letter code of the required sidechain and does a simple
377  maximum overlap replacement of the sidechain. Also requires filenames
378  of the two datafiles.
379 
380 - 12.08.96 Original based on RepSChain()
381 - 15.08.96 Removed unused variables
382 - 07.07.14 Use bl prefix for functions By: CTP
383 - 23.02.15 Modified for new blRenumAtomsPDB() which takes an offset
384 - 29.09.15 Renamed as doRepOneSChain() and wrappers written as
385  blRepOneSChain() and blRepOneSChainForce()
386 */
387 static BOOL doRepOneSChain(PDB *pdb, char *ResSpec, char aa,
388  char *ChiTable, char *RefCoords, BOOL force)
389 {
390  PDB *ResStart, /* Start of residue */
391  *NextRes; /* Start of next residue */
392  BOOL noenv = FALSE; /* Flag for no env. var. found */
393 
394  if(sFirstCall)
395  {
396  FILE *fp_ChiTable;
397 
398  /* Allocate 2D array for equivalent torsions */
399  if((sChiTab = (int **)blArray2D(sizeof(int), NUMAAKNOWN, NUMAAKNOWN))
400  == NULL)
401  return(FALSE);
402 
403  /* Open files */
404  if((fp_ChiTable = blOpenFile(ChiTable,"DATADIR","r",&noenv)) == NULL)
405  {
406  if(noenv)
407  {
408  sprintf(gRSCError,"DATADIR environment variable not set\n");
409  }
410  else
411  {
412  sprintf(gRSCError,"Unable to open chi link table: %s\n",
413  ChiTable);
414  }
415  return(FALSE);
416  }
417 
418  if((sFp_RefCoords = blOpenFile(RefCoords,"DATADIR","r",&noenv)) ==
419  NULL)
420  {
421  if(noenv)
422  {
423  sprintf(gRSCError,"DATADIR environment variable not set\n");
424  }
425  else
426  {
427  sprintf(gRSCError,"Unable to open reference coordinates: \
428 %s\n", RefCoords);
429  }
430  return(FALSE);
431  }
432 
433  /* Read the equivalent chi table and the atom table */
434  ReadChiTable(fp_ChiTable, sChiTab);
435 
436  /* Close the table files */
437  fclose(fp_ChiTable);
438 
439  sFirstCall = FALSE;
440  }
441 
442  /* Find the specified residue and the one following */
443  if((ResStart = blFindResidueSpec(pdb, ResSpec))==NULL)
444  {
445  sprintf(gRSCError,"Residue specification not in PDB list\n");
446  return(FALSE);
447  }
448  NextRes = blFindNextResidue(ResStart);
449 
450  /* If there is a sequence mismatch, or force is set,
451  replace the residue
452  */
453  if((aa != blThrone(ResStart->resnam)) || force)
454  {
455  if(DoReplace(ResStart, NextRes, aa, sChiTab, sFp_RefCoords) ==
456  NULL)
457  {
458  return(FALSE);
459  }
460  }
461 
462  blRenumAtomsPDB(pdb, 1);
463 
464  return(TRUE);
465 }
466 
467 
468 /************************************************************************/
469 /*>void blEndRepSChain(void)
470  -------------------------
471 *//**
472 
473  Cleans up open files and memory used by the sidechain replacement
474  routines.
475 
476 - 12.08.96 Original By: ACRM
477 - 07.07.14 Use bl prefix for functions By: CTP
478 */
479 void blEndRepSChain(void)
480 {
481  if(!sFirstCall)
482  {
483  sFirstCall = TRUE;
484 
485  if(sFp_RefCoords != NULL)
486  {
487  fclose(sFp_RefCoords);
488  sFp_RefCoords = NULL;
489  }
490 
491  if(sChiTab != NULL)
492  {
493  blFreeArray2D((char **)sChiTab, NUMAAKNOWN, NUMAAKNOWN);
494  sChiTab = NULL;
495  }
496  }
497 }
498 
499 
500 /************************************************************************/
501 /*>static PDB *DoReplace(PDB *ResStart, PDB *NextRes, char seq,
502  int **chitab, FILE *fp_RefCoords)
503  --------------------------------------------------------------
504 *//**
505 
506  \param[in,out] *ResStart Pointer to start of residue
507  \param[in] *NextRes Pointer to start of next res
508  \param[in] seq 1-letter code for this aa
509  \param[in] **chitab Equivalent chis
510  \param[in] *fp_RefCoords Reference coordinate file
511  \return If OK, Pointer to end of replaced
512  residue; NULL if error.
513 
514  Main dispatch routine for replacing one residue with another.
515 
516 - 12.05.92 Original
517 - 21.06.93 Changed to use Array2D allocated chitab
518 - 29.09.15 Removed check that we need to do the replacement
519 */
520 static PDB *DoReplace(PDB *ResStart, /* Pointer to start of residue */
521  PDB *NextRes, /* Pointer to start of next res */
522  char seq, /* 1-letter code for this aa */
523  int **chitab, /* Equivalent chis */
524  FILE *fp_RefCoords) /* Reference coordinate file */
525 {
526  int retval = 0;
527  PDB *p;
528 
529  /* Check we need to do a replacement */
530 /* if(seq == blThrone(ResStart->resnam)) return(NULL); */
531 
532  if(!strncmp(ResStart->resnam,"GLY",3)) /* Replace Gly with X */
533  {
534  retval = ReplaceGly(ResStart,NextRes,seq,fp_RefCoords);
535  }
536  else
537  {
538  /* The original is not gly, so we need to check that the CBeta is
539  there
540  */
541  if(gotCBeta(ResStart, NextRes))
542  {
543  if(seq == 'G') /* Replace X with Gly */
544  retval = ReplaceWithGly(ResStart, NextRes);
545  else if(seq == 'A') /* Replace X with Ala */
546  retval = ReplaceWithAla(ResStart, NextRes);
547  else /* Replace X with Y */
548  retval = Replace(ResStart,NextRes,seq,chitab,fp_RefCoords);
549  }
550  else /* No CBeta, so treat it as if it were a glycine */
551  {
552  retval = ReplaceGly(ResStart,NextRes,seq,fp_RefCoords);
553  }
554 
555  }
556 
557 
558  if(retval) /* Problem */
559  {
560  switch(retval)
561  {
562  case ERROR_NOMEM:
563  strcpy(gRSCError, "Memory allocation failed");
564  break;
565  case ERROR_ATOMS:
566  strcpy(gRSCError, "Could not build sidechain as backbone atoms \
567 were missing");
568  break;
569  case ERROR_UNKNOWNAA:
570  strcpy(gRSCError, "Unknown replacement amino acid");
571  break;
572  default:
573  strcpy(gRSCError, "Undefined error");
574  }
575  return(NULL);
576  }
577 
578 
579  /* Step through from ResStart to find the last replaced atom */
580  for(p=ResStart; p && p->next != NextRes; NEXT(p));
581 
582  return(p);
583 }
584 
585 
586 /************************************************************************/
587 /*>static BOOL gotCBeta(PDB *ResStart, PDB *NextRes)
588  -------------------------------------------------
589 *//**
590  \param[in,out] *ResStart Start of residue to be modified
591  \param[in] *NextRes Pointer to start of next residue
592  \return TRUE: CB present; FALST; not present
593 
594  Checks if the residue has a CBeta atom
595 
596 - 23.03.17 Original By: ACRM
597 */
598 static BOOL gotCBeta(PDB *ResStart, PDB *NextRes)
599 {
600  PDB *p;
601 
602  for(p=ResStart; p!=NextRes; NEXT(p))
603  {
604  if(!strncmp(p->atnam, "CB ", 4))
605  return(TRUE);
606  }
607  return(FALSE);
608 }
609 
610 
611 /************************************************************************/
612 /*>static int ReplaceWithGly(PDB *ResStart, PDB *NextRes)
613  ------------------------------------------------------
614 *//**
615 
616  \param[in,out] *ResStart Start of residue to be modified
617  \param[in] *NextRes Pointer to start of next residue
618  \return 0: OK, 1: error
619 
620  Replace residue X with Gly. This is simply a case of trimming the
621  sidechain and changing the residue name.
622 
623 - 12.05.92 Original
624 - 05.10.94 Changed for BOOL return from KillSidechain()
625 - 07.07.14 Use bl prefix for functions By: CTP
626 */
627 static int ReplaceWithGly(PDB *ResStart, /* Start of res */
628  PDB *NextRes) /* Start of next res */
629 {
630  BOOL retval;
631 
632  /* Kill sidechain. Third parameter is a flag to kill CB */
633  retval = blKillSidechain(ResStart,NextRes,TRUE);
634 
635  /* If OK, set the residue name */
636  if(retval) blSetResnam(ResStart,NextRes,"GLY ",ResStart->resnum,
637  ResStart->insert,ResStart->chain);
638 
639  return(retval?ERROR_OK:ERROR_NOMEM);
640 }
641 
642 
643 /************************************************************************/
644 /*>static int ReplaceWithAla(PDB *ResStart, PDB *NextRes)
645  ------------------------------------------------------
646 *//**
647 
648  \param[in,out] *ResStart Start of residue to be modified
649  \param[in] *NextRes Pointer to start of next residue
650  \return 0: OK, 1: error
651 
652  Replace residue X with Ala. This is simply a case of trimming the
653  sidechain and changing the residue name.
654 
655 - 12.05.92 Original
656 - 05.10.94 Changed for BOOL return from KillSidechain()
657 - 07.07.14 Use bl prefix for functions By: CTP
658 */
659 static int ReplaceWithAla(PDB *ResStart, /* Start of residue */
660  PDB *NextRes) /* Start of next residue */
661 {
662  BOOL retval;
663 
664  /* Kill sidechain. Third parameter is a flag not to kill CB */
665  retval = blKillSidechain(ResStart,NextRes,FALSE);
666 
667  /* If OK, set the residue name */
668  if(retval) blSetResnam(ResStart,NextRes,"ALA ",ResStart->resnum,
669  ResStart->insert,ResStart->chain);
670 
671  return(retval?ERROR_OK:ERROR_NOMEM);
672 }
673 
674 
675 /************************************************************************/
676 /*>static int ReplaceGly(PDB *ResStart, PDB *NextRes, char seq,
677  FILE *fp_RefCoords)
678  ------------------------------------------------------------
679 *//**
680 
681  \param[in,out] *ResStart Start of residue to be modified
682  \param[in] *NextRes Pointer to start of next residue
683  \param[in] seq 1-letter code for replacement residue
684  \param[in] *fp_RefCoords Reference coordinate file pointer
685  \return 0: OK
686  1: memory allocation error
687  2: missing atoms error
688 
689  Replace a Gly with another residue type.
690 
691 - 12.05.92 Original
692 - 21.06.93 Changed for new version of onethr(). Removed unused param.
693 - 09.07.93 Simplified allocation checking
694 - 07.07.14 Use bl prefix for functions By: CTP
695 - 21.03.17 Added different error returns
696 */
697 static int ReplaceGly(PDB *ResStart,
698  PDB *NextRes,
699  char seq,
700  FILE *fp_RefCoords)
701 {
702  int retval = 0, /* Assume everything OK */
703  natoms;
704  PDB *p, /* General PDB pointer */
705  *q, /* General PDB pointer */
706  *reference = NULL, /* Reference PDB linked list */
707  *ref_mc = NULL, /* Mainchain from reference PDB list*/
708  *parent_mc = NULL; /* Parent mainchain */
709  char *three; /* Three letter code */
710 
711  three = blOnethr(seq);
712 
713  /* Read the required residue type out of the reference coordinate file.
714  Returns NULL if unable to allocate memory, or residue not found.
715  */
716  reference = ReadRefCoords(fp_RefCoords, seq);
717  if(reference == NULL)
718  {
719  retval = ERROR_NOMEM;
720  goto Cleanup;
721  }
722 
723  /* Build a PDB linked list from the parent N, CA, C */
724  natoms = 0;
725  for(p=ResStart; p && p!=NextRes; NEXT(p))
726  {
727  if(!strncmp(p->atnam,"N ",4) ||
728  !strncmp(p->atnam,"CA ",4) ||
729  !strncmp(p->atnam,"C ",4))
730  {
731  natoms++;
732 
733  if(parent_mc == NULL) /* Initialise start of list */
734  {
735  INIT(parent_mc,PDB);
736  q = parent_mc;
737  }
738  else /* Next item in list */
739  {
740  ALLOCNEXT(q,PDB);
741  }
742 
743  /* Check allocation */
744  if(q == NULL)
745  {
746  retval = ERROR_NOMEM;
747  goto Cleanup;
748  }
749 
750 
751  blCopyPDB(q,p); /* Copy PDB item */
752  }
753  }
754  if(natoms != 3) /* Atoms missing */
755  {
756  retval = ERROR_ATOMS;
757  goto Cleanup;
758  }
759 
760 
761  /* Build a PDB linked list from the reference N, CA, C */
762  natoms = 0;
763  for(p=reference; p; NEXT(p))
764  {
765  if(!strncmp(p->atnam,"N ",4) ||
766  !strncmp(p->atnam,"CA ",4) ||
767  !strncmp(p->atnam,"C ",4))
768  {
769  natoms++;
770 
771  if(ref_mc == NULL) /* Initialise start of list */
772  {
773  INIT(ref_mc,PDB);
774  q = ref_mc;
775  }
776  else /* Next item in list */
777  {
778  ALLOCNEXT(q,PDB);
779  }
780 
781  /* Check allocation */
782  if(q == NULL)
783  {
784  retval = ERROR_NOMEM;
785  goto Cleanup;
786  }
787 
788  blCopyPDB(q,p); /* Copy PDB item */
789  }
790  }
791  if(natoms != 3) /* Atoms missing */
792  {
793  retval = ERROR_ATOMS;
794  goto Cleanup;
795  }
796 
797  /* Move the reference aa by fitting on the atoms stored in _mc */
798  if(FitByFragment(parent_mc, ref_mc, reference))
799  {
800  retval = ERROR_NOMEM;
801  goto Cleanup;
802  }
803 
804  /* Now insert the s/c into the main linked list, last parameter is a
805  flag to insert the CB
806  */
807  if(InsertSC(reference, ResStart, NextRes, TRUE))
808  retval = ERROR_NOMEM;
809 
810  if(retval == ERROR_OK)
811  blSetResnam(ResStart,NextRes,three,ResStart->resnum,
812  ResStart->insert,ResStart->chain);
813 
814 Cleanup:
815  if(reference != NULL) FREELIST(reference, PDB);
816  if(ref_mc != NULL) FREELIST(ref_mc, PDB);
817  if(parent_mc != NULL) FREELIST(parent_mc, PDB);
818 
819  return(retval);
820 }
821 
822 
823 /************************************************************************/
824 /*>static int FitByFragment(PDB *destination, PDB *fragment, PDB *mobile)
825  ----------------------------------------------------------------------
826 *//**
827 
828  \param[in] *destination Fragment we're fitting to
829  \param[in] *fragment Part of mobile to fit
830  \param[in,out] *mobile Whole section to move
831  Returns int 0:OK, 1:Error
832 
833  Calculate the best fit for moving fragment onto destination. Then move
834  mobile in this manner. This is used to fit one mainchain (fragment)
835  onto another (destination) then move the whole amino acid (mobile) to
836  overlap the mainchains.
837 
838 - 12.05.92 Original
839 - 19.05.94 Calls ApplyMatrixPDB() rather than RotatePDB()
840 - 07.07.14 Use bl prefix for functions By: CTP
841 */
842 static int FitByFragment(PDB *destination, /* Fragment we're fitting to */
843  PDB *fragment, /* Part of mobile to fit */
844  PDB *mobile) /* Whole section to move */
845 {
846  VEC3F cg_fragment,
847  cg_destination;
848  REAL rm[3][3]; /* Rotation matrix from fitting */
849 
850  /* Correct the atom order for the PDB lists */
851  destination = blShuffleBB(destination);
852  fragment = blShuffleBB(fragment);
853  mobile = blShuffleBB(mobile);
854 
855  /* Get CofG of fragment and destination */
856  blGetCofGPDB(fragment, &cg_fragment);
857  blGetCofGPDB(destination, &cg_destination);
858 
859  /* Fit the fragment to the destination */
860  if(!blFitCaCbPDB(destination, fragment, rm))
861  return(1);
862 
863  /* Negate the vector for the fragment CofG so we can translate
864  mobile to the origin.
865  */
866  cg_fragment.x = -cg_fragment.x;
867  cg_fragment.y = -cg_fragment.y;
868  cg_fragment.z = -cg_fragment.z;
869 
870  /* Move mobile so the CofG of fragment is at the origin */
871  blTranslatePDB(mobile, cg_fragment);
872 
873  /* RotatePDB mobile onto the destination */
874  blApplyMatrixPDB(mobile, rm);
875 
876  /* TranslatePDB mobile back to coincide fragments and
877  destination CofG
878  */
879  blTranslatePDB(mobile, cg_destination);
880 
881  return(0);
882 }
883 
884 
885 /************************************************************************/
886 /*>static int InsertSC(PDB *insert, PDB *ResStart, PDB *NextRes,
887  BOOL doCB)
888  -------------------------------------------------------------
889 *//**
890 
891  \param[in] *insert PDB linked list to insert
892  \param[in] *ResStart Start of residue
893  \param[in] *NextRes Start of next residue
894  \param[in] doCB TRUE: CB will be inserted
895  FALSE: CB not inserted
896  \return 0 if OK, 1 if error.
897 
898  Inserts the sidechain from insert into the PDB linked list just before
899  NextRes. Fresh allocations are made for the copy.
900 
901 - 12.05.92 Original
902 - 19.06.92 Added num char param to strncmp()!
903 - 11.03.94 Changed doCB to BOOL
904 */
905 static int InsertSC(PDB *insert,
906  PDB *ResStart,
907  PDB *NextRes,
908  BOOL doCB)
909 {
910  PDB *p,
911  *start,
912  *prev = NULL;
913 
914  if(doCB)
915  {
916  /* If doCB is set, kill the CB between ResStart and NextRes
917  if found
918  */
919  for(p=ResStart; p && p != NextRes; NEXT(p))
920  {
921  if(!strncmp(p->atnam,"CB ",4))
922  {
923  if(prev == NULL) return(1); /* No b/b atom before s/c */
924  blKillPDB(p, prev);
925  break;
926  }
927  prev = p;
928  }
929  }
930 
931  /* Find the position to insert. This will be start */
932  for(start=ResStart; start && start->next != NextRes; NEXT(start));
933 
934  /* Step through insert, copying non-backbone atoms into the linked list
935  after start
936  */
937  for(p=insert; p; NEXT(p))
938  {
939  if(strcmp(p->atnam, "N ") &&
940  strcmp(p->atnam, "CA ") &&
941  strcmp(p->atnam, "C ") &&
942  strcmp(p->atnam, "O ") &&
943  strcmp(p->atnam, "CB "))
944  {
945  ALLOCNEXT(start, PDB);
946  if(start == NULL) return(1);
947  blCopyPDB(start, p);
948  }
949 
950  /* Insert the CB if required */
951  if(doCB && !strcmp(p->atnam,"CB "))
952  {
953  ALLOCNEXT(start, PDB);
954  if(start == NULL) return(1);
955  blCopyPDB(start, p);
956  }
957  }
958 
959  /* Now link the end of this new section to NextRes */
960  start->next = NextRes;
961 
962  return(0);
963 }
964 
965 
966 /************************************************************************/
967 /*>static int Replace(PDB *ResStart, PDB *NextRes, char seq,
968  int **chitab, FILE *fp_RefCoords)
969  ---------------------------------------------------------
970 *//**
971 
972  \param[in,out] *ResStart Start of residue to be modified
973  \param[in] *NextRes Pointer to start of next residue
974  \param[in] seq 1-letter code for replacement residue
975  \param[in] **chitab Equivalent chi table
976  \param[in] *fp_RefCoords Reference coordinate file pointer
977  \return 0: OK, 1: error
978 
979  Replace a non-Gly with another residue type.
980 
981 - 12.05.92 Original
982 - 21.06.93 Changed for new version of onethr()
983 - 21.06.93 Changed to use Array2D allocated chitab
984 - 09.07.93 Simplified allocation checking
985 - 05.10.94 Changed for BOOL return from KillSidechain()
986 - 07.07.14 Use bl prefix for functions By: CTP
987 */
988 static int Replace(PDB *ResStart,
989  PDB *NextRes,
990  char seq,
991  int **chitab,
992  FILE *fp_RefCoords)
993 {
994  int retval = ERROR_OK, /* Assume everything OK */
995  natoms;
996  PDB *p, /* General PDB pointer */
997  *q, /* General PDB pointer */
998  *reference = NULL, /* Reference PDB linked list */
999  *ref_mc = NULL, /* Mainchain from reference PDB list*/
1000  *parent_mc = NULL; /* Parent mainchain */
1001  char *three; /* Three letter code */
1002 
1003  three = blOnethr(seq);
1004 
1005  /* Read the required residue type out of the reference coordinate file.
1006  Returns NULL if unable to allocate memory, or residue not found.
1007  */
1008  reference = ReadRefCoords(fp_RefCoords, seq);
1009  if(reference == NULL)
1010  {
1011  retval = ERROR_UNKNOWNAA;
1012  goto Cleanup;
1013  }
1014 
1015  /* Build a PDB linked list from the parent N, CA, C, CB */
1016  natoms = 0;
1017  for(p=ResStart; p && p!=NextRes; NEXT(p))
1018  {
1019  if(!strncmp(p->atnam,"N ",4) ||
1020  !strncmp(p->atnam,"CA ",4) ||
1021  !strncmp(p->atnam,"CB ",4) ||
1022  !strncmp(p->atnam,"C ",4))
1023  {
1024  natoms++;
1025 
1026  if(parent_mc == NULL) /* Initialise start of list*/
1027  {
1028  INIT(parent_mc,PDB);
1029  q = parent_mc;
1030  }
1031  else /* Next item in list */
1032  {
1033  ALLOCNEXT(q,PDB);
1034  }
1035 
1036  /* Check allocation */
1037  if(q == NULL)
1038  {
1039  retval = ERROR_NOMEM;
1040  goto Cleanup;
1041  }
1042 
1043  blCopyPDB(q,p); /* Copy PDB item */
1044  }
1045  }
1046  if(natoms != 4) /* Atoms missing */
1047  {
1048  retval = ERROR_ATOMS;
1049  goto Cleanup;
1050  }
1051 
1052 #ifdef DEBUG
1053  printf("Parent mainchain:\n");
1054  blWritePDB(stdout, parent_mc);
1055 #endif
1056 
1057  /* Build a PDB linked list from the reference N, CA, C, CB */
1058  natoms = 0;
1059  for(p=reference; p; NEXT(p))
1060  {
1061  if(!strncmp(p->atnam,"N ",4) ||
1062  !strncmp(p->atnam,"CA ",4) ||
1063  !strncmp(p->atnam,"CB ",4) ||
1064  !strncmp(p->atnam,"C ",4))
1065  {
1066  natoms++;
1067 
1068  if(ref_mc == NULL) /* Initialise start of list*/
1069  {
1070  INIT(ref_mc,PDB);
1071  q = ref_mc;
1072  }
1073  else /* Next item in list */
1074  {
1075  ALLOCNEXT(q,PDB);
1076  }
1077 
1078  /* Check allocation */
1079  if(q == NULL)
1080  {
1081  retval = ERROR_NOMEM;
1082  goto Cleanup;
1083  }
1084 
1085  blCopyPDB(q,p); /* Copy PDB item */
1086  }
1087  }
1088  if(natoms != 4) /* Atoms missing */
1089  {
1090  retval = ERROR_ATOMS;
1091  goto Cleanup;
1092  }
1093 
1094 #ifdef DEBUG
1095  printf("Reference mainchain:\n");
1096  blWritePDB(stdout, ref_mc);
1097 #endif
1098 
1099  /* Move the reference aa by fitting on the atoms stored in _mc */
1100  if(FitByFragment(parent_mc, ref_mc, reference))
1101  {
1102  retval = ERROR_NOMEM;
1103  goto Cleanup;
1104  }
1105 
1106 #ifdef DEBUG
1107  printf("Reference structure after fitting to parent:\n");
1108  blWritePDB(stdout, reference);
1109 #endif
1110 
1111  /* Fix the s/c torsion angles to match those in the parent. This may
1112  shuffle the atom order, so ResStart gets reset.
1113  */
1114  ResStart = FixTorsions(reference, ResStart, NextRes, chitab);
1115 
1116 #ifdef DEBUG
1117  printf("Reference structure matching torsions:\n");
1118  blWritePDB(stdout, reference);
1119 #endif
1120 
1121  /* Kill sidechain. Third parameter is a flag kill CB */
1122  retval = ((blKillSidechain(ResStart,NextRes,TRUE))
1123  ? ERROR_OK : ERROR_NOMEM);
1124 
1125  /* Now insert the s/c into the main linked list, last parameter is a
1126  flag to insert the CB
1127  */
1128  if(InsertSC(reference, ResStart, NextRes, TRUE))
1129  retval = ERROR_NOMEM;
1130 
1131  if(retval == ERROR_OK)
1132  blSetResnam(ResStart,NextRes,three,ResStart->resnum,
1133  ResStart->insert,ResStart->chain);
1134 
1135 Cleanup:
1136  if(reference != NULL) FREELIST(reference, PDB);
1137  if(ref_mc != NULL) FREELIST(ref_mc, PDB);
1138  if(parent_mc != NULL) FREELIST(parent_mc, PDB);
1139 
1140  return(retval);
1141 }
1142 
1143 
1144 /************************************************************************/
1145 /*>static PDB *ReadRefCoords(FILE *fp, char seq)
1146  ---------------------------------------------
1147 *//**
1148 
1149  \param[in] *fp Reference PDB file pointer
1150  \param[in] seq Residue for which to search
1151  \return PDB linked list containing residue information
1152 
1153  Reads the sidechain reference file (fp) to find residue type seq, then
1154  reads in the data for that sidechain into a PDB linked list which is
1155  then returned.
1156  Returns NULL if there is a problem;
1157 
1158 - 12.05.92 Original
1159 - 21.06.93 Changed for new version of onethr()
1160 - 09.07.93 Corrected check on allocations
1161 - 04.01.94 Corrected string assignments of NULL to '\0'
1162 - 09.02.05 Sets atnam_raw
1163  Sets default occ/bval to 1.0 and 20.0
1164 - 03.06.05 Sets altpos
1165 - 05.08.14 Use CLEAR_PDB() to set default values. By: CTP
1166 - 25.02.15 Now sets the element type By: ACRM
1167 */
1168 static PDB *ReadRefCoords(FILE *fp,
1169  char seq)
1170 {
1171  PDB *p = NULL,
1172  *pdb = NULL;
1173  char buffer[MAXBUFF],
1174  *ptr,
1175  *three;
1176  int done = FALSE;
1177 
1178  rewind(fp);
1179 
1180  three = blOnethr(seq);
1181 
1182  /* Get lines from the file */
1183  while(fgets(buffer, MAXBUFF, fp))
1184  {
1185  TERMINATE(buffer);
1186  ptr = buffer;
1187 
1188  if(!strncmp(buffer,"ATOM ",6) && !strncmp(buffer+17, three, 3))
1189  {
1190  if(pdb == NULL) /* Initialise PDB list */
1191  {
1192  INIT(pdb, PDB);
1193  p = pdb;
1194  }
1195  else /* Allocate next record */
1196  {
1197  ALLOCNEXT(p, PDB);
1198  }
1199 
1200  /* Check allocation */
1201  if(p==NULL)
1202  {
1203  if(pdb!=NULL) FREELIST(pdb,PDB);
1204  return(NULL);
1205  }
1206 
1207  /* Clear PDB */
1208  CLEAR_PDB(p);
1209 
1210  /* Copy the first 6 charcters into RECORD_TYPE */
1211  strncpy(p->record_type,ptr,6);
1212  p->record_type[6] = '\0';
1213 
1214  ptr += 6;
1215 
1216  /* Read atnum from here */
1217  sscanf(ptr,"%d",&(p->atnum));
1218 
1219  ptr += 7; /* 2 spaces */
1220 
1221  /* Copy the next 4 characters into ATNAM */
1222  strncpy(p->atnam,ptr,4);
1223  p->atnam[4] = '\0';
1224 
1225  /* 09.02.05 ...and into atnam_raw */
1226  p->atnam_raw[0] = ' ';
1227  strncpy(p->atnam_raw+1,ptr,3);
1228  p->atnam_raw[4] = '\0';
1229 
1230  /* 03.06.05 set alternate indicator to a blank */
1231  p->altpos = ' ';
1232 
1233  ptr += 4;
1234 
1235  /* Copy the next 4 characters into RESNAM */
1236  strncpy(p->resnam,ptr,4);
1237  p->resnam[4] = '\0';
1238 
1239  ptr += 4;
1240 
1241  /* Copy the next 1 character into CHAIN */
1242  strncpy(p->chain,ptr,1);
1243  p->chain[1] = '\0';
1244 
1245  ptr += 1;
1246 
1247  /* Read resnum from here */
1248  sscanf(ptr,"%d",&(p->resnum));
1249 
1250  ptr += 4;
1251 
1252 
1253  /* Copy the next character into INSERT */
1254  strncpy(p->insert,ptr,1);
1255  p->insert[1] = '\0';
1256 
1257  ptr += 4;
1258 
1259  /* Read x from here */
1260  sscanf(ptr,"%lf",&(p->x));
1261 
1262  ptr += 8;
1263 
1264  /* Read y from here */
1265  sscanf(ptr,"%lf",&(p->y));
1266 
1267  ptr += 8;
1268 
1269  /* Read z from here */
1270  sscanf(ptr,"%lf",&(p->z));
1271 
1272  /* We don't care about occ and BVal */
1273  p->occ = 1.0;
1274  p->bval = 20.0;
1275 
1276  /* 25.02.15 Set the element type from atnam_raw */
1278 
1279  done = TRUE;
1280  }
1281  else
1282  {
1283  /* If we've got some data we exit as soon as another residue is
1284  found.
1285  */
1286  if(done) break;
1287  }
1288  }
1289 
1290  return(pdb);
1291 }
1292 
1293 
1294 /************************************************************************/
1295 /*>static void ReadChiTable(FILE *fp, int **chitab)
1296  ------------------------------------------------
1297 *//**
1298 
1299  \param[in] *fp Equivalent Chi table file pointer
1300  \param[out] **chitab Equivalent chi table.
1301 
1302  Read the chi table and creates the chitab array.
1303 
1304 - 13.05.92 Original
1305 - 21.06.93 Changed to use Array2D allocated chitab
1306 */
1307 static void ReadChiTable(FILE *fp,
1308  int **chitab)
1309 {
1310  char buffer[160],
1311  *ptr;
1312  int StarFound = FALSE,
1313  row = 0,
1314  col = 0;
1315 
1316  while(fgets(buffer,160,fp))
1317  {
1318  if(StarFound)
1319  {
1320  ptr = buffer+4;
1321  for(col = 0; col<NUMAAKNOWN; col++, ptr += 4)
1322  sscanf(ptr,"%d",&(chitab[row][col]));
1323  if(row++ >= NUMAAKNOWN) break;
1324  }
1325  if(buffer[0] == '*') StarFound = TRUE;
1326  }
1327 
1328 #ifdef DEBUG
1329  for(row=0; row<NUMAAKNOWN; row++)
1330  {
1331  for(col=0; col<NUMAAKNOWN; col++) printf("%3d",chitab[row][col]);
1332  printf("\n");
1333  }
1334 #endif
1335 }
1336 
1337 
1338 /************************************************************************/
1339 /*>static int FindChiIndex(char *resnam)
1340  -------------------------------------
1341 *//**
1342 
1343  \param[in] *resnam Residue name
1344  \return Pointer into Chi table
1345 
1346  Find the index into the Chi table for a residue name
1347 - 13.05.92 Original
1348 */
1349 static int FindChiIndex(char *resnam)
1350 {
1351  int ret = -1;
1352 
1353  if(!strncmp(resnam,"ALA",3)) ret = 0;
1354  if(!strncmp(resnam,"ARG",3)) ret = 1;
1355  if(!strncmp(resnam,"ASN",3)) ret = 2;
1356  if(!strncmp(resnam,"ASP",3)) ret = 3;
1357  if(!strncmp(resnam,"CYS",3)) ret = 4;
1358  if(!strncmp(resnam,"GLN",3)) ret = 5;
1359  if(!strncmp(resnam,"GLU",3)) ret = 6;
1360  if(!strncmp(resnam,"GLY",3)) ret = 7;
1361  if(!strncmp(resnam,"HIS",3)) ret = 8;
1362  if(!strncmp(resnam,"ILE",3)) ret = 9;
1363  if(!strncmp(resnam,"LEU",3)) ret = 10;
1364  if(!strncmp(resnam,"LYS",3)) ret = 11;
1365  if(!strncmp(resnam,"MET",3)) ret = 12;
1366  if(!strncmp(resnam,"PHE",3)) ret = 13;
1367  if(!strncmp(resnam,"PRO",3)) ret = 14;
1368  if(!strncmp(resnam,"SER",3)) ret = 15;
1369  if(!strncmp(resnam,"THR",3)) ret = 16;
1370  if(!strncmp(resnam,"TRP",3)) ret = 17;
1371  if(!strncmp(resnam,"TYR",3)) ret = 18;
1372  if(!strncmp(resnam,"VAL",3)) ret = 19;
1373 
1374  return(ret);
1375 }
1376 
1377 
1378 /************************************************************************/
1379 /*>static PDB *FixTorsions(PDB *pdb, PDB *ResStart, PDB *NextRes,
1380  int **chitab)
1381  --------------------------------------------------------------
1382 *//**
1383 
1384  \param[in,out] *pdb Linked list to fix torsions
1385  \param[in] *ResStart Beginning of reference frag
1386  \param[in] *NextRes Start of next residue
1387  \param[in] **chitab Equivalent chis table
1388  \return Start of residue. Normally same as input
1389  ResStart, but may differ as backbone
1390  order will be corrected.
1391 
1392  Take the equivalent torsion angle between ResStart and NextRes and
1393  apply them to pdb.
1394 
1395 - 13.05.92 Original
1396 - 21.06.93 Changed to use Array2D allocated chitab
1397 - 09.02.05 Chain name was getting set to last one in pdb
1398 - 14.12.16 Added check on return from blCalcChi()
1399 */
1400 static PDB *FixTorsions(PDB *pdb, /* Linked list to fix torsions */
1401  PDB *ResStart, /* Beginning of reference frag */
1402  PDB *NextRes, /* End of reference fragment */
1403  int **chitab) /* Equivalent chis */
1404 {
1405  int nchi,
1406  i,
1407  j;
1408  REAL ParentChi;
1409  char chain[8];
1410  PDB *p;
1411 
1412  strcpy(chain, ResStart->chain);
1413 
1414  /* Correct the atom order of pdb and ResStart */
1415  ResStart = blShuffleBB(ResStart);
1416 
1417  /* 09.02.05 Fix the chain name */
1418  for(p=ResStart; p!=NextRes; NEXT(p))
1419  {
1420  strcpy(p->chain, chain);
1421  }
1422 
1423  i = FindChiIndex(pdb->resnam);
1424  j = FindChiIndex(ResStart->resnam);
1425 
1426  /* If we haven't found one, we just return */
1427  if(i<0 || j<0) return(ResStart);
1428 
1429  /* look in the table for the number of chis */
1430  nchi = chitab[i][j];
1431 
1432  /* For each of the chis */
1433  for(j=0;j<nchi;j++)
1434  {
1435  if((ParentChi = blCalcChi(ResStart, j)) < 9998.0)
1436  {
1437  blSetChi(pdb, NULL, ParentChi, j);
1438  }
1439  }
1440 
1441  return(ResStart);
1442 }
1443 
1444 
#define ALLOCNEXT(x, y)
Definition: macros.h:251
PDB * blKillPDB(PDB *pdb, PDB *prev)
Definition: KillPDB.c:214
#define ERROR_UNKNOWNAA
Definition: rsc.c:130
void blSetChi(PDB *pdb, PDB *next, REAL chi, int type)
Definition: SetChi.c:119
Include file for PDB routines.
#define ERROR_NOMEM
Definition: rsc.c:128
REAL x
Definition: MathType.h:70
int resnum
Definition: pdb.h:310
short BOOL
Definition: SysDefs.h:64
#define NULL
Definition: array2.c:99
BOOL blFitCaCbPDB(PDB *ref_pdb, PDB *fit_pdb, REAL rm[3][3])
Definition: FitCaCbPDB.c:122
void blSetResnam(PDB *ResStart, PDB *NextRes, char *resnam, int resnum, char *insert, char *chain)
Definition: SetResnam.c:101
Definition: pdb.h:298
char ** blArray2D(int size, int dim1, int dim2)
Definition: array2.c:130
#define CLEAR_PDB(p)
Definition: pdb.h:460
char * blOnethr(char one)
Definition: throne.c:223
#define NUMAAKNOWN
Definition: rsc.c:125
#define ERROR_ATOMS
Definition: rsc.c:129
#define FALSE
Definition: macros.h:223
#define NEXT(x)
Definition: macros.h:249
char altpos
Definition: pdb.h:324
int atnum
Definition: pdb.h:309
char record_type[8]
Definition: pdb.h:315
Useful macros.
Include file for 2D/3D array functions.
Definition: aalist.h:70
FILE * blOpenFile(char *filename, char *envvar, char *mode, BOOL *noenv)
Definition: OpenFile.c:146
#define TERMINATE(x)
Definition: macros.h:366
char atnam[8]
Definition: pdb.h:316
Definition: MathType.h:69
char resnam[8]
Definition: pdb.h:319
double REAL
Definition: MathType.h:67
REAL z
Definition: pdb.h:300
Header file for sequence handling.
PDB * blFindResidueSpec(PDB *pdb, char *resspec)
char element[8]
Definition: pdb.h:322
void blFreeArray2D(char **array, int dim1, int dim2)
Definition: array2.c:174
void blEndRepSChain(void)
Definition: rsc.c:479
Include file for angle functions.
REAL blCalcChi(PDB *pdb, int type)
Definition: CalcChiPDB.c:111
char gRSCError[80]
#define TRUE
Definition: macros.h:219
PDB * blShuffleBB(PDB *pdb)
Definition: OrderPDB.c:389
BOOL blKillSidechain(PDB *ResStart, PDB *NextRes, BOOL doCB)
char atnam_raw[8]
Definition: pdb.h:317
int blWritePDB(FILE *fp, PDB *pdb)
Definition: WritePDB.c:223
BOOL blRepOneSChain(PDB *pdb, char *ResSpec, char aa, char *ChiTable, char *RefCoords)
Definition: rsc.c:319
char blThrone(char *three)
Definition: throne.c:153
void blCopyPDB(PDB *out, PDB *in)
Definition: CopyPDB.c:108
#define ERROR_OK
Definition: rsc.c:127
Header file for general purpose routines.
void blGetCofGPDB(PDB *pdb, VEC3F *cg)
Definition: GetCGPDB.c:98
#define FREELIST(y, z)
Definition: macros.h:264
#define INIT(x, y)
Definition: macros.h:244
System-type variable type definitions.
PDB * blFindNextResidue(PDB *pdb)
REAL occ
Definition: pdb.h:300
BOOL blRepOneSChainForce(PDB *pdb, char *ResSpec, char aa, char *ChiTable, char *RefCoords)
Definition: rsc.c:350
#define MAXBUFF
Definition: rsc.c:126
Type definitions for maths.
struct pdb_entry * next
Definition: pdb.h:307
REAL z
Definition: MathType.h:70
char chain[blMAXCHAINLABEL]
Definition: pdb.h:321
void blTranslatePDB(PDB *pdb, VEC3F tvect)
Definition: TranslatePDB.c:95
void blSetElementSymbolFromAtomName(char *element, char *atom_name)
Definition: WritePDB.c:1433
BOOL blRepSChain(PDB *pdb, char *sequence, char *ChiTable, char *RefCoords)
Definition: rsc.c:193
REAL y
Definition: MathType.h:70
REAL x
Definition: pdb.h:300
REAL y
Definition: pdb.h:300
REAL bval
Definition: pdb.h:300
void blRenumAtomsPDB(PDB *pdb, int offset)
void blApplyMatrixPDB(PDB *pdb, REAL matrix[3][3])
Definition: ApMatPDB.c:92
char insert[8]
Definition: pdb.h:320