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"
46 #include "gromacs/legacyheaders/macros.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"
64 #include "gromacs/legacyheaders/copyrite.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] = gmx_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] = gmx_strdup(ptr+1);
187 ffs_dir[i] = gmx_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] = gmx_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 = gmx_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 = gmx_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);
739 static void do_ssbonds(t_params *ps, t_atoms *atoms,
740 int nssbonds, t_ssbond *ssbonds, gmx_bool bAllowMissing)
745 for (i = 0; (i < nssbonds); i++)
747 ri = ssbonds[i].res1;
748 rj = ssbonds[i].res2;
749 ai = search_res_atom(ssbonds[i].a1, ri, atoms,
750 "special bond", bAllowMissing);
751 aj = search_res_atom(ssbonds[i].a2, rj, atoms,
752 "special bond", bAllowMissing);
753 if ((ai == NO_ATID) || (aj == NO_ATID))
755 gmx_fatal(FARGS, "Trying to make impossible special bond (%s-%s)!",
756 ssbonds[i].a1, ssbonds[i].a2);
758 add_param(ps, ai, aj, NULL, NULL);
762 static void at2bonds(t_params *psb, t_hackblock *hb,
765 real long_bond_dist, real short_bond_dist)
769 real dist2, long_bond_dist2, short_bond_dist2;
772 long_bond_dist2 = sqr(long_bond_dist);
773 short_bond_dist2 = sqr(short_bond_dist);
784 fprintf(stderr, "Making bonds...\n");
786 for (resind = 0; (resind < atoms->nres) && (i < atoms->nr); resind++)
788 /* add bonds from list of bonded interactions */
789 for (j = 0; j < hb[resind].rb[ebtsBONDS].nb; j++)
791 /* Unfortunately we can not issue errors or warnings
792 * for missing atoms in bonds, as the hydrogens and terminal atoms
793 * have not been added yet.
795 ai = search_atom(hb[resind].rb[ebtsBONDS].b[j].a[0], i, atoms,
797 aj = search_atom(hb[resind].rb[ebtsBONDS].b[j].a[1], i, atoms,
799 if (ai != NO_ATID && aj != NO_ATID)
801 dist2 = distance2(x[ai], x[aj]);
802 if (dist2 > long_bond_dist2)
805 fprintf(stderr, "Warning: Long Bond (%d-%d = %g nm)\n",
806 ai+1, aj+1, sqrt(dist2));
808 else if (dist2 < short_bond_dist2)
810 fprintf(stderr, "Warning: Short Bond (%d-%d = %g nm)\n",
811 ai+1, aj+1, sqrt(dist2));
813 add_param(psb, ai, aj, NULL, hb[resind].rb[ebtsBONDS].b[j].s);
816 /* add bonds from list of hacks (each added atom gets a bond) */
817 while ( (i < atoms->nr) && (atoms->atom[i].resind == resind) )
819 for (j = 0; j < hb[resind].nhack; j++)
821 if ( ( hb[resind].hack[j].tp > 0 ||
822 hb[resind].hack[j].oname == NULL ) &&
823 strcmp(hb[resind].hack[j].a[0], *(atoms->atomname[i])) == 0)
825 switch (hb[resind].hack[j].tp)
827 case 9: /* COOH terminus */
828 add_param(psb, i, i+1, NULL, NULL); /* C-O */
829 add_param(psb, i, i+2, NULL, NULL); /* C-OA */
830 add_param(psb, i+2, i+3, NULL, NULL); /* OA-H */
833 for (k = 0; (k < hb[resind].hack[j].nr); k++)
835 add_param(psb, i, i+k+1, NULL, NULL);
842 /* we're now at the start of the next residue */
846 static int pcompar(const void *a, const void *b)
853 d = pa->a[0] - pb->a[0];
856 d = pa->a[1] - pb->a[1];
860 return strlen(pb->s) - strlen(pa->s);
868 static void clean_bonds(t_params *ps)
875 /* swap atomnumbers in bond if first larger than second: */
876 for (i = 0; (i < ps->nr); i++)
878 if (ps->param[i].a[1] < ps->param[i].a[0])
880 a = ps->param[i].a[0];
881 ps->param[i].a[0] = ps->param[i].a[1];
882 ps->param[i].a[1] = a;
887 qsort(ps->param, ps->nr, (size_t)sizeof(ps->param[0]), pcompar);
889 /* remove doubles, keep the first one always. */
891 for (i = 1; (i < ps->nr); i++)
893 if ((ps->param[i].a[0] != ps->param[j-1].a[0]) ||
894 (ps->param[i].a[1] != ps->param[j-1].a[1]) )
898 cp_param(&(ps->param[j]), &(ps->param[i]));
903 fprintf(stderr, "Number of bonds was %d, now %d\n", ps->nr, j);
908 fprintf(stderr, "No bonds\n");
912 void print_sums(t_atoms *atoms, gmx_bool bSystem)
920 where = " in system";
929 for (i = 0; (i < atoms->nr); i++)
931 m += atoms->atom[i].m;
932 qtot += atoms->atom[i].q;
935 fprintf(stderr, "Total mass%s %.3f a.m.u.\n", where, m);
936 fprintf(stderr, "Total charge%s %.3f e\n", where, qtot);
939 static void check_restp_type(const char *name, int t1, int t2)
943 gmx_fatal(FARGS, "Residues in one molecule have a different '%s' type: %d and %d", name, t1, t2);
947 static void check_restp_types(t_restp *r0, t_restp *r1)
951 check_restp_type("all dihedrals", r0->bKeepAllGeneratedDihedrals, r1->bKeepAllGeneratedDihedrals);
952 check_restp_type("nrexcl", r0->nrexcl, r1->nrexcl);
953 check_restp_type("HH14", r0->bGenerateHH14Interactions, r1->bGenerateHH14Interactions);
954 check_restp_type("remove dihedrals", r0->bRemoveDihedralIfWithImproper, r1->bRemoveDihedralIfWithImproper);
956 for (i = 0; i < ebtsNR; i++)
958 check_restp_type(btsNames[i], r0->rb[i].type, r1->rb[i].type);
962 void add_atom_to_restp(t_restp *restp, int at_start, const t_hack *hack)
966 const char *Hnum = "123456";
970 fprintf(debug,"adding atom(s) %s to atom %s in res %d%s in rtp\n",
972 * restp->atomname[at_start], resnr, restp->resname);
974 strcpy(buf, hack->nname);
975 buf[strlen(buf)+1] = '\0';
978 buf[strlen(buf)] = '-';
981 restp->natom += hack->nr;
982 srenew(restp->atom, restp->natom);
983 srenew(restp->atomname, restp->natom);
984 srenew(restp->cgnr, restp->natom);
986 for (k = restp->natom-1; k > at_start+hack->nr; k--)
989 restp->atom [k - hack->nr];
991 restp->atomname[k - hack->nr];
993 restp->cgnr [k - hack->nr];
996 for (k = 0; k < hack->nr; k++)
998 /* set counter in atomname */
1001 buf[strlen(buf)-1] = Hnum[k];
1003 snew( restp->atomname[at_start+1+k], 1);
1004 restp->atom [at_start+1+k] = *hack->atom;
1005 *restp->atomname[at_start+1+k] = gmx_strdup(buf);
1006 if (hack->cgnr != NOTSET)
1008 restp->cgnr [at_start+1+k] = hack->cgnr;
1012 restp->cgnr [at_start+1+k] = restp->cgnr[at_start];
1017 void get_hackblocks_rtp(t_hackblock **hb, t_restp **restp,
1018 int nrtp, t_restp rtp[],
1019 int nres, t_resinfo *resinfo,
1021 t_hackblock **ntdb, t_hackblock **ctdb,
1032 /* first the termini */
1033 for (i = 0; i < nterpairs; i++)
1035 if (rn[i] >= 0 && ntdb[i] != NULL)
1037 copy_t_hackblock(ntdb[i], &(*hb)[rn[i]]);
1039 if (rc[i] >= 0 && ctdb[i] != NULL)
1041 merge_t_hackblock(ctdb[i], &(*hb)[rc[i]]);
1045 /* then the whole rtp */
1046 for (i = 0; i < nres; i++)
1048 /* Here we allow a mismatch of one character when looking for the rtp entry.
1049 * For such a mismatch there should be only one mismatching name.
1050 * This is mainly useful for small molecules such as ions.
1051 * Note that this will usually not work for protein, DNA and RNA,
1052 * since there the residue names should be listed in residuetypes.dat
1053 * and an error will have been generated earlier in the process.
1055 key = *resinfo[i].rtp;
1056 snew(resinfo[i].rtp, 1);
1057 *resinfo[i].rtp = search_rtp(key, nrtp, rtp);
1058 res = get_restp(*resinfo[i].rtp, nrtp, rtp);
1059 copy_t_restp(res, &(*restp)[i]);
1061 /* Check that we do not have different bonded types in one molecule */
1062 check_restp_types(&(*restp)[0], &(*restp)[i]);
1065 for (j = 0; j < nterpairs && tern == -1; j++)
1073 for (j = 0; j < nterpairs && terc == -1; j++)
1080 bRM = merge_t_bondeds(res->rb, (*hb)[i].rb, tern >= 0, terc >= 0);
1082 if (bRM && ((tern >= 0 && ntdb[tern] == NULL) ||
1083 (terc >= 0 && ctdb[terc] == NULL)))
1085 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).");
1087 if (bRM && ((tern >= 0 && ntdb[tern]->nhack == 0) ||
1088 (terc >= 0 && ctdb[terc]->nhack == 0)))
1090 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.");
1094 /* now perform t_hack's on t_restp's,
1095 i.e. add's and deletes from termini database will be
1096 added to/removed from residue topology
1097 we'll do this on one big dirty loop, so it won't make easy reading! */
1098 for (i = 0; i < nres; i++)
1100 for (j = 0; j < (*hb)[i].nhack; j++)
1102 if ( (*hb)[i].hack[j].nr)
1104 /* find atom in restp */
1105 for (l = 0; l < (*restp)[i].natom; l++)
1107 if ( ( (*hb)[i].hack[j].oname == NULL &&
1108 strcmp((*hb)[i].hack[j].a[0], *(*restp)[i].atomname[l]) == 0 ) ||
1109 ( (*hb)[i].hack[j].oname != NULL &&
1110 strcmp((*hb)[i].hack[j].oname, *(*restp)[i].atomname[l]) == 0 ) )
1115 if (l == (*restp)[i].natom)
1117 /* If we are doing an atom rename only, we don't need
1118 * to generate a fatal error if the old name is not found
1121 /* Deleting can happen also only on the input atoms,
1122 * not necessarily always on the rtp entry.
1124 if (!((*hb)[i].hack[j].oname != NULL &&
1125 (*hb)[i].hack[j].nname != NULL) &&
1126 !((*hb)[i].hack[j].oname != NULL &&
1127 (*hb)[i].hack[j].nname == NULL))
1130 "atom %s not found in buiding block %d%s "
1131 "while combining tdb and rtp",
1132 (*hb)[i].hack[j].oname != NULL ?
1133 (*hb)[i].hack[j].oname : (*hb)[i].hack[j].a[0],
1134 i+1, *resinfo[i].rtp);
1139 if ( (*hb)[i].hack[j].oname == NULL)
1142 add_atom_to_restp(&(*restp)[i], l, &(*hb)[i].hack[j]);
1147 if ( (*hb)[i].hack[j].nname == NULL)
1149 /* we're deleting */
1152 fprintf(debug, "deleting atom %s from res %d%s in rtp\n",
1153 *(*restp)[i].atomname[l],
1154 i+1, (*restp)[i].resname);
1156 /* shift the rest */
1157 (*restp)[i].natom--;
1158 for (k = l; k < (*restp)[i].natom; k++)
1160 (*restp)[i].atom [k] = (*restp)[i].atom [k+1];
1161 (*restp)[i].atomname[k] = (*restp)[i].atomname[k+1];
1162 (*restp)[i].cgnr [k] = (*restp)[i].cgnr [k+1];
1164 /* give back space */
1165 srenew((*restp)[i].atom, (*restp)[i].natom);
1166 srenew((*restp)[i].atomname, (*restp)[i].natom);
1167 srenew((*restp)[i].cgnr, (*restp)[i].natom);
1169 else /* nname != NULL */
1170 { /* we're replacing */
1173 fprintf(debug, "replacing atom %s by %s in res %d%s in rtp\n",
1174 *(*restp)[i].atomname[l], (*hb)[i].hack[j].nname,
1175 i+1, (*restp)[i].resname);
1177 snew( (*restp)[i].atomname[l], 1);
1178 (*restp)[i].atom[l] = *(*hb)[i].hack[j].atom;
1179 *(*restp)[i].atomname[l] = gmx_strdup((*hb)[i].hack[j].nname);
1180 if ( (*hb)[i].hack[j].cgnr != NOTSET)
1182 (*restp)[i].cgnr [l] = (*hb)[i].hack[j].cgnr;
1192 static gmx_bool atomname_cmp_nr(const char *anm, t_hack *hack, int *nr)
1199 return (gmx_strcasecmp(anm, hack->nname) == 0);
1203 if (isdigit(anm[strlen(anm)-1]))
1205 *nr = anm[strlen(anm)-1] - '0';
1211 if (*nr <= 0 || *nr > hack->nr)
1217 return (strlen(anm) == strlen(hack->nname) + 1 &&
1218 gmx_strncasecmp(anm, hack->nname, strlen(hack->nname)) == 0);
1223 static gmx_bool match_atomnames_with_rtp_atom(t_atoms *pdba, rvec *x, int atind,
1224 t_restp *rptr, t_hackblock *hbr,
1229 char *oldnm, *newnm;
1231 char *start_at, buf[STRLEN];
1233 gmx_bool bReplaceReplace, bFoundInAdd;
1236 oldnm = *pdba->atomname[atind];
1237 resnr = pdba->resinfo[pdba->atom[atind].resind].nr;
1240 for (j = 0; j < hbr->nhack; j++)
1242 if (hbr->hack[j].oname != NULL && hbr->hack[j].nname != NULL &&
1243 gmx_strcasecmp(oldnm, hbr->hack[j].oname) == 0)
1245 /* This is a replace entry. */
1246 /* Check if we are not replacing a replaced atom. */
1247 bReplaceReplace = FALSE;
1248 for (k = 0; k < hbr->nhack; k++)
1251 hbr->hack[k].oname != NULL && hbr->hack[k].nname != NULL &&
1252 gmx_strcasecmp(hbr->hack[k].nname, hbr->hack[j].oname) == 0)
1254 /* The replace in hack[j] replaces an atom that
1255 * was already replaced in hack[k], we do not want
1256 * second or higher level replaces at this stage.
1258 bReplaceReplace = TRUE;
1261 if (bReplaceReplace)
1263 /* Skip this replace. */
1267 /* This atom still has the old name, rename it */
1268 newnm = hbr->hack[j].nname;
1269 for (k = 0; k < rptr->natom; k++)
1271 if (gmx_strcasecmp(newnm, *rptr->atomname[k]) == 0)
1276 if (k == rptr->natom)
1278 /* The new name is not present in the rtp.
1279 * We need to apply the replace also to the rtp entry.
1282 /* We need to find the add hack that can add this atom
1283 * to find out after which atom it should be added.
1285 bFoundInAdd = FALSE;
1286 for (k = 0; k < hbr->nhack; k++)
1288 if (hbr->hack[k].oname == NULL &&
1289 hbr->hack[k].nname != NULL &&
1290 atomname_cmp_nr(newnm, &hbr->hack[k], &anmnr))
1294 start_at = hbr->hack[k].a[0];
1298 sprintf(buf, "%s%d", hbr->hack[k].nname, anmnr-1);
1301 for (start_nr = 0; start_nr < rptr->natom; start_nr++)
1303 if (gmx_strcasecmp(start_at, (*rptr->atomname[start_nr])) == 0)
1308 if (start_nr == rptr->natom)
1310 gmx_fatal(FARGS, "Could not find atom '%s' in residue building block '%s' to add atom '%s' to",
1311 start_at, rptr->resname, newnm);
1313 /* We can add the atom after atom start_nr */
1314 add_atom_to_restp(rptr, start_nr, &hbr->hack[j]);
1322 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'",
1324 hbr->hack[j].oname, hbr->hack[j].nname,
1331 printf("Renaming atom '%s' in residue '%s' %d to '%s'\n",
1332 oldnm, rptr->resname, resnr, newnm);
1334 /* Rename the atom in pdba */
1335 snew(pdba->atomname[atind], 1);
1336 *pdba->atomname[atind] = gmx_strdup(newnm);
1338 else if (hbr->hack[j].oname != NULL && hbr->hack[j].nname == NULL &&
1339 gmx_strcasecmp(oldnm, hbr->hack[j].oname) == 0)
1341 /* This is a delete entry, check if this atom is present
1342 * in the rtp entry of this residue.
1344 for (k = 0; k < rptr->natom; k++)
1346 if (gmx_strcasecmp(oldnm, *rptr->atomname[k]) == 0)
1351 if (k == rptr->natom)
1353 /* This atom is not present in the rtp entry,
1354 * delete is now from the input pdba.
1358 printf("Deleting atom '%s' in residue '%s' %d\n",
1359 oldnm, rptr->resname, resnr);
1361 /* We should free the atom name,
1362 * but it might be used multiple times in the symtab.
1363 * sfree(pdba->atomname[atind]);
1365 for (k = atind+1; k < pdba->nr; k++)
1367 pdba->atom[k-1] = pdba->atom[k];
1368 pdba->atomname[k-1] = pdba->atomname[k];
1369 copy_rvec(x[k], x[k-1]);
1380 void match_atomnames_with_rtp(t_restp restp[], t_hackblock hb[],
1381 t_atoms *pdba, rvec *x,
1388 for (i = 0; i < pdba->nr; i++)
1390 oldnm = *pdba->atomname[i];
1391 rptr = &restp[pdba->atom[i].resind];
1392 for (j = 0; (j < rptr->natom); j++)
1394 if (gmx_strcasecmp(oldnm, *(rptr->atomname[j])) == 0)
1399 if (j == rptr->natom)
1401 /* Not found yet, check if we have to rename this atom */
1402 if (match_atomnames_with_rtp_atom(pdba, x, i,
1403 rptr, &(hb[pdba->atom[i].resind]),
1406 /* We deleted this atom, decrease the atom counter by 1. */
1413 #define NUM_CMAP_ATOMS 5
1414 static void gen_cmap(t_params *psb, t_restp *restp, t_atoms *atoms)
1416 int residx, i, j, k;
1419 t_resinfo *resinfo = atoms->resinfo;
1420 int nres = atoms->nres;
1422 atom_id cmap_atomid[NUM_CMAP_ATOMS];
1423 int cmap_chainnum = -1, this_residue_index;
1434 fprintf(stderr, "Making cmap torsions...\n");
1436 /* Most cmap entries use the N atom from the next residue, so the last
1437 * residue should not have its CMAP entry in that case, but for things like
1438 * dipeptides we sometimes define a complete CMAP entry inside a residue,
1439 * and in this case we need to process everything through the last residue.
1441 for (residx = 0; residx < nres; residx++)
1443 /* Add CMAP terms from the list of CMAP interactions */
1444 for (j = 0; j < restp[residx].rb[ebtsCMAP].nb; j++)
1447 /* Loop over atoms in a candidate CMAP interaction and
1448 * check that they exist, are from the same chain and are
1449 * from residues labelled as protein. */
1450 for (k = 0; k < NUM_CMAP_ATOMS && bAddCMAP; k++)
1452 /* Assign the pointer to the name of the next reference atom.
1453 * This can use -/+ labels to refer to previous/next residue.
1455 pname = restp[residx].rb[ebtsCMAP].b[j].a[k];
1456 /* Skip this CMAP entry if it refers to residues before the
1457 * first or after the last residue.
1459 if (((strchr(pname, '-') != NULL) && (residx == 0)) ||
1460 ((strchr(pname, '+') != NULL) && (residx == nres-1)))
1466 cmap_atomid[k] = search_atom(pname,
1467 i, atoms, ptr, TRUE);
1468 bAddCMAP = bAddCMAP && (cmap_atomid[k] != NO_ATID);
1471 /* This break is necessary, because cmap_atomid[k]
1472 * == NO_ATID cannot be safely used as an index
1473 * into the atom array. */
1476 this_residue_index = atoms->atom[cmap_atomid[k]].resind;
1479 cmap_chainnum = resinfo[this_residue_index].chainnum;
1483 /* Does the residue for this atom have the same
1484 * chain number as the residues for previous
1486 bAddCMAP = bAddCMAP &&
1487 cmap_chainnum == resinfo[this_residue_index].chainnum;
1489 /* Here we used to check that the residuetype was protein and
1490 * disable bAddCMAP if that was not the case. However, some
1491 * special residues (say, alanine dipeptides) might not adhere
1492 * to standard naming, and if we start calling them normal
1493 * protein residues the user will be bugged to select termini.
1495 * Instead, I believe that the right course of action is to
1496 * keep the CMAP interaction if it is present in the RTP file
1497 * and we correctly identified all atoms (which is the case
1504 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);
1508 if (residx < nres-1)
1510 while (atoms->atom[i].resind < residx+1)
1516 /* Start the next residue */
1520 scrub_charge_groups(int *cgnr, int natoms)
1524 for (i = 0; i < natoms; i++)
1531 void pdb2top(FILE *top_file, char *posre_fn, char *molname,
1532 t_atoms *atoms, rvec **x, gpp_atomtype_t atype, t_symtab *tab,
1533 int nrtp, t_restp rtp[],
1534 t_restp *restp, t_hackblock *hb,
1535 gmx_bool bAllowMissing,
1536 gmx_bool bVsites, gmx_bool bVsiteAromatics,
1539 int nssbonds, t_ssbond *ssbonds,
1540 real long_bond_dist, real short_bond_dist,
1541 gmx_bool bDeuterate, gmx_bool bChargeGroups, gmx_bool bCmap,
1542 gmx_bool bRenumRes, gmx_bool bRTPresname)
1548 t_params plist[F_NRE];
1555 gmx_residuetype_t*rt;
1558 gmx_residuetype_init(&rt);
1562 print_resall(debug, atoms->nres, restp, atype);
1563 dump_hb(debug, atoms->nres, hb);
1567 at2bonds(&(plist[F_BONDS]), hb,
1569 long_bond_dist, short_bond_dist);
1571 /* specbonds: disulphide bonds & heme-his */
1572 do_ssbonds(&(plist[F_BONDS]),
1573 atoms, nssbonds, ssbonds,
1576 nmissat = name2type(atoms, &cgnr, restp, rt);
1581 fprintf(stderr, "There were %d missing atoms in molecule %s\n",
1586 gmx_fatal(FARGS, "There were %d missing atoms in molecule %s, if you want to use this incomplete topology anyhow, use the option -missing",
1591 /* Cleanup bonds (sort and rm doubles) */
1592 clean_bonds(&(plist[F_BONDS]));
1594 snew(vsite_type, atoms->nr);
1595 for (i = 0; i < atoms->nr; i++)
1597 vsite_type[i] = NOTSET;
1601 /* determine which atoms will be vsites and add dummy masses
1602 also renumber atom numbers in plist[0..F_NRE]! */
1603 do_vsites(nrtp, rtp, atype, atoms, tab, x, plist,
1604 &vsite_type, &cgnr, mHmult, bVsiteAromatics, ffdir);
1607 /* Make Angles and Dihedrals */
1608 fprintf(stderr, "Generating angles, dihedrals and pairs...\n");
1609 snew(excls, atoms->nr);
1610 init_nnb(&nnb, atoms->nr, 4);
1611 gen_nnb(&nnb, plist);
1612 print_nnb(&nnb, "NNB");
1613 gen_pad(&nnb, atoms, restp, plist, excls, hb, bAllowMissing);
1619 gen_cmap(&(plist[F_CMAP]), restp, atoms);
1620 if (plist[F_CMAP].nr > 0)
1622 fprintf(stderr, "There are %4d cmap torsion pairs\n",
1627 /* set mass of all remaining hydrogen atoms */
1630 do_h_mass(&(plist[F_BONDS]), vsite_type, atoms, mHmult, bDeuterate);
1634 /* Cleanup bonds (sort and rm doubles) */
1635 /* clean_bonds(&(plist[F_BONDS]));*/
1638 "There are %4d dihedrals, %4d impropers, %4d angles\n"
1639 " %4d pairs, %4d bonds and %4d virtual sites\n",
1640 plist[F_PDIHS].nr, plist[F_IDIHS].nr, plist[F_ANGLES].nr,
1641 plist[F_LJ14].nr, plist[F_BONDS].nr,
1642 plist[F_VSITE2].nr +
1643 plist[F_VSITE3].nr +
1644 plist[F_VSITE3FD].nr +
1645 plist[F_VSITE3FAD].nr +
1646 plist[F_VSITE3OUT].nr +
1647 plist[F_VSITE4FD].nr +
1648 plist[F_VSITE4FDN].nr );
1650 print_sums(atoms, FALSE);
1652 if (FALSE == bChargeGroups)
1654 scrub_charge_groups(cgnr, atoms->nr);
1659 for (i = 0; i < atoms->nres; i++)
1661 atoms->resinfo[i].nr = i + 1;
1662 atoms->resinfo[i].ic = ' ';
1668 fprintf(stderr, "Writing topology\n");
1669 /* We can copy the bonded types from the first restp,
1670 * since the types have to be identical for all residues in one molecule.
1672 for (i = 0; i < ebtsNR; i++)
1674 bts[i] = restp[0].rb[i].type;
1676 write_top(top_file, posre_fn, molname,
1678 bts, plist, excls, atype, cgnr, restp[0].nrexcl);
1682 free_t_hackblock(atoms->nres, &hb);
1683 free_t_restp(atoms->nres, &restp);
1684 gmx_residuetype_destroy(rt);
1686 /* we should clean up hb and restp here, but that is a *L*O*T* of work! */
1688 for (i = 0; i < F_NRE; i++)
1690 sfree(plist[i].param);
1692 for (i = 0; i < atoms->nr; i++)