VECTOR vdw_frc(VECTOR v1, VECTOR v2, float C6, float C12) { VECTOR frc; float d2, d4, d8, d14; VECTOR frc6,frc12; d2 = ddvv(v1, v2); if (d2 > cutoff_far2) {frc.x=0;frc.y=0;frc.z=0;return frc;} if (d2 < cutoff_near2) d2 = cutoff_near2; d4 = d2*d2; d8 = d4*d4; d14 = d8*d4*d2; frc12 = vector_rescale(vector_vminusv(v2,v1), (-12.*C12/d14)); frc6 = vector_rescale(vector_vminusv(v2,v1), ( 6.*C6/d8)); frc = vector_vplusv(frc12, frc6); return frc; }
int relax_water(PROT prot) { int i_res,i_conf,i_atom,j_res,j_conf,j_atom,k_res,k_conf,k_atom; int n_conf, add, counter; FILE *debug_fp; for (i_res=0; i_res<prot.n_res; i_res++) { RES *ires_p = &prot.res[i_res]; if (strcmp(prot.res[i_res].resName, "HOH")) continue; n_conf = prot.res[i_res].n_conf; counter = 0; for (i_conf=1; i_conf<n_conf; i_conf++) { CONF *iconf_p = &prot.res[i_res].conf[i_conf]; if (!iconf_p->n_atom) continue; for (j_res=0; j_res<prot.n_res; j_res++) { if (!strcmp(prot.res[j_res].resName, "HOH")) continue; for (j_conf=0; j_conf<prot.res[j_res].n_conf; j_conf++) { CONF *jconf_p = &prot.res[j_res].conf[j_conf]; ATOM *iatom_p; CONF conf; conf.n_atom = iconf_p->n_atom; conf.atom = (ATOM *) malloc(conf.n_atom*sizeof(ATOM)); cpy_conf(&conf,iconf_p); for (i_atom=0;i_atom<conf.n_atom;i_atom++) { if (!conf.atom[i_atom].on) continue; if (conf.atom[i_atom].name[1] == 'O') break; } if (i_atom<conf.n_atom) iatom_p = &conf.atom[i_atom]; else break; add = 0; for (j_atom=0; j_atom<prot.res[j_res].conf[j_conf].n_atom; j_atom++) { ATOM *jatom_p = &jconf_p->atom[j_atom]; if (!jatom_p->on) continue; if (jatom_p->name[1] == 'H') continue; if (ddvv(iatom_p->xyz,jatom_p->xyz) > RELAX_THR2) continue; add = 1; for (i_atom=0;i_atom<conf.n_atom;i_atom++) { if (!conf.atom[i_atom].on) continue; conf.atom[i_atom].xyz = vector_vplusv(jatom_p->xyz, vector_rescale(vector_normalize( vector_vminusv(conf.atom[i_atom].xyz, jatom_p->xyz)), env.water_relax_thr)); } /* ins_conf(ires_p, ires_p->n_conf, iconf_p->n_atom); iconf_p = &prot.res[i_res].conf[i_conf]; if (cpy_conf(&ires_p->conf[ires_p->n_conf-1], &ires_p->conf[i_conf])) {printf(" Error! relax_water(): couldn't copy the conformer \"%s\" in residue %s %d, to new position k_conf = %d\n",ires_p->conf[i_conf].confName,ires_p->resName, ires_p->resSeq, ires_p->n_conf-1); return USERERR;} for (i_conf2=1; i_conf2<ires_p->n_conf-1; i_conf2++) { if (!cmp_conf(ires_p->conf[i_conf2], ires_p->conf[ires_p->n_conf-1],0.05)) break; } if ( i_conf2 < ires_p->n_conf-1 ) { del_conf(ires_p, ires_p->n_conf-1); iconf_p = &prot.res[i_res].conf[i_conf]; continue; } */ //printf(" Debugging! residue %s%4d nconf=%d, residue %s%4d, distance %8.3f\n", prot.res[i_res].resName,prot.res[i_res].resSeq,ires_p->n_conf, prot.res[j_res].resName,prot.res[j_res].resSeq,dvv(iatom_p->xyz,jatom_p->xyz)); } if (add) { for (j_atom=0; j_atom<prot.res[j_res].conf[j_conf].n_atom; j_atom++) { ATOM *jatom_p = &jconf_p->atom[j_atom]; if (!jatom_p->on) continue; if (jatom_p->name[1] == 'H') continue; if (ddvv(iatom_p->xyz,jatom_p->xyz) > RELAX_THR2) continue; add = 0; } } if (add) { for (k_conf=1; k_conf<ires_p->n_conf; k_conf++) { if (!cmp_conf(ires_p->conf[k_conf], conf, 0.05)) break; } if ( k_conf<ires_p->n_conf ) add = 0; } if (add) { for (k_res=0; k_res<prot.n_res; k_res++) { k_conf = 0; for (k_atom=0; k_atom<prot.res[k_res].conf[k_conf].n_atom; k_atom++) { ATOM *katom_p = &prot.res[k_res].conf[k_conf].atom[k_atom]; if (!katom_p->on) continue; if (katom_p->name[1] == 'H') continue; if (ddvv(iatom_p->xyz,katom_p->xyz) > RELAX_THR2) continue; add = 0; } } } if (add) { counter++; ins_conf(ires_p, ires_p->n_conf, conf.n_atom); iconf_p = &prot.res[i_res].conf[i_conf]; if (cpy_conf(&ires_p->conf[ires_p->n_conf-1], &conf)) {printf(" Error! relax_water(): couldn't copy a new conformer \"%s\" in residue %s %d, to new position k_conf = %d\n",conf.confName,ires_p->resName, ires_p->resSeq, ires_p->n_conf-1); return USERERR;} debug_fp = fopen(env.debug_log,"a"); fprintf(debug_fp,"add conformer to HOH %c%04d to relax against %s %c%04d\n",ires_p->chainID,ires_p->resSeq,prot.res[j_res].resName,prot.res[j_res].chainID,prot.res[j_res].resSeq); fclose(debug_fp); } free(conf.atom); } } } } return 0; }
/* Move the protein to the position so the membrane is between z=+/- half_membrane_thichness */ int mem_position(PROT *prot_p, IPECE *ipece) { VECTOR *orig_r; ATOM **all_atoms; /* a list of pointers pointing to all atoms in prot */ int i_res, i_conf, i_atom, na; ATOM *atom_p; VECTOR vec_orig, vec_i, vec_j, vec_k; vec_orig.x = 0.; vec_orig.y = 0.; vec_orig.z = 0.; vec_i.x=1.; vec_i.y=0.; vec_i.z=0.; vec_j.x=0.; vec_j.y=1.; vec_j.z=0.; vec_k.x=0.; vec_k.y=0.; vec_k.z=1.; idum = time(NULL); /* set up. add a residue to contain anchor vectors, initialize all_atoms array, backup all atom coordinates to orig_r */ ins_res(prot_p, prot_p->n_res); ins_conf(&prot_p->res[prot_p->n_res-1],0,4); for (i_atom=0;i_atom<4;i_atom++) { prot_p->res[prot_p->n_res-1].conf[0].atom[i_atom].on = 1; } prot_p->res[prot_p->n_res-1].conf[0].atom[0].xyz = vec_orig; prot_p->res[prot_p->n_res-1].conf[0].atom[1].xyz = vector_rescale(vec_i,100.); prot_p->res[prot_p->n_res-1].conf[0].atom[2].xyz = vector_rescale(vec_j,100.); prot_p->res[prot_p->n_res-1].conf[0].atom[3].xyz = vector_rescale(vec_k,100.); na = 0; all_atoms = NULL; orig_r = NULL; for (i_res=0; i_res<prot_p->n_res; i_res++) { for (i_conf=0; i_conf<prot_p->res[i_res].n_conf; i_conf++) { for (i_atom=0; i_atom<prot_p->res[i_res].conf[i_conf].n_atom; i_atom++) { atom_p = &prot_p->res[i_res].conf[i_conf].atom[i_atom]; if (!atom_p->on) continue; na++; orig_r = (VECTOR *) realloc(orig_r, na*sizeof(VECTOR)); orig_r[na-1] = atom_p->xyz; all_atoms = (ATOM **) realloc(all_atoms, na*sizeof(ATOM *)); all_atoms[na-1] = atom_p; atom_p->i_atom_prot = na-1; } } } /* move the center of the protein to the origin */ VECTOR center; center = vec_orig; int ia; for (ia=0; ia<na; ia++) { center = vector_vplusv(center, all_atoms[ia]->xyz); } center = vector_rescale(center, 1./na); for (ia=0; ia<na; ia++) { all_atoms[ia]->xyz = vector_vminusv(all_atoms[ia]->xyz, center); } float score, min_score; int best_pos; /* get the initial score for the protein */ probe(*prot_p, ipece); /* collect atoms used for calculating scores */ get_scored_atoms(*prot_p, ipece); min_score = calc_score(ipece); best_pos = 1; /* rotate around x axis by 90� to calculate score again */ rotate_atoms(vec_orig, vec_i, env.PI/2., ipece->n_scored_atom, ipece->scored_atoms); score = calc_score(ipece); if (score < min_score) { min_score = score; best_pos = 2; } rotate_atoms(vec_orig, vec_i, -env.PI/2., ipece->n_scored_atom, ipece->scored_atoms); /* rotate around y axis by 90� to calculate score again */ rotate_atoms(vec_orig, vec_j, env.PI/2., ipece->n_scored_atom, ipece->scored_atoms); score = calc_score(ipece); if (score < min_score) { min_score = score; best_pos = 3; } rotate_atoms(vec_orig, vec_j, -env.PI/2., ipece->n_scored_atom, ipece->scored_atoms); /* choose the lowest scored position to start with */ if (best_pos == 2) { rotate_atoms(vec_orig, vec_i, env.PI/2., na, all_atoms); rotate_atoms(vec_orig, vec_i, env.PI/2., ipece->n_scored_atom, ipece->scored_atoms); } if (best_pos == 3) { rotate_atoms(vec_orig, vec_j, env.PI/2., na, all_atoms); rotate_atoms(vec_orig, vec_j, env.PI/2., ipece->n_scored_atom, ipece->scored_atoms); } /* randomly translate the protein in z direction or rotation around an axis on x-y plane to find the lowest scored position. sampling the positions in a way similar as monte carlo */ VECTOR vec_trans = vec_orig; VECTOR vec_axis = vec_orig; score = calc_score(ipece); min_score = score; for (ia=0;ia<4;ia++) { ipece->membrane_position[ia] = prot_p->res[prot_p->n_res-1].conf[0].atom[ia].xyz; } int iter; for (iter=0;iter<ipece->n_iteration;iter++) { float new_score, delta_score; /* translation */ if (ran2(&idum) < 0.5) { vec_trans.z = 2.*(ran2(&idum) - 0.5)*ipece->translation_max; translate_atoms(vec_trans, ipece->n_scored_atom, ipece->scored_atoms); new_score = calc_score(ipece); delta_score = new_score - score; if (ran2(&idum) < exp(-ipece->beta * delta_score)) { translate_atoms(vec_trans, na, all_atoms); score = new_score; } else { vec_trans.z = -vec_trans.z; translate_atoms(vec_trans, ipece->n_scored_atom, ipece->scored_atoms); } } /* rotation */ else { float phi, theta; phi = ran2(&idum)*2.*env.PI; theta = ran2(&idum)*ipece->rotation_max; /* rotation_max has been converted to radian in parameter reading process */ vec_axis.x = cos(phi); vec_axis.y = sin(phi); rotate_atoms(vec_orig, vec_axis, theta, ipece->n_scored_atom, ipece->scored_atoms); new_score = calc_score(ipece); delta_score = new_score - score; if (ran2(&idum) < exp(-ipece->beta * delta_score)) { rotate_atoms(vec_orig, vec_axis, theta, na, all_atoms); score = new_score; } else { vec_trans.z = -vec_trans.z; rotate_atoms(vec_orig, vec_axis, -theta, ipece->n_scored_atom, ipece->scored_atoms); } } if (score < min_score) { min_score = score; for (ia=0;ia<4;ia++) { ipece->membrane_position[ia] = prot_p->res[prot_p->n_res-1].conf[0].atom[ia].xyz; } } /* printf("\n"); for (i=0;i<4;i++) { printf(" %10.6f %10.6f %10.6f\n", prot_p->res[prot_p->n_res-1].conf[0].atom[i].xyz.x, prot_p->res[prot_p->n_res-1].conf[0].atom[i].xyz.y, prot_p->res[prot_p->n_res-1].conf[0].atom[i].xyz.z); } */ } ipece->mem_position_defined = 1; /* move the protein back to orginal position */ for (ia=0; ia<na; ia++) { all_atoms[ia]->xyz = orig_r[ia]; } /* free memory */ free_scored_atoms(ipece); free_probe(ipece); free(all_atoms); free(orig_r); na = 0; /* delete the extra anchor residue */ del_res(prot_p, prot_p->n_res-1); return 0; }