2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team.
6 * Copyright (c) 2013,2014, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
45 #include "gromacs/fileio/filenm.h"
46 #include "gromacs/fileio/pdbio.h"
47 #include "gromacs/fileio/strdb.h"
48 #include "gromacs/gmxpreprocess/add_par.h"
49 #include "gromacs/gmxpreprocess/fflibutil.h"
50 #include "gromacs/gmxpreprocess/gen_ad.h"
51 #include "gromacs/gmxpreprocess/gen_vsite.h"
52 #include "gromacs/gmxpreprocess/gpp_nextnb.h"
53 #include "gromacs/gmxpreprocess/h_db.h"
54 #include "gromacs/gmxpreprocess/pgutil.h"
55 #include "gromacs/gmxpreprocess/resall.h"
56 #include "gromacs/gmxpreprocess/topdirs.h"
57 #include "gromacs/gmxpreprocess/topio.h"
58 #include "gromacs/gmxpreprocess/toputil.h"
59 #include "gromacs/legacyheaders/copyrite.h"
60 #include "gromacs/legacyheaders/macros.h"
61 #include "gromacs/math/vec.h"
62 #include "gromacs/topology/residuetypes.h"
63 #include "gromacs/topology/symtab.h"
64 #include "gromacs/utility/cstringutil.h"
65 #include "gromacs/utility/exceptions.h"
66 #include "gromacs/utility/fatalerror.h"
67 #include "gromacs/utility/futil.h"
68 #include "gromacs/utility/programcontext.h"
69 #include "gromacs/utility/smalloc.h"
71 /* this must correspond to enum in pdb2top.h */
72 const char *hh[ehisNR] = { "HISD", "HISE", "HISH", "HIS1" };
74 static int missing_atoms(t_restp *rp, int resind, t_atoms *at, int i0, int i)
81 for (j = 0; j < rp->natom; j++)
83 name = *(rp->atomname[j]);
85 for (k = i0; k < i; k++)
87 bFound = (bFound || !gmx_strcasecmp(*(at->atomname[k]), name));
92 fprintf(stderr, "\nWARNING: "
93 "atom %s is missing in residue %s %d in the pdb file\n",
94 name, *(at->resinfo[resind].name), at->resinfo[resind].nr);
95 if (name[0] == 'H' || name[0] == 'h')
97 fprintf(stderr, " You might need to add atom %s to the hydrogen database of building block %s\n"
98 " in the file %s.hdb (see the manual)\n",
99 name, *(at->resinfo[resind].rtp), rp->filebase);
101 fprintf(stderr, "\n");
108 gmx_bool is_int(double x)
110 const double tol = 1e-4;
119 return (fabs(x-ix) < tol);
122 static void swap_strings(char **s, int i, int j)
132 choose_ff(const char *ffsel,
133 char *forcefield, int ff_maxlen,
134 char *ffdir, int ffdir_maxlen)
137 char **ffdirs, **ffs, **ffs_dir, *ptr;
138 int i, j, sel, cwdsel, nfound;
139 char buf[STRLEN], **desc;
143 nff = fflib_search_file_in_dirend(fflib_forcefield_itp(),
144 fflib_forcefield_dir_ext(),
149 gmx_fatal(FARGS, "No force fields found (files with name '%s' in subdirectories ending on '%s')",
150 fflib_forcefield_itp(), fflib_forcefield_dir_ext());
153 /* Replace with unix path separators */
154 if (DIR_SEPARATOR != '/')
156 for (i = 0; i < nff; i++)
158 while ( (ptr = strchr(ffdirs[i], DIR_SEPARATOR)) != NULL)
165 /* Store the force field names in ffs */
168 for (i = 0; i < nff; i++)
170 /* Remove the path from the ffdir name - use our unix standard here! */
171 ptr = strrchr(ffdirs[i], '/');
174 ffs[i] = gmx_strdup(ffdirs[i]);
175 ffs_dir[i] = low_gmxlibfn(ffdirs[i], FALSE, FALSE);
176 if (ffs_dir[i] == NULL)
178 gmx_fatal(FARGS, "Can no longer find file '%s'", ffdirs[i]);
183 ffs[i] = gmx_strdup(ptr+1);
184 ffs_dir[i] = gmx_strdup(ffdirs[i]);
186 ffs_dir[i][strlen(ffs_dir[i])-strlen(ffs[i])-1] = '\0';
187 /* Remove the extension from the ffdir name */
188 ffs[i][strlen(ffs[i])-strlen(fflib_forcefield_dir_ext())] = '\0';
196 for (i = 0; i < nff; i++)
198 if (strcmp(ffs[i], ffsel) == 0)
200 /* Matching ff name */
204 if (strncmp(ffs_dir[i], ".", 1) == 0)
221 "Force field '%s' occurs in %d places. pdb2gmx is using the one in the\n"
222 "current directory. Use interactive selection (not the -ff option) if\n"
223 "you would prefer a different one.\n", ffsel, nfound);
228 "Force field '%s' occurs in %d places, but not in the current directory.\n"
229 "Run without the -ff switch and select the force field interactively.", ffsel, nfound);
232 else if (nfound == 0)
234 gmx_fatal(FARGS, "Could not find force field '%s' in current directory, install tree or GMXDATA path.", ffsel);
240 for (i = 0; (i < nff); i++)
242 sprintf(buf, "%s%c%s%s%c%s",
243 ffs_dir[i], DIR_SEPARATOR,
244 ffs[i], fflib_forcefield_dir_ext(), DIR_SEPARATOR,
245 fflib_forcefield_doc());
248 /* We don't use fflib_open, because we don't want printf's */
249 fp = gmx_ffopen(buf, "r");
250 snew(desc[i], STRLEN);
251 get_a_line(fp, desc[i], STRLEN);
256 desc[i] = gmx_strdup(ffs[i]);
259 /* Order force fields from the same dir alphabetically
260 * and put deprecated force fields at the end.
262 for (i = 0; (i < nff); i++)
264 for (j = i+1; (j < nff); j++)
266 if (strcmp(ffs_dir[i], ffs_dir[j]) == 0 &&
267 ((desc[i][0] == '[' && desc[j][0] != '[') ||
268 ((desc[i][0] == '[' || desc[j][0] != '[') &&
269 gmx_strcasecmp(desc[i], desc[j]) > 0)))
271 swap_strings(ffdirs, i, j);
272 swap_strings(ffs, i, j);
273 swap_strings(desc, i, j);
278 printf("\nSelect the Force Field:\n");
279 for (i = 0; (i < nff); i++)
281 if (i == 0 || strcmp(ffs_dir[i-1], ffs_dir[i]) != 0)
283 if (strcmp(ffs_dir[i], ".") == 0)
285 printf("From current directory:\n");
289 printf("From '%s':\n", ffs_dir[i]);
292 printf("%2d: %s\n", i+1, desc[i]);
300 pret = fgets(buf, STRLEN, stdin);
304 sel = strtol(buf, NULL, 10);
308 while (pret == NULL || (sel < 0) || (sel >= nff));
310 /* Check for a current limitation of the fflib code.
311 * It will always read from the first ff directory in the list.
312 * This check assumes that the order of ffs matches the order
313 * in which fflib_open searches ff library files.
315 for (i = 0; i < sel; i++)
317 if (strcmp(ffs[i], ffs[sel]) == 0)
319 gmx_fatal(FARGS, "Can only select the first of multiple force field entries with directory name '%s%s' in the list. If you want to use the next entry, run pdb2gmx in a different directory or rename or move the force field directory present in the current working directory.",
320 ffs[sel], fflib_forcefield_dir_ext());
329 if (strlen(ffs[sel]) >= (size_t)ff_maxlen)
331 gmx_fatal(FARGS, "Length of force field name (%d) >= maxlen (%d)",
332 strlen(ffs[sel]), ff_maxlen);
334 strcpy(forcefield, ffs[sel]);
336 if (strlen(ffdirs[sel]) >= (size_t)ffdir_maxlen)
338 gmx_fatal(FARGS, "Length of force field dir (%d) >= maxlen (%d)",
339 strlen(ffdirs[sel]), ffdir_maxlen);
341 strcpy(ffdir, ffdirs[sel]);
343 for (i = 0; (i < nff); i++)
354 void choose_watermodel(const char *wmsel, const char *ffdir,
357 const char *fn_watermodels = "watermodels.dat";
358 char fn_list[STRLEN];
365 if (strcmp(wmsel, "none") == 0)
371 else if (strcmp(wmsel, "select") != 0)
373 *watermodel = gmx_strdup(wmsel);
378 sprintf(fn_list, "%s%c%s", ffdir, DIR_SEPARATOR, fn_watermodels);
380 if (!fflib_fexist(fn_list))
382 fprintf(stderr, "No file '%s' found, will not include a water model\n",
389 fp = fflib_open(fn_list);
390 printf("\nSelect the Water Model:\n");
393 while (get_a_line(fp, buf, STRLEN))
395 srenew(model, nwm+1);
396 snew(model[nwm], STRLEN);
397 sscanf(buf, "%s%n", model[nwm], &i);
401 fprintf(stderr, "%2d: %s\n", nwm+1, buf+i);
410 fprintf(stderr, "%2d: %s\n", nwm+1, "None");
415 pret = fgets(buf, STRLEN, stdin);
419 sel = strtol(buf, NULL, 10);
423 while (pret == NULL || sel < 0 || sel > nwm);
431 *watermodel = gmx_strdup(model[sel]);
434 for (i = 0; i < nwm; i++)
441 static int name2type(t_atoms *at, int **cgnr,
442 t_restp restp[], gmx_residuetype_t *rt)
444 int i, j, prevresind, resind, i0, prevcg, cg, curcg;
462 for (i = 0; (i < at->nr); i++)
465 if (at->atom[i].resind != resind)
468 resind = at->atom[i].resind;
469 bProt = gmx_residuetype_is_protein(rt, *(at->resinfo[resind].name));
470 bNterm = bProt && (resind == 0);
473 nmissat += missing_atoms(&restp[prevresind], prevresind, at, i0, i);
477 if (at->atom[i].m == 0)
481 fprintf(debug, "atom %d%s: curcg=%d, prevcg=%d, cg=%d\n",
482 i+1, *(at->atomname[i]), curcg, prevcg,
483 j == NOTSET ? NOTSET : restp[resind].cgnr[j]);
487 name = *(at->atomname[i]);
488 j = search_jtype(&restp[resind], name, bNterm);
489 at->atom[i].type = restp[resind].atom[j].type;
490 at->atom[i].q = restp[resind].atom[j].q;
491 at->atom[i].m = restp[resind].atom[j].m;
492 cg = restp[resind].cgnr[j];
493 /* A charge group number -1 signals a separate charge group
496 if ( (cg == -1) || (cg != prevcg) || (resind != prevresind) )
505 fprintf(debug, "atom %d%s: curcg=%d, qt=%g, is_int=%d\n",
506 i+1, *(at->atomname[i]), curcg, qt, is_int(qt));
517 at->atom[i].typeB = at->atom[i].type;
518 at->atom[i].qB = at->atom[i].q;
519 at->atom[i].mB = at->atom[i].m;
521 nmissat += missing_atoms(&restp[resind], resind, at, i0, i);
526 static void print_top_heavy_H(FILE *out, real mHmult)
530 fprintf(out, "; Using deuterium instead of hydrogen\n\n");
532 else if (mHmult == 4.0)
534 fprintf(out, "#define HEAVY_H\n\n");
536 else if (mHmult != 1.0)
538 fprintf(stderr, "WARNING: unsupported proton mass multiplier (%g) "
539 "in pdb2top\n", mHmult);
543 void print_top_comment(FILE *out,
544 const char *filename,
548 char ffdir_parent[STRLEN];
551 nice_header(out, filename);
552 fprintf(out, ";\tThis is a %s topology file\n;\n", bITP ? "include" : "standalone");
555 gmx::BinaryInformationSettings settings;
556 settings.generatedByHeader(true);
557 settings.linePrefix(";\t");
558 gmx::printBinaryInformation(out, gmx::getProgramContext(), settings);
560 GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
562 if (strchr(ffdir, '/') == NULL)
564 fprintf(out, ";\tForce field was read from the standard Gromacs share directory.\n;\n\n");
566 else if (ffdir[0] == '.')
568 fprintf(out, ";\tForce field was read from current directory or a relative path - path added.\n;\n\n");
572 strncpy(ffdir_parent, ffdir, STRLEN-1);
573 ffdir_parent[STRLEN-1] = '\0'; /*make sure it is 0-terminated even for long string*/
574 p = strrchr(ffdir_parent, '/');
579 ";\tForce field data was read from:\n"
583 ";\tThis might be a non-standard force field location. When you use this topology, the\n"
584 ";\tforce field must either be present in the current directory, or the location\n"
585 ";\tspecified in the GMXLIB path variable or with the 'include' mdp file option.\n;\n\n",
590 void print_top_header(FILE *out, const char *filename,
591 gmx_bool bITP, const char *ffdir, real mHmult)
595 print_top_comment(out, filename, ffdir, bITP);
597 print_top_heavy_H(out, mHmult);
598 fprintf(out, "; Include forcefield parameters\n");
600 p = strrchr(ffdir, '/');
601 p = (ffdir[0] == '.' || p == NULL) ? ffdir : p+1;
603 fprintf(out, "#include \"%s/%s\"\n\n", p, fflib_forcefield_itp());
606 static void print_top_posre(FILE *out, const char *pr)
608 fprintf(out, "; Include Position restraint file\n");
609 fprintf(out, "#ifdef POSRES\n");
610 fprintf(out, "#include \"%s\"\n", pr);
611 fprintf(out, "#endif\n\n");
614 static void print_top_water(FILE *out, const char *ffdir, const char *water)
619 fprintf(out, "; Include water topology\n");
621 p = strrchr(ffdir, '/');
622 p = (ffdir[0] == '.' || p == NULL) ? ffdir : p+1;
623 fprintf(out, "#include \"%s/%s.itp\"\n", p, water);
626 fprintf(out, "#ifdef POSRES_WATER\n");
627 fprintf(out, "; Position restraint for each water oxygen\n");
628 fprintf(out, "[ position_restraints ]\n");
629 fprintf(out, ";%3s %5s %9s %10s %10s\n", "i", "funct", "fcx", "fcy", "fcz");
630 fprintf(out, "%4d %4d %10g %10g %10g\n", 1, 1, 1000.0, 1000.0, 1000.0);
631 fprintf(out, "#endif\n");
634 sprintf(buf, "%s/ions.itp", p);
636 if (fflib_fexist(buf))
638 fprintf(out, "; Include topology for ions\n");
639 fprintf(out, "#include \"%s\"\n", buf);
644 static void print_top_system(FILE *out, const char *title)
646 fprintf(out, "[ %s ]\n", dir2str(d_system));
647 fprintf(out, "; Name\n");
648 fprintf(out, "%s\n\n", title[0] ? title : "Protein");
651 void print_top_mols(FILE *out,
652 const char *title, const char *ffdir, const char *water,
653 int nincl, char **incls, int nmol, t_mols *mols)
660 fprintf(out, "; Include chain topologies\n");
661 for (i = 0; (i < nincl); i++)
663 incl = strrchr(incls[i], DIR_SEPARATOR);
670 /* Remove the path from the include name */
673 fprintf(out, "#include \"%s\"\n", incl);
680 print_top_water(out, ffdir, water);
682 print_top_system(out, title);
686 fprintf(out, "[ %s ]\n", dir2str(d_molecules));
687 fprintf(out, "; %-15s %5s\n", "Compound", "#mols");
688 for (i = 0; (i < nmol); i++)
690 fprintf(out, "%-15s %5d\n", mols[i].name, mols[i].nr);
695 void write_top(FILE *out, char *pr, char *molname,
696 t_atoms *at, gmx_bool bRTPresname,
697 int bts[], t_params plist[], t_excls excls[],
698 gpp_atomtype_t atype, int *cgnr, int nrexcl)
699 /* NOTE: nrexcl is not the size of *excl! */
701 if (at && atype && cgnr)
703 fprintf(out, "[ %s ]\n", dir2str(d_moleculetype));
704 fprintf(out, "; %-15s %5s\n", "Name", "nrexcl");
705 fprintf(out, "%-15s %5d\n\n", molname ? molname : "Protein", nrexcl);
707 print_atoms(out, atype, at, cgnr, bRTPresname);
708 print_bondeds(out, at->nr, d_bonds, F_BONDS, bts[ebtsBONDS], plist);
709 print_bondeds(out, at->nr, d_constraints, F_CONSTR, 0, plist);
710 print_bondeds(out, at->nr, d_constraints, F_CONSTRNC, 0, plist);
711 print_bondeds(out, at->nr, d_pairs, F_LJ14, 0, plist);
712 print_excl(out, at->nr, excls);
713 print_bondeds(out, at->nr, d_angles, F_ANGLES, bts[ebtsANGLES], plist);
714 print_bondeds(out, at->nr, d_dihedrals, F_PDIHS, bts[ebtsPDIHS], plist);
715 print_bondeds(out, at->nr, d_dihedrals, F_IDIHS, bts[ebtsIDIHS], plist);
716 print_bondeds(out, at->nr, d_cmap, F_CMAP, bts[ebtsCMAP], plist);
717 print_bondeds(out, at->nr, d_polarization, F_POLARIZATION, 0, plist);
718 print_bondeds(out, at->nr, d_thole_polarization, F_THOLE_POL, 0, plist);
719 print_bondeds(out, at->nr, d_vsites2, F_VSITE2, 0, plist);
720 print_bondeds(out, at->nr, d_vsites3, F_VSITE3, 0, plist);
721 print_bondeds(out, at->nr, d_vsites3, F_VSITE3FD, 0, plist);
722 print_bondeds(out, at->nr, d_vsites3, F_VSITE3FAD, 0, plist);
723 print_bondeds(out, at->nr, d_vsites3, F_VSITE3OUT, 0, plist);
724 print_bondeds(out, at->nr, d_vsites4, F_VSITE4FD, 0, plist);
725 print_bondeds(out, at->nr, d_vsites4, F_VSITE4FDN, 0, plist);
729 print_top_posre(out, pr);
736 static void do_ssbonds(t_params *ps, t_atoms *atoms,
737 int nssbonds, t_ssbond *ssbonds, gmx_bool bAllowMissing)
742 for (i = 0; (i < nssbonds); i++)
744 ri = ssbonds[i].res1;
745 rj = ssbonds[i].res2;
746 ai = search_res_atom(ssbonds[i].a1, ri, atoms,
747 "special bond", bAllowMissing);
748 aj = search_res_atom(ssbonds[i].a2, rj, atoms,
749 "special bond", bAllowMissing);
750 if ((ai == NO_ATID) || (aj == NO_ATID))
752 gmx_fatal(FARGS, "Trying to make impossible special bond (%s-%s)!",
753 ssbonds[i].a1, ssbonds[i].a2);
755 add_param(ps, ai, aj, NULL, NULL);
759 static void at2bonds(t_params *psb, t_hackblock *hb,
762 real long_bond_dist, real short_bond_dist)
766 real dist2, long_bond_dist2, short_bond_dist2;
769 long_bond_dist2 = sqr(long_bond_dist);
770 short_bond_dist2 = sqr(short_bond_dist);
781 fprintf(stderr, "Making bonds...\n");
783 for (resind = 0; (resind < atoms->nres) && (i < atoms->nr); resind++)
785 /* add bonds from list of bonded interactions */
786 for (j = 0; j < hb[resind].rb[ebtsBONDS].nb; j++)
788 /* Unfortunately we can not issue errors or warnings
789 * for missing atoms in bonds, as the hydrogens and terminal atoms
790 * have not been added yet.
792 ai = search_atom(hb[resind].rb[ebtsBONDS].b[j].a[0], i, atoms,
794 aj = search_atom(hb[resind].rb[ebtsBONDS].b[j].a[1], i, atoms,
796 if (ai != NO_ATID && aj != NO_ATID)
798 dist2 = distance2(x[ai], x[aj]);
799 if (dist2 > long_bond_dist2)
802 fprintf(stderr, "Warning: Long Bond (%d-%d = %g nm)\n",
803 ai+1, aj+1, sqrt(dist2));
805 else if (dist2 < short_bond_dist2)
807 fprintf(stderr, "Warning: Short Bond (%d-%d = %g nm)\n",
808 ai+1, aj+1, sqrt(dist2));
810 add_param(psb, ai, aj, NULL, hb[resind].rb[ebtsBONDS].b[j].s);
813 /* add bonds from list of hacks (each added atom gets a bond) */
814 while ( (i < atoms->nr) && (atoms->atom[i].resind == resind) )
816 for (j = 0; j < hb[resind].nhack; j++)
818 if ( ( hb[resind].hack[j].tp > 0 ||
819 hb[resind].hack[j].oname == NULL ) &&
820 strcmp(hb[resind].hack[j].a[0], *(atoms->atomname[i])) == 0)
822 switch (hb[resind].hack[j].tp)
824 case 9: /* COOH terminus */
825 add_param(psb, i, i+1, NULL, NULL); /* C-O */
826 add_param(psb, i, i+2, NULL, NULL); /* C-OA */
827 add_param(psb, i+2, i+3, NULL, NULL); /* OA-H */
830 for (k = 0; (k < hb[resind].hack[j].nr); k++)
832 add_param(psb, i, i+k+1, NULL, NULL);
839 /* we're now at the start of the next residue */
843 static int pcompar(const void *a, const void *b)
850 d = pa->a[0] - pb->a[0];
853 d = pa->a[1] - pb->a[1];
857 return strlen(pb->s) - strlen(pa->s);
865 static void clean_bonds(t_params *ps)
872 /* swap atomnumbers in bond if first larger than second: */
873 for (i = 0; (i < ps->nr); i++)
875 if (ps->param[i].a[1] < ps->param[i].a[0])
877 a = ps->param[i].a[0];
878 ps->param[i].a[0] = ps->param[i].a[1];
879 ps->param[i].a[1] = a;
884 qsort(ps->param, ps->nr, (size_t)sizeof(ps->param[0]), pcompar);
886 /* remove doubles, keep the first one always. */
888 for (i = 1; (i < ps->nr); i++)
890 if ((ps->param[i].a[0] != ps->param[j-1].a[0]) ||
891 (ps->param[i].a[1] != ps->param[j-1].a[1]) )
895 cp_param(&(ps->param[j]), &(ps->param[i]));
900 fprintf(stderr, "Number of bonds was %d, now %d\n", ps->nr, j);
905 fprintf(stderr, "No bonds\n");
909 void print_sums(t_atoms *atoms, gmx_bool bSystem)
917 where = " in system";
926 for (i = 0; (i < atoms->nr); i++)
928 m += atoms->atom[i].m;
929 qtot += atoms->atom[i].q;
932 fprintf(stderr, "Total mass%s %.3f a.m.u.\n", where, m);
933 fprintf(stderr, "Total charge%s %.3f e\n", where, qtot);
936 static void check_restp_type(const char *name, int t1, int t2)
940 gmx_fatal(FARGS, "Residues in one molecule have a different '%s' type: %d and %d", name, t1, t2);
944 static void check_restp_types(t_restp *r0, t_restp *r1)
948 check_restp_type("all dihedrals", r0->bKeepAllGeneratedDihedrals, r1->bKeepAllGeneratedDihedrals);
949 check_restp_type("nrexcl", r0->nrexcl, r1->nrexcl);
950 check_restp_type("HH14", r0->bGenerateHH14Interactions, r1->bGenerateHH14Interactions);
951 check_restp_type("remove dihedrals", r0->bRemoveDihedralIfWithImproper, r1->bRemoveDihedralIfWithImproper);
953 for (i = 0; i < ebtsNR; i++)
955 check_restp_type(btsNames[i], r0->rb[i].type, r1->rb[i].type);
959 void add_atom_to_restp(t_restp *restp, int at_start, const t_hack *hack)
963 const char *Hnum = "123456";
967 fprintf(debug,"adding atom(s) %s to atom %s in res %d%s in rtp\n",
969 * restp->atomname[at_start], resnr, restp->resname);
971 strcpy(buf, hack->nname);
972 buf[strlen(buf)+1] = '\0';
975 buf[strlen(buf)] = '-';
978 restp->natom += hack->nr;
979 srenew(restp->atom, restp->natom);
980 srenew(restp->atomname, restp->natom);
981 srenew(restp->cgnr, restp->natom);
983 for (k = restp->natom-1; k > at_start+hack->nr; k--)
986 restp->atom [k - hack->nr];
988 restp->atomname[k - hack->nr];
990 restp->cgnr [k - hack->nr];
993 for (k = 0; k < hack->nr; k++)
995 /* set counter in atomname */
998 buf[strlen(buf)-1] = Hnum[k];
1000 snew( restp->atomname[at_start+1+k], 1);
1001 restp->atom [at_start+1+k] = *hack->atom;
1002 *restp->atomname[at_start+1+k] = gmx_strdup(buf);
1003 if (hack->cgnr != NOTSET)
1005 restp->cgnr [at_start+1+k] = hack->cgnr;
1009 restp->cgnr [at_start+1+k] = restp->cgnr[at_start];
1014 void get_hackblocks_rtp(t_hackblock **hb, t_restp **restp,
1015 int nrtp, t_restp rtp[],
1016 int nres, t_resinfo *resinfo,
1018 t_hackblock **ntdb, t_hackblock **ctdb,
1029 /* first the termini */
1030 for (i = 0; i < nterpairs; i++)
1032 if (rn[i] >= 0 && ntdb[i] != NULL)
1034 copy_t_hackblock(ntdb[i], &(*hb)[rn[i]]);
1036 if (rc[i] >= 0 && ctdb[i] != NULL)
1038 merge_t_hackblock(ctdb[i], &(*hb)[rc[i]]);
1042 /* then the whole rtp */
1043 for (i = 0; i < nres; i++)
1045 /* Here we allow a mismatch of one character when looking for the rtp entry.
1046 * For such a mismatch there should be only one mismatching name.
1047 * This is mainly useful for small molecules such as ions.
1048 * Note that this will usually not work for protein, DNA and RNA,
1049 * since there the residue names should be listed in residuetypes.dat
1050 * and an error will have been generated earlier in the process.
1052 key = *resinfo[i].rtp;
1053 snew(resinfo[i].rtp, 1);
1054 *resinfo[i].rtp = search_rtp(key, nrtp, rtp);
1055 res = get_restp(*resinfo[i].rtp, nrtp, rtp);
1056 copy_t_restp(res, &(*restp)[i]);
1058 /* Check that we do not have different bonded types in one molecule */
1059 check_restp_types(&(*restp)[0], &(*restp)[i]);
1062 for (j = 0; j < nterpairs && tern == -1; j++)
1070 for (j = 0; j < nterpairs && terc == -1; j++)
1077 bRM = merge_t_bondeds(res->rb, (*hb)[i].rb, tern >= 0, terc >= 0);
1079 if (bRM && ((tern >= 0 && ntdb[tern] == NULL) ||
1080 (terc >= 0 && ctdb[terc] == NULL)))
1082 gmx_fatal(FARGS, "There is a dangling bond at at least one of the terminal ends and the force field does not provide terminal entries or files. Fix your terminal residues so that they match the residue database (.rtp) entries, or provide terminal database entries (.tdb).");
1084 if (bRM && ((tern >= 0 && ntdb[tern]->nhack == 0) ||
1085 (terc >= 0 && ctdb[terc]->nhack == 0)))
1087 gmx_fatal(FARGS, "There is a dangling bond at at least one of the terminal ends. Fix your coordinate file, add a new terminal database entry (.tdb), or select the proper existing terminal entry.");
1091 /* now perform t_hack's on t_restp's,
1092 i.e. add's and deletes from termini database will be
1093 added to/removed from residue topology
1094 we'll do this on one big dirty loop, so it won't make easy reading! */
1095 for (i = 0; i < nres; i++)
1097 for (j = 0; j < (*hb)[i].nhack; j++)
1099 if ( (*hb)[i].hack[j].nr)
1101 /* find atom in restp */
1102 for (l = 0; l < (*restp)[i].natom; l++)
1104 if ( ( (*hb)[i].hack[j].oname == NULL &&
1105 strcmp((*hb)[i].hack[j].a[0], *(*restp)[i].atomname[l]) == 0 ) ||
1106 ( (*hb)[i].hack[j].oname != NULL &&
1107 strcmp((*hb)[i].hack[j].oname, *(*restp)[i].atomname[l]) == 0 ) )
1112 if (l == (*restp)[i].natom)
1114 /* If we are doing an atom rename only, we don't need
1115 * to generate a fatal error if the old name is not found
1118 /* Deleting can happen also only on the input atoms,
1119 * not necessarily always on the rtp entry.
1121 if (!((*hb)[i].hack[j].oname != NULL &&
1122 (*hb)[i].hack[j].nname != NULL) &&
1123 !((*hb)[i].hack[j].oname != NULL &&
1124 (*hb)[i].hack[j].nname == NULL))
1127 "atom %s not found in buiding block %d%s "
1128 "while combining tdb and rtp",
1129 (*hb)[i].hack[j].oname != NULL ?
1130 (*hb)[i].hack[j].oname : (*hb)[i].hack[j].a[0],
1131 i+1, *resinfo[i].rtp);
1136 if ( (*hb)[i].hack[j].oname == NULL)
1139 add_atom_to_restp(&(*restp)[i], l, &(*hb)[i].hack[j]);
1144 if ( (*hb)[i].hack[j].nname == NULL)
1146 /* we're deleting */
1149 fprintf(debug, "deleting atom %s from res %d%s in rtp\n",
1150 *(*restp)[i].atomname[l],
1151 i+1, (*restp)[i].resname);
1153 /* shift the rest */
1154 (*restp)[i].natom--;
1155 for (k = l; k < (*restp)[i].natom; k++)
1157 (*restp)[i].atom [k] = (*restp)[i].atom [k+1];
1158 (*restp)[i].atomname[k] = (*restp)[i].atomname[k+1];
1159 (*restp)[i].cgnr [k] = (*restp)[i].cgnr [k+1];
1161 /* give back space */
1162 srenew((*restp)[i].atom, (*restp)[i].natom);
1163 srenew((*restp)[i].atomname, (*restp)[i].natom);
1164 srenew((*restp)[i].cgnr, (*restp)[i].natom);
1166 else /* nname != NULL */
1167 { /* we're replacing */
1170 fprintf(debug, "replacing atom %s by %s in res %d%s in rtp\n",
1171 *(*restp)[i].atomname[l], (*hb)[i].hack[j].nname,
1172 i+1, (*restp)[i].resname);
1174 snew( (*restp)[i].atomname[l], 1);
1175 (*restp)[i].atom[l] = *(*hb)[i].hack[j].atom;
1176 *(*restp)[i].atomname[l] = gmx_strdup((*hb)[i].hack[j].nname);
1177 if ( (*hb)[i].hack[j].cgnr != NOTSET)
1179 (*restp)[i].cgnr [l] = (*hb)[i].hack[j].cgnr;
1189 static gmx_bool atomname_cmp_nr(const char *anm, t_hack *hack, int *nr)
1196 return (gmx_strcasecmp(anm, hack->nname) == 0);
1200 if (isdigit(anm[strlen(anm)-1]))
1202 *nr = anm[strlen(anm)-1] - '0';
1208 if (*nr <= 0 || *nr > hack->nr)
1214 return (strlen(anm) == strlen(hack->nname) + 1 &&
1215 gmx_strncasecmp(anm, hack->nname, strlen(hack->nname)) == 0);
1220 static gmx_bool match_atomnames_with_rtp_atom(t_atoms *pdba, rvec *x, int atind,
1221 t_restp *rptr, t_hackblock *hbr,
1226 char *oldnm, *newnm;
1228 char *start_at, buf[STRLEN];
1230 gmx_bool bReplaceReplace, bFoundInAdd;
1233 oldnm = *pdba->atomname[atind];
1234 resnr = pdba->resinfo[pdba->atom[atind].resind].nr;
1237 for (j = 0; j < hbr->nhack; j++)
1239 if (hbr->hack[j].oname != NULL && hbr->hack[j].nname != NULL &&
1240 gmx_strcasecmp(oldnm, hbr->hack[j].oname) == 0)
1242 /* This is a replace entry. */
1243 /* Check if we are not replacing a replaced atom. */
1244 bReplaceReplace = FALSE;
1245 for (k = 0; k < hbr->nhack; k++)
1248 hbr->hack[k].oname != NULL && hbr->hack[k].nname != NULL &&
1249 gmx_strcasecmp(hbr->hack[k].nname, hbr->hack[j].oname) == 0)
1251 /* The replace in hack[j] replaces an atom that
1252 * was already replaced in hack[k], we do not want
1253 * second or higher level replaces at this stage.
1255 bReplaceReplace = TRUE;
1258 if (bReplaceReplace)
1260 /* Skip this replace. */
1264 /* This atom still has the old name, rename it */
1265 newnm = hbr->hack[j].nname;
1266 for (k = 0; k < rptr->natom; k++)
1268 if (gmx_strcasecmp(newnm, *rptr->atomname[k]) == 0)
1273 if (k == rptr->natom)
1275 /* The new name is not present in the rtp.
1276 * We need to apply the replace also to the rtp entry.
1279 /* We need to find the add hack that can add this atom
1280 * to find out after which atom it should be added.
1282 bFoundInAdd = FALSE;
1283 for (k = 0; k < hbr->nhack; k++)
1285 if (hbr->hack[k].oname == NULL &&
1286 hbr->hack[k].nname != NULL &&
1287 atomname_cmp_nr(newnm, &hbr->hack[k], &anmnr))
1291 start_at = hbr->hack[k].a[0];
1295 sprintf(buf, "%s%d", hbr->hack[k].nname, anmnr-1);
1298 for (start_nr = 0; start_nr < rptr->natom; start_nr++)
1300 if (gmx_strcasecmp(start_at, (*rptr->atomname[start_nr])) == 0)
1305 if (start_nr == rptr->natom)
1307 gmx_fatal(FARGS, "Could not find atom '%s' in residue building block '%s' to add atom '%s' to",
1308 start_at, rptr->resname, newnm);
1310 /* We can add the atom after atom start_nr */
1311 add_atom_to_restp(rptr, start_nr, &hbr->hack[j]);
1319 gmx_fatal(FARGS, "Could not find an 'add' entry for atom named '%s' corresponding to the 'replace' entry from atom name '%s' to '%s' for tdb or hdb database of residue type '%s'",
1321 hbr->hack[j].oname, hbr->hack[j].nname,
1328 printf("Renaming atom '%s' in residue '%s' %d to '%s'\n",
1329 oldnm, rptr->resname, resnr, newnm);
1331 /* Rename the atom in pdba */
1332 snew(pdba->atomname[atind], 1);
1333 *pdba->atomname[atind] = gmx_strdup(newnm);
1335 else if (hbr->hack[j].oname != NULL && hbr->hack[j].nname == NULL &&
1336 gmx_strcasecmp(oldnm, hbr->hack[j].oname) == 0)
1338 /* This is a delete entry, check if this atom is present
1339 * in the rtp entry of this residue.
1341 for (k = 0; k < rptr->natom; k++)
1343 if (gmx_strcasecmp(oldnm, *rptr->atomname[k]) == 0)
1348 if (k == rptr->natom)
1350 /* This atom is not present in the rtp entry,
1351 * delete is now from the input pdba.
1355 printf("Deleting atom '%s' in residue '%s' %d\n",
1356 oldnm, rptr->resname, resnr);
1358 /* We should free the atom name,
1359 * but it might be used multiple times in the symtab.
1360 * sfree(pdba->atomname[atind]);
1362 for (k = atind+1; k < pdba->nr; k++)
1364 pdba->atom[k-1] = pdba->atom[k];
1365 pdba->atomname[k-1] = pdba->atomname[k];
1366 copy_rvec(x[k], x[k-1]);
1377 void match_atomnames_with_rtp(t_restp restp[], t_hackblock hb[],
1378 t_atoms *pdba, rvec *x,
1385 for (i = 0; i < pdba->nr; i++)
1387 oldnm = *pdba->atomname[i];
1388 rptr = &restp[pdba->atom[i].resind];
1389 for (j = 0; (j < rptr->natom); j++)
1391 if (gmx_strcasecmp(oldnm, *(rptr->atomname[j])) == 0)
1396 if (j == rptr->natom)
1398 /* Not found yet, check if we have to rename this atom */
1399 if (match_atomnames_with_rtp_atom(pdba, x, i,
1400 rptr, &(hb[pdba->atom[i].resind]),
1403 /* We deleted this atom, decrease the atom counter by 1. */
1410 #define NUM_CMAP_ATOMS 5
1411 static void gen_cmap(t_params *psb, t_restp *restp, t_atoms *atoms)
1413 int residx, i, j, k;
1416 t_resinfo *resinfo = atoms->resinfo;
1417 int nres = atoms->nres;
1419 atom_id cmap_atomid[NUM_CMAP_ATOMS];
1420 int cmap_chainnum = -1, this_residue_index;
1431 fprintf(stderr, "Making cmap torsions...\n");
1433 /* Most cmap entries use the N atom from the next residue, so the last
1434 * residue should not have its CMAP entry in that case, but for things like
1435 * dipeptides we sometimes define a complete CMAP entry inside a residue,
1436 * and in this case we need to process everything through the last residue.
1438 for (residx = 0; residx < nres; residx++)
1440 /* Add CMAP terms from the list of CMAP interactions */
1441 for (j = 0; j < restp[residx].rb[ebtsCMAP].nb; j++)
1444 /* Loop over atoms in a candidate CMAP interaction and
1445 * check that they exist, are from the same chain and are
1446 * from residues labelled as protein. */
1447 for (k = 0; k < NUM_CMAP_ATOMS && bAddCMAP; k++)
1449 /* Assign the pointer to the name of the next reference atom.
1450 * This can use -/+ labels to refer to previous/next residue.
1452 pname = restp[residx].rb[ebtsCMAP].b[j].a[k];
1453 /* Skip this CMAP entry if it refers to residues before the
1454 * first or after the last residue.
1456 if (((strchr(pname, '-') != NULL) && (residx == 0)) ||
1457 ((strchr(pname, '+') != NULL) && (residx == nres-1)))
1463 cmap_atomid[k] = search_atom(pname,
1464 i, atoms, ptr, TRUE);
1465 bAddCMAP = bAddCMAP && (cmap_atomid[k] != NO_ATID);
1468 /* This break is necessary, because cmap_atomid[k]
1469 * == NO_ATID cannot be safely used as an index
1470 * into the atom array. */
1473 this_residue_index = atoms->atom[cmap_atomid[k]].resind;
1476 cmap_chainnum = resinfo[this_residue_index].chainnum;
1480 /* Does the residue for this atom have the same
1481 * chain number as the residues for previous
1483 bAddCMAP = bAddCMAP &&
1484 cmap_chainnum == resinfo[this_residue_index].chainnum;
1486 /* Here we used to check that the residuetype was protein and
1487 * disable bAddCMAP if that was not the case. However, some
1488 * special residues (say, alanine dipeptides) might not adhere
1489 * to standard naming, and if we start calling them normal
1490 * protein residues the user will be bugged to select termini.
1492 * Instead, I believe that the right course of action is to
1493 * keep the CMAP interaction if it is present in the RTP file
1494 * and we correctly identified all atoms (which is the case
1501 add_cmap_param(psb, cmap_atomid[0], cmap_atomid[1], cmap_atomid[2], cmap_atomid[3], cmap_atomid[4], restp[residx].rb[ebtsCMAP].b[j].s);
1505 if (residx < nres-1)
1507 while (atoms->atom[i].resind < residx+1)
1513 /* Start the next residue */
1517 scrub_charge_groups(int *cgnr, int natoms)
1521 for (i = 0; i < natoms; i++)
1528 void pdb2top(FILE *top_file, char *posre_fn, char *molname,
1529 t_atoms *atoms, rvec **x, gpp_atomtype_t atype, t_symtab *tab,
1530 int nrtp, t_restp rtp[],
1531 t_restp *restp, t_hackblock *hb,
1532 gmx_bool bAllowMissing,
1533 gmx_bool bVsites, gmx_bool bVsiteAromatics,
1536 int nssbonds, t_ssbond *ssbonds,
1537 real long_bond_dist, real short_bond_dist,
1538 gmx_bool bDeuterate, gmx_bool bChargeGroups, gmx_bool bCmap,
1539 gmx_bool bRenumRes, gmx_bool bRTPresname)
1545 t_params plist[F_NRE];
1552 gmx_residuetype_t*rt;
1555 gmx_residuetype_init(&rt);
1559 print_resall(debug, atoms->nres, restp, atype);
1560 dump_hb(debug, atoms->nres, hb);
1564 at2bonds(&(plist[F_BONDS]), hb,
1566 long_bond_dist, short_bond_dist);
1568 /* specbonds: disulphide bonds & heme-his */
1569 do_ssbonds(&(plist[F_BONDS]),
1570 atoms, nssbonds, ssbonds,
1573 nmissat = name2type(atoms, &cgnr, restp, rt);
1578 fprintf(stderr, "There were %d missing atoms in molecule %s\n",
1583 gmx_fatal(FARGS, "There were %d missing atoms in molecule %s, if you want to use this incomplete topology anyhow, use the option -missing",
1588 /* Cleanup bonds (sort and rm doubles) */
1589 clean_bonds(&(plist[F_BONDS]));
1591 snew(vsite_type, atoms->nr);
1592 for (i = 0; i < atoms->nr; i++)
1594 vsite_type[i] = NOTSET;
1598 /* determine which atoms will be vsites and add dummy masses
1599 also renumber atom numbers in plist[0..F_NRE]! */
1600 do_vsites(nrtp, rtp, atype, atoms, tab, x, plist,
1601 &vsite_type, &cgnr, mHmult, bVsiteAromatics, ffdir);
1604 /* Make Angles and Dihedrals */
1605 fprintf(stderr, "Generating angles, dihedrals and pairs...\n");
1606 snew(excls, atoms->nr);
1607 init_nnb(&nnb, atoms->nr, 4);
1608 gen_nnb(&nnb, plist);
1609 print_nnb(&nnb, "NNB");
1610 gen_pad(&nnb, atoms, restp, plist, excls, hb, bAllowMissing);
1616 gen_cmap(&(plist[F_CMAP]), restp, atoms);
1617 if (plist[F_CMAP].nr > 0)
1619 fprintf(stderr, "There are %4d cmap torsion pairs\n",
1624 /* set mass of all remaining hydrogen atoms */
1627 do_h_mass(&(plist[F_BONDS]), vsite_type, atoms, mHmult, bDeuterate);
1631 /* Cleanup bonds (sort and rm doubles) */
1632 /* clean_bonds(&(plist[F_BONDS]));*/
1635 "There are %4d dihedrals, %4d impropers, %4d angles\n"
1636 " %4d pairs, %4d bonds and %4d virtual sites\n",
1637 plist[F_PDIHS].nr, plist[F_IDIHS].nr, plist[F_ANGLES].nr,
1638 plist[F_LJ14].nr, plist[F_BONDS].nr,
1639 plist[F_VSITE2].nr +
1640 plist[F_VSITE3].nr +
1641 plist[F_VSITE3FD].nr +
1642 plist[F_VSITE3FAD].nr +
1643 plist[F_VSITE3OUT].nr +
1644 plist[F_VSITE4FD].nr +
1645 plist[F_VSITE4FDN].nr );
1647 print_sums(atoms, FALSE);
1649 if (FALSE == bChargeGroups)
1651 scrub_charge_groups(cgnr, atoms->nr);
1656 for (i = 0; i < atoms->nres; i++)
1658 atoms->resinfo[i].nr = i + 1;
1659 atoms->resinfo[i].ic = ' ';
1665 fprintf(stderr, "Writing topology\n");
1666 /* We can copy the bonded types from the first restp,
1667 * since the types have to be identical for all residues in one molecule.
1669 for (i = 0; i < ebtsNR; i++)
1671 bts[i] = restp[0].rb[i].type;
1673 write_top(top_file, posre_fn, molname,
1675 bts, plist, excls, atype, cgnr, restp[0].nrexcl);
1679 free_t_hackblock(atoms->nres, &hb);
1680 free_t_restp(atoms->nres, &restp);
1681 gmx_residuetype_destroy(rt);
1683 /* we should clean up hb and restp here, but that is a *L*O*T* of work! */
1685 for (i = 0; i < F_NRE; i++)
1687 sfree(plist[i].param);
1689 for (i = 0; i < atoms->nr; i++)