Пример #1
0
static int add_h_low(t_atoms **pdbaptr, rvec *xptr[],
                     int nah, t_hackblock ah[],
                     int nterpairs, t_hackblock **ntdb, t_hackblock **ctdb,
                     int *rN, int *rC, gmx_bool bCheckMissing,
                     int **nabptr, t_hack ***abptr,
                     gmx_bool bUpdate_pdba, gmx_bool bKeep_old_pdba)
{
    t_atoms        *newpdba = NULL, *pdba = NULL;
    int             nadd;
    int             i, newi, j, d, natoms, nalreadypresent;
    int            *nab = NULL;
    t_hack        **ab  = NULL;
    t_hackblock    *hb;
    rvec           *xn;
    gmx_bool        bKeep_ab;

    /* set flags for adding hydrogens (according to hdb) */
    pdba   = *pdbaptr;
    natoms = pdba->nr;

    if (nabptr && abptr)
    {
        /* the first time these will be pointers to NULL, but we will
           return in them the completed arrays, which we will get back
           the second time */
        nab      = *nabptr;
        ab       = *abptr;
        bKeep_ab = TRUE;
        if (debug)
        {
            fprintf(debug, "pointer to ab found\n");
        }
    }
    else
    {
        bKeep_ab = FALSE;
    }

    if (nab && ab)
    {
        /* WOW, everything was already figured out */
        bUpdate_pdba = FALSE;
        if (debug)
        {
            fprintf(debug, "pointer to non-null ab found\n");
        }
    }
    else
    {
        /* We'll have to do all the hard work */
        bUpdate_pdba = TRUE;
        /* first get all the hackblocks for each residue: */
        hb = get_hackblocks(pdba, nah, ah, nterpairs, ntdb, ctdb, rN, rC);
        if (debug)
        {
            dump_hb(debug, pdba->nres, hb);
        }

        /* expand the hackblocks to atom level */
        snew(nab, natoms);
        snew(ab, natoms);
        expand_hackblocks(pdba, hb, nab, ab, nterpairs, rN, rC);
        free_t_hackblock(pdba->nres, &hb);
    }

    if (debug)
    {
        fprintf(debug, "before calc_all_pos\n");
        dump_ab(debug, natoms, nab, ab, TRUE);
    }

    /* Now calc the positions */
    calc_all_pos(pdba, *xptr, nab, ab, bCheckMissing);

    if (debug)
    {
        fprintf(debug, "after calc_all_pos\n");
        dump_ab(debug, natoms, nab, ab, TRUE);
    }

    if (bUpdate_pdba)
    {
        /* we don't have to add atoms that are already present in pdba,
           so we will remove them from the ab (t_hack) */
        nadd = check_atoms_present(pdba, nab, ab);
        if (debug)
        {
            fprintf(debug, "removed add hacks that were already in pdba:\n");
            dump_ab(debug, natoms, nab, ab, TRUE);
            fprintf(debug, "will be adding %d atoms\n", nadd);
        }

        /* Copy old atoms, making space for new ones */
        snew(newpdba, 1);
        init_t_atoms(newpdba, natoms+nadd, FALSE);
        newpdba->nres    = pdba->nres;
        sfree(newpdba->resinfo);
        newpdba->resinfo = pdba->resinfo;
    }
    else
    {
        nadd = 0;
    }
    if (debug)
    {
        fprintf(debug, "snew xn for %d old + %d new atoms %d total)\n",
                natoms, nadd, natoms+nadd);
    }

    if (nadd == 0)
    {
        /* There is nothing to do: return now */
        if (!bKeep_ab)
        {
            free_ab(natoms, nab, ab);
        }

        return natoms;
    }

    snew(xn, natoms+nadd);
    newi = 0;
    for (i = 0; (i < natoms); i++)
    {
        /* check if this atom wasn't scheduled for deletion */
        if (nab[i] == 0 || (ab[i][0].nname != NULL) )
        {
            if (newi >= natoms+nadd)
            {
                /*gmx_fatal(FARGS,"Not enough space for adding atoms");*/
                nadd += 10;
                srenew(xn, natoms+nadd);
                if (bUpdate_pdba)
                {
                    srenew(newpdba->atom, natoms+nadd);
                    srenew(newpdba->atomname, natoms+nadd);
                }
                debug_gmx();
            }
            if (debug)
            {
                fprintf(debug, "(%3d) %3d %4s %4s%3d %3d",
                        i+1, newi+1, *pdba->atomname[i],
                        *pdba->resinfo[pdba->atom[i].resind].name,
                        pdba->resinfo[pdba->atom[i].resind].nr, nab[i]);
            }
            if (bUpdate_pdba)
            {
                copy_atom(pdba, i, newpdba, newi);
            }
            copy_rvec((*xptr)[i], xn[newi]);
            /* process the hacks for this atom */
            nalreadypresent = 0;
            for (j = 0; j < nab[i]; j++)
            {
                if (ab[i][j].oname == NULL) /* add */
                {
                    newi++;
                    if (newi >= natoms+nadd)
                    {
                        /* gmx_fatal(FARGS,"Not enough space for adding atoms");*/
                        nadd += 10;
                        srenew(xn, natoms+nadd);
                        if (bUpdate_pdba)
                        {
                            srenew(newpdba->atom, natoms+nadd);
                            srenew(newpdba->atomname, natoms+nadd);
                        }
                        debug_gmx();
                    }
                    if (bUpdate_pdba)
                    {
                        newpdba->atom[newi].resind = pdba->atom[i].resind;
                    }
                    if (debug)
                    {
                        fprintf(debug, " + %d", newi+1);
                    }
                }
                if (ab[i][j].nname != NULL &&
                    (ab[i][j].oname == NULL ||
                     strcmp(ab[i][j].oname, *newpdba->atomname[newi]) == 0))
                {
                    /* add or replace */
                    if (ab[i][j].oname == NULL && ab[i][j].bAlreadyPresent)
                    {
                        /* This atom is already present, copy it from the input. */
                        nalreadypresent++;
                        if (bUpdate_pdba)
                        {
                            copy_atom(pdba, i+nalreadypresent, newpdba, newi);
                        }
                        copy_rvec((*xptr)[i+nalreadypresent], xn[newi]);
                    }
                    else
                    {
                        if (bUpdate_pdba)
                        {
                            if (gmx_debug_at)
                            {
                                fprintf(debug, "Replacing %d '%s' with (old name '%s') %s\n",
                                        newi,
                                        (newpdba->atomname[newi] && *newpdba->atomname[newi]) ? *newpdba->atomname[newi] : "",
                                        ab[i][j].oname ? ab[i][j].oname : "",
                                        ab[i][j].nname);
                            }
                            snew(newpdba->atomname[newi], 1);
                            *newpdba->atomname[newi] = strdup(ab[i][j].nname);
                            if (ab[i][j].oname != NULL && ab[i][j].atom) /* replace */
                            {                                            /*          newpdba->atom[newi].m    = ab[i][j].atom->m; */
/*        newpdba->atom[newi].q    = ab[i][j].atom->q; */
/*        newpdba->atom[newi].type = ab[i][j].atom->type; */
                            }
                        }
                        if (ab[i][j].bXSet)
                        {
                            copy_rvec(ab[i][j].newx, xn[newi]);
                        }
                    }
                    if (bUpdate_pdba && debug)
                    {
                        fprintf(debug, " %s %g %g", *newpdba->atomname[newi],
                                newpdba->atom[newi].m, newpdba->atom[newi].q);
                    }
                }
            }
            newi++;
            i += nalreadypresent;
            if (debug)
            {
                fprintf(debug, "\n");
            }
        }
    }
    if (bUpdate_pdba)
    {
        newpdba->nr = newi;
    }

    if (bKeep_ab)
    {
        *nabptr = nab;
        *abptr  = ab;
    }
    else
    {
        /* Clean up */
        free_ab(natoms, nab, ab);
    }

    if (bUpdate_pdba)
    {
        if (!bKeep_old_pdba)
        {
            for (i = 0; i < natoms; i++)
            {
                /* Do not free the atomname string itself, it might be in symtab */
                /* sfree(*(pdba->atomname[i])); */
                /* sfree(pdba->atomname[i]); */
            }
            sfree(pdba->atomname);
            sfree(pdba->atom);
            sfree(pdba->pdbinfo);
            sfree(pdba);
        }
        *pdbaptr = newpdba;
    }
    else
    {
        nadd = newi-natoms;
    }

    sfree(*xptr);
    *xptr = xn;

    return newi;
}
Пример #2
0
int add_h(t_atoms **pdbaptr, rvec *xptr[], 
	  int nah, t_hackblock ah[],
	  int nterpairs, t_hackblock **ntdb, t_hackblock **ctdb, 
	  int *rN, int *rC, bool bMissing,
	  int **nabptr, t_hack ***abptr,
	  bool bUpdate_pdba, bool bKeep_old_pdba)
{
  t_atoms     *newpdba=NULL,*pdba=NULL;
  bool        bSet;
  int         nadd;
  int         i,newi,j,d,natoms;
  int         *nab=NULL;
  t_hack      **ab=NULL;
  t_hackblock *hb;
  rvec        *xn;
  bool        bKeep_ab;
  
  /* set flags for adding hydrogens (according to hdb) */
  pdba=*pdbaptr;
  natoms=pdba->nr;
  
  if (nabptr && abptr) {
    /* the first time these will be pointers to NULL, but we will
       return in them the completed arrays, which we will get back
       the second time */
    nab = *nabptr;
    ab  = *abptr;
    bKeep_ab=TRUE;
    if (debug) fprintf(debug,"pointer to ab found\n");
  } else
    bKeep_ab=FALSE;
  
  if (nab && ab) {
    /* WOW, everything was already figured out */
    bUpdate_pdba = FALSE;
    if (debug) fprintf(debug,"pointer to non-null ab found\n");
  } else {
    /* We'll have to do all the hard work */
    bUpdate_pdba = TRUE;
    /* first get all the hackblocks for each residue: */
    hb = get_hackblocks(pdba, nah, ah, nterpairs, ntdb, ctdb, rN, rC);
    if (debug) dump_hb(debug, pdba->nres, hb);
    
    /* expand the hackblocks to atom level */
    snew(nab,natoms);
    snew(ab,natoms);
    expand_hackblocks(pdba, hb, nab, ab, nterpairs, rN, rC);
    free_t_hackblock(pdba->nres, &hb);
  }
  
  if (debug) { 
    fprintf(debug,"before calc_all_pos\n");
    dump_ab(debug, natoms, nab, ab, TRUE);
  }
  
  /* Now calc the positions */
  calc_all_pos(pdba, *xptr, nab, ab, bMissing);

  if (debug) { 
    fprintf(debug,"after calc_all_pos\n");
    dump_ab(debug, natoms, nab, ab, TRUE);
  }
  
  if (bUpdate_pdba) {
    /* we don't have to add atoms that are already present in pdba,
       so we will remove them from the ab (t_hack) */
    nadd = check_atoms_present(pdba, nab, ab, bMissing);
    if (debug) {
      fprintf(debug, "removed add hacks that were already in pdba:\n");
      dump_ab(debug, natoms, nab, ab, TRUE);
      fprintf(debug, "will be adding %d atoms\n",nadd);
    }
    
    /* Copy old atoms, making space for new ones */
    snew(newpdba,1);
    init_t_atoms(newpdba,natoms+nadd,FALSE);
    newpdba->nres    = pdba->nres;   
    sfree(newpdba->resname);
    newpdba->resname = pdba->resname;
  } else {
    nadd = 0;
  }
  if (debug) fprintf(debug,"snew xn for %d old + %d new atoms %d total)\n",
		     natoms, nadd, natoms+nadd);
  snew(xn,natoms+nadd);
  newi=0;
  for(i=0; (i<natoms); i++) {
    /* check if this atom wasn't scheduled for deletion */
    if ( nab[i]==0 || (ab[i][0].nname != NULL) ) {
      if (newi >= natoms+nadd) {
	/*gmx_fatal(FARGS,"Not enough space for adding atoms");*/
	nadd+=10;
	srenew(xn,natoms+nadd);
	if (bUpdate_pdba) {
	  srenew(newpdba->atom,natoms+nadd);
	  srenew(newpdba->atomname,natoms+nadd);
	}
	debug_gmx();
      }
      if (debug) fprintf(debug,"(%3d) %3d %4s %4s%3d %3d",
			 i+1, newi+1, *pdba->atomname[i],
			 *pdba->resname[pdba->atom[i].resnr],
			 pdba->atom[i].resnr+1, nab[i]);
      if (bUpdate_pdba)
	copy_atom(pdba,i, newpdba,newi);
      copy_rvec((*xptr)[i],xn[newi]);
      /* process the hacks for this atom */
      for(j=0; j<nab[i]; j++) {
	if ( ab[i][j].oname==NULL ) { /* add */
	  newi++;
	  if (newi >= natoms+nadd) {
	    /* gmx_fatal(FARGS,"Not enough space for adding atoms");*/
	    nadd+=10;
	    srenew(xn,natoms+nadd);
	    if (bUpdate_pdba) {
	      srenew(newpdba->atom,natoms+nadd);
	      srenew(newpdba->atomname,natoms+nadd);
	    }
	    debug_gmx();
	  }
	  if (bUpdate_pdba) {
	    newpdba->atom[newi].resnr=pdba->atom[i].resnr;
	  }
	  if (debug) fprintf(debug," + %d",newi+1);
	}
	if ( ab[i][j].nname!=NULL ) { /* add or replace */
	  if (bUpdate_pdba) {
	    snew(newpdba->atomname[newi],1);
	    *newpdba->atomname[newi]=strdup(ab[i][j].nname);
	    if ( ab[i][j].oname!=NULL && ab[i][j].atom ) { /* replace */
/* 	      newpdba->atom[newi].m    = ab[i][j].atom->m; */
/* 	      newpdba->atom[newi].q    = ab[i][j].atom->q; */
/* 	      newpdba->atom[newi].type = ab[i][j].atom->type; */
	    }
	  }
	  bSet=TRUE;
	  for(d=0; d<DIM; d++)
	    bSet = bSet && ab[i][j].newx[d]!=NOTSET;
	  if (bSet)
	    copy_rvec(ab[i][j].newx, xn[newi]);
	  if (bUpdate_pdba && debug) 
	    fprintf(debug," %s %g %g",*newpdba->atomname[newi],
		    newpdba->atom[newi].m,newpdba->atom[newi].q);
	}
      }
      newi++;
      if (debug) fprintf(debug,"\n");
    }
  }
  if (bUpdate_pdba)
    newpdba->nr = newi;
  
  if ( bKeep_ab ) {
    *nabptr=nab;
    *abptr=ab;
  } else {
    /* Clean up */
    for(i=0; i<natoms; i++)
      free_t_hack(nab[i], &ab[i]);
    sfree(nab);
    sfree(ab);
  }
    
  if ( bUpdate_pdba ) {
    if ( !bKeep_old_pdba ) {
      for(i=0; i < natoms; i++) {
	sfree(*(pdba->atomname[i]));
	/*       sfree(pdba->atomname[i]); */
      }
      sfree(pdba->atomname);
      sfree(pdba->atom);
      sfree(pdba->pdbinfo);
      sfree(pdba);
    }
    *pdbaptr=newpdba;
  } else
    nadd = newi-natoms;
  
  sfree(*xptr);
  *xptr=xn;
  
  return newi;
}