void generate_excl (int nrexcl, int nratoms, t_params plist[], t_nextnb *nnb, t_blocka *excl) { int i, j, k; if (nrexcl < 0) { gmx_fatal(FARGS, "Can't have %d exclusions...", nrexcl); } init_nnb(nnb, nratoms, nrexcl); gen_nnb(nnb, plist); excl->nr = nratoms; sort_and_purge_nnb(nnb); nnb2excl (nnb, excl); }
int gmx_x2top(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] generates a primitive topology from a coordinate file.", "The program assumes all hydrogens are present when defining", "the hybridization from the atom name and the number of bonds.", "The program can also make an [TT].rtp[tt] entry, which you can then add", "to the [TT].rtp[tt] database.[PAR]", "When [TT]-param[tt] is set, equilibrium distances and angles", "and force constants will be printed in the topology for all", "interactions. The equilibrium distances and angles are taken", "from the input coordinates, the force constant are set with", "command line options.", "The force fields somewhat supported currently are:[PAR]", "G53a5 GROMOS96 53a5 Forcefield (official distribution)[PAR]", "oplsaa OPLS-AA/L all-atom force field (2001 aminoacid dihedrals)[PAR]", "The corresponding data files can be found in the library directory", "with name [TT]atomname2type.n2t[tt]. Check Chapter 5 of the manual for more", "information about file formats. By default, the force field selection", "is interactive, but you can use the [TT]-ff[tt] option to specify", "one of the short names above on the command line instead. In that", "case [THISMODULE] just looks for the corresponding file.[PAR]", }; const char *bugs[] = { "The atom type selection is primitive. Virtually no chemical knowledge is used", "Periodic boundary conditions screw up the bonding", "No improper dihedrals are generated", "The atoms to atomtype translation table is incomplete ([TT]atomname2type.n2t[tt] file in the data directory). Please extend it and send the results back to the GROMACS crew." }; FILE *fp; t_params plist[F_NRE]; t_excls *excls; t_atoms *atoms; /* list with all atoms */ gpp_atomtype_t atype; t_nextnb nnb; t_nm2type *nm2t; t_mols mymol; int nnm; char title[STRLEN], forcefield[32], ffdir[STRLEN]; rvec *x; /* coordinates? */ int *nbonds, *cgnr; int bts[] = { 1, 1, 1, 2 }; matrix box; /* box length matrix */ int natoms; /* number of atoms in one molecule */ int nres; /* number of molecules? */ int i, j, k, l, m, ndih; int epbc; gmx_bool bRTP, bTOP, bOPLS; t_symtab symtab; real cutoff, qtot, mtot; char n2t[STRLEN]; output_env_t oenv; t_filenm fnm[] = { { efSTX, "-f", "conf", ffREAD }, { efTOP, "-o", "out", ffOPTWR }, { efRTP, "-r", "out", ffOPTWR } }; #define NFILE asize(fnm) static real scale = 1.1, kb = 4e5, kt = 400, kp = 5; static t_restp rtp_header_settings; static gmx_bool bRemoveDihedralIfWithImproper = FALSE; static gmx_bool bGenerateHH14Interactions = TRUE; static gmx_bool bKeepAllGeneratedDihedrals = FALSE; static int nrexcl = 3; static gmx_bool bParam = TRUE, bRound = TRUE; static gmx_bool bPairs = TRUE, bPBC = TRUE; static gmx_bool bUsePDBcharge = FALSE, bVerbose = FALSE; static const char *molnm = "ICE"; static const char *ff = "oplsaa"; t_pargs pa[] = { { "-ff", FALSE, etSTR, {&ff}, "Force field for your simulation. Type \"select\" for interactive selection." }, { "-v", FALSE, etBOOL, {&bVerbose}, "Generate verbose output in the top file." }, { "-nexcl", FALSE, etINT, {&nrexcl}, "Number of exclusions" }, { "-H14", FALSE, etBOOL, {&bGenerateHH14Interactions}, "Use 3rd neighbour interactions for hydrogen atoms" }, { "-alldih", FALSE, etBOOL, {&bKeepAllGeneratedDihedrals}, "Generate all proper dihedrals" }, { "-remdih", FALSE, etBOOL, {&bRemoveDihedralIfWithImproper}, "Remove dihedrals on the same bond as an improper" }, { "-pairs", FALSE, etBOOL, {&bPairs}, "Output 1-4 interactions (pairs) in topology file" }, { "-name", FALSE, etSTR, {&molnm}, "Name of your molecule" }, { "-pbc", FALSE, etBOOL, {&bPBC}, "Use periodic boundary conditions." }, { "-pdbq", FALSE, etBOOL, {&bUsePDBcharge}, "Use the B-factor supplied in a [TT].pdb[tt] file for the atomic charges" }, { "-param", FALSE, etBOOL, {&bParam}, "Print parameters in the output" }, { "-round", FALSE, etBOOL, {&bRound}, "Round off measured values" }, { "-kb", FALSE, etREAL, {&kb}, "Bonded force constant (kJ/mol/nm^2)" }, { "-kt", FALSE, etREAL, {&kt}, "Angle force constant (kJ/mol/rad^2)" }, { "-kp", FALSE, etREAL, {&kp}, "Dihedral angle force constant (kJ/mol/rad^2)" } }; if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv)) { return 0; } bRTP = opt2bSet("-r", NFILE, fnm); bTOP = opt2bSet("-o", NFILE, fnm); /* C89 requirements mean that these struct members cannot be used in * the declaration of pa. So some temporary variables are needed. */ rtp_header_settings.bRemoveDihedralIfWithImproper = bRemoveDihedralIfWithImproper; rtp_header_settings.bGenerateHH14Interactions = bGenerateHH14Interactions; rtp_header_settings.bKeepAllGeneratedDihedrals = bKeepAllGeneratedDihedrals; rtp_header_settings.nrexcl = nrexcl; if (!bRTP && !bTOP) { gmx_fatal(FARGS, "Specify at least one output file"); } /* Force field selection, interactive or direct */ choose_ff(strcmp(ff, "select") == 0 ? NULL : ff, forcefield, sizeof(forcefield), ffdir, sizeof(ffdir)); bOPLS = (strcmp(forcefield, "oplsaa") == 0); mymol.name = strdup(molnm); mymol.nr = 1; /* Init parameter lists */ init_plist(plist); /* Read coordinates */ get_stx_coordnum(opt2fn("-f", NFILE, fnm), &natoms); snew(atoms, 1); /* make space for all the atoms */ init_t_atoms(atoms, natoms, TRUE); snew(x, natoms); read_stx_conf(opt2fn("-f", NFILE, fnm), title, atoms, x, NULL, &epbc, box); sprintf(n2t, "%s", ffdir); nm2t = rd_nm2type(n2t, &nnm); if (nnm == 0) { gmx_fatal(FARGS, "No or incorrect atomname2type.n2t file found (looking for %s)", n2t); } else { printf("There are %d name to type translations in file %s\n", nnm, n2t); } if (debug) { dump_nm2type(debug, nnm, nm2t); } printf("Generating bonds from distances...\n"); snew(nbonds, atoms->nr); mk_bonds(nnm, nm2t, atoms, x, &(plist[F_BONDS]), nbonds, bPBC, box); open_symtab(&symtab); atype = set_atom_type(&symtab, atoms, &(plist[F_BONDS]), nbonds, nnm, nm2t); /* Make Angles and Dihedrals */ snew(excls, atoms->nr); printf("Generating angles and dihedrals from bonds...\n"); init_nnb(&nnb, atoms->nr, 4); gen_nnb(&nnb, plist); print_nnb(&nnb, "NNB"); gen_pad(&nnb, atoms, &rtp_header_settings, plist, excls, NULL, TRUE); done_nnb(&nnb); if (!bPairs) { plist[F_LJ14].nr = 0; } fprintf(stderr, "There are %4d %s dihedrals, %4d impropers, %4d angles\n" " %4d pairs, %4d bonds and %4d atoms\n", plist[F_PDIHS].nr, bOPLS ? "Ryckaert-Bellemans" : "proper", plist[F_IDIHS].nr, plist[F_ANGLES].nr, plist[F_LJ14].nr, plist[F_BONDS].nr, atoms->nr); calc_angles_dihs(&plist[F_ANGLES], &plist[F_PDIHS], x, bPBC, box); set_force_const(plist, kb, kt, kp, bRound, bParam); cgnr = set_cgnr(atoms, bUsePDBcharge, &qtot, &mtot); printf("Total charge is %g, total mass is %g\n", qtot, mtot); if (bOPLS) { bts[2] = 3; bts[3] = 1; } if (bTOP) { fp = ftp2FILE(efTOP, NFILE, fnm, "w"); print_top_header(fp, ftp2fn(efTOP, NFILE, fnm), TRUE, ffdir, 1.0); write_top(fp, NULL, mymol.name, atoms, FALSE, bts, plist, excls, atype, cgnr, rtp_header_settings.nrexcl); print_top_mols(fp, mymol.name, ffdir, NULL, 0, NULL, 1, &mymol); ffclose(fp); } if (bRTP) { print_rtp(ftp2fn(efRTP, NFILE, fnm), "Generated by x2top", atoms, plist, atype, cgnr); } if (debug) { dump_hybridization(debug, atoms, nbonds); } close_symtab(&symtab); free(mymol.name); printf("\nWARNING: topologies generated by %s can not be trusted at face value.\n", ShortProgram()); printf(" Please verify atomtypes and charges by comparison to other\n"); printf(" topologies.\n"); return 0; }
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); }