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/math/vec.h"
47 #include "gromacs/utility/futil.h"
49 #include "gpp_nextnb.h"
56 #include "gromacs/utility/cstringutil.h"
57 #include "gromacs/fileio/pdbio.h"
59 #include "gromacs/fileio/filenm.h"
60 #include "gen_vsite.h"
63 #include "fflibutil.h"
66 #include "gromacs/fileio/strdb.h"
67 #include "gromacs/topology/residuetypes.h"
68 #include "gromacs/topology/symtab.h"
69 #include "gromacs/utility/exceptions.h"
70 #include "gromacs/utility/fatalerror.h"
71 #include "gromacs/utility/programcontext.h"
72 #include "gromacs/utility/smalloc.h"
74 /* this must correspond to enum in pdb2top.h */
75 const char *hh[ehisNR] = { "HISD", "HISE", "HISH", "HIS1" };
77 static int missing_atoms(t_restp *rp, int resind, t_atoms *at, int i0, int i)
84 for (j = 0; j < rp->natom; j++)
86 name = *(rp->atomname[j]);
88 for (k = i0; k < i; k++)
90 bFound = (bFound || !gmx_strcasecmp(*(at->atomname[k]), name));
95 fprintf(stderr, "\nWARNING: "
96 "atom %s is missing in residue %s %d in the pdb file\n",
97 name, *(at->resinfo[resind].name), at->resinfo[resind].nr);
98 if (name[0] == 'H' || name[0] == 'h')
100 fprintf(stderr, " You might need to add atom %s to the hydrogen database of building block %s\n"
101 " in the file %s.hdb (see the manual)\n",
102 name, *(at->resinfo[resind].rtp), rp->filebase);
104 fprintf(stderr, "\n");
111 gmx_bool is_int(double x)
113 const double tol = 1e-4;
122 return (fabs(x-ix) < tol);
125 static void swap_strings(char **s, int i, int j)
135 choose_ff(const char *ffsel,
136 char *forcefield, int ff_maxlen,
137 char *ffdir, int ffdir_maxlen)
140 char **ffdirs, **ffs, **ffs_dir, *ptr;
141 int i, j, sel, cwdsel, nfound;
142 char buf[STRLEN], **desc;
146 nff = fflib_search_file_in_dirend(fflib_forcefield_itp(),
147 fflib_forcefield_dir_ext(),
152 gmx_fatal(FARGS, "No force fields found (files with name '%s' in subdirectories ending on '%s')",
153 fflib_forcefield_itp(), fflib_forcefield_dir_ext());
156 /* Replace with unix path separators */
157 if (DIR_SEPARATOR != '/')
159 for (i = 0; i < nff; i++)
161 while ( (ptr = strchr(ffdirs[i], DIR_SEPARATOR)) != NULL)
168 /* Store the force field names in ffs */
171 for (i = 0; i < nff; i++)
173 /* Remove the path from the ffdir name - use our unix standard here! */
174 ptr = strrchr(ffdirs[i], '/');
177 ffs[i] = strdup(ffdirs[i]);
178 ffs_dir[i] = low_gmxlibfn(ffdirs[i], FALSE, FALSE);
179 if (ffs_dir[i] == NULL)
181 gmx_fatal(FARGS, "Can no longer find file '%s'", ffdirs[i]);
186 ffs[i] = strdup(ptr+1);
187 ffs_dir[i] = strdup(ffdirs[i]);
189 ffs_dir[i][strlen(ffs_dir[i])-strlen(ffs[i])-1] = '\0';
190 /* Remove the extension from the ffdir name */
191 ffs[i][strlen(ffs[i])-strlen(fflib_forcefield_dir_ext())] = '\0';
199 for (i = 0; i < nff; i++)
201 if (strcmp(ffs[i], ffsel) == 0)
203 /* Matching ff name */
207 if (strncmp(ffs_dir[i], ".", 1) == 0)
224 "Force field '%s' occurs in %d places. pdb2gmx is using the one in the\n"
225 "current directory. Use interactive selection (not the -ff option) if\n"
226 "you would prefer a different one.\n", ffsel, nfound);
231 "Force field '%s' occurs in %d places, but not in the current directory.\n"
232 "Run without the -ff switch and select the force field interactively.", ffsel, nfound);
235 else if (nfound == 0)
237 gmx_fatal(FARGS, "Could not find force field '%s' in current directory, install tree or GMXDATA path.", ffsel);
243 for (i = 0; (i < nff); i++)
245 sprintf(buf, "%s%c%s%s%c%s",
246 ffs_dir[i], DIR_SEPARATOR,
247 ffs[i], fflib_forcefield_dir_ext(), DIR_SEPARATOR,
248 fflib_forcefield_doc());
251 /* We don't use fflib_open, because we don't want printf's */
252 fp = gmx_ffopen(buf, "r");
253 snew(desc[i], STRLEN);
254 get_a_line(fp, desc[i], STRLEN);
259 desc[i] = strdup(ffs[i]);
262 /* Order force fields from the same dir alphabetically
263 * and put deprecated force fields at the end.
265 for (i = 0; (i < nff); i++)
267 for (j = i+1; (j < nff); j++)
269 if (strcmp(ffs_dir[i], ffs_dir[j]) == 0 &&
270 ((desc[i][0] == '[' && desc[j][0] != '[') ||
271 ((desc[i][0] == '[' || desc[j][0] != '[') &&
272 gmx_strcasecmp(desc[i], desc[j]) > 0)))
274 swap_strings(ffdirs, i, j);
275 swap_strings(ffs, i, j);
276 swap_strings(desc, i, j);
281 printf("\nSelect the Force Field:\n");
282 for (i = 0; (i < nff); i++)
284 if (i == 0 || strcmp(ffs_dir[i-1], ffs_dir[i]) != 0)
286 if (strcmp(ffs_dir[i], ".") == 0)
288 printf("From current directory:\n");
292 printf("From '%s':\n", ffs_dir[i]);
295 printf("%2d: %s\n", i+1, desc[i]);
303 pret = fgets(buf, STRLEN, stdin);
307 sel = strtol(buf, NULL, 10);
311 while (pret == NULL || (sel < 0) || (sel >= nff));
313 /* Check for a current limitation of the fflib code.
314 * It will always read from the first ff directory in the list.
315 * This check assumes that the order of ffs matches the order
316 * in which fflib_open searches ff library files.
318 for (i = 0; i < sel; i++)
320 if (strcmp(ffs[i], ffs[sel]) == 0)
322 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.",
323 ffs[sel], fflib_forcefield_dir_ext());
332 if (strlen(ffs[sel]) >= (size_t)ff_maxlen)
334 gmx_fatal(FARGS, "Length of force field name (%d) >= maxlen (%d)",
335 strlen(ffs[sel]), ff_maxlen);
337 strcpy(forcefield, ffs[sel]);
339 if (strlen(ffdirs[sel]) >= (size_t)ffdir_maxlen)
341 gmx_fatal(FARGS, "Length of force field dir (%d) >= maxlen (%d)",
342 strlen(ffdirs[sel]), ffdir_maxlen);
344 strcpy(ffdir, ffdirs[sel]);
346 for (i = 0; (i < nff); i++)
357 void choose_watermodel(const char *wmsel, const char *ffdir,
360 const char *fn_watermodels = "watermodels.dat";
361 char fn_list[STRLEN];
368 if (strcmp(wmsel, "none") == 0)
374 else if (strcmp(wmsel, "select") != 0)
376 *watermodel = strdup(wmsel);
381 sprintf(fn_list, "%s%c%s", ffdir, DIR_SEPARATOR, fn_watermodels);
383 if (!fflib_fexist(fn_list))
385 fprintf(stderr, "No file '%s' found, will not include a water model\n",
392 fp = fflib_open(fn_list);
393 printf("\nSelect the Water Model:\n");
396 while (get_a_line(fp, buf, STRLEN))
398 srenew(model, nwm+1);
399 snew(model[nwm], STRLEN);
400 sscanf(buf, "%s%n", model[nwm], &i);
404 fprintf(stderr, "%2d: %s\n", nwm+1, buf+i);
413 fprintf(stderr, "%2d: %s\n", nwm+1, "None");
418 pret = fgets(buf, STRLEN, stdin);
422 sel = strtol(buf, NULL, 10);
426 while (pret == NULL || sel < 0 || sel > nwm);
434 *watermodel = strdup(model[sel]);
437 for (i = 0; i < nwm; i++)
444 static int name2type(t_atoms *at, int **cgnr,
445 t_restp restp[], gmx_residuetype_t *rt)
447 int i, j, prevresind, resind, i0, prevcg, cg, curcg;
465 for (i = 0; (i < at->nr); i++)
468 if (at->atom[i].resind != resind)
471 resind = at->atom[i].resind;
472 bProt = gmx_residuetype_is_protein(rt, *(at->resinfo[resind].name));
473 bNterm = bProt && (resind == 0);
476 nmissat += missing_atoms(&restp[prevresind], prevresind, at, i0, i);
480 if (at->atom[i].m == 0)
484 fprintf(debug, "atom %d%s: curcg=%d, prevcg=%d, cg=%d\n",
485 i+1, *(at->atomname[i]), curcg, prevcg,
486 j == NOTSET ? NOTSET : restp[resind].cgnr[j]);
490 name = *(at->atomname[i]);
491 j = search_jtype(&restp[resind], name, bNterm);
492 at->atom[i].type = restp[resind].atom[j].type;
493 at->atom[i].q = restp[resind].atom[j].q;
494 at->atom[i].m = restp[resind].atom[j].m;
495 cg = restp[resind].cgnr[j];
496 /* A charge group number -1 signals a separate charge group
499 if ( (cg == -1) || (cg != prevcg) || (resind != prevresind) )
508 fprintf(debug, "atom %d%s: curcg=%d, qt=%g, is_int=%d\n",
509 i+1, *(at->atomname[i]), curcg, qt, is_int(qt));
520 at->atom[i].typeB = at->atom[i].type;
521 at->atom[i].qB = at->atom[i].q;
522 at->atom[i].mB = at->atom[i].m;
524 nmissat += missing_atoms(&restp[resind], resind, at, i0, i);
529 static void print_top_heavy_H(FILE *out, real mHmult)
533 fprintf(out, "; Using deuterium instead of hydrogen\n\n");
535 else if (mHmult == 4.0)
537 fprintf(out, "#define HEAVY_H\n\n");
539 else if (mHmult != 1.0)
541 fprintf(stderr, "WARNING: unsupported proton mass multiplier (%g) "
542 "in pdb2top\n", mHmult);
546 void print_top_comment(FILE *out,
547 const char *filename,
551 char ffdir_parent[STRLEN];
554 nice_header(out, filename);
555 fprintf(out, ";\tThis is a %s topology file\n;\n", bITP ? "include" : "standalone");
558 gmx::BinaryInformationSettings settings;
559 settings.generatedByHeader(true);
560 settings.linePrefix(";\t");
561 gmx::printBinaryInformation(out, gmx::getProgramContext(), settings);
563 GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
565 if (strchr(ffdir, '/') == NULL)
567 fprintf(out, ";\tForce field was read from the standard Gromacs share directory.\n;\n\n");
569 else if (ffdir[0] == '.')
571 fprintf(out, ";\tForce field was read from current directory or a relative path - path added.\n;\n\n");
575 strncpy(ffdir_parent, ffdir, STRLEN-1);
576 ffdir_parent[STRLEN-1] = '\0'; /*make sure it is 0-terminated even for long string*/
577 p = strrchr(ffdir_parent, '/');
582 ";\tForce field data was read from:\n"
586 ";\tThis might be a non-standard force field location. When you use this topology, the\n"
587 ";\tforce field must either be present in the current directory, or the location\n"
588 ";\tspecified in the GMXLIB path variable or with the 'include' mdp file option.\n;\n\n",
593 void print_top_header(FILE *out, const char *filename,
594 gmx_bool bITP, const char *ffdir, real mHmult)
598 print_top_comment(out, filename, ffdir, bITP);
600 print_top_heavy_H(out, mHmult);
601 fprintf(out, "; Include forcefield parameters\n");
603 p = strrchr(ffdir, '/');
604 p = (ffdir[0] == '.' || p == NULL) ? ffdir : p+1;
606 fprintf(out, "#include \"%s/%s\"\n\n", p, fflib_forcefield_itp());
609 static void print_top_posre(FILE *out, const char *pr)
611 fprintf(out, "; Include Position restraint file\n");
612 fprintf(out, "#ifdef POSRES\n");
613 fprintf(out, "#include \"%s\"\n", pr);
614 fprintf(out, "#endif\n\n");
617 static void print_top_water(FILE *out, const char *ffdir, const char *water)
622 fprintf(out, "; Include water topology\n");
624 p = strrchr(ffdir, '/');
625 p = (ffdir[0] == '.' || p == NULL) ? ffdir : p+1;
626 fprintf(out, "#include \"%s/%s.itp\"\n", p, water);
629 fprintf(out, "#ifdef POSRES_WATER\n");
630 fprintf(out, "; Position restraint for each water oxygen\n");
631 fprintf(out, "[ position_restraints ]\n");
632 fprintf(out, ";%3s %5s %9s %10s %10s\n", "i", "funct", "fcx", "fcy", "fcz");
633 fprintf(out, "%4d %4d %10g %10g %10g\n", 1, 1, 1000.0, 1000.0, 1000.0);
634 fprintf(out, "#endif\n");
637 sprintf(buf, "%s/ions.itp", p);
639 if (fflib_fexist(buf))
641 fprintf(out, "; Include topology for ions\n");
642 fprintf(out, "#include \"%s\"\n", buf);
647 static void print_top_system(FILE *out, const char *title)
649 fprintf(out, "[ %s ]\n", dir2str(d_system));
650 fprintf(out, "; Name\n");
651 fprintf(out, "%s\n\n", title[0] ? title : "Protein");
654 void print_top_mols(FILE *out,
655 const char *title, const char *ffdir, const char *water,
656 int nincl, char **incls, int nmol, t_mols *mols)
663 fprintf(out, "; Include chain topologies\n");
664 for (i = 0; (i < nincl); i++)
666 incl = strrchr(incls[i], DIR_SEPARATOR);
673 /* Remove the path from the include name */
676 fprintf(out, "#include \"%s\"\n", incl);
683 print_top_water(out, ffdir, water);
685 print_top_system(out, title);
689 fprintf(out, "[ %s ]\n", dir2str(d_molecules));
690 fprintf(out, "; %-15s %5s\n", "Compound", "#mols");
691 for (i = 0; (i < nmol); i++)
693 fprintf(out, "%-15s %5d\n", mols[i].name, mols[i].nr);
698 void write_top(FILE *out, char *pr, char *molname,
699 t_atoms *at, gmx_bool bRTPresname,
700 int bts[], t_params plist[], t_excls excls[],
701 gpp_atomtype_t atype, int *cgnr, int nrexcl)
702 /* NOTE: nrexcl is not the size of *excl! */
704 if (at && atype && cgnr)
706 fprintf(out, "[ %s ]\n", dir2str(d_moleculetype));
707 fprintf(out, "; %-15s %5s\n", "Name", "nrexcl");
708 fprintf(out, "%-15s %5d\n\n", molname ? molname : "Protein", nrexcl);
710 print_atoms(out, atype, at, cgnr, bRTPresname);
711 print_bondeds(out, at->nr, d_bonds, F_BONDS, bts[ebtsBONDS], plist);
712 print_bondeds(out, at->nr, d_constraints, F_CONSTR, 0, plist);
713 print_bondeds(out, at->nr, d_constraints, F_CONSTRNC, 0, plist);
714 print_bondeds(out, at->nr, d_pairs, F_LJ14, 0, plist);
715 print_excl(out, at->nr, excls);
716 print_bondeds(out, at->nr, d_angles, F_ANGLES, bts[ebtsANGLES], plist);
717 print_bondeds(out, at->nr, d_dihedrals, F_PDIHS, bts[ebtsPDIHS], plist);
718 print_bondeds(out, at->nr, d_dihedrals, F_IDIHS, bts[ebtsIDIHS], plist);
719 print_bondeds(out, at->nr, d_cmap, F_CMAP, bts[ebtsCMAP], plist);
720 print_bondeds(out, at->nr, d_polarization, F_POLARIZATION, 0, plist);
721 print_bondeds(out, at->nr, d_thole_polarization, F_THOLE_POL, 0, plist);
722 print_bondeds(out, at->nr, d_vsites2, F_VSITE2, 0, plist);
723 print_bondeds(out, at->nr, d_vsites3, F_VSITE3, 0, plist);
724 print_bondeds(out, at->nr, d_vsites3, F_VSITE3FD, 0, plist);
725 print_bondeds(out, at->nr, d_vsites3, F_VSITE3FAD, 0, plist);
726 print_bondeds(out, at->nr, d_vsites3, F_VSITE3OUT, 0, plist);
727 print_bondeds(out, at->nr, d_vsites4, F_VSITE4FD, 0, plist);
728 print_bondeds(out, at->nr, d_vsites4, F_VSITE4FDN, 0, plist);
732 print_top_posre(out, pr);
737 static atom_id search_res_atom(const char *type, int resind,
739 const char *bondtype, gmx_bool bAllowMissing)
743 for (i = 0; (i < atoms->nr); i++)
745 if (atoms->atom[i].resind == resind)
747 return search_atom(type, i, atoms, bondtype, bAllowMissing);
754 static void do_ssbonds(t_params *ps, t_atoms *atoms,
755 int nssbonds, t_ssbond *ssbonds, gmx_bool bAllowMissing)
760 for (i = 0; (i < nssbonds); i++)
762 ri = ssbonds[i].res1;
763 rj = ssbonds[i].res2;
764 ai = search_res_atom(ssbonds[i].a1, ri, atoms,
765 "special bond", bAllowMissing);
766 aj = search_res_atom(ssbonds[i].a2, rj, atoms,
767 "special bond", bAllowMissing);
768 if ((ai == NO_ATID) || (aj == NO_ATID))
770 gmx_fatal(FARGS, "Trying to make impossible special bond (%s-%s)!",
771 ssbonds[i].a1, ssbonds[i].a2);
773 add_param(ps, ai, aj, NULL, NULL);
777 static void at2bonds(t_params *psb, t_hackblock *hb,
780 real long_bond_dist, real short_bond_dist)
784 real dist2, long_bond_dist2, short_bond_dist2;
787 long_bond_dist2 = sqr(long_bond_dist);
788 short_bond_dist2 = sqr(short_bond_dist);
799 fprintf(stderr, "Making bonds...\n");
801 for (resind = 0; (resind < atoms->nres) && (i < atoms->nr); resind++)
803 /* add bonds from list of bonded interactions */
804 for (j = 0; j < hb[resind].rb[ebtsBONDS].nb; j++)
806 /* Unfortunately we can not issue errors or warnings
807 * for missing atoms in bonds, as the hydrogens and terminal atoms
808 * have not been added yet.
810 ai = search_atom(hb[resind].rb[ebtsBONDS].b[j].a[0], i, atoms,
812 aj = search_atom(hb[resind].rb[ebtsBONDS].b[j].a[1], i, atoms,
814 if (ai != NO_ATID && aj != NO_ATID)
816 dist2 = distance2(x[ai], x[aj]);
817 if (dist2 > long_bond_dist2)
819 fprintf(stderr, "Warning: Long Bond (%d-%d = %g nm)\n",
820 ai+1, aj+1, sqrt(dist2));
822 else if (dist2 < short_bond_dist2)
824 fprintf(stderr, "Warning: Short Bond (%d-%d = %g nm)\n",
825 ai+1, aj+1, sqrt(dist2));
827 add_param(psb, ai, aj, NULL, hb[resind].rb[ebtsBONDS].b[j].s);
830 /* add bonds from list of hacks (each added atom gets a bond) */
831 while ( (i < atoms->nr) && (atoms->atom[i].resind == resind) )
833 for (j = 0; j < hb[resind].nhack; j++)
835 if ( ( hb[resind].hack[j].tp > 0 ||
836 hb[resind].hack[j].oname == NULL ) &&
837 strcmp(hb[resind].hack[j].a[0], *(atoms->atomname[i])) == 0)
839 switch (hb[resind].hack[j].tp)
841 case 9: /* COOH terminus */
842 add_param(psb, i, i+1, NULL, NULL); /* C-O */
843 add_param(psb, i, i+2, NULL, NULL); /* C-OA */
844 add_param(psb, i+2, i+3, NULL, NULL); /* OA-H */
847 for (k = 0; (k < hb[resind].hack[j].nr); k++)
849 add_param(psb, i, i+k+1, NULL, NULL);
856 /* we're now at the start of the next residue */
860 static int pcompar(const void *a, const void *b)
867 d = pa->a[0] - pb->a[0];
870 d = pa->a[1] - pb->a[1];
874 return strlen(pb->s) - strlen(pa->s);
882 static void clean_bonds(t_params *ps)
889 /* swap atomnumbers in bond if first larger than second: */
890 for (i = 0; (i < ps->nr); i++)
892 if (ps->param[i].a[1] < ps->param[i].a[0])
894 a = ps->param[i].a[0];
895 ps->param[i].a[0] = ps->param[i].a[1];
896 ps->param[i].a[1] = a;
901 qsort(ps->param, ps->nr, (size_t)sizeof(ps->param[0]), pcompar);
903 /* remove doubles, keep the first one always. */
905 for (i = 1; (i < ps->nr); i++)
907 if ((ps->param[i].a[0] != ps->param[j-1].a[0]) ||
908 (ps->param[i].a[1] != ps->param[j-1].a[1]) )
912 cp_param(&(ps->param[j]), &(ps->param[i]));
917 fprintf(stderr, "Number of bonds was %d, now %d\n", ps->nr, j);
922 fprintf(stderr, "No bonds\n");
926 void print_sums(t_atoms *atoms, gmx_bool bSystem)
934 where = " in system";
943 for (i = 0; (i < atoms->nr); i++)
945 m += atoms->atom[i].m;
946 qtot += atoms->atom[i].q;
949 fprintf(stderr, "Total mass%s %.3f a.m.u.\n", where, m);
950 fprintf(stderr, "Total charge%s %.3f e\n", where, qtot);
953 static void check_restp_type(const char *name, int t1, int t2)
957 gmx_fatal(FARGS, "Residues in one molecule have a different '%s' type: %d and %d", name, t1, t2);
961 static void check_restp_types(t_restp *r0, t_restp *r1)
965 check_restp_type("all dihedrals", r0->bKeepAllGeneratedDihedrals, r1->bKeepAllGeneratedDihedrals);
966 check_restp_type("nrexcl", r0->nrexcl, r1->nrexcl);
967 check_restp_type("HH14", r0->bGenerateHH14Interactions, r1->bGenerateHH14Interactions);
968 check_restp_type("remove dihedrals", r0->bRemoveDihedralIfWithImproper, r1->bRemoveDihedralIfWithImproper);
970 for (i = 0; i < ebtsNR; i++)
972 check_restp_type(btsNames[i], r0->rb[i].type, r1->rb[i].type);
976 void add_atom_to_restp(t_restp *restp, int at_start, const t_hack *hack)
980 const char *Hnum = "123456";
984 fprintf(debug,"adding atom(s) %s to atom %s in res %d%s in rtp\n",
986 * restp->atomname[at_start], resnr, restp->resname);
988 strcpy(buf, hack->nname);
989 buf[strlen(buf)+1] = '\0';
992 buf[strlen(buf)] = '-';
995 restp->natom += hack->nr;
996 srenew(restp->atom, restp->natom);
997 srenew(restp->atomname, restp->natom);
998 srenew(restp->cgnr, restp->natom);
1000 for (k = restp->natom-1; k > at_start+hack->nr; k--)
1003 restp->atom [k - hack->nr];
1004 restp->atomname[k] =
1005 restp->atomname[k - hack->nr];
1007 restp->cgnr [k - hack->nr];
1010 for (k = 0; k < hack->nr; k++)
1012 /* set counter in atomname */
1015 buf[strlen(buf)-1] = Hnum[k];
1017 snew( restp->atomname[at_start+1+k], 1);
1018 restp->atom [at_start+1+k] = *hack->atom;
1019 *restp->atomname[at_start+1+k] = strdup(buf);
1020 if (hack->cgnr != NOTSET)
1022 restp->cgnr [at_start+1+k] = hack->cgnr;
1026 restp->cgnr [at_start+1+k] = restp->cgnr[at_start];
1031 void get_hackblocks_rtp(t_hackblock **hb, t_restp **restp,
1032 int nrtp, t_restp rtp[],
1033 int nres, t_resinfo *resinfo,
1035 t_hackblock **ntdb, t_hackblock **ctdb,
1046 /* first the termini */
1047 for (i = 0; i < nterpairs; i++)
1049 if (rn[i] >= 0 && ntdb[i] != NULL)
1051 copy_t_hackblock(ntdb[i], &(*hb)[rn[i]]);
1053 if (rc[i] >= 0 && ctdb[i] != NULL)
1055 merge_t_hackblock(ctdb[i], &(*hb)[rc[i]]);
1059 /* then the whole rtp */
1060 for (i = 0; i < nres; i++)
1062 /* Here we allow a mismatch of one character when looking for the rtp entry.
1063 * For such a mismatch there should be only one mismatching name.
1064 * This is mainly useful for small molecules such as ions.
1065 * Note that this will usually not work for protein, DNA and RNA,
1066 * since there the residue names should be listed in residuetypes.dat
1067 * and an error will have been generated earlier in the process.
1069 key = *resinfo[i].rtp;
1070 snew(resinfo[i].rtp, 1);
1071 *resinfo[i].rtp = search_rtp(key, nrtp, rtp);
1072 res = get_restp(*resinfo[i].rtp, nrtp, rtp);
1073 copy_t_restp(res, &(*restp)[i]);
1075 /* Check that we do not have different bonded types in one molecule */
1076 check_restp_types(&(*restp)[0], &(*restp)[i]);
1079 for (j = 0; j < nterpairs && tern == -1; j++)
1087 for (j = 0; j < nterpairs && terc == -1; j++)
1094 bRM = merge_t_bondeds(res->rb, (*hb)[i].rb, tern >= 0, terc >= 0);
1096 if (bRM && ((tern >= 0 && ntdb[tern] == NULL) ||
1097 (terc >= 0 && ctdb[terc] == NULL)))
1099 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).");
1101 if (bRM && ((tern >= 0 && ntdb[tern]->nhack == 0) ||
1102 (terc >= 0 && ctdb[terc]->nhack == 0)))
1104 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.");
1108 /* now perform t_hack's on t_restp's,
1109 i.e. add's and deletes from termini database will be
1110 added to/removed from residue topology
1111 we'll do this on one big dirty loop, so it won't make easy reading! */
1112 for (i = 0; i < nres; i++)
1114 for (j = 0; j < (*hb)[i].nhack; j++)
1116 if ( (*hb)[i].hack[j].nr)
1118 /* find atom in restp */
1119 for (l = 0; l < (*restp)[i].natom; l++)
1121 if ( ( (*hb)[i].hack[j].oname == NULL &&
1122 strcmp((*hb)[i].hack[j].a[0], *(*restp)[i].atomname[l]) == 0 ) ||
1123 ( (*hb)[i].hack[j].oname != NULL &&
1124 strcmp((*hb)[i].hack[j].oname, *(*restp)[i].atomname[l]) == 0 ) )
1129 if (l == (*restp)[i].natom)
1131 /* If we are doing an atom rename only, we don't need
1132 * to generate a fatal error if the old name is not found
1135 /* Deleting can happen also only on the input atoms,
1136 * not necessarily always on the rtp entry.
1138 if (!((*hb)[i].hack[j].oname != NULL &&
1139 (*hb)[i].hack[j].nname != NULL) &&
1140 !((*hb)[i].hack[j].oname != NULL &&
1141 (*hb)[i].hack[j].nname == NULL))
1144 "atom %s not found in buiding block %d%s "
1145 "while combining tdb and rtp",
1146 (*hb)[i].hack[j].oname != NULL ?
1147 (*hb)[i].hack[j].oname : (*hb)[i].hack[j].a[0],
1148 i+1, *resinfo[i].rtp);
1153 if ( (*hb)[i].hack[j].oname == NULL)
1156 add_atom_to_restp(&(*restp)[i], l, &(*hb)[i].hack[j]);
1161 if ( (*hb)[i].hack[j].nname == NULL)
1163 /* we're deleting */
1166 fprintf(debug, "deleting atom %s from res %d%s in rtp\n",
1167 *(*restp)[i].atomname[l],
1168 i+1, (*restp)[i].resname);
1170 /* shift the rest */
1171 (*restp)[i].natom--;
1172 for (k = l; k < (*restp)[i].natom; k++)
1174 (*restp)[i].atom [k] = (*restp)[i].atom [k+1];
1175 (*restp)[i].atomname[k] = (*restp)[i].atomname[k+1];
1176 (*restp)[i].cgnr [k] = (*restp)[i].cgnr [k+1];
1178 /* give back space */
1179 srenew((*restp)[i].atom, (*restp)[i].natom);
1180 srenew((*restp)[i].atomname, (*restp)[i].natom);
1181 srenew((*restp)[i].cgnr, (*restp)[i].natom);
1183 else /* nname != NULL */
1184 { /* we're replacing */
1187 fprintf(debug, "replacing atom %s by %s in res %d%s in rtp\n",
1188 *(*restp)[i].atomname[l], (*hb)[i].hack[j].nname,
1189 i+1, (*restp)[i].resname);
1191 snew( (*restp)[i].atomname[l], 1);
1192 (*restp)[i].atom[l] = *(*hb)[i].hack[j].atom;
1193 *(*restp)[i].atomname[l] = strdup((*hb)[i].hack[j].nname);
1194 if ( (*hb)[i].hack[j].cgnr != NOTSET)
1196 (*restp)[i].cgnr [l] = (*hb)[i].hack[j].cgnr;
1206 static gmx_bool atomname_cmp_nr(const char *anm, t_hack *hack, int *nr)
1213 return (gmx_strcasecmp(anm, hack->nname) == 0);
1217 if (isdigit(anm[strlen(anm)-1]))
1219 *nr = anm[strlen(anm)-1] - '0';
1225 if (*nr <= 0 || *nr > hack->nr)
1231 return (strlen(anm) == strlen(hack->nname) + 1 &&
1232 gmx_strncasecmp(anm, hack->nname, strlen(hack->nname)) == 0);
1237 static gmx_bool match_atomnames_with_rtp_atom(t_atoms *pdba, rvec *x, int atind,
1238 t_restp *rptr, t_hackblock *hbr,
1243 char *oldnm, *newnm;
1245 char *start_at, buf[STRLEN];
1247 gmx_bool bReplaceReplace, bFoundInAdd;
1250 oldnm = *pdba->atomname[atind];
1251 resnr = pdba->resinfo[pdba->atom[atind].resind].nr;
1254 for (j = 0; j < hbr->nhack; j++)
1256 if (hbr->hack[j].oname != NULL && hbr->hack[j].nname != NULL &&
1257 gmx_strcasecmp(oldnm, hbr->hack[j].oname) == 0)
1259 /* This is a replace entry. */
1260 /* Check if we are not replacing a replaced atom. */
1261 bReplaceReplace = FALSE;
1262 for (k = 0; k < hbr->nhack; k++)
1265 hbr->hack[k].oname != NULL && hbr->hack[k].nname != NULL &&
1266 gmx_strcasecmp(hbr->hack[k].nname, hbr->hack[j].oname) == 0)
1268 /* The replace in hack[j] replaces an atom that
1269 * was already replaced in hack[k], we do not want
1270 * second or higher level replaces at this stage.
1272 bReplaceReplace = TRUE;
1275 if (bReplaceReplace)
1277 /* Skip this replace. */
1281 /* This atom still has the old name, rename it */
1282 newnm = hbr->hack[j].nname;
1283 for (k = 0; k < rptr->natom; k++)
1285 if (gmx_strcasecmp(newnm, *rptr->atomname[k]) == 0)
1290 if (k == rptr->natom)
1292 /* The new name is not present in the rtp.
1293 * We need to apply the replace also to the rtp entry.
1296 /* We need to find the add hack that can add this atom
1297 * to find out after which atom it should be added.
1299 bFoundInAdd = FALSE;
1300 for (k = 0; k < hbr->nhack; k++)
1302 if (hbr->hack[k].oname == NULL &&
1303 hbr->hack[k].nname != NULL &&
1304 atomname_cmp_nr(newnm, &hbr->hack[k], &anmnr))
1308 start_at = hbr->hack[k].a[0];
1312 sprintf(buf, "%s%d", hbr->hack[k].nname, anmnr-1);
1315 for (start_nr = 0; start_nr < rptr->natom; start_nr++)
1317 if (gmx_strcasecmp(start_at, (*rptr->atomname[start_nr])) == 0)
1322 if (start_nr == rptr->natom)
1324 gmx_fatal(FARGS, "Could not find atom '%s' in residue building block '%s' to add atom '%s' to",
1325 start_at, rptr->resname, newnm);
1327 /* We can add the atom after atom start_nr */
1328 add_atom_to_restp(rptr, start_nr, &hbr->hack[j]);
1336 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'",
1338 hbr->hack[j].oname, hbr->hack[j].nname,
1345 printf("Renaming atom '%s' in residue '%s' %d to '%s'\n",
1346 oldnm, rptr->resname, resnr, newnm);
1348 /* Rename the atom in pdba */
1349 snew(pdba->atomname[atind], 1);
1350 *pdba->atomname[atind] = strdup(newnm);
1352 else if (hbr->hack[j].oname != NULL && hbr->hack[j].nname == NULL &&
1353 gmx_strcasecmp(oldnm, hbr->hack[j].oname) == 0)
1355 /* This is a delete entry, check if this atom is present
1356 * in the rtp entry of this residue.
1358 for (k = 0; k < rptr->natom; k++)
1360 if (gmx_strcasecmp(oldnm, *rptr->atomname[k]) == 0)
1365 if (k == rptr->natom)
1367 /* This atom is not present in the rtp entry,
1368 * delete is now from the input pdba.
1372 printf("Deleting atom '%s' in residue '%s' %d\n",
1373 oldnm, rptr->resname, resnr);
1375 /* We should free the atom name,
1376 * but it might be used multiple times in the symtab.
1377 * sfree(pdba->atomname[atind]);
1379 for (k = atind+1; k < pdba->nr; k++)
1381 pdba->atom[k-1] = pdba->atom[k];
1382 pdba->atomname[k-1] = pdba->atomname[k];
1383 copy_rvec(x[k], x[k-1]);
1394 void match_atomnames_with_rtp(t_restp restp[], t_hackblock hb[],
1395 t_atoms *pdba, rvec *x,
1402 for (i = 0; i < pdba->nr; i++)
1404 oldnm = *pdba->atomname[i];
1405 rptr = &restp[pdba->atom[i].resind];
1406 for (j = 0; (j < rptr->natom); j++)
1408 if (gmx_strcasecmp(oldnm, *(rptr->atomname[j])) == 0)
1413 if (j == rptr->natom)
1415 /* Not found yet, check if we have to rename this atom */
1416 if (match_atomnames_with_rtp_atom(pdba, x, i,
1417 rptr, &(hb[pdba->atom[i].resind]),
1420 /* We deleted this atom, decrease the atom counter by 1. */
1427 #define NUM_CMAP_ATOMS 5
1428 static void gen_cmap(t_params *psb, t_restp *restp, t_atoms *atoms, gmx_residuetype_t *rt)
1430 int residx, i, j, k;
1432 t_resinfo *resinfo = atoms->resinfo;
1433 int nres = atoms->nres;
1435 atom_id cmap_atomid[NUM_CMAP_ATOMS];
1436 int cmap_chainnum = -1, this_residue_index;
1447 fprintf(stderr, "Making cmap torsions...");
1449 /* End loop at nres-1, since the very last residue does not have a +N atom, and
1450 * therefore we get a valgrind invalid 4 byte read error with atom am */
1451 for (residx = 0; residx < nres-1; residx++)
1453 /* Add CMAP terms from the list of CMAP interactions */
1454 for (j = 0; j < restp[residx].rb[ebtsCMAP].nb; j++)
1457 /* Loop over atoms in a candidate CMAP interaction and
1458 * check that they exist, are from the same chain and are
1459 * from residues labelled as protein. */
1460 for (k = 0; k < NUM_CMAP_ATOMS && bAddCMAP; k++)
1462 cmap_atomid[k] = search_atom(restp[residx].rb[ebtsCMAP].b[j].a[k],
1463 i, atoms, ptr, TRUE);
1464 bAddCMAP = bAddCMAP && (cmap_atomid[k] != NO_ATID);
1467 /* This break is necessary, because cmap_atomid[k]
1468 * == NO_ATID cannot be safely used as an index
1469 * into the atom array. */
1472 this_residue_index = atoms->atom[cmap_atomid[k]].resind;
1475 cmap_chainnum = resinfo[this_residue_index].chainnum;
1479 /* Does the residue for this atom have the same
1480 * chain number as the residues for previous
1482 bAddCMAP = bAddCMAP &&
1483 cmap_chainnum == resinfo[this_residue_index].chainnum;
1485 bAddCMAP = bAddCMAP && gmx_residuetype_is_protein(rt, *(resinfo[this_residue_index].name));
1490 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);
1494 if (residx < nres-1)
1496 while (atoms->atom[i].resind < residx+1)
1503 /* Start the next residue */
1507 scrub_charge_groups(int *cgnr, int natoms)
1511 for (i = 0; i < natoms; i++)
1518 void pdb2top(FILE *top_file, char *posre_fn, char *molname,
1519 t_atoms *atoms, rvec **x, gpp_atomtype_t atype, t_symtab *tab,
1520 int nrtp, t_restp rtp[],
1521 t_restp *restp, t_hackblock *hb,
1522 gmx_bool bAllowMissing,
1523 gmx_bool bVsites, gmx_bool bVsiteAromatics,
1526 int nssbonds, t_ssbond *ssbonds,
1527 real long_bond_dist, real short_bond_dist,
1528 gmx_bool bDeuterate, gmx_bool bChargeGroups, gmx_bool bCmap,
1529 gmx_bool bRenumRes, gmx_bool bRTPresname)
1535 t_params plist[F_NRE];
1542 gmx_residuetype_t*rt;
1545 gmx_residuetype_init(&rt);
1549 print_resall(debug, atoms->nres, restp, atype);
1550 dump_hb(debug, atoms->nres, hb);
1554 at2bonds(&(plist[F_BONDS]), hb,
1556 long_bond_dist, short_bond_dist);
1558 /* specbonds: disulphide bonds & heme-his */
1559 do_ssbonds(&(plist[F_BONDS]),
1560 atoms, nssbonds, ssbonds,
1563 nmissat = name2type(atoms, &cgnr, restp, rt);
1568 fprintf(stderr, "There were %d missing atoms in molecule %s\n",
1573 gmx_fatal(FARGS, "There were %d missing atoms in molecule %s, if you want to use this incomplete topology anyhow, use the option -missing",
1578 /* Cleanup bonds (sort and rm doubles) */
1579 clean_bonds(&(plist[F_BONDS]));
1581 snew(vsite_type, atoms->nr);
1582 for (i = 0; i < atoms->nr; i++)
1584 vsite_type[i] = NOTSET;
1588 /* determine which atoms will be vsites and add dummy masses
1589 also renumber atom numbers in plist[0..F_NRE]! */
1590 do_vsites(nrtp, rtp, atype, atoms, tab, x, plist,
1591 &vsite_type, &cgnr, mHmult, bVsiteAromatics, ffdir);
1594 /* Make Angles and Dihedrals */
1595 fprintf(stderr, "Generating angles, dihedrals and pairs...\n");
1596 snew(excls, atoms->nr);
1597 init_nnb(&nnb, atoms->nr, 4);
1598 gen_nnb(&nnb, plist);
1599 print_nnb(&nnb, "NNB");
1600 gen_pad(&nnb, atoms, restp, plist, excls, hb, bAllowMissing);
1606 gen_cmap(&(plist[F_CMAP]), restp, atoms, rt);
1607 if (plist[F_CMAP].nr > 0)
1609 fprintf(stderr, "There are %4d cmap torsion pairs\n",
1614 /* set mass of all remaining hydrogen atoms */
1617 do_h_mass(&(plist[F_BONDS]), vsite_type, atoms, mHmult, bDeuterate);
1621 /* Cleanup bonds (sort and rm doubles) */
1622 /* clean_bonds(&(plist[F_BONDS]));*/
1625 "There are %4d dihedrals, %4d impropers, %4d angles\n"
1626 " %4d pairs, %4d bonds and %4d virtual sites\n",
1627 plist[F_PDIHS].nr, plist[F_IDIHS].nr, plist[F_ANGLES].nr,
1628 plist[F_LJ14].nr, plist[F_BONDS].nr,
1629 plist[F_VSITE2].nr +
1630 plist[F_VSITE3].nr +
1631 plist[F_VSITE3FD].nr +
1632 plist[F_VSITE3FAD].nr +
1633 plist[F_VSITE3OUT].nr +
1634 plist[F_VSITE4FD].nr +
1635 plist[F_VSITE4FDN].nr );
1637 print_sums(atoms, FALSE);
1639 if (FALSE == bChargeGroups)
1641 scrub_charge_groups(cgnr, atoms->nr);
1646 for (i = 0; i < atoms->nres; i++)
1648 atoms->resinfo[i].nr = i + 1;
1649 atoms->resinfo[i].ic = ' ';
1655 fprintf(stderr, "Writing topology\n");
1656 /* We can copy the bonded types from the first restp,
1657 * since the types have to be identical for all residues in one molecule.
1659 for (i = 0; i < ebtsNR; i++)
1661 bts[i] = restp[0].rb[i].type;
1663 write_top(top_file, posre_fn, molname,
1665 bts, plist, excls, atype, cgnr, restp[0].nrexcl);
1669 free_t_hackblock(atoms->nres, &hb);
1670 free_t_restp(atoms->nres, &restp);
1671 gmx_residuetype_destroy(rt);
1673 /* we should clean up hb and restp here, but that is a *L*O*T* of work! */
1675 for (i = 0; i < F_NRE; i++)
1677 sfree(plist[i].param);
1679 for (i = 0; i < atoms->nr; i++)