#include #include #include #include #include #include "psa.h" #include "main.h" /* #include "states.h" #include "cs.h" #include "nn.h" #include "ssbond.h" #include "residue.h" #include "hetatm.h" #include "vector.h" #include "phipsi.h" #include "torison.h" #include "hydrogens.h" #include "rings.h" #include "es.h" #include "proline.h" #include "hbond.h" #include "optimize.h" #include "display.h" #include "chi.h" */ void define1(RESIDUE rz[]); void get_ca_dist(RESIDUE rz[],double ca_matrix[]); static double get_dist(RESIDUE rz[],int indxi,int indxj); void post_check(RESIDUE rz[]); static double get_rmsd(double ca_matrix[], double mask[], int maskLen, int idx); void check_beta(RESIDUE rz[],double ca_matrix[]); void check_helix(RESIDUE rz[],double ca_matrix[]); void hbond(RESIDUE *res, int resIdx,RESIDUE resArray[]); int getHbondIndex(float newDist,BOND_REC bondrec[MAX_HBONDS]); float v_get_dist(float onex,float oney,float onez,float twox,float twoy,float twoz); void calc_hcoords(RESIDUE resArray[]); float get_energy(RESIDUE *res1,RESIDUE *res2); void check_mainsidebond(int didx, int dneighbour, int donor, int aidx, int acceptor, int aneighbour,RESIDUE resArray[]); void getall_sbond(int idx,RESIDUE resArray[]); void check_sidebond(int didx, int dneighbour, int donor, int aidx,int acceptor, int aneighbour,RESIDUE resArray[]); void calc_bturn(RESIDUE resArray[]); void check_ho_bond(int didx,int donor,int dneighbour,void (*bond_check)(),RESIDUE resArray[]); void pickType(int val1_1, int val2_1, int val1_3, int val2_3, int index, char *type1, char *type3,RESIDUE resArray[]); int checkType(int val1,int val2,int val3,int val4,int val5,int indx,char *bturn_type,int bounds[5],RESIDUE resArray[]); void store_dist(float dist, int didx, int aidx, int donor, int neighbour,int acceptor,int aneighbour,RESIDUE resArray[]); float angle(RESIDUE rec1,int vec1a,int vec1b, RESIDUE rec2,int vec2a,int vec2b); void define3(RESIDUE resArray[]); void assign_define3(RESIDUE resArray[]); int get_beta(int residx,float phi,RESIDUE resArray[]); int old_get_beta(int i, float phi,float psi,float lastphi,RESIDUE resArray[]); void smooth_define3(RESIDUE resArray[]); void smooth_helix(RESIDUE resArray[]); void smooth_beta(RESIDUE resArray[]); void filter_define3(RESIDUE resArray[]); void do_consensus(RESIDUE resArray[]); void bturn_ss(RESIDUE resArray[]); void check_turn(int i,char *bturn,RESIDUE resArray[]); void smooth_ss(RESIDUE resArray[]); void do_consens_caps(int i,RESIDUE resArray[]); void do_consens_bridge(int i,RESIDUE resArray[]); int hbonded(int i,RESIDUE resArray[]); void assignSS(int residx,int type,char *value,RESIDUE resArray[]); int legitBond(RESIDUE residue,RESIDUE resArray[], int bondType); int getType(RESIDUE resx,int type); void do_define2(RESIDUE resArray[]); #define COIL 0 #define BETA 1 #define HELIX 2 #define TURN 3 #define ALSO_HELIX 4 #define ALSO_BETA 5 #define DSTR(x)( strcmp(x.dstruct3, "H") == 0 ? HELIX : ( strcmp(x.dstruct3, "B") == 0 ? BETA : COIL) ) #define NUM_SKIP 5 #define LEN_HELIX_MASK 5 #define LEN_BETA_MASK 3 #define hbond_dist 3.5 #define hbond_angle 90 #define hbond_dist2 2.5 #define sidebond_dist 3.5 #define DONOR 1 #define ACCEPTOR 2 #define RAD(x) x*M_PI/180 #define DEG(x) x*180/M_PI #define ABS(x)( (x)<0 ? -(x) : (x)) #define IN(x, target, range) ( (x >= (target - range)) && (x <= (target + range)) ) #ifdef _WIN32 /* SJN */ #include "direct.h" /* SJN */ #else /* SJN */ #include /* SJN */ #endif static int num_res; double hmask[LEN_HELIX_MASK] = {0,3.75,5.36,5.02,6.11}; double bmask[LEN_BETA_MASK] = {4.95,4.95,4.95}; double helix_rmsd = 0.22; double beta_rmsd = 0.6; void do_ss(RESIDUE rz[],int rno) { int i,j; num_res = rno + 1; // SJN: added offset of one calc_hcoords(rz); /* if (hbondsH2O) { read_H2O(); } */ for (i=0; i < rno; i++) { hbond(&rz[i], i,rz); getall_sbond(i,rz); /* if (hbondsH2O) { check_hbonds_water(i); } */ } calc_bturn(rz); // input_vadar(); /* calculate secondary structure using masks */ define1(rz); do_define2(rz); /* calculate secondary structure, using hbond information */ define3(rz); /* calculate consensus secondary structure */ do_consensus(rz); /* incorporate the bturn info into the secondary structures */ bturn_ss(rz); /* smooth all secondary structures */ smooth_ss(rz); } /* do_ss */ void define1(RESIDUE rz[]) { double *ca_matrix; int i; /*get_input_def1();*/ for (i=0; i 0 then it can not be a helix, * and if 0 < phi < 160 it can not be a beta. */ void post_check(RESIDUE rz[]) { int i; for (i=0; i 0.0) ) rz[i].ss = COIL; if ( (rz[i].ss == HELIX) && ( (rz[i].psi > 110) || (rz[i].phi < -110.0) ) ) rz[i].ss = COIL; if ( (rz[i].ss == BETA) && (rz[i].phi > 0.0) && (rz[i].phi < 160.0) ) rz[i].ss = COIL; } } /* post_check */ void calc_hcoords(RESIDUE resArray[]) { int i, j; float lengthoc; float ocx, ocy, ocz; for (i=1; i< num_res; i++) { /* skip if the coordinates are in the input file */ if (resArray[i].coords[H_COORD].x != NA) continue; /* calculate h atom */ ocx = - ( resArray[i-1].coords[O_COORD].x - resArray[i-1].coords[C_COORD].x); ocy = - ( resArray[i-1].coords[O_COORD].y - resArray[i-1].coords[C_COORD].y ); ocz = - ( resArray[i-1].coords[O_COORD].z - resArray[i-1].coords[C_COORD].z ); lengthoc = (float)sqrt((double) (pow((double)ocx,(double)2) + pow((double)ocy,(double)2) + pow((double)ocz,(double)2))); resArray[i].coords[H_COORD].x = resArray[i].coords[N_COORD].x + ocx/lengthoc; resArray[i].coords[H_COORD].y = resArray[i].coords[N_COORD].y + ocy/lengthoc; resArray[i].coords[H_COORD].z = resArray[i].coords[N_COORD].z + ocz/lengthoc; for (j = 0; j < MAX_HBONDS; j++) { resArray[i].hbonds[j].partner = NA; } } } /* calc_hcoords */ /************************************************************* * PURPOSE: calculate hydrogen bonds * INPUT: single residue record */ void hbond(RESIDUE *res, int resIdx,RESIDUE resArray[]) { int i, index; float hoDist, noDist, minimum; float bondangle; float energy; minimum = 4; for (i=0; i < num_res; i++) { /* if some residue < hbond_dist to this rec */ hoDist = v_get_dist(resArray[i].coords[H_COORD].x, resArray[i].coords[H_COORD].y, resArray[i].coords[H_COORD].z, res->coords[O_COORD].x, res->coords[O_COORD].y, res->coords[O_COORD].z); noDist = v_get_dist(resArray[i].coords[N_COORD].x, resArray[i].coords[N_COORD].y, resArray[i].coords[N_COORD].z, res->coords[O_COORD].x, res->coords[O_COORD].y, res->coords[O_COORD].z); if ( (hoDist < hbond_dist) && (hoDist < noDist) && (res->num != resArray[i].num) ) { /* check angle between OC and NH */ bondangle = angle(*res, O_COORD, C_COORD, resArray[i], N_COORD, H_COORD); /* set of checks to make sure it is a hbond */ if ( (fabs((double)bondangle) < hbond_angle) && (hoDist < (hbond_dist2 + fabs((double)cos((double)RAD(bondangle)))))&& (hoDist < minimum) ) { minimum = hoDist; /* get hbond energy */ energy = get_energy(res, &resArray[i]); /* set hbond for current res */ index = getHbondIndex(hoDist, res->hbonds); if (index != -1) { res->hbonds[index].partner = i; res->hbonds[index].dist = hoDist; /* normalize bond angle */ res->hbonds[index].angle = 180 - bondangle; res->hbonds[index].DA_FLAG = ACCEPTOR; res->hbonds[index].energy = energy; } /* set corresponding hbond */ index = getHbondIndex(hoDist, resArray[i].hbonds); if (index != -1) { resArray[i].hbonds[index].partner = resIdx; resArray[i].hbonds[index].dist = hoDist; resArray[i].hbonds[index].angle = bondangle; resArray[i].hbonds[index].DA_FLAG = DONOR; resArray[i].hbonds[index].energy = energy; } } } } } /* hbond */ /********************************************************************* * PURPOSE: to calculate the hbond energy between two residues */ float get_energy(RESIDUE *res1,RESIDUE *res2) { float energy; float rON, rCH, rOH, rCN; rON = v_get_dist(res1->coords[O_COORD].x, res1->coords[O_COORD].y, res1->coords[O_COORD].z, res2->coords[N_COORD].x, res2->coords[N_COORD].y, res2->coords[N_COORD].z); rCH = v_get_dist(res1->coords[C_COORD].x, res1->coords[C_COORD].y, res1->coords[C_COORD].z, res2->coords[H_COORD].x, res2->coords[H_COORD].y, res2->coords[H_COORD].z); rOH = v_get_dist(res1->coords[O_COORD].x, res1->coords[O_COORD].y, res1->coords[O_COORD].z, res2->coords[H_COORD].x, res2->coords[H_COORD].y, res2->coords[H_COORD].z); rCN = v_get_dist(res1->coords[C_COORD].x, res1->coords[C_COORD].y, res1->coords[C_COORD].z, res2->coords[N_COORD].x, res2->coords[N_COORD].y, res2->coords[N_COORD].z); /* formula from kabsch and sander, 1983 * hbond energy should be less than -0.5 kcal/mol * a good hbond has ~ -3.0 kcal/mol */ energy = 332 * .42 * .20 * ( 1/rON + 1/rCH - 1/rOH - 1/rCN); if (energy > 0) energy = 0; return(energy); } /* get_energy */ /*************************************************************/ /* return the distance between two points. */ float v_get_dist(float onex,float oney,float onez,float twox,float twoy,float twoz) { float distx, disty, distz; float distance; distx = onex - twox; disty = oney - twoy; distz = onez - twoz; distance = (float) sqrt((double) (pow((double)distx,(double)2)+ pow((double)disty,(double)2)+ pow((double)distz,(double)2))); return(distance); } /* get_dist */ /********************************************************************* * PURPOSE: get the index into the hbonds array */ int getHbondIndex(float newDist,BOND_REC bondrec[MAX_HBONDS]) { int j, maxIdx; float maximum; maximum = 0; for (j=0; j maximum) { maximum = bondrec[j].dist; maxIdx = j; } } if (newDist < maximum) { return(maxIdx); } else { return(-1); } } /* getHbondIndex */ /************************************************************* * PURPOSE: calculate all sidebond-sidebond bonds , and * all sidebond-mainchain bonds. * INPUT: single residue record */ void getall_sbond(int idx,RESIDUE resArray[]) { check_ho_bond(idx, N_COORD, H_COORD, check_mainsidebond,resArray); if (0 == strcmp(resArray[idx].type, "ARG")) { check_ho_bond(idx, NH1_COORD, CZ_COORD, check_sidebond,resArray); check_ho_bond(idx, NH2_COORD, CZ_COORD, check_sidebond,resArray); check_ho_bond(idx, NE_COORD, CZ_COORD, check_sidebond,resArray); } else if (0 == strcmp(resArray[idx].type, "ASP")) { check_ho_bond(idx, OD1_COORD, CG_COORD, check_sidebond,resArray); check_ho_bond(idx, OD2_COORD, CG_COORD, check_sidebond,resArray); } else if (0 == strcmp(resArray[idx].type, "GLU")) { check_ho_bond(idx, OE1_COORD, CD_COORD, check_sidebond,resArray); check_ho_bond(idx, OE2_COORD, CD_COORD, check_sidebond,resArray); } else if (0 == strcmp(resArray[idx].type, "LYS")) { check_ho_bond(idx, NZ_COORD, CE_COORD, check_sidebond,resArray); } else if (0 == strcmp(resArray[idx].type, "ASN")) { check_ho_bond(idx, ND2_COORD, CG_COORD, check_sidebond,resArray); } else if (0 == strcmp(resArray[idx].type, "GLN")) { check_ho_bond(idx, NE2_COORD, CD_COORD, check_sidebond,resArray); } else if (0 == strcmp(resArray[idx].type, "THR")) { check_ho_bond(idx, OG1_COORD, CB_COORD, check_sidebond,resArray); } else if (0 == strcmp(resArray[idx].type, "TYR")) { check_ho_bond(idx, OH_COORD, CZ_COORD, check_sidebond,resArray); } else if (0 == strcmp(resArray[idx].type, "SER")) { check_ho_bond(idx, OG_COORD, CB_COORD, check_sidebond,resArray); } else if (0 == strcmp(resArray[idx].type, "HIS")) { check_ho_bond(idx, ND1_COORD, CG_COORD, check_sidebond,resArray); check_ho_bond(idx, NE2_COORD, CG_COORD, check_sidebond,resArray); } else if (0 == strcmp(resArray[idx].type, "TRP")) { check_ho_bond(idx, NE1_COORD, CG_COORD, check_sidebond,resArray); } else return; } /* getall_sbond */ /*........................................................................... * PURPOSE: to assign b-turn designations to all residues */ void calc_bturn(RESIDUE resArray[]) { int i, j, k; int t1, t3, t1p, t3p; int doubleH, isHbond; int bounds[5]; int partIdx; for (i=0; i < num_res; i++) strcpy(resArray[i].bturn, " "); for (i=0; i < num_res -2; i++) { /* only assign a bturn IF no bturn has already been * assigned, AND there is not a double hydrogen bond * (for all i to i+3) AND there is an hbond from * i to i+3 */ doubleH = TRUE; isHbond = FALSE; for (j=i; j<=i+3; j++) { for (k=0; k 1) ) || ( ( (dist1 == 3) || (dist1 == 4) ) && (dist0 > 1) ) ) && ( psi < 100 ) ) strcpy(resArray[i].dstruct3, "H"); /* BETA */ /* else if (old_get_beta(i, phi, psi, lastphi)); */ else if (get_beta(i, phi,resArray)); /* COIL */ else strcpy(resArray[i].dstruct3, "C"); lastphi = phi; } } /* assign_define3 */ /********************************************************************* * PURPOSE: to assign the betas */ int get_beta(int residx,float phi,RESIDUE resArray[]) { int i; int dist; int partidx; int partnum; for (i=0; i 4) && (resArray[residx].dstruct3[0] != 'H') && (phi < 0) ) { strcpy(resArray[residx].dstruct3, "B"); return(TRUE); } } /* look also for beta smoothing in the smoothing calculations */ return(FALSE); } /* get_beta */ /********************************************************************* * PURPOSE: to assign the betas * NOTE: this routine has been replaced by get_beta. */ int old_get_beta(int i, float phi,float psi,float lastphi,RESIDUE resArray[]) { psi = resArray[i].psi; phi = resArray[i].phi; if ( legitBond(resArray[i],resArray, BETA) && (((phi < -40) && (phi > -180)) || ((phi > 160) && (phi <= 180))) && (((psi > 70) && (psi < 180)) || ((psi < -170) && (psi > -180)))) { strcpy(resArray[i].dstruct3, "B"); if ( (DSTR(resArray[i-1]) != BETA) && (DSTR(resArray[i-2]) != BETA) && (lastphi <-100) ) strcpy(resArray[i-1].dstruct3, "B"); return(TRUE); } /* also BETA */ if ( legitBond(resArray[i],resArray, ALSO_BETA) && (phi < -95) ) { strcpy(resArray[i].dstruct3, "B"); return(TRUE); } return(FALSE); } /* old_get_beta */ /********************************************************************* * PURPOSE: smooth out secondary structures */ void smooth_define3(RESIDUE resArray[]) { smooth_helix(resArray); smooth_beta(resArray); } /* smooth_define3 */ /********************************************************************* * PURPOSE: to smooth helices */ void smooth_helix(RESIDUE resArray[]) { int i; float phi, psi; /* check for pattern of HCHH or HHCH */ for (i=0; i 0) ) strcpy(resArray[i].dstruct3, "B"); } } } /* smooth_beta */ /********************************************************************* * PURPOSE: to smooth the beta's * NOTE: this routine is replaced by smooth_beta */ void old_smooth_beta(RESIDUE resArray[]) { int i; for (i=1; i=i-strucCount; j--) strcpy(resArray[j].dstruct3, "C"); if ( (strucLast == BETA) && (strucCount < 3) ) for (j=i-1; j>=i-strucCount; j--) strcpy(resArray[j].dstruct3, "C"); strucCount = 1; } strucLast = DSTR(resArray[i]); } } /* filter_define3 */ /********************************************************************* * PURPOSE: to see if there is a hydrogen bond that is legitimate * for a HELIX or BETA * CALLER: define3 */ int legitBond(RESIDUE residue,RESIDUE resArray[],int bondType) { int i, bondDist; int bond3, bond4; bond3 = bond4 = FALSE; for (i=0; i 2) && (bondDist < 6) ) return(TRUE); break; case ALSO_HELIX: if (bondDist == 3) bond3 = TRUE; if (bondDist == 4) bond4 = TRUE; if (bond3 && bond4) return(TRUE); break; case BETA: if ( bondDist > 2 ) return(TRUE); break; case ALSO_BETA: if ( bondDist >= 6 ) return(TRUE); break; } } return(FALSE); } /* legitBond */ /********************************************************************* * PURPOSE: to calculate a consensus secondary structure */ void do_consensus(RESIDUE resArray[]) { int i; for (i=0; i=i-strucCount; j--) assignSS(j, ss_type, "C",resArray); if ( (strucLast == BETA) && (strucCount < 3) ) for (j=i-1; j>=i-strucCount; j--) assignSS(j, ss_type, "C",resArray); strucCount = 1; } strucLast = strucThis; } } /* include helix caps and beta bridges */ for (i=0; i num_res) return; if ( (strcmp(resArray[i].consens, "C") == 0) && (strcmp(resArray[i+1].consens, "C") == 0) && (strcmp(resArray[i+2].consens, "H") == 0) && (strcmp(resArray[i+3].consens, "H") == 0) && (strcmp(resArray[i+4].consens, "H") == 0) ) { diff3 = diff4 = FALSE; for (j=0; j 90) ) { strcpy(resArray[i+1].dstruct1, "H"); strcpy(resArray[i+1].dstruct2, "H"); strcpy(resArray[i+1].dstruct3, "H"); strcpy(resArray[i+1].consens, "H"); } } } /* do_consens_caps */ /********************************************************************* * PURPOSE: to assign short beta bridges, on the consensus and * the other structures. */ void do_consens_bridge(int i,RESIDUE resArray[]) { short j, diff4; /* placing helix N-cap * look for CCC * then look at the i+1 position */ if (i+2 > num_res) { return; } if ( (strcmp(resArray[i].consens, "C") == 0) && (strcmp(resArray[i+1].consens, "C") == 0) && (strcmp(resArray[i+2].consens, "C") == 0) ) { diff4 = FALSE; for (j=0; j 4) ) { diff4 = TRUE; } } if ( diff4 && ( resArray[i].phi < 0 ) && ( resArray[i+1].phi < 0 ) && ( resArray[i+2].phi < 0 ) && ( ABS(resArray[i].psi) > 90 ) && ( ABS(resArray[i+1].psi) > 90 ) && ( ABS(resArray[i+2].psi) > 90 ) ) { strcpy(resArray[i].dstruct1, "B"); strcpy(resArray[i].dstruct2, "B"); strcpy(resArray[i].dstruct3, "B"); strcpy(resArray[i].consens, "B"); strcpy(resArray[i+1].dstruct1, "B"); strcpy(resArray[i+1].dstruct2, "B"); strcpy(resArray[i+1].dstruct3, "B"); strcpy(resArray[i+1].consens, "B"); strcpy(resArray[i+2].dstruct1, "B"); strcpy(resArray[i+2].dstruct2, "B"); strcpy(resArray[i+2].dstruct3, "B"); strcpy(resArray[i+2].consens, "B"); } } } /* do_consens_bridge */ /************************************************************************ * PURPOSE: to see if there are double hydrogen bonds */ int hbonded(int i,RESIDUE resArray[]) { if ( (resArray[i+1].hbonds[0].partner != NA) && (resArray[i+1].hbonds[1].partner != NA) && (resArray[i+2].hbonds[0].partner != NA) && (resArray[i+2].hbonds[1].partner != NA) ) { return(TRUE); } else { return(FALSE); } } /* hbonded */ /********************************************************************* * PURPOSE: assign the structure fo residue. */ void assignSS(int residx,int type,char *value,RESIDUE resArray[]) { switch (type) { case 0: strcpy(resArray[residx].dstruct1, value); break; case 1: strcpy(resArray[residx].dstruct2, value); break; case 2: strcpy(resArray[residx].dstruct3, value); break; case 3: strcpy(resArray[residx].consens, value); break; } } /* assignSS */ /********************************************************************* * PURPOSE: return the type of ss structure for residue. */ int getType(RESIDUE resx,int type) { int ret; switch (type) { case 0: ret = strcmp(resx.dstruct1, "H") == 0 ? HELIX : ( ret = strcmp(resx.dstruct1, "B") == 0 ? BETA : COIL ) ; break; case 1: ret = strcmp(resx.dstruct2, "H") == 0 ? HELIX : ( ret = strcmp(resx.dstruct2, "B") == 0 ? BETA : COIL ) ; break; case 2: ret = strcmp(resx.dstruct3, "H") == 0 ? HELIX : ( ret = strcmp(resx.dstruct3, "B") == 0 ? BETA : COIL ) ; break; case 3: ret = strcmp(resx.consens, "H") == 0 ? HELIX : ( ret = strcmp(resx.consens, "B") == 0 ? BETA : COIL ) ; break; } return(ret); } /* getType */ /*************************************************************/ /* Main calculation loop */ void do_define2(RESIDUE resArray[]) { int i, j; int ret; int strucCount, strucLast; float lastphi; float phi, psi; lastphi = 0.0; /* print_run(outfp); fprintf(stdout, " Calculating secondary structure...\n"); */ for (i=0; i -120) && (resArray[i].psi >-80) && (resArray[i].psi < 6) ) { resArray[i].ss = HELIX; } if ( (resArray[i].ss == HELIX) && (resArray[i-1].ss != HELIX) && (resArray[i-2].ss != HELIX) && (lastphi <-55) && (lastphi >-90) ) { resArray[i-1].ss = HELIX; } if ( ( (resArray[i].phi < -40) && (resArray[i].phi > -180) || ( (resArray[i].phi > 160) && (resArray[i].phi <= 180) ) ) && ( ((resArray[i].psi > 70) && (resArray[i].psi < 180) ) || ((resArray[i].psi < -170) && (resArray[i].psi > -180)) ) ) resArray[i].ss = BETA; if ( (resArray[i].ss == BETA) && (resArray[i-1].ss != BETA) && (resArray[i-2].ss != BETA) && (lastphi <-100) ) resArray[i-1].ss = BETA; lastphi = resArray[i].phi; } /* filter */ strucCount = 1; strucLast = 0; for (i=1; i< num_res; i++) { if ( (resArray[i].ss == resArray[i-1].ss) ) { strucCount++; } else { if ( (strucLast == HELIX) && (strucCount <= 3) ) { for (j=i-1; j>=i-strucCount; j--) { resArray[j].ss = COIL; } } if ( (strucLast == BETA) && (strucCount <= 2) ) { for (j=i-1; j>=i-strucCount; j--) { resArray[j].ss = COIL; } } strucCount = 1; } strucLast = resArray[i].ss; } for (i=0; icoords[H_COORD].x, drez->coords[H_COORD].y, drez->coords[H_COORD].z, rrez->coords[oindex].x, rrez->coords[oindex].y, rrez->coords[oindex].z); noDist = v_get_dist(drez->coords[N_COORD].x, drez->coords[N_COORD].y, drez->coords[N_COORD].z, rrez->coords[oindex].x, rrez->coords[oindex].y, rrez->coords[oindex].z); if ( (hoDist < hbond_dist) && (hoDist < noDist) && ( rrez->num != drez->num) ) { /* check angle between OC and NH */ bondangle = angle(*rrez, oindex, cindex,*drez, N_COORD, H_COORD); /* set of checks to make sure it is a hbond */ if ( (fabs((double)bondangle) < hbond_angle) && (hoDist < (hbond_dist2 + fabs((double)cos((double)RAD(bondangle)))))) { *energy = get_energy(rrez, drez); return(1); } } return(0); } /* Much like the preceding, but checks distances only --- no bond angles */ int CheckSolventHBond(RESIDUE *drez,double ox,double oy,double oz) { double hoDist, noDist; double bondangle; hoDist = v_get_dist(drez->coords[H_COORD].x, drez->coords[H_COORD].y, drez->coords[H_COORD].z, ox, oy, oz); noDist = v_get_dist(drez->coords[N_COORD].x, drez->coords[N_COORD].y, drez->coords[N_COORD].z, ox, oy, oz); if ( (hoDist < hbond_dist) && (hoDist < noDist)) { return(1); } return(0); }