#include "pdb.h" #define LOOP_RES_CHAIN(res,body) while(res != NULL) { body res = res->next;} void free_file_residues (file_records *file) { int ii,jj; residue_record ***residues = file->residues ; int * resnum_vector = file->resnum ; for(ii= 0 ; ii < 128 ; ii++) if (resnum_vector[ii]) { int limit = resnum_vector[ii] ; residue_record ** chain_residues = residues[ii] ; for(jj = 0 ; jj < limit ; jj++) { residue_record * res = chain_residues[jj] ; maybe_free(res) ; } free (chain_residues ) ; } } static int residue_count ; residue_record * allocate_residue_record(atom_record *atom,file_records *file, int index) { residue_record *res_pointer = ( residue_record *) malloc(sizeof(residue_record)); res_pointer->restype = atom->restype ; res_pointer->start = index; res_pointer->end = index + 1; res_pointer->chain = atom->chain ; res_pointer->file = (void *) file ; res_pointer->flags = 0 ; res_pointer->x_char = atom->x_char ; res_pointer->number = atom->resnum ; res_pointer->n = NULL ; res_pointer->cb= NULL ; res_pointer->ca = NULL ; res_pointer->c = NULL ; res_pointer->o = NULL ; if (PROTEIN_ATOM_P(atom)) residue_count++ ; strcpy(res_pointer->resname,atom->resname) ; return res_pointer ; } /* Make the residues records for the file. Return -1 on failure, when there are atoms in the same residue but not contiguous. */ int make_residues (file_records *file) { residue_record ***residues = file->residues ; int *resnum_vector = file->resnum ; int ii ; residue_record *previous_residue =NULL; atom_record **atoms = file->atoms; int atomnum = file->atomnum ; int maxres = 0 ; residue_count = 0 ; for(ii= 0 ;ii < atomnum ; ii++) { atom_record *atom = atoms[ii] ; if (atom->atomtype == RECORD_ATOM) { residue_description * res_type = atom->restype; int resnum = atom->resnum ; int chain = atom->chain ; int x_char = atom->x_char ; residue_record **chain_residues = residues[chain] ; if (chain_residues == NULL) { residue_record ** new = (residue_record **) malloc_and_zero(5000 * sizeof(residue_record *)) ; chain_residues = residues[chain] = new ; resnum_vector[chain] = 0 ; } { residue_record * res_pointer = previous_residue ; if (res_pointer == NULL || res_pointer->x_char != x_char || res_pointer->chain != chain || res_pointer->number != resnum) { res_pointer = allocate_residue_record(atom,file,ii) ; if(previous_residue != NULL) previous_residue->end = ii ; chain_residues[ resnum_vector[chain] ] = res_pointer ; res_pointer->index = resnum_vector[chain] ; resnum_vector[chain]++ ; } previous_residue = res_pointer ; /** ** MBG : Added following line on 2.II.94 ** replacing is_ca(atom) */ if (isCAorP(atom)) res_pointer->ca = atom ; else if (is_cb(atom)) res_pointer->cb = atom ; else if (is_o(atom)) res_pointer->o = atom ; else if (is_n(atom)) res_pointer->n = atom ; else if (is_c(atom)) res_pointer->c = atom ; } } } if(previous_residue != NULL) previous_residue->end = atomnum ; for (ii = 0 ; ii < 128 ; ii++) if (resnum_vector[ii]) { { int len = sizeof( residue_record *) * (resnum_vector[ii] ) ; residue_record ** temp = residues[ii] ; residues[ii] = calloc (resnum_vector[ii], sizeof (residue_record *)); bcopy(temp , residues[ii] ,len) ; free(temp ) ; } } file->flag =1 ; file->residue_count = residue_count ; return 0; } /* travrse all the atoms that belong to residue */ void traverse_residue_atoms (residue_record *res, void (*function)(), void *arg) { int ii; atom_record **atoms = res->file->atoms ; for(ii = res->start; ii< res->end ; ii++) { atom_record *atom = atoms[ii] ; if (!(atom->flags & IGNORE_ATOM)) (*function)(atom,arg,ii) ; } } /* traverse all the residues in the file */ int traverse_file_residues(file_records *file, void (*function)(), void *arg) { int ii ; if(!file->flag) { ii = make_residues(file) ; if(ii) return ii ; } { int jj; int * resnum_vector = file->resnum ; residue_record ***residues = file->residues ; for(ii =0 ; ii< 128; ii++) if(resnum_vector[ii]) { residue_record **chain_residues = residues[ii] ; int limit = resnum_vector[ii] ; for(jj = 0 ; jj< limit ; jj++) { (*function)( chain_residues[jj] ,arg) ; } } return 0 ; } } /* traverse only residues which are protein residues */ int traverse_file_protein_residues(file_records *file, void (*function)(), void *arg) { int ii,jj ; residue_record ***residues = file->residues ; int * resnum = file->resnum ; if (!file->flag) { ii = make_residues(file) ; if(ii) return ii ; } for(ii = 0 ; ii< 128 ; ii++) { if (resnum[ii]) { residue_record **chain_residues = residues[ii] ; for(jj = 0 ; jj< resnum[ii] ; jj++) { residue_record *res = chain_residues[jj] ; residue_description * restype = res->restype; if (restype != NULL) { int resindex = restype->index ; if (resindex >= 0 && resindex <= 20) (*function)(res,arg) ; } } } } return 0 ; } /* find a residue by its number and chain number*/ residue_record * residue_by_number (file_records *file, int index,int cc,int x_char) { int ii; if (!file->flag) { ii = make_residues(file) ; if(ii) return NULL ; } if (!cc) cc = ' ' ; { residue_record **residues = file->residues[cc] ; int limit = file->resnum[cc] ; if(residues == NULL) return NULL ; if (index >= 0 && index < limit && residues[index] != NULL ) { residue_record *res = residues[index] ; if(res->x_char == x_char && res->number == index) return res ; } for(ii = 0 ;ii < limit ; ii++) { residue_record *res = residues[ii] ; if(res->x_char == x_char && res->number == index) return res ; } return NULL ; } } /* travrse all the atoms that belong to residue */ atom_record *find_atom_in_residue (residue_record *res, char *name) { int ii; atom_record **atoms = res->file->atoms ; char first = name[0]; char second= name[1]; char third = name[2]; char fourth= name[3]; if (first != '\0') if (second == '\0') { second = ' ' ; third = ' '; fourth = '\0';} else if (third == '\0') { third = ' ' ; fourth = '\0' ; } ; for(ii = res->start; ii< res->end ; ii++) { atom_record *atom = atoms[ii] ; char *other_name = atom-> name ; if (other_name[0] == first && other_name[1] == second && other_name[2] == third && other_name[3] == fourth ) return atom ; } return NULL ; } /* the atom with the same name and same residue number in the file */ atom_record *find_atom (file_records *file, atom_record *atom) { residue_record *res = residue_by_number(file, atom->resnum,atom->chain,atom->x_char) ; if (res != NULL) return find_atom_in_residue(res, atom->name) ; return NULL ; } residue_record * next_residue(residue_record *res) { file_records *file = res->file ; int chain = res->chain; int next_index = res->index +1 ; int limit= file->resnum[chain] ; residue_record * next ; if (next_index < limit) return file->residues[chain][next_index] ; return NULL ; } residue_record *find_atom_residue(file_records *file, atom_record *atom) { return residue_by_number(file, atom->resnum,atom->chain,atom->x_char) ; } /*--------------------------------------------------------------------------*/