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); }
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); } }
/** 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; }