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; }
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; }