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; } }
static gmx_bool pdb_next_x(t_trxstatus *status, FILE *fp,t_trxframe *fr) { t_atoms atoms; matrix boxpdb; int ePBC,model_nr,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 */ model_nr=NOTSET; na=read_pdbfile(fp,title,&model_nr,&atoms,fr->x,&ePBC,boxpdb,TRUE,NULL); 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!=NOTSET) { fr->bStep = TRUE; fr->step = model_nr; } time=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 write_trxframe_indexed(t_trxstatus *status, const t_trxframe *fr, int nind, const int *ind, gmx_conect gc) { char title[STRLEN]; rvec *xout = nullptr, *vout = nullptr, *fout = nullptr; int i, ftp = -1; real prec; if (fr->bPrec) { prec = fr->prec; } else { prec = 1000.0; } if (status->tng) { ftp = efTNG; } else if (status->fio) { ftp = gmx_fio_getftp(status->fio); } else { gmx_incons("No input file available"); } switch (ftp) { case efTRR: case efTNG: break; default: if (!fr->bX) { gmx_fatal(FARGS, "Need coordinates to write a %s trajectory", ftp2ext(ftp)); } break; } switch (ftp) { case efTRR: case efTNG: if (fr->bV) { snew(vout, nind); for (i = 0; i < nind; i++) { copy_rvec(fr->v[ind[i]], vout[i]); } } if (fr->bF) { snew(fout, nind); for (i = 0; i < nind; i++) { copy_rvec(fr->f[ind[i]], fout[i]); } } // fallthrough case efXTC: if (fr->bX) { snew(xout, nind); for (i = 0; i < nind; i++) { copy_rvec(fr->x[ind[i]], xout[i]); } } break; default: break; } switch (ftp) { case efTNG: gmx_write_tng_from_trxframe(status->tng, fr, nind); break; case efXTC: write_xtc(status->fio, nind, fr->step, fr->time, fr->box, xout, prec); break; case efTRR: gmx_trr_write_frame(status->fio, nframes_read(status), fr->time, fr->step, fr->box, nind, xout, vout, fout); break; case efGRO: case efPDB: case efBRK: case efENT: if (!fr->bAtoms) { gmx_fatal(FARGS, "Can not write a %s file without atom names", ftp2ext(ftp)); } sprintf(title, "frame t= %.3f", fr->time); if (ftp == efGRO) { write_hconf_indexed_p(gmx_fio_getfp(status->fio), title, fr->atoms, nind, ind, fr->x, fr->bV ? fr->v : nullptr, fr->box); } else { write_pdbfile_indexed(gmx_fio_getfp(status->fio), title, fr->atoms, fr->x, -1, fr->box, ' ', fr->step, nind, ind, gc, TRUE); } break; case efG96: sprintf(title, "frame t= %.3f", fr->time); write_g96_conf(gmx_fio_getfp(status->fio), title, fr, nind, ind); break; default: gmx_fatal(FARGS, "Sorry, write_trxframe_indexed can not write %s", ftp2ext(ftp)); break; } switch (ftp) { case efTRR: case efTNG: if (vout) { sfree(vout); } if (fout) { sfree(fout); } // fallthrough case efXTC: sfree(xout); break; default: break; } return 0; }
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 write_trxframe_indexed(t_trxstatus *status, t_trxframe *fr, int nind, const atom_id *ind, gmx_conect gc) { char title[STRLEN]; rvec *xout = NULL, *vout = NULL, *fout = NULL; int i; real prec; if (fr->bPrec) { prec = fr->prec; } else { prec = 1000.0; } switch (gmx_fio_getftp(status->fio)) { case efTRJ: case efTRR: break; default: if (!fr->bX) { gmx_fatal(FARGS, "Need coordinates to write a %s trajectory", ftp2ext(gmx_fio_getftp(status->fio))); } break; } switch (gmx_fio_getftp(status->fio)) { case efTRJ: case efTRR: if (fr->bV) { snew(vout, nind); for (i = 0; i < nind; i++) { copy_rvec(fr->v[ind[i]], vout[i]); } } if (fr->bF) { snew(fout, nind); for (i = 0; i < nind; i++) { copy_rvec(fr->f[ind[i]], fout[i]); } } /* no break */ case efXTC: case efG87: if (fr->bX) { snew(xout, nind); for (i = 0; i < nind; i++) { copy_rvec(fr->x[ind[i]], xout[i]); } } break; default: break; } switch (gmx_fio_getftp(status->fio)) { case efXTC: write_xtc(status->fio, nind, fr->step, fr->time, fr->box, xout, prec); break; case efTRJ: case efTRR: fwrite_trn(status->fio, nframes_read(status), fr->time, fr->step, fr->box, nind, xout, vout, fout); break; case efGRO: case efPDB: case efBRK: case efENT: if (!fr->bAtoms) { gmx_fatal(FARGS, "Can not write a %s file without atom names", ftp2ext(gmx_fio_getftp(status->fio))); } sprintf(title, "frame t= %.3f", fr->time); if (gmx_fio_getftp(status->fio) == efGRO) { write_hconf_indexed_p(gmx_fio_getfp(status->fio), title, fr->atoms, nind, ind, prec2ndec(prec), fr->x, fr->bV ? fr->v : NULL, fr->box); } else { write_pdbfile_indexed(gmx_fio_getfp(status->fio), title, fr->atoms, fr->x, -1, fr->box, ' ', fr->step, nind, ind, gc, TRUE); } break; case efG87: write_gms(gmx_fio_getfp(status->fio), nind, xout, fr->box); break; case efG96: write_g96_conf(gmx_fio_getfp(status->fio), fr, nind, ind); break; default: gmx_fatal(FARGS, "Sorry, write_trxframe_indexed can not write %s", ftp2ext(gmx_fio_getftp(status->fio))); break; } switch (gmx_fio_getftp(status->fio)) { case efTRN: case efTRJ: case efTRR: if (vout) { sfree(vout); } if (fout) { sfree(fout); } /* no break */ case efXTC: case efG87: sfree(xout); break; default: break; } return 0; }
int gmx_rmsdist(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] computes the root mean square deviation of atom distances,", "which has the advantage that no fit is needed like in standard RMS", "deviation as computed by [gmx-rms].", "The reference structure is taken from the structure file.", "The RMSD at time t is calculated as the RMS", "of the differences in distance between atom-pairs in the reference", "structure and the structure at time t.[PAR]", "[THISMODULE] can also produce matrices of the rms distances, rms distances", "scaled with the mean distance and the mean distances and matrices with", "NMR averaged distances (1/r^3 and 1/r^6 averaging). Finally, lists", "of atom pairs with 1/r^3 and 1/r^6 averaged distance below the", "maximum distance ([TT]-max[tt], which will default to 0.6 in this case)", "can be generated, by default averaging over equivalent hydrogens", "(all triplets of hydrogens named *[123]). Additionally a list of", "equivalent atoms can be supplied ([TT]-equiv[tt]), each line containing", "a set of equivalent atoms specified as residue number and name and", "atom name; e.g.:[PAR]", "[TT]3 SER HB1 3 SER HB2[tt][PAR]", "Residue and atom names must exactly match those in the structure", "file, including case. Specifying non-sequential atoms is undefined." }; int natom, i, j, teller, gi, gj; real t; t_topology top; int ePBC; t_atoms *atoms; matrix box; rvec *x; FILE *fp; t_trxstatus *status; int isize, gnr = 0; atom_id *index, *noe_index; char *grpname; real **d_r, **d, **dtot, **dtot2, **mean, **rms, **rmsc, *resnr; real **dtot1_3 = NULL, **dtot1_6 = NULL; real rmsnow, meanmax, rmsmax, rmscmax; real max1_3, max1_6; t_noe_gr *noe_gr = NULL; t_noe **noe = NULL; t_rgb rlo, rhi; char buf[255]; gmx_bool bRMS, bScale, bMean, bNOE, bNMR3, bNMR6, bNMR; static int nlevels = 40; static real scalemax = -1.0; static gmx_bool bSumH = TRUE; static gmx_bool bPBC = TRUE; output_env_t oenv; t_pargs pa[] = { { "-nlevels", FALSE, etINT, {&nlevels}, "Discretize RMS in this number of levels" }, { "-max", FALSE, etREAL, {&scalemax}, "Maximum level in matrices" }, { "-sumh", FALSE, etBOOL, {&bSumH}, "Average distance over equivalent hydrogens" }, { "-pbc", FALSE, etBOOL, {&bPBC}, "Use periodic boundary conditions when computing distances" } }; t_filenm fnm[] = { { efTRX, "-f", NULL, ffREAD }, { efTPS, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffOPTRD }, { efDAT, "-equiv", "equiv", ffOPTRD }, { efXVG, NULL, "distrmsd", ffWRITE }, { efXPM, "-rms", "rmsdist", ffOPTWR }, { efXPM, "-scl", "rmsscale", ffOPTWR }, { efXPM, "-mean", "rmsmean", ffOPTWR }, { efXPM, "-nmr3", "nmr3", ffOPTWR }, { efXPM, "-nmr6", "nmr6", ffOPTWR }, { efDAT, "-noe", "noe", ffOPTWR }, }; #define NFILE asize(fnm) if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } bRMS = opt2bSet("-rms", NFILE, fnm); bScale = opt2bSet("-scl", NFILE, fnm); bMean = opt2bSet("-mean", NFILE, fnm); bNOE = opt2bSet("-noe", NFILE, fnm); bNMR3 = opt2bSet("-nmr3", NFILE, fnm); bNMR6 = opt2bSet("-nmr6", NFILE, fnm); bNMR = bNMR3 || bNMR6 || bNOE; max1_3 = 0; max1_6 = 0; /* check input */ if (bNOE && scalemax < 0) { scalemax = 0.6; fprintf(stderr, "WARNING: using -noe without -max " "makes no sense, setting -max to %g\n\n", scalemax); } /* get topology and index */ read_tps_conf(ftp2fn(efTPS, NFILE, fnm), buf, &top, &ePBC, &x, NULL, box, FALSE); if (!bPBC) { ePBC = epbcNONE; } atoms = &(top.atoms); get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpname); /* initialize arrays */ snew(d, isize); snew(dtot, isize); snew(dtot2, isize); if (bNMR) { snew(dtot1_3, isize); snew(dtot1_6, isize); } snew(mean, isize); snew(rms, isize); snew(rmsc, isize); snew(d_r, isize); snew(resnr, isize); for (i = 0; (i < isize); i++) { snew(d[i], isize); snew(dtot[i], isize); snew(dtot2[i], isize); if (bNMR) { snew(dtot1_3[i], isize); snew(dtot1_6[i], isize); } snew(mean[i], isize); snew(rms[i], isize); snew(rmsc[i], isize); snew(d_r[i], isize); resnr[i] = i+1; } /*set box type*/ calc_dist(isize, index, x, ePBC, box, d_r); sfree(x); /*open output files*/ fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "RMS Deviation", "Time (ps)", "RMSD (nm)", oenv); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(fp, "@ subtitle \"of distances between %s atoms\"\n", grpname); } /*do a first step*/ natom = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); do { calc_dist_tot(isize, index, x, ePBC, box, d, dtot, dtot2, bNMR, dtot1_3, dtot1_6); rmsnow = rms_diff(isize, d, d_r); fprintf(fp, "%g %g\n", t, rmsnow); } while (read_next_x(oenv, status, &t, x, box)); fprintf(stderr, "\n"); gmx_ffclose(fp); teller = nframes_read(status); close_trj(status); calc_rms(isize, teller, dtot, dtot2, mean, &meanmax, rms, &rmsmax, rmsc, &rmscmax); fprintf(stderr, "rmsmax = %g, rmscmax = %g\n", rmsmax, rmscmax); if (bNMR) { calc_nmr(isize, teller, dtot1_3, dtot1_6, &max1_3, &max1_6); } if (scalemax > -1.0) { rmsmax = scalemax; rmscmax = scalemax; meanmax = scalemax; max1_3 = scalemax; max1_6 = scalemax; } if (bNOE) { /* make list of noe atom groups */ snew(noe_index, isize+1); snew(noe_gr, isize); gnr = analyze_noe_equivalent(opt2fn_null("-equiv", NFILE, fnm), atoms, isize, index, bSumH, noe_index, noe_gr); fprintf(stdout, "Found %d non-equivalent atom-groups in %d atoms\n", gnr, isize); /* make half matrix of of noe-group distances from atom distances */ snew(noe, gnr); for (i = 0; i < gnr; i++) { snew(noe[i], gnr); } calc_noe(isize, noe_index, dtot1_3, dtot1_6, gnr, noe); } rlo.r = 1.0, rlo.g = 1.0, rlo.b = 1.0; rhi.r = 0.0, rhi.g = 0.0, rhi.b = 0.0; if (bRMS) { write_xpm(opt2FILE("-rms", NFILE, fnm, "w"), 0, "RMS of distance", "RMS (nm)", "Atom Index", "Atom Index", isize, isize, resnr, resnr, rms, 0.0, rmsmax, rlo, rhi, &nlevels); } if (bScale) { write_xpm(opt2FILE("-scl", NFILE, fnm, "w"), 0, "Relative RMS", "RMS", "Atom Index", "Atom Index", isize, isize, resnr, resnr, rmsc, 0.0, rmscmax, rlo, rhi, &nlevels); } if (bMean) { write_xpm(opt2FILE("-mean", NFILE, fnm, "w"), 0, "Mean Distance", "Distance (nm)", "Atom Index", "Atom Index", isize, isize, resnr, resnr, mean, 0.0, meanmax, rlo, rhi, &nlevels); } if (bNMR3) { write_xpm(opt2FILE("-nmr3", NFILE, fnm, "w"), 0, "1/r^3 averaged distances", "Distance (nm)", "Atom Index", "Atom Index", isize, isize, resnr, resnr, dtot1_3, 0.0, max1_3, rlo, rhi, &nlevels); } if (bNMR6) { write_xpm(opt2FILE("-nmr6", NFILE, fnm, "w"), 0, "1/r^6 averaged distances", "Distance (nm)", "Atom Index", "Atom Index", isize, isize, resnr, resnr, dtot1_6, 0.0, max1_6, rlo, rhi, &nlevels); } if (bNOE) { write_noe(opt2FILE("-noe", NFILE, fnm, "w"), gnr, noe, noe_gr, scalemax); } do_view(oenv, ftp2fn(efXVG, NFILE, fnm), NULL); return 0; }