Example #1
0
void gen_pad(t_nextnb *nnb, t_atoms *atoms, int nrexcl, bool bH14,
	     t_params plist[], t_excls excls[], t_hackblock hb[], 
	     bool bAlldih, bool bRemoveDih, bool bMissing)
{
  t_param *ang,*dih,*pai,*idih;
  t_rbondeds *hbang, *hbdih;
  char    **anm;
  int     res,minres,maxres;
  int     i,j,j1,k,k1,l,l1,m,n,i1,i2;
  int     ninc,maxang,maxdih,maxpai;
  int     nang,ndih,npai,nidih,nbd;
  int     nFound;
  bool    bFound,bExcl;
  

  /* These are the angles, dihedrals and pairs that we generate
   * from the bonds. The ones that are already there from the rtp file
   * will be retained.
   */
  nang   = 0;
  npai   = 0;
  ndih   = 0;
  ninc   = 500;
  maxang = maxdih = maxpai = ninc;
  snew(ang, maxang);
  snew(dih, maxdih);
  snew(pai, maxpai);

  snew(anm,4);
  for(i=0;i<4;i++)
    snew(anm[i],12);

  if (hb)
    gen_excls(atoms,excls,hb,bMissing);
  
  /* extract all i-j-k-l neighbours from nnb struct */
  for(i=0; (i<nnb->nr); i++) 
    /* For all particles */
    for(j=0; (j<nnb->nrexcl[i][1]); j++) {
      /* For all first neighbours */
      j1=nnb->a[i][1][j];
      for(k=0; (k<nnb->nrexcl[j1][1]); k++) {
	/* For all first neighbours of j1 */
	k1=nnb->a[j1][1][k];
	if (k1 != i) {
	  /* Generate every angle only once */
	  if (i < k1) {
	    if (nang == maxang) {
	      maxang += ninc;
	      srenew(ang,maxang);
	    }
	    ang[nang].AI=i;
	    ang[nang].AJ=j1;
	    ang[nang].AK=k1;
	    ang[nang].C0=NOTSET;
	    ang[nang].C1=NOTSET;
	    set_p_string(&(ang[nang]),"");
	    if (hb) {
	      minres = atoms->atom[ang[nang].a[0]].resind;
	      maxres = minres;
	      for(m=1; m<3; m++) {
		minres = min(minres,atoms->atom[ang[nang].a[m]].resind);
		maxres = max(maxres,atoms->atom[ang[nang].a[m]].resind);
	      }
	      res = 2*minres-maxres;
	      do {
		res += maxres-minres;
		get_atomnames_min(3,anm,res,atoms,ang[nang].a);
		hbang=&hb[res].rb[ebtsANGLES];
		for(l=0; (l<hbang->nb); l++) {
		  if (strcmp(anm[1],hbang->b[l].AJ)==0) {
		    bFound=FALSE;
		    for (m=0; m<3; m+=2)
		      bFound=(bFound ||
			      ((strcmp(anm[m],hbang->b[l].AI)==0) &&
			       (strcmp(anm[2-m],hbang->b[l].AK)==0)));
		    if (bFound) {
		      set_p_string(&(ang[nang]),hbang->b[l].s);
		    }
		  }
		}
	      } while (res < maxres);
	    }
	    nang++;
	  }
	  /* Generate every dihedral, 1-4 exclusion and 1-4 interaction
	     only once */
	  if (j1 < k1) {
	    for(l=0; (l<nnb->nrexcl[k1][1]); l++) {
	      /* For all first neighbours of k1 */
	      l1=nnb->a[k1][1][l];
	      if ((l1 != i) && (l1 != j1)) {
		if (ndih == maxdih) {
		  maxdih += ninc;
		  srenew(dih,maxdih);
		}
		dih[ndih].AI=i;
		dih[ndih].AJ=j1;
		dih[ndih].AK=k1;
		dih[ndih].AL=l1;
		for (m=0; m<MAXFORCEPARAM; m++)
		  dih[ndih].c[m]=NOTSET;
		set_p_string(&(dih[ndih]),"");
		nFound = 0;
		if (hb) {
		  minres = atoms->atom[dih[ndih].a[0]].resind;
		  maxres = minres;
		  for(m=1; m<4; m++) {
		    minres = min(minres,atoms->atom[dih[ndih].a[m]].resind);
		    maxres = max(maxres,atoms->atom[dih[ndih].a[m]].resind);
		  }
		  res = 2*minres-maxres;
		  do {
		    res += maxres-minres;
		    get_atomnames_min(4,anm,res,atoms,dih[ndih].a);
		    hbdih=&hb[res].rb[ebtsPDIHS];
		    for(n=0; (n<hbdih->nb); n++) {
		      bFound=FALSE;
		      for (m=0; m<2; m++)
			bFound=(bFound ||
				((strcmp(anm[3*m],  hbdih->b[n].AI)==0) &&
				 (strcmp(anm[1+m],  hbdih->b[n].AJ)==0) &&
				 (strcmp(anm[2-m],  hbdih->b[n].AK)==0) &&
				 (strcmp(anm[3-3*m],hbdih->b[n].AL)==0)));
		      if (bFound) {
			set_p_string(&dih[ndih],hbdih->b[n].s);
			
			/* Set the last parameter to be able to see
			   if the dihedral was in the rtp list.
			   */
			dih[ndih].c[MAXFORCEPARAM-1] = 0;
			nFound++;
			ndih++;
			/* Set the next direct in case the rtp contains
			   multiple entries for this dihedral.
			   */
			if (ndih == maxdih) {
			  maxdih += ninc;
			  srenew(dih,maxdih);
			}
			dih[ndih].AI=i;
			dih[ndih].AJ=j1;
			dih[ndih].AK=k1;
			dih[ndih].AL=l1;
			for (m=0; m<MAXFORCEPARAM; m++)
			  dih[ndih].c[m]=NOTSET;
		      }
		    }
		  } while (res < maxres);
		}
		if (nFound == 0) {
		  if (ndih == maxdih) {
		    maxdih += ninc;
		    srenew(dih,maxdih);
		  }
		  dih[ndih].AI=i;
		  dih[ndih].AJ=j1;
		  dih[ndih].AK=k1;
		  dih[ndih].AL=l1;
		  for (m=0; m<MAXFORCEPARAM; m++)
		    dih[ndih].c[m]=NOTSET;
		  set_p_string(&(dih[ndih]),"");
		  ndih++;
		}

		nbd=nb_dist(nnb,i,l1);
		if (debug)
		  fprintf(debug,"Distance (%d-%d) = %d\n",i+1,l1+1,nbd);
		if (nbd == 3) {
		  i1 = min(i,l1);
		  i2 = max(i,l1);
		  bExcl = FALSE;
		  for(m=0; m<excls[i1].nr; m++)
		    bExcl = bExcl || excls[i1].e[m]==i2;
		  if (!bExcl) {
		    if (bH14 || !(is_hydro(atoms,i1) && is_hydro(atoms,i2))) {
		      if (npai == maxpai) {
			maxpai += ninc;
			srenew(pai,maxpai);
		      }
		      pai[npai].AI=i1;
		      pai[npai].AJ=i2;
		      pai[npai].C0=NOTSET;
		      pai[npai].C1=NOTSET;
		      set_p_string(&(pai[npai]),"");
		      npai++;
		    }
		  }
		}
	      }
	    }
	  }
	}
      }
    }

  /* Sort angles with respect to j-i-k (middle atom first) */
  if (nang > 1)
    qsort(ang,nang,(size_t)sizeof(ang[0]),acomp);
  
  /* Sort dihedrals with respect to j-k-i-l (middle atoms first) */
  if (ndih > 1)
    qsort(dih,ndih,(size_t)sizeof(dih[0]),dcomp);
  
  /* Sort the pairs */
  if (npai > 1)
    qsort(pai,npai,(size_t)sizeof(pai[0]),pcomp);
  if (npai > 0) {
    /* Remove doubles, could occur in 6-rings, such as phenyls,
       maybe one does not want this when fudgeQQ < 1.
       */
    fprintf(stderr,"Before cleaning: %d pairs\n",npai);
    rm2par(pai,&npai,preq);
  }

  /* Get the impropers from the database */
  nidih = get_impropers(atoms,hb,&idih,bMissing);

  /* Sort the impropers */
  sort_id(nidih,idih);
 
  if (ndih > 0) {
    /* Remove dihedrals which are impropers
       and when bAlldih is not set remove multiple dihedrals over one bond.
       */
    fprintf(stderr,"Before cleaning: %d dihedrals\n",ndih);
    clean_dih(dih,&ndih,idih,nidih,atoms,bAlldih,bRemoveDih);
  }

  /* Now we have unique lists of angles and dihedrals 
   * Copy them into the destination struct
   */
  cppar(ang, nang, plist,F_ANGLES);
  cppar(dih, ndih, plist,F_PDIHS);
  cppar(idih,nidih,plist,F_IDIHS);
  cppar(pai, npai, plist,F_LJ14);

  /* Remove all exclusions which are within nrexcl */
  clean_excls(nnb,nrexcl,excls);

  sfree(ang);
  sfree(dih);
  sfree(idih);
  sfree(pai);
}
Example #2
0
/* Generate pairs, angles and dihedrals from .rtp settings */
void gen_pad(t_nextnb *nnb, t_atoms *atoms, t_restp rtp[],
             t_params plist[], t_excls excls[], t_hackblock hb[],
             gmx_bool bAllowMissing)
{
    t_param    *ang, *dih, *pai, *improper;
    t_rbondeds *hbang, *hbdih;
    char      **anm;
    const char *p;
    int         res, minres, maxres;
    int         i, j, j1, k, k1, l, l1, m, n, i1, i2;
    int         ninc, maxang, maxdih, maxpai;
    int         nang, ndih, npai, nimproper, nbd;
    int         nFound;
    gmx_bool    bFound, bExcl;

    /* These are the angles, dihedrals and pairs that we generate
     * from the bonds. The ones that are already there from the rtp file
     * will be retained.
     */
    nang   = 0;
    npai   = 0;
    ndih   = 0;
    ninc   = 500;
    maxang = maxdih = maxpai = ninc;
    snew(ang, maxang);
    snew(dih, maxdih);
    snew(pai, maxpai);

    snew(anm, 4);
    for (i = 0; i < 4; i++)
    {
        snew(anm[i], 12);
    }

    if (hb)
    {
        gen_excls(atoms, excls, hb, bAllowMissing);
        /* mark all entries as not matched yet */
        for (i = 0; i < atoms->nres; i++)
        {
            for (j = 0; j < ebtsNR; j++)
            {
                for (k = 0; k < hb[i].rb[j].nb; k++)
                {
                    hb[i].rb[j].b[k].match = FALSE;
                }
            }
        }
    }

    /* Extract all i-j-k-l neighbours from nnb struct to generate all
     * angles and dihedrals. */
    for (i = 0; (i < nnb->nr); i++)
    {
        /* For all particles */
        for (j = 0; (j < nnb->nrexcl[i][1]); j++)
        {
            /* For all first neighbours */
            j1 = nnb->a[i][1][j];
            for (k = 0; (k < nnb->nrexcl[j1][1]); k++)
            {
                /* For all first neighbours of j1 */
                k1 = nnb->a[j1][1][k];
                if (k1 != i)
                {
                    /* Generate every angle only once */
                    if (i < k1)
                    {
                        if (nang == maxang)
                        {
                            maxang += ninc;
                            srenew(ang, maxang);
                        }
                        ang[nang].ai() = i;
                        ang[nang].aj() = j1;
                        ang[nang].ak() = k1;
                        ang[nang].c0() = NOTSET;
                        ang[nang].c1() = NOTSET;
                        set_p_string(&(ang[nang]), "");
                        if (hb)
                        {
                            minres = atoms->atom[ang[nang].a[0]].resind;
                            maxres = minres;
                            for (m = 1; m < 3; m++)
                            {
                                minres = std::min(minres, atoms->atom[ang[nang].a[m]].resind);
                                maxres = std::max(maxres, atoms->atom[ang[nang].a[m]].resind);
                            }
                            res = 2*minres-maxres;
                            do
                            {
                                res += maxres-minres;
                                get_atomnames_min(3, anm, res, atoms, ang[nang].a);
                                hbang = &hb[res].rb[ebtsANGLES];
                                for (l = 0; (l < hbang->nb); l++)
                                {
                                    if (strcmp(anm[1], hbang->b[l].aj()) == 0)
                                    {
                                        bFound = FALSE;
                                        for (m = 0; m < 3; m += 2)
                                        {
                                            bFound = (bFound ||
                                                      ((strcmp(anm[m], hbang->b[l].ai()) == 0) &&
                                                       (strcmp(anm[2-m], hbang->b[l].ak()) == 0)));
                                        }
                                        if (bFound)
                                        {
                                            set_p_string(&(ang[nang]), hbang->b[l].s);
                                            /* Mark that we found a match for this entry */
                                            hbang->b[l].match = TRUE;
                                        }
                                    }
                                }
                            }
                            while (res < maxres);
                        }
                        nang++;
                    }
                    /* Generate every dihedral, 1-4 exclusion and 1-4 interaction
                       only once */
                    if (j1 < k1)
                    {
                        for (l = 0; (l < nnb->nrexcl[k1][1]); l++)
                        {
                            /* For all first neighbours of k1 */
                            l1 = nnb->a[k1][1][l];
                            if ((l1 != i) && (l1 != j1))
                            {
                                if (ndih == maxdih)
                                {
                                    maxdih += ninc;
                                    srenew(dih, maxdih);
                                }
                                dih[ndih].ai() = i;
                                dih[ndih].aj() = j1;
                                dih[ndih].ak() = k1;
                                dih[ndih].al() = l1;
                                for (m = 0; m < MAXFORCEPARAM; m++)
                                {
                                    dih[ndih].c[m] = NOTSET;
                                }
                                set_p_string(&(dih[ndih]), "");
                                nFound = 0;
                                if (hb)
                                {
                                    minres = atoms->atom[dih[ndih].a[0]].resind;
                                    maxres = minres;
                                    for (m = 1; m < 4; m++)
                                    {
                                        minres = std::min(minres, atoms->atom[dih[ndih].a[m]].resind);
                                        maxres = std::max(maxres, atoms->atom[dih[ndih].a[m]].resind);
                                    }
                                    res = 2*minres-maxres;
                                    do
                                    {
                                        res += maxres-minres;
                                        get_atomnames_min(4, anm, res, atoms, dih[ndih].a);
                                        hbdih = &hb[res].rb[ebtsPDIHS];
                                        for (n = 0; (n < hbdih->nb); n++)
                                        {
                                            bFound = FALSE;
                                            for (m = 0; m < 2; m++)
                                            {
                                                bFound = (bFound ||
                                                          ((strcmp(anm[3*m],  hbdih->b[n].ai()) == 0) &&
                                                           (strcmp(anm[1+m],  hbdih->b[n].aj()) == 0) &&
                                                           (strcmp(anm[2-m],  hbdih->b[n].ak()) == 0) &&
                                                           (strcmp(anm[3-3*m], hbdih->b[n].al()) == 0)));
                                            }
                                            if (bFound)
                                            {
                                                set_p_string(&dih[ndih], hbdih->b[n].s);
                                                /* Mark that we found a match for this entry */
                                                hbdih->b[n].match = TRUE;

                                                /* Set the last parameter to be able to see
                                                   if the dihedral was in the rtp list.
                                                 */
                                                dih[ndih].c[MAXFORCEPARAM-1] = DIHEDRAL_WAS_SET_IN_RTP;
                                                nFound++;
                                                ndih++;
                                                /* Set the next direct in case the rtp contains
                                                   multiple entries for this dihedral.
                                                 */
                                                if (ndih == maxdih)
                                                {
                                                    maxdih += ninc;
                                                    srenew(dih, maxdih);
                                                }
                                                dih[ndih].ai() = i;
                                                dih[ndih].aj() = j1;
                                                dih[ndih].ak() = k1;
                                                dih[ndih].al() = l1;
                                                for (m = 0; m < MAXFORCEPARAM; m++)
                                                {
                                                    dih[ndih].c[m] = NOTSET;
                                                }
                                            }
                                        }
                                    }
                                    while (res < maxres);
                                }
                                if (nFound == 0)
                                {
                                    if (ndih == maxdih)
                                    {
                                        maxdih += ninc;
                                        srenew(dih, maxdih);
                                    }
                                    dih[ndih].ai() = i;
                                    dih[ndih].aj() = j1;
                                    dih[ndih].ak() = k1;
                                    dih[ndih].al() = l1;
                                    for (m = 0; m < MAXFORCEPARAM; m++)
                                    {
                                        dih[ndih].c[m] = NOTSET;
                                    }
                                    set_p_string(&(dih[ndih]), "");
                                    ndih++;
                                }

                                nbd = nb_dist(nnb, i, l1);
                                if (debug)
                                {
                                    fprintf(debug, "Distance (%d-%d) = %d\n", i+1, l1+1, nbd);
                                }
                                if (nbd == 3)
                                {
                                    i1    = std::min(i, l1);
                                    i2    = std::max(i, l1);
                                    bExcl = FALSE;
                                    for (m = 0; m < excls[i1].nr; m++)
                                    {
                                        bExcl = bExcl || excls[i1].e[m] == i2;
                                    }
                                    if (!bExcl)
                                    {
                                        if (rtp[0].bGenerateHH14Interactions ||
                                            !(is_hydro(atoms, i1) && is_hydro(atoms, i2)))
                                        {
                                            if (npai == maxpai)
                                            {
                                                maxpai += ninc;
                                                srenew(pai, maxpai);
                                            }
                                            pai[npai].ai() = i1;
                                            pai[npai].aj() = i2;
                                            pai[npai].c0() = NOTSET;
                                            pai[npai].c1() = NOTSET;
                                            set_p_string(&(pai[npai]), "");
                                            npai++;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    if (hb)
    {
        /* The above approach is great in that we double-check that e.g. an angle
         * really corresponds to three atoms connected by bonds, but this is not
         * generally true. Go through the angle and dihedral hackblocks to add
         * entries that we have not yet marked as matched when going through bonds.
         */
        for (i = 0; i < atoms->nres; i++)
        {
            /* Add remaining angles from hackblock */
            hbang = &hb[i].rb[ebtsANGLES];
            for (j = 0; j < hbang->nb; j++)
            {
                if (hbang->b[j].match == TRUE)
                {
                    /* We already used this entry, continue to the next */
                    continue;
                }
                /* Hm - entry not used, let's see if we can find all atoms */
                if (nang == maxang)
                {
                    maxang += ninc;
                    srenew(ang, maxang);
                }
                bFound = TRUE;
                for (k = 0; k < 3 && bFound; k++)
                {
                    p   = hbang->b[j].a[k];
                    res = i;
                    if (p[0] == '-')
                    {
                        p++;
                        res--;
                    }
                    else if (p[0] == '+')
                    {
                        p++;
                        res++;
                    }
                    ang[nang].a[k] = search_res_atom(p, res, atoms, "angle", TRUE);
                    bFound         = (ang[nang].a[k] != NO_ATID);
                }
                ang[nang].c0() = NOTSET;
                ang[nang].c1() = NOTSET;

                if (bFound)
                {
                    set_p_string(&(ang[nang]), hbang->b[j].s);
                    hbang->b[j].match = TRUE;
                    /* Incrementing nang means we save this angle */
                    nang++;
                }
            }

            /* Add remaining dihedrals from hackblock */
            hbdih = &hb[i].rb[ebtsPDIHS];
            for (j = 0; j < hbdih->nb; j++)
            {
                if (hbdih->b[j].match == TRUE)
                {
                    /* We already used this entry, continue to the next */
                    continue;
                }
                /* Hm - entry not used, let's see if we can find all atoms */
                if (ndih == maxdih)
                {
                    maxdih += ninc;
                    srenew(dih, maxdih);
                }
                bFound = TRUE;
                for (k = 0; k < 4 && bFound; k++)
                {
                    p   = hbdih->b[j].a[k];
                    res = i;
                    if (p[0] == '-')
                    {
                        p++;
                        res--;
                    }
                    else if (p[0] == '+')
                    {
                        p++;
                        res++;
                    }
                    dih[ndih].a[k] = search_res_atom(p, res, atoms, "dihedral", TRUE);
                    bFound         = (dih[ndih].a[k] != NO_ATID);
                }
                for (m = 0; m < MAXFORCEPARAM; m++)
                {
                    dih[ndih].c[m] = NOTSET;
                }

                if (bFound)
                {
                    set_p_string(&(dih[ndih]), hbdih->b[j].s);
                    hbdih->b[j].match = TRUE;
                    /* Incrementing ndih means we save this dihedral */
                    ndih++;
                }
            }
        }
    }

    /* Sort angles with respect to j-i-k (middle atom first) */
    if (nang > 1)
    {
        qsort(ang, nang, (size_t)sizeof(ang[0]), acomp);
    }

    /* Sort dihedrals with respect to j-k-i-l (middle atoms first) */
    if (ndih > 1)
    {
        qsort(dih, ndih, (size_t)sizeof(dih[0]), dcomp);
    }

    /* Sort the pairs */
    if (npai > 1)
    {
        qsort(pai, npai, (size_t)sizeof(pai[0]), pcomp);
    }
    if (npai > 0)
    {
        /* Remove doubles, could occur in 6-rings, such as phenyls,
           maybe one does not want this when fudgeQQ < 1.
         */
        fprintf(stderr, "Before cleaning: %d pairs\n", npai);
        rm2par(pai, &npai, preq);
    }

    /* Get the impropers from the database */
    nimproper = get_impropers(atoms, hb, &improper, bAllowMissing);

    /* Sort the impropers */
    sort_id(nimproper, improper);

    if (ndih > 0)
    {
        fprintf(stderr, "Before cleaning: %d dihedrals\n", ndih);
        clean_dih(dih, &ndih, improper, nimproper, atoms,
                  rtp[0].bKeepAllGeneratedDihedrals,
                  rtp[0].bRemoveDihedralIfWithImproper);
    }

    /* Now we have unique lists of angles and dihedrals
     * Copy them into the destination struct
     */
    cppar(ang, nang, plist, F_ANGLES);
    cppar(dih, ndih, plist, F_PDIHS);
    cppar(improper, nimproper, plist, F_IDIHS);
    cppar(pai, npai, plist, F_LJ14);

    /* Remove all exclusions which are within nrexcl */
    clean_excls(nnb, rtp[0].nrexcl, excls);

    sfree(ang);
    sfree(dih);
    sfree(improper);
    sfree(pai);
}