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,2013, 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.
46 #ifdef GMX_NATIVE_WINDOWS
59 #include "gmx_fatal.h"
61 #include "gpp_nextnb.h"
74 #include "gen_vsite.h"
77 #include "fflibutil.h"
80 /* this must correspond to enum in pdb2top.h */
81 const char *hh[ehisNR] = { "HISD", "HISE", "HISH", "HIS1" };
83 static int missing_atoms(t_restp *rp, int resind,t_atoms *at, int i0, int i)
87 gmx_bool bFound, bRet;
90 for (j=0; j<rp->natom; j++)
92 name=*(rp->atomname[j]);
96 bFound = (bFound || !gmx_strcasecmp(*(at->atomname[k]),name));
101 fprintf(stderr,"\nWARNING: "
102 "atom %s is missing in residue %s %d in the pdb file\n",
103 name,*(at->resinfo[resind].name),at->resinfo[resind].nr);
104 if (name[0]=='H' || name[0]=='h')
106 fprintf(stderr," You might need to add atom %s to the hydrogen database of building block %s\n"
107 " in the file %s.hdb (see the manual)\n",
108 name,*(at->resinfo[resind].rtp),rp->filebase);
110 fprintf(stderr,"\n");
117 gmx_bool is_int(double x)
119 const double tol = 1e-4;
126 return (fabs(x-ix) < tol);
129 static void swap_strings(char **s,int i,int j)
139 choose_ff(const char *ffsel,
140 char *forcefield, int ff_maxlen,
141 char *ffdir, int ffdir_maxlen)
144 char **ffdirs,**ffs,**ffs_dir,*ptr;
145 int i,j,sel,cwdsel,nfound;
146 char buf[STRLEN],**desc;
150 nff = fflib_search_file_in_dirend(fflib_forcefield_itp(),
151 fflib_forcefield_dir_ext(),
156 gmx_fatal(FARGS,"No force fields found (files with name '%s' in subdirectories ending on '%s')",
157 fflib_forcefield_itp(),fflib_forcefield_dir_ext());
160 /* Replace with unix path separators */
161 if(DIR_SEPARATOR!='/')
165 while( (ptr=strchr(ffdirs[i],DIR_SEPARATOR))!=NULL )
172 /* Store the force field names in ffs */
177 /* Remove the path from the ffdir name - use our unix standard here! */
178 ptr = strrchr(ffdirs[i],'/');
181 ffs[i] = strdup(ffdirs[i]);
182 ffs_dir[i] = low_gmxlibfn(ffdirs[i],FALSE,FALSE);
183 if (ffs_dir[i] == NULL)
185 gmx_fatal(FARGS,"Can no longer find file '%s'",ffdirs[i]);
190 ffs[i] = strdup(ptr+1);
191 ffs_dir[i] = strdup(ffdirs[i]);
193 ffs_dir[i][strlen(ffs_dir[i])-strlen(ffs[i])-1] = '\0';
194 /* Remove the extension from the ffdir name */
195 ffs[i][strlen(ffs[i])-strlen(fflib_forcefield_dir_ext())] = '\0';
205 if ( strcmp(ffs[i],ffsel)==0 )
207 /* Matching ff name */
211 if( strncmp(ffs_dir[i],".",1)==0 )
228 "Force field '%s' occurs in %d places. pdb2gmx is using the one in the\n"
229 "current directory. Use interactive selection (not the -ff option) if\n"
230 "you would prefer a different one.\n",ffsel,nfound);
235 "Force field '%s' occurs in %d places, but not in the current directory.\n"
236 "Run without the -ff switch and select the force field interactively.",ffsel,nfound);
241 gmx_fatal(FARGS,"Could not find force field '%s' in current directory, install tree or GMXDATA path.",ffsel);
247 for(i=0; (i<nff); i++)
249 sprintf(buf,"%s%c%s%s%c%s",
250 ffs_dir[i],DIR_SEPARATOR,
251 ffs[i],fflib_forcefield_dir_ext(),DIR_SEPARATOR,
252 fflib_forcefield_doc());
255 /* We don't use fflib_open, because we don't want printf's */
256 fp = ffopen(buf,"r");
257 snew(desc[i],STRLEN);
258 get_a_line(fp,desc[i],STRLEN);
263 desc[i] = strdup(ffs[i]);
266 /* Order force fields from the same dir alphabetically
267 * and put deprecated force fields at the end.
269 for(i=0; (i<nff); i++)
271 for(j=i+1; (j<nff); j++)
273 if (strcmp(ffs_dir[i],ffs_dir[j]) == 0 &&
274 ((desc[i][0] == '[' && desc[j][0] != '[') ||
275 ((desc[i][0] == '[' || desc[j][0] != '[') &&
276 gmx_strcasecmp(desc[i],desc[j]) > 0)))
278 swap_strings(ffdirs,i,j);
279 swap_strings(ffs ,i,j);
280 swap_strings(desc ,i,j);
285 printf("\nSelect the Force Field:\n");
286 for(i=0; (i<nff); i++)
288 if (i == 0 || strcmp(ffs_dir[i-1],ffs_dir[i]) != 0)
290 if( strcmp(ffs_dir[i],".")==0 )
292 printf("From current directory:\n");
296 printf("From '%s':\n",ffs_dir[i]);
299 printf("%2d: %s\n",i+1,desc[i]);
306 pret = fgets(buf,STRLEN,stdin);
310 sscanf(buf,"%d",&sel);
314 while ( pret==NULL || (sel < 0) || (sel >= nff));
316 /* Check for a current limitation of the fflib code.
317 * It will always read from the first ff directory in the list.
318 * This check assumes that the order of ffs matches the order
319 * in which fflib_open searches ff library files.
323 if (strcmp(ffs[i],ffs[sel]) == 0)
325 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.",
326 ffs[sel],fflib_forcefield_dir_ext());
335 if (strlen(ffs[sel]) >= (size_t)ff_maxlen)
337 gmx_fatal(FARGS,"Length of force field name (%d) >= maxlen (%d)",
338 strlen(ffs[sel]),ff_maxlen);
340 strcpy(forcefield,ffs[sel]);
342 if (strlen(ffdirs[sel]) >= (size_t)ffdir_maxlen)
344 gmx_fatal(FARGS,"Length of force field dir (%d) >= maxlen (%d)",
345 strlen(ffdirs[sel]),ffdir_maxlen);
347 strcpy(ffdir,ffdirs[sel]);
349 for(i=0; (i<nff); i++)
360 void choose_watermodel(const char *wmsel,const char *ffdir,
363 const char *fn_watermodels="watermodels.dat";
364 char fn_list[STRLEN];
371 if (strcmp(wmsel,"none") == 0)
377 else if (strcmp(wmsel,"select") != 0)
379 *watermodel = strdup(wmsel);
384 sprintf(fn_list,"%s%c%s",ffdir,DIR_SEPARATOR,fn_watermodels);
386 if (!fflib_fexist(fn_list))
388 fprintf(stderr,"No file '%s' found, will not include a water model\n",
395 fp = fflib_open(fn_list);
396 printf("\nSelect the Water Model:\n");
399 while (get_a_line(fp,buf,STRLEN))
402 snew(model[nwm],STRLEN);
403 sscanf(buf,"%s%n",model[nwm],&i);
407 fprintf(stderr,"%2d: %s\n",nwm+1,buf+i);
416 fprintf(stderr,"%2d: %s\n",nwm+1,"None");
420 pret = fgets(buf,STRLEN,stdin);
424 sscanf(buf,"%d",&sel);
428 while (pret == NULL || sel < 0 || sel > nwm);
436 *watermodel = strdup(model[sel]);
446 static int name2type(t_atoms *at, int **cgnr, gpp_atomtype_t atype,
447 t_restp restp[], gmx_residuetype_t rt)
449 int i,j,prevresind,resind,i0,prevcg,cg,curcg;
451 gmx_bool bProt, bNterm;
468 for(i=0; (i<at->nr); i++) {
470 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);
475 nmissat += missing_atoms(&restp[prevresind],prevresind,at,i0,i);
479 if (at->atom[i].m == 0) {
481 fprintf(debug,"atom %d%s: curcg=%d, prevcg=%d, cg=%d\n",
482 i+1,*(at->atomname[i]),curcg,prevcg,
483 j==NOTSET ? NOTSET : restp[resind].cgnr[j]);
486 name=*(at->atomname[i]);
487 j=search_jtype(&restp[resind],name,bNterm);
488 at->atom[i].type = restp[resind].atom[j].type;
489 at->atom[i].q = restp[resind].atom[j].q;
490 at->atom[i].m = get_atomtype_massA(restp[resind].atom[j].type,
492 cg = restp[resind].cgnr[j];
493 /* A charge group number -1 signals a separate charge group
496 if ( (cg == -1) || (cg != prevcg) || (resind != prevresind) ) {
501 fprintf(debug,"atom %d%s: curcg=%d, qt=%g, is_int=%d\n",
502 i+1,*(at->atomname[i]),curcg,qt,is_int(qt));
511 at->atom[i].typeB = at->atom[i].type;
512 at->atom[i].qB = at->atom[i].q;
513 at->atom[i].mB = at->atom[i].m;
515 nmissat += missing_atoms(&restp[resind],resind,at,i0,i);
520 static void print_top_heavy_H(FILE *out, real mHmult)
523 fprintf(out,"; Using deuterium instead of hydrogen\n\n");
524 else if (mHmult == 4.0)
525 fprintf(out,"#define HEAVY_H\n\n");
526 else if (mHmult != 1.0)
527 fprintf(stderr,"WARNING: unsupported proton mass multiplier (%g) "
528 "in pdb2top\n",mHmult);
531 void print_top_comment(FILE *out,
532 const char *filename,
533 const char *generator,
538 char ffdir_parent[STRLEN];
541 nice_header(out,filename);
542 fprintf(out,";\tThis is a %s topology file\n;\n",bITP ? "include" : "standalone");
543 fprintf(out,";\tIt was generated using program:\n;\t%s\n;\n",
544 (NULL == generator) ? "unknown" : generator);
545 fprintf(out,";\tCommand line was:\n;\t%s\n;\n",command_line());
547 if(strchr(ffdir,'/')==NULL)
549 fprintf(out,";\tForce field was read from the standard Gromacs share directory.\n;\n\n");
551 else if(ffdir[0]=='.')
553 fprintf(out,";\tForce field was read from current directory or a relative path - path added.\n;\n\n");
557 strncpy(ffdir_parent,ffdir,STRLEN-1);
558 ffdir_parent[STRLEN-1]='\0'; /*make sure it is 0-terminated even for long string*/
559 p=strrchr(ffdir_parent,'/');
564 ";\tForce field data was read from:\n"
568 ";\tThis might be a non-standard force field location. When you use this topology, the\n"
569 ";\tforce field must either be present in the current directory, or the location\n"
570 ";\tspecified in the GMXLIB path variable or with the 'include' mdp file option.\n;\n\n",
575 void print_top_header(FILE *out,const char *filename,
576 const char *title,gmx_bool bITP,const char *ffdir,real mHmult)
580 print_top_comment(out,filename,title,ffdir,bITP);
582 print_top_heavy_H(out, mHmult);
583 fprintf(out,"; Include forcefield parameters\n");
585 p=strrchr(ffdir,'/');
586 p = (ffdir[0]=='.' || p==NULL) ? ffdir : p+1;
588 fprintf(out,"#include \"%s/%s\"\n\n",p,fflib_forcefield_itp());
591 static void print_top_posre(FILE *out,const char *pr)
593 fprintf(out,"; Include Position restraint file\n");
594 fprintf(out,"#ifdef POSRES\n");
595 fprintf(out,"#include \"%s\"\n",pr);
596 fprintf(out,"#endif\n\n");
599 static void print_top_water(FILE *out,const char *ffdir,const char *water)
604 fprintf(out,"; Include water topology\n");
606 p=strrchr(ffdir,'/');
607 p = (ffdir[0]=='.' || p==NULL) ? ffdir : p+1;
608 fprintf(out,"#include \"%s/%s.itp\"\n",p,water);
611 fprintf(out,"#ifdef POSRES_WATER\n");
612 fprintf(out,"; Position restraint for each water oxygen\n");
613 fprintf(out,"[ position_restraints ]\n");
614 fprintf(out,";%3s %5s %9s %10s %10s\n","i","funct","fcx","fcy","fcz");
615 fprintf(out,"%4d %4d %10g %10g %10g\n",1,1,1000.0,1000.0,1000.0);
616 fprintf(out,"#endif\n");
619 sprintf(buf,"%s/ions.itp",p);
621 if (fflib_fexist(buf))
623 fprintf(out,"; Include topology for ions\n");
624 fprintf(out,"#include \"%s\"\n",buf);
629 static void print_top_system(FILE *out, const char *title)
631 fprintf(out,"[ %s ]\n",dir2str(d_system));
632 fprintf(out,"; Name\n");
633 fprintf(out,"%s\n\n",title[0]?title:"Protein");
636 void print_top_mols(FILE *out,
637 const char *title, const char *ffdir, const char *water,
638 int nincl, char **incls, int nmol, t_mols *mols)
644 fprintf(out,"; Include chain topologies\n");
645 for (i=0; (i<nincl); i++) {
646 incl = strrchr(incls[i],DIR_SEPARATOR);
650 /* Remove the path from the include name */
653 fprintf(out,"#include \"%s\"\n",incl);
660 print_top_water(out,ffdir,water);
662 print_top_system(out, title);
665 fprintf(out,"[ %s ]\n",dir2str(d_molecules));
666 fprintf(out,"; %-15s %5s\n","Compound","#mols");
667 for (i=0; (i<nmol); i++)
668 fprintf(out,"%-15s %5d\n",mols[i].name,mols[i].nr);
672 void write_top(FILE *out, char *pr,char *molname,
673 t_atoms *at,gmx_bool bRTPresname,
674 int bts[],t_params plist[],t_excls excls[],
675 gpp_atomtype_t atype,int *cgnr, int nrexcl)
676 /* NOTE: nrexcl is not the size of *excl! */
678 if (at && atype && cgnr) {
679 fprintf(out,"[ %s ]\n",dir2str(d_moleculetype));
680 fprintf(out,"; %-15s %5s\n","Name","nrexcl");
681 fprintf(out,"%-15s %5d\n\n",molname?molname:"Protein",nrexcl);
683 print_atoms(out, atype, at, cgnr, bRTPresname);
684 print_bondeds(out,at->nr,d_bonds, F_BONDS, bts[ebtsBONDS], plist);
685 print_bondeds(out,at->nr,d_constraints,F_CONSTR, 0, plist);
686 print_bondeds(out,at->nr,d_constraints,F_CONSTRNC, 0, plist);
687 print_bondeds(out,at->nr,d_pairs, F_LJ14, 0, plist);
688 print_excl(out,at->nr,excls);
689 print_bondeds(out,at->nr,d_angles, F_ANGLES, bts[ebtsANGLES],plist);
690 print_bondeds(out,at->nr,d_dihedrals, F_PDIHS, bts[ebtsPDIHS], plist);
691 print_bondeds(out,at->nr,d_dihedrals, F_IDIHS, bts[ebtsIDIHS], plist);
692 print_bondeds(out,at->nr,d_cmap, F_CMAP, bts[ebtsCMAP], plist);
693 print_bondeds(out,at->nr,d_polarization,F_POLARIZATION, 0, plist);
694 print_bondeds(out,at->nr,d_thole_polarization,F_THOLE_POL,0, plist);
695 print_bondeds(out,at->nr,d_vsites2, F_VSITE2, 0, plist);
696 print_bondeds(out,at->nr,d_vsites3, F_VSITE3, 0, plist);
697 print_bondeds(out,at->nr,d_vsites3, F_VSITE3FD, 0, plist);
698 print_bondeds(out,at->nr,d_vsites3, F_VSITE3FAD,0, plist);
699 print_bondeds(out,at->nr,d_vsites3, F_VSITE3OUT,0, plist);
700 print_bondeds(out,at->nr,d_vsites4, F_VSITE4FD, 0, plist);
701 print_bondeds(out,at->nr,d_vsites4, F_VSITE4FDN, 0, plist);
704 print_top_posre(out,pr);
708 static atom_id search_res_atom(const char *type,int resind,
710 const char *bondtype,gmx_bool bAllowMissing)
714 for(i=0; (i<atoms->nr); i++)
716 if (atoms->atom[i].resind == resind)
718 return search_atom(type,i,atoms,bondtype,bAllowMissing);
725 static void do_ssbonds(t_params *ps,t_atoms *atoms,
726 int nssbonds,t_ssbond *ssbonds,gmx_bool bAllowMissing)
731 for(i=0; (i<nssbonds); i++) {
732 ri = ssbonds[i].res1;
733 rj = ssbonds[i].res2;
734 ai = search_res_atom(ssbonds[i].a1,ri,atoms,
735 "special bond",bAllowMissing);
736 aj = search_res_atom(ssbonds[i].a2,rj,atoms,
737 "special bond",bAllowMissing);
738 if ((ai == NO_ATID) || (aj == NO_ATID))
739 gmx_fatal(FARGS,"Trying to make impossible special bond (%s-%s)!",
740 ssbonds[i].a1,ssbonds[i].a2);
741 add_param(ps,ai,aj,NULL,NULL);
745 static void at2bonds(t_params *psb, t_hackblock *hb,
748 real long_bond_dist, real short_bond_dist,
749 gmx_bool bAllowMissing)
753 real dist2, long_bond_dist2, short_bond_dist2;
756 long_bond_dist2 = sqr(long_bond_dist);
757 short_bond_dist2 = sqr(short_bond_dist);
764 fprintf(stderr,"Making bonds...\n");
766 for(resind=0; (resind < atoms->nres) && (i<atoms->nr); resind++) {
767 /* add bonds from list of bonded interactions */
768 for(j=0; j < hb[resind].rb[ebtsBONDS].nb; j++) {
769 /* Unfortunately we can not issue errors or warnings
770 * for missing atoms in bonds, as the hydrogens and terminal atoms
771 * have not been added yet.
773 ai=search_atom(hb[resind].rb[ebtsBONDS].b[j].AI,i,atoms,
775 aj=search_atom(hb[resind].rb[ebtsBONDS].b[j].AJ,i,atoms,
777 if (ai != NO_ATID && aj != NO_ATID) {
778 dist2 = distance2(x[ai],x[aj]);
779 if (dist2 > long_bond_dist2 )
781 fprintf(stderr,"Warning: Long Bond (%d-%d = %g nm)\n",
782 ai+1,aj+1,sqrt(dist2));
784 else if (dist2 < short_bond_dist2 )
786 fprintf(stderr,"Warning: Short Bond (%d-%d = %g nm)\n",
787 ai+1,aj+1,sqrt(dist2));
789 add_param(psb,ai,aj,NULL,hb[resind].rb[ebtsBONDS].b[j].s);
792 /* add bonds from list of hacks (each added atom gets a bond) */
793 while( (i<atoms->nr) && (atoms->atom[i].resind == resind) ) {
794 for(j=0; j < hb[resind].nhack; j++)
795 if ( ( hb[resind].hack[j].tp > 0 ||
796 hb[resind].hack[j].oname==NULL ) &&
797 strcmp(hb[resind].hack[j].AI,*(atoms->atomname[i])) == 0 ) {
798 switch(hb[resind].hack[j].tp) {
799 case 9: /* COOH terminus */
800 add_param(psb,i,i+1,NULL,NULL); /* C-O */
801 add_param(psb,i,i+2,NULL,NULL); /* C-OA */
802 add_param(psb,i+2,i+3,NULL,NULL); /* OA-H */
805 for(k=0; (k<hb[resind].hack[j].nr); k++)
806 add_param(psb,i,i+k+1,NULL,NULL);
811 /* we're now at the start of the next residue */
815 static int pcompar(const void *a, const void *b)
826 return strlen(pb->s) - strlen(pa->s);
831 static void clean_bonds(t_params *ps)
837 /* swap atomnumbers in bond if first larger than second: */
838 for(i=0; (i<ps->nr); i++)
839 if ( ps->param[i].AJ < ps->param[i].AI ) {
841 ps->param[i].AI = ps->param[i].AJ;
846 qsort(ps->param,ps->nr,(size_t)sizeof(ps->param[0]),pcompar);
848 /* remove doubles, keep the first one always. */
850 for(i=1; (i<ps->nr); i++) {
851 if ((ps->param[i].AI != ps->param[j-1].AI) ||
852 (ps->param[i].AJ != ps->param[j-1].AJ) ) {
854 cp_param(&(ps->param[j]),&(ps->param[i]));
859 fprintf(stderr,"Number of bonds was %d, now %d\n",ps->nr,j);
863 fprintf(stderr,"No bonds\n");
866 void print_sums(t_atoms *atoms, gmx_bool bSystem)
879 for(i=0; (i<atoms->nr); i++) {
881 qtot+=atoms->atom[i].q;
884 fprintf(stderr,"Total mass%s %.3f a.m.u.\n",where,m);
885 fprintf(stderr,"Total charge%s %.3f e\n",where,qtot);
888 static void check_restp_type(const char *name,int t1,int t2)
892 gmx_fatal(FARGS,"Residues in one molecule have a different '%s' type: %d and %d",name,t1,t2);
896 static void check_restp_types(t_restp *r0,t_restp *r1)
900 check_restp_type("all dihedrals",r0->bKeepAllGeneratedDihedrals,r1->bKeepAllGeneratedDihedrals);
901 check_restp_type("nrexcl",r0->nrexcl,r1->nrexcl);
902 check_restp_type("HH14",r0->bGenerateHH14Interactions,r1->bGenerateHH14Interactions);
903 check_restp_type("remove dihedrals",r0->bRemoveDihedralIfWithImproper,r1->bRemoveDihedralIfWithImproper);
905 for(i=0; i<ebtsNR; i++)
907 check_restp_type(btsNames[i],r0->rb[i].type,r1->rb[i].type);
911 void add_atom_to_restp(t_restp *restp,int resnr,int at_start,const t_hack *hack)
915 const char *Hnum="123456";
919 fprintf(debug,"adding atom(s) %s to atom %s in res %d%s in rtp\n",
921 *restp->atomname[at_start], resnr, restp->resname);
923 strcpy(buf, hack->nname);
924 buf[strlen(buf)+1]='\0';
927 buf[strlen(buf)]='-';
930 restp->natom += hack->nr;
931 srenew(restp->atom, restp->natom);
932 srenew(restp->atomname, restp->natom);
933 srenew(restp->cgnr, restp->natom);
935 for(k=restp->natom-1; k > at_start+hack->nr; k--)
938 restp->atom [k - hack->nr];
940 restp->atomname[k - hack->nr];
942 restp->cgnr [k - hack->nr];
945 for(k=0; k < hack->nr; k++)
947 /* set counter in atomname */
950 buf[strlen(buf)-1] = Hnum[k];
952 snew( restp->atomname[at_start+1+k], 1);
953 restp->atom [at_start+1+k] = *hack->atom;
954 *restp->atomname[at_start+1+k] = strdup(buf);
955 if ( hack->cgnr != NOTSET )
957 restp->cgnr [at_start+1+k] = hack->cgnr;
961 restp->cgnr [at_start+1+k] = restp->cgnr[at_start];
966 void get_hackblocks_rtp(t_hackblock **hb, t_restp **restp,
967 int nrtp, t_restp rtp[],
968 int nres, t_resinfo *resinfo,
970 t_hackblock **ntdb, t_hackblock **ctdb,
977 const char *Hnum="123456";
983 /* first the termini */
984 for(i=0; i<nterpairs; i++) {
985 if (rn[i] >= 0 && ntdb[i] != NULL) {
986 copy_t_hackblock(ntdb[i], &(*hb)[rn[i]]);
988 if (rc[i] >= 0 && ctdb[i] != NULL) {
989 merge_t_hackblock(ctdb[i], &(*hb)[rc[i]]);
993 /* then the whole rtp */
994 for(i=0; i < nres; i++) {
995 /* Here we allow a mismatch of one character when looking for the rtp entry.
996 * For such a mismatch there should be only one mismatching name.
997 * This is mainly useful for small molecules such as ions.
998 * Note that this will usually not work for protein, DNA and RNA,
999 * since there the residue names should be listed in residuetypes.dat
1000 * and an error will have been generated earlier in the process.
1002 key = *resinfo[i].rtp;
1003 snew(resinfo[i].rtp,1);
1004 *resinfo[i].rtp = search_rtp(key,nrtp,rtp);
1005 res = get_restp(*resinfo[i].rtp,nrtp,rtp);
1006 copy_t_restp(res, &(*restp)[i]);
1008 /* Check that we do not have different bonded types in one molecule */
1009 check_restp_types(&(*restp)[0],&(*restp)[i]);
1012 for(j=0; j<nterpairs && tern==-1; j++) {
1018 for(j=0; j<nterpairs && terc == -1; j++) {
1023 bRM = merge_t_bondeds(res->rb, (*hb)[i].rb,tern>=0,terc>=0);
1025 if (bRM && ((tern >= 0 && ntdb[tern] == NULL) ||
1026 (terc >= 0 && ctdb[terc] == NULL))) {
1027 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).");
1029 if (bRM && ((tern >= 0 && ntdb[tern]->nhack == 0) ||
1030 (terc >= 0 && ctdb[terc]->nhack == 0))) {
1031 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.");
1035 /* now perform t_hack's on t_restp's,
1036 i.e. add's and deletes from termini database will be
1037 added to/removed from residue topology
1038 we'll do this on one big dirty loop, so it won't make easy reading! */
1039 for(i=0; i < nres; i++)
1041 for(j=0; j < (*hb)[i].nhack; j++)
1043 if ( (*hb)[i].hack[j].nr )
1045 /* find atom in restp */
1046 for(l=0; l < (*restp)[i].natom; l++)
1047 if ( ( (*hb)[i].hack[j].oname==NULL &&
1048 strcmp((*hb)[i].hack[j].AI, *(*restp)[i].atomname[l])==0 ) ||
1049 ( (*hb)[i].hack[j].oname!=NULL &&
1050 strcmp((*hb)[i].hack[j].oname,*(*restp)[i].atomname[l])==0 ) )
1052 if (l == (*restp)[i].natom)
1054 /* If we are doing an atom rename only, we don't need
1055 * to generate a fatal error if the old name is not found
1058 /* Deleting can happen also only on the input atoms,
1059 * not necessarily always on the rtp entry.
1061 if (!((*hb)[i].hack[j].oname != NULL &&
1062 (*hb)[i].hack[j].nname != NULL) &&
1063 !((*hb)[i].hack[j].oname != NULL &&
1064 (*hb)[i].hack[j].nname == NULL))
1067 "atom %s not found in buiding block %d%s "
1068 "while combining tdb and rtp",
1069 (*hb)[i].hack[j].oname!=NULL ?
1070 (*hb)[i].hack[j].oname : (*hb)[i].hack[j].AI,
1071 i+1,*resinfo[i].rtp);
1076 if ( (*hb)[i].hack[j].oname==NULL ) {
1078 add_atom_to_restp(&(*restp)[i],resinfo[i].nr,l,
1084 if ( (*hb)[i].hack[j].nname==NULL ) {
1085 /* we're deleting */
1087 fprintf(debug, "deleting atom %s from res %d%s in rtp\n",
1088 *(*restp)[i].atomname[l],
1089 i+1,(*restp)[i].resname);
1090 /* shift the rest */
1091 (*restp)[i].natom--;
1092 for(k=l; k < (*restp)[i].natom; k++) {
1093 (*restp)[i].atom [k] = (*restp)[i].atom [k+1];
1094 (*restp)[i].atomname[k] = (*restp)[i].atomname[k+1];
1095 (*restp)[i].cgnr [k] = (*restp)[i].cgnr [k+1];
1097 /* give back space */
1098 srenew((*restp)[i].atom, (*restp)[i].natom);
1099 srenew((*restp)[i].atomname, (*restp)[i].natom);
1100 srenew((*restp)[i].cgnr, (*restp)[i].natom);
1101 } else { /* nname != NULL */
1102 /* we're replacing */
1104 fprintf(debug, "replacing atom %s by %s in res %d%s in rtp\n",
1105 *(*restp)[i].atomname[l], (*hb)[i].hack[j].nname,
1106 i+1,(*restp)[i].resname);
1107 snew( (*restp)[i].atomname[l], 1);
1108 (*restp)[i].atom[l] = *(*hb)[i].hack[j].atom;
1109 *(*restp)[i].atomname[l] = strdup((*hb)[i].hack[j].nname);
1110 if ( (*hb)[i].hack[j].cgnr != NOTSET )
1111 (*restp)[i].cgnr [l] = (*hb)[i].hack[j].cgnr;
1120 static gmx_bool atomname_cmp_nr(const char *anm,t_hack *hack,int *nr)
1127 return (gmx_strcasecmp(anm,hack->nname) == 0);
1131 if (isdigit(anm[strlen(anm)-1]))
1133 *nr = anm[strlen(anm)-1] - '0';
1139 if (*nr <= 0 || *nr > hack->nr)
1145 return (strlen(anm) == strlen(hack->nname) + 1 &&
1146 gmx_strncasecmp(anm,hack->nname,strlen(hack->nname)) == 0);
1151 static gmx_bool match_atomnames_with_rtp_atom(t_atoms *pdba,rvec *x,int atind,
1152 t_restp *rptr,t_hackblock *hbr,
1159 char *start_at,buf[STRLEN];
1161 gmx_bool bReplaceReplace,bFoundInAdd;
1164 oldnm = *pdba->atomname[atind];
1165 resnr = pdba->resinfo[pdba->atom[atind].resind].nr;
1168 for(j=0; j<hbr->nhack; j++)
1170 if (hbr->hack[j].oname != NULL && hbr->hack[j].nname != NULL &&
1171 gmx_strcasecmp(oldnm,hbr->hack[j].oname) == 0)
1173 /* This is a replace entry. */
1174 /* Check if we are not replacing a replaced atom. */
1175 bReplaceReplace = FALSE;
1176 for(k=0; k<hbr->nhack; k++) {
1178 hbr->hack[k].oname != NULL && hbr->hack[k].nname != NULL &&
1179 gmx_strcasecmp(hbr->hack[k].nname,hbr->hack[j].oname) == 0)
1181 /* The replace in hack[j] replaces an atom that
1182 * was already replaced in hack[k], we do not want
1183 * second or higher level replaces at this stage.
1185 bReplaceReplace = TRUE;
1188 if (bReplaceReplace)
1190 /* Skip this replace. */
1194 /* This atom still has the old name, rename it */
1195 newnm = hbr->hack[j].nname;
1196 for(k=0; k<rptr->natom; k++)
1198 if (gmx_strcasecmp(newnm,*rptr->atomname[k]) == 0)
1203 if (k == rptr->natom)
1205 /* The new name is not present in the rtp.
1206 * We need to apply the replace also to the rtp entry.
1209 /* We need to find the add hack that can add this atom
1210 * to find out after which atom it should be added.
1212 bFoundInAdd = FALSE;
1213 for(k=0; k<hbr->nhack; k++)
1215 if (hbr->hack[k].oname == NULL &&
1216 hbr->hack[k].nname != NULL &&
1217 atomname_cmp_nr(newnm,&hbr->hack[k],&anmnr))
1221 start_at = hbr->hack[k].a[0];
1225 sprintf(buf,"%s%d",hbr->hack[k].nname,anmnr-1);
1228 for(start_nr=0; start_nr<rptr->natom; start_nr++)
1230 if (gmx_strcasecmp(start_at,(*rptr->atomname[start_nr])) == 0)
1235 if (start_nr == rptr->natom)
1237 gmx_fatal(FARGS,"Could not find atom '%s' in residue building block '%s' to add atom '%s' to",
1238 start_at,rptr->resname,newnm);
1240 /* We can add the atom after atom start_nr */
1241 add_atom_to_restp(rptr,resnr,start_nr,
1250 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'",
1252 hbr->hack[j].oname,hbr->hack[j].nname,
1259 printf("Renaming atom '%s' in residue '%s' %d to '%s'\n",
1260 oldnm,rptr->resname,resnr,newnm);
1262 /* Rename the atom in pdba */
1263 snew(pdba->atomname[atind],1);
1264 *pdba->atomname[atind] = strdup(newnm);
1266 else if (hbr->hack[j].oname != NULL && hbr->hack[j].nname == NULL &&
1267 gmx_strcasecmp(oldnm,hbr->hack[j].oname) == 0)
1269 /* This is a delete entry, check if this atom is present
1270 * in the rtp entry of this residue.
1272 for(k=0; k<rptr->natom; k++)
1274 if (gmx_strcasecmp(oldnm,*rptr->atomname[k]) == 0)
1279 if (k == rptr->natom)
1281 /* This atom is not present in the rtp entry,
1282 * delete is now from the input pdba.
1286 printf("Deleting atom '%s' in residue '%s' %d\n",
1287 oldnm,rptr->resname,resnr);
1289 /* We should free the atom name,
1290 * but it might be used multiple times in the symtab.
1291 * sfree(pdba->atomname[atind]);
1293 for(k=atind+1; k<pdba->nr; k++)
1295 pdba->atom[k-1] = pdba->atom[k];
1296 pdba->atomname[k-1] = pdba->atomname[k];
1297 copy_rvec(x[k],x[k-1]);
1308 void match_atomnames_with_rtp(t_restp restp[],t_hackblock hb[],
1309 t_atoms *pdba,rvec *x,
1318 char *start_at,buf[STRLEN];
1320 gmx_bool bFoundInAdd;
1322 for(i=0; i<pdba->nr; i++)
1324 oldnm = *pdba->atomname[i];
1325 resnr = pdba->resinfo[pdba->atom[i].resind].nr;
1326 rptr = &restp[pdba->atom[i].resind];
1327 for(j=0; (j<rptr->natom); j++)
1329 if (gmx_strcasecmp(oldnm,*(rptr->atomname[j])) == 0)
1334 if (j == rptr->natom)
1336 /* Not found yet, check if we have to rename this atom */
1337 if (match_atomnames_with_rtp_atom(pdba,x,i,
1338 rptr,&(hb[pdba->atom[i].resind]),
1341 /* We deleted this atom, decrease the atom counter by 1. */
1348 #define NUM_CMAP_ATOMS 5
1349 static void gen_cmap(t_params *psb, t_restp *restp, t_atoms *atoms, gmx_residuetype_t rt)
1353 t_resinfo *resinfo = atoms->resinfo;
1354 int nres = atoms->nres;
1356 atom_id cmap_atomid[NUM_CMAP_ATOMS];
1357 int cmap_chainnum=-1, this_residue_index;
1364 fprintf(stderr,"Making cmap torsions...");
1366 /* End loop at nres-1, since the very last residue does not have a +N atom, and
1367 * therefore we get a valgrind invalid 4 byte read error with atom am */
1368 for(residx=0; residx<nres-1; residx++)
1370 /* Add CMAP terms from the list of CMAP interactions */
1371 for(j=0;j<restp[residx].rb[ebtsCMAP].nb; j++)
1374 /* Loop over atoms in a candidate CMAP interaction and
1375 * check that they exist, are from the same chain and are
1376 * from residues labelled as protein. */
1377 for(k = 0; k < NUM_CMAP_ATOMS && bAddCMAP; k++)
1379 cmap_atomid[k] = search_atom(restp[residx].rb[ebtsCMAP].b[j].a[k],
1381 bAddCMAP = bAddCMAP && (cmap_atomid[k] != NO_ATID);
1384 /* This break is necessary, because cmap_atomid[k]
1385 * == NO_ATID cannot be safely used as an index
1386 * into the atom array. */
1389 this_residue_index = atoms->atom[cmap_atomid[k]].resind;
1392 cmap_chainnum = resinfo[this_residue_index].chainnum;
1396 /* Does the residue for this atom have the same
1397 * chain number as the residues for previous
1399 bAddCMAP = bAddCMAP &&
1400 cmap_chainnum == resinfo[this_residue_index].chainnum;
1402 bAddCMAP = bAddCMAP && gmx_residuetype_is_protein(rt,*(resinfo[this_residue_index].name));
1407 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);
1413 while(atoms->atom[i].resind<residx+1)
1420 /* Start the next residue */
1424 scrub_charge_groups(int *cgnr, int natoms)
1428 for(i=0;i<natoms;i++)
1435 void pdb2top(FILE *top_file, char *posre_fn, char *molname,
1436 t_atoms *atoms, rvec **x, gpp_atomtype_t atype, t_symtab *tab,
1437 int nrtp, t_restp rtp[],
1438 t_restp *restp, t_hackblock *hb,
1439 int nterpairs,t_hackblock **ntdb, t_hackblock **ctdb,
1440 gmx_bool bAllowMissing,
1441 gmx_bool bVsites, gmx_bool bVsiteAromatics,
1442 const char *ff, const char *ffdir,
1444 int nssbonds, t_ssbond *ssbonds,
1445 real long_bond_dist, real short_bond_dist,
1446 gmx_bool bDeuterate, gmx_bool bChargeGroups, gmx_bool bCmap,
1447 gmx_bool bRenumRes,gmx_bool bRTPresname)
1453 t_params plist[F_NRE];
1460 gmx_residuetype_t rt;
1463 gmx_residuetype_init(&rt);
1466 print_resall(debug, atoms->nres, restp, atype);
1467 dump_hb(debug, atoms->nres, hb);
1471 at2bonds(&(plist[F_BONDS]), hb,
1473 long_bond_dist, short_bond_dist, bAllowMissing);
1475 /* specbonds: disulphide bonds & heme-his */
1476 do_ssbonds(&(plist[F_BONDS]),
1477 atoms, nssbonds, ssbonds,
1480 nmissat = name2type(atoms, &cgnr, atype, restp, rt);
1483 fprintf(stderr,"There were %d missing atoms in molecule %s\n",
1486 gmx_fatal(FARGS,"There were %d missing atoms in molecule %s, if you want to use this incomplete topology anyhow, use the option -missing",
1490 /* Cleanup bonds (sort and rm doubles) */
1491 clean_bonds(&(plist[F_BONDS]));
1493 snew(vsite_type,atoms->nr);
1494 for(i=0; i<atoms->nr; i++)
1495 vsite_type[i]=NOTSET;
1497 /* determine which atoms will be vsites and add dummy masses
1498 also renumber atom numbers in plist[0..F_NRE]! */
1499 do_vsites(nrtp, rtp, atype, atoms, tab, x, plist,
1500 &vsite_type, &cgnr, mHmult, bVsiteAromatics, ffdir);
1503 /* Make Angles and Dihedrals */
1504 fprintf(stderr,"Generating angles, dihedrals and pairs...\n");
1505 snew(excls,atoms->nr);
1506 init_nnb(&nnb,atoms->nr,4);
1507 gen_nnb(&nnb,plist);
1508 print_nnb(&nnb,"NNB");
1509 gen_pad(&nnb,atoms,restp,plist,excls,hb,bAllowMissing);
1515 gen_cmap(&(plist[F_CMAP]), restp, atoms, rt);
1516 if (plist[F_CMAP].nr > 0)
1518 fprintf(stderr, "There are %4d cmap torsion pairs\n",
1523 /* set mass of all remaining hydrogen atoms */
1525 do_h_mass(&(plist[F_BONDS]),vsite_type,atoms,mHmult,bDeuterate);
1528 /* Cleanup bonds (sort and rm doubles) */
1529 /* clean_bonds(&(plist[F_BONDS]));*/
1532 "There are %4d dihedrals, %4d impropers, %4d angles\n"
1533 " %4d pairs, %4d bonds and %4d virtual sites\n",
1534 plist[F_PDIHS].nr, plist[F_IDIHS].nr, plist[F_ANGLES].nr,
1535 plist[F_LJ14].nr, plist[F_BONDS].nr,
1536 plist[F_VSITE2].nr +
1537 plist[F_VSITE3].nr +
1538 plist[F_VSITE3FD].nr +
1539 plist[F_VSITE3FAD].nr +
1540 plist[F_VSITE3OUT].nr +
1541 plist[F_VSITE4FD].nr +
1542 plist[F_VSITE4FDN].nr );
1544 print_sums(atoms, FALSE);
1546 if (FALSE == bChargeGroups)
1548 scrub_charge_groups(cgnr, atoms->nr);
1553 for(i=0; i<atoms->nres; i++)
1555 atoms->resinfo[i].nr = i + 1;
1556 atoms->resinfo[i].ic = ' ';
1561 fprintf(stderr,"Writing topology\n");
1562 /* We can copy the bonded types from the first restp,
1563 * since the types have to be identical for all residues in one molecule.
1565 for(i=0; i<ebtsNR; i++) {
1566 bts[i] = restp[0].rb[i].type;
1568 write_top(top_file, posre_fn, molname,
1570 bts, plist, excls, atype, cgnr, restp[0].nrexcl);
1574 free_t_hackblock(atoms->nres, &hb);
1575 free_t_restp(atoms->nres, &restp);
1576 gmx_residuetype_destroy(rt);
1578 /* we should clean up hb and restp here, but that is a *L*O*T* of work! */
1580 for (i=0; i<F_NRE; i++)
1581 sfree(plist[i].param);
1582 for (i=0; i<atoms->nr; i++)