예제 #1
0
파일: save.c 프로젝트: bitursa/maos
void save_gradstat(SIM_T *simu) {
    const PARMS_T *parms=simu->parms;
    const int isim=simu->isim;
    //Save pistat in the end of simulation
    for(int iwfs=0; iwfs<simu->parms->nwfs; iwfs++) {
        int ipowfs=parms->wfsr[iwfs].powfs;
        const int dtrat=parms->powfs[ipowfs].dtrat;
        double scale;
        if(parms->powfs[ipowfs].usephy) {
            scale=(simu->isim+1-simu->parms->powfs[ipowfs].phystep)/dtrat;
        } else {
            scale=(simu->isim+1)/dtrat;
        }
        if(scale<=0) continue;
        if(simu->pistatout && simu->pistatout->p[iwfs]) {
            int nstep=isim+1-parms->powfs[ipowfs].pistatstart;
            scale=1./(double)nstep;
            dcell *pp=simu->pistatout->p[iwfs];
            dcellscale(pp,scale);
            if(parms->sim.skysim) { /*need peak in corner */
                for(long ic=0; ic<pp->nx*pp->ny; ic++) {
                    dfftshift(pp->p[ic]);
                }
                writebin(pp,"%s/pistat/pistat_seed%d_sa%d_x%g_y%g.bin",
                         dirskysim,simu->seed,
                         parms->powfs[ipowfs].order,
                         parms->wfs[iwfs].thetax*206265,
                         parms->wfs[iwfs].thetay*206265);
                for(long ic=0; ic<pp->nx*pp->ny; ic++) {
                    dfftshift(pp->p[ic]);
                }
            } else { /*need peak in center */
                writebin(pp,"pistat_seed%d_wfs%d.bin", simu->seed,iwfs);
            }
            dcellscale(pp,1./scale);
        }
    }
}
예제 #2
0
파일: servo.c 프로젝트: bitursa/maos
/**
   prepare the integrator by shifting commands. similar to laos.
   inte->p[0]=inte->p[0]*ap[0]+inte->p[1]*ap[1]+...
*/
static void servo_shift_ap(SERVO_T *st){
    const dmat *ap=st->ap;
    if(!ap) return; //no need to shift.
    if(st->mint->nx<ap->nx){
	cellresize(st->mint, ap->nx, 1);
    }
    if(!st->initialized) return;
    dcell **inte=st->mint->p;
    dcell *cyclic=inte[ap->nx-1];
    dcellscale(cyclic, ap->p[ap->nx-1]);
    for(int iap=ap->nx-2; iap>=0; iap--){
	dcelladd(&cyclic,1,inte[iap],ap->p[iap]);
    }
    for(int iap=ap->nx-1; iap>0; iap--){
	inte[iap]=inte[iap-1];/*shifting */
    }
    inte[0]=cyclic;/*new command. */
}
예제 #3
0
파일: save.c 프로젝트: bitursa/maos
void save_recon(SIM_T *simu) {
    const PARMS_T *parms=simu->parms;
    const RECON_T *recon=simu->recon;
    if(parms->plot.run) {
        if(parms->recon.alg==0) {
            for(int i=0; simu->opdr && i<simu->opdr->nx; i++) {
                if(simu->opdr->p[i]) {
                    drawopd("opdr", recon->xloc->p[i], simu->opdr->p[i]->p, NULL,
                            "Reconstructed Atmosphere","x (m)","y (m)","opdr %d",i);
                }
            }
            for(int i=0; simu->dmfit && i<simu->dmfit->nx; i++) {
                if(simu->dmfit->p[i]) {
                    drawopd("DM", recon->aloc->p[i], simu->dmfit->p[i]->p,NULL,
                            "DM Fitting Output","x (m)", "y (m)","Fit %d",i);
                }
            }
        }
        if(!parms->recon.modal) {
            for(int idm=0; simu->dmerr && idm<parms->ndm; idm++) {
                if(simu->dmerr->p[idm]) {
                    drawopd("DM",recon->aloc->p[idm], simu->dmerr->p[idm]->p,NULL,
                            "DM Error Signal (Hi)","x (m)","y (m)",
                            "Err Hi %d",idm);
                }
            }
        }
        for(int idm=0; simu->dmerr && idm<parms->ndm; idm++) {
            if(simu->dmint->mint->p[0]->p[idm]) {
                drawopd("DM",recon->aloc->p[idm], simu->dmint->mint->p[0]->p[idm]->p,NULL,
                        "DM Integrator (Hi)","x (m)","y (m)",
                        "Int Hi %d",idm);
            }
        }
        if(simu->dm_wfs) {
            for(int iwfs=0; iwfs<parms->nwfs; iwfs++) {
                int ipowfs=parms->wfs[iwfs].powfs;
                int imoao=parms->powfs[ipowfs].moao;
                if(imoao<0) continue;
                drawopd("moao", recon->moao[imoao].aloc->p[0], simu->dm_wfs->p[iwfs]->p, NULL,
                        "MOAO", "x(m)", "y(m)", "WFS %d", iwfs);
            }
        }
        if(simu->dm_evl) {
            int imoao=parms->evl.moao;
            for(int ievl=0; ievl<parms->evl.nevl && imoao>=0; ievl++) {
                drawopd("moao", recon->moao[imoao].aloc->p[0], simu->dm_evl->p[ievl]->p, NULL,
                        "MOAO", "x(m)", "y(m)", "Evl %d", ievl);
            }
        }
    }
    if(parms->plot.run && simu->Merr_lo) {
        dcell *dmlo=NULL;
        switch(simu->parms->recon.split) {
        case 1:
            ngsmod2dm(&dmlo, recon, simu->Merr_lo, 1);
            break;
        case 2:
            dcellmm(&dmlo, simu->recon->MVModes, simu->Merr_lo, "nn", 1);
            break;
        }
        for(int idm=0; dmlo && idm<parms->ndm; idm++) {
            drawopd("DM",recon->aloc->p[idm], dmlo->p[idm]->p,NULL,
                    "DM Error Signal (Lo)","x (m)","y (m)",
                    "Err Lo %d",idm);
        }
        dcellfree(dmlo);
    }
    if(parms->plot.run && simu->Mint_lo && simu->Mint_lo->mint->p[0]) {
        dcell *dmlo=NULL;
        switch(simu->parms->recon.split) {
        case 1:
            ngsmod2dm(&dmlo, recon, simu->Mint_lo->mint->p[0], 1);
            break;
        case 2:
            dcellmm(&dmlo, simu->recon->MVModes, simu->Mint_lo->mint->p[0], "nn", 1);
            break;
        }
        for(int idm=0; dmlo && idm<parms->ndm; idm++) {
            drawopd("DM",recon->aloc->p[idm], dmlo->p[idm]->p,NULL,
                    "DM Integrator (Lo)","x (m)","y (m)",
                    "Int Lo %d",idm);
        }
        dcellfree(dmlo);
    }
    if(parms->recon.alg==0) { /*minimum variance tomo/fit reconstructor */
        if(parms->save.opdr) {
            cellarr_dcell(simu->save->opdr, simu->reconisim, simu->opdr);
        }
        if(parms->save.opdx || parms->plot.opdx) {
            dcell *opdx=simu->opdx;
            if(!opdx) {
                atm2xloc(&opdx, simu);
            }
            if(parms->save.opdx) {
                cellarr_dcell(simu->save->opdx, simu->isim, opdx);
            }
            if(parms->plot.opdx) { /*draw opdx */
                for(int i=0; i<opdx->nx; i++) {
                    if(opdx->p[i]) {
                        drawopd("opdx", recon->xloc->p[i], opdx->p[i]->p, NULL,
                                "Atmosphere Projected to XLOC","x (m)","y (m)","opdx %d",i);
                    }
                }
            }
            if(!parms->sim.idealfit) {
                dcellfree(opdx);
            }
        }
    }
    if(parms->save.dm && (!parms->sim.closeloop || simu->isim>0)) {
        if(simu->dmfit) {
            cellarr_dcell(simu->save->dmfit, simu->reconisim, simu->dmfit);
        }
        if(simu->dmerr) {
            cellarr_dcell(simu->save->dmerr, simu->reconisim, simu->dmerr);
        }
        if(simu->dmint->mint->p[0]) {
            cellarr_dcell(simu->save->dmint, simu->reconisim, simu->dmint->mint->p[0]);
        }
        if(simu->Merr_lo) {
            cellarr_dcell(simu->save->Merr_lo, simu->reconisim, simu->Merr_lo);
            if(!parms->sim.fuseint && simu->Mint_lo->mint->p[0]) {
                cellarr_dcell(simu->save->Mint_lo, simu->reconisim, simu->Mint_lo->mint->p[0]);
            }
        }
    }
    const int seed=simu->seed;
    if(parms->save.ngcov>0 && CHECK_SAVE(parms->sim.start, parms->sim.end-(parms->sim.closeloop?1:0), simu->reconisim, parms->save.gcovp)) {
        double scale=1./(double)(simu->reconisim-parms->sim.start+1);
        dcellscale(simu->gcov, scale);
        for(int igcov=0; igcov<parms->save.ngcov; igcov++) {
            writebin(simu->gcov->p[igcov], "gcov_%d_wfs%ld_%ld_%d.bin", seed,
                     parms->save.gcov->p[igcov*2], parms->save.gcov->p[igcov*2+1],
                     simu->reconisim+1);
        }
        dcellscale(simu->gcov, 1./scale);
    }
    if(parms->sim.psfr && CHECK_SAVE(parms->evl.psfisim, parms->sim.end-(parms->sim.closeloop?1:0), simu->reconisim, parms->sim.psfr)) {
        info2("Output PSF Recon Telemetry\n");
        long nstep=simu->reconisim+1-parms->evl.psfisim;
        double scale=1./nstep;
        dcellscale(simu->ecov, scale);
        if(!parms->dbg.useopdr || parms->sim.idealfit) {
            writebin(simu->ecov, "ecov_%d_%ld", seed, nstep);
        } else { /*deprecated */
            char strht[24];
            for(int ievl=0; ievl<parms->evl.nevl; ievl++) {
                if(!simu->ecov->p[ievl]) continue;
                if(isfinite(parms->evl.hs->p[ievl])) {
                    snprintf(strht, 24, "_%g", parms->evl.hs->p[ievl]);
                } else {
                    strht[0]='\0';
                }
                writebin(simu->ecov->p[ievl], "ecov_%d_x%g_y%g%s_%ld.bin", seed,
                         parms->evl.thetax->p[ievl]*206265,
                         parms->evl.thetay->p[ievl]*206265, strht, nstep);
            }
        }
        dcellscale(simu->ecov, 1./scale);//scale back to continuous accumulation
    }
}
예제 #4
0
/**
   Setup the least square reconstruct by directly inverting GA matrix. 
   The reconstructor is simply the pseudo inverse of GA matrix:
   \f[\hat{x}=(G_a^TC_g^{-1}G_a)^{-1}G_a^TC_g^{-1}\f]

   This is very close to RR except replacing GX with GA.

   We use the tomograhy parameters for lsr, since lsr is simply "tomography" onto DM directly.
*/
void setup_recon_lsr(RECON_T *recon, const PARMS_T *parms){
    const int ndm=parms->ndm;
    const int nwfs=parms->nwfsr;
    cell *GAlsr;
    cell *GAM=parms->recon.modal?(cell*)recon->GM:(cell*)recon->GA;
    if(parms->recon.split){ //high order wfs only in split mode. 
	GAlsr=parms->recon.modal?(cell*)recon->GMhi:(cell*)recon->GAhi;
    }else{ //all wfs in integrated mode. 
	GAlsr=GAM;
    }
    int free_GAlsr=0;
    if(GAlsr->p[0]->id!=M_DBL){
	dsp *tmp=dsp_cast(GAlsr->p[0]);
	if(tmp->nzmax>tmp->nx*tmp->ny*0.2){//not very sparse
	    dcell *tmp2=0;
	    free_GAlsr=1;
	    dcelladd(&tmp2, 1, (dspcell*)GAlsr, 1);
	    GAlsr=(cell*)tmp2;
	}
    }
    info2("Building recon->LR\n");
    recon->LR.M=dcellmm2(GAlsr, recon->saneai, "tn");
    // Tip/tilt and diff focus removal low rand terms for LGS WFS.
    if(recon->TTF){
	dcellmm(&recon->LR.U, recon->LR.M, recon->TTF, "nn", 1);
	recon->LR.V=dcelltrans(recon->PTTF);
    }
    info2("Building recon->LL\n");
    recon->LL.M=dcellmm2(recon->LR.M, GAlsr, "nn");
    if(free_GAlsr){
	cellfree(GAlsr);
    }
    double maxeig=pow(recon->neamhi * recon->aloc->p[0]->dx, -2);
    if(parms->recon.modal){
	double strength=1;
	for(int idm=0; idm<ndm; idm++){
	    strength*=dnorm(recon->amod->p[idm]);
	}
	strength=pow(strength, 2./ndm);
	maxeig*=strength;
    }
    if(fabs(parms->lsr.tikcr)>EPS){
	info2("Adding tikhonov constraint of %g to LLM\n", parms->lsr.tikcr);
	info2("The maximum eigen value is estimated to be around %g\n", maxeig);
	dcelladdI(recon->LL.M, parms->lsr.tikcr*maxeig);
    }
    dcell *NW=NULL;
    if(!parms->recon.modal){
	if(parms->lsr.alg!=2){
	    /* Not SVD, need low rank terms for piston/waffle mode constraint. */
	    NW=dcellnew(ndm,1);
	    int nmod=2;/*two modes. */
	    for(int idm=0; idm<ndm; idm++){
		loc_create_map(recon->aloc->p[idm]);
		const long nloc=recon->aloc->p[idm]->nloc;
		NW->p[idm]=dnew(nloc, ndm*nmod);
		double *p=NW->p[idm]->p+nmod*idm*nloc;
		const double *cpl=recon->actcpl->p[idm]->p;
		for(long iloc=0; iloc<nloc; iloc++){
		    if(cpl[iloc]>0.1){
			p[iloc]=1;/*piston mode */
		    }
		}
		/*notice offset of 1 because map start count at 1 */
		p=NW->p[idm]->p+(1+nmod*idm)*nloc-1;
		map_t *map=recon->aloc->p[idm]->map;
		for(long iy=0; iy<map->ny; iy++){
		    for(long ix=0; ix<map->nx; ix++){
			if(IND(map,ix,iy)){
			    p[(long)IND(map,ix,iy)]=(double)2*((iy+ix)&1)-1;
			}
		    }
		}
	    }
	    /*scale it to match the magnitude of LL.M */
	    dcellscale(NW, sqrt(maxeig));
	    if(parms->save.setup){
		writebin(NW, "lsrNW");
	    }
	}
	if(parms->lsr.actslave){
	    /*actuator slaving. important. change from 0.5 to 0.1 on 2011-07-14. */
	    dspcell *actslave=slaving(recon->aloc, recon->actcpl, NW,
				      recon->actstuck, recon->actfloat, parms->lsr.actthres, maxeig);
	    if(parms->save.setup){
		if(NW){
		    writebin(NW, "lsrNW2");
		}
		writebin(actslave,"actslave");
	    }
	    dcelladd(&recon->LL.M, 1, actslave, 1);
	    cellfree(actslave);
	}
    }
    /*Low rank terms for low order wfs. Only in Integrated tomography. */
    dcell *ULo=dcellnew(ndm,nwfs);
    dcell *VLo=dcellnew(ndm,nwfs);
    dcell*  pULo=ULo/*PDELL*/;
    dcell*  pVLo=VLo/*PDELL*/;
    for(int iwfs=0; iwfs<nwfs; iwfs++){
	int ipowfs=parms->wfsr[iwfs].powfs;
	if(parms->powfs[ipowfs].skip || !parms->powfs[ipowfs].lo){
	    continue;
	}
	for(int idm=0; idm<ndm; idm++){
	    dspfull(PIND(pULo,idm,iwfs), (dsp*)IND(recon->LR.M, idm, iwfs),'n',-1);
	    dspfull(PIND(pVLo,idm,iwfs), (dsp*)IND(GAM, iwfs, idm),'t',1);
	}
    }
    recon->LL.U=dcellcat(recon->LR.U, ULo, 2);
    dcell *GPTTDF=NULL;
    dcellmm(&GPTTDF, GAM, recon->LR.V, "tn", 1);
    recon->LL.V=dcellcat(GPTTDF, VLo, 2);
    dcellfree(GPTTDF);
    dcellfree(ULo);
    dcellfree(VLo);
    if(!parms->recon.modal && NW){
	info2("Create piston and check board modes that are in NULL space of GA.\n");
	/*add to low rank terms. */
	dcell *tmp=recon->LL.U;
	recon->LL.U=dcellcat(tmp, NW, 2);
	dcellfree(tmp);
	dcellscale(NW, -1);
	tmp=recon->LL.V;
	recon->LL.V=dcellcat(tmp, NW, 2);
	dcellfree(tmp);
	dcellfree(NW);
    }
    if(parms->lsr.fnreg){
	warning("Loading LSR regularization from file %s.\n", parms->lsr.fnreg);
	dspcell *tmp=dspcellread("%s", parms->lsr.fnreg);
	dcelladd(&recon->LL.M, 1, tmp, 1);
	dspcellfree(tmp);
    }
    recon->LL.alg = parms->lsr.alg;
    recon->LL.bgs = parms->lsr.bgs;
    recon->LL.warm = parms->recon.warm_restart;
    recon->LL.maxit = parms->lsr.maxit;
    /*Remove empty cells. */
    dcelldropempty(&recon->LR.U,2);
    dcelldropempty(&recon->LR.V,2);
    dcelldropempty(&recon->LL.U,2);
    dcelldropempty(&recon->LL.V,2);
    if(parms->save.recon){
	writebin(recon->LR.M,"LRM");
	writebin(recon->LR.U,"LRU");
	writebin(recon->LR.V,"LRV");
	writebin(recon->LL.M,"LLM.bin");/*disable compression */
	writebin(recon->LL.U,"LLU");
	writebin(recon->LL.V,"LLV"); 
    }
    if(parms->lsr.alg==0 || parms->lsr.alg==2){
	if(!parms->lsr.bgs){
	    muv_direct_prep(&recon->LL, (parms->lsr.alg==2)*parms->lsr.svdthres);
	    if(parms->save.recon){
		if(recon->LL.C)
		    chol_save(recon->LL.C, "LLC.bin");
		else
		    writebin(recon->LL.MI, "LLMI.bin");
	    }
	    cellfree(recon->LL.M);
	    dcellfree(recon->LL.U);
	    dcellfree(recon->LL.V);	
	}else{
	    muv_direct_diag_prep(&(recon->LL), (parms->lsr.alg==2)*parms->lsr.svdthres);
	    if(parms->save.recon){
		for(int ib=0; ib<recon->LL.nb; ib++){
		    if(recon->LL.CB)
			chol_save(recon->LL.CB[ib],"LLCB_%d.bin", ib);
		    else
			writebin(recon->LL.MI,"LLMIB_%d.bin", ib);
		}
	    }
	    /*Don't free M, U, V */
	}
    }
}
예제 #5
0
/**
   Read in pistat information, used to compute matched filter, and SANEA.
*/
static void setup_star_read_pistat(SIM_S *simu, STAR_S *star, int nstar, int seed){
    const PARMS_S *parms=simu->parms;
    const int npowfs=parms->maos.npowfs;
    const int nwvl=parms->maos.nwvl;
    const double ngsgrid=parms->maos.ngsgrid;
    for(int istar=0; istar<nstar; istar++){
	STAR_S *stari=&star[istar];
	stari->pistat=mycalloc(npowfs,PISTAT_S);
	const double thetax=stari->thetax*206265;/*in as */
	const double thetay=stari->thetay*206265;
	double thxnorm=thetax/ngsgrid;
	double thynorm=thetay/ngsgrid;
	long thxl=(long)floor(thxnorm);
	long thyl=(long)floor(thynorm);
	double wtx=thxnorm-thxl;
	double wty=thynorm-thyl;
	for(int ipowfs=0; ipowfs<npowfs; ipowfs++){
	    const int msa=parms->maos.msa[ipowfs];
	    const int nsa=parms->maos.nsa[ipowfs];
	    dcell *avgpsf=NULL;
	    dcell *neaspec=NULL;
	    double wtsum=0;
	    for(int ix=0; ix<2; ix++){
		double thx=(thxl+ix)*ngsgrid;
		for(int iy=0; iy<2; iy++){
		    double thy=(thyl+iy)*ngsgrid;
		    double wtxi=fabs(((1-ix)-wtx)*((1-iy)-wty));
		    if(wtxi<0.01){
			/*info("skipping ix=%d,iy=%d because wt=%g\n",ix,iy,wtxi); */
			continue;
		    }
		    char fn[PATH_MAX];
		    snprintf(fn,PATH_MAX,"%s/pistat/pistat_seed%d_sa%d_x%g_y%g",
			     dirstart, seed,msa,thx,thy);
		    if(!zfexist(fn)){
			/*warning("%s doesn't exist\n",fn); */
		    }else{
			dcell *avgpsfi=dcellread("%s",fn);
			dcelladd(&avgpsf, 1, avgpsfi, wtxi);
			dcellfree(avgpsfi);
			wtsum+=wtxi;
			
			snprintf(fn,PATH_MAX,"%s/neaspec/neaspec_seed%d_sa%d_x%g_y%g",
				 dirstart, seed, msa, thx, thy);
			dcell *neaspeci=dcellread("%s",fn);
			dcelladd(&neaspec, 1, neaspeci, wtxi);
			dcellfree(neaspeci);
		    }
		}
	    }
	    if(wtsum<0.01){
		warning("PISTAT is not available for (%g,%g) msa=%d\n",thetax,thetay,msa);
	    }
	    dcellscale(neaspec, 1./wtsum);
	    dcellscale(avgpsf, 1./wtsum);
	    dmat *scale=NULL;
	    if(parms->skyc.bspstrehl){
		scale=dnew(nsa,nwvl);
		dmat *gx=dnew(1,1); gx->p[0]=thxnorm;
		dmat *gy=dnew(1,1); gy->p[0]=thynorm;
		if(nsa!=avgpsf->nx || nwvl!=avgpsf->ny){
		    error("Mismatch: nsa=%d, nwvl=%d, avgpsf->nx=%ld, avgpsf->ny=%ld\n",
			  nsa, nwvl, avgpsf->nx, avgpsf->ny);
		}
		for(int ic=0; ic<nsa*nwvl; ic++){
		    dmat *val=dbspline_eval(simu->bspstrehl[ipowfs][ic],
					    simu->bspstrehlxy,simu->bspstrehlxy,
					    gx, gy);
		    double ratio=val->p[0]/avgpsf->p[ic]->p[0];
		    /*info("strehl: bilinear: %g, cubic: %g\n", avgpsf->p[ic]->p[0],val->p[0]); */
		    if(ratio<0){
			warning("Ratio=%g is less than zero.\n", ratio);
			scale->p[ic]=1;
		    }else{
			dscale(avgpsf->p[ic], ratio);
			scale->p[ic]=ratio;
		    }
		    dfree(val);
		}
		dfree(gx);
		dfree(gy);
	    }

	    stari->pistat[ipowfs].psf=avgpsf;/*PSF is in corner. */
	    stari->pistat[ipowfs].neaspec=dcellnew(nsa*2, 1);
	    for(int ig=0; ig<nsa*2; ig++){
		dmat *tmp=0;
		for(int iwvl=0; iwvl<nwvl; iwvl++){
		    dadd(&tmp, 0, neaspec->p[ig+nsa*2*iwvl], parms->skyc.wvlwt->p[iwvl]);
		}
		stari->pistat[ipowfs].neaspec->p[ig]=dinterp1(simu->neaspec_dtrats, tmp, parms->skyc.dtrats, 0);
		dfree(tmp);
	    }
	    dcellfree(neaspec);
	    stari->pistat[ipowfs].scale=scale;
	    {/* skip stars with large PSF.*/
		int size=INT_MAX;
		for(int ic=0; ic<avgpsf->nx*avgpsf->ny; ic++){
		    int size0=dfwhm(avgpsf->p[ic]);
		    if(size0<size) size=size0;
		}
		if(size>6){
		    stari->use[ipowfs]=-1;
		}
	    }
	    if(parms->skyc.dbg){
		writebin(avgpsf, "%s/avgpsf_star%d_ipowfs%d_psf",dirsetup,istar,ipowfs);
		writebin(stari->pistat[ipowfs].neaspec, "%s/pistat_star%d_ipowfs%d_neaspec",dirsetup,istar,ipowfs);
	    }
	}
    }
}