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; }
static void mk_diamond(t_atoms *a,rvec x[],real odist,t_symtab *symtab, gmx_bool bPBC,matrix box) { int i,ib,j,k,l,m,nrm=0; t_bbb *bbb; gmx_bool *bRemove; rvec dx; do { nrm = 0; bbb = mk_bonds(a->nr,x,odist,bPBC,box); for(i=0; (i<a->nr); i++) { if (bbb[i].n < 2) { for(k=0; (k<bbb[i].n); k++) { ib = bbb[i].aa[k]; for(j=0; (j<bbb[ib].n); j++) if (bbb[ib].aa[j] == i) break; if (j == bbb[ib].n) gmx_fatal(FARGS,"Bond inconsistency (%d not in list of %d)!\n",i,ib); for( ; (j<bbb[ib].n-1); j++) bbb[ib].aa[j] = bbb[ib].aa[j+1]; bbb[ib].n--; nrm++; } bbb[i].n = 0; } } for(i=j=0; (i<a->nr); i++) { if (bbb[i].n >= 2) { copy_rvec(x[i],x[j]); j++; } } fprintf(stderr,"Kicking out %d carbon atoms (out of %d)\n", a->nr-j,a->nr); a->nr = j; sfree(bbb); } while (nrm > 0); /* Rename atoms */ bbb = mk_bonds(a->nr,x,odist,bPBC,box); for(i=0; (i<a->nr); i++) { switch (bbb[i].n) { case 4: a->atomname[i] = put_symtab(symtab,"C"); break; case 3: a->atomname[i] = put_symtab(symtab,"CH1"); break; case 2: a->atomname[i] = put_symtab(symtab,"CH2"); break; default: gmx_fatal(FARGS,"This atom (%d) has %d bonds only",i,bbb[i].n); } } sfree(bbb); }