示例#1
0
void setup_aster_lsr(ASTER_S *aster, STAR_S *star, const PARMS_S *parms){
    int ndtrat=parms->skyc.ndtrat;
    if(aster->pgm){
	dcellfree(aster->pgm);
	dcellfree(aster->sigman);
    }
    aster->pgm=cellnew(ndtrat,1);
    aster->sigman=cellnew(ndtrat,1);
    dmat *gm=ddup(aster->gm);
    if(aster->nwfs==1 && parms->maos.nmod==6 && gm->nx==8){
	info2("set 3rd column of gm to zero\n");
	memset(gm->p+gm->nx*2, 0, sizeof(double)*gm->nx);
    }

    for(int idtrat=0; idtrat<ndtrat; idtrat++){
	dcell *nea=cellnew(aster->nwfs, 1);
	for(int iwfs=0; iwfs<aster->nwfs; iwfs++){
	    nea->p[iwfs]=ddup(aster->wfs[iwfs].pistat->sanea->p[idtrat]);
	    dcwpow(nea->p[iwfs], 2);
	}
	dmat *neam=dcell2m(nea);//measurement error covariance
	dcellfree(nea); 
	dcwpow(neam, -1);//inverse
	/*Reconstructor */
	aster->pgm->p[idtrat]=dpinv(gm, neam);
	/*sigman is error due to noise. */
	dcwpow(neam, -1);//inverse again
	aster->sigman->p[idtrat]=calc_recon_error(aster->pgm->p[idtrat],neam,parms->maos.mcc);
	dfree(neam);
    }	
    if(parms->skyc.dbg){
	writebin(gm,"%s/aster%d_gm",dirsetup,aster->iaster);
	writebin(aster->pgm,    "%s/aster%d_pgm", dirsetup,aster->iaster);
	writebin(aster->sigman, "%s/aster%d_sigman", dirsetup,aster->iaster);
    }
    dfree(gm);
}
示例#2
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);
    }
}
示例#3
0
/**
   Compute Von Karman covariance function at separations computed from the grid
   size nx and sampling dx, with Fried parameter of r0, and outerscale of L0.  
   ninit is the initial side size of the atm array to start with.
*/
static vkcov_t* vkcov_calc(double r0, double L0, double dx, long n, long ninit){
    if(L0>9000) L0=INFINITY;/*L0 bigger than 9000 is treated as infinity. */
    vkcov_t *node=vkcov_get(r0, L0, dx, n, ninit);
    if(node) return node;
    node=mycalloc(1,vkcov_t);
    node->r0=r0;
    node->L0=L0;
    node->dx=dx;
    node->n=n;
    node->ninit=ninit;
    long nroot=(long)round(log2((double)n-1));
    node->next=head;
    if(r0>=L0){
	error("Illegal parameter: r0=%g, L0=%g\n", r0, L0);
    }
    head=node;
    dmat *r=dnew(2, nroot+2);
    double sqrt2=sqrt(2);
    IND(r,0,0)=0;
    IND(r,1,0)=0;
    for(long i=0; i<=nroot; i++){
	long j=1<<i;
	IND(r,0,i+1)=j*dx;
	IND(r,1,i+1)=j*dx*sqrt2;
    }
    double D=(n-1)*dx;
    node->cov=turbcov(r, D*sqrt(2), r0, L0);
    dfree(r);
    dmat *rc0=dnew(ninit*ninit, ninit*ninit);
    dmat*  rc=rc0;
    double dx2=dx*(n-1)/(ninit-1);
    for(long j=0; j<ninit; j++){
	double y=dx2*j;
	for(long i=0; i<ninit; i++){
	    double x=dx2*i;
	    long k=i+j*ninit;
	    for(long j2=0; j2<ninit; j2++){
		double y2=dx2*j2;
		for(long i2=0; i2<ninit; i2++){
		    double x2=dx2*i2;
		    long k2=i2+j2*ninit;
		    IND(rc,k2,k)=sqrt((x-x2)*(x-x2)+(y-y2)*(y-y2));
		}
	    }
	}
    }
    node->C=turbcov(rc0, D*sqrt(2), r0, L0);
    dfree(rc0);
    dmat *u=NULL, *s=NULL, *v=NULL;
    dsvd(&u, &s, &v, node->C);
    dcwpow(s, 1./2.);
    node->K=ddup(u);
    dmuldiag(node->K, s);

    dcwpow(s, -1);
    dmuldiag(u, s);
    node->KI=dtrans(u);
    dfree(u);
    dfree(v);
    dfree(s);
    /*we have: K*K'==C */
    return node;
}