t_topology gmx_mtop_t_to_t_topology(gmx_mtop_t *mtop) { int mt,mb; gmx_localtop_t ltop; t_topology top; gen_local_top(mtop,NULL,<op); open_symtab(&top.symtab); top.name = mtop->name; top.idef = ltop.idef; top.atomtypes = ltop.atomtypes; top.cgs = ltop.cgs; top.excls = ltop.excls; top.atoms = gmx_mtop_global_atoms(mtop); top.mols = mtop->mols; /* We only need to free the moltype and molblock data, * all other pointers have been copied to top. */ for(mt=0; mt<mtop->nmoltype; mt++) { done_moltype(&mtop->moltype[mt]); } sfree(mtop->moltype); for(mb=0; mb<mtop->nmolblock; mb++) { done_molblock(&mtop->molblock[mb]); } sfree(mtop->molblock); return top; }
gmx_bool gro_next_x_or_v(FILE *status, t_trxframe *fr) { t_atoms atoms; t_symtab symtab; char title[STRLEN], *p; double tt; int ndec = 0, i; if (gmx_one_before_eof(status)) { return FALSE; } open_symtab(&symtab); atoms.nr = fr->natoms; snew(atoms.atom, fr->natoms); atoms.nres = fr->natoms; snew(atoms.resinfo, fr->natoms); snew(atoms.atomname, fr->natoms); fr->bV = get_w_conf(status, title, title, &symtab, &atoms, &ndec, fr->x, fr->v, fr->box); fr->bPrec = TRUE; fr->prec = 1; /* prec = 10^ndec: */ for (i = 0; i < ndec; i++) { fr->prec *= 10; } fr->title = title; fr->bTitle = TRUE; fr->bX = TRUE; fr->bBox = TRUE; sfree(atoms.atom); sfree(atoms.resinfo); sfree(atoms.atomname); done_symtab(&symtab); if ((p = strstr(title, "t=")) != NULL) { p += 2; if (sscanf(p, "%lf", &tt) == 1) { fr->time = tt; fr->bTime = TRUE; } else { fr->time = 0; fr->bTime = FALSE; } } if (atoms.nr != fr->natoms) { gmx_fatal(FARGS, "Number of atoms in gro frame (%d) doesn't match the number in the previous frame (%d)", atoms.nr, fr->natoms); } return TRUE; }
// TODO this will go away when we use a // std::list<std::vector<std::string>>> for t_symtab. t_symtab *duplicateSymtab(const t_symtab *symtab) { t_symtab *copySymtab; snew(copySymtab, 1); open_symtab(copySymtab); t_symbuf *symbuf = symtab->symbuf; if (symbuf != nullptr) { snew(copySymtab->symbuf, 1); } t_symbuf *copySymbuf = copySymtab->symbuf; while (symbuf != nullptr) { snew(copySymbuf->buf, symbuf->bufsize); copySymbuf->bufsize = symbuf->bufsize; for (int i = 0; (i < symbuf->bufsize) && (i < symtab->nr); i++) { if (symbuf->buf[i]) { copySymbuf->buf[i] = gmx_strdup(symbuf->buf[i]); } } symbuf = symbuf->next; if (symbuf != nullptr) { snew(copySymbuf->next, 1); copySymbuf = copySymbuf->next; } } copySymtab->nr = symtab->nr; return copySymtab; }
void print_bondeds(FILE *out, int natoms, directive d, int ftype, int fsubtype, t_params plist[]) { t_symtab stab; gpp_atomtype_t atype; t_param *param; t_atom *a; int i; atype = init_atomtype(); snew(a, 1); snew(param, 1); open_symtab(&stab); for (i = 0; (i < natoms); i++) { char buf[12]; sprintf(buf, "%4d", (i+1)); add_atomtype(atype, &stab, a, buf, param, 0, 0, 0, 0, 0, 0, 0); } print_bt(out, d, atype, ftype, fsubtype, plist, TRUE); done_symtab(&stab); sfree(a); sfree(param); done_atomtype(atype); }
static gmx_bool pdb_next_x(t_trxstatus *status, FILE *fp, t_trxframe *fr) { t_atoms atoms; t_symtab *symtab; matrix boxpdb; // Initiate model_nr to -1 rather than NOTSET. // It is not worthwhile introducing extra variables in the // read_pdbfile call to verify that a model_nr was read. int ePBC, model_nr = -1, na; char title[STRLEN], *time, *step; double dbl; atoms.nr = fr->natoms; atoms.atom = nullptr; atoms.pdbinfo = nullptr; /* the other pointers in atoms should not be accessed if these are NULL */ snew(symtab, 1); open_symtab(symtab); na = read_pdbfile(fp, title, &model_nr, &atoms, symtab, fr->x, &ePBC, boxpdb, TRUE, nullptr); free_symtab(symtab); sfree(symtab); set_trxframe_ePBC(fr, ePBC); if (nframes_read(status) == 0) { fprintf(stderr, " '%s', %d atoms\n", title, fr->natoms); } fr->bPrec = TRUE; fr->prec = 10000; fr->bX = TRUE; fr->bBox = (boxpdb[XX][XX] != 0.0); if (fr->bBox) { copy_mat(boxpdb, fr->box); } fr->step = 0; step = std::strstr(title, " step= "); fr->bStep = ((step != nullptr) && sscanf(step+7, "%" SCNd64, &fr->step) == 1); dbl = 0.0; time = std::strstr(title, " t= "); fr->bTime = ((time != nullptr) && sscanf(time+4, "%lf", &dbl) == 1); fr->time = dbl; if (na == 0) { return FALSE; } else { if (na != fr->natoms) { gmx_fatal(FARGS, "Number of atoms in pdb frame %d is %d instead of %d", nframes_read(status), na, fr->natoms); } return TRUE; } }
void init_top(t_topology *top) { top->name = NULL; init_atom(&(top->atoms)); init_atomtypes(&(top->atomtypes)); init_block(&top->cgs); init_block(&top->mols); init_blocka(&top->excls); open_symtab(&top->symtab); }
void init_mtop(gmx_mtop_t *mtop) { mtop->name = NULL; mtop->nmoltype = 0; mtop->moltype = NULL; mtop->nmolblock = 0; mtop->molblock = NULL; init_groups(&mtop->groups); init_block(&mtop->mols); open_symtab(&mtop->symtab); }
static void read_whole_conf(const char *infile, char *title, t_atoms *atoms, rvec x[], rvec *v, matrix box) { FILE *in; int ndec; t_symtab symtab; /* open file */ in = gmx_fio_fopen(infile, "r"); open_symtab(&symtab); get_w_conf(in, infile, title, &symtab, atoms, &ndec, x, v, box); /* We can't free the symbols, as they are still used in atoms, so * the only choice is to leak them. */ free_symtab(&symtab); gmx_fio_fclose(in); }
int protonate(t_atoms **atomsptr, rvec **xptr, t_protonate *protdata) { #define NTERPAIRS 1 t_atoms *atoms; gmx_bool bUpdate_pdba, bKeep_old_pdba; int nntdb, nctdb, nt, ct; int nadd; atoms = NULL; if (!protdata->bInit) { if (debug) { fprintf(debug, "protonate: Initializing protdata\n"); } /* set forcefield to use: */ strcpy(protdata->FF, "oplsaa.ff"); /* get the databases: */ protdata->nah = read_h_db(protdata->FF, &protdata->ah); open_symtab(&protdata->tab); protdata->atype = read_atype(protdata->FF, &protdata->tab); nntdb = read_ter_db(protdata->FF, 'n', &protdata->ntdb, protdata->atype); if (nntdb < 1) { gmx_fatal(FARGS, "no N-terminus database"); } nctdb = read_ter_db(protdata->FF, 'c', &protdata->ctdb, protdata->atype); if (nctdb < 1) { gmx_fatal(FARGS, "no C-terminus database"); } /* set terminus types: -NH3+ (different for Proline) and -COO- */ atoms = *atomsptr; snew(protdata->sel_ntdb, NTERPAIRS); snew(protdata->sel_ctdb, NTERPAIRS); if (nntdb >= 4 && nctdb >= 2) { /* Yuk, yuk, hardcoded default termini selections !!! */ if (strncmp(*atoms->resinfo[atoms->atom[atoms->nr-1].resind].name, "PRO", 3) == 0) { nt = 3; } else { nt = 1; } ct = 1; } else { nt = 0; ct = 0; } protdata->sel_ntdb[0] = &(protdata->ntdb[nt]); protdata->sel_ctdb[0] = &(protdata->ctdb[ct]); /* set terminal residue numbers: */ snew(protdata->rN, NTERPAIRS); snew(protdata->rC, NTERPAIRS); protdata->rN[0] = 0; protdata->rC[0] = atoms->atom[atoms->nr-1].resind; /* keep unprotonated topology: */ protdata->upatoms = atoms; /* we don't have these yet: */ protdata->patoms = NULL; bUpdate_pdba = TRUE; bKeep_old_pdba = TRUE; /* clear hackblocks: */ protdata->nab = NULL; protdata->ab = NULL; /* set flag to show we're initialized: */ protdata->bInit = TRUE; } else { if (debug) { fprintf(debug, "protonate: using available protdata\n"); } /* add_h will need the unprotonated topology again: */ atoms = protdata->upatoms; bUpdate_pdba = FALSE; bKeep_old_pdba = FALSE; } /* now protonate */ nadd = add_h(&atoms, xptr, protdata->nah, protdata->ah, NTERPAIRS, protdata->sel_ntdb, protdata->sel_ctdb, protdata->rN, protdata->rC, TRUE, &protdata->nab, &protdata->ab, bUpdate_pdba, bKeep_old_pdba); if (!protdata->patoms) { /* store protonated topology */ protdata->patoms = atoms; } *atomsptr = protdata->patoms; if (debug) { fprintf(debug, "natoms: %d -> %d (nadd=%d)\n", protdata->upatoms->nr, protdata->patoms->nr, nadd); } return nadd; #undef NTERPAIRS }
int read_first_frame(const gmx_output_env_t *oenv, t_trxstatus **status, const char *fn, t_trxframe *fr, int flags) { t_fileio *fio; gmx_bool bFirst, bOK; int ftp = fn2ftp(fn); clear_trxframe(fr, TRUE); fr->flags = flags; bFirst = TRUE; snew((*status), 1); status_init( *status ); (*status)->nxframe = 1; initcount(*status); if (efTNG == ftp) { /* Special treatment for TNG files */ gmx_tng_open(fn, 'r', &(*status)->tng); } else { fio = (*status)->fio = gmx_fio_open(fn, "r"); } switch (ftp) { case efTRR: break; case efCPT: read_checkpoint_trxframe(fio, fr); bFirst = FALSE; break; case efG96: { /* Can not rewind a compressed file, so open it twice */ if (!(*status)->persistent_line) { /* allocate the persistent line */ snew((*status)->persistent_line, STRLEN+1); } t_symtab *symtab; snew(symtab, 1); open_symtab(symtab); read_g96_conf(gmx_fio_getfp(fio), fn, fr, symtab, (*status)->persistent_line); free_symtab(symtab); gmx_fio_close(fio); clear_trxframe(fr, FALSE); if (flags & (TRX_READ_X | TRX_NEED_X)) { snew(fr->x, fr->natoms); } if (flags & (TRX_READ_V | TRX_NEED_V)) { snew(fr->v, fr->natoms); } (*status)->fio = gmx_fio_open(fn, "r"); break; } case efXTC: if (read_first_xtc(fio, &fr->natoms, &fr->step, &fr->time, fr->box, &fr->x, &fr->prec, &bOK) == 0) { GMX_RELEASE_ASSERT(!bOK, "Inconsistent results - OK status from read_first_xtc, but 0 atom coords read"); fr->not_ok = DATA_NOT_OK; } if (fr->not_ok) { fr->natoms = 0; printincomp(*status, fr); } else { fr->bPrec = (fr->prec > 0); fr->bStep = TRUE; fr->bTime = TRUE; fr->bX = TRUE; fr->bBox = TRUE; printcount(*status, oenv, fr->time, FALSE); } bFirst = FALSE; break; case efTNG: fr->step = -1; if (!gmx_read_next_tng_frame((*status)->tng, fr, NULL, 0)) { fr->not_ok = DATA_NOT_OK; fr->natoms = 0; printincomp(*status, fr); } else { printcount(*status, oenv, fr->time, FALSE); } bFirst = FALSE; break; case efPDB: pdb_first_x(*status, gmx_fio_getfp(fio), fr); if (fr->natoms) { printcount(*status, oenv, fr->time, FALSE); } bFirst = FALSE; break; case efGRO: if (gro_first_x_or_v(gmx_fio_getfp(fio), fr)) { printcount(*status, oenv, fr->time, FALSE); } bFirst = FALSE; break; default: #ifdef GMX_USE_PLUGINS fprintf(stderr, "The file format of %s is not a known trajectory format to GROMACS.\n" "Please make sure that the file is a trajectory!\n" "GROMACS will now assume it to be a trajectory and will try to open it using the VMD plug-ins.\n" "This will only work in case the VMD plugins are found and it is a trajectory format supported by VMD.\n", fn); gmx_fio_fp_close(fio); /*only close the file without removing FIO entry*/ if (!read_first_vmd_frame(fn, fr)) { gmx_fatal(FARGS, "Not supported in read_first_frame: %s", fn); } #else gmx_fatal(FARGS, "Not supported in read_first_frame: %s. Please make sure that the file is a trajectory.\n" "GROMACS is not compiled with plug-in support. Thus it cannot read non-GROMACS trajectory formats using the VMD plug-ins.\n" "Please compile with plug-in support if you want to read non-GROMACS trajectory formats.\n", fn); #endif break; } fr->tf = fr->time; /* Return FALSE if we read a frame that's past the set ending time. */ if (!bFirst && (!(fr->flags & TRX_DONT_SKIP) && check_times(fr->time) > 0)) { fr->t0 = fr->time; return FALSE; } if (bFirst || (!(fr->flags & TRX_DONT_SKIP) && check_times(fr->time) < 0)) { /* Read a frame when no frame was read or the first was skipped */ if (!read_next_frame(oenv, *status, fr)) { return FALSE; } } fr->t0 = fr->time; /* We need the number of atoms for random-access XTC searching, even when * we don't have access to the actual frame data. */ (*status)->natoms = fr->natoms; return (fr->natoms > 0); }
gmx_bool read_next_frame(const gmx_output_env_t *oenv, t_trxstatus *status, t_trxframe *fr) { real pt; int ct; gmx_bool bOK, bRet, bMissingData = FALSE, bSkip = FALSE; int ftp; bRet = FALSE; pt = fr->tf; do { clear_trxframe(fr, FALSE); fr->tppf = fr->tpf; fr->tpf = fr->tf; if (status->tng) { /* Special treatment for TNG files */ ftp = efTNG; } else { ftp = gmx_fio_getftp(status->fio); } switch (ftp) { case efTRR: bRet = gmx_next_frame(status, fr); break; case efCPT: /* Checkpoint files can not contain mulitple frames */ break; case efG96: { t_symtab *symtab; snew(symtab, 1); open_symtab(symtab); read_g96_conf(gmx_fio_getfp(status->fio), NULL, fr, symtab, status->persistent_line); free_symtab(symtab); bRet = (fr->natoms > 0); break; } case efXTC: /* B. Hess 2005-4-20 * Sometimes is off by one frame * and sometimes reports frame not present/file not seekable */ /* DvdS 2005-05-31: this has been fixed along with the increased * accuracy of the control over -b and -e options. */ if (bTimeSet(TBEGIN) && (fr->tf < rTimeValue(TBEGIN))) { if (xtc_seek_time(status->fio, rTimeValue(TBEGIN), fr->natoms, TRUE)) { gmx_fatal(FARGS, "Specified frame (time %f) doesn't exist or file corrupt/inconsistent.", rTimeValue(TBEGIN)); } initcount(status); } bRet = read_next_xtc(status->fio, fr->natoms, &fr->step, &fr->time, fr->box, fr->x, &fr->prec, &bOK); fr->bPrec = (bRet && fr->prec > 0); fr->bStep = bRet; fr->bTime = bRet; fr->bX = bRet; fr->bBox = bRet; if (!bOK) { /* Actually the header could also be not ok, but from bOK from read_next_xtc this can't be distinguished */ fr->not_ok = DATA_NOT_OK; } break; case efTNG: bRet = gmx_read_next_tng_frame(status->tng, fr, NULL, 0); break; case efPDB: bRet = pdb_next_x(status, gmx_fio_getfp(status->fio), fr); break; case efGRO: bRet = gro_next_x_or_v(gmx_fio_getfp(status->fio), fr); break; default: #ifdef GMX_USE_PLUGINS bRet = read_next_vmd_frame(fr); #else gmx_fatal(FARGS, "DEATH HORROR in read_next_frame ftp=%s,status=%s", ftp2ext(gmx_fio_getftp(status->fio)), gmx_fio_getname(status->fio)); #endif } fr->tf = fr->time; if (bRet) { bMissingData = (((fr->flags & TRX_NEED_X) && !fr->bX) || ((fr->flags & TRX_NEED_V) && !fr->bV) || ((fr->flags & TRX_NEED_F) && !fr->bF)); bSkip = FALSE; if (!bMissingData) { ct = check_times2(fr->time, fr->t0, fr->bDouble); if (ct == 0 || ((fr->flags & TRX_DONT_SKIP) && ct < 0)) { printcount(status, oenv, fr->time, FALSE); } else if (ct > 0) { bRet = FALSE; } else { printcount(status, oenv, fr->time, TRUE); bSkip = TRUE; } } } } while (bRet && (bMissingData || bSkip)); if (!bRet) { printlast(status, oenv, pt); if (fr->not_ok) { printincomp(status, fr); } } return bRet; }
static gmx_bool pdb_next_x(t_trxstatus *status, FILE *fp, t_trxframe *fr) { t_atoms atoms; t_symtab *symtab; matrix boxpdb; // Initiate model_nr to -1 rather than NOTSET. // It is not worthwhile introducing extra variables in the // read_pdbfile call to verify that a model_nr was read. int ePBC, model_nr = -1, na; char title[STRLEN], *time; double dbl; atoms.nr = fr->natoms; atoms.atom = NULL; atoms.pdbinfo = NULL; /* the other pointers in atoms should not be accessed if these are NULL */ snew(symtab, 1); open_symtab(symtab); na = read_pdbfile(fp, title, &model_nr, &atoms, symtab, fr->x, &ePBC, boxpdb, TRUE, NULL); free_symtab(symtab); sfree(symtab); set_trxframe_ePBC(fr, ePBC); if (nframes_read(status) == 0) { fprintf(stderr, " '%s', %d atoms\n", title, fr->natoms); } fr->bPrec = TRUE; fr->prec = 10000; fr->bX = TRUE; fr->bBox = (boxpdb[XX][XX] != 0.0); if (fr->bBox) { copy_mat(boxpdb, fr->box); } if (model_nr != -1) { fr->bStep = TRUE; fr->step = model_nr; } time = std::strstr(title, " t= "); if (time) { fr->bTime = TRUE; sscanf(time+4, "%lf", &dbl); fr->time = (real)dbl; } else { fr->bTime = FALSE; /* this is a bit dirty, but it will work: if no time is read from comment line in pdb file, set time to current frame number */ if (fr->bStep) { fr->time = (real)fr->step; } else { fr->time = (real)nframes_read(status); } } if (na == 0) { return FALSE; } else { if (na != fr->natoms) { gmx_fatal(FARGS, "Number of atoms in pdb frame %d is %d instead of %d", nframes_read(status), na, fr->natoms); } return TRUE; } }
int read_g96_conf(FILE *fp, const char *infile, t_trxframe *fr, char *line) { t_symtab *symtab = NULL; gmx_bool bAtStart, bTime, bAtoms, bPos, bVel, bBox, bEnd, bFinished; int natoms, nbp; double db1, db2, db3, db4, db5, db6, db7, db8, db9; bAtStart = (ftell(fp) == 0); clear_trxframe(fr, FALSE); if (!symtab) { snew(symtab, 1); open_symtab(symtab); } natoms = 0; if (bAtStart) { while (!fr->bTitle && fgets2(line, STRLEN, fp)) { fr->bTitle = (strcmp(line, "TITLE") == 0); } if (fr->title == NULL) { fgets2(line, STRLEN, fp); fr->title = gmx_strdup(line); } bEnd = FALSE; while (!bEnd && fgets2(line, STRLEN, fp)) { bEnd = (strcmp(line, "END") == 0); } fgets2(line, STRLEN, fp); } /* Do not get a line if we are not at the start of the file, * * because without a parameter file we don't know what is in * * the trajectory and we have already read the line in the * * previous call (VERY DIRTY). */ bFinished = FALSE; do { bTime = (strcmp(line, "TIMESTEP") == 0); bAtoms = (strcmp(line, "POSITION") == 0); bPos = (bAtoms || (strcmp(line, "POSITIONRED") == 0)); bVel = (strncmp(line, "VELOCITY", 8) == 0); bBox = (strcmp(line, "BOX") == 0); if (bTime) { if (!fr->bTime && !fr->bX) { fr->bStep = bTime; fr->bTime = bTime; do { bFinished = (fgets2(line, STRLEN, fp) == NULL); } while (!bFinished && (line[0] == '#')); sscanf(line, "%15d%15lf", &(fr->step), &db1); fr->time = db1; } else { bFinished = TRUE; } } if (bPos) { if (!fr->bX) { fr->bAtoms = bAtoms; fr->bX = bPos; natoms = read_g96_pos(line, symtab, fp, infile, fr); } else { bFinished = TRUE; } } if (fr->v && bVel) { fr->bV = bVel; natoms = read_g96_vel(line, fp, infile, fr); } if (bBox) { fr->bBox = bBox; clear_mat(fr->box); bEnd = FALSE; while (!bEnd && fgets2(line, STRLEN, fp)) { bEnd = (strncmp(line, "END", 3) == 0); if (!bEnd && (line[0] != '#')) { nbp = sscanf(line, "%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf", &db1, &db2, &db3, &db4, &db5, &db6, &db7, &db8, &db9); if (nbp < 3) { gmx_fatal(FARGS, "Found a BOX line, but no box in %s", infile); } fr->box[XX][XX] = db1; fr->box[YY][YY] = db2; fr->box[ZZ][ZZ] = db3; if (nbp == 9) { fr->box[XX][YY] = db4; fr->box[XX][ZZ] = db5; fr->box[YY][XX] = db6; fr->box[YY][ZZ] = db7; fr->box[ZZ][XX] = db8; fr->box[ZZ][YY] = db9; } } } bFinished = TRUE; } } while (!bFinished && fgets2(line, STRLEN, fp)); free_symtab(symtab); fr->natoms = natoms; return natoms; }
int main(int argc,char *argv[]) { static char *desc[] = { "[TT]mkice[tt] generates an ice crystal in the Ih crystal form which is the", "most stable form. The rectangular unitcell contains eight molecules", "and all oxygens are tetrahedrally coordinated.[PAR]", "If an input file is given it is interpreted as a series of oxygen", "coordinates the distance between which can be scaled by the odist flag.", "The program then adds hydrogens to the oxygens in random orientation", "but with proper OH distances and HOH angle. This feature allows to", "build water clusters based on oxygen coordinates only." }; static int nx=1,ny=1,nz=1; static gmx_bool bYaw=FALSE,bLJ=TRUE,bFull=TRUE,bSeries=FALSE; static gmx_bool bOrdered=TRUE,bDiamond=FALSE,bPBC=TRUE; static real rcut=0.3,odist=0.274,hdist=0.09572; t_pargs pa[] = { { "-nx", FALSE, etINT, {&nx}, "nx" }, { "-ny", FALSE, etINT, {&ny}, "ny" }, { "-nz", FALSE, etINT, {&nz}, "nz" }, { "-yaw", FALSE, etBOOL, {&bYaw}, "Generate virtual sites and shell positions" }, { "-lj", FALSE, etBOOL, {&bLJ}, "Use LJ as well as coulomb for virial calculation" }, { "-rcut", FALSE,etREAL, {&rcut},"Cut-off for virial calculations" }, { "-full", FALSE,etBOOL, {&bFull},"Full virial output" }, { "-odist", FALSE, etREAL, {&odist}, "Distance (nm) between oxygens" }, { "-hdist", FALSE, etREAL, {&hdist}, "Bondlength (nm) for OH bond" }, { "-diamond",FALSE,etBOOL, {&bDiamond}, "Make a diamond instead" }, { "-pbc", FALSE, etBOOL, {&bPBC}, "Make a periodic diamond" }, { "-order", FALSE,etBOOL, {&bOrdered}, "Make a proton-ordered ice lattice" }, { "-series",FALSE, etBOOL, {&bSeries}, "Do a series of virial calculations with different cut-off (from 0.3 up till the specified one)" } }; t_filenm fnm[] = { { efSTO, "-p", "ice", ffWRITE }, { efSTO, "-c", NULL, ffOPTRD }, { efDAT, "-f", NULL, ffOPTRD }, { efTRN, "-o", "ice", ffOPTWR } }; #define NFILE asize(fnm) FILE *fp; char *fn,quote[256]; int i,j,k,n,nmax,m,natom,natmol; t_atoms *pdba; t_atoms atoms; t_symtab symtab; rvec box,tmp,*xx; matrix boxje; CopyRight(stdout,argv[0]); parse_common_args(&argc,argv,0,NFILE,fnm,asize(pa),pa,asize(desc), desc,0,NULL); if (debug) { fprintf(debug,"nx = %3d, ny = %3d, nz = %3d\n",nx,ny,nz); fprintf(debug,"YAW = %3s, LJ = %3s, rcut = %g\n",yesno_names[bYaw], yesno_names[bLJ],rcut); } if (bYaw) natmol = 5; else if (bDiamond) natmol = 1; else natmol = 3; if (opt2bSet("-f",NFILE,fnm)) { natom = read_rel_coords(opt2fn("-f",NFILE,fnm),&xx,natmol); nmax = natom; } else { natom = natmol*8; nmax = natom*nx*ny*nz; snew(xx,nmax); } snew(pdba,1); init_t_atoms(pdba,nmax,TRUE); pdba->nr = nmax; open_symtab(&symtab); for(n=0; (n<nmax); n++) { pdba->pdbinfo[n].type = epdbATOM; pdba->pdbinfo[n].atomnr = 1+n; pdba->atom[n].resnr = 1+(n/natmol); pdba->atomname[n] = put_symtab(&symtab, bDiamond ? diamname[(n % natmol)] : watname[(n % natmol)]); if (bDiamond) pdba->resname[n] = put_symtab(&symtab,"DIA"); else pdba->resname[n] = put_symtab(&symtab,"SOL"); sprintf(pdba->pdbinfo[n].pdbresnr,"%d",n); pdba->atom[n].chain = ' '; } /* Generate the unit cell */ if (bDiamond) unitcell_d(xx,box,odist); else if (opt2bSet("-f",NFILE,fnm)) { random_h_coords(natmol,natom/natmol,xx,box,bYaw,odist,hdist); } else unitcell(xx,box,bYaw,odist,hdist); if (debug) { clear_mat(boxje); boxje[XX][XX] = box[XX]; boxje[YY][YY] = box[YY]; boxje[ZZ][ZZ] = box[ZZ]; } n=0; for(i=0; (i<nx); i++) { tmp[XX] = i*box[XX]; for(j=0; (j<ny); j++) { tmp[YY] = j*box[YY]; for(k=0; (k<nz); k++) { tmp[ZZ] = k*box[ZZ]; for(m=0; (m<natom); m++,n++) { if ((!bOrdered && ((m % natmol) == 0)) || bOrdered) rvec_add(xx[n % natom],tmp,xx[n]); else ; } } } } clear_mat(boxje); boxje[XX][XX] = box[XX]*nx; boxje[YY][YY] = box[YY]*ny; boxje[ZZ][ZZ] = box[ZZ]*nz; printf("Crystal: %10.5f %10.5f %10.5f\n", nx*box[XX],ny*box[YY],nz*box[ZZ]); if (debug && !bDiamond) { if (bSeries) for(i=3; (i<=10*rcut); i++) { fprintf(debug,"This is with rcut = %g\n",i*0.1); virial(debug,bFull,nmax/natmol,xx,boxje, 0.1*i,bYaw,bYaw ? qyaw : qspc,bLJ); } else virial(debug,bFull,nmax/natmol,xx,boxje, rcut,bYaw,bYaw ? qyaw : qspc,bLJ); } if (bDiamond) mk_diamond(pdba,xx,odist,&symtab,bPBC,boxje); fn = ftp2fn(efSTO,NFILE,fnm); if (fn2ftp(fn) == efPDB) { fp = gmx_ffopen(fn,"w"); if (bDiamond) fprintf(fp,"HEADER This is a *diamond*\n"); else fprintf(fp,"HEADER A beautiful Ice Ih crystal\n"); fprintf(fp,"REMARK Generated by mkice with the following options:\n" "REMARK nx = %d, ny = %d, nz = %d, odist = %g, hdist = %g\n", nx,ny,nz,odist,hdist); bromacs(quote,255); write_pdbfile(fp,quote,pdba,xx,boxje,' ',-1); gmx_ffclose(fp); } else { bromacs(quote,255); write_sto_conf(fn,quote,pdba,xx,NULL,boxje); } if (ftp2bSet(efTRN,NFILE,fnm)) write_trn(ftp2fn(efTRN,NFILE,fnm),0,0,0,boxje,nmax,xx,NULL,NULL); return 0; }
static void read_espresso_conf(const char *infile, t_atoms *atoms, rvec x[], rvec *v, matrix box) { t_symtab *symtab = NULL; FILE *fp; char word[STRLEN], buf[STRLEN]; int natoms, level, npar, r, nprop, p, i, m, molnr; int prop[32]; double d; gmx_bool bFoundParticles, bFoundProp, bFoundVariable, bMol; if (!symtab) { snew(symtab, 1); open_symtab(symtab); } clear_mat(box); fp = gmx_fio_fopen(infile, "r"); bFoundParticles = FALSE; bFoundVariable = FALSE; bMol = FALSE; level = 0; while ((r = get_espresso_word(fp, word))) { if (level == 1 && strcmp(word, "particles") == 0 && !bFoundParticles) { bFoundParticles = TRUE; level += check_open_parenthesis(fp, r, infile, "particles"); nprop = 0; while (level == 2 && (r = get_espresso_word(fp, word))) { bFoundProp = FALSE; for (p = 0; p < espNR; p++) { if (strcmp(word, esp_prop[p]) == 0) { bFoundProp = TRUE; prop[nprop++] = p; /* printf(" prop[%d] = %s\n",nprop-1,esp_prop[prop[nprop-1]]); */ } } if (!bFoundProp && word[0] != '}') { gmx_fatal(FARGS, "Can not read Espresso files with particle property '%s'", word); } if (bFoundProp && p == espMOLECULE) { bMol = TRUE; } if (r == 3) { level--; } } i = 0; while (level > 0 && (r = get_espresso_word(fp, word))) { if (r == 2) { level++; } else if (r == 3) { level--; } if (level == 2) { for (p = 0; p < nprop; p++) { switch (prop[p]) { case espID: r = get_espresso_word(fp, word); /* Not used */ break; case espPOS: for (m = 0; m < 3; m++) { r = get_espresso_word(fp, word); sscanf(word, "%lf", &d); x[i][m] = d; } break; case espTYPE: r = get_espresso_word(fp, word); atoms->atom[i].type = strtol(word, NULL, 10); break; case espQ: r = get_espresso_word(fp, word); sscanf(word, "%lf", &d); atoms->atom[i].q = d; break; case espV: for (m = 0; m < 3; m++) { r = get_espresso_word(fp, word); sscanf(word, "%lf", &d); v[i][m] = d; } break; case espF: for (m = 0; m < 3; m++) { r = get_espresso_word(fp, word); /* not used */ } break; case espMOLECULE: r = get_espresso_word(fp, word); molnr = strtol(word, NULL, 10); if (i == 0 || atoms->resinfo[atoms->atom[i-1].resind].nr != molnr) { atoms->atom[i].resind = (i == 0 ? 0 : atoms->atom[i-1].resind+1); atoms->resinfo[atoms->atom[i].resind].nr = molnr; atoms->resinfo[atoms->atom[i].resind].ic = ' '; atoms->resinfo[atoms->atom[i].resind].chainid = ' '; atoms->resinfo[atoms->atom[i].resind].chainnum = molnr; /* Not sure if this is right? */ } else { atoms->atom[i].resind = atoms->atom[i-1].resind; } break; } } /* Generate an atom name from the particle type */ sprintf(buf, "T%d", atoms->atom[i].type); atoms->atomname[i] = put_symtab(symtab, buf); if (bMol) { if (i == 0 || atoms->atom[i].resind != atoms->atom[i-1].resind) { atoms->resinfo[atoms->atom[i].resind].name = put_symtab(symtab, "MOL"); } } else { /* Residue number is the atom number */ atoms->atom[i].resind = i; /* Generate an residue name from the particle type */ if (atoms->atom[i].type < 26) { sprintf(buf, "T%c", 'A'+atoms->atom[i].type); } else { sprintf(buf, "T%c%c", 'A'+atoms->atom[i].type/26, 'A'+atoms->atom[i].type%26); } t_atoms_set_resinfo(atoms, i, symtab, buf, i, ' ', 0, ' '); } if (r == 3) { level--; } i++; } } atoms->nres = atoms->nr; if (i != atoms->nr) { gmx_fatal(FARGS, "Internal inconsistency in Espresso routines, read %d atoms, expected %d atoms", i, atoms->nr); } } else if (level == 1 && strcmp(word, "variable") == 0 && !bFoundVariable) { bFoundVariable = TRUE; level += check_open_parenthesis(fp, r, infile, "variable"); while (level == 2 && (r = get_espresso_word(fp, word))) { if (level == 2 && strcmp(word, "box_l") == 0) { for (m = 0; m < 3; m++) { r = get_espresso_word(fp, word); sscanf(word, "%lf", &d); box[m][m] = d; } level += check_close_parenthesis(fp, r, infile, "box_l"); } } } else if (r == 2) { level++; } else if (r == 3) { level--; } } if (!bFoundParticles) { fprintf(stderr, "Did not find a particles section in Espresso file '%s'\n", infile); } gmx_fio_fclose(fp); }
int gmx_x2top(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] generates a primitive topology from a coordinate file.", "The program assumes all hydrogens are present when defining", "the hybridization from the atom name and the number of bonds.", "The program can also make an [TT].rtp[tt] entry, which you can then add", "to the [TT].rtp[tt] database.[PAR]", "When [TT]-param[tt] is set, equilibrium distances and angles", "and force constants will be printed in the topology for all", "interactions. The equilibrium distances and angles are taken", "from the input coordinates, the force constant are set with", "command line options.", "The force fields somewhat supported currently are:[PAR]", "G53a5 GROMOS96 53a5 Forcefield (official distribution)[PAR]", "oplsaa OPLS-AA/L all-atom force field (2001 aminoacid dihedrals)[PAR]", "The corresponding data files can be found in the library directory", "with name [TT]atomname2type.n2t[tt]. Check Chapter 5 of the manual for more", "information about file formats. By default, the force field selection", "is interactive, but you can use the [TT]-ff[tt] option to specify", "one of the short names above on the command line instead. In that", "case [THISMODULE] just looks for the corresponding file.[PAR]", }; const char *bugs[] = { "The atom type selection is primitive. Virtually no chemical knowledge is used", "Periodic boundary conditions screw up the bonding", "No improper dihedrals are generated", "The atoms to atomtype translation table is incomplete ([TT]atomname2type.n2t[tt] file in the data directory). Please extend it and send the results back to the GROMACS crew." }; FILE *fp; t_params plist[F_NRE]; t_excls *excls; t_atoms *atoms; /* list with all atoms */ gpp_atomtype_t atype; t_nextnb nnb; t_nm2type *nm2t; t_mols mymol; int nnm; char title[STRLEN], forcefield[32], ffdir[STRLEN]; rvec *x; /* coordinates? */ int *nbonds, *cgnr; int bts[] = { 1, 1, 1, 2 }; matrix box; /* box length matrix */ int natoms; /* number of atoms in one molecule */ int nres; /* number of molecules? */ int i, j, k, l, m, ndih; int epbc; gmx_bool bRTP, bTOP, bOPLS; t_symtab symtab; real cutoff, qtot, mtot; char n2t[STRLEN]; output_env_t oenv; t_filenm fnm[] = { { efSTX, "-f", "conf", ffREAD }, { efTOP, "-o", "out", ffOPTWR }, { efRTP, "-r", "out", ffOPTWR } }; #define NFILE asize(fnm) static real scale = 1.1, kb = 4e5, kt = 400, kp = 5; static t_restp rtp_header_settings; static gmx_bool bRemoveDihedralIfWithImproper = FALSE; static gmx_bool bGenerateHH14Interactions = TRUE; static gmx_bool bKeepAllGeneratedDihedrals = FALSE; static int nrexcl = 3; static gmx_bool bParam = TRUE, bRound = TRUE; static gmx_bool bPairs = TRUE, bPBC = TRUE; static gmx_bool bUsePDBcharge = FALSE, bVerbose = FALSE; static const char *molnm = "ICE"; static const char *ff = "oplsaa"; t_pargs pa[] = { { "-ff", FALSE, etSTR, {&ff}, "Force field for your simulation. Type \"select\" for interactive selection." }, { "-v", FALSE, etBOOL, {&bVerbose}, "Generate verbose output in the top file." }, { "-nexcl", FALSE, etINT, {&nrexcl}, "Number of exclusions" }, { "-H14", FALSE, etBOOL, {&bGenerateHH14Interactions}, "Use 3rd neighbour interactions for hydrogen atoms" }, { "-alldih", FALSE, etBOOL, {&bKeepAllGeneratedDihedrals}, "Generate all proper dihedrals" }, { "-remdih", FALSE, etBOOL, {&bRemoveDihedralIfWithImproper}, "Remove dihedrals on the same bond as an improper" }, { "-pairs", FALSE, etBOOL, {&bPairs}, "Output 1-4 interactions (pairs) in topology file" }, { "-name", FALSE, etSTR, {&molnm}, "Name of your molecule" }, { "-pbc", FALSE, etBOOL, {&bPBC}, "Use periodic boundary conditions." }, { "-pdbq", FALSE, etBOOL, {&bUsePDBcharge}, "Use the B-factor supplied in a [TT].pdb[tt] file for the atomic charges" }, { "-param", FALSE, etBOOL, {&bParam}, "Print parameters in the output" }, { "-round", FALSE, etBOOL, {&bRound}, "Round off measured values" }, { "-kb", FALSE, etREAL, {&kb}, "Bonded force constant (kJ/mol/nm^2)" }, { "-kt", FALSE, etREAL, {&kt}, "Angle force constant (kJ/mol/rad^2)" }, { "-kp", FALSE, etREAL, {&kp}, "Dihedral angle force constant (kJ/mol/rad^2)" } }; if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv)) { return 0; } bRTP = opt2bSet("-r", NFILE, fnm); bTOP = opt2bSet("-o", NFILE, fnm); /* C89 requirements mean that these struct members cannot be used in * the declaration of pa. So some temporary variables are needed. */ rtp_header_settings.bRemoveDihedralIfWithImproper = bRemoveDihedralIfWithImproper; rtp_header_settings.bGenerateHH14Interactions = bGenerateHH14Interactions; rtp_header_settings.bKeepAllGeneratedDihedrals = bKeepAllGeneratedDihedrals; rtp_header_settings.nrexcl = nrexcl; if (!bRTP && !bTOP) { gmx_fatal(FARGS, "Specify at least one output file"); } /* Force field selection, interactive or direct */ choose_ff(strcmp(ff, "select") == 0 ? NULL : ff, forcefield, sizeof(forcefield), ffdir, sizeof(ffdir)); bOPLS = (strcmp(forcefield, "oplsaa") == 0); mymol.name = strdup(molnm); mymol.nr = 1; /* Init parameter lists */ init_plist(plist); /* Read coordinates */ get_stx_coordnum(opt2fn("-f", NFILE, fnm), &natoms); snew(atoms, 1); /* make space for all the atoms */ init_t_atoms(atoms, natoms, TRUE); snew(x, natoms); read_stx_conf(opt2fn("-f", NFILE, fnm), title, atoms, x, NULL, &epbc, box); sprintf(n2t, "%s", ffdir); nm2t = rd_nm2type(n2t, &nnm); if (nnm == 0) { gmx_fatal(FARGS, "No or incorrect atomname2type.n2t file found (looking for %s)", n2t); } else { printf("There are %d name to type translations in file %s\n", nnm, n2t); } if (debug) { dump_nm2type(debug, nnm, nm2t); } printf("Generating bonds from distances...\n"); snew(nbonds, atoms->nr); mk_bonds(nnm, nm2t, atoms, x, &(plist[F_BONDS]), nbonds, bPBC, box); open_symtab(&symtab); atype = set_atom_type(&symtab, atoms, &(plist[F_BONDS]), nbonds, nnm, nm2t); /* Make Angles and Dihedrals */ snew(excls, atoms->nr); printf("Generating angles and dihedrals from bonds...\n"); init_nnb(&nnb, atoms->nr, 4); gen_nnb(&nnb, plist); print_nnb(&nnb, "NNB"); gen_pad(&nnb, atoms, &rtp_header_settings, plist, excls, NULL, TRUE); done_nnb(&nnb); if (!bPairs) { plist[F_LJ14].nr = 0; } fprintf(stderr, "There are %4d %s dihedrals, %4d impropers, %4d angles\n" " %4d pairs, %4d bonds and %4d atoms\n", plist[F_PDIHS].nr, bOPLS ? "Ryckaert-Bellemans" : "proper", plist[F_IDIHS].nr, plist[F_ANGLES].nr, plist[F_LJ14].nr, plist[F_BONDS].nr, atoms->nr); calc_angles_dihs(&plist[F_ANGLES], &plist[F_PDIHS], x, bPBC, box); set_force_const(plist, kb, kt, kp, bRound, bParam); cgnr = set_cgnr(atoms, bUsePDBcharge, &qtot, &mtot); printf("Total charge is %g, total mass is %g\n", qtot, mtot); if (bOPLS) { bts[2] = 3; bts[3] = 1; } if (bTOP) { fp = ftp2FILE(efTOP, NFILE, fnm, "w"); print_top_header(fp, ftp2fn(efTOP, NFILE, fnm), TRUE, ffdir, 1.0); write_top(fp, NULL, mymol.name, atoms, FALSE, bts, plist, excls, atype, cgnr, rtp_header_settings.nrexcl); print_top_mols(fp, mymol.name, ffdir, NULL, 0, NULL, 1, &mymol); ffclose(fp); } if (bRTP) { print_rtp(ftp2fn(efRTP, NFILE, fnm), "Generated by x2top", atoms, plist, atype, cgnr); } if (debug) { dump_hybridization(debug, atoms, nbonds); } close_symtab(&symtab); free(mymol.name); printf("\nWARNING: topologies generated by %s can not be trusted at face value.\n", ShortProgram()); printf(" Please verify atomtypes and charges by comparison to other\n"); printf(" topologies.\n"); return 0; }
gmx_bool read_tps_conf(const char *infile, t_topology *top, int *ePBC, rvec **x, rvec **v, matrix box, gmx_bool bMass) { t_tpxheader header; int natoms, i; gmx_bool bTop, bXNULL = FALSE; gmx_mtop_t *mtop; gmx_atomprop_t aps; bTop = fn2bTPX(infile); if (ePBC != NULL) { *ePBC = -1; } if (bTop) { read_tpxheader(infile, &header, TRUE); if (x) { snew(*x, header.natoms); } if (v) { snew(*v, header.natoms); } snew(mtop, 1); int ePBC_tmp = read_tpx(infile, NULL, box, &natoms, (x == NULL) ? NULL : *x, (v == NULL) ? NULL : *v, mtop); if (ePBC != NULL) { *ePBC = ePBC_tmp; } *top = gmx_mtop_t_to_t_topology(mtop); /* In this case we need to throw away the group data too */ done_gmx_groups_t(&mtop->groups); sfree(mtop); tpx_make_chain_identifiers(&top->atoms, &top->mols); } else { open_symtab(&top->symtab); get_stx_coordnum(infile, &natoms); init_t_atoms(&top->atoms, natoms, (fn2ftp(infile) == efPDB)); if (x == NULL) { snew(x, 1); bXNULL = TRUE; } snew(*x, natoms); if (v) { snew(*v, natoms); } read_stx_conf(infile, top, *x, (v == NULL) ? NULL : *v, ePBC, box); if (bXNULL) { sfree(*x); sfree(x); } if (bMass) { aps = gmx_atomprop_init(); for (i = 0; (i < natoms); i++) { if (!gmx_atomprop_query(aps, epropMass, *top->atoms.resinfo[top->atoms.atom[i].resind].name, *top->atoms.atomname[i], &(top->atoms.atom[i].m))) { if (debug) { fprintf(debug, "Can not find mass for atom %s %d %s, setting to 1\n", *top->atoms.resinfo[top->atoms.atom[i].resind].name, top->atoms.resinfo[top->atoms.atom[i].resind].nr, *top->atoms.atomname[i]); } } } gmx_atomprop_destroy(aps); } top->idef.ntypes = -1; } return bTop; }
int read_pdbfile(FILE *in,char *title,int *model_nr, t_atoms *atoms,rvec x[],int *ePBC,matrix box,bool bChange, gmx_conect conect) { gmx_conect_t *gc = (gmx_conect_t *)conect; static t_symtab symtab; static bool bFirst=TRUE; bool bCOMPND; bool bConnWarn = FALSE; char line[STRLEN+1]; int line_type; char *c,*d; int natom; bool bStop=FALSE; if (ePBC) { /* Only assume pbc when there is a CRYST1 entry */ *ePBC = epbcNONE; } if (box != NULL) clear_mat(box); if (bFirst) { open_symtab(&symtab); bFirst=FALSE; } bCOMPND=FALSE; title[0]='\0'; natom=0; while (!bStop && (fgets2(line,STRLEN,in) != NULL)) { line_type = line2type(line); switch(line_type) { case epdbATOM: case epdbHETATM: natom = read_atom(&symtab,line,line_type,natom,atoms,x,bChange); break; case epdbANISOU: if (atoms->pdbinfo) read_anisou(line,natom,atoms); break; case epdbCRYST1: read_cryst1(line,ePBC,box); break; case epdbTITLE: case epdbHEADER: if (strlen(line) > 6) { c=line+6; /* skip HEADER or TITLE and spaces */ while (c && (c[0]!=' ')) c++; while (c && (c[0]==' ')) c++; /* truncate after title */ d=strstr(c," "); if (d) { d[0]='\0'; } if (strlen(c)>0) strcpy(title,c); } break; case epdbCOMPND: if ((!strstr(line,": ")) || (strstr(line+6,"MOLECULE:"))) { if ( !(c=strstr(line+6,"MOLECULE:")) ) c=line; /* skip 'MOLECULE:' and spaces */ while (c && (c[0]!=' ')) c++; while (c && (c[0]==' ')) c++; /* truncate after title */ d=strstr(c," "); if (d) { while ( (d[-1]==';') && d>c) d--; d[0]='\0'; } if (strlen(c) > 0) { if (bCOMPND) { strcat(title,"; "); strcat(title,c); } else strcpy(title,c); } bCOMPND=TRUE; } break; case epdbTER: if (bTER) bStop=TRUE; break; case epdbMODEL: if(model_nr) sscanf(line,"%*s%d",model_nr); break; case epdbENDMDL: bStop=TRUE; break; case epdbCONECT: if (gc) add_conection(gc,line); else if (!bConnWarn) { fprintf(stderr,"WARNING: all CONECT records are ignored\n"); bConnWarn = TRUE; } break; default: break; } } return natom; }
static bool get_w_conf(FILE *in, char *infile, char *title, t_atoms *atoms, int *ndec, rvec x[],rvec *v, matrix box) { static t_symtab *symtab=NULL; char name[6]; char line[STRLEN+1],*ptr; char buf[256]; double x1,y1,z1,x2,y2,z2; rvec xmin,xmax; int natoms,i,m,resnr,newres,oldres,ddist,c; bool bFirst,bVel; char *p1,*p2,*p3; newres = 0; oldres = NOTSET; /* Unlikely number for the first residue! */ ddist = 0; if (!symtab) { snew(symtab,1); open_symtab(symtab); } /* Read the title and number of atoms */ get_coordnum_fp(in,title,&natoms); if (natoms > atoms->nr) gmx_fatal(FARGS,"gro file contains more atoms (%d) than expected (%d)", natoms,atoms->nr); else if (natoms < atoms->nr) fprintf(stderr,"Warning: gro file contains less atoms (%d) than expected" " (%d)\n",natoms,atoms->nr); bFirst=TRUE; bVel = FALSE; /* just pray the arrays are big enough */ for (i=0; (i < natoms) ; i++) { if ((fgets2 (line,STRLEN,in)) == NULL) { unexpected_eof(infile,i+2); } if (strlen(line) < 39) gmx_fatal(FARGS,"Invalid line in %s for atom %d:\n%s",infile,i+1,line); /* determine read precision from distance between periods (decimal points) */ if (bFirst) { bFirst=FALSE; p1=strchr(line,'.'); if (p1 == NULL) gmx_fatal(FARGS,"A coordinate in file %s does not contain a '.'",infile); p2=strchr(&p1[1],'.'); if (p2 == NULL) gmx_fatal(FARGS,"A coordinate in file %s does not contain a '.'",infile); ddist = p2 - p1; *ndec = ddist - 5; p3=strchr(&p2[1],'.'); if (p3 == NULL) gmx_fatal(FARGS,"A coordinate in file %s does not contain a '.'",infile); if (p3 - p2 != ddist) gmx_fatal(FARGS,"The spacing of the decimal points in file %s is not consistent for x, y and z",infile); } /* residue number*/ memcpy(name,line,5); name[5]='\0'; sscanf(name,"%d",&resnr); memcpy(name,line+5,5); name[5]='\0'; if (resnr != oldres) { oldres = resnr; if (newres >= natoms) gmx_fatal(FARGS,"More residues than atoms in %s (natoms = %d)", infile,natoms); atoms->resname[newres] = put_symtab(symtab,name); newres++; } resnr = newres; atoms->atom[i].resnr = resnr-1; /* atomname */ memcpy(name,line+10,5); atoms->atomname[i]=put_symtab(symtab,name); /* eventueel controle atomnumber met i+1 */ /* coordinates (start after residue shit) */ ptr = line + 20; /* Read fixed format */ for(m=0; m<DIM; m++) { for(c=0; (c<ddist && ptr[0]); c++) { buf[c] = ptr[0]; ptr++; } buf[c] = '\0'; if (sscanf (buf,"%lf %lf",&x1,&x2) != 1) { gmx_fatal(FARGS,"Something is wrong in the coordinate formatting of file %s. Note that gro is fixed format (see the manual)",infile); } else { x[i][m] = x1; } } /* velocities (start after residues and coordinates) */ if (v) { /* Read fixed format */ for(m=0; m<DIM; m++) { for(c=0; (c<ddist && ptr[0]); c++) { buf[c] = ptr[0]; ptr++; } buf[c] = '\0'; if (sscanf (buf,"%lf",&x1) != 1) { v[i][m] = 0; } else { v[i][m] = x1; bVel = TRUE; } } } } atoms->nres=newres; /* box */ fgets2 (line,STRLEN,in); if (sscanf (line,"%lf%lf%lf",&x1,&y1,&z1) != 3) { sprintf(buf,"Bad box in file %s",infile); warning(buf); /* Generate a cubic box */ for(m=0; (m<DIM); m++) xmin[m]=xmax[m]=x[0][m]; for(i=1; (i<atoms->nr); i++) for(m=0; (m<DIM); m++) { xmin[m]=min(xmin[m],x[i][m]); xmax[m]=max(xmax[m],x[i][m]); } for (i=0; i<DIM; i++) for (m=0; m<DIM; m++) box[i][m]=0.0; for(m=0; (m<DIM); m++) box[m][m]=(xmax[m]-xmin[m]); fprintf(stderr,"Generated a cubic box %8.3f x %8.3f x %8.3f\n", box[XX][XX],box[YY][YY],box[ZZ][ZZ]); } else { /* We found the first three values, the diagonal elements */ box[XX][XX]=x1; box[YY][YY]=y1; box[ZZ][ZZ]=z1; if (sscanf (line,"%*f%*f%*f%lf%lf%lf%lf%lf%lf", &x1,&y1,&z1,&x2,&y2,&z2) != 6) x1=y1=z1=x2=y2=z2=0.0; box[XX][YY] = x1; box[XX][ZZ] = y1; box[YY][XX] = z1; box[YY][ZZ] = x2; box[ZZ][XX] = y2; box[ZZ][YY] = z2; } close_symtab(symtab); return bVel; }