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 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
41 #include "gmx_header_config.h"
47 #ifdef GMX_NATIVE_WINDOWS
60 #include "gmx_fatal.h"
62 #include "gpp_nextnb.h"
75 #include "gen_vsite.h"
78 #include "fflibutil.h"
81 /* this must correspond to enum in pdb2top.h */
82 const char *hh[ehisNR] = { "HISD", "HISE", "HISH", "HIS1" };
84 static int missing_atoms(t_restp *rp, int resind,t_atoms *at, int i0, int i)
88 gmx_bool bFound, bRet;
91 for (j=0; j<rp->natom; j++)
93 name=*(rp->atomname[j]);
97 bFound = (bFound || !gmx_strcasecmp(*(at->atomname[k]),name));
102 fprintf(stderr,"\nWARNING: "
103 "atom %s is missing in residue %s %d in the pdb file\n",
104 name,*(at->resinfo[resind].name),at->resinfo[resind].nr);
105 if (name[0]=='H' || name[0]=='h')
107 fprintf(stderr," You might need to add atom %s to the hydrogen database of building block %s\n"
108 " in the file %s.hdb (see the manual)\n",
109 name,*(at->resinfo[resind].rtp),rp->filebase);
111 fprintf(stderr,"\n");
118 gmx_bool is_int(double x)
120 const double tol = 1e-4;
127 return (fabs(x-ix) < tol);
130 static void swap_strings(char **s,int i,int j)
140 choose_ff(const char *ffsel,
141 char *forcefield, int ff_maxlen,
142 char *ffdir, int ffdir_maxlen)
145 char **ffdirs,**ffs,**ffs_dir,*ptr;
146 int i,j,sel,cwdsel,nfound;
147 char buf[STRLEN],**desc;
151 nff = fflib_search_file_in_dirend(fflib_forcefield_itp(),
152 fflib_forcefield_dir_ext(),
157 gmx_fatal(FARGS,"No force fields found (files with name '%s' in subdirectories ending on '%s')",
158 fflib_forcefield_itp(),fflib_forcefield_dir_ext());
161 /* Replace with unix path separators */
162 if(DIR_SEPARATOR!='/')
166 while( (ptr=strchr(ffdirs[i],DIR_SEPARATOR))!=NULL )
173 /* Store the force field names in ffs */
178 /* Remove the path from the ffdir name - use our unix standard here! */
179 ptr = strrchr(ffdirs[i],'/');
182 ffs[i] = strdup(ffdirs[i]);
183 ffs_dir[i] = low_gmxlibfn(ffdirs[i],FALSE,FALSE);
184 if (ffs_dir[i] == NULL)
186 gmx_fatal(FARGS,"Can no longer find file '%s'",ffdirs[i]);
191 ffs[i] = strdup(ptr+1);
192 ffs_dir[i] = strdup(ffdirs[i]);
194 ffs_dir[i][strlen(ffs_dir[i])-strlen(ffs[i])-1] = '\0';
195 /* Remove the extension from the ffdir name */
196 ffs[i][strlen(ffs[i])-strlen(fflib_forcefield_dir_ext())] = '\0';
206 if ( strcmp(ffs[i],ffsel)==0 )
208 /* Matching ff name */
212 if( strncmp(ffs_dir[i],".",1)==0 )
229 "Force field '%s' occurs in %d places. pdb2gmx is using the one in the\n"
230 "current directory. Use interactive selection (not the -ff option) if\n"
231 "you would prefer a different one.\n",ffsel,nfound);
236 "Force field '%s' occurs in %d places, but not in the current directory.\n"
237 "Run without the -ff switch and select the force field interactively.",ffsel,nfound);
242 gmx_fatal(FARGS,"Could not find force field '%s' in current directory, install tree or GMXDATA path.",ffsel);
248 for(i=0; (i<nff); i++)
250 sprintf(buf,"%s%c%s%s%c%s",
251 ffs_dir[i],DIR_SEPARATOR,
252 ffs[i],fflib_forcefield_dir_ext(),DIR_SEPARATOR,
253 fflib_forcefield_doc());
256 /* We don't use fflib_open, because we don't want printf's */
257 fp = ffopen(buf,"r");
258 snew(desc[i],STRLEN);
259 get_a_line(fp,desc[i],STRLEN);
264 desc[i] = strdup(ffs[i]);
267 /* Order force fields from the same dir alphabetically
268 * and put deprecated force fields at the end.
270 for(i=0; (i<nff); i++)
272 for(j=i+1; (j<nff); j++)
274 if (strcmp(ffs_dir[i],ffs_dir[j]) == 0 &&
275 ((desc[i][0] == '[' && desc[j][0] != '[') ||
276 ((desc[i][0] == '[' || desc[j][0] != '[') &&
277 gmx_strcasecmp(desc[i],desc[j]) > 0)))
279 swap_strings(ffdirs,i,j);
280 swap_strings(ffs ,i,j);
281 swap_strings(desc ,i,j);
286 printf("\nSelect the Force Field:\n");
287 for(i=0; (i<nff); i++)
289 if (i == 0 || strcmp(ffs_dir[i-1],ffs_dir[i]) != 0)
291 if( strcmp(ffs_dir[i],".")==0 )
293 printf("From current directory:\n");
297 printf("From '%s':\n",ffs_dir[i]);
300 printf("%2d: %s\n",i+1,desc[i]);
307 pret = fgets(buf,STRLEN,stdin);
311 sscanf(buf,"%d",&sel);
315 while ( pret==NULL || (sel < 0) || (sel >= nff));
317 /* Check for a current limitation of the fflib code.
318 * It will always read from the first ff directory in the list.
319 * This check assumes that the order of ffs matches the order
320 * in which fflib_open searches ff library files.
324 if (strcmp(ffs[i],ffs[sel]) == 0)
326 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.",
327 ffs[sel],fflib_forcefield_dir_ext());
336 if (strlen(ffs[sel]) >= (size_t)ff_maxlen)
338 gmx_fatal(FARGS,"Length of force field name (%d) >= maxlen (%d)",
339 strlen(ffs[sel]),ff_maxlen);
341 strcpy(forcefield,ffs[sel]);
343 if (strlen(ffdirs[sel]) >= (size_t)ffdir_maxlen)
345 gmx_fatal(FARGS,"Length of force field dir (%d) >= maxlen (%d)",
346 strlen(ffdirs[sel]),ffdir_maxlen);
348 strcpy(ffdir,ffdirs[sel]);
350 for(i=0; (i<nff); i++)
361 void choose_watermodel(const char *wmsel,const char *ffdir,
364 const char *fn_watermodels="watermodels.dat";
365 char fn_list[STRLEN];
372 if (strcmp(wmsel,"none") == 0)
378 else if (strcmp(wmsel,"select") != 0)
380 *watermodel = strdup(wmsel);
385 sprintf(fn_list,"%s%c%s",ffdir,DIR_SEPARATOR,fn_watermodels);
387 if (!fflib_fexist(fn_list))
389 fprintf(stderr,"No file '%s' found, will not include a water model\n",
396 fp = fflib_open(fn_list);
397 printf("\nSelect the Water Model:\n");
400 while (get_a_line(fp,buf,STRLEN))
403 snew(model[nwm],STRLEN);
404 sscanf(buf,"%s%n",model[nwm],&i);
408 fprintf(stderr,"%2d: %s\n",nwm+1,buf+i);
417 fprintf(stderr,"%2d: %s\n",nwm+1,"None");
421 pret = fgets(buf,STRLEN,stdin);
425 sscanf(buf,"%d",&sel);
429 while (pret == NULL || sel < 0 || sel > nwm);
437 *watermodel = strdup(model[sel]);
447 static int name2type(t_atoms *at, int **cgnr, gpp_atomtype_t atype,
448 t_restp restp[], gmx_residuetype_t rt)
450 int i,j,prevresind,resind,i0,prevcg,cg,curcg;
452 gmx_bool bProt, bNterm;
469 for(i=0; (i<at->nr); i++) {
471 if (at->atom[i].resind != resind) {
472 resind = at->atom[i].resind;
473 bProt = gmx_residuetype_is_protein(rt,*(at->resinfo[resind].name));
474 bNterm=bProt && (resind == 0);
476 nmissat += missing_atoms(&restp[prevresind],prevresind,at,i0,i);
480 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]);
487 name=*(at->atomname[i]);
488 j=search_jtype(&restp[resind],name,bNterm);
489 at->atom[i].type = restp[resind].atom[j].type;
490 at->atom[i].q = restp[resind].atom[j].q;
491 at->atom[i].m = get_atomtype_massA(restp[resind].atom[j].type,
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) ) {
502 fprintf(debug,"atom %d%s: curcg=%d, qt=%g, is_int=%d\n",
503 i+1,*(at->atomname[i]),curcg,qt,is_int(qt));
512 at->atom[i].typeB = at->atom[i].type;
513 at->atom[i].qB = at->atom[i].q;
514 at->atom[i].mB = at->atom[i].m;
516 nmissat += missing_atoms(&restp[resind],resind,at,i0,i);
521 static void print_top_heavy_H(FILE *out, real mHmult)
524 fprintf(out,"; Using deuterium instead of hydrogen\n\n");
525 else if (mHmult == 4.0)
526 fprintf(out,"#define HEAVY_H\n\n");
527 else if (mHmult != 1.0)
528 fprintf(stderr,"WARNING: unsupported proton mass multiplier (%g) "
529 "in pdb2top\n",mHmult);
532 void print_top_comment(FILE *out,
533 const char *filename,
534 const char *generator,
539 char ffdir_parent[STRLEN];
542 nice_header(out,filename);
543 fprintf(out,";\tThis is a %s topology file\n;\n",bITP ? "include" : "standalone");
544 fprintf(out,";\tIt was generated using program:\n;\t%s\n;\n",
545 (NULL == generator) ? "unknown" : generator);
546 fprintf(out,";\tCommand line was:\n;\t%s\n;\n",command_line());
548 if(strchr(ffdir,'/')==NULL)
550 fprintf(out,";\tForce field was read from the standard Gromacs share directory.\n;\n\n");
552 else if(ffdir[0]=='.')
554 fprintf(out,";\tForce field was read from current directory or a relative path - path added.\n;\n\n");
558 strncpy(ffdir_parent,ffdir,STRLEN-1);
559 ffdir_parent[STRLEN-1]='\0'; /*make sure it is 0-terminated even for long string*/
560 p=strrchr(ffdir_parent,'/');
565 ";\tForce field data was read from:\n"
569 ";\tThis might be a non-standard force field location. When you use this topology, the\n"
570 ";\tforce field must either be present in the current directory, or the location\n"
571 ";\tspecified in the GMXLIB path variable or with the 'include' mdp file option.\n;\n\n",
576 void print_top_header(FILE *out,const char *filename,
577 const char *title,gmx_bool bITP,const char *ffdir,real mHmult)
581 print_top_comment(out,filename,title,ffdir,bITP);
583 print_top_heavy_H(out, mHmult);
584 fprintf(out,"; Include forcefield parameters\n");
586 p=strrchr(ffdir,'/');
587 p = (ffdir[0]=='.' || p==NULL) ? ffdir : p+1;
589 fprintf(out,"#include \"%s/%s\"\n\n",p,fflib_forcefield_itp());
592 static void print_top_posre(FILE *out,const char *pr)
594 fprintf(out,"; Include Position restraint file\n");
595 fprintf(out,"#ifdef POSRES\n");
596 fprintf(out,"#include \"%s\"\n",pr);
597 fprintf(out,"#endif\n\n");
600 static void print_top_water(FILE *out,const char *ffdir,const char *water)
605 fprintf(out,"; Include water topology\n");
607 p=strrchr(ffdir,'/');
608 p = (ffdir[0]=='.' || p==NULL) ? ffdir : p+1;
609 fprintf(out,"#include \"%s/%s.itp\"\n",p,water);
612 fprintf(out,"#ifdef POSRES_WATER\n");
613 fprintf(out,"; Position restraint for each water oxygen\n");
614 fprintf(out,"[ position_restraints ]\n");
615 fprintf(out,";%3s %5s %9s %10s %10s\n","i","funct","fcx","fcy","fcz");
616 fprintf(out,"%4d %4d %10g %10g %10g\n",1,1,1000.0,1000.0,1000.0);
617 fprintf(out,"#endif\n");
620 sprintf(buf,"%s/ions.itp",p);
622 if (fflib_fexist(buf))
624 fprintf(out,"; Include topology for ions\n");
625 fprintf(out,"#include \"%s\"\n",buf);
630 static void print_top_system(FILE *out, const char *title)
632 fprintf(out,"[ %s ]\n",dir2str(d_system));
633 fprintf(out,"; Name\n");
634 fprintf(out,"%s\n\n",title[0]?title:"Protein");
637 void print_top_mols(FILE *out,
638 const char *title, const char *ffdir, const char *water,
639 int nincl, char **incls, int nmol, t_mols *mols)
645 fprintf(out,"; Include chain topologies\n");
646 for (i=0; (i<nincl); i++) {
647 incl = strrchr(incls[i],DIR_SEPARATOR);
651 /* Remove the path from the include name */
654 fprintf(out,"#include \"%s\"\n",incl);
661 print_top_water(out,ffdir,water);
663 print_top_system(out, title);
666 fprintf(out,"[ %s ]\n",dir2str(d_molecules));
667 fprintf(out,"; %-15s %5s\n","Compound","#mols");
668 for (i=0; (i<nmol); i++)
669 fprintf(out,"%-15s %5d\n",mols[i].name,mols[i].nr);
673 void write_top(FILE *out, char *pr,char *molname,
674 t_atoms *at,gmx_bool bRTPresname,
675 int bts[],t_params plist[],t_excls excls[],
676 gpp_atomtype_t atype,int *cgnr, int nrexcl)
677 /* NOTE: nrexcl is not the size of *excl! */
679 if (at && atype && cgnr) {
680 fprintf(out,"[ %s ]\n",dir2str(d_moleculetype));
681 fprintf(out,"; %-15s %5s\n","Name","nrexcl");
682 fprintf(out,"%-15s %5d\n\n",molname?molname:"Protein",nrexcl);
684 print_atoms(out, atype, at, cgnr, bRTPresname);
685 print_bondeds(out,at->nr,d_bonds, F_BONDS, bts[ebtsBONDS], plist);
686 print_bondeds(out,at->nr,d_constraints,F_CONSTR, 0, plist);
687 print_bondeds(out,at->nr,d_constraints,F_CONSTRNC, 0, plist);
688 print_bondeds(out,at->nr,d_pairs, F_LJ14, 0, plist);
689 print_excl(out,at->nr,excls);
690 print_bondeds(out,at->nr,d_angles, F_ANGLES, bts[ebtsANGLES],plist);
691 print_bondeds(out,at->nr,d_dihedrals, F_PDIHS, bts[ebtsPDIHS], plist);
692 print_bondeds(out,at->nr,d_dihedrals, F_IDIHS, bts[ebtsIDIHS], plist);
693 print_bondeds(out,at->nr,d_cmap, F_CMAP, bts[ebtsCMAP], plist);
694 print_bondeds(out,at->nr,d_polarization,F_POLARIZATION, 0, plist);
695 print_bondeds(out,at->nr,d_thole_polarization,F_THOLE_POL,0, plist);
696 print_bondeds(out,at->nr,d_vsites2, F_VSITE2, 0, plist);
697 print_bondeds(out,at->nr,d_vsites3, F_VSITE3, 0, plist);
698 print_bondeds(out,at->nr,d_vsites3, F_VSITE3FD, 0, plist);
699 print_bondeds(out,at->nr,d_vsites3, F_VSITE3FAD,0, plist);
700 print_bondeds(out,at->nr,d_vsites3, F_VSITE3OUT,0, plist);
701 print_bondeds(out,at->nr,d_vsites4, F_VSITE4FD, 0, plist);
702 print_bondeds(out,at->nr,d_vsites4, F_VSITE4FDN, 0, plist);
705 print_top_posre(out,pr);
709 static atom_id search_res_atom(const char *type,int resind,
711 const char *bondtype,gmx_bool bAllowMissing)
715 for(i=0; (i<atoms->nr); i++)
717 if (atoms->atom[i].resind == resind)
719 return search_atom(type,i,atoms,bondtype,bAllowMissing);
726 static void do_ssbonds(t_params *ps,t_atoms *atoms,
727 int nssbonds,t_ssbond *ssbonds,gmx_bool bAllowMissing)
732 for(i=0; (i<nssbonds); i++) {
733 ri = ssbonds[i].res1;
734 rj = ssbonds[i].res2;
735 ai = search_res_atom(ssbonds[i].a1,ri,atoms,
736 "special bond",bAllowMissing);
737 aj = search_res_atom(ssbonds[i].a2,rj,atoms,
738 "special bond",bAllowMissing);
739 if ((ai == NO_ATID) || (aj == NO_ATID))
740 gmx_fatal(FARGS,"Trying to make impossible special bond (%s-%s)!",
741 ssbonds[i].a1,ssbonds[i].a2);
742 add_param(ps,ai,aj,NULL,NULL);
746 static void at2bonds(t_params *psb, t_hackblock *hb,
749 real long_bond_dist, real short_bond_dist,
750 gmx_bool bAllowMissing)
754 real dist2, long_bond_dist2, short_bond_dist2;
757 long_bond_dist2 = sqr(long_bond_dist);
758 short_bond_dist2 = sqr(short_bond_dist);
765 fprintf(stderr,"Making bonds...\n");
767 for(resind=0; (resind < atoms->nres) && (i<atoms->nr); resind++) {
768 /* add bonds from list of bonded interactions */
769 for(j=0; j < hb[resind].rb[ebtsBONDS].nb; j++) {
770 /* Unfortunately we can not issue errors or warnings
771 * for missing atoms in bonds, as the hydrogens and terminal atoms
772 * have not been added yet.
774 ai=search_atom(hb[resind].rb[ebtsBONDS].b[j].AI,i,atoms,
776 aj=search_atom(hb[resind].rb[ebtsBONDS].b[j].AJ,i,atoms,
778 if (ai != NO_ATID && aj != NO_ATID) {
779 dist2 = distance2(x[ai],x[aj]);
780 if (dist2 > long_bond_dist2 )
782 fprintf(stderr,"Warning: Long Bond (%d-%d = %g nm)\n",
783 ai+1,aj+1,sqrt(dist2));
785 else if (dist2 < short_bond_dist2 )
787 fprintf(stderr,"Warning: Short Bond (%d-%d = %g nm)\n",
788 ai+1,aj+1,sqrt(dist2));
790 add_param(psb,ai,aj,NULL,hb[resind].rb[ebtsBONDS].b[j].s);
793 /* add bonds from list of hacks (each added atom gets a bond) */
794 while( (i<atoms->nr) && (atoms->atom[i].resind == resind) ) {
795 for(j=0; j < hb[resind].nhack; j++)
796 if ( ( hb[resind].hack[j].tp > 0 ||
797 hb[resind].hack[j].oname==NULL ) &&
798 strcmp(hb[resind].hack[j].AI,*(atoms->atomname[i])) == 0 ) {
799 switch(hb[resind].hack[j].tp) {
800 case 9: /* COOH terminus */
801 add_param(psb,i,i+1,NULL,NULL); /* C-O */
802 add_param(psb,i,i+2,NULL,NULL); /* C-OA */
803 add_param(psb,i+2,i+3,NULL,NULL); /* OA-H */
806 for(k=0; (k<hb[resind].hack[j].nr); k++)
807 add_param(psb,i,i+k+1,NULL,NULL);
812 /* we're now at the start of the next residue */
816 static int pcompar(const void *a, const void *b)
827 return strlen(pb->s) - strlen(pa->s);
832 static void clean_bonds(t_params *ps)
838 /* swap atomnumbers in bond if first larger than second: */
839 for(i=0; (i<ps->nr); i++)
840 if ( ps->param[i].AJ < ps->param[i].AI ) {
842 ps->param[i].AI = ps->param[i].AJ;
847 qsort(ps->param,ps->nr,(size_t)sizeof(ps->param[0]),pcompar);
849 /* remove doubles, keep the first one always. */
851 for(i=1; (i<ps->nr); i++) {
852 if ((ps->param[i].AI != ps->param[j-1].AI) ||
853 (ps->param[i].AJ != ps->param[j-1].AJ) ) {
855 cp_param(&(ps->param[j]),&(ps->param[i]));
860 fprintf(stderr,"Number of bonds was %d, now %d\n",ps->nr,j);
864 fprintf(stderr,"No bonds\n");
867 void print_sums(t_atoms *atoms, gmx_bool bSystem)
880 for(i=0; (i<atoms->nr); i++) {
882 qtot+=atoms->atom[i].q;
885 fprintf(stderr,"Total mass%s %.3f a.m.u.\n",where,m);
886 fprintf(stderr,"Total charge%s %.3f e\n",where,qtot);
889 static void check_restp_type(const char *name,int t1,int t2)
893 gmx_fatal(FARGS,"Residues in one molecule have a different '%s' type: %d and %d",name,t1,t2);
897 static void check_restp_types(t_restp *r0,t_restp *r1)
901 check_restp_type("all dihedrals",r0->bKeepAllGeneratedDihedrals,r1->bKeepAllGeneratedDihedrals);
902 check_restp_type("nrexcl",r0->nrexcl,r1->nrexcl);
903 check_restp_type("HH14",r0->bGenerateHH14Interactions,r1->bGenerateHH14Interactions);
904 check_restp_type("remove dihedrals",r0->bRemoveDihedralIfWithImproper,r1->bRemoveDihedralIfWithImproper);
906 for(i=0; i<ebtsNR; i++)
908 check_restp_type(btsNames[i],r0->rb[i].type,r1->rb[i].type);
912 void add_atom_to_restp(t_restp *restp,int resnr,int at_start,const t_hack *hack)
916 const char *Hnum="123456";
920 fprintf(debug,"adding atom(s) %s to atom %s in res %d%s in rtp\n",
922 *restp->atomname[at_start], resnr, restp->resname);
924 strcpy(buf, hack->nname);
925 buf[strlen(buf)+1]='\0';
928 buf[strlen(buf)]='-';
931 restp->natom += hack->nr;
932 srenew(restp->atom, restp->natom);
933 srenew(restp->atomname, restp->natom);
934 srenew(restp->cgnr, restp->natom);
936 for(k=restp->natom-1; k > at_start+hack->nr; k--)
939 restp->atom [k - hack->nr];
941 restp->atomname[k - hack->nr];
943 restp->cgnr [k - hack->nr];
946 for(k=0; k < hack->nr; k++)
948 /* set counter in atomname */
951 buf[strlen(buf)-1] = Hnum[k];
953 snew( restp->atomname[at_start+1+k], 1);
954 restp->atom [at_start+1+k] = *hack->atom;
955 *restp->atomname[at_start+1+k] = strdup(buf);
956 if ( hack->cgnr != NOTSET )
958 restp->cgnr [at_start+1+k] = hack->cgnr;
962 restp->cgnr [at_start+1+k] = restp->cgnr[at_start];
967 void get_hackblocks_rtp(t_hackblock **hb, t_restp **restp,
968 int nrtp, t_restp rtp[],
969 int nres, t_resinfo *resinfo,
971 t_hackblock **ntdb, t_hackblock **ctdb,
978 const char *Hnum="123456";
984 /* first the termini */
985 for(i=0; i<nterpairs; i++) {
986 if (rn[i] >= 0 && ntdb[i] != NULL) {
987 copy_t_hackblock(ntdb[i], &(*hb)[rn[i]]);
989 if (rc[i] >= 0 && ctdb[i] != NULL) {
990 merge_t_hackblock(ctdb[i], &(*hb)[rc[i]]);
994 /* then the whole rtp */
995 for(i=0; i < nres; i++) {
996 /* Here we allow a mismatch of one character when looking for the rtp entry.
997 * For such a mismatch there should be only one mismatching name.
998 * This is mainly useful for small molecules such as ions.
999 * Note that this will usually not work for protein, DNA and RNA,
1000 * since there the residue names should be listed in residuetypes.dat
1001 * and an error will have been generated earlier in the process.
1003 key = *resinfo[i].rtp;
1004 snew(resinfo[i].rtp,1);
1005 *resinfo[i].rtp = search_rtp(key,nrtp,rtp);
1006 res = get_restp(*resinfo[i].rtp,nrtp,rtp);
1007 copy_t_restp(res, &(*restp)[i]);
1009 /* Check that we do not have different bonded types in one molecule */
1010 check_restp_types(&(*restp)[0],&(*restp)[i]);
1013 for(j=0; j<nterpairs && tern==-1; j++) {
1019 for(j=0; j<nterpairs && terc == -1; j++) {
1024 bRM = merge_t_bondeds(res->rb, (*hb)[i].rb,tern>=0,terc>=0);
1026 if (bRM && ((tern >= 0 && ntdb[tern] == NULL) ||
1027 (terc >= 0 && ctdb[terc] == NULL))) {
1028 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).");
1030 if (bRM && ((tern >= 0 && ntdb[tern]->nhack == 0) ||
1031 (terc >= 0 && ctdb[terc]->nhack == 0))) {
1032 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.");
1036 /* now perform t_hack's on t_restp's,
1037 i.e. add's and deletes from termini database will be
1038 added to/removed from residue topology
1039 we'll do this on one big dirty loop, so it won't make easy reading! */
1040 for(i=0; i < nres; i++)
1042 for(j=0; j < (*hb)[i].nhack; j++)
1044 if ( (*hb)[i].hack[j].nr )
1046 /* find atom in restp */
1047 for(l=0; l < (*restp)[i].natom; l++)
1048 if ( ( (*hb)[i].hack[j].oname==NULL &&
1049 strcmp((*hb)[i].hack[j].AI, *(*restp)[i].atomname[l])==0 ) ||
1050 ( (*hb)[i].hack[j].oname!=NULL &&
1051 strcmp((*hb)[i].hack[j].oname,*(*restp)[i].atomname[l])==0 ) )
1053 if (l == (*restp)[i].natom)
1055 /* If we are doing an atom rename only, we don't need
1056 * to generate a fatal error if the old name is not found
1059 /* Deleting can happen also only on the input atoms,
1060 * not necessarily always on the rtp entry.
1062 if (!((*hb)[i].hack[j].oname != NULL &&
1063 (*hb)[i].hack[j].nname != NULL) &&
1064 !((*hb)[i].hack[j].oname != NULL &&
1065 (*hb)[i].hack[j].nname == NULL))
1068 "atom %s not found in buiding block %d%s "
1069 "while combining tdb and rtp",
1070 (*hb)[i].hack[j].oname!=NULL ?
1071 (*hb)[i].hack[j].oname : (*hb)[i].hack[j].AI,
1072 i+1,*resinfo[i].rtp);
1077 if ( (*hb)[i].hack[j].oname==NULL ) {
1079 add_atom_to_restp(&(*restp)[i],resinfo[i].nr,l,
1085 if ( (*hb)[i].hack[j].nname==NULL ) {
1086 /* we're deleting */
1088 fprintf(debug, "deleting atom %s from res %d%s in rtp\n",
1089 *(*restp)[i].atomname[l],
1090 i+1,(*restp)[i].resname);
1091 /* shift the rest */
1092 (*restp)[i].natom--;
1093 for(k=l; k < (*restp)[i].natom; k++) {
1094 (*restp)[i].atom [k] = (*restp)[i].atom [k+1];
1095 (*restp)[i].atomname[k] = (*restp)[i].atomname[k+1];
1096 (*restp)[i].cgnr [k] = (*restp)[i].cgnr [k+1];
1098 /* give back space */
1099 srenew((*restp)[i].atom, (*restp)[i].natom);
1100 srenew((*restp)[i].atomname, (*restp)[i].natom);
1101 srenew((*restp)[i].cgnr, (*restp)[i].natom);
1102 } else { /* nname != NULL */
1103 /* we're replacing */
1105 fprintf(debug, "replacing atom %s by %s in res %d%s in rtp\n",
1106 *(*restp)[i].atomname[l], (*hb)[i].hack[j].nname,
1107 i+1,(*restp)[i].resname);
1108 snew( (*restp)[i].atomname[l], 1);
1109 (*restp)[i].atom[l] = *(*hb)[i].hack[j].atom;
1110 *(*restp)[i].atomname[l] = strdup((*hb)[i].hack[j].nname);
1111 if ( (*hb)[i].hack[j].cgnr != NOTSET )
1112 (*restp)[i].cgnr [l] = (*hb)[i].hack[j].cgnr;
1121 static gmx_bool atomname_cmp_nr(const char *anm,t_hack *hack,int *nr)
1128 return (gmx_strcasecmp(anm,hack->nname) == 0);
1132 if (isdigit(anm[strlen(anm)-1]))
1134 *nr = anm[strlen(anm)-1] - '0';
1140 if (*nr <= 0 || *nr > hack->nr)
1146 return (strlen(anm) == strlen(hack->nname) + 1 &&
1147 gmx_strncasecmp(anm,hack->nname,strlen(hack->nname)) == 0);
1152 static gmx_bool match_atomnames_with_rtp_atom(t_atoms *pdba,rvec *x,int atind,
1153 t_restp *rptr,t_hackblock *hbr,
1160 char *start_at,buf[STRLEN];
1162 gmx_bool bReplaceReplace,bFoundInAdd;
1165 oldnm = *pdba->atomname[atind];
1166 resnr = pdba->resinfo[pdba->atom[atind].resind].nr;
1169 for(j=0; j<hbr->nhack; j++)
1171 if (hbr->hack[j].oname != NULL && hbr->hack[j].nname != NULL &&
1172 gmx_strcasecmp(oldnm,hbr->hack[j].oname) == 0)
1174 /* This is a replace entry. */
1175 /* Check if we are not replacing a replaced atom. */
1176 bReplaceReplace = FALSE;
1177 for(k=0; k<hbr->nhack; k++) {
1179 hbr->hack[k].oname != NULL && hbr->hack[k].nname != NULL &&
1180 gmx_strcasecmp(hbr->hack[k].nname,hbr->hack[j].oname) == 0)
1182 /* The replace in hack[j] replaces an atom that
1183 * was already replaced in hack[k], we do not want
1184 * second or higher level replaces at this stage.
1186 bReplaceReplace = TRUE;
1189 if (bReplaceReplace)
1191 /* Skip this replace. */
1195 /* This atom still has the old name, rename it */
1196 newnm = hbr->hack[j].nname;
1197 for(k=0; k<rptr->natom; k++)
1199 if (gmx_strcasecmp(newnm,*rptr->atomname[k]) == 0)
1204 if (k == rptr->natom)
1206 /* The new name is not present in the rtp.
1207 * We need to apply the replace also to the rtp entry.
1210 /* We need to find the add hack that can add this atom
1211 * to find out after which atom it should be added.
1213 bFoundInAdd = FALSE;
1214 for(k=0; k<hbr->nhack; k++)
1216 if (hbr->hack[k].oname == NULL &&
1217 hbr->hack[k].nname != NULL &&
1218 atomname_cmp_nr(newnm,&hbr->hack[k],&anmnr))
1222 start_at = hbr->hack[k].a[0];
1226 sprintf(buf,"%s%d",hbr->hack[k].nname,anmnr-1);
1229 for(start_nr=0; start_nr<rptr->natom; start_nr++)
1231 if (gmx_strcasecmp(start_at,(*rptr->atomname[start_nr])) == 0)
1236 if (start_nr == rptr->natom)
1238 gmx_fatal(FARGS,"Could not find atom '%s' in residue building block '%s' to add atom '%s' to",
1239 start_at,rptr->resname,newnm);
1241 /* We can add the atom after atom start_nr */
1242 add_atom_to_restp(rptr,resnr,start_nr,
1251 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'",
1253 hbr->hack[j].oname,hbr->hack[j].nname,
1260 printf("Renaming atom '%s' in residue '%s' %d to '%s'\n",
1261 oldnm,rptr->resname,resnr,newnm);
1263 /* Rename the atom in pdba */
1264 snew(pdba->atomname[atind],1);
1265 *pdba->atomname[atind] = strdup(newnm);
1267 else if (hbr->hack[j].oname != NULL && hbr->hack[j].nname == NULL &&
1268 gmx_strcasecmp(oldnm,hbr->hack[j].oname) == 0)
1270 /* This is a delete entry, check if this atom is present
1271 * in the rtp entry of this residue.
1273 for(k=0; k<rptr->natom; k++)
1275 if (gmx_strcasecmp(oldnm,*rptr->atomname[k]) == 0)
1280 if (k == rptr->natom)
1282 /* This atom is not present in the rtp entry,
1283 * delete is now from the input pdba.
1287 printf("Deleting atom '%s' in residue '%s' %d\n",
1288 oldnm,rptr->resname,resnr);
1290 /* We should free the atom name,
1291 * but it might be used multiple times in the symtab.
1292 * sfree(pdba->atomname[atind]);
1294 for(k=atind+1; k<pdba->nr; k++)
1296 pdba->atom[k-1] = pdba->atom[k];
1297 pdba->atomname[k-1] = pdba->atomname[k];
1298 copy_rvec(x[k],x[k-1]);
1309 void match_atomnames_with_rtp(t_restp restp[],t_hackblock hb[],
1310 t_atoms *pdba,rvec *x,
1319 char *start_at,buf[STRLEN];
1321 gmx_bool bFoundInAdd;
1323 for(i=0; i<pdba->nr; i++)
1325 oldnm = *pdba->atomname[i];
1326 resnr = pdba->resinfo[pdba->atom[i].resind].nr;
1327 rptr = &restp[pdba->atom[i].resind];
1328 for(j=0; (j<rptr->natom); j++)
1330 if (gmx_strcasecmp(oldnm,*(rptr->atomname[j])) == 0)
1335 if (j == rptr->natom)
1337 /* Not found yet, check if we have to rename this atom */
1338 if (match_atomnames_with_rtp_atom(pdba,x,i,
1339 rptr,&(hb[pdba->atom[i].resind]),
1342 /* We deleted this atom, decrease the atom counter by 1. */
1349 #define NUM_CMAP_ATOMS 5
1350 static void gen_cmap(t_params *psb, t_restp *restp, t_atoms *atoms, gmx_residuetype_t rt)
1354 t_resinfo *resinfo = atoms->resinfo;
1355 int nres = atoms->nres;
1357 atom_id cmap_atomid[NUM_CMAP_ATOMS];
1358 int cmap_chainnum=-1, this_residue_index;
1365 fprintf(stderr,"Making cmap torsions...");
1367 /* End loop at nres-1, since the very last residue does not have a +N atom, and
1368 * therefore we get a valgrind invalid 4 byte read error with atom am */
1369 for(residx=0; residx<nres-1; residx++)
1371 /* Add CMAP terms from the list of CMAP interactions */
1372 for(j=0;j<restp[residx].rb[ebtsCMAP].nb; j++)
1375 /* Loop over atoms in a candidate CMAP interaction and
1376 * check that they exist, are from the same chain and are
1377 * from residues labelled as protein. */
1378 for(k = 0; k < NUM_CMAP_ATOMS && bAddCMAP; k++)
1380 cmap_atomid[k] = search_atom(restp[residx].rb[ebtsCMAP].b[j].a[k],
1382 bAddCMAP = bAddCMAP && (cmap_atomid[k] != NO_ATID);
1385 /* This break is necessary, because cmap_atomid[k]
1386 * == NO_ATID cannot be safely used as an index
1387 * into the atom array. */
1390 this_residue_index = atoms->atom[cmap_atomid[k]].resind;
1393 cmap_chainnum = resinfo[this_residue_index].chainnum;
1397 /* Does the residue for this atom have the same
1398 * chain number as the residues for previous
1400 bAddCMAP = bAddCMAP &&
1401 cmap_chainnum == resinfo[this_residue_index].chainnum;
1403 bAddCMAP = bAddCMAP && gmx_residuetype_is_protein(rt,*(resinfo[this_residue_index].name));
1408 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);
1414 while(atoms->atom[i].resind<residx+1)
1421 /* Start the next residue */
1425 scrub_charge_groups(int *cgnr, int natoms)
1429 for(i=0;i<natoms;i++)
1436 void pdb2top(FILE *top_file, char *posre_fn, char *molname,
1437 t_atoms *atoms, rvec **x, gpp_atomtype_t atype, t_symtab *tab,
1438 int nrtp, t_restp rtp[],
1439 t_restp *restp, t_hackblock *hb,
1440 int nterpairs,t_hackblock **ntdb, t_hackblock **ctdb,
1441 gmx_bool bAllowMissing,
1442 gmx_bool bVsites, gmx_bool bVsiteAromatics,
1443 const char *ff, const char *ffdir,
1445 int nssbonds, t_ssbond *ssbonds,
1446 real long_bond_dist, real short_bond_dist,
1447 gmx_bool bDeuterate, gmx_bool bChargeGroups, gmx_bool bCmap,
1448 gmx_bool bRenumRes,gmx_bool bRTPresname)
1454 t_params plist[F_NRE];
1461 gmx_residuetype_t rt;
1464 gmx_residuetype_init(&rt);
1467 print_resall(debug, atoms->nres, restp, atype);
1468 dump_hb(debug, atoms->nres, hb);
1472 at2bonds(&(plist[F_BONDS]), hb,
1474 long_bond_dist, short_bond_dist, bAllowMissing);
1476 /* specbonds: disulphide bonds & heme-his */
1477 do_ssbonds(&(plist[F_BONDS]),
1478 atoms, nssbonds, ssbonds,
1481 nmissat = name2type(atoms, &cgnr, atype, restp, rt);
1484 fprintf(stderr,"There were %d missing atoms in molecule %s\n",
1487 gmx_fatal(FARGS,"There were %d missing atoms in molecule %s, if you want to use this incomplete topology anyhow, use the option -missing",
1491 /* Cleanup bonds (sort and rm doubles) */
1492 clean_bonds(&(plist[F_BONDS]));
1494 snew(vsite_type,atoms->nr);
1495 for(i=0; i<atoms->nr; i++)
1496 vsite_type[i]=NOTSET;
1498 /* determine which atoms will be vsites and add dummy masses
1499 also renumber atom numbers in plist[0..F_NRE]! */
1500 do_vsites(nrtp, rtp, atype, atoms, tab, x, plist,
1501 &vsite_type, &cgnr, mHmult, bVsiteAromatics, ffdir);
1504 /* Make Angles and Dihedrals */
1505 fprintf(stderr,"Generating angles, dihedrals and pairs...\n");
1506 snew(excls,atoms->nr);
1507 init_nnb(&nnb,atoms->nr,4);
1508 gen_nnb(&nnb,plist);
1509 print_nnb(&nnb,"NNB");
1510 gen_pad(&nnb,atoms,restp,plist,excls,hb,bAllowMissing);
1516 gen_cmap(&(plist[F_CMAP]), restp, atoms, rt);
1517 if (plist[F_CMAP].nr > 0)
1519 fprintf(stderr, "There are %4d cmap torsion pairs\n",
1524 /* set mass of all remaining hydrogen atoms */
1526 do_h_mass(&(plist[F_BONDS]),vsite_type,atoms,mHmult,bDeuterate);
1529 /* Cleanup bonds (sort and rm doubles) */
1530 /* clean_bonds(&(plist[F_BONDS]));*/
1533 "There are %4d dihedrals, %4d impropers, %4d angles\n"
1534 " %4d pairs, %4d bonds and %4d virtual sites\n",
1535 plist[F_PDIHS].nr, plist[F_IDIHS].nr, plist[F_ANGLES].nr,
1536 plist[F_LJ14].nr, plist[F_BONDS].nr,
1537 plist[F_VSITE2].nr +
1538 plist[F_VSITE3].nr +
1539 plist[F_VSITE3FD].nr +
1540 plist[F_VSITE3FAD].nr +
1541 plist[F_VSITE3OUT].nr +
1542 plist[F_VSITE4FD].nr +
1543 plist[F_VSITE4FDN].nr );
1545 print_sums(atoms, FALSE);
1547 if (FALSE == bChargeGroups)
1549 scrub_charge_groups(cgnr, atoms->nr);
1554 for(i=0; i<atoms->nres; i++)
1556 atoms->resinfo[i].nr = i + 1;
1557 atoms->resinfo[i].ic = ' ';
1562 fprintf(stderr,"Writing topology\n");
1563 /* We can copy the bonded types from the first restp,
1564 * since the types have to be identical for all residues in one molecule.
1566 for(i=0; i<ebtsNR; i++) {
1567 bts[i] = restp[0].rb[i].type;
1569 write_top(top_file, posre_fn, molname,
1571 bts, plist, excls, atype, cgnr, restp[0].nrexcl);
1575 free_t_hackblock(atoms->nres, &hb);
1576 free_t_restp(atoms->nres, &restp);
1577 gmx_residuetype_destroy(rt);
1579 /* we should clean up hb and restp here, but that is a *L*O*T* of work! */
1581 for (i=0; i<F_NRE; i++)
1582 sfree(plist[i].param);
1583 for (i=0; i<atoms->nr; i++)