void orient_princ(t_atoms *atoms, int isize, atom_id *index, int natoms, rvec x[], rvec *v, rvec d) { int i, m; rvec xcm, prcomp; matrix trans; calc_xcm(x, isize, index, atoms->atom, xcm, FALSE); for (i = 0; i < natoms; i++) { rvec_dec(x[i], xcm); } principal_comp(isize, index, atoms->atom, x, trans, prcomp); if (d) { copy_rvec(prcomp, d); } /* Check whether this trans matrix mirrors the molecule */ if (det(trans) < 0) { for (m = 0; (m < DIM); m++) { trans[ZZ][m] = -trans[ZZ][m]; } } rotate_atoms(natoms, NULL, x, trans); if (v) { rotate_atoms(natoms, NULL, v, trans); } for (i = 0; i < natoms; i++) { rvec_inc(x[i], xcm); } }
/* move protein so that the anchor is aligned to a defined orientation */ int anchor2defined(PROT *prot_p, VECTOR *pos) { float cos_theta, theta; int i_res, i_conf, i_atom, na, ia; ATOM **all_atoms; /* a list of pointers pointing to all atoms in prot */ ATOM *prot_anchor; prot_anchor = prot_p->res[prot_p->n_res-1].conf[0].atom; na = 0; all_atoms = 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 *atom_p = &prot_p->res[i_res].conf[i_conf].atom[i_atom]; if (!atom_p->on) continue; na++; all_atoms = (ATOM **) realloc(all_atoms, na*sizeof(ATOM *)); all_atoms[na-1] = atom_p; } } } /* move anchor[0] to pos[0] */ VECTOR shift = vector_vminusv(pos[0], prot_anchor[0].xyz); for (ia=0; ia<na; ia++) { all_atoms[ia]->xyz = vector_vplusv(all_atoms[ia]->xyz, shift); } /* rotate anchor[1] to be aligned with pos[1] */ /* get i direction given by the defined orientaion (pos) and the current protein position (prot_anchor) */ VECTOR vec_axis; VECTOR pos_i, pos_j, pos_k; VECTOR anchor_i, anchor_j; pos_i = vector_normalize(vector_vminusv(pos[1],pos[0])); anchor_i = vector_normalize(vector_vminusv(prot_anchor[1].xyz, prot_anchor[0].xyz)); cos_theta = vdotv(anchor_i, pos_i); theta = acos(cos_theta); vec_axis = vector_vplusv(pos[0],vector_vxv(anchor_i, pos_i)); rotate_atoms(pos[0], vec_axis, theta, na, all_atoms); /* rotate anchor[2] to be aligned with pos[2] */ pos_j = vector_normalize(vector_vminusv(pos[2],pos[0])); anchor_j = vector_normalize(vector_vminusv(prot_anchor[2].xyz, prot_anchor[0].xyz)); cos_theta = vdotv(anchor_j, pos_j); theta = acos(cos_theta); pos_k = vector_normalize(vector_vminusv(pos[3],pos[0])); if (vdotv(vector_vxv(anchor_j,pos_j),pos_i) <0.) theta = 2.*env.PI - theta; rotate_atoms(pos[0], pos[1], theta, na, all_atoms); free(all_atoms); na = 0; 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; }