int main(){ int N=4; dmat *A=dnew(N,N); dcell *B=cellnew(2,2); B->p[0]=dnew(N,N); B->p[2]=dnew(N,N); rand_t rstat; seed_rand(&rstat, 1); drandn(A, 1, &rstat); drandn(B->p[0], 1, &rstat); drandn(B->p[2], 1, &rstat); A->header=strdup("dx=1/64\ndy=1/64\nLong=kaflasdjfl ksflksjlfjasdflkj asldfj als fals fl asfjalsdf jalsf djasldf jal fsalfkjasdflkj asldfkj asldf \nadf\nwvf=1.e-4"); writebin(A, "A.bin"); writebin(A, "A.fits"); writebin(A, "A.fits.gz"); writebin(B, "B.bin"); writebin(B, "B.fits"); dmat *C=dread("A.fits"); writebin(C, "C.fits"); dcell *D=dcellread("B.fits"); writebin(D, "D.fits"); dcell *E=dcellread("A.fits"); writebin(E, "E.fits"); writebin(E, "E.fits.gz"); }
/** * Initialize client state. */ int init_client_state() { client.host = NULL; client.client = NULL; client.state = SVCECLIENT_STATE_DISCONNECTED; client.input_buffer_size = 1024*1024; /* or 1<<20? */ client.input_buffer = (char*)malloc(client.input_buffer_size); client.input_queue = dlist_new(); client.input_error = 0; mutex_create(&client.input_lock); thread_create(&client.input_thread, input_thread, NULL); mutex_create(&client.network_lock); client.server_info = NULL; client.peers = NULL; client.peers_size = 0; client.my_id = -1; client.server_host_name = dnew(); client.server_host_addr = dnew(); client.server_host_port = 0; return 0; }
static void test_cov(){/*not good */ rand_t rstat; int seed=4; double r0=0.2; double dx=1./64; long N=1+1024; long nx=N; long ny=N; long nframe=1; seed_rand(&rstat, seed); map_t *atm=mapnew(nx, ny, dx,dx, NULL); cmat *atmhat=cnew((N+1)*3,(N+1)*3); dmat *atmhattot=dnew((N+1)*3,(N+1)*3); //cfft2plan(atmhat,-1); //cfft2plan(atmhat, 1); dset((dmat*)atm,1); cembedd(atmhat, (dmat*)atm, 0); cfft2(atmhat, -1); cabs22d(&atmhattot, 1, atmhat, 1); ccpd(&atmhat, atmhattot); cfft2i(atmhat, 1); cfftshift(atmhat); dmat *denom=dnew((N+1)*3,(N+1)*3); dmat *cov=dnew((N+1)*3,(N+1)*3); creal2d(&denom, 0, atmhat, 1); writebin(denom, "denom.bin"); dzero(atmhattot); for(long i=0; i<nframe; i++){ info("%ld of %ld\n", i, nframe); for(long j=0; j<nx*ny; j++){ atm->p[j]=randn(&rstat); } fractal_do((dmat*)atm, dx, r0,L0,ninit); /*mapwrite(atm, "atm_%ld.bin", i); */ cembedd(atmhat, (dmat*)atm, 0); cfft2(atmhat, -1); cabs22d(&atmhattot, 1, atmhat, 1); if(i==0 || (i+1)%10==0){ dscale(atmhattot, 1./(i+1)); ccpd(&atmhat, atmhattot); writebin(atmhattot, "atm_psf_%ld.bin",i+1); cfft2i(atmhat, 1); cfftshift(atmhat); creal2d(&cov, 0, atmhat, 1); for(long k=0; k<cov->nx*cov->ny; k++){ cov->p[k]/=denom->p[k]; } writebin(cov, "atm_cov_%ld.bin",i+1); } } }
/** test type I/II filter with ideal measurement to make sure it is implemented correctly. */ dmat* servo_test(dmat *input, double dt, int dtrat, dmat *sigma2n, dmat *gain){ if(input->ny==1){/*single mode. each column is for a mode.*/ input->ny=input->nx; input->nx=1; } int nmod=input->nx; PDMAT(input,pinput); dmat *merr=dnew(nmod,1); dcell *mreal=cellnew(1,1); dmat *mres=dnew(nmod,input->ny); dmat *sigman=NULL; if(dnorm(sigma2n)>0){ sigman=dchol(sigma2n); } dcell *meas=cellnew(1,1); dmat *noise=dnew(nmod, 1); SERVO_T *st2t=servo_new(NULL, NULL, 0, dt*dtrat, gain); rand_t rstat; seed_rand(&rstat, 1); PDMAT(mres,pmres); /*two step delay is ensured with the order of using, copy, acc*/ for(int istep=0; istep<input->ny; istep++){ memcpy(merr->p, pinput[istep], nmod*sizeof(double)); dadd(&merr, 1, mreal->p[0], -1); memcpy(pmres[istep],merr->p,sizeof(double)*nmod); if(istep % dtrat == 0){ dzero(meas->p[0]); } dadd(&meas->p[0], 1, merr, 1);/*average the error. */ dcellcp(&mreal, st2t->mint->p[0]); if((istep+1) % dtrat == 0){ if(dtrat!=1) dscale(meas->p[0], 1./dtrat); if(sigman){ drandn(noise, 1, &rstat); if(sigman->nx>0){ dmm(&meas->p[0], 1, sigman, noise, "nn", 1); }else{ dadd(&meas->p[0], 1, noise, sigman->p[0]); } } servo_filter(st2t, meas); } } dfree(sigman); dfree(merr); dcellfree(mreal); dcellfree(meas); servo_free(st2t); return mres; }
/** Compute Signal level */ static void setup_star_siglev(const PARMS_S *parms, STAR_S *star, int nstar){ const long npowfs=parms->maos.npowfs; const long nwvl=parms->maos.nwvl; const double r2=pow(parms->skyc.patfov/206265./2.,2); dmat* rnefs=parms->skyc.rnefs; for(int istar=0; istar<nstar; istar++){ star[istar].siglev=dcellnew(npowfs, 1); star[istar].bkgrnd=dnew(npowfs,1); star[istar].siglevtot=dnew(npowfs,1); /*Normalized angular distance */ double th2=(pow(star[istar].thetax,2)+pow(star[istar].thetay,2))/r2; /*Field dependent error: nm^2=nma^2+nmb^2*theta_norm^2; */ double imperrnm=sqrt(pow(parms->skyc.imperrnm,2)+th2*pow(parms->skyc.imperrnmb,2)); for(long ipowfs=0; ipowfs<npowfs; ipowfs++){ star[istar].siglev->p[ipowfs]=dnew(nwvl,1); int iscircle=parms->maos.nsa[ipowfs]<=4?1:0; photon_flux(&parms->skyc.zb, star[istar].siglev->p[ipowfs]->p, &star[istar].siglevtot->p[ipowfs], &star[istar].bkgrnd->p[ipowfs], NULL, NULL, parms->maos.nwvl, parms->maos.wvl, star[istar].mags->p, parms->maos.dxsa[ipowfs], iscircle, parms->skyc.pixtheta[ipowfs], parms->maos.dt, parms->maos.za, NULL, imperrnm, parms->skyc.telthruput, parms->skyc.qe, IND(rnefs,parms->skyc.ndtrat-1,ipowfs)); if(parms->skyc.verbose && ipowfs==npowfs-1){ info2("star %d at (%5.1f %5.1f)",istar, star[istar].thetax*206265,star[istar].thetay*206265); info2(" bkgrnd=%5.2f, pixtheta=%4.1fmas mag=[", star[istar].bkgrnd->p[ipowfs],parms->skyc.pixtheta[ipowfs]*206265000); for(int iwvl=0; iwvl<parms->maos.nwvl; iwvl++){ info2("%5.2f ", star[istar].mags->p[iwvl]); } info2("] siglev=["); for(int iwvl=0; iwvl<parms->maos.nwvl; iwvl++){ info2("%6.1f ", star[istar].siglev->p[ipowfs]->p[iwvl]); } info2("]\n"); } } } }
void setup_recon_fit(RECON_T *recon, const PARMS_T *parms){ TIC;tic; if(!parms->sim.idealfit){ /*In idealfit, xloc has high sampling. We avoid HXF. */ setup_recon_HXF(recon,parms); } /*copy over fitwt since we need a dmat */ int nfit=parms->fit.nfit; recon->fitwt=dnew(nfit,1); dcp(&recon->fitwt,parms->fit.wt); /*always assemble fit matrix, faster if many directions */ if(parms->fit.assemble){ setup_recon_fit_matrix(recon,parms); } toc2("Generating fit matrix "); /*Fall back function method if FR.M is NULL (!HXF<-idealfit) */ if(!recon->FR.M){ recon->FR.Mfun = FitR; recon->FR.Mdata = recon; } /*Fall back function method if FL.M is NULL */ if(!recon->FL.M){ recon->FL.Mfun = FitL; recon->FL.Mdata = recon; } recon->FL.alg = parms->fit.alg; recon->FL.bgs = parms->fit.bgs; recon->FL.warm = parms->recon.warm_restart; recon->FL.maxit = parms->fit.maxit; }
/** Convert Closed loop residual PSD back to OL psd using rejection transfer function: PSD_OL=(PSD_CL-sigma2n/F_nyquist)/Hrej; */ dmat *servo_rej2ol(const dmat *psdcl, double dt, long dtrat, double gain, double sigma2n){ SERVO_CALC_T st={0}; servo_calc_init(&st, psdcl, dt, dtrat); const dmat *nu=st.nu; const dmat *psd=st.psd; dmat *psdol=dnew(psd->nx, psd->ny+1); double psdn=sigma2n*(dt*dtrat*2); cadd(&st.Hol, 0, st.Hsys, gain); for(int i=0; i<nu->nx; i++){ dcomplex Hol=st.Hol->p[i]; dcomplex Hrej=1./(1.+Hol); double normHrej=Hrej*conj(Hrej); //dcomplex Hcl=Hol*Hrej; //dcomplex Hwfs=st.Hwfs->p[i]; //dcomplex Hn=Hcl/Hwfs; //double normHn=Hn*conj(Hn); IND(psdol, i, 0)=nu->p[i];//frequency. for(int icol=0; icol<psd->ny; icol++){ IND(psdol, i, icol+1)=IND(psd, i, icol)/(normHrej)-psdn; if(IND(psdol, i, icol+1)<0){ IND(psdol, i, icol+1)=0; } } } servo_calc_free(&st); return psdol; }
dstring* dfromc(int chr) { dstring* s = dnew(); s->data[0] = chr; s->len = 1; put_z(s); return s; }
/** Estimate wavefront error propagated from measurement error. pgm is the reconstructor. ineam is the error inverse. trace(Mcc*(pgm*neam*pgm')) */ static dmat *calc_recon_error(const dmat *pgm, /**<[in] the reconstructor*/ const dmat *neam,/**<[in] the inverse of error covariance matrix*/ const dmat *mcc /**<[in] NGS mode covariance matrix.*/ ){ dmat *psp=NULL; dmat *tmp=NULL; dcp(&tmp, pgm); dmuldiag(tmp, neam); dmm(&psp, 0, tmp, pgm, "nt", 1); PDMAT(psp,ppsp); PDMAT(mcc,pmcc); /*It is right for both ix, iy to stop at ib.*/ double all[mcc->nx]; for(int ib=0; ib<mcc->ny; ib++){ all[ib]=0; for(int iy=0; iy<=ib; iy++){ for(int ix=0; ix<=ib; ix++){ all[ib]+=ppsp[iy][ix]*pmcc[iy][ix]; } } } dfree(psp); dmat *res=dnew(3,1); res->p[0]=all[5];//total error res->p[1]=all[1];//total TT error if(mcc->nx>5){ res->p[2]=all[5]-all[4];//focus alone if(res->p[2]<0){ res->p[2]=0;//due to coupling, this may be negative. } } return res; }
static void test_part(){/**Compute the covariance of 4 points with various separation.*/ rand_t rstat; int seed=4; double r0=0.2; double dx=1./64.; long N=1+2; long ofx=0; long ofy=0; long nx=N; long ny=N; long nframe=1000000; seed_rand(&rstat, seed); map_t *atm=mapnew(nx, ny, dx,dx, NULL); dmat *vec=dnew(4,1); dmat *cov=NULL; dmat* pp=(dmat*)atm; for(long i=0; i<nframe; i++){ info("%ld of %ld\n", i, nframe); for(long j=0; j<nx*ny; j++){ atm->p[j]=randn(&rstat); } fractal_do((dmat*)atm, dx, r0,L0,ninit); vec->p[0]=IND(pp,ofx+0,ofy+0); vec->p[1]=IND(pp,ofx+1,ofy+0); vec->p[2]=IND(pp,ofx+0,ofy+1); vec->p[3]=IND(pp,ofx+1,ofy+1); dmm(&cov, 1, vec, vec, "nt", 1); } dscale(cov, 1./nframe); writebin(cov,"cov.bin"); }
dstring* dsub(const dstring* a, dstrlen_t start, dstrlen_t length) { if (start > a->len) { return dnew(); } else if (start+length > a->len) { length = a->len - start; } return dfrommem(a->data + start, length); }
int client(const char *hostname, int port, int nmin, int nmax, int nstep, int nrep){ int sock=connect_port(hostname, port, 0, 1); if(sock<0 || stwriteint(sock, nstep) || stwriteint(sock, nmin) || stwriteint(sock, nmax) || stwriteint(sock, nrep)) { warning("Unable to connecto to %s\n", hostname); close(sock); return 1; } buf1=(char*)malloc(nmax*nstep); for(int i=0;i<10;i++){//warm up stwrite(sock, buf1, nmax); stread(sock, buf1, 64); usleep(500); } double tim1, tim2, tim3; int nlen=(nmax-nmin+nstep)/nstep; dmat *timing=dnew(nrep, nlen); dmat *timing2=dnew(nrep, nlen); int ilen=-1; for(int len=nmin; len<=nmax; len+=nstep){ ilen++; info("len=%d\n", len); for(int irep=0; irep<nrep; irep++){ if(irep%800==0){ info("irep=%d of %d\n", irep, nrep); } usleep(500); tim1=myclockd(); stwrite(sock, buf1, len); tim2=myclockd(); stread(sock, buf1, 64); tim3=myclockd(); timing->p[irep+ilen*nrep]=tim3-tim1; timing2->p[irep+ilen*nrep]=tim2-tim1; } } close(sock); writebin(timing, "pix_timing_%s_%d_%d_%d", HOST, nmin, nmax, nstep); writebin(timing2, "pix_timing2_%s_%d_%d_%d", HOST, nmin, nmax, nstep); dbg("done\n"); return 0; }
/** Allocate a new array of the same type */ void *cellnew2(const void *A_){ cell *A=(cell*)A_; if(!A_){ return 0; }else if(iscell(A)){ return cellnew(A->nx, A->ny); }else if(A->id==M_DBL){ return dnew(A->nx, A->ny); }else{ error("Invalid type: id=%u\n", A->id); return 0; } }
/** Wrap of psd1d to put the frequency along the first column. */ dmat *psd1dt(const dmat *v, long nseg, double dt){ dmat *psd=psd1d(v, nseg); dmat *psd2=dnew(psd->nx, psd->ny+1); int N=(psd->nx-1)*2; double df=1./(N*dt); for(int i=0; i<psd->nx; i++){ psd2->p[i]=df*i; } dscale(psd, 1./df);//divide so the value is point, not integrated in a bin. memcpy(psd2->p+psd2->nx, psd->p, psd->nx*psd->ny*sizeof(double)); dfree(psd); return psd2; }
dstring* dlist_joinc(const dstrlist* list, int c) { dstrnode* node = list->front; dstring* s = dnew(); while(node) { dcat(s, node->string); node = node->next; if (node) { dcatc(s, c); } } return s; }
dstring* dlist_join(const dstrlist* list, const dstring* glue) { dstrnode* node = list->front; dstring* s = dnew(); while(node) { dcat(s, node->string); node = node->next; if (node) { dcat(s, glue); } } return s; }
/** Add two PSDs that doesn't have the same frequency. the first column of each dmat is the frequency nu, and the second column is PSD. Bug discovered on 2013-03-24:only psd2 was added to to psd.*/ static dmat *add_psd_nomatch(const dmat *psd1,const dmat *psd2){ dmat *nu1=dsub(psd1,0,psd1->nx,0,1); dmat *p2ynew=dinterp1(psd2, 0, nu1, 1e-40); dmat *psd=dnew(nu1->nx,2); double *py=psd->p+psd->nx; const double *p1y=psd1->p+psd1->nx; for(long i=0; i<psd->nx; i++){ psd->p[i]=nu1->p[i]; py[i]=p1y[i]+p2ynew->p[i]; } dfree(nu1); dfree(p2ynew); return psd; }
/** Update servo parameters */ void servo_update(SERVO_T *st, const dmat *ep){ dfree(st->ep); if(ep->nx!=3){//type I st->ep=ddup(ep); }else{//type II. convert data format st->ep=dnew(ep->nx, ep->ny); for(int i=0; i<ep->ny; i++){ st->ep->p[i*3]=ep->p[i*3]; double a=ep->p[1+i*3]; double T=ep->p[2+i*3]; st->ep->p[1+i*3]=exp(-st->dt/(a*T)); st->ep->p[2+i*3]=exp(-st->dt/T); } } }
dstring* dlist_joincs(const dstrlist* list, const char* glue) { dstrnode* node = list->front; dstring* s = dnew(); int len = strlen(glue); while(node) { dcat(s, node->string); node = node->next; if (node) { dcatmem(s, glue, len); } } return s; }
/** Convert PSD into time series.*/ dmat* psd2time(const dmat *psdin, rand_t *rstat, double dt, int nstepin){ if(!psdin){ error("psdin cannot be null\n"); } long nstep=nextpow2(nstepin); double df=1./(dt*nstep); dmat *fs=dlinspace(0, df, nstep); dmat *psd=NULL; if(psdin->ny==1){//[alpha, beta, fmin, fmax] discribes power law with cut on/off freq. psd=dnew(nstep, 1); double alpha=psdin->p[0]; double beta=psdin->p[1]; long i0=1, imax=nstep; if(psdin->nx>2){ i0=(long)round(psdin->p[2]/df); if(i0<1) i0=1; } if(psdin->nx>3){ imax=(long)round(psdin->p[3]/df); } info("fmin=%g, fmax=%g, df=%g, i0=%ld, imax=%ld\n", psdin->p[2], psdin->p[3], df, i0, imax); for(long i=i0; i<imax; i++){ psd->p[i]=beta*pow(i*df, alpha); } }else if(psdin->ny==2){ if(psdin->nx<2){ error("Invalid PSD\n"); } psd=dinterp1(psdin, 0, fs, 1e-40); psd->p[0]=0;/*disable pistion. */ }else{ error("psdin is invalid format.\n"); } cmat *wshat=cnew(nstep, 1); //cfft2plan(wshat, -1); for(long i=0; i<nstep; i++){ wshat->p[i]=sqrt(psd->p[i]*df)*COMPLEX(randn(rstat), randn(rstat)); } cfft2(wshat, -1); dmat *out=NULL; creal2d(&out, 0, wshat, 1); cfree(wshat); dfree(psd); dfree(fs); dresize(out, nstepin, 1); return out; }
/** Compute Modal to gradient operator using average gradients. Similar to Z tilt since the mode is low order */ static void setup_star_g(const PARMS_S *parms, POWFS_S *powfs, STAR_S *star, int nstar){ const long npowfs=parms->maos.npowfs; const double hc=parms->maos.hc; const double hs=parms->maos.hs; const double scale=pow(1.-hc/hs, -2); const double scale1=1.-scale; const int nmod=parms->maos.nmod; assert(nmod>=5 && nmod<=6); for(int istar=0; istar<nstar; istar++){ star[istar].g=dcellnew(npowfs, 1); for(int ipowfs=0; ipowfs<npowfs; ipowfs++){ const long nsa=parms->maos.nsa[ipowfs]; const double thetax=star[istar].thetax; const double thetay=star[istar].thetay; star[istar].g->p[ipowfs]=dnew(nsa*2, nmod); dmat* pg=star[istar].g->p[ipowfs]; for(long isa=0; isa<nsa; isa++){ const double xm=powfs[ipowfs].locxamp[isa];/*dot of x with amp. */ const double ym=powfs[ipowfs].locyamp[isa]; IND(pg,isa,0) = 1.; IND(pg,isa+nsa,1) = 1.; if(parms->maos.ahstfocus){/*This mode has no global focus*/ IND(pg,isa,2) = ( - 2*thetax*hc*scale); IND(pg,isa+nsa,2) = ( - 2*thetay*hc*scale); }else{ IND(pg,isa,2) = (scale1*2*xm - 2*thetax*hc*scale); IND(pg,isa+nsa,2) = (scale1*2*ym - 2*thetay*hc*scale); } IND(pg,isa,3) = (scale1*2*xm - 2*thetax*hc*scale); IND(pg,isa+nsa,3) = (-scale1*2*ym+ 2*thetay*hc*scale); IND(pg,isa,4) = (scale1*ym - thetay*hc*scale); IND(pg,isa+nsa,4) = (scale1*xm - thetax*hc*scale); if(nmod>5){/*include a defocus term*/ IND(pg,isa,5) = xm*2; IND(pg,isa+nsa,5) = ym*2; } } } if(parms->skyc.dbg){ writebin(star[istar].g,"%s/star%d_g",dirsetup,istar); } } }
/* static int test_fft_speed_small(){ int nis=128; int *is=mycalloc(nis,int); dmat *tim=dnew(nis,1); for(int ii=0; ii<nis; ii++){ is[ii]=ii+1; } ccell *ac=cellnew(nis,1); rand_t stat; seed_rand(&stat,1); for(int ii=0; ii<nis; ii++){ ac->p[ii]=cnew(is[ii],is[ii]); //cfft2plan(ac->p[ii],-1); crandn(ac->p[ii],20,&stat); } TIC; for(int ii=0; ii<nis; ii++){ info2("size %4d: ",is[ii]); tic; for(int i=0; i<1000; i++){ cfft2(ac->p[ii],-1); } toc2("fft"); tim->p[ii]=toc3; } writebin(tim,"fft_timing"); } static void test_fft_speed(){ int nis=2048; int *is=mycalloc(nis,int); dmat *tim=dnew(nis,1); for(int ii=0; ii<nis; ii++){ is[ii]=(ii+1)*2; } ccell *ac=cellnew(nis,1); rand_t stat; seed_rand(&stat,1); TIC; for(int ii=0; ii<nis; ii++){ info2("size %4d: ",is[ii]); tic; ac->p[ii]=cnew(is[ii],is[ii]); //cfft2plan(ac->p[ii],-1); crandn(ac->p[ii],20,&stat); toc("plan"); } toc("plan"); for(int ii=0; ii<nis; ii++){ info2("size %4d: ",is[ii]); tic; int nrepeat; if(is[ii]<300) nrepeat=100; else if(is[ii]<1000) nrepeat=10; else nrepeat=1; for(int i=0; i<nrepeat; i++){ cfft2(ac->p[ii],-1); } toc2("fft"); tim->p[ii]=toc3/nrepeat; } writebin(tim,"fft_timing"); }*/ static void test_fft_special(){ int nis=2; int *is=mycalloc(nis,int); dmat *tim=dnew(nis,1); is[0]=3824; is[1]=4096; ccell *ac=ccellnew(nis,1); rand_t rstat; seed_rand(&rstat,1); TIC; for(int ii=0; ii<nis; ii++){ info2("size %4d: ",is[ii]); tic; ac->p[ii]=cnew(is[ii],is[ii]); //cfft2plan(ac->p[ii],-1); //cfft2partialplan(ac->p[ii],512,-1); crandn(ac->p[ii],20,&rstat); toc("plan"); } for(int ii=0; ii<nis; ii++){ info2("size %4d: ",is[ii]); tic; int nrepeat; if(is[ii]<300) nrepeat=100; else if(is[ii]<1000) nrepeat=10; else nrepeat=4; for(int i=0; i<nrepeat; i++){ cfft2(ac->p[ii],-1); } toc2("fft"); for(int i=0; i<nrepeat; i++){ cfft2partial(ac->p[ii],512,-1); } toc2("fft2partial"); tim->p[ii]=toc3/nrepeat; } writebin(tim,"fft_timing"); }
int main(int argc, char *argv[]) { if(argc<7) { info("Usage: %s loc.bin amp.bin cov.bin ncomp pttr wvl1 wvl2 ...\n", argv[0]); exit(0); } enum { P_EXE, P_LOC, P_AMP, P_COV, P_NCOMP, P_PTTR, P_WVL }; loc_t *loc=locread("%s",argv[P_LOC]); dmat *amp=NULL; if(strcmp(argv[P_AMP],"NULL")) { amp=dread("%s",argv[P_AMP]); } else { amp=dnew(loc->nloc,1); dset(amp,1); } dmat *cov=dread("%s",argv[P_COV]); long ncomp=strtol(argv[P_NCOMP], NULL, 10); long pttr=strtol(argv[P_PTTR], NULL, 10); cmat *otf=otf=cnew(ncomp, ncomp); dmat *psf=NULL; for(int iwvl=0; iwvl<argc-P_WVL; iwvl++) { double wvl=strtod(argv[iwvl+P_WVL], NULL); double dtheta=wvl/(ncomp*loc->dx); genotf(&otf, loc, amp, NULL, NULL, 0, wvl, dtheta, cov, 0, 0, ncomp, ncomp, 1, pttr); writebin(otf, "%s_otf_%g.bin", argv[P_COV], wvl); cfftshift(otf); cfft2i(otf, 1); cfftshift(otf); creal2d(&psf, 0, otf, 1); writebin(psf, "%s_psf_%g.bin", argv[P_COV], wvl); } cfree(otf); dfree(psf); dfree(cov); dfree(amp); locfree(loc); }
static void test_ints(){ rand_t init; seed_rand(&init,1); const int nwfs=6; lrand(&init);/*atm */ rand_t wfs_rand[nwfs]; for(int iwfs=0; iwfs<nwfs; iwfs++){ seed_rand(wfs_rand+iwfs,lrand(&init)); } dcell *mtche=dcellread("powfs0_mtche.bin"); int nsim=500; int nsa=2582; dmat *nea=dnew(nsim,nsa*2); double(*pnea)[nsim]=(void*)nea->p; double rne=3; double bkgrnd=0; double siglev=1000; for(int iwfs=0; iwfs<nwfs; iwfs++){ for(int isim=0; isim<nsim; isim++){ dbg("iwfs %d isim=%d\n",iwfs,isim); /*dcell *ints=dcellread("ints_%d_wfs%d.bin",isim,iwfs); */ dcell *ints=dcellread("ints_%d_wfs%d.bin",isim,iwfs); /*dcell *i0=dcellread("powfs0_i0.bin"); */ dmat *im=NULL, *imy=NULL; double gnf[2], gny[2]; for(int isa=0; isa<nsa; isa++){ dcp(&im,ints->p[isa]); dscale(im,siglev); gnf[0]=0; gnf[1]=0; dmulvec(gnf, mtche->p[isa], im->p,1.); gny[0]=0; gny[1]=0; dcp(&imy, im); addnoise(imy, &wfs_rand[iwfs], bkgrnd, bkgrnd, 0,0,rne); dmulvec(gny, mtche->p[isa], imy->p,1.); P(pnea,isim,isa)=gny[0]-gnf[0]; P(pnea,isim,isa+nsa)=gny[1]-gnf[1]; } } writebin(nea,"test_sanea_wfs%d.bin",iwfs); } }
dmat *psd1d(const dmat *v, /**<[in] The data sequence*/ long nseg /**<[in] Number of overlapping segments*/ ){ long nx; long ncol; if(v->nx==1){ nx=v->ny; ncol=1; }else{ nx=v->nx; ncol=v->ny; } if(nseg<=1) nseg=1; const int lseg2=nx/(nseg+1); const int lseg=lseg2*2; dmat *psd=dnew(lseg2+1, ncol); cmat *hat=cnew(lseg, 1); //cfft2plan(hat, -1); for(long icol=0; icol<ncol; icol++){ double *ppsd=psd->p+icol*(lseg2+1); for(int iseg=0; iseg<nseg; iseg++){ double* p=v->p+icol*nx+iseg*lseg2; for(int ix=0; ix<lseg; ix++){ hat->p[ix]=p[ix]*W_J(ix, lseg2); } cfft2(hat, -1); ppsd[0]+=cabs2(hat->p[0]); for(int ix=1; ix<lseg2; ix++){ ppsd[ix]+=cabs2(hat->p[ix])+cabs2(hat->p[lseg-ix]); } ppsd[lseg2]+=cabs2(hat->p[lseg2]); } } double sumwt=0; for(int ix=0; ix<lseg; ix++){ sumwt+=pow(W_J(ix, lseg2), 2); } sumwt*=lseg*nseg; dscale(psd, 1./sumwt); cfree(hat); return psd; }
int main(int argc, char* argv[]){ /*dsp *RLMc1=dspread("RLMc_old.bin"); */ if(argc!=2){ error("Need 1 argument\n"); } dspcell *RLM=dspcellread("%s",argv[1]); dsp *RLMc=dspcell2sp(RLM); tic;info2("chol ..."); spchol *R1=chol_factorize(RLMc); toc("done"); rand_t rstat; seed_rand(&rstat,1); dmat *y=dnew(RLMc->m, 1); drandn(y, 1, &rstat); dmat *x=NULL, *x2=NULL, *x3=NULL; chol_convert(R1, 1); tic; chol_solve(&x, R1, y); toc("cholmod");tic; chol_solve(&x, R1, y); toc("cholmod");tic; chol_solve_upper(&x3, R1, y); toc("upper");tic; chol_solve_upper(&x3, R1, y); toc("upper");tic; chol_solve_lower(&x2, R1,y); toc("lower");tic; chol_solve_lower(&x2, R1,y); toc("lower");tic; chol_solve(&x, R1, y); toc("cholmod");tic; chol_solve(&x, R1, y); toc("cholmod");tic; writebin(y,"y"); writebin(x,"x"); writebin(x2,"x2"); writebin(x3,"x3"); chol_free(R1); dspfree(RLMc); dspcellfree(RLM); }
/** Optimize the type II servo gains by balancing errors due to noise and signal propagation. Written: 2010-06-11 Tested OK: 2010-06-11 2011-01-17: The optimization process is quite slow, but the result is only dependent on the sigma2n and fs. psdin does not change during the simulation. Built a lookup table in skyc using various sigma2n and interpolate to get ress, resn, and gain. 2012-03-28: Cleaned up this routine. groupped similar calculations together. Change g2=a from g=sqrt(a) 2013-06-27: The maximum gain should not be limited to 0.5 beause it is later scaled by sqrt(a); sigma2n is a dmat array of all wanted sigma2n. Returns a cellarray of a dmat of [g0, a, T, res_sig, res_n] */ dcell* servo_optim(const dmat *psdin, double dt, long dtrat, double pmargin, const dmat* sigma2n, int servo_type){ /*The upper end must be nyquist freq so that noise transfer can be computed. But we need to capture the turbulence PSD beyond nyquist freq, which are uncorrectable. */ SERVO_CALC_T st={0}; servo_calc_init(&st, psdin, dt, dtrat); st.type=servo_type; st.pmargin=pmargin; int ng=1; switch(servo_type){ case 1: ng=1;break; case 2: ng=3; break; default: error("Invalid servo_type=%d\n", servo_type); } dcell *gm=cellnew(sigma2n?sigma2n->nx:1, sigma2n?sigma2n->ny:1); double g0_step=1e-6; double g0_min=1e-6;/*the minimum gain allowed.*/ double g0_max=2.0; for(long ins=0; ins<gm->nx*gm->ny; ins++){ st.sigma2n=sigma2n?sigma2n->p[ins]:0; double g0=golden_section_search((golden_section_fun)servo_calc_do, &st, g0_min, g0_max, g0_step); servo_calc_do(&st, g0); gm->p[ins]=dnew(ng+2,1); gm->p[ins]->p[0]=st.g; if(servo_type==2){ gm->p[ins]->p[1]=st.a; gm->p[ins]->p[2]=st.T; } gm->p[ins]->p[ng]=st.res_sig; gm->p[ins]->p[ng+1]=st.res_n; /*info2("g0=%.1g, g2=%.1g, res_sig=%.1g, res_n=%.1g, tot=%.1g, gain_n=%.1g sigma2n=%.1g\n", g0, st.g, st.res_sig, st.res_n, st.res_n+st.res_sig, st.gain_n, st.sigma2n);*/ }/*for ins. */ servo_calc_free(&st); return gm; }
/** Add two PSDs. the first column of each dmat is the frequency nu, and the second column is PSD*/ dmat *add_psd(const dmat *psd1, const dmat *psd2){ if(psd1->nx!=psd2->nx){ //warning("The two PSDs have different length\n"); return add_psd_nomatch(psd1, psd2); } dmat *psd=dnew(psd1->nx,2); double *restrict pp=psd->p+psd->nx; const double *p1=psd1->p+psd1->nx; const double *p2=psd2->p+psd2->nx; for(long i=0; i<psd->nx; i++){ if(fabs(psd1->p[i]-psd2->p[i])>1.e-2){ warning("The two PSDs doesn't have the same freq."); dfree(psd); return add_psd_nomatch(psd1,psd2); /*todo: apply interp1 to interpolate the second PSD. */ } psd->p[i]=psd1->p[i]; pp[i]=p1[i]+p2[i]; } return psd; }
/** Initialize. al is additional latency */ SERVO_T *servo_new(dcell *merr, const dmat *ap, int al, double dt, const dmat *ep){ SERVO_T *st=calloc(1, sizeof(SERVO_T)); if(ap){ st->ap=ddup(ap); }else{ st->ap=dnew(2,1); st->ap->p[0]=1; } if(st->ap->nx<2){ dresize(st->ap, 2, 1);//2 element to ensure we keep integrator history. } st->mint=cellnew(st->ap->nx, 1); st->dt=dt; st->al=al; st->merrhist=cellnew(st->al+1, 1); servo_update(st, ep); if(merr && merr->nx!=0 && merr->ny!=0 && merr->p[0]){ servo_init(st, merr); } return st; }
/**Convert special PSD to temporal*/ dmat *psds2t(const dmat *psds, double vmean){ if(psds->nx!=1 || psds->ny>4){ error("psds needs to be 1 row and less than 4 cols\n"); } double alpha=psds->p[0];//power double beta=psds->p[1];//strength double alpha2=alpha+1; //n is -alpha double bfun=tgamma(0.5)*tgamma((-alpha-1)*0.5)/tgamma(-alpha*0.5); double beta2=beta*bfun*pow(vmean, -2-alpha); dmat *psdt=dnew(psds->nx, psds->ny); psdt->p[0]=alpha2; psdt->p[1]=beta2; if(psds->ny>2){ psdt->p[2]=psds->p[2]*vmean; } if(psds->ny>3){ psdt->p[3]=psds->p[3]*vmean; } return psdt; }