static void setup_aster_kalman(SIM_S *simu, ASTER_S *aster, STAR_S *star, const PARMS_S *parms){ int ndtrat=parms->skyc.ndtrat; if(parms->skyc.multirate){ aster->res_ngs=dnew(1,1); //assemble neam if(aster->neam) error("neam is already set?\n"); aster->neam=calloc(1, sizeof(dcell*)); aster->neam[0]=cellnew(aster->nwfs, aster->nwfs); for(int iwfs=0; iwfs<aster->nwfs; iwfs++){ int ng=aster->g->p[iwfs]->nx; aster->neam[0]->p[iwfs+aster->nwfs*iwfs]=dnew(ng, ng); } aster->dtrats=dnew(aster->nwfs, 1); aster->idtrats=dnew(aster->nwfs, 1); int wfs0_min=0, wfs0_max=0; PISTAT_S *pistat0=&star[aster->wfs[0].istar].pistat[aster->wfs[0].ipowfs]; for(int idtrat=0; idtrat<parms->skyc.ndtrat; idtrat++){ if(wfs0_min==0 && pistat0->snr->p[idtrat]>3){ wfs0_min=idtrat; } if(pistat0->snr->p[idtrat]>=parms->skyc.snrmin->p[idtrat]){ wfs0_max=idtrat; } } aster->kalman=calloc(1, sizeof(kalman_t*)); double resmin=INFINITY; kalman_t *kalman_min=0; int idtrat_min=0; //Try progressively lower sampling frequencies until performance starts to degrades for(int idtrat_limit=wfs0_max; idtrat_limit>wfs0_min; idtrat_limit--){ setup_aster_kalman_dtrat(aster, star, parms, idtrat_limit); aster->kalman[0]=sde_kalman(simu->sdecoeff, parms->maos.dt, aster->dtrats, aster->g, aster->neam[0], 0); dmat *rests=0; #if 1 //more accurate dmat *res=skysim_sim(parms->skyc.dbg?&rests:0, simu->mideal, simu->mideal_oa, simu->rmsol, aster, 0, parms, -1, 1, -1); double res0=res?res->p[0]:simu->rmsol; dfree(res); #else rests=kalman_test(aster->kalman[0], simu->mideal); double res0=calc_rms(rests, parms->maos.mcc, parms->skyc.evlstart); #endif if(parms->skyc.dbg){ writebin(rests, "isky%d_iaster%d_dtrat%d_rest", simu->isky, aster->iaster, idtrat_limit); } if(parms->skyc.verbose) info2("res0=%g, resmin=%g\n", sqrt(res0)*1e9, sqrt(resmin)*1e9); dfree(rests); if(res0<resmin-100e-18){//better by 10 nm resmin=res0; kalman_free(kalman_min); kalman_min=aster->kalman[0]; aster->kalman[0]=0; idtrat_min=idtrat_limit; }else{ kalman_free(aster->kalman[0]);aster->kalman[0]=0; if(isfinite(resmin) && res0>resmin*2){//stop trying. break; } } } setup_aster_kalman_dtrat(aster, star, parms, idtrat_min); if(parms->skyc.verbose) info2("selected\n"); aster->res_ngs->p[0]=resmin; aster->kalman[0]=kalman_min; }else{ if(aster->neam) dcellfreearr(aster->neam, ndtrat); aster->neam=calloc(ndtrat, sizeof(dcell*)); aster->res_ngs=dnew(ndtrat,3); PDMAT(aster->res_ngs, pres_ngs); aster->kalman=calloc(ndtrat, sizeof(kalman_t*)); dmat *dtrats=dnew(aster->nwfs,1); for(int idtrat=0; idtrat<ndtrat; idtrat++){ //assemble neam //TIC;tic; aster->neam[idtrat]=cellnew(aster->nwfs, aster->nwfs); for(int iwfs=0; iwfs<aster->nwfs; iwfs++){ dmat *tmp=ddup(aster->wfs[iwfs].pistat->sanea->p[idtrat]);/*in rad */ dcwpow(tmp, 2); dsp *tmp2=dspnewdiag(tmp->nx, tmp->p, 1); dspfull(&aster->neam[idtrat]->p[iwfs+aster->nwfs*iwfs], tmp2,'n',1); dfree(tmp); dspfree(tmp2); } int dtrat=parms->skyc.dtrats->p[idtrat]; for(int iwfs=0; iwfs<aster->nwfs; iwfs++){ dtrats->p[iwfs]=dtrat; } aster->kalman[idtrat]=sde_kalman(simu->sdecoeff, parms->maos.dt, dtrats, aster->g, aster->neam[idtrat], 0); //toc("kalman"); #if 1 dmat *res=skysim_sim(0, simu->mideal, simu->mideal_oa, simu->rmsol, aster, 0, parms, idtrat, 1, -1); double rms=res?res->p[0]:simu->rmsol; dfree(res); #else dmat *res=kalman_test(aster->kalman[idtrat], simu->mideal); double rms=calc_rms(res, parms->maos.mcc, parms->skyc.evlstart); dfree(res); #endif //toc("estimate"); pres_ngs[0][idtrat]=rms; } dfree(dtrats); } }
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]HB* 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 i, teller; 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; 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, 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), &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*/ read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); teller = 0; 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); teller++; } while (read_next_x(oenv, status, &t, x, box)); fprintf(stderr, "\n"); xvgrclose(fp); close_trj(status); calc_rms(isize, teller, dtot, dtot2, rms, &rmsmax, rmsc, &rmscmax, mean, &meanmax); 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; }