void pdb2top(FILE *top_file, char *posre_fn, char *molname, t_atoms *atoms, rvec **x, gpp_atomtype_t atype, t_symtab *tab, int nrtp, t_restp rtp[], t_restp *restp, t_hackblock *hb, int nterpairs,t_hackblock **ntdb, t_hackblock **ctdb, gmx_bool bAllowMissing, gmx_bool bVsites, gmx_bool bVsiteAromatics, const char *ff, const char *ffdir, real mHmult, int nssbonds, t_ssbond *ssbonds, real long_bond_dist, real short_bond_dist, gmx_bool bDeuterate, gmx_bool bChargeGroups, gmx_bool bCmap, gmx_bool bRenumRes,gmx_bool bRTPresname) { /* t_hackblock *hb; t_restp *restp; */ t_params plist[F_NRE]; t_excls *excls; t_nextnb nnb; int *cgnr; int *vsite_type; int i,nmissat; int bts[ebtsNR]; init_plist(plist); if (debug) { print_resall(debug, atoms->nres, restp, atype); dump_hb(debug, atoms->nres, hb); } /* Make bonds */ at2bonds(&(plist[F_BONDS]), hb, atoms->nr, atoms->atom, atoms->atomname, atoms->nres, *x, long_bond_dist, short_bond_dist, bAllowMissing); /* specbonds: disulphide bonds & heme-his */ do_ssbonds(&(plist[F_BONDS]), atoms->nr, atoms->atom, atoms->atomname, nssbonds, ssbonds, bAllowMissing); nmissat = name2type(atoms, &cgnr, atype, restp); if (nmissat) { if (bAllowMissing) fprintf(stderr,"There were %d missing atoms in molecule %s\n", nmissat,molname); else gmx_fatal(FARGS,"There were %d missing atoms in molecule %s, if you want to use this incomplete topology anyhow, use the option -missing", nmissat,molname); } /* Cleanup bonds (sort and rm doubles) */ clean_bonds(&(plist[F_BONDS])); snew(vsite_type,atoms->nr); for(i=0; i<atoms->nr; i++) vsite_type[i]=NOTSET; if (bVsites) { /* determine which atoms will be vsites and add dummy masses also renumber atom numbers in plist[0..F_NRE]! */ do_vsites(nrtp, rtp, atype, atoms, tab, x, plist, &vsite_type, &cgnr, mHmult, bVsiteAromatics, ffdir); } /* Make Angles and Dihedrals */ fprintf(stderr,"Generating angles, dihedrals and pairs...\n"); snew(excls,atoms->nr); init_nnb(&nnb,atoms->nr,4); gen_nnb(&nnb,plist); print_nnb(&nnb,"NNB"); gen_pad(&nnb,atoms,restp[0].nrexcl,restp[0].HH14, plist,excls,hb,restp[0].bAlldih,restp[0].bRemoveDih, bAllowMissing); done_nnb(&nnb); /* Make CMAP */ if (TRUE == bCmap) { gen_cmap(&(plist[F_CMAP]), restp, atoms->nr, atoms->atom, atoms->atomname, atoms->nres); if (plist[F_CMAP].nr > 0) { fprintf(stderr, "There are %4d cmap torsion pairs\n", plist[F_CMAP].nr); } } /* set mass of all remaining hydrogen atoms */ if (mHmult != 1.0) do_h_mass(&(plist[F_BONDS]),vsite_type,atoms,mHmult,bDeuterate); sfree(vsite_type); /* Cleanup bonds (sort and rm doubles) */ /* clean_bonds(&(plist[F_BONDS]));*/ fprintf(stderr, "There are %4d dihedrals, %4d impropers, %4d angles\n" " %4d pairs, %4d bonds and %4d virtual sites\n", plist[F_PDIHS].nr, plist[F_IDIHS].nr, plist[F_ANGLES].nr, plist[F_LJ14].nr, plist[F_BONDS].nr, plist[F_VSITE2].nr + plist[F_VSITE3].nr + plist[F_VSITE3FD].nr + plist[F_VSITE3FAD].nr + plist[F_VSITE3OUT].nr + plist[F_VSITE4FD].nr + plist[F_VSITE4FDN].nr ); print_sums(atoms, FALSE); if (FALSE == bChargeGroups) { scrub_charge_groups(cgnr, atoms->nr); } if (bRenumRes) { for(i=0; i<atoms->nres; i++) { atoms->resinfo[i].nr = i + 1; atoms->resinfo[i].ic = ' '; } } if (top_file) { fprintf(stderr,"Writing topology\n"); /* We can copy the bonded types from the first restp, * since the types have to be identical for all residues in one molecule. */ for(i=0; i<ebtsNR; i++) { bts[i] = restp[0].rb[i].type; } write_top(top_file, posre_fn, molname, atoms, bRTPresname, bts, plist, excls, atype, cgnr, restp[0].nrexcl); } /* cleaning up */ free_t_hackblock(atoms->nres, &hb); free_t_restp(atoms->nres, &restp); /* we should clean up hb and restp here, but that is a *L*O*T* of work! */ sfree(cgnr); for (i=0; i<F_NRE; i++) sfree(plist[i].param); for (i=0; i<atoms->nr; i++) sfree(excls[i].e); sfree(excls); }
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; }