static void rd_nm2type_file(const char *fn,int *nnm,t_nm2type **nmp) { FILE *fp; gmx_bool bCont; char libfilename[128]; char format[128],f1[128]; char buf[1024],elem[16],type[16],nbbuf[16],**newbuf; int i,nb,nnnm,line=1; double qq,mm,*blen; t_nm2type *nm2t=NULL; fp = fflib_open(fn); if (NULL == fp) gmx_fatal(FARGS,"Can not find %s in library directory",fn); nnnm = *nnm; nm2t = *nmp; do { /* Read a line from the file */ bCont = (fgets2(buf,1023,fp) != NULL); if (bCont) { /* Remove comment */ strip_comment(buf); if (sscanf(buf,"%s%s%lf%lf%d",elem,type,&qq,&mm,&nb) == 5) { /* If we can read the first four, there probably is more */ srenew(nm2t,nnnm+1); snew(nm2t[nnnm].blen,nb); if (nb > 0) { snew(newbuf,nb); strcpy(format,"%*s%*s%*s%*s%*s"); for(i=0; (i<nb); i++) { /* Complicated format statement */ strcpy(f1,format); strcat(f1,"%s%lf"); if (sscanf(buf,f1,nbbuf,&(nm2t[nnnm].blen[i])) != 2) gmx_fatal(FARGS,"Error on line %d of %s",line,libfilename); newbuf[i] = strdup(nbbuf); strcat(format,"%*s%*s"); } } else newbuf = NULL; nm2t[nnnm].elem = strdup(elem); nm2t[nnnm].type = strdup(type); nm2t[nnnm].q = qq; nm2t[nnnm].m = mm; nm2t[nnnm].nbonds = nb; nm2t[nnnm].bond = newbuf; nnnm++; } line++; } } while(bCont); ffclose(fp); *nnm = nnnm; *nmp = nm2t; }
gpp_atomtype_t read_atype(const char *ffdir, t_symtab *tab) { int nfile, f; char **file; FILE *in; char buf[STRLEN], name[STRLEN]; double m; int nratt = 0; gpp_atomtype_t at; t_atom *a; t_param *nb; nfile = fflib_search_file_end(ffdir, ".atp", TRUE, &file); at = init_atomtype(); snew(a, 1); snew(nb, 1); for (f = 0; f < nfile; f++) { in = fflib_open(file[f]); while (!feof(in)) { /* Skip blank or comment-only lines */ do { if (fgets2(buf, STRLEN, in) != NULL) { strip_comment(buf); trim(buf); } } while (!feof(in) && strlen(buf) == 0); if (sscanf(buf, "%s%lf", name, &m) == 2) { a->m = m; add_atomtype(at, tab, a, name, nb, 0, 0.0, 0.0, 0.0, 0, 0.0, 0.0 ); fprintf(stderr, "\rAtomtype %d", ++nratt); fflush(stderr); } else { fprintf(stderr, "\nInvalid format: %s\n", buf); } } gmx_ffclose(in); sfree(file[f]); } fprintf(stderr, "\n"); sfree(file); return at; }
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); }
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; }
static void read_h_db_file(const char *hfn,int *nahptr,t_hackblock **ah) { FILE *in; char filebase[STRLEN],line[STRLEN], buf[STRLEN]; int i, n, nab, nah; t_hackblock *aah; if (debug) fprintf(debug,"Hydrogen Database (%s):\n",hfn); fflib_filename_base(hfn,filebase,STRLEN); /* Currently filebase is read and set, but not used. * hdb entries from any hdb file and be applied to rtp entries * in any rtp file. */ in = fflib_open(hfn); nah = *nahptr; aah = *ah; while (fgets2(line,STRLEN-1,in)) { if (sscanf(line,"%s%n",buf,&n) != 1) { fprintf(stderr,"Error in hdb file: nah = %d\nline = '%s'\n", nah,line); break; } if (debug) fprintf(debug,"%s",buf); srenew(aah,nah+1); clear_t_hackblock(&aah[nah]); aah[nah].name = strdup(buf); aah[nah].filebase = strdup(filebase); if (sscanf(line+n,"%d",&nab) == 1) { if (debug) fprintf(debug," %d\n",nab); snew(aah[nah].hack,nab); aah[nah].nhack = nab; for(i=0; (i<nab); i++) { if (feof(in)) gmx_fatal(FARGS, "Expected %d lines of hydrogens, found only %d " "while reading Hydrogen Database %s residue %s", nab, i-1, aah[nah].name, hfn); if(NULL==fgets(buf, STRLEN, in)) { gmx_fatal(FARGS,"Error reading from file %s",hfn); } read_ab(buf,hfn,&(aah[nah].hack[i])); } } nah++; } ffclose(in); /* Sort the list (necessary to be able to use bsearch */ qsort(aah,nah,(size_t)sizeof(**ah),compaddh); /* if (debug) dump_h_db(hfn,nah,aah); */ *nahptr = nah; *ah = aah; }
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],*ptr,line[STRLEN],header[STRLEN]; int i,nrtp,maxrtp,bt,nparam; int dum1,dum2,dum3; t_restp *rrtp; gmx_bool bNextResidue,bError; int bts[ebtsNR]; gmx_bool bAlldih; int nrexcl; gmx_bool HH14; gmx_bool bRemoveDih; 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"); } /* these bonded parameters will overwritten be when * * there is a [ bondedtypes ] entry in the .rtp file */ bts[ebtsBONDS] = 1; /* normal bonds */ bts[ebtsANGLES] = 1; /* normal angles */ bts[ebtsPDIHS] = 1; /* normal dihedrals */ bts[ebtsIDIHS] = 2; /* normal impropers */ bts[ebtsEXCLS] = 1; /* normal exclusions */ bts[ebtsCMAP] = 1; /* normal cmap torsions */ bAlldih = FALSE; nrexcl = 3; HH14 = TRUE; bRemoveDih = TRUE; /* Column 5 & 6 aren't really bonded types, but we include * them here to avoid introducing a new section: * Column 5: 1 means generate all dihedrals, 0 not. * Column 6: Number of bonded neighbors to exclude. * Coulmn 7: Generate 1,4 interactions between pairs of hydrogens * Column 8: Remove impropers over the same bond as a proper 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", &bts[ebtsBONDS],&bts[ebtsANGLES], &bts[ebtsPDIHS],&bts[ebtsIDIHS], &dum1,&nrexcl,&dum2,&dum3)) < 4 ) { gmx_fatal(FARGS,"need at least 4 (up to 8) parameters in .rtp file at line:\n%s\n",line); } bAlldih = (dum1 != 0); HH14 = (dum2 != 0); bRemoveDih = (dum3 != 0); get_a_line(in,line,STRLEN); if(nparam<5) { fprintf(stderr,"Using default: not generating all possible dihedrals\n"); bAlldih = FALSE; } if(nparam<6) { fprintf(stderr,"Using default: excluding 3 bonded neighbors\n"); nrexcl = 3; } if(nparam<7) { fprintf(stderr,"Using default: generating 1,4 H--H interactions\n"); HH14 = TRUE; } if(nparam<8) { fprintf(stderr,"Using default: removing impropers on same bond as a proper\n"); bRemoveDih = TRUE; } } else { fprintf(stderr, "Reading .rtp file without '[ bondedtypes ]' directive,\n" "Will proceed as if the entry\n" "\n" "\n[ bondedtypes ]" "\n; bonds angles dihedrals impropers all_dihedrals nr_exclusions HH14 remove_dih" "\n %3d %3d %3d %3d %3d %3d %3d %3d" "\n" "was present at the beginning of %s", bts[0],bts[1],bts[2],bts[3], bAlldih ? 1 : 0,nrexcl,HH14,bRemoveDih,rrdb); } /* 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); } clear_t_restp(&rrtp[nrtp]); if (!get_header(line,header)) gmx_fatal(FARGS,"in .rtp file at line:\n%s\n",line); rrtp[nrtp].resname = strdup(header); rrtp[nrtp].filebase = strdup(filebase); /* Set the bonded types */ rrtp[nrtp].bAlldih = bAlldih; rrtp[nrtp].nrexcl = nrexcl; rrtp[nrtp].HH14 = HH14; rrtp[nrtp].bRemoveDih = bRemoveDih; for(i=0; i<ebtsNR; i++) { rrtp[nrtp].rb[i].type = bts[i]; } 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); } 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); } } } 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; }
void choose_watermodel(const char *wmsel,const char *ffdir, char **watermodel) { const char *fn_watermodels="watermodels.dat"; char fn_list[STRLEN]; FILE *fp; char buf[STRLEN]; int nwm,sel,i; char **model; char *pret; if (strcmp(wmsel,"none") == 0) { *watermodel = NULL; return; } else if (strcmp(wmsel,"select") != 0) { *watermodel = strdup(wmsel); return; } sprintf(fn_list,"%s%c%s",ffdir,DIR_SEPARATOR,fn_watermodels); if (!fflib_fexist(fn_list)) { fprintf(stderr,"No file '%s' found, will not include a water model\n", fn_watermodels); *watermodel = NULL; return; } fp = fflib_open(fn_list); printf("\nSelect the Water Model:\n"); nwm = 0; model = NULL; while (get_a_line(fp,buf,STRLEN)) { srenew(model,nwm+1); snew(model[nwm],STRLEN); sscanf(buf,"%s%n",model[nwm],&i); if (i > 0) { ltrim(buf+i); fprintf(stderr,"%2d: %s\n",nwm+1,buf+i); nwm++; } else { sfree(model[nwm]); } } fclose(fp); fprintf(stderr,"%2d: %s\n",nwm+1,"None"); do { pret = fgets(buf,STRLEN,stdin); if (pret != NULL) { sscanf(buf,"%d",&sel); sel--; } } while (pret == NULL || sel < 0 || sel > nwm); if (sel == nwm) { *watermodel = NULL; } else { *watermodel = strdup(model[sel]); } for(i=0; i<nwm; i++) { sfree(model[i]); } sfree(model); }
static void read_ter_db_file(const char *fn, int *ntbptr, t_hackblock **tbptr, gpp_atomtype_t atype) { char filebase[STRLEN], *ptr; FILE *in; char header[STRLEN], buf[STRLEN], line[STRLEN]; t_hackblock *tb; int i, j, n, ni, kwnr, nb, maxnb, nh; fflib_filename_base(fn, filebase, STRLEN); /* Remove the C/N termini extension */ ptr = strrchr(filebase, '.'); if (ptr != nullptr) { ptr[0] = '\0'; } in = fflib_open(fn); tb = *tbptr; nb = *ntbptr - 1; maxnb = 0; kwnr = NOTSET; get_a_line(in, line, STRLEN); while (!feof(in)) { if (get_header(line, header)) { /* this is a new block, or a new keyword */ kwnr = find_kw(header); if (kwnr == NOTSET) { nb++; /* here starts a new block */ if (nb >= maxnb) { maxnb = nb + 100; srenew(tb, maxnb); } clear_t_hackblock(&tb[nb]); tb[nb].name = gmx_strdup(header); tb[nb].filebase = gmx_strdup(filebase); } } else { if (nb < 0) { gmx_fatal(FARGS, "reading termini database: " "directive expected before line:\n%s\n" "This might be a file in an old format.", line); } /* this is not a header, so it must be data */ if (kwnr >= ebtsNR) { /* this is a hack: add/rename/delete atoms */ /* make space for hacks */ if (tb[nb].nhack >= tb[nb].maxhack) { tb[nb].maxhack += 10; srenew(tb[nb].hack, tb[nb].maxhack); } nh = tb[nb].nhack; clear_t_hack(&(tb[nb].hack[nh])); for (i = 0; i < 4; i++) { tb[nb].hack[nh].a[i] = nullptr; } tb[nb].nhack++; /* get data */ n = 0; if (kwnr == ekwRepl || kwnr == ekwDel) { if (sscanf(line, "%s%n", buf, &n) != 1) { gmx_fatal(FARGS, "Reading Termini Database '%s': " "expected atom name on line\n%s", fn, line); } tb[nb].hack[nh].oname = gmx_strdup(buf); /* we only replace or delete one atom at a time */ tb[nb].hack[nh].nr = 1; } else if (kwnr == ekwAdd) { read_ab(line, fn, &(tb[nb].hack[nh])); get_a_line(in, line, STRLEN); } else { gmx_fatal(FARGS, "unimplemented keyword number %d (%s:%d)", kwnr, __FILE__, __LINE__); } if (kwnr == ekwRepl || kwnr == ekwAdd) { snew(tb[nb].hack[nh].atom, 1); read_atom(line+n, kwnr == ekwAdd, &tb[nb].hack[nh].nname, tb[nb].hack[nh].atom, atype, &tb[nb].hack[nh].cgnr); if (tb[nb].hack[nh].nname == nullptr) { if (tb[nb].hack[nh].oname != nullptr) { tb[nb].hack[nh].nname = gmx_strdup(tb[nb].hack[nh].oname); } else { gmx_fatal(FARGS, "Reading Termini Database '%s': don't know which name the new atom should have on line\n%s", fn, line); } } } } else if (kwnr >= 0 && kwnr < ebtsNR) { /* this is bonded data: bonds, angles, dihedrals or impropers */ srenew(tb[nb].rb[kwnr].b, tb[nb].rb[kwnr].nb+1); n = 0; for (j = 0; j < btsNiatoms[kwnr]; j++) { if (sscanf(line+n, "%s%n", buf, &ni) == 1) { tb[nb].rb[kwnr].b[tb[nb].rb[kwnr].nb].a[j] = gmx_strdup(buf); } else { gmx_fatal(FARGS, "Reading Termini Database '%s': expected %d atom names (found %d) on line\n%s", fn, btsNiatoms[kwnr], j-1, line); } n += ni; } for (; j < MAXATOMLIST; j++) { tb[nb].rb[kwnr].b[tb[nb].rb[kwnr].nb].a[j] = nullptr; } strcpy(buf, ""); sscanf(line+n, "%s", buf); tb[nb].rb[kwnr].b[tb[nb].rb[kwnr].nb].s = gmx_strdup(buf); tb[nb].rb[kwnr].nb++; } else { gmx_fatal(FARGS, "Reading Termini Database: Expecting a header at line\n" "%s", line); } } get_a_line(in, line, STRLEN); } nb++; srenew(tb, nb); gmx_ffclose(in); *ntbptr = nb; *tbptr = tb; }