/** Release memory. */ void free_powfs(POWFS_S *powfs, const PARMS_S *parms){ const int npowfs=parms->maos.npowfs; for(int ipowfs=0; ipowfs<npowfs; ipowfs++){ for(int iwvl=0; iwvl<parms->maos.nwvl; iwvl++){ cfree(powfs[ipowfs].dtf[iwvl].U); cfree(powfs[ipowfs].dtf[iwvl].nominal); dspfree(powfs[ipowfs].dtf[iwvl].si); } free(powfs[ipowfs].dtf); locfree(powfs[ipowfs].loc); locfree(powfs[ipowfs].saloc); dfree(powfs[ipowfs].amp); free(powfs[ipowfs].locxamp); free(powfs[ipowfs].locyamp); } }
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); }
/** Setup the detector transfer functions. See maos/setup_powfs.c */ static void setup_powfs_dtf(POWFS_S *powfs, const PARMS_S* parms){ const int npowfs=parms->maos.npowfs; for(int ipowfs=0; ipowfs<npowfs; ipowfs++){ const int ncomp=parms->maos.ncomp[ipowfs]; const int ncomp2=ncomp>>1; const int embfac=parms->maos.embfac[ipowfs]; const int pixpsa=parms->skyc.pixpsa[ipowfs]; const double pixtheta=parms->skyc.pixtheta[ipowfs]; const double blur=parms->skyc.pixblur[ipowfs]*pixtheta; const double e0=exp(-2*M_PI*M_PI*blur*blur); const double dxsa=parms->maos.dxsa[ipowfs]; const double pixoffx=parms->skyc.pixoffx[ipowfs]; const double pixoffy=parms->skyc.pixoffy[ipowfs]; const double pxo=-(pixpsa/2-0.5+pixoffx)*pixtheta; const double pyo=-(pixpsa/2-0.5+pixoffy)*pixtheta; loc_t *loc_ccd=mksqloc(pixpsa, pixpsa, pixtheta, pixtheta, pxo, pyo); powfs[ipowfs].dtf=mycalloc(parms->maos.nwvl,DTF_S); for(int iwvl=0; iwvl<parms->maos.nwvl; iwvl++){ const double wvl=parms->maos.wvl[iwvl]; const double dtheta=wvl/(dxsa*embfac); const double pdtheta=pixtheta*pixtheta/(dtheta*dtheta); const double du=1./(dtheta*ncomp); const double du2=du*du; const double dupth=du*pixtheta; cmat *nominal=cnew(ncomp,ncomp); //cfft2plan(nominal,-1); //cfft2plan(nominal,1); cmat* pn=nominal; const double theta=0; const double ct=cos(theta); const double st=sin(theta); for(int iy=0; iy<ncomp; iy++){ int jy=iy-ncomp2; for(int ix=0; ix<ncomp; ix++){ int jx=ix-ncomp2; double ir=ct*jx+st*jy; double ia=-st*jx+ct*jy; IND(pn,ix,iy)=sinc(ir*dupth)*sinc(ia*dupth) *pow(e0,ir*ir*du2)*pow(e0,ia*ia*du2) *pdtheta; } } if(parms->skyc.fnpsf1[ipowfs]){ warning("powfs %d has additional otf to be multiplied\n", ipowfs); dcell *psf1c=dcellread("%s", parms->skyc.fnpsf1[ipowfs]); dmat *psf1=NULL; if(psf1c->nx == 1){ psf1=dref(psf1c->p[0]); }else if(psf1c->nx==parms->maos.nwvl){ psf1=dref(psf1c->p[iwvl]); }else{ error("skyc.fnpsf1 has wrong dimension\n"); } dcellfree(psf1c); if(psf1->ny!=2){ error("skyc.fnpsf1 has wrong dimension\n"); } dmat *psf1x=dnew_ref(psf1->nx, 1, psf1->p); dmat *psf1y=dnew_ref(psf1->nx, 1, psf1->p+psf1->nx); dmat *psf2x=dnew(ncomp*ncomp, 1); for(int iy=0; iy<ncomp; iy++){ int jy=iy-ncomp2; for(int ix=0; ix<ncomp; ix++){ int jx=ix-ncomp2; psf2x->p[ix+iy*ncomp]=sqrt(jx*jx+jy*jy)*dtheta; } } info("powfs %d, iwvl=%d, dtheta=%g\n", ipowfs, iwvl, dtheta*206265000); writebin(psf2x, "powfs%d_psf2x_%d", ipowfs,iwvl); dmat *psf2=dinterp1(psf1x, psf1y, psf2x, 0); normalize_sum(psf2->p, psf2->nx*psf2->ny, 1); psf2->nx=ncomp; psf2->ny=ncomp; writebin(psf2, "powfs%d_psf2_%d", ipowfs,iwvl); cmat *otf2=cnew(ncomp, ncomp); //cfft2plan(otf2, -1); ccpd(&otf2, psf2);//peak in center cfftshift(otf2);//peak in corner cfft2(otf2, -1); cfftshift(otf2);//peak in center writebin(otf2, "powfs%d_otf2_%d", ipowfs, iwvl); writebin(nominal, "powfs%d_dtf%d_nominal_0",ipowfs,iwvl); for(int i=0; i<ncomp*ncomp; i++){ nominal->p[i]*=otf2->p[i]; } writebin(nominal, "powfs%d_dtf%d_nominal_1",ipowfs,iwvl); dfree(psf1x); dfree(psf1y); dfree(psf2x); dfree(psf1); cfree(otf2); dfree(psf2); } cfftshift(nominal);//peak in corner cfft2(nominal,-1); cfftshift(nominal);//peak in center cfft2i(nominal,1); warning_once("double check nominal for off centered skyc.fnpsf1\n"); /*This nominal will multiply to OTF with peak in corner. But after inverse fft, peak will be in center*/ ccp(&powfs[ipowfs].dtf[iwvl].nominal, nominal); cfree(nominal); loc_t *loc_psf=mksqloc(ncomp, ncomp, dtheta, dtheta, -ncomp2*dtheta, -ncomp2*dtheta); powfs[ipowfs].dtf[iwvl].si=mkh(loc_psf,loc_ccd,0,0,1); locfree(loc_psf); if(parms->skyc.dbg){ writebin(powfs[ipowfs].dtf[iwvl].nominal, "%s/powfs%d_dtf%d_nominal",dirsetup,ipowfs,iwvl); writebin(powfs[ipowfs].dtf[iwvl].si, "%s/powfs%d_dtf%d_si",dirsetup,ipowfs,iwvl); } powfs[ipowfs].dtf[iwvl].U=cnew(ncomp,1); dcomplex *U=powfs[ipowfs].dtf[iwvl].U->p; for(int ix=0; ix<ncomp; ix++){ int jx=ix<ncomp2?ix:(ix-ncomp); U[ix]=COMPLEX(0, -2.*M_PI*jx*du); } }/*iwvl */ locfree(loc_ccd); }/*ipowfs */ }
static void test_accuracy(int argc, char **argv){ double displacex=0.01; double displacey=0.05; double scale=1.01;/*.414065; */ int wrap=0; double D=30; double D2=32; int save=1; if(argc>1){ scale=strtod(argv[1], 0); } if(argc>2){ displacex=strtod(argv[2], 0); } if(argc>3){ displacey=strtod(argv[3], 0); } if(argc>4){ wrap=strtol(argv[4], 0, 10); } if(argc>5){ D=strtod(argv[5], 0); } if(argc>6){ D2=strtod(argv[6], 0); } if(argc>7){ save=strtol(argv[7], 0, 10); } double dx=1/64.; double dsa=0.5; map_t *screen=mapnew(D2/dx, D2/dx, dx, dx, 0); dset((dmat*)screen, 1); for(long iy=0; iy<screen->ny; iy++){ for(long ix=0; ix<screen->nx; ix++){ screen->p[ix+iy*screen->nx]=sin((double)ix/screen->nx*2*M_PI)*sin((double)iy/screen->ny*2*M_PI); } } /*loc for the map */ loc_t *locin=mksqloc(screen->nx,screen->ny,dx,dx,screen->ox,screen->oy); //pts_t *pts=realloc(mkannloc(D, 0, 1./2.,0), sizeof(pts_t)); pts_t *pts=realloc(mksqloc_auto(D/dsa, D/dsa, dsa, dsa), sizeof(pts_t)); pts->dx=dx; pts->dy=dx; pts->nx=dsa/dx; pts->ny=pts->nx; loc_t *loc=pts2loc(pts); loc_create_map(locin); loc_create_stat(loc); loc_create_map(loc); locstat_t *locstat=loc->stat; map_t *screen2=mapnew2(locin->map); dset((dmat*)screen2, NAN); loc_embed(screen2, locin, screen->p); double *phi_pts, *phi_loc, *phi_stat; double *phi_loc2loc, *phi_h, *phi_cub, *phi_cub2, *phi_cubh; double cubic=0.3; int ii; info("displacex=%g, displacey=%g, scale=%g, wrap=%d\n", displacex, displacey,scale,wrap); double diff1, diff2,diff3,diff14,diff15; diff1=0; diff2=0; diff3=0; diff14=0; diff15=0; phi_pts=calloc(loc->nloc, sizeof(double)); phi_loc=calloc(loc->nloc, sizeof(double)); phi_stat=calloc(loc->nloc, sizeof(double)); phi_loc2loc=calloc(loc->nloc, sizeof(double)); map_t *map1=mapnew2(loc->map); prop_grid_map(screen, map1, -2, displacex, displacey, scale, wrap, 0,0); tic; prop_grid_map(screen, map1, 1, displacex, displacey, scale, wrap, 0,0); toc("map\t\t"); prop_grid_pts(screen, pts, phi_pts, -2, displacex, displacey, scale, wrap, 0,0); tic; prop_grid_pts(screen, pts, phi_pts, 1, displacex, displacey, scale, wrap, 0,0); toc("pts\t\t"); prop_grid_stat(screen, locstat, phi_stat, -2,displacex, displacey, scale, wrap, 0,0); tic; prop_grid_stat(screen, locstat, phi_stat , 1, displacex, displacey, scale, wrap, 0,0); toc("stat\t");tic; prop_grid(screen, loc, phi_loc, -2,displacex, displacey, scale, wrap, 0,0); tic; prop_grid(screen, loc, phi_loc, 1,displacex, displacey, scale, wrap, 0,0); toc("loc\t\t"); prop_nongrid(locin, screen->p,loc, phi_loc2loc, -2,displacex, displacey, scale,0,0); toc("nongrid\t"); tic; prop_nongrid(locin, screen->p,loc, phi_loc2loc, 1,displacex, displacey, scale,0,0); toc("nongrid\t"); phi_h=calloc(loc->nloc,sizeof(double)); tic; dsp *hfor=mkh(locin, loc, displacex, displacey, scale); toc("mkh\t\t\t"); dspmulvec(phi_h,hfor, screen->p, 'n', -2); tic; dspmulvec(phi_h,hfor, screen->p, 'n', 1); toc("mul h\t\t"); phi_cub=calloc(loc->nloc,sizeof(double)); phi_cub2=calloc(loc->nloc,sizeof(double)); double *phi_cub3=calloc(loc->nloc,sizeof(double)); double *phi_cub4=calloc(loc->nloc,sizeof(double)); phi_cubh=calloc(loc->nloc, sizeof(double)); prop_nongrid_cubic(locin,screen->p,loc,phi_cub,-2, displacex, displacey, scale, cubic,0,0); tic; prop_nongrid_cubic(locin,screen->p,loc,phi_cub,1, displacex, displacey, scale, cubic,0,0); toc("nongrid, cubic\t"); prop_grid_cubic(screen, loc, phi_cub2, -2,displacex, displacey, scale, cubic, 0,0); tic; prop_grid_cubic(screen, loc, phi_cub2, 1,displacex, displacey, scale, cubic, 0,0); toc("grid, cubic\t"); prop_grid_cubic(screen2, loc,phi_cub3, -2,displacex, displacey, scale, cubic, 0,0); tic; prop_grid_cubic(screen2, loc,phi_cub3, 1,displacex, displacey, scale, cubic, 0,0); toc("grid2, cubic\t"); prop_grid_stat_cubic(screen, locstat,phi_cub4, -2,displacex, displacey, scale, cubic, 0,0); tic; prop_grid_stat_cubic(screen, locstat,phi_cub4, 1,displacex, displacey, scale, cubic, 0,0); toc("grid 2stat, cubic\t"); dsp *hforcubic; tic; hforcubic=mkh_cubic(locin, loc, displacex, displacey, scale, cubic); toc("mkh cubic \t\t"); dspmulvec(phi_cubh, hforcubic,screen->p,'n',-2); tic; dspmulvec(phi_cubh, hforcubic,screen->p,'n',1); toc("cubic mul h\t\t"); double diffc12=0,diff45=0,diff46=0,diff47=0; for(ii=0; ii<loc->nloc; ii++){ diff1+=fabs(phi_loc[ii]-phi_pts[ii]); diff2+=fabs(phi_stat[ii]-phi_loc[ii]); diff3+=fabs(phi_stat[ii]-phi_pts[ii]); diff14+=fabs(phi_loc2loc[ii]-phi_pts[ii]); diff15+=fabs(phi_h[ii]-phi_pts[ii]); diff45+=fabs(phi_loc2loc[ii]-phi_h[ii]); diffc12+=fabs(phi_cub[ii]-phi_cubh[ii]); diff46+=fabs(phi_cub[ii]-phi_cub2[ii]); diff47+=fabs(phi_cub[ii]-phi_cub3[ii]); } info2("(pts-loc)=\t%g\n(loc-stat)=\t%g\n(stat-pts)=\t%g\n" "(loc2loc-pts)=\t%g\n(h-pts)=\t%g\n" "(loc2loc-h)=\t%g\n" "(cub:h-loc2loc)=\t%g\n" "(cub:map2loc-loc2loc)=\t%g\n" "(cub:locmap2loc-loc2loc=\t%g\n" ,diff1, diff2,diff3,diff14,diff15,diff45,diffc12, diff46, diff47); // exit(0); if(!save) return; mapwrite(screen2,"accphi_screen2"); mapwrite(screen,"accphi_screen"); locwrite((loc_t*)pts,"accphi_pts"); locwrite(loc,"accphi_loc"); locwrite(locin, "accphi_locin"); loc_create_map_npad(locin, 0, 0, 0); mapwrite(locin->map, "accphi_locin_map"); mapwrite(loc->map, "accphi_loc_map"); mapwrite(map1, "accphi_map2map.bin"); writedbl(phi_pts,loc->nloc,1,"accphi_pts1.bin"); writedbl(phi_loc,loc->nloc,1,"accphi_loc0.bin"); writedbl(phi_stat,loc->nloc,1,"accphi_stat.bin"); writedbl(phi_loc2loc,loc->nloc,1,"accphi_loc2loc.bin"); writedbl(phi_h,loc->nloc,1,"accphi_loc2h.bin"); writedbl(phi_cub,loc->nloc,1,"accphi_cub_loc2loc.bin"); writedbl(phi_cub2,loc->nloc,1,"accphi_cub_map2loc.bin"); writedbl(phi_cub3,loc->nloc,1,"accphi_cub_locmap2loc.bin"); writedbl(phi_cub4,loc->nloc,1,"accphi_cub_locmap2stat.bin"); writedbl(phi_cubh,loc->nloc,1,"accphi_cub_loc2h.bin"); info("saved\n"); writedbl(phi_pts,loc->nloc,1,"accphi_pts.bin"); writedbl(phi_cub,loc->nloc,1,"accphi_cub.bin"); writebin(hfor, "accphi_hfor"); writebin(hforcubic, "accphi_cub_hfor"); dspfree(hfor); dspfree(hforcubic); free(phi_loc); free(phi_stat); free(phi_loc2loc); free(phi_pts); free(phi_h); free(phi_cub); free(phi_cubh); cellfree(screen); locfree(locin); }
/** Returns the transpose of a ztilt gradient operator that converts the OPDs defined on xloc to subapertures defines on saloc. */ dsp * mkzt(loc_t* xloc, double *amp, loc_t *saloc, int saorc, double scale, double dispx, double dispy) { /*compute ztilt influence function from xloc to saloc saorc: SALOC is subaperture origin or center. 1: origin (lower left corner), 0: center. */ long nsa=saloc->nloc; double dsa=saloc->dx; double dx1=1./xloc->dx; double dx2=scale*dx1; double dy1=1./xloc->dy; double dy2=scale*dy1; loc_create_map(xloc); map_t *map=xloc->map; dispx=(dispx-map->ox+saorc*dsa*0.5*scale)*dx1; dispy=(dispy-map->oy+saorc*dsa*0.5*scale)*dy1; double dsa2=dsa*0.5*dx2; long nmax=(dsa2*2+2)*(dsa2*2+2); long *ind=mycalloc(nmax,long); loc_t *sloc=mycalloc(1,loc_t); sloc->dx=xloc->dx; sloc->dy=xloc->dy; sloc->locx=mycalloc(nmax,double); sloc->locy=mycalloc(nmax,double); double *amploc=NULL; if(amp) amploc=mycalloc(nmax,double); dsp*zax=dspnew(xloc->nloc,nsa,xloc->nloc); dsp*zay=dspnew(xloc->nloc,nsa,xloc->nloc); long xcount=0,ycount=0; spint *xpp=zax->p; spint *xpi=zax->i; double *xpx=zax->x; spint *ypp=zay->p; spint *ypi=zay->i; double *ypx=zay->x; const double *locx=xloc->locx; const double *locy=xloc->locy; double *slocx=sloc->locx; double *slocy=sloc->locy; for(int isa=0; isa<nsa; isa++){ /*center of subaperture when mapped onto XLOC*/ double scx=saloc->locx[isa]*dx2+dispx; double scy=saloc->locy[isa]*dy2+dispy; int count=0; /*find points that belongs to this subaperture. */ for(int iy=iceil(scy-dsa2); iy<ifloor(scy+dsa2);iy++){ for(int ix=iceil(scx-dsa2); ix<ifloor(scx+dsa2);ix++){ int ii=loc_map_get(map, ix, iy); if(ii>0){ ii--; ind[count]=ii; slocx[count]=locx[ii]; slocy[count]=locy[ii]; if(amp) amploc[count]=amp[ii]; count++; } } } /*locwrite(sloc,"sloc_isa%d",isa); */ /*writedbl(amploc,count,1,"amploc_isa%d",isa); */ sloc->nloc=count; dmat *mcc=loc_mcc_ptt(sloc,amploc); /*writebin(mcc,"mcc_isa%d",isa); */ dinvspd_inplace(mcc); /*writebin(mcc,"imcc_isa%d",isa); */ xpp[isa]=xcount; ypp[isa]=ycount; for(int ic=0; ic<count; ic++){ double xx=IND(mcc,0,1)+IND(mcc,1,1)*slocx[ic]+IND(mcc,2,1)*slocy[ic]; double yy=IND(mcc,0,2)+IND(mcc,1,2)*slocx[ic]+IND(mcc,2,2)*slocy[ic]; if(amp){ xx*=amploc[ic]; yy*=amploc[ic]; } xpi[xcount]=ind[ic]; xpx[xcount]=xx; xcount++; ypi[ycount]=ind[ic]; ypx[ycount]=yy; ycount++; } dfree(mcc); } xpp[nsa]=xcount; ypp[nsa]=ycount; locfree(sloc); free(ind); dspsetnzmax(zax,xcount); dspsetnzmax(zay,ycount); dsp*ZAT=dspcat(zax,zay,1); dspfree(zax); dspfree(zay); if(amp) free(amploc); return ZAT; }