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.
43 #include "gromacs/math/vec.h"
44 #include "gromacs/legacyheaders/macros.h"
45 #include "gromacs/utility/futil.h"
47 #include "gpp_nextnb.h"
54 #include "gromacs/utility/cstringutil.h"
55 #include "gromacs/fileio/pdbio.h"
57 #include "gromacs/fileio/filenm.h"
58 #include "gen_vsite.h"
61 #include "fflibutil.h"
62 #include "gromacs/legacyheaders/copyrite.h"
64 #include "gromacs/fileio/strdb.h"
65 #include "gromacs/topology/residuetypes.h"
66 #include "gromacs/topology/symtab.h"
67 #include "gromacs/utility/exceptions.h"
68 #include "gromacs/utility/fatalerror.h"
69 #include "gromacs/utility/programcontext.h"
70 #include "gromacs/utility/smalloc.h"
72 /* this must correspond to enum in pdb2top.h */
73 const char *hh[ehisNR] = { "HISD", "HISE", "HISH", "HIS1" };
75 static int missing_atoms(t_restp *rp, int resind, t_atoms *at, int i0, int i)
82 for (j = 0; j < rp->natom; j++)
84 name = *(rp->atomname[j]);
86 for (k = i0; k < i; k++)
88 bFound = (bFound || !gmx_strcasecmp(*(at->atomname[k]), name));
93 fprintf(stderr, "\nWARNING: "
94 "atom %s is missing in residue %s %d in the pdb file\n",
95 name, *(at->resinfo[resind].name), at->resinfo[resind].nr);
96 if (name[0] == 'H' || name[0] == 'h')
98 fprintf(stderr, " You might need to add atom %s to the hydrogen database of building block %s\n"
99 " in the file %s.hdb (see the manual)\n",
100 name, *(at->resinfo[resind].rtp), rp->filebase);
102 fprintf(stderr, "\n");
109 gmx_bool is_int(double x)
111 const double tol = 1e-4;
120 return (fabs(x-ix) < tol);
123 static void swap_strings(char **s, int i, int j)
133 choose_ff(const char *ffsel,
134 char *forcefield, int ff_maxlen,
135 char *ffdir, int ffdir_maxlen)
138 char **ffdirs, **ffs, **ffs_dir, *ptr;
139 int i, j, sel, cwdsel, nfound;
140 char buf[STRLEN], **desc;
144 nff = fflib_search_file_in_dirend(fflib_forcefield_itp(),
145 fflib_forcefield_dir_ext(),
150 gmx_fatal(FARGS, "No force fields found (files with name '%s' in subdirectories ending on '%s')",
151 fflib_forcefield_itp(), fflib_forcefield_dir_ext());
154 /* Replace with unix path separators */
155 if (DIR_SEPARATOR != '/')
157 for (i = 0; i < nff; i++)
159 while ( (ptr = strchr(ffdirs[i], DIR_SEPARATOR)) != NULL)
166 /* Store the force field names in ffs */
169 for (i = 0; i < nff; i++)
171 /* Remove the path from the ffdir name - use our unix standard here! */
172 ptr = strrchr(ffdirs[i], '/');
175 ffs[i] = gmx_strdup(ffdirs[i]);
176 ffs_dir[i] = low_gmxlibfn(ffdirs[i], FALSE, FALSE);
177 if (ffs_dir[i] == NULL)
179 gmx_fatal(FARGS, "Can no longer find file '%s'", ffdirs[i]);
184 ffs[i] = gmx_strdup(ptr+1);
185 ffs_dir[i] = gmx_strdup(ffdirs[i]);
187 ffs_dir[i][strlen(ffs_dir[i])-strlen(ffs[i])-1] = '\0';
188 /* Remove the extension from the ffdir name */
189 ffs[i][strlen(ffs[i])-strlen(fflib_forcefield_dir_ext())] = '\0';
197 for (i = 0; i < nff; i++)
199 if (strcmp(ffs[i], ffsel) == 0)
201 /* Matching ff name */
205 if (strncmp(ffs_dir[i], ".", 1) == 0)
222 "Force field '%s' occurs in %d places. pdb2gmx is using the one in the\n"
223 "current directory. Use interactive selection (not the -ff option) if\n"
224 "you would prefer a different one.\n", ffsel, nfound);
229 "Force field '%s' occurs in %d places, but not in the current directory.\n"
230 "Run without the -ff switch and select the force field interactively.", ffsel, nfound);
233 else if (nfound == 0)
235 gmx_fatal(FARGS, "Could not find force field '%s' in current directory, install tree or GMXDATA path.", ffsel);
241 for (i = 0; (i < nff); i++)
243 sprintf(buf, "%s%c%s%s%c%s",
244 ffs_dir[i], DIR_SEPARATOR,
245 ffs[i], fflib_forcefield_dir_ext(), DIR_SEPARATOR,
246 fflib_forcefield_doc());
249 /* We don't use fflib_open, because we don't want printf's */
250 fp = gmx_ffopen(buf, "r");
251 snew(desc[i], STRLEN);
252 get_a_line(fp, desc[i], STRLEN);
257 desc[i] = gmx_strdup(ffs[i]);
260 /* Order force fields from the same dir alphabetically
261 * and put deprecated force fields at the end.
263 for (i = 0; (i < nff); i++)
265 for (j = i+1; (j < nff); j++)
267 if (strcmp(ffs_dir[i], ffs_dir[j]) == 0 &&
268 ((desc[i][0] == '[' && desc[j][0] != '[') ||
269 ((desc[i][0] == '[' || desc[j][0] != '[') &&
270 gmx_strcasecmp(desc[i], desc[j]) > 0)))
272 swap_strings(ffdirs, i, j);
273 swap_strings(ffs, i, j);
274 swap_strings(desc, i, j);
279 printf("\nSelect the Force Field:\n");
280 for (i = 0; (i < nff); i++)
282 if (i == 0 || strcmp(ffs_dir[i-1], ffs_dir[i]) != 0)
284 if (strcmp(ffs_dir[i], ".") == 0)
286 printf("From current directory:\n");
290 printf("From '%s':\n", ffs_dir[i]);
293 printf("%2d: %s\n", i+1, desc[i]);
301 pret = fgets(buf, STRLEN, stdin);
305 sel = strtol(buf, NULL, 10);
309 while (pret == NULL || (sel < 0) || (sel >= nff));
311 /* Check for a current limitation of the fflib code.
312 * It will always read from the first ff directory in the list.
313 * This check assumes that the order of ffs matches the order
314 * in which fflib_open searches ff library files.
316 for (i = 0; i < sel; i++)
318 if (strcmp(ffs[i], ffs[sel]) == 0)
320 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.",
321 ffs[sel], fflib_forcefield_dir_ext());
330 if (strlen(ffs[sel]) >= (size_t)ff_maxlen)
332 gmx_fatal(FARGS, "Length of force field name (%d) >= maxlen (%d)",
333 strlen(ffs[sel]), ff_maxlen);
335 strcpy(forcefield, ffs[sel]);
337 if (strlen(ffdirs[sel]) >= (size_t)ffdir_maxlen)
339 gmx_fatal(FARGS, "Length of force field dir (%d) >= maxlen (%d)",
340 strlen(ffdirs[sel]), ffdir_maxlen);
342 strcpy(ffdir, ffdirs[sel]);
344 for (i = 0; (i < nff); i++)
355 void choose_watermodel(const char *wmsel, const char *ffdir,
358 const char *fn_watermodels = "watermodels.dat";
359 char fn_list[STRLEN];
366 if (strcmp(wmsel, "none") == 0)
372 else if (strcmp(wmsel, "select") != 0)
374 *watermodel = gmx_strdup(wmsel);
379 sprintf(fn_list, "%s%c%s", ffdir, DIR_SEPARATOR, fn_watermodels);
381 if (!fflib_fexist(fn_list))
383 fprintf(stderr, "No file '%s' found, will not include a water model\n",
390 fp = fflib_open(fn_list);
391 printf("\nSelect the Water Model:\n");
394 while (get_a_line(fp, buf, STRLEN))
396 srenew(model, nwm+1);
397 snew(model[nwm], STRLEN);
398 sscanf(buf, "%s%n", model[nwm], &i);
402 fprintf(stderr, "%2d: %s\n", nwm+1, buf+i);
411 fprintf(stderr, "%2d: %s\n", nwm+1, "None");
416 pret = fgets(buf, STRLEN, stdin);
420 sel = strtol(buf, NULL, 10);
424 while (pret == NULL || sel < 0 || sel > nwm);
432 *watermodel = gmx_strdup(model[sel]);
435 for (i = 0; i < nwm; i++)
442 static int name2type(t_atoms *at, int **cgnr,
443 t_restp restp[], gmx_residuetype_t *rt)
445 int i, j, prevresind, resind, i0, prevcg, cg, curcg;
463 for (i = 0; (i < at->nr); i++)
466 if (at->atom[i].resind != resind)
469 resind = at->atom[i].resind;
470 bProt = gmx_residuetype_is_protein(rt, *(at->resinfo[resind].name));
471 bNterm = bProt && (resind == 0);
474 nmissat += missing_atoms(&restp[prevresind], prevresind, at, i0, i);
478 if (at->atom[i].m == 0)
482 fprintf(debug, "atom %d%s: curcg=%d, prevcg=%d, cg=%d\n",
483 i+1, *(at->atomname[i]), curcg, prevcg,
484 j == NOTSET ? NOTSET : restp[resind].cgnr[j]);
488 name = *(at->atomname[i]);
489 j = search_jtype(&restp[resind], name, bNterm);
490 at->atom[i].type = restp[resind].atom[j].type;
491 at->atom[i].q = restp[resind].atom[j].q;
492 at->atom[i].m = restp[resind].atom[j].m;
493 cg = restp[resind].cgnr[j];
494 /* A charge group number -1 signals a separate charge group
497 if ( (cg == -1) || (cg != prevcg) || (resind != prevresind) )
506 fprintf(debug, "atom %d%s: curcg=%d, qt=%g, is_int=%d\n",
507 i+1, *(at->atomname[i]), curcg, qt, is_int(qt));
518 at->atom[i].typeB = at->atom[i].type;
519 at->atom[i].qB = at->atom[i].q;
520 at->atom[i].mB = at->atom[i].m;
522 nmissat += missing_atoms(&restp[resind], resind, at, i0, i);
527 static void print_top_heavy_H(FILE *out, real mHmult)
531 fprintf(out, "; Using deuterium instead of hydrogen\n\n");
533 else if (mHmult == 4.0)
535 fprintf(out, "#define HEAVY_H\n\n");
537 else if (mHmult != 1.0)
539 fprintf(stderr, "WARNING: unsupported proton mass multiplier (%g) "
540 "in pdb2top\n", mHmult);
544 void print_top_comment(FILE *out,
545 const char *filename,
549 char ffdir_parent[STRLEN];
552 nice_header(out, filename);
553 fprintf(out, ";\tThis is a %s topology file\n;\n", bITP ? "include" : "standalone");
556 gmx::BinaryInformationSettings settings;
557 settings.generatedByHeader(true);
558 settings.linePrefix(";\t");
559 gmx::printBinaryInformation(out, gmx::getProgramContext(), settings);
561 GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
563 if (strchr(ffdir, '/') == NULL)
565 fprintf(out, ";\tForce field was read from the standard Gromacs share directory.\n;\n\n");
567 else if (ffdir[0] == '.')
569 fprintf(out, ";\tForce field was read from current directory or a relative path - path added.\n;\n\n");
573 strncpy(ffdir_parent, ffdir, STRLEN-1);
574 ffdir_parent[STRLEN-1] = '\0'; /*make sure it is 0-terminated even for long string*/
575 p = strrchr(ffdir_parent, '/');
580 ";\tForce field data was read from:\n"
584 ";\tThis might be a non-standard force field location. When you use this topology, the\n"
585 ";\tforce field must either be present in the current directory, or the location\n"
586 ";\tspecified in the GMXLIB path variable or with the 'include' mdp file option.\n;\n\n",
591 void print_top_header(FILE *out, const char *filename,
592 gmx_bool bITP, const char *ffdir, real mHmult)
596 print_top_comment(out, filename, ffdir, bITP);
598 print_top_heavy_H(out, mHmult);
599 fprintf(out, "; Include forcefield parameters\n");
601 p = strrchr(ffdir, '/');
602 p = (ffdir[0] == '.' || p == NULL) ? ffdir : p+1;
604 fprintf(out, "#include \"%s/%s\"\n\n", p, fflib_forcefield_itp());
607 static void print_top_posre(FILE *out, const char *pr)
609 fprintf(out, "; Include Position restraint file\n");
610 fprintf(out, "#ifdef POSRES\n");
611 fprintf(out, "#include \"%s\"\n", pr);
612 fprintf(out, "#endif\n\n");
615 static void print_top_water(FILE *out, const char *ffdir, const char *water)
620 fprintf(out, "; Include water topology\n");
622 p = strrchr(ffdir, '/');
623 p = (ffdir[0] == '.' || p == NULL) ? ffdir : p+1;
624 fprintf(out, "#include \"%s/%s.itp\"\n", p, water);
627 fprintf(out, "#ifdef POSRES_WATER\n");
628 fprintf(out, "; Position restraint for each water oxygen\n");
629 fprintf(out, "[ position_restraints ]\n");
630 fprintf(out, ";%3s %5s %9s %10s %10s\n", "i", "funct", "fcx", "fcy", "fcz");
631 fprintf(out, "%4d %4d %10g %10g %10g\n", 1, 1, 1000.0, 1000.0, 1000.0);
632 fprintf(out, "#endif\n");
635 sprintf(buf, "%s/ions.itp", p);
637 if (fflib_fexist(buf))
639 fprintf(out, "; Include topology for ions\n");
640 fprintf(out, "#include \"%s\"\n", buf);
645 static void print_top_system(FILE *out, const char *title)
647 fprintf(out, "[ %s ]\n", dir2str(d_system));
648 fprintf(out, "; Name\n");
649 fprintf(out, "%s\n\n", title[0] ? title : "Protein");
652 void print_top_mols(FILE *out,
653 const char *title, const char *ffdir, const char *water,
654 int nincl, char **incls, int nmol, t_mols *mols)
661 fprintf(out, "; Include chain topologies\n");
662 for (i = 0; (i < nincl); i++)
664 incl = strrchr(incls[i], DIR_SEPARATOR);
671 /* Remove the path from the include name */
674 fprintf(out, "#include \"%s\"\n", incl);
681 print_top_water(out, ffdir, water);
683 print_top_system(out, title);
687 fprintf(out, "[ %s ]\n", dir2str(d_molecules));
688 fprintf(out, "; %-15s %5s\n", "Compound", "#mols");
689 for (i = 0; (i < nmol); i++)
691 fprintf(out, "%-15s %5d\n", mols[i].name, mols[i].nr);
696 void write_top(FILE *out, char *pr, char *molname,
697 t_atoms *at, gmx_bool bRTPresname,
698 int bts[], t_params plist[], t_excls excls[],
699 gpp_atomtype_t atype, int *cgnr, int nrexcl)
700 /* NOTE: nrexcl is not the size of *excl! */
702 if (at && atype && cgnr)
704 fprintf(out, "[ %s ]\n", dir2str(d_moleculetype));
705 fprintf(out, "; %-15s %5s\n", "Name", "nrexcl");
706 fprintf(out, "%-15s %5d\n\n", molname ? molname : "Protein", nrexcl);
708 print_atoms(out, atype, at, cgnr, bRTPresname);
709 print_bondeds(out, at->nr, d_bonds, F_BONDS, bts[ebtsBONDS], plist);
710 print_bondeds(out, at->nr, d_constraints, F_CONSTR, 0, plist);
711 print_bondeds(out, at->nr, d_constraints, F_CONSTRNC, 0, plist);
712 print_bondeds(out, at->nr, d_pairs, F_LJ14, 0, plist);
713 print_excl(out, at->nr, excls);
714 print_bondeds(out, at->nr, d_angles, F_ANGLES, bts[ebtsANGLES], plist);
715 print_bondeds(out, at->nr, d_dihedrals, F_PDIHS, bts[ebtsPDIHS], plist);
716 print_bondeds(out, at->nr, d_dihedrals, F_IDIHS, bts[ebtsIDIHS], plist);
717 print_bondeds(out, at->nr, d_cmap, F_CMAP, bts[ebtsCMAP], plist);
718 print_bondeds(out, at->nr, d_polarization, F_POLARIZATION, 0, plist);
719 print_bondeds(out, at->nr, d_thole_polarization, F_THOLE_POL, 0, plist);
720 print_bondeds(out, at->nr, d_vsites2, F_VSITE2, 0, plist);
721 print_bondeds(out, at->nr, d_vsites3, F_VSITE3, 0, plist);
722 print_bondeds(out, at->nr, d_vsites3, F_VSITE3FD, 0, plist);
723 print_bondeds(out, at->nr, d_vsites3, F_VSITE3FAD, 0, plist);
724 print_bondeds(out, at->nr, d_vsites3, F_VSITE3OUT, 0, plist);
725 print_bondeds(out, at->nr, d_vsites4, F_VSITE4FD, 0, plist);
726 print_bondeds(out, at->nr, d_vsites4, F_VSITE4FDN, 0, plist);
730 print_top_posre(out, pr);
737 static void do_ssbonds(t_params *ps, t_atoms *atoms,
738 int nssbonds, t_ssbond *ssbonds, gmx_bool bAllowMissing)
743 for (i = 0; (i < nssbonds); i++)
745 ri = ssbonds[i].res1;
746 rj = ssbonds[i].res2;
747 ai = search_res_atom(ssbonds[i].a1, ri, atoms,
748 "special bond", bAllowMissing);
749 aj = search_res_atom(ssbonds[i].a2, rj, atoms,
750 "special bond", bAllowMissing);
751 if ((ai == NO_ATID) || (aj == NO_ATID))
753 gmx_fatal(FARGS, "Trying to make impossible special bond (%s-%s)!",
754 ssbonds[i].a1, ssbonds[i].a2);
756 add_param(ps, ai, aj, NULL, NULL);
760 static void at2bonds(t_params *psb, t_hackblock *hb,
763 real long_bond_dist, real short_bond_dist)
767 real dist2, long_bond_dist2, short_bond_dist2;
770 long_bond_dist2 = sqr(long_bond_dist);
771 short_bond_dist2 = sqr(short_bond_dist);
782 fprintf(stderr, "Making bonds...\n");
784 for (resind = 0; (resind < atoms->nres) && (i < atoms->nr); resind++)
786 /* add bonds from list of bonded interactions */
787 for (j = 0; j < hb[resind].rb[ebtsBONDS].nb; j++)
789 /* Unfortunately we can not issue errors or warnings
790 * for missing atoms in bonds, as the hydrogens and terminal atoms
791 * have not been added yet.
793 ai = search_atom(hb[resind].rb[ebtsBONDS].b[j].a[0], i, atoms,
795 aj = search_atom(hb[resind].rb[ebtsBONDS].b[j].a[1], i, atoms,
797 if (ai != NO_ATID && aj != NO_ATID)
799 dist2 = distance2(x[ai], x[aj]);
800 if (dist2 > long_bond_dist2)
803 fprintf(stderr, "Warning: Long Bond (%d-%d = %g nm)\n",
804 ai+1, aj+1, sqrt(dist2));
806 else if (dist2 < short_bond_dist2)
808 fprintf(stderr, "Warning: Short Bond (%d-%d = %g nm)\n",
809 ai+1, aj+1, sqrt(dist2));
811 add_param(psb, ai, aj, NULL, hb[resind].rb[ebtsBONDS].b[j].s);
814 /* add bonds from list of hacks (each added atom gets a bond) */
815 while ( (i < atoms->nr) && (atoms->atom[i].resind == resind) )
817 for (j = 0; j < hb[resind].nhack; j++)
819 if ( ( hb[resind].hack[j].tp > 0 ||
820 hb[resind].hack[j].oname == NULL ) &&
821 strcmp(hb[resind].hack[j].a[0], *(atoms->atomname[i])) == 0)
823 switch (hb[resind].hack[j].tp)
825 case 9: /* COOH terminus */
826 add_param(psb, i, i+1, NULL, NULL); /* C-O */
827 add_param(psb, i, i+2, NULL, NULL); /* C-OA */
828 add_param(psb, i+2, i+3, NULL, NULL); /* OA-H */
831 for (k = 0; (k < hb[resind].hack[j].nr); k++)
833 add_param(psb, i, i+k+1, NULL, NULL);
840 /* we're now at the start of the next residue */
844 static int pcompar(const void *a, const void *b)
851 d = pa->a[0] - pb->a[0];
854 d = pa->a[1] - pb->a[1];
858 return strlen(pb->s) - strlen(pa->s);
866 static void clean_bonds(t_params *ps)
873 /* swap atomnumbers in bond if first larger than second: */
874 for (i = 0; (i < ps->nr); i++)
876 if (ps->param[i].a[1] < ps->param[i].a[0])
878 a = ps->param[i].a[0];
879 ps->param[i].a[0] = ps->param[i].a[1];
880 ps->param[i].a[1] = a;
885 qsort(ps->param, ps->nr, (size_t)sizeof(ps->param[0]), pcompar);
887 /* remove doubles, keep the first one always. */
889 for (i = 1; (i < ps->nr); i++)
891 if ((ps->param[i].a[0] != ps->param[j-1].a[0]) ||
892 (ps->param[i].a[1] != ps->param[j-1].a[1]) )
896 cp_param(&(ps->param[j]), &(ps->param[i]));
901 fprintf(stderr, "Number of bonds was %d, now %d\n", ps->nr, j);
906 fprintf(stderr, "No bonds\n");
910 void print_sums(t_atoms *atoms, gmx_bool bSystem)
918 where = " in system";
927 for (i = 0; (i < atoms->nr); i++)
929 m += atoms->atom[i].m;
930 qtot += atoms->atom[i].q;
933 fprintf(stderr, "Total mass%s %.3f a.m.u.\n", where, m);
934 fprintf(stderr, "Total charge%s %.3f e\n", where, qtot);
937 static void check_restp_type(const char *name, int t1, int t2)
941 gmx_fatal(FARGS, "Residues in one molecule have a different '%s' type: %d and %d", name, t1, t2);
945 static void check_restp_types(t_restp *r0, t_restp *r1)
949 check_restp_type("all dihedrals", r0->bKeepAllGeneratedDihedrals, r1->bKeepAllGeneratedDihedrals);
950 check_restp_type("nrexcl", r0->nrexcl, r1->nrexcl);
951 check_restp_type("HH14", r0->bGenerateHH14Interactions, r1->bGenerateHH14Interactions);
952 check_restp_type("remove dihedrals", r0->bRemoveDihedralIfWithImproper, r1->bRemoveDihedralIfWithImproper);
954 for (i = 0; i < ebtsNR; i++)
956 check_restp_type(btsNames[i], r0->rb[i].type, r1->rb[i].type);
960 void add_atom_to_restp(t_restp *restp, int at_start, const t_hack *hack)
964 const char *Hnum = "123456";
968 fprintf(debug,"adding atom(s) %s to atom %s in res %d%s in rtp\n",
970 * restp->atomname[at_start], resnr, restp->resname);
972 strcpy(buf, hack->nname);
973 buf[strlen(buf)+1] = '\0';
976 buf[strlen(buf)] = '-';
979 restp->natom += hack->nr;
980 srenew(restp->atom, restp->natom);
981 srenew(restp->atomname, restp->natom);
982 srenew(restp->cgnr, restp->natom);
984 for (k = restp->natom-1; k > at_start+hack->nr; k--)
987 restp->atom [k - hack->nr];
989 restp->atomname[k - hack->nr];
991 restp->cgnr [k - hack->nr];
994 for (k = 0; k < hack->nr; k++)
996 /* set counter in atomname */
999 buf[strlen(buf)-1] = Hnum[k];
1001 snew( restp->atomname[at_start+1+k], 1);
1002 restp->atom [at_start+1+k] = *hack->atom;
1003 *restp->atomname[at_start+1+k] = gmx_strdup(buf);
1004 if (hack->cgnr != NOTSET)
1006 restp->cgnr [at_start+1+k] = hack->cgnr;
1010 restp->cgnr [at_start+1+k] = restp->cgnr[at_start];
1015 void get_hackblocks_rtp(t_hackblock **hb, t_restp **restp,
1016 int nrtp, t_restp rtp[],
1017 int nres, t_resinfo *resinfo,
1019 t_hackblock **ntdb, t_hackblock **ctdb,
1030 /* first the termini */
1031 for (i = 0; i < nterpairs; i++)
1033 if (rn[i] >= 0 && ntdb[i] != NULL)
1035 copy_t_hackblock(ntdb[i], &(*hb)[rn[i]]);
1037 if (rc[i] >= 0 && ctdb[i] != NULL)
1039 merge_t_hackblock(ctdb[i], &(*hb)[rc[i]]);
1043 /* then the whole rtp */
1044 for (i = 0; i < nres; i++)
1046 /* Here we allow a mismatch of one character when looking for the rtp entry.
1047 * For such a mismatch there should be only one mismatching name.
1048 * This is mainly useful for small molecules such as ions.
1049 * Note that this will usually not work for protein, DNA and RNA,
1050 * since there the residue names should be listed in residuetypes.dat
1051 * and an error will have been generated earlier in the process.
1053 key = *resinfo[i].rtp;
1054 snew(resinfo[i].rtp, 1);
1055 *resinfo[i].rtp = search_rtp(key, nrtp, rtp);
1056 res = get_restp(*resinfo[i].rtp, nrtp, rtp);
1057 copy_t_restp(res, &(*restp)[i]);
1059 /* Check that we do not have different bonded types in one molecule */
1060 check_restp_types(&(*restp)[0], &(*restp)[i]);
1063 for (j = 0; j < nterpairs && tern == -1; j++)
1071 for (j = 0; j < nterpairs && terc == -1; j++)
1078 bRM = merge_t_bondeds(res->rb, (*hb)[i].rb, tern >= 0, terc >= 0);
1080 if (bRM && ((tern >= 0 && ntdb[tern] == NULL) ||
1081 (terc >= 0 && ctdb[terc] == NULL)))
1083 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).");
1085 if (bRM && ((tern >= 0 && ntdb[tern]->nhack == 0) ||
1086 (terc >= 0 && ctdb[terc]->nhack == 0)))
1088 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.");
1092 /* now perform t_hack's on t_restp's,
1093 i.e. add's and deletes from termini database will be
1094 added to/removed from residue topology
1095 we'll do this on one big dirty loop, so it won't make easy reading! */
1096 for (i = 0; i < nres; i++)
1098 for (j = 0; j < (*hb)[i].nhack; j++)
1100 if ( (*hb)[i].hack[j].nr)
1102 /* find atom in restp */
1103 for (l = 0; l < (*restp)[i].natom; l++)
1105 if ( ( (*hb)[i].hack[j].oname == NULL &&
1106 strcmp((*hb)[i].hack[j].a[0], *(*restp)[i].atomname[l]) == 0 ) ||
1107 ( (*hb)[i].hack[j].oname != NULL &&
1108 strcmp((*hb)[i].hack[j].oname, *(*restp)[i].atomname[l]) == 0 ) )
1113 if (l == (*restp)[i].natom)
1115 /* If we are doing an atom rename only, we don't need
1116 * to generate a fatal error if the old name is not found
1119 /* Deleting can happen also only on the input atoms,
1120 * not necessarily always on the rtp entry.
1122 if (!((*hb)[i].hack[j].oname != NULL &&
1123 (*hb)[i].hack[j].nname != NULL) &&
1124 !((*hb)[i].hack[j].oname != NULL &&
1125 (*hb)[i].hack[j].nname == NULL))
1128 "atom %s not found in buiding block %d%s "
1129 "while combining tdb and rtp",
1130 (*hb)[i].hack[j].oname != NULL ?
1131 (*hb)[i].hack[j].oname : (*hb)[i].hack[j].a[0],
1132 i+1, *resinfo[i].rtp);
1137 if ( (*hb)[i].hack[j].oname == NULL)
1140 add_atom_to_restp(&(*restp)[i], l, &(*hb)[i].hack[j]);
1145 if ( (*hb)[i].hack[j].nname == NULL)
1147 /* we're deleting */
1150 fprintf(debug, "deleting atom %s from res %d%s in rtp\n",
1151 *(*restp)[i].atomname[l],
1152 i+1, (*restp)[i].resname);
1154 /* shift the rest */
1155 (*restp)[i].natom--;
1156 for (k = l; k < (*restp)[i].natom; k++)
1158 (*restp)[i].atom [k] = (*restp)[i].atom [k+1];
1159 (*restp)[i].atomname[k] = (*restp)[i].atomname[k+1];
1160 (*restp)[i].cgnr [k] = (*restp)[i].cgnr [k+1];
1162 /* give back space */
1163 srenew((*restp)[i].atom, (*restp)[i].natom);
1164 srenew((*restp)[i].atomname, (*restp)[i].natom);
1165 srenew((*restp)[i].cgnr, (*restp)[i].natom);
1167 else /* nname != NULL */
1168 { /* we're replacing */
1171 fprintf(debug, "replacing atom %s by %s in res %d%s in rtp\n",
1172 *(*restp)[i].atomname[l], (*hb)[i].hack[j].nname,
1173 i+1, (*restp)[i].resname);
1175 snew( (*restp)[i].atomname[l], 1);
1176 (*restp)[i].atom[l] = *(*hb)[i].hack[j].atom;
1177 *(*restp)[i].atomname[l] = gmx_strdup((*hb)[i].hack[j].nname);
1178 if ( (*hb)[i].hack[j].cgnr != NOTSET)
1180 (*restp)[i].cgnr [l] = (*hb)[i].hack[j].cgnr;
1190 static gmx_bool atomname_cmp_nr(const char *anm, t_hack *hack, int *nr)
1197 return (gmx_strcasecmp(anm, hack->nname) == 0);
1201 if (isdigit(anm[strlen(anm)-1]))
1203 *nr = anm[strlen(anm)-1] - '0';
1209 if (*nr <= 0 || *nr > hack->nr)
1215 return (strlen(anm) == strlen(hack->nname) + 1 &&
1216 gmx_strncasecmp(anm, hack->nname, strlen(hack->nname)) == 0);
1221 static gmx_bool match_atomnames_with_rtp_atom(t_atoms *pdba, rvec *x, int atind,
1222 t_restp *rptr, t_hackblock *hbr,
1227 char *oldnm, *newnm;
1229 char *start_at, buf[STRLEN];
1231 gmx_bool bReplaceReplace, bFoundInAdd;
1234 oldnm = *pdba->atomname[atind];
1235 resnr = pdba->resinfo[pdba->atom[atind].resind].nr;
1238 for (j = 0; j < hbr->nhack; j++)
1240 if (hbr->hack[j].oname != NULL && hbr->hack[j].nname != NULL &&
1241 gmx_strcasecmp(oldnm, hbr->hack[j].oname) == 0)
1243 /* This is a replace entry. */
1244 /* Check if we are not replacing a replaced atom. */
1245 bReplaceReplace = FALSE;
1246 for (k = 0; k < hbr->nhack; k++)
1249 hbr->hack[k].oname != NULL && hbr->hack[k].nname != NULL &&
1250 gmx_strcasecmp(hbr->hack[k].nname, hbr->hack[j].oname) == 0)
1252 /* The replace in hack[j] replaces an atom that
1253 * was already replaced in hack[k], we do not want
1254 * second or higher level replaces at this stage.
1256 bReplaceReplace = TRUE;
1259 if (bReplaceReplace)
1261 /* Skip this replace. */
1265 /* This atom still has the old name, rename it */
1266 newnm = hbr->hack[j].nname;
1267 for (k = 0; k < rptr->natom; k++)
1269 if (gmx_strcasecmp(newnm, *rptr->atomname[k]) == 0)
1274 if (k == rptr->natom)
1276 /* The new name is not present in the rtp.
1277 * We need to apply the replace also to the rtp entry.
1280 /* We need to find the add hack that can add this atom
1281 * to find out after which atom it should be added.
1283 bFoundInAdd = FALSE;
1284 for (k = 0; k < hbr->nhack; k++)
1286 if (hbr->hack[k].oname == NULL &&
1287 hbr->hack[k].nname != NULL &&
1288 atomname_cmp_nr(newnm, &hbr->hack[k], &anmnr))
1292 start_at = hbr->hack[k].a[0];
1296 sprintf(buf, "%s%d", hbr->hack[k].nname, anmnr-1);
1299 for (start_nr = 0; start_nr < rptr->natom; start_nr++)
1301 if (gmx_strcasecmp(start_at, (*rptr->atomname[start_nr])) == 0)
1306 if (start_nr == rptr->natom)
1308 gmx_fatal(FARGS, "Could not find atom '%s' in residue building block '%s' to add atom '%s' to",
1309 start_at, rptr->resname, newnm);
1311 /* We can add the atom after atom start_nr */
1312 add_atom_to_restp(rptr, start_nr, &hbr->hack[j]);
1320 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'",
1322 hbr->hack[j].oname, hbr->hack[j].nname,
1329 printf("Renaming atom '%s' in residue '%s' %d to '%s'\n",
1330 oldnm, rptr->resname, resnr, newnm);
1332 /* Rename the atom in pdba */
1333 snew(pdba->atomname[atind], 1);
1334 *pdba->atomname[atind] = gmx_strdup(newnm);
1336 else if (hbr->hack[j].oname != NULL && hbr->hack[j].nname == NULL &&
1337 gmx_strcasecmp(oldnm, hbr->hack[j].oname) == 0)
1339 /* This is a delete entry, check if this atom is present
1340 * in the rtp entry of this residue.
1342 for (k = 0; k < rptr->natom; k++)
1344 if (gmx_strcasecmp(oldnm, *rptr->atomname[k]) == 0)
1349 if (k == rptr->natom)
1351 /* This atom is not present in the rtp entry,
1352 * delete is now from the input pdba.
1356 printf("Deleting atom '%s' in residue '%s' %d\n",
1357 oldnm, rptr->resname, resnr);
1359 /* We should free the atom name,
1360 * but it might be used multiple times in the symtab.
1361 * sfree(pdba->atomname[atind]);
1363 for (k = atind+1; k < pdba->nr; k++)
1365 pdba->atom[k-1] = pdba->atom[k];
1366 pdba->atomname[k-1] = pdba->atomname[k];
1367 copy_rvec(x[k], x[k-1]);
1378 void match_atomnames_with_rtp(t_restp restp[], t_hackblock hb[],
1379 t_atoms *pdba, rvec *x,
1386 for (i = 0; i < pdba->nr; i++)
1388 oldnm = *pdba->atomname[i];
1389 rptr = &restp[pdba->atom[i].resind];
1390 for (j = 0; (j < rptr->natom); j++)
1392 if (gmx_strcasecmp(oldnm, *(rptr->atomname[j])) == 0)
1397 if (j == rptr->natom)
1399 /* Not found yet, check if we have to rename this atom */
1400 if (match_atomnames_with_rtp_atom(pdba, x, i,
1401 rptr, &(hb[pdba->atom[i].resind]),
1404 /* We deleted this atom, decrease the atom counter by 1. */
1411 #define NUM_CMAP_ATOMS 5
1412 static void gen_cmap(t_params *psb, t_restp *restp, t_atoms *atoms)
1414 int residx, i, j, k;
1417 t_resinfo *resinfo = atoms->resinfo;
1418 int nres = atoms->nres;
1420 atom_id cmap_atomid[NUM_CMAP_ATOMS];
1421 int cmap_chainnum = -1, this_residue_index;
1432 fprintf(stderr, "Making cmap torsions...\n");
1434 /* Most cmap entries use the N atom from the next residue, so the last
1435 * residue should not have its CMAP entry in that case, but for things like
1436 * dipeptides we sometimes define a complete CMAP entry inside a residue,
1437 * and in this case we need to process everything through the last residue.
1439 for (residx = 0; residx < nres; residx++)
1441 /* Add CMAP terms from the list of CMAP interactions */
1442 for (j = 0; j < restp[residx].rb[ebtsCMAP].nb; j++)
1445 /* Loop over atoms in a candidate CMAP interaction and
1446 * check that they exist, are from the same chain and are
1447 * from residues labelled as protein. */
1448 for (k = 0; k < NUM_CMAP_ATOMS && bAddCMAP; k++)
1450 /* Assign the pointer to the name of the next reference atom.
1451 * This can use -/+ labels to refer to previous/next residue.
1453 pname = restp[residx].rb[ebtsCMAP].b[j].a[k];
1454 /* Skip this CMAP entry if it refers to residues before the
1455 * first or after the last residue.
1457 if (((strchr(pname, '-') != NULL) && (residx == 0)) ||
1458 ((strchr(pname, '+') != NULL) && (residx == nres-1)))
1464 cmap_atomid[k] = search_atom(pname,
1465 i, atoms, ptr, TRUE);
1466 bAddCMAP = bAddCMAP && (cmap_atomid[k] != NO_ATID);
1469 /* This break is necessary, because cmap_atomid[k]
1470 * == NO_ATID cannot be safely used as an index
1471 * into the atom array. */
1474 this_residue_index = atoms->atom[cmap_atomid[k]].resind;
1477 cmap_chainnum = resinfo[this_residue_index].chainnum;
1481 /* Does the residue for this atom have the same
1482 * chain number as the residues for previous
1484 bAddCMAP = bAddCMAP &&
1485 cmap_chainnum == resinfo[this_residue_index].chainnum;
1487 /* Here we used to check that the residuetype was protein and
1488 * disable bAddCMAP if that was not the case. However, some
1489 * special residues (say, alanine dipeptides) might not adhere
1490 * to standard naming, and if we start calling them normal
1491 * protein residues the user will be bugged to select termini.
1493 * Instead, I believe that the right course of action is to
1494 * keep the CMAP interaction if it is present in the RTP file
1495 * and we correctly identified all atoms (which is the case
1502 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);
1506 if (residx < nres-1)
1508 while (atoms->atom[i].resind < residx+1)
1514 /* Start the next residue */
1518 scrub_charge_groups(int *cgnr, int natoms)
1522 for (i = 0; i < natoms; i++)
1529 void pdb2top(FILE *top_file, char *posre_fn, char *molname,
1530 t_atoms *atoms, rvec **x, gpp_atomtype_t atype, t_symtab *tab,
1531 int nrtp, t_restp rtp[],
1532 t_restp *restp, t_hackblock *hb,
1533 gmx_bool bAllowMissing,
1534 gmx_bool bVsites, gmx_bool bVsiteAromatics,
1537 int nssbonds, t_ssbond *ssbonds,
1538 real long_bond_dist, real short_bond_dist,
1539 gmx_bool bDeuterate, gmx_bool bChargeGroups, gmx_bool bCmap,
1540 gmx_bool bRenumRes, gmx_bool bRTPresname)
1546 t_params plist[F_NRE];
1553 gmx_residuetype_t*rt;
1556 gmx_residuetype_init(&rt);
1560 print_resall(debug, atoms->nres, restp, atype);
1561 dump_hb(debug, atoms->nres, hb);
1565 at2bonds(&(plist[F_BONDS]), hb,
1567 long_bond_dist, short_bond_dist);
1569 /* specbonds: disulphide bonds & heme-his */
1570 do_ssbonds(&(plist[F_BONDS]),
1571 atoms, nssbonds, ssbonds,
1574 nmissat = name2type(atoms, &cgnr, restp, rt);
1579 fprintf(stderr, "There were %d missing atoms in molecule %s\n",
1584 gmx_fatal(FARGS, "There were %d missing atoms in molecule %s, if you want to use this incomplete topology anyhow, use the option -missing",
1589 /* Cleanup bonds (sort and rm doubles) */
1590 clean_bonds(&(plist[F_BONDS]));
1592 snew(vsite_type, atoms->nr);
1593 for (i = 0; i < atoms->nr; i++)
1595 vsite_type[i] = NOTSET;
1599 /* determine which atoms will be vsites and add dummy masses
1600 also renumber atom numbers in plist[0..F_NRE]! */
1601 do_vsites(nrtp, rtp, atype, atoms, tab, x, plist,
1602 &vsite_type, &cgnr, mHmult, bVsiteAromatics, ffdir);
1605 /* Make Angles and Dihedrals */
1606 fprintf(stderr, "Generating angles, dihedrals and pairs...\n");
1607 snew(excls, atoms->nr);
1608 init_nnb(&nnb, atoms->nr, 4);
1609 gen_nnb(&nnb, plist);
1610 print_nnb(&nnb, "NNB");
1611 gen_pad(&nnb, atoms, restp, plist, excls, hb, bAllowMissing);
1617 gen_cmap(&(plist[F_CMAP]), restp, atoms);
1618 if (plist[F_CMAP].nr > 0)
1620 fprintf(stderr, "There are %4d cmap torsion pairs\n",
1625 /* set mass of all remaining hydrogen atoms */
1628 do_h_mass(&(plist[F_BONDS]), vsite_type, atoms, mHmult, bDeuterate);
1632 /* Cleanup bonds (sort and rm doubles) */
1633 /* clean_bonds(&(plist[F_BONDS]));*/
1636 "There are %4d dihedrals, %4d impropers, %4d angles\n"
1637 " %4d pairs, %4d bonds and %4d virtual sites\n",
1638 plist[F_PDIHS].nr, plist[F_IDIHS].nr, plist[F_ANGLES].nr,
1639 plist[F_LJ14].nr, plist[F_BONDS].nr,
1640 plist[F_VSITE2].nr +
1641 plist[F_VSITE3].nr +
1642 plist[F_VSITE3FD].nr +
1643 plist[F_VSITE3FAD].nr +
1644 plist[F_VSITE3OUT].nr +
1645 plist[F_VSITE4FD].nr +
1646 plist[F_VSITE4FDN].nr );
1648 print_sums(atoms, FALSE);
1650 if (FALSE == bChargeGroups)
1652 scrub_charge_groups(cgnr, atoms->nr);
1657 for (i = 0; i < atoms->nres; i++)
1659 atoms->resinfo[i].nr = i + 1;
1660 atoms->resinfo[i].ic = ' ';
1666 fprintf(stderr, "Writing topology\n");
1667 /* We can copy the bonded types from the first restp,
1668 * since the types have to be identical for all residues in one molecule.
1670 for (i = 0; i < ebtsNR; i++)
1672 bts[i] = restp[0].rb[i].type;
1674 write_top(top_file, posre_fn, molname,
1676 bts, plist, excls, atype, cgnr, restp[0].nrexcl);
1680 free_t_hackblock(atoms->nres, &hb);
1681 free_t_restp(atoms->nres, &restp);
1682 gmx_residuetype_destroy(rt);
1684 /* we should clean up hb and restp here, but that is a *L*O*T* of work! */
1686 for (i = 0; i < F_NRE; i++)
1688 sfree(plist[i].param);
1690 for (i = 0; i < atoms->nr; i++)