static void calc_all_pos(t_atoms *pdba, rvec x[], int nab[], t_hack *ab[], gmx_bool bCheckMissing) { int i, j, ii, jj, m, ia, d, rnr,l=0; #define MAXH 4 rvec xa[4]; /* control atoms for calc_h_pos */ rvec xh[MAXH]; /* hydrogen positions from calc_h_pos */ gmx_bool bFoundAll; jj = 0; for(i=0; i < pdba->nr; i++) { rnr = pdba->atom[i].resind; for(j=0; j < nab[i]; j+=ab[i][j].nr) { /* check if we're adding: */ if (ab[i][j].oname==NULL && ab[i][j].tp > 0) { bFoundAll = TRUE; for(m=0; (m<ab[i][j].nctl && bFoundAll); m++) { ia = pdbasearch_atom(ab[i][j].a[m], rnr, pdba, bCheckMissing ? "atom" : "check", !bCheckMissing); if (ia < 0) { /* not found in original atoms, might still be in t_hack (ab) */ hacksearch_atom(&ii, &jj, ab[i][j].a[m], nab, ab, rnr, pdba); if (ii >= 0) { copy_rvec(ab[ii][jj].newx, xa[m]); } else { bFoundAll = FALSE; if (bCheckMissing) { gmx_fatal(FARGS,"Atom %s not found in residue %s %d" ", rtp entry %s" " while adding hydrogens", ab[i][j].a[m], *pdba->resinfo[rnr].name, pdba->resinfo[rnr].nr, *pdba->resinfo[rnr].rtp); } } } else { copy_rvec(x[ia], xa[m]); } } if (bFoundAll) { for(m=0; (m<MAXH); m++) for(d=0; d<DIM; d++) if (m<ab[i][j].nr) xh[m][d] = 0; else xh[m][d] = NOTSET; calc_h_pos(ab[i][j].tp, xa, xh, &l); for(m=0; m<ab[i][j].nr; m++) { copy_rvec(xh[m],ab[i][j+m].newx); ab[i][j+m].bXSet = TRUE; } } } } } }
static void calc_all_pos(t_atoms *pdba, rvec x[], int nab[], t_hack *ab[], bool bMissing) { int i, j, ii, jj, m, ia, d, rnr; #define MAXH 4 rvec xa[4]; /* control atoms for calc_h_pos */ rvec xh[MAXH]; /* hydrogen positions from calc_h_pos */ jj = 0; for(i=0; i < pdba->nr; i++) { rnr = pdba->atom[i].resind; for(j=0; j < nab[i]; j+=ab[i][j].nr) { /* check if we're adding: */ if (ab[i][j].oname==NULL && ab[i][j].tp > 0) { for(m=0; (m<ab[i][j].nctl); m++) { ia = pdbasearch_atom(ab[i][j].a[m], rnr, pdba, "atom", bMissing); if (ia < 0) { /* not found in original atoms, might still be in t_hack (ab) */ hacksearch_atom(&ii, &jj, ab[i][j].a[m], nab, ab, rnr, pdba); if (ii < 0) gmx_fatal(FARGS,"Atom %s not found in residue %s%d" " while adding hydrogens", ab[i][j].a[m], *pdba->resinfo[rnr].name, pdba->resinfo[rnr].nr); else copy_rvec(ab[ii][jj].newx, xa[m]); } else copy_rvec(x[ia], xa[m]); } for(m=0; (m<MAXH); m++) for(d=0; d<DIM; d++) if (m<ab[i][j].nr) xh[m][d] = 0; else xh[m][d] = NOTSET; calc_h_pos(ab[i][j].tp, xa, xh); for(m=0; m<ab[i][j].nr; m++) copy_rvec(xh[m],ab[i][j+m].newx); } } } }
void calc_h_pos(int nht, rvec xa[], rvec xh[]) { #define alfaH (acos(-1/3.0)) /* 109.47 degrees */ #define alfaHpl (2*M_PI/3) /* 120 degrees */ #define distH 0.1 #define alfaCOM (DEG2RAD*117) #define alfaCO (DEG2RAD*121) #define alfaCOA (DEG2RAD*115) #define distO 0.123 #define distOA 0.125 #define distOM 0.136 rvec sa,sb,sij; real s6,rij,ra,rb,xd; int d; s6=0.5*sqrt(3.e0); /* common work for constructing one, two or three dihedral hydrogens */ switch (nht) { case 2: case 3: case 4: case 8: case 9: rij = 0.e0; for(d=0; (d<DIM); d++) { xd = xAJ[d]; sij[d] = xAI[d]-xd; sb[d] = xd-xAK[d]; rij += sqr(sij[d]); } rij = sqrt(rij); sa[XX] = sij[YY]*sb[ZZ]-sij[ZZ]*sb[YY]; sa[YY] = sij[ZZ]*sb[XX]-sij[XX]*sb[ZZ]; sa[ZZ] = sij[XX]*sb[YY]-sij[YY]*sb[XX]; ra = 0.e0; for(d=0; (d<DIM); d++) { sij[d] = sij[d]/rij; ra += sqr(sa[d]); } ra = sqrt(ra); for(d=0; (d<DIM); d++) sa[d] = sa[d]/ra; sb[XX] = sa[YY]*sij[ZZ]-sa[ZZ]*sij[YY]; sb[YY] = sa[ZZ]*sij[XX]-sa[XX]*sij[ZZ]; sb[ZZ] = sa[XX]*sij[YY]-sa[YY]*sij[XX]; break; }/* end switch */ switch (nht) { case 1: /* construct one planar hydrogen (peptide,rings) */ rij = 0.e0; rb = 0.e0; for(d=0; (d<DIM); d++) { sij[d] = xAI[d]-xAJ[d]; sb[d] = xAI[d]-xAK[d]; rij += sqr(sij[d]); rb += sqr(sb[d]); } rij = sqrt(rij); rb = sqrt(rb); ra = 0.e0; for(d=0; (d<DIM); d++) { sa[d] = sij[d]/rij+sb[d]/rb; ra += sqr(sa[d]); } ra = sqrt(ra); for(d=0; (d<DIM); d++) xH1[d] = xAI[d]+distH*sa[d]/ra; break; case 2: /* one single hydrogen, e.g. hydroxyl */ for(d=0; (d<DIM); d++) { xH1[d] = xAI[d]+distH*sin(alfaH)*sb[d]-distH*cos(alfaH)*sij[d]; } break; case 3: /* two planar hydrogens, e.g. -NH2 */ for(d=0; (d<DIM); d++) { xH1[d] = xAI[d]-distH*sin(alfaHpl)*sb[d]-distH*cos(alfaHpl)*sij[d]; xH2[d] = xAI[d]+distH*sin(alfaHpl)*sb[d]-distH*cos(alfaHpl)*sij[d]; } break; case 4: /* two or three tetrahedral hydrogens, e.g. -CH3 */ for(d=0; (d<DIM); d++) { xH1[d] = xAI[d]+distH*sin(alfaH)*sb[d]-distH*cos(alfaH)*sij[d]; xH2[d] = ( xAI[d] - distH*sin(alfaH)*0.5*sb[d] + distH*sin(alfaH)*s6*sa[d] - distH*cos(alfaH)*sij[d] ); if ( xH3[XX]!=NOTSET && xH3[YY]!=NOTSET && xH3[ZZ]!=NOTSET ) xH3[d] = ( xAI[d] - distH*sin(alfaH)*0.5*sb[d] - distH*sin(alfaH)*s6*sa[d] - distH*cos(alfaH)*sij[d] ); } break; case 5: { /* one tetrahedral hydrogen, e.g. C3CH */ real center; rvec dxc; for(d=0; (d<DIM); d++) { center=(xAJ[d]+xAK[d]+xAL[d])/3.0; dxc[d]=xAI[d]-center; } center=norm(dxc); for(d=0; (d<DIM); d++) xH1[d]=xAI[d]+dxc[d]*distH/center; break; } case 6: { /* two tetrahedral hydrogens, e.g. C-CH2-C */ rvec rBB,rCC1,rCC2,rNN; real bb,nn; for(d=0; (d<DIM); d++) rBB[d]=xAI[d]-0.5*(xAJ[d]+xAK[d]); bb=norm(rBB); rvec_sub(xAI,xAJ,rCC1); rvec_sub(xAI,xAK,rCC2); cprod(rCC1,rCC2,rNN); nn=norm(rNN); for(d=0; (d<DIM); d++) { xH1[d]=xAI[d]+distH*(cos(alfaH/2.0)*rBB[d]/bb+ sin(alfaH/2.0)*rNN[d]/nn); xH2[d]=xAI[d]+distH*(cos(alfaH/2.0)*rBB[d]/bb- sin(alfaH/2.0)*rNN[d]/nn); } break; } case 7: /* two water hydrogens */ gen_waterhydrogen(2, xa, xh); break; case 10: /* three water hydrogens */ gen_waterhydrogen(3, xa, xh); break; case 11: /* four water hydrogens */ gen_waterhydrogen(4, xa, xh); break; case 8: /* two carboxyl oxygens, -COO- */ for(d=0; (d<DIM); d++) { xH1[d] = xAI[d]-distOM*sin(alfaCOM)*sb[d]-distOM*cos(alfaCOM)*sij[d]; xH2[d] = xAI[d]+distOM*sin(alfaCOM)*sb[d]-distOM*cos(alfaCOM)*sij[d]; } break; case 9: { /* carboxyl oxygens and hydrogen, -COOH */ rvec xa2[4]; /* i,j,k,l */ /* first add two oxygens */ for(d=0; (d<DIM); d++) { xH1[d] = xAI[d]-distO *sin(alfaCO )*sb[d]-distO *cos(alfaCO )*sij[d]; xH2[d] = xAI[d]+distOA*sin(alfaCOA)*sb[d]-distOA*cos(alfaCOA)*sij[d]; } /* now use rule 2 to add hydrogen to 2nd oxygen */ copy_rvec(xH2, xa2[0]); /* new i = n' */ copy_rvec(xAI, xa2[1]); /* new j = i */ copy_rvec(xAJ, xa2[2]); /* new k = j */ copy_rvec(xAK, xa2[3]); /* new l = k, not used */ calc_h_pos(2, xa2, (xh+2)); break; } default: gmx_fatal(FARGS,"Invalid argument (%d) for nht in routine genh\n",nht); } /* end switch */ }