/*>static int InsertSC(PDB *insert, PDB *ResStart, PDB *NextRes, BOOL doCB) ------------------------------------------------------------- *//** \param[in] *insert PDB linked list to insert \param[in] *ResStart Start of residue \param[in] *NextRes Start of next residue \param[in] doCB TRUE: CB will be inserted FALSE: CB not inserted \return 0 if OK, 1 if error. Inserts the sidechain from insert into the PDB linked list just before NextRes. Fresh allocations are made for the copy. - 12.05.92 Original - 19.06.92 Added num char param to strncmp()! - 11.03.94 Changed doCB to BOOL */ static int InsertSC(PDB *insert, PDB *ResStart, PDB *NextRes, BOOL doCB) { PDB *p, *start, *prev = NULL; if(doCB) { /* If doCB is set, kill the CB between ResStart and NextRes if found */ for(p=ResStart; p && p != NextRes; NEXT(p)) { if(!strncmp(p->atnam,"CB ",4)) { if(prev == NULL) return(1); /* No b/b atom before s/c */ blKillPDB(p, prev); break; } prev = p; } } /* Find the position to insert. This will be start */ for(start=ResStart; start && start->next != NextRes; NEXT(start)); /* Step through insert, copying non-backbone atoms into the linked list after start */ for(p=insert; p; NEXT(p)) { if(strcmp(p->atnam, "N ") && strcmp(p->atnam, "CA ") && strcmp(p->atnam, "C ") && strcmp(p->atnam, "O ") && strcmp(p->atnam, "CB ")) { ALLOCNEXT(start, PDB); if(start == NULL) return(1); blCopyPDB(start, p); } /* Insert the CB if required */ if(doCB && !strcmp(p->atnam,"CB ")) { ALLOCNEXT(start, PDB); if(start == NULL) return(1); blCopyPDB(start, p); } } /* Now link the end of this new section to NextRes */ start->next = NextRes; return(0); }
/*>PDB *DupePDB(PDB *in) --------------------- Input: PDB *in Input PDB linked list Returns: PDB * Duplicated PDB linked list (NULL on allocation failure) Duplicates a PDB linked list. Allocates new linked list with identical data. 11.10.95 Original By: ACRM 08.10.99 Initialise q to NULL */ PDB *DupePDB(PDB *in) { PDB *out = NULL, *p, *q = NULL; for(p=in; p!=NULL; NEXT(p)) { if(out==NULL) { INIT(out, PDB); q=out; } else { ALLOCNEXT(q, PDB); } if(q==NULL) { FREELIST(out, PDB); return(NULL); } CopyPDB(q, p); } return(out); }
/*>SEQDATA *ReadAllSeqs(FILE *fp) ------------------------------ Reads in all the sequences in a PIR file into a linked list of sequences. 11.09.96 Original By: ACRM */ SEQDATA *ReadAllSeqs(FILE *fp) { SEQDATA *start = NULL, *prev = NULL, *p = NULL; SEQINFO seqinfo; BOOL punct, error; INIT(start, SEQDATA); if((p=start)==NULL) return(NULL); while(blReadPIR(fp, TRUE, p->seqs, 2, &seqinfo, &punct, &error)) { if(error) { FREELIST(start, SEQDATA); return(NULL); } prev = p; ALLOCNEXT(p,SEQDATA); if(p==NULL) { FREELIST(start, SEQDATA); return(NULL); } } /* Free up last one which was unused */ free(p); prev->next = NULL; return(start); }
/*>static int Replace(PDB *ResStart, PDB *NextRes, char seq, int **chitab, FILE *fp_RefCoords) --------------------------------------------------------- *//** \param[in,out] *ResStart Start of residue to be modified \param[in] *NextRes Pointer to start of next residue \param[in] seq 1-letter code for replacement residue \param[in] **chitab Equivalent chi table \param[in] *fp_RefCoords Reference coordinate file pointer \return 0: OK, 1: error Replace a non-Gly with another residue type. - 12.05.92 Original - 21.06.93 Changed for new version of onethr() - 21.06.93 Changed to use Array2D allocated chitab - 09.07.93 Simplified allocation checking - 05.10.94 Changed for BOOL return from KillSidechain() - 07.07.14 Use bl prefix for functions By: CTP */ static int Replace(PDB *ResStart, PDB *NextRes, char seq, int **chitab, FILE *fp_RefCoords) { int retval = 0, /* Assume everything OK */ natoms; PDB *p, /* General PDB pointer */ *q, /* General PDB pointer */ *reference = NULL, /* Reference PDB linked list */ *ref_mc = NULL, /* Mainchain from reference PDB list*/ *parent_mc = NULL; /* Parent mainchain */ char *three; /* Three letter code */ three = blOnethr(seq); /* Read the required residue type out of the reference coordinate file. Returns NULL if unable to allocate memory, or residue not found. */ reference = ReadRefCoords(fp_RefCoords, seq); if(reference == NULL) { retval = 1; goto Cleanup; } /* Build a PDB linked list from the parent N, CA, C, CB */ natoms = 0; for(p=ResStart; p && p!=NextRes; NEXT(p)) { if(!strncmp(p->atnam,"N ",4) || !strncmp(p->atnam,"CA ",4) || !strncmp(p->atnam,"CB ",4) || !strncmp(p->atnam,"C ",4)) { natoms++; if(parent_mc == NULL) /* Initialise start of list*/ { INIT(parent_mc,PDB); q = parent_mc; } else /* Next item in list */ { ALLOCNEXT(q,PDB); } /* Check allocation */ if(q == NULL) { retval = 1; goto Cleanup; } blCopyPDB(q,p); /* Copy PDB item */ } } if(natoms != 4) /* Atoms missing */ { retval = 1; goto Cleanup; } #ifdef DEBUG printf("Parent mainchain:\n"); blWritePDB(stdout, parent_mc); #endif /* Build a PDB linked list from the reference N, CA, C, CB */ natoms = 0; for(p=reference; p; NEXT(p)) { if(!strncmp(p->atnam,"N ",4) || !strncmp(p->atnam,"CA ",4) || !strncmp(p->atnam,"CB ",4) || !strncmp(p->atnam,"C ",4)) { natoms++; if(ref_mc == NULL) /* Initialise start of list*/ { INIT(ref_mc,PDB); q = ref_mc; } else /* Next item in list */ { ALLOCNEXT(q,PDB); } /* Check allocation */ if(q == NULL) { retval = 1; goto Cleanup; } blCopyPDB(q,p); /* Copy PDB item */ } } if(natoms != 4) /* Atoms missing */ { retval = 1; goto Cleanup; } #ifdef DEBUG printf("Reference mainchain:\n"); blWritePDB(stdout, ref_mc); #endif /* Move the reference aa by fitting on the atoms stored in _mc */ if(FitByFragment(parent_mc, ref_mc, reference)) { retval = 1; goto Cleanup; } #ifdef DEBUG printf("Reference structure after fitting to parent:\n"); blWritePDB(stdout, reference); #endif /* Fix the s/c torsion angles to match those in the parent. This may shuffle the atom order, so ResStart gets reset. */ ResStart = FixTorsions(reference, ResStart, NextRes, chitab); #ifdef DEBUG printf("Reference structure matching torsions:\n"); blWritePDB(stdout, reference); #endif /* Kill sidechain. Third parameter is a flag kill CB */ retval = ((blKillSidechain(ResStart,NextRes,TRUE)) ? 0 : 1); /* Now insert the s/c into the main linked list, last parameter is a flag to insert the CB */ if(InsertSC(reference, ResStart, NextRes, TRUE)) retval = 1; if(retval == 0) blSetResnam(ResStart,NextRes,three,ResStart->resnum, ResStart->insert,ResStart->chain); Cleanup: if(reference != NULL) FREELIST(reference, PDB); if(ref_mc != NULL) FREELIST(ref_mc, PDB); if(parent_mc != NULL) FREELIST(parent_mc, PDB); return(retval); }
/*>static int ReplaceGly(PDB *ResStart, PDB *NextRes, char seq, FILE *fp_RefCoords) ------------------------------------------------------------ *//** \param[in,out] *ResStart Start of residue to be modified \param[in] *NextRes Pointer to start of next residue \param[in] seq 1-letter code for replacement residue \param[in] *fp_RefCoords Reference coordinate file pointer \return 0: OK, 1: error Replace a Gly with another residue type. - 12.05.92 Original - 21.06.93 Changed for new version of onethr(). Removed unused param. - 09.07.93 Simplified allocation checking - 07.07.14 Use bl prefix for functions By: CTP */ static int ReplaceGly(PDB *ResStart, PDB *NextRes, char seq, FILE *fp_RefCoords) { int retval = 0, /* Assume everything OK */ natoms; PDB *p, /* General PDB pointer */ *q, /* General PDB pointer */ *reference = NULL, /* Reference PDB linked list */ *ref_mc = NULL, /* Mainchain from reference PDB list*/ *parent_mc = NULL; /* Parent mainchain */ char *three; /* Three letter code */ three = blOnethr(seq); /* Read the required residue type out of the reference coordinate file. Returns NULL if unable to allocate memory, or residue not found. */ reference = ReadRefCoords(fp_RefCoords, seq); if(reference == NULL) { retval = 1; goto Cleanup; } /* Build a PDB linked list from the parent N, CA, C */ natoms = 0; for(p=ResStart; p && p!=NextRes; NEXT(p)) { if(!strncmp(p->atnam,"N ",4) || !strncmp(p->atnam,"CA ",4) || !strncmp(p->atnam,"C ",4)) { natoms++; if(parent_mc == NULL) /* Initialise start of list */ { INIT(parent_mc,PDB); q = parent_mc; } else /* Next item in list */ { ALLOCNEXT(q,PDB); } /* Check allocation */ if(q == NULL) { retval = 1; goto Cleanup; } blCopyPDB(q,p); /* Copy PDB item */ } } if(natoms != 3) /* Atoms missing */ { retval = 1; goto Cleanup; } /* Build a PDB linked list from the reference N, CA, C */ natoms = 0; for(p=reference; p; NEXT(p)) { if(!strncmp(p->atnam,"N ",4) || !strncmp(p->atnam,"CA ",4) || !strncmp(p->atnam,"C ",4)) { natoms++; if(ref_mc == NULL) /* Initialise start of list */ { INIT(ref_mc,PDB); q = ref_mc; } else /* Next item in list */ { ALLOCNEXT(q,PDB); } /* Check allocation */ if(q == NULL) { retval = 1; goto Cleanup; } blCopyPDB(q,p); /* Copy PDB item */ } } if(natoms != 3) /* Atoms missing */ { retval = 1; goto Cleanup; } /* Move the reference aa by fitting on the atoms stored in _mc */ if(FitByFragment(parent_mc, ref_mc, reference)) { retval = 1; goto Cleanup; } /* Now insert the s/c into the main linked list, last parameter is a flag to insert the CB */ if(InsertSC(reference, ResStart, NextRes, TRUE)) retval = 1; if(retval == 0) blSetResnam(ResStart,NextRes,three,ResStart->resnum, ResStart->insert,ResStart->chain); Cleanup: if(reference != NULL) FREELIST(reference, PDB); if(ref_mc != NULL) FREELIST(ref_mc, PDB); if(parent_mc != NULL) FREELIST(parent_mc, PDB); return(retval); }
/*>static PDB *ReadRefCoords(FILE *fp, char seq) --------------------------------------------- *//** \param[in] *fp Reference PDB file pointer \param[in] seq Residue for which to search \return PDB linked list containing residue information Reads the sidechain reference file (fp) to find residue type seq, then reads in the data for that sidechain into a PDB linked list which is then returned. Returns NULL if there is a problem; - 12.05.92 Original - 21.06.93 Changed for new version of onethr() - 09.07.93 Corrected check on allocations - 04.01.94 Corrected string assignments of NULL to '\0' - 09.02.05 Sets atnam_raw Sets default occ/bval to 1.0 and 20.0 - 03.06.05 Sets altpos - 05.08.14 Use CLEAR_PDB() to set default values. By: CTP - 25.02.15 Now sets the element type By: ACRM */ static PDB *ReadRefCoords(FILE *fp, char seq) { PDB *p = NULL, *pdb = NULL; char buffer[MAXBUFF], *ptr, *three; int done = FALSE; rewind(fp); three = blOnethr(seq); /* Get lines from the file */ while(fgets(buffer, MAXBUFF, fp)) { TERMINATE(buffer); ptr = buffer; if(!strncmp(buffer,"ATOM ",6) && !strncmp(buffer+17, three, 3)) { if(pdb == NULL) /* Initialise PDB list */ { INIT(pdb, PDB); p = pdb; } else /* Allocate next record */ { ALLOCNEXT(p, PDB); } /* Check allocation */ if(p==NULL) { if(pdb!=NULL) FREELIST(pdb,PDB); return(NULL); } /* Clear PDB */ CLEAR_PDB(p); /* Copy the first 6 charcters into RECORD_TYPE */ strncpy(p->record_type,ptr,6); p->record_type[6] = '\0'; ptr += 6; /* Read atnum from here */ sscanf(ptr,"%d",&(p->atnum)); ptr += 7; /* 2 spaces */ /* Copy the next 4 characters into ATNAM */ strncpy(p->atnam,ptr,4); p->atnam[4] = '\0'; /* 09.02.05 ...and into atnam_raw */ p->atnam_raw[0] = ' '; strncpy(p->atnam_raw+1,ptr,3); p->atnam_raw[4] = '\0'; /* 03.06.05 set alternate indicator to a blank */ p->altpos = ' '; ptr += 4; /* Copy the next 4 characters into RESNAM */ strncpy(p->resnam,ptr,4); p->resnam[4] = '\0'; ptr += 4; /* Copy the next 1 character into CHAIN */ strncpy(p->chain,ptr,1); p->chain[1] = '\0'; ptr += 1; /* Read resnum from here */ sscanf(ptr,"%d",&(p->resnum)); ptr += 4; /* Copy the next character into INSERT */ strncpy(p->insert,ptr,1); p->insert[1] = '\0'; ptr += 4; /* Read x from here */ sscanf(ptr,"%lf",&(p->x)); ptr += 8; /* Read y from here */ sscanf(ptr,"%lf",&(p->y)); ptr += 8; /* Read z from here */ sscanf(ptr,"%lf",&(p->z)); /* We don't care about occ and BVal */ p->occ = 1.0; p->bval = 20.0; /* 25.02.15 Set the element type from atnam_raw */ blSetElementSymbolFromAtomName(p->element, p->atnam_raw); done = TRUE; } else { /* If we've got some data we exit as soon as another residue is found. */ if(done) break; } } return(pdb); }