Пример #1
0
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);
    }
}
Пример #2
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]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;
}