static void check_rtp(int nrtp,t_restp rtp[],char *libfn) { int i; /* check for double entries, assuming list is already sorted */ for(i=1; (i<nrtp); i++) { if (gmx_strcasecmp(rtp[i-1].resname,rtp[i].resname) == 0) fprintf(stderr,"WARNING double entry %s in file %s\n", rtp[i].resname,libfn); } }
int search_string(char *s,int ng,char ***gn) { int i; for(i=0; (i<ng); i++) if (gmx_strcasecmp(s,*gn[i]) == 0) return i; gmx_fatal(FARGS,"Group %s not found in indexfile.\nMaybe you have non-default groups in your mdp file, while not using the '-n' option of grompp.\nIn that case use the '-n' option.\n",s); return -1; }
static int find_kw(char *keyw) { int i; for (i = 0; i < ebtsNR; i++) { if (gmx_strcasecmp(btsNames[i], keyw) == 0) { return i; } } for (i = 0; i < ekwNR; i++) { if (gmx_strcasecmp(kw_names[i], keyw) == 0) { return ebtsNR + 1 + i; } } return NOTSET; }
int get_bt(char* header) { int i; for (i = 0; i < ebtsNR; i++) { if (gmx_strcasecmp(btsNames[i], header) == 0) { return i; } } return NOTSET; }
/* Search for a residuetype with name resnm within the * gmx_residuetype database. Return the index if found, * otherwise -1. */ int gmx_residuetype_get_index(gmx_residuetype_t rt, const char *resnm) { int i,rc; rc=-1; for(i=0;i<rt->n && rc;i++) { rc=gmx_strcasecmp(rt->resname[i],resnm); } return (0 == rc) ? i-1 : -1; }
static int match_str(const char *atom,const char *template_string) { if (!atom || !template_string) return ematchNone; else if (gmx_strcasecmp(atom,template_string) == 0) return ematchExact; else if (atom[0] == template_string[0]) return ematchElem; else if (strcmp(template_string,"*") == 0) return ematchWild; else return ematchNone; }
int gmx_atomprop_atomnumber(gmx_atomprop_t aps,const char *elem) { gmx_atomprop *ap = (gmx_atomprop*) aps; int i; set_prop(aps,epropElement); for(i=0; (i<ap->prop[epropElement].nprop); i++) { if (gmx_strcasecmp(ap->prop[epropElement].atomnm[i],elem) == 0) { return gmx_nint(ap->prop[epropElement].value[i]); } } return NOTSET; }
int search_jtype(t_restp *rtp,char *name,gmx_bool bNterm) { int niter,iter,j,k,kmax,jmax,minstrlen; char *rtpname,searchname[12]; strcpy(searchname,name); /* Do a best match comparison */ /* for protein N-terminus, allow renaming of H1, H2 and H3 to H */ if ( bNterm && (strlen(searchname)==2) && (searchname[0] == 'H') && ( (searchname[1] == '1') || (searchname[1] == '2') || (searchname[1] == '3') ) ) { niter = 2; } else { niter = 1; } kmax=0; jmax=-1; for(iter=0; (iter<niter && jmax==-1); iter++) { if (iter == 1) { /* Try without the hydrogen number in the N-terminus */ searchname[1] = '\0'; } for(j=0; (j<rtp->natom); j++) { rtpname=*(rtp->atomname[j]); if (gmx_strcasecmp(searchname,rtpname) == 0) { jmax=j; kmax=strlen(searchname); break; } if (iter == niter - 1) { minstrlen = min(strlen(searchname), strlen(rtpname)); for(k=0; k < minstrlen; k++) if (searchname[k] != rtpname[k]) break; if (k > kmax) { kmax=k; jmax=j; } } } } if (jmax == -1) gmx_fatal(FARGS,"Atom %s not found in rtp database in residue %s", searchname,rtp->resname); if (kmax != strlen(searchname)) gmx_fatal(FARGS,"Atom %s not found in rtp database in residue %s, " "it looks a bit like %s", searchname,rtp->resname,*(rtp->atomname[jmax])); return jmax; }
static void set_extension(char *buf, int ftp) { int len, extlen; const t_deffile *df; /* check if extension is already at end of filename */ df = &(deffile[ftp]); len = strlen(buf); extlen = strlen(df->ext); if ((len <= extlen) || (gmx_strcasecmp(&(buf[len - extlen]), df->ext) != 0)) { strcat(buf, df->ext); } }
/* Return 0 if the name was found, otherwise -1. * p_restype is set to a pointer to the type name, or 'Other' if we did not find it. */ int gmx_residuetype_get_type(gmx_residuetype_t rt,const char * resname, const char ** p_restype) { int i,rc; rc=-1; for(i=0;i<rt->n && rc;i++) { rc=gmx_strcasecmp(rt->resname[i],resname); } *p_restype = (rc==0) ? rt->restype[i-1] : gmx_residuetype_undefined; return rc; }
static void QuitCB(t_x11 *x11, int dlg_mess, int /*item_id*/, char *set, void *data) { t_gmx *gmx; gmx = (t_gmx *)data; hide_mb(gmx); if (dlg_mess == DLG_EXIT) { if (gmx_strcasecmp("yes", set) == 0) { write_gmx(x11, gmx, IDTERM); } } }
int search_str(int nstr, char **str, char *key) { int i; /* Linear search */ for (i = 0; (i < nstr); i++) { if (gmx_strcasecmp(str[i], key) == 0) { return i; } } return -1; }
int get_bond_atomtype_type(char *str, t_bond_atomtype at) { gpp_bond_atomtype *ga = (gpp_bond_atomtype *) at; int i; for (i = 0; (i < ga->nr); i++) { if (gmx_strcasecmp(str, *(ga->atomname[i])) == 0) { return i; } } return NOTSET; }
gmx_bool gmx_residuetype_is_rna(gmx_residuetype_t rt, const char *resnm) { gmx_bool rc; const char *p_type; if(gmx_residuetype_get_type(rt,resnm,&p_type)==0 && gmx_strcasecmp(p_type,"RNA")==0) { rc=TRUE; } else { rc=FALSE; } return rc; }
t_restp *get_restp(const char *rtpname, int nrtp, t_restp rtp[]) { int i; i = 0; while (i < nrtp && gmx_strcasecmp(rtpname, rtp[i].resname) != 0) { i++; } if (i >= nrtp) { /* This should never happen, since search_rtp should have been called * before calling get_restp. */ gmx_fatal(FARGS, "Residue type '%s' not found in residue topology database", rtpname); } return &rtp[i]; }
static void ExportCB(t_x11 *x11, int dlg_mess, int item_id, char *set, void *data) { bool bOk; t_gmx *gmx; t_dlg *dlg; gmx = (t_gmx *)data; dlg = gmx->dlgs[edExport]; switch (dlg_mess) { case DLG_SET: switch (item_id) { case eExGrom: gmx->ExpMode = eExpGromos; break; case eExPdb: gmx->ExpMode = eExpPDB; break; default: break; } #ifdef DEBUG fprintf(stderr, "exportcb: item_id=%d\n", item_id); #endif break; case DLG_EXIT: if ((bOk = gmx_strcasecmp("ok", set)) == 0) { strcpy(gmx->confout, EditText(dlg, eExConf)); } HideDlg(dlg); if (bOk) { write_gmx(x11, gmx, IDDOEXPORT); } break; } }
void match_atomnames_with_rtp(t_restp restp[],t_hackblock hb[], t_atoms *pdba,rvec *x, gmx_bool bVerbose) { int i,j,k; char *oldnm,*newnm; int resnr; t_restp *rptr; t_hackblock *hbr; int anmnr; char *start_at,buf[STRLEN]; int start_nr; gmx_bool bFoundInAdd; for(i=0; i<pdba->nr; i++) { oldnm = *pdba->atomname[i]; resnr = pdba->resinfo[pdba->atom[i].resind].nr; rptr = &restp[pdba->atom[i].resind]; for(j=0; (j<rptr->natom); j++) { if (gmx_strcasecmp(oldnm,*(rptr->atomname[j])) == 0) { break; } } if (j == rptr->natom) { /* Not found yet, check if we have to rename this atom */ if (match_atomnames_with_rtp_atom(pdba,x,i, rptr,&(hb[pdba->atom[i].resind]), bVerbose)) { /* We deleted this atom, decrease the atom counter by 1. */ i--; } } } }
static char *html_xref(char *s, const char *program, t_linkdata *links, gmx_bool bWiki) { char buf[256], **filestr; int i, j, n; if (links->sr == NULL) { n = get_file("links.dat", &(filestr)); links->nsr = n; snew(links->sr, n); for (i = 0, j = 0; (i < n); i++) { if (!program || (gmx_strcasecmp(program, filestr[i]) != 0)) { links->sr[j].search = gmx_strdup(filestr[i]); if (bWiki) { sprintf(buf, "[[%s]]", filestr[i]); } else { sprintf(buf, "<a href=\"%s.html\">%s</a>", filestr[i], filestr[i]); } links->sr[j].replace = gmx_strdup(buf); j++; } } links->nsr = j; for (i = 0; i < n; i++) { sfree(filestr[i]); } sfree(filestr); } return repallww(s, links->nsr, links->sr); }
/*! \brief * Checks the validity of parameters. * * \param[in] fp File handle to use for diagnostic messages * (can be NULL). * \param[in] name Name of the method (used for error messages). * \param[in] nparams Number of parameters in \p param. * \param[in,out] param Parameter array * (only the \c flags field of gmx_boolean parameters may be modified). * \param[in] symtab Symbol table (used for checking overlaps). * \returns TRUE if there are no problems with the parameters, * FALSE otherwise. * * This function performs some checks common to both check_method() and * check_modifier(). * The purpose of these checks is to ensure that the selection parser does not * need to check for the validity of the parameters at each turn, and to * report programming errors as early as possible. * If you remove a check, make sure that the parameter parser can handle the * resulting parameters. */ static gmx_bool check_params(FILE *fp, const char *name, int nparams, gmx_ana_selparam_t param[], gmx_sel_symtab_t *symtab) { gmx_bool bOk = TRUE; gmx_sel_symrec_t *sym; int i, j; if (nparams > 0 && !param) { report_error(fp, name, "error: missing parameter data"); return FALSE; } if (nparams == 0 && param) { report_error(fp, name, "warning: parameter data unused because nparams=0"); } /* Check each parameter */ for (i = 0; i < nparams; ++i) { /* Check that there is at most one NULL name, in the beginning */ if (param[i].name == NULL && i > 0) { report_error(fp, name, "error: NULL parameter should be the first one"); bOk = FALSE; continue; } /* Check for duplicates */ for (j = 0; j < i; ++j) { if (param[j].name == NULL) { continue; } if (!gmx_strcasecmp(param[i].name, param[j].name)) { report_error(fp, name, "error: duplicate parameter name '%s'", param[i].name); bOk = FALSE; break; } } /* Check flags */ if (param[i].flags & SPAR_SET) { report_param_error(fp, name, param[i].name, "warning: flag SPAR_SET is set"); param[i].flags &= ~SPAR_SET; } if (param[i].flags & SPAR_RANGES) { if (param[i].val.type != INT_VALUE && param[i].val.type != REAL_VALUE) { report_param_error(fp, name, param[i].name, "error: SPAR_RANGES cannot be set for a non-numeric parameter"); bOk = FALSE; } if (param[i].flags & SPAR_DYNAMIC) { report_param_error(fp, name, param[i].name, "warning: SPAR_DYNAMIC does not have effect with SPAR_RANGES"); param[i].flags &= ~SPAR_DYNAMIC; } if (!(param[i].flags & SPAR_VARNUM) && param[i].val.nr != 1) { report_param_error(fp, name, param[i].name, "error: range should take either one or an arbitrary number of values"); bOk = FALSE; } if (param[i].flags & SPAR_ATOMVAL) { report_param_error(fp, name, param[i].name, "error: SPAR_RANGES and SPAR_ATOMVAL both set"); bOk = FALSE; } } if ((param[i].flags & SPAR_VARNUM) && (param[i].flags & SPAR_ATOMVAL)) { report_param_error(fp, name, param[i].name, "error: SPAR_VARNUM and SPAR_ATOMVAL both set"); bOk = FALSE; } if (param[i].flags & SPAR_ENUMVAL) { if (param[i].val.type != STR_VALUE) { report_param_error(fp, name, param[i].name, "error: SPAR_ENUMVAL can only be set for string parameters"); bOk = FALSE; } if (param[i].val.nr != 1) { report_param_error(fp, name, param[i].name, "error: SPAR_ENUMVAL parameters should take exactly one value"); bOk = FALSE; } if (param[i].flags & (SPAR_DYNAMIC | SPAR_VARNUM | SPAR_ATOMVAL)) { report_param_error(fp, name, param[i].name, "error: only SPAR_OPTIONAL supported with SPAR_ENUMVAL"); bOk = FALSE; } } /* Check gmx_boolean parameters */ if (param[i].val.type == NO_VALUE) { if (param[i].val.nr != 0) { report_param_error(fp, name, param[i].name, "error: number of values should be zero for gmx_boolean parameters"); bOk = FALSE; } /* The gmx_boolean parameters should always be optional, so set the * flag for convenience. */ param[i].flags |= SPAR_OPTIONAL; /* Any other flags should not be specified */ if (param[i].flags & ~SPAR_OPTIONAL) { report_param_error(fp, name, param[i].name, "error: gmx_boolean parameter should not have any flags set"); bOk = FALSE; } } /* Check val.nr */ if (param[i].flags & (SPAR_VARNUM | SPAR_ATOMVAL)) { if (param[i].val.nr != -1) { report_param_error(fp, name, param[i].name, "warning: val.nr is not -1 although SPAR_VARNUM/SPAR_ATOMVAL is set"); } param[i].val.nr = -1; } else if (param[i].val.type != NO_VALUE) { if (param[i].val.nr <= 0) { report_param_error(fp, name, param[i].name, "error: val.nr <= 0"); bOk = FALSE; } } /* Check that the value pointer is NULL */ if (param[i].nvalptr != NULL) { report_param_error(fp, name, param[i].name, "warning: nvalptr is set"); } if (param[i].val.u.ptr != NULL && !(param[i].flags & SPAR_ENUMVAL)) { report_param_error(fp, name, param[i].name, "warning: value pointer is set"); } /* Check that the name contains only valid characters */ if (param[i].name == NULL) { continue; } if (!isalpha(param[i].name[0])) { report_param_error(fp, name, param[i].name, "error: name does not begin with a letter"); bOk = FALSE; continue; } for (j = 1; param[i].name[j] != 0; ++j) { if (param[i].name[j] != '_' && !isalnum(param[i].name[j])) { report_param_error(fp, name, param[i].name, "error: name contains non-alphanumeric characters"); bOk = FALSE; break; } } if (param[i].name[j] != 0) { continue; } /* Check that the name does not conflict with a method */ if (_gmx_sel_find_symbol(symtab, param[i].name, TRUE)) { report_param_error(fp, name, param[i].name, "error: name conflicts with another method or a keyword"); bOk = FALSE; } } /* End of parameter loop */ /* Check parameters of existing methods */ sym = _gmx_sel_first_symbol(symtab, SYMBOL_METHOD); while (sym) { gmx_ana_selmethod_t *method = _gmx_sel_sym_value_method(sym); gmx_ana_selparam_t *param = gmx_ana_selmethod_find_param(name, method); if (param) { report_param_error(fp, method->name, param->name, "error: name conflicts with another method or a keyword"); bOk = FALSE; } sym = _gmx_sel_next_symbol(sym, SYMBOL_METHOD); } return bOk; }
void analyse(t_atoms *atoms,t_blocka *gb,char ***gn,gmx_bool bASK,gmx_bool bVerb) { gmx_residuetype_t rt; char *resnm; atom_id *aid; const char ** restype; int nra; int i,k; size_t j; int ntypes; char * p; const char ** p_typename; int iwater,iion; int nwater,nion; int found; if (bVerb) { printf("Analysing residue names:\n"); } /* Create system group, every single atom */ snew(aid,atoms->nr); for(i=0;i<atoms->nr;i++) { aid[i]=i; } add_grp(gb,gn,atoms->nr,aid,"System"); sfree(aid); /* For every residue, get a pointer to the residue type name */ gmx_residuetype_init(&rt); snew(restype,atoms->nres); ntypes = 0; p_typename = NULL; for(i=0;i<atoms->nres;i++) { resnm = *atoms->resinfo[i].name; gmx_residuetype_get_type(rt,resnm,&(restype[i])); /* Note that this does not lead to a N*N loop, but N*K, where * K is the number of residue _types_, which is small and independent of N. */ found = 0; for(k=0;k<ntypes && !found;k++) { found = !strcmp(restype[i],p_typename[k]); } if(!found) { srenew(p_typename,ntypes+1); p_typename[ntypes++] = strdup(restype[i]); } } if (bVerb) { p_status(restype,atoms->nres,p_typename,ntypes); } for(k=0;k<ntypes;k++) { aid=mk_aid(atoms,restype,p_typename[k],&nra,TRUE); /* Check for special types to do fancy stuff with */ if(!gmx_strcasecmp(p_typename[k],"Protein") && nra>0) { sfree(aid); /* PROTEIN */ analyse_prot(restype,atoms,gb,gn,bASK,bVerb); /* Create a Non-Protein group */ aid=mk_aid(atoms,restype,"Protein",&nra,FALSE); if ((nra > 0) && (nra < atoms->nr)) { add_grp(gb,gn,nra,aid,"non-Protein"); } sfree(aid); } else if(!gmx_strcasecmp(p_typename[k],"Water") && nra>0) { add_grp(gb,gn,nra,aid,p_typename[k]); /* Add this group as 'SOL' too, for backward compatibility with older gromacs versions */ add_grp(gb,gn,nra,aid,"SOL"); sfree(aid); /* Solvent, create a negated group too */ aid=mk_aid(atoms,restype,"Water",&nra,FALSE); if ((nra > 0) && (nra < atoms->nr)) { add_grp(gb,gn,nra,aid,"non-Water"); } sfree(aid); } else if(nra>0) { /* Other groups */ add_grp(gb,gn,nra,aid,p_typename[k]); sfree(aid); analyse_other(restype,atoms,gb,gn,bASK,bVerb); } } sfree(p_typename); sfree(restype); gmx_residuetype_destroy(rt); /* Create a merged water_and_ions group */ iwater = -1; iion = -1; nwater = 0; nion = 0; for(i=0;i<gb->nr;i++) { if(!gmx_strcasecmp((*gn)[i],"Water")) { iwater = i; nwater = gb->index[i+1]-gb->index[i]; } else if(!gmx_strcasecmp((*gn)[i],"Ion")) { iion = i; nion = gb->index[i+1]-gb->index[i]; } } if(nwater>0 && nion>0) { srenew(gb->index,gb->nr+2); srenew(*gn,gb->nr+1); (*gn)[gb->nr] = strdup("Water_and_ions"); srenew(gb->a,gb->nra+nwater+nion); if(nwater>0) { for(i=gb->index[iwater];i<gb->index[iwater+1];i++) { gb->a[gb->nra++] = gb->a[i]; } } if(nion>0) { for(i=gb->index[iion];i<gb->index[iion+1];i++) { gb->a[gb->nra++] = gb->a[i]; } } gb->nr++; gb->index[gb->nr]=gb->nra; } }
int mk_specbonds(t_atoms *pdba,rvec x[],gmx_bool bInteractive, t_ssbond **specbonds,gmx_bool bVerbose) { t_specbond *sb=NULL; t_ssbond *bonds=NULL; int nsb; int nspec,nbonds; int *specp,*sgp; gmx_bool bDoit,bSwap; int i,j,b,e,e2; int ai,aj,index_sb; real **d; char buf[10]; nbonds = 0; sb = get_specbonds(&nsb); if (nsb > 0) { snew(specp,pdba->nr); snew(sgp,pdba->nr); nspec = 0; for(i=0; (i<pdba->nr); i++) { /* Check if this atom is special and if it is not a double atom * in the input that still needs to be removed. */ if (is_special(nsb,sb,*pdba->resinfo[pdba->atom[i].resind].name, *pdba->atomname[i]) && !(nspec > 0 && pdba->atom[sgp[nspec-1]].resind == pdba->atom[i].resind && gmx_strcasecmp(*pdba->atomname[sgp[nspec-1]], *pdba->atomname[i]) == 0)) { specp[nspec] = pdba->atom[i].resind; sgp[nspec] = i; nspec++; } } /* distance matrix d[nspec][nspec] */ snew(d,nspec); for(i=0; (i<nspec); i++) snew(d[i],nspec); for(i=0; (i<nspec); i++) { ai=sgp[i]; for(j=0; (j<nspec); j++) { aj=sgp[j]; d[i][j]=sqrt(distance2(x[ai],x[aj])); } } if (nspec > 1) { #define MAXCOL 7 fprintf(stderr,"Special Atom Distance matrix:\n"); for(b=0; (b<nspec); b+=MAXCOL) { /* print resname/number column headings */ fprintf(stderr,"%8s%8s","",""); e=min(b+MAXCOL, nspec-1); for(i=b; (i<e); i++) { sprintf(buf,"%s%d",*pdba->resinfo[pdba->atom[sgp[i]].resind].name, pdba->resinfo[specp[i]].nr); fprintf(stderr,"%8s",buf); } fprintf(stderr,"\n"); /* print atomname/number column headings */ fprintf(stderr,"%8s%8s","",""); e=min(b+MAXCOL, nspec-1); for(i=b; (i<e); i++) { sprintf(buf,"%s%d",*pdba->atomname[sgp[i]], sgp[i]+1); fprintf(stderr,"%8s",buf); } fprintf(stderr,"\n"); /* print matrix */ e=min(b+MAXCOL, nspec); for(i=b+1; (i<nspec); i++) { sprintf(buf,"%s%d",*pdba->resinfo[pdba->atom[sgp[i]].resind].name, pdba->resinfo[specp[i]].nr); fprintf(stderr,"%8s",buf); sprintf(buf,"%s%d", *pdba->atomname[sgp[i]], sgp[i]+1); fprintf(stderr,"%8s",buf); e2=min(i,e); for(j=b; (j<e2); j++) fprintf(stderr," %7.3f",d[i][j]); fprintf(stderr,"\n"); } } } snew(bonds,nspec); for(i=0; (i<nspec); i++) { ai = sgp[i]; for(j=i+1; (j<nspec); j++) { aj = sgp[j]; if (is_bond(nsb,sb,pdba,ai,aj,d[i][j],&index_sb,&bSwap)) { fprintf(stderr,"%s %s-%d %s-%d and %s-%d %s-%d%s", bInteractive ? "Link" : "Linking", *pdba->resinfo[pdba->atom[ai].resind].name, pdba->resinfo[specp[i]].nr, *pdba->atomname[ai], ai+1, *pdba->resinfo[pdba->atom[aj].resind].name, pdba->resinfo[specp[j]].nr, *pdba->atomname[aj], aj+1, bInteractive ? " (y/n) ?" : "...\n"); bDoit=bInteractive ? yesno() : TRUE; if (bDoit) { /* Store the residue numbers in the bonds array */ bonds[nbonds].res1 = specp[i]; bonds[nbonds].res2 = specp[j]; bonds[nbonds].a1 = strdup(*pdba->atomname[ai]); bonds[nbonds].a2 = strdup(*pdba->atomname[aj]); /* rename residues */ if (bSwap) { rename_1res(pdba,specp[i],sb[index_sb].newres2,bVerbose); rename_1res(pdba,specp[j],sb[index_sb].newres1,bVerbose); } else { rename_1res(pdba,specp[i],sb[index_sb].newres1,bVerbose); rename_1res(pdba,specp[j],sb[index_sb].newres2,bVerbose); } nbonds++; } } } } for(i=0; (i<nspec); i++) sfree(d[i]); sfree(d); sfree(sgp); sfree(specp); done_specbonds(nsb,sb); sfree(sb); } *specbonds=bonds; return nbonds; }
int search_atom(const char *type, int start, t_atoms *atoms, const char *bondtype, bool bAllowMissing) { int i, resind = -1; bool bPrevious, bNext; int natoms = atoms->nr; t_atom *at = atoms->atom; char ** const * anm = atoms->atomname; bPrevious = (strchr(type, '-') != nullptr); bNext = (strchr(type, '+') != nullptr); if (!bPrevious) { resind = at[start].resind; if (bNext) { /* The next residue */ type++; while ((start < natoms) && (at[start].resind == resind)) { start++; } if (start < natoms) { resind = at[start].resind; } } for (i = start; (i < natoms) && (bNext || (at[i].resind == resind)); i++) { if (anm[i] && gmx_strcasecmp(type, *(anm[i])) == 0) { return i; } } if (!(bNext && at[start].resind == at[natoms-1].resind)) { atom_not_found(FARGS, type, at[start].resind, *atoms->resinfo[resind].name, bondtype, bAllowMissing); } } else { /* The previous residue */ type++; if (start > 0) { resind = at[start-1].resind; } for (i = start-1; (i >= 0) /*&& (at[i].resind == resind)*/; i--) { if (gmx_strcasecmp(type, *(anm[i])) == 0) { return i; } } if (start > 0) { atom_not_found(FARGS, type, at[start].resind, *atoms->resinfo[resind].name, bondtype, bAllowMissing); } } return -1; }
void do_adress_index(t_adress *adress, gmx_groups_t *groups, char **gnames, t_grpopts *opts, warninp_t wi) { int nr, i, j, k; char *ptr1[MAXPTR]; int nadress_cg_grp_names, nadress_tf_grp_names; /* AdResS coarse grained groups input */ nr = groups->grps[egcENER].nr; snew(adress->group_explicit, nr); for (i = 0; i < nr; i++) { adress->group_explicit[i] = TRUE; } adress->n_energy_grps = nr; nadress_cg_grp_names = str_nelem(adress_cg_grp_names, MAXPTR, ptr1); if (nadress_cg_grp_names > 0) { for (i = 0; i < nadress_cg_grp_names; i++) { /* search for the group name mathching the tf group name */ k = 0; while ((k < nr) && gmx_strcasecmp(ptr1[i], (char*)(gnames[groups->grps[egcENER].nm_ind[k]]))) { k++; } if (k == nr) { gmx_fatal(FARGS, "Adress cg energy group %s not found\n", ptr1[i]); } adress->group_explicit[k] = FALSE; printf ("AdResS: Energy group %s is treated as coarse-grained \n", (char*)(gnames[groups->grps[egcENER].nm_ind[k]])); } /* set energy group exclusions between all coarse-grained and explicit groups */ for (j = 0; j < nr; j++) { for (k = 0; k < nr; k++) { if (!(adress->group_explicit[k] == adress->group_explicit[j])) { opts->egp_flags[nr * j + k] |= EGP_EXCL; if (debug) { fprintf(debug, "AdResS excl %s %s \n", (char*)(gnames[groups->grps[egcENER].nm_ind[j]]), (char*)(gnames[groups->grps[egcENER].nm_ind[k]])); } } } } } else { warning(wi, "For an AdResS simulation at least one coarse-grained energy group has to be specified in adress_cg_grp_names"); } /* AdResS multiple tf tables input */ nadress_tf_grp_names = str_nelem(adress_tf_grp_names, MAXPTR, ptr1); adress->n_tf_grps = nadress_tf_grp_names; snew(adress->tf_table_index, nadress_tf_grp_names); nr = groups->grps[egcENER].nr; if (nadress_tf_grp_names > 0) { for (i = 0; i < nadress_tf_grp_names; i++) { /* search for the group name mathching the tf group name */ k = 0; while ((k < nr) && gmx_strcasecmp(ptr1[i], (char*)(gnames[groups->grps[egcENER].nm_ind[k]]))) { k++; } if (k == nr) { gmx_fatal(FARGS, "Adress tf energy group %s not found\n", ptr1[i]); } adress->tf_table_index[i] = k; if (debug) { fprintf(debug, "found tf group %s id %d \n", ptr1[i], k); } if (adress->group_explicit[k]) { gmx_fatal(FARGS, "Thermodynamic force group %s is not a coarse-grained group in adress_cg_grp_names. The thermodynamic force has to act on the coarse-grained vsite of a molecule.\n", ptr1[i]); } } } /* end AdResS multiple tf tables input */ }
static void update_topol(const char *topinout, int p_num, int n_num, const char *p_name, const char *n_name, char *grpname) { FILE *fpin, *fpout; char buf[STRLEN], buf2[STRLEN], *temp, **mol_line = NULL; int line, i, nmol_line, sol_line, nsol_last; gmx_bool bMolecules; char temporary_filename[STRLEN]; printf("\nProcessing topology\n"); fpin = gmx_ffopen(topinout, "r"); std::strncpy(temporary_filename, "temp.topXXXXXX", STRLEN); fpout = gmx_fopen_temporary(temporary_filename); line = 0; bMolecules = FALSE; nmol_line = 0; sol_line = -1; nsol_last = -1; while (fgets(buf, STRLEN, fpin)) { line++; std::strcpy(buf2, buf); if ((temp = std::strchr(buf2, '\n')) != NULL) { temp[0] = '\0'; } ltrim(buf2); if (buf2[0] == '[') { buf2[0] = ' '; if ((temp = std::strchr(buf2, '\n')) != NULL) { temp[0] = '\0'; } rtrim(buf2); if (buf2[std::strlen(buf2)-1] == ']') { buf2[std::strlen(buf2)-1] = '\0'; ltrim(buf2); rtrim(buf2); bMolecules = (gmx_strcasecmp(buf2, "molecules") == 0); } fprintf(fpout, "%s", buf); } else if (!bMolecules) { fprintf(fpout, "%s", buf); } else { /* Check if this is a line with solvent molecules */ sscanf(buf, "%s", buf2); if (gmx_strcasecmp(buf2, grpname) == 0) { sol_line = nmol_line; sscanf(buf, "%*s %d", &nsol_last); } /* Store this molecules section line */ srenew(mol_line, nmol_line+1); mol_line[nmol_line] = gmx_strdup(buf); nmol_line++; } } gmx_ffclose(fpin); if (sol_line == -1) { gmx_ffclose(fpout); gmx_fatal(FARGS, "No line with moleculetype '%s' found the [ molecules ] section of file '%s'", grpname, topinout); } if (nsol_last < p_num+n_num) { gmx_ffclose(fpout); gmx_fatal(FARGS, "The last entry for moleculetype '%s' in the [ molecules ] section of file '%s' has less solvent molecules (%d) than were replaced (%d)", grpname, topinout, nsol_last, p_num+n_num); } /* Print all the molecule entries */ for (i = 0; i < nmol_line; i++) { if (i != sol_line) { fprintf(fpout, "%s", mol_line[i]); } else { printf("Replacing %d solute molecules in topology file (%s) " " by %d %s and %d %s ions.\n", p_num+n_num, topinout, p_num, p_name, n_num, n_name); nsol_last -= p_num + n_num; if (nsol_last > 0) { fprintf(fpout, "%-10s %d\n", grpname, nsol_last); } if (p_num > 0) { fprintf(fpout, "%-15s %d\n", p_name, p_num); } if (n_num > 0) { fprintf(fpout, "%-15s %d\n", n_name, n_num); } } } gmx_ffclose(fpout); make_backup(topinout); gmx_file_rename(temporary_filename, topinout); }
static void analyse_prot(const char ** restype,t_atoms *atoms, t_blocka *gb,char ***gn,gmx_bool bASK,gmx_bool bVerb) { /* atomnames to be used in constructing index groups: */ static const char *pnoh[] = { "H" }; static const char *pnodum[] = { "MN1", "MN2", "MCB1", "MCB2", "MCG1", "MCG2", "MCD1", "MCD2", "MCE1", "MCE2", "MNZ1", "MNZ2" }; static const char *calpha[] = { "CA" }; static const char *bb[] = { "N","CA","C" }; static const char *mc[] = { "N","CA","C","O","O1","O2","OC1","OC2","OT","OXT" }; static const char *mcb[] = { "N","CA","CB","C","O","O1","O2","OC1","OC2","OT","OXT" }; static const char *mch[] = { "N","CA","C","O","O1","O2","OC1","OC2","OT","OXT", "H1","H2","H3","H" }; /* array of arrays of atomnames: */ static const char **chains[] = { NULL,pnoh,calpha,bb,mc,mcb,mch,mch,mch,pnodum }; #define NCH asize(chains) /* array of sizes of arrays of atomnames: */ const int sizes[NCH] = { 0, asize(pnoh), asize(calpha), asize(bb), asize(mc), asize(mcb), asize(mch), asize(mch), asize(mch), asize(pnodum) }; /* descriptive names of index groups */ const char *ch_name[NCH] = { "Protein", "Protein-H", "C-alpha", "Backbone", "MainChain", "MainChain+Cb", "MainChain+H", "SideChain", "SideChain-H", "Prot-Masses" }; /* construct index group containing (TRUE) or excluding (FALSE) given atom names */ const gmx_bool complement[NCH] = { TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE }; const int wholename[NCH] = { -1, 0,-1,-1,-1,-1,-1,-1, 11,-1 }; /* the index in wholename gives the first item in the arrays of * atomtypes that should be tested with 'gmx_strncasecmp' in stead of * gmx_strcasecmp, or -1 if all items should be tested with strcasecmp * This is comparable to using a '*' wildcard at the end of specific * atom names, but that is more involved to implement... */ /* only add index group if it differs from the specified one, specify -1 to always add group */ const int compareto[NCH] = { -1,-1,-1,-1,-1,-1,-1,-1,-1, 0 }; int n,j; atom_id *aid; int nra,nnpres,npres; gmx_bool match; char ndx_name[STRLEN],*atnm; int i; if (bVerb) { printf("Analysing Protein...\n"); } snew(aid,atoms->nr); /* calculate the number of protein residues */ npres=0; for(i=0; (i<atoms->nres); i++) if (!gmx_strcasecmp(restype[i],"Protein")) { npres++; } /* find matching or complement atoms */ for(i=0; (i<(int)NCH); i++) { nra=0; for(n=0; (n<atoms->nr); n++) { if (!gmx_strcasecmp(restype[atoms->atom[n].resind],"Protein")) { match=FALSE; for(j=0; (j<sizes[i]); j++) { /* skip digits at beginning of atomname, e.g. 1H */ atnm=*atoms->atomname[n]; while (isdigit(atnm[0])) atnm++; if ( (wholename[i]==-1) || (j<wholename[i]) ) { if (gmx_strcasecmp(chains[i][j],atnm) == 0) match=TRUE; } else { if (gmx_strncasecmp(chains[i][j],atnm,strlen(chains[i][j])) == 0) match=TRUE; } } if (match != complement[i]) aid[nra++]=n; } } /* if we want to add this group always or it differs from previous group, add it: */ if ( compareto[i] == -1 || !grp_cmp(gb,nra,aid,compareto[i]-i) ) add_grp(gb,gn,nra,aid,ch_name[i]); } if (bASK) { for(i=0; (i<(int)NCH); i++) { printf("Split %12s into %5d residues (y/n) ? ",ch_name[i],npres); if (gmx_ask_yesno(bASK)) { int resind; nra = 0; for(n=0;((atoms->atom[n].resind < npres) && (n<atoms->nr));) { resind = atoms->atom[n].resind; for(;((atoms->atom[n].resind==resind) && (n<atoms->nr));n++) { match=FALSE; for(j=0;(j<sizes[i]); j++) if (gmx_strcasecmp(chains[i][j],*atoms->atomname[n]) == 0) match=TRUE; if (match != complement[i]) aid[nra++]=n; } /* copy the residuename to the tail of the groupname */ if (nra > 0) { t_resinfo *ri; ri = &atoms->resinfo[resind]; sprintf(ndx_name,"%s_%s%d%c", ch_name[i],*ri->name,ri->nr,ri->ic==' ' ? '\0' : ri->ic); add_grp(gb,gn,nra,aid,ndx_name); nra = 0; } } } } printf("Make group with sidechain and C=O swapped (y/n) ? "); if (gmx_ask_yesno(bASK)) { /* Make swap sidechain C=O index */ int resind,hold; nra = 0; for(n=0;((atoms->atom[n].resind < npres) && (n<atoms->nr));) { resind = atoms->atom[n].resind; hold = -1; for(;((atoms->atom[n].resind==resind) && (n<atoms->nr));n++) if (strcmp("CA",*atoms->atomname[n]) == 0) { aid[nra++]=n; hold=nra; nra+=2; } else if (strcmp("C",*atoms->atomname[n]) == 0) { if (hold == -1) gmx_incons("Atom naming problem"); aid[hold]=n; } else if (strcmp("O",*atoms->atomname[n]) == 0) { if (hold == -1) gmx_incons("Atom naming problem"); aid[hold+1]=n; } else if (strcmp("O1",*atoms->atomname[n]) == 0) { if (hold == -1) gmx_incons("Atom naming problem"); aid[hold+1]=n; } else aid[nra++]=n; } /* copy the residuename to the tail of the groupname */ if (nra > 0) { add_grp(gb,gn,nra,aid,"SwapSC-CO"); nra = 0; } } } sfree(aid); }
static void analyse_other(const char ** restype,t_atoms *atoms, t_blocka *gb,char ***gn,gmx_bool bASK,gmx_bool bVerb) { restp_t *restp=NULL; char **attp=NULL; char *rname,*aname; atom_id *other_ndx,*aid,*aaid; int i,j,k,l,resind,naid,naaid,natp,nrestp=0; for(i=0; (i<atoms->nres); i++) { if (gmx_strcasecmp(restype[i],"Protein") && gmx_strcasecmp(restype[i],"DNA") && gmx_strcasecmp(restype[i],"RNA") && gmx_strcasecmp(restype[i],"Water")) { break; } } if (i < atoms->nres) { /* we have others */ if (bVerb) printf("Analysing residues not classified as Protein/DNA/RNA/Water and splitting into groups...\n"); snew(other_ndx,atoms->nr); for(k=0; (k<atoms->nr); k++) { resind = atoms->atom[k].resind; rname = *atoms->resinfo[resind].name; if (gmx_strcasecmp(restype[resind],"Protein") && gmx_strcasecmp(restype[resind],"DNA") && gmx_strcasecmp(restype[resind],"RNA") && gmx_strcasecmp(restype[resind],"Water")) { for(l=0; (l<nrestp); l++) if (strcmp(restp[l].rname,rname) == 0) break; if (l==nrestp) { srenew(restp,nrestp+1); restp[nrestp].rname = strdup(rname); restp[nrestp].bNeg = FALSE; restp[nrestp].gname = strdup(rname); nrestp++; } } } for(i=0; (i<nrestp); i++) { snew(aid,atoms->nr); naid=0; for(j=0; (j<atoms->nr); j++) { rname = *atoms->resinfo[atoms->atom[j].resind].name; if ((strcmp(restp[i].rname,rname) == 0 && !restp[i].bNeg) || (strcmp(restp[i].rname,rname) != 0 && restp[i].bNeg)) { aid[naid++] = j; } } add_grp(gb,gn,naid,aid,restp[i].gname); if (bASK) { printf("split %s into atoms (y/n) ? ",restp[i].gname); fflush(stdout); if (gmx_ask_yesno(bASK)) { natp=0; for(k=0; (k<naid); k++) { aname=*atoms->atomname[aid[k]]; for(l=0; (l<natp); l++) if (strcmp(aname,attp[l]) == 0) break; if (l == natp) { srenew(attp,++natp); attp[natp-1]=aname; } } if (natp > 1) { for(l=0; (l<natp); l++) { snew(aaid,naid); naaid=0; for(k=0; (k<naid); k++) { aname=*atoms->atomname[aid[k]]; if (strcmp(aname,attp[l])==0) aaid[naaid++]=aid[k]; } add_grp(gb,gn,naaid,aaid,attp[l]); sfree(aaid); } } sfree(attp); attp=NULL; } sfree(aid); } } sfree(other_ndx); } }
void rename_atoms(const char *xlfile,const char *ffdir, t_atoms *atoms,t_symtab *symtab,const t_restp *restp, gmx_bool bResname,gmx_residuetype_t rt,gmx_bool bReorderNum, gmx_bool bVerbose) { FILE *fp; int nxlate,a,i,resind; t_xlate_atom *xlatom; int nf; char **f; char c,*rnm,atombuf[32],*ptr0,*ptr1; gmx_bool bReorderedNum,bRenamed,bMatch; nxlate = 0; xlatom = NULL; if (xlfile != NULL) { fp = libopen(xlfile); get_xlatoms(xlfile,fp,&nxlate,&xlatom); fclose(fp); } else { nf = fflib_search_file_end(ffdir,".arn",FALSE,&f); for(i=0; i<nf; i++) { fp = fflib_open(f[i]); get_xlatoms(f[i],fp,&nxlate,&xlatom); fclose(fp); sfree(f[i]); } sfree(f); } for(a=0; (a<atoms->nr); a++) { resind = atoms->atom[a].resind; if (bResname) { rnm = *(atoms->resinfo[resind].name); } else { rnm = *(atoms->resinfo[resind].rtp); } strcpy(atombuf,*(atoms->atomname[a])); bReorderedNum = FALSE; if (bReorderNum) { if (isdigit(atombuf[0])) { c = atombuf[0]; for (i=0; ((size_t)i<strlen(atombuf)-1); i++) { atombuf[i] = atombuf[i+1]; } atombuf[i] = c; bReorderedNum = TRUE; } } bRenamed = FALSE; for(i=0; (i<nxlate) && !bRenamed; i++) { /* Check if the base file name of the rtp and arn entry match */ if (restp == NULL || gmx_strcasecmp(restp[resind].filebase,xlatom[i].filebase) == 0) { /* Match the residue name */ bMatch = (xlatom[i].res == NULL || (gmx_strcasecmp("protein",xlatom[i].res) == 0 && gmx_residuetype_is_protein(rt,rnm)) || (gmx_strcasecmp("DNA",xlatom[i].res) == 0 && gmx_residuetype_is_dna(rt,rnm)) || (gmx_strcasecmp("RNA",xlatom[i].res) == 0 && gmx_residuetype_is_rna(rt,rnm))); if (!bMatch) { ptr0 = rnm; ptr1 = xlatom[i].res; while (ptr0[0] != '\0' && ptr1[0] != '\0' && (ptr0[0] == ptr1[0] || ptr1[0] == '?')) { ptr0++; ptr1++; } bMatch = (ptr0[0] == '\0' && ptr1[0] == '\0'); } if (bMatch && strcmp(atombuf,xlatom[i].atom) == 0) { /* We have a match. */ /* Don't free the old atomname, * since it might be in the symtab. */ ptr0 = strdup(xlatom[i].replace); if (bVerbose) { printf("Renaming atom '%s' in residue %d %s to '%s'\n", *atoms->atomname[a], atoms->resinfo[resind].nr, *atoms->resinfo[resind].name, ptr0); } atoms->atomname[a] = put_symtab(symtab,ptr0); bRenamed = TRUE; } } } if (bReorderedNum && !bRenamed) { atoms->atomname[a] = put_symtab(symtab,atombuf); } } done_xlatom(nxlate,xlatom); }
char *search_rtp(const char *key, int nrtp, t_restp rtp[]) { int i, n, nbest, best, besti; char bestbuf[STRLEN]; nbest = 0; besti = -1; /* We want to match at least one character */ best = 1; for (i = 0; (i < nrtp); i++) { if (gmx_strcasecmp(key, rtp[i].resname) == 0) { besti = i; nbest = 1; break; } else { /* Allow a mismatch of at most a sign character (with warning) */ n = neq_str_sign(key, rtp[i].resname); if (n >= best && n+1 >= (int)strlen(key) && n+1 >= (int)strlen(rtp[i].resname)) { if (n == best) { if (nbest == 1) { strcpy(bestbuf, rtp[besti].resname); } if (nbest >= 1) { strcat(bestbuf, " or "); strcat(bestbuf, rtp[i].resname); } } else { nbest = 0; } besti = i; best = n; nbest++; } } } if (nbest > 1) { gmx_fatal(FARGS, "Residue '%s' not found in residue topology database, looks a bit like %s", key, bestbuf); } else if (besti == -1) { gmx_fatal(FARGS, "Residue '%s' not found in residue topology database", key); } if (gmx_strcasecmp(rtp[besti].resname, key) != 0) { fprintf(stderr, "\nWARNING: '%s' not found in residue topology database, " "trying to use '%s'\n\n", key, rtp[besti].resname); } return rtp[besti].resname; }
static void update_top(t_atoms *atoms, matrix box, int NFILE, t_filenm fnm[], gmx_atomprop_t aps) { #define TEMP_FILENM "temp.top" FILE *fpin, *fpout; char buf[STRLEN], buf2[STRLEN], *temp; const char *topinout; int line; gmx_bool bSystem, bMolecules, bSkip; int i, nsol = 0; double mtot; real vol, mm; for (i = 0; (i < atoms->nres); i++) { /* calculate number of SOLvent molecules */ if ( (strcmp(*atoms->resinfo[i].name, "SOL") == 0) || (strcmp(*atoms->resinfo[i].name, "WAT") == 0) || (strcmp(*atoms->resinfo[i].name, "HOH") == 0) ) { nsol++; } } mtot = 0; for (i = 0; (i < atoms->nr); i++) { gmx_atomprop_query(aps, epropMass, *atoms->resinfo[atoms->atom[i].resind].name, *atoms->atomname[i], &mm); mtot += mm; } vol = det(box); fprintf(stderr, "Volume : %10g (nm^3)\n", vol); fprintf(stderr, "Density : %10g (g/l)\n", (mtot*1e24)/(AVOGADRO*vol)); fprintf(stderr, "Number of SOL molecules: %5d \n\n", nsol); /* open topology file and append sol molecules */ topinout = ftp2fn(efTOP, NFILE, fnm); if (ftp2bSet(efTOP, NFILE, fnm) ) { fprintf(stderr, "Processing topology\n"); fpin = ffopen(topinout, "r"); fpout = ffopen(TEMP_FILENM, "w"); line = 0; bSystem = bMolecules = FALSE; while (fgets(buf, STRLEN, fpin)) { bSkip = FALSE; line++; strcpy(buf2, buf); if ((temp = strchr(buf2, '\n')) != NULL) { temp[0] = '\0'; } ltrim(buf2); if (buf2[0] == '[') { buf2[0] = ' '; if ((temp = strchr(buf2, '\n')) != NULL) { temp[0] = '\0'; } rtrim(buf2); if (buf2[strlen(buf2)-1] == ']') { buf2[strlen(buf2)-1] = '\0'; ltrim(buf2); rtrim(buf2); bSystem = (gmx_strcasecmp(buf2, "system") == 0); bMolecules = (gmx_strcasecmp(buf2, "molecules") == 0); } } else if (bSystem && nsol && (buf[0] != ';') ) { /* if sol present, append "in water" to system name */ rtrim(buf2); if (buf2[0] && (!strstr(buf2, " water")) ) { sprintf(buf, "%s in water\n", buf2); bSystem = FALSE; } } else if (bMolecules) { /* check if this is a line with solvent molecules */ sscanf(buf, "%s", buf2); if (strcmp(buf2, "SOL") == 0) { sscanf(buf, "%*s %d", &i); nsol -= i; if (nsol < 0) { bSkip = TRUE; nsol += i; } } } if (bSkip) { if ((temp = strchr(buf, '\n')) != NULL) { temp[0] = '\0'; } fprintf(stdout, "Removing line #%d '%s' from topology file (%s)\n", line, buf, topinout); } else { fprintf(fpout, "%s", buf); } } ffclose(fpin); if (nsol) { fprintf(stdout, "Adding line for %d solvent molecules to " "topology file (%s)\n", nsol, topinout); fprintf(fpout, "%-15s %5d\n", "SOL", nsol); } ffclose(fpout); /* use ffopen to generate backup of topinout */ fpout = ffopen(topinout, "w"); ffclose(fpout); rename(TEMP_FILENM, topinout); } #undef TEMP_FILENM }
void read_resall(char *rrdb, int *nrtpptr, t_restp **rtp, gpp_atomtype_t atype, t_symtab *tab, gmx_bool bAllowOverrideRTP) { FILE *in; char filebase[STRLEN], line[STRLEN], header[STRLEN]; int i, nrtp, maxrtp, bt, nparam; int dum1, dum2, dum3; t_restp *rrtp, *header_settings; gmx_bool bNextResidue, bError; int firstrtp; fflib_filename_base(rrdb, filebase, STRLEN); in = fflib_open(rrdb); if (debug) { fprintf(debug, "%9s %5s", "Residue", "atoms"); for (i = 0; i < ebtsNR; i++) { fprintf(debug, " %10s", btsNames[i]); } fprintf(debug, "\n"); } snew(header_settings, 1); /* these bonded parameters will overwritten be when * * there is a [ bondedtypes ] entry in the .rtp file */ header_settings->rb[ebtsBONDS].type = 1; /* normal bonds */ header_settings->rb[ebtsANGLES].type = 1; /* normal angles */ header_settings->rb[ebtsPDIHS].type = 1; /* normal dihedrals */ header_settings->rb[ebtsIDIHS].type = 2; /* normal impropers */ header_settings->rb[ebtsEXCLS].type = 1; /* normal exclusions */ header_settings->rb[ebtsCMAP].type = 1; /* normal cmap torsions */ header_settings->bKeepAllGeneratedDihedrals = FALSE; header_settings->nrexcl = 3; header_settings->bGenerateHH14Interactions = TRUE; header_settings->bRemoveDihedralIfWithImproper = TRUE; /* Column 5 & 6 aren't really bonded types, but we include * them here to avoid introducing a new section: * Column 5 : This controls the generation of dihedrals from the bonding. * All possible dihedrals are generated automatically. A value of * 1 here means that all these are retained. A value of * 0 here requires generated dihedrals be removed if * * there are any dihedrals on the same central atoms * specified in the residue topology, or * * there are other identical generated dihedrals * sharing the same central atoms, or * * there are other generated dihedrals sharing the * same central bond that have fewer hydrogen atoms * Column 6: Number of bonded neighbors to exclude. * Column 7: Generate 1,4 interactions between two hydrogen atoms * Column 8: Remove proper dihedrals if centered on the same bond * as an improper dihedral */ get_a_line(in, line, STRLEN); if (!get_header(line, header)) { gmx_fatal(FARGS, "in .rtp file at line:\n%s\n", line); } if (gmx_strncasecmp("bondedtypes", header, 5) == 0) { get_a_line(in, line, STRLEN); if ((nparam = sscanf(line, "%d %d %d %d %d %d %d %d", &header_settings->rb[ebtsBONDS].type, &header_settings->rb[ebtsANGLES].type, &header_settings->rb[ebtsPDIHS].type, &header_settings->rb[ebtsIDIHS].type, &dum1, &header_settings->nrexcl, &dum2, &dum3)) < 4) { gmx_fatal(FARGS, "need 4 to 8 parameters in the header of .rtp file %s at line:\n%s\n", rrdb, line); } header_settings->bKeepAllGeneratedDihedrals = (dum1 != 0); header_settings->bGenerateHH14Interactions = (dum2 != 0); header_settings->bRemoveDihedralIfWithImproper = (dum3 != 0); get_a_line(in, line, STRLEN); if (nparam < 5) { fprintf(stderr, "Using default: not generating all possible dihedrals\n"); header_settings->bKeepAllGeneratedDihedrals = FALSE; } if (nparam < 6) { fprintf(stderr, "Using default: excluding 3 bonded neighbors\n"); header_settings->nrexcl = 3; } if (nparam < 7) { fprintf(stderr, "Using default: generating 1,4 H--H interactions\n"); header_settings->bGenerateHH14Interactions = TRUE; } if (nparam < 8) { fprintf(stderr, "Using default: removing proper dihedrals found on the same bond as a proper dihedral\n"); header_settings->bRemoveDihedralIfWithImproper = TRUE; } } else { fprintf(stderr, "Reading .rtp file without '[ bondedtypes ]' directive,\n" "Will proceed as if the entry was:\n"); print_resall_header(stderr, header_settings); } /* We don't know the current size of rrtp, but simply realloc immediately */ nrtp = *nrtpptr; rrtp = *rtp; maxrtp = nrtp; while (!feof(in)) { if (nrtp >= maxrtp) { maxrtp += 100; srenew(rrtp, maxrtp); } /* Initialise rtp entry structure */ rrtp[nrtp] = *header_settings; if (!get_header(line, header)) { gmx_fatal(FARGS, "in .rtp file at line:\n%s\n", line); } rrtp[nrtp].resname = gmx_strdup(header); rrtp[nrtp].filebase = gmx_strdup(filebase); get_a_line(in, line, STRLEN); bError = FALSE; bNextResidue = FALSE; do { if (!get_header(line, header)) { bError = TRUE; } else { bt = get_bt(header); if (bt != NOTSET) { /* header is an bonded directive */ bError = !read_bondeds(bt, in, line, &rrtp[nrtp]); } else if (gmx_strncasecmp("atoms", header, 5) == 0) { /* header is the atoms directive */ bError = !read_atoms(in, line, &(rrtp[nrtp]), tab, atype); } else { /* else header must be a residue name */ bNextResidue = TRUE; } } if (bError) { gmx_fatal(FARGS, "in .rtp file in residue %s at line:\n%s\n", rrtp[nrtp].resname, line); } } while (!feof(in) && !bNextResidue); if (rrtp[nrtp].natom == 0) { gmx_fatal(FARGS, "No atoms found in .rtp file in residue %s\n", rrtp[nrtp].resname); } if (debug) { fprintf(debug, "%3d %5s %5d", nrtp+1, rrtp[nrtp].resname, rrtp[nrtp].natom); for (i = 0; i < ebtsNR; i++) { fprintf(debug, " %10d", rrtp[nrtp].rb[i].nb); } fprintf(debug, "\n"); } firstrtp = -1; for (i = 0; i < nrtp; i++) { if (gmx_strcasecmp(rrtp[i].resname, rrtp[nrtp].resname) == 0) { firstrtp = i; } } if (firstrtp == -1) { nrtp++; fprintf(stderr, "\rResidue %d", nrtp); fflush(stderr); } else { if (firstrtp >= *nrtpptr) { gmx_fatal(FARGS, "Found a second entry for '%s' in '%s'", rrtp[nrtp].resname, rrdb); } if (bAllowOverrideRTP) { fprintf(stderr, "\n"); fprintf(stderr, "Found another rtp entry for '%s' in '%s', ignoring this entry and keeping the one from '%s.rtp'\n", rrtp[nrtp].resname, rrdb, rrtp[firstrtp].filebase); /* We should free all the data for this entry. * The current code gives a lot of dangling pointers. */ clear_t_restp(&rrtp[nrtp]); } else { gmx_fatal(FARGS, "Found rtp entries for '%s' in both '%s' and '%s'. If you want the first definition to override the second one, set the -rtpo option of pdb2gmx.", rrtp[nrtp].resname, rrtp[firstrtp].filebase, rrdb); } } } gmx_ffclose(in); /* give back unused memory */ srenew(rrtp, nrtp); fprintf(stderr, "\nSorting it all out...\n"); qsort(rrtp, nrtp, (size_t)sizeof(rrtp[0]), comprtp); check_rtp(nrtp, rrtp, rrdb); *nrtpptr = nrtp; *rtp = rrtp; }