int ifft2d (CmplxArray *z) { /* argument: CmplxArray *z io: complex array */ CmplxArray scr; /* scratch space for FT of columns */ int i, j; /* loop indexes */ int nx, ny; /* image size */ int status; nx = z->nx; ny = z->ny; /* Allocate a 1-D array for a column. */ InitCmplxArray (&scr); if ((status = AllocCmplxArray (&scr, ny, 1))) return (status); for (j = 0; j < ny; j++) /* transform each line */ CFFTB (&nx, &(RPIX2D(z,0,j)), z->workx); for (i = 0; i < nx; i++) { /* transform each column */ for (j = 0; j < ny; j++) { RPIX1D (&scr, j) = RPIX2D (z, i, j); IPIX1D (&scr, j) = IPIX2D (z, i, j); } CFFTB (&scr.nx, scr.data, scr.workx); for (j = 0; j < ny; j++) { RPIX2D (z, i, j) = RPIX1D (&scr, j) / (nx * ny); IPIX2D (z, i, j) = IPIX1D (&scr, j) / (nx * ny); } } FreeCmplxArray (&scr); return (0); }
static int MakeFT (Image *iso, Image *psf, ScatterFunctions *scf, CmplxArray *ft, CmplxArray *fto) { /* arguments Image *iso; i: isotropic halo function (1024 x 1024) Image *psf; i: telescope PSF for the aperture (normalized) ScatterFunctions *scf; i: scattering functions CmplxArray *ft; o: FT CmplxArray *fto; o: object (central 11 X 11) FT */ CmplxArray ziso, zpsf; float *hold; int i, j, k, i1, i2, j1, j2, ki, kj, kk; int ki1, ki2, kj1, kj2; int status, wsize; int FFTConvolve (CmplxArray *, CmplxArray *); /* Initialize complex arrays. */ InitCmplxArray (&ziso); InitCmplxArray (&zpsf); /* Copy real into complex arrays. PSF must be copied into larger array so its size matches the halo array size. */ if ((status = AllocCmplxArray (&ziso, iso->nx, iso->ny))) return (status); for (j = 1; j < iso->ny - 1; j++) { for (i = 1; i < iso->nx - 1; i++) RPIX2D (&ziso, i, j) = PPIX (iso, i-1, j-1); } if ((status = AllocCmplxArray (&zpsf, iso->nx, iso->ny))) return (status); /* The following code only works when both axis are simultaneously either even or odd-sized. Half-pixel shifting uses linear interp. (Is that comment correct?) */ if (psf->nx <= iso->nx) { /* this is the normal case */ i1 = (iso->nx - psf->nx) / 2; i2 = i1 + psf->nx; ki1 = 0; ki2 = psf->nx; } else { i1 = 0; i2 = iso->nx; ki1 = (psf->nx - iso->nx) / 2; ki2 = ki1 + iso->nx; } if (psf->ny <= iso->ny) { /* this is the normal case, i.e. a small slit */ j1 = (iso->ny - psf->ny) / 2; j2 = j1 + psf->ny; kj1 = 0; kj2 = psf->ny; } else { /* long slit, greater than about 29 arcsec */ j1 = 0; j2 = iso->ny; kj1 = (psf->ny - iso->ny) / 2; kj2 = kj1 + iso->ny; } /* xxx ... if ((i1 % 2) == 0) { ... xxx */ /* copy psf into zpsf */ for (j = j1, kj = kj1; j < j2 && kj < kj2; j++, kj++) { for (i = i1, ki = ki1; i < i2 && ki < ki2; i++, ki++) RPIX2D (&zpsf, i, j) = PPIX (psf, ki, kj); } /* xxx ... } else { for (j = j1, kj = 1; j < j2 - 1; j++, kj++) { for (i = i1, ki = 1; i < i2 - 1; i++, ki++) { RPIX2D (&zpsf, i, j) = (PPIX (psf, ki, kj) + PPIX (psf, ki-1, kj) + PPIX (psf, ki, kj-1) + PPIX (psf, ki-1, kj-1)) / 4.0; } } } ... xxx */ /* Convolve halo with telescope PSF. */ if ((status = FFTConvolve (&zpsf, &ziso))) return (status); /* Now convolve column-by-column with x-disp scattering function. */ for (i = 0; i < iso->nx; i++) { hold = (float *) calloc (iso->ny, sizeof (float)); if (hold == NULL) return (OUT_OF_MEMORY); for (j = 0; j < iso->ny; j++) { kk = j - scf->nxdisp / 2; for (k = 0; k <scf->nxdisp; k++, kk++) { kk = (kk < 0) ? 0 : kk; kk = (kk >= iso->ny) ? iso->ny - 1 : kk; hold[j] += RPIX2D (&zpsf, i, kk) * scf->xdisp[k]; } } for (j = 0; j < iso->ny; j++) RPIX2D (&zpsf, i, j) = hold[j]; free (hold); } /* Insert array into twice as large array and compute FT. No need to normalize ! */ if ((status = AllocCmplxArray (ft, 2 * iso->nx, 2 * iso->ny))) return (status); /* Only works when both are even-sized. */ i1 = iso->nx / 2; j1 = iso->ny / 2; i2 = i1 + iso->nx; j2 = j1 + iso->ny; for (j = j1, kj = 0; j < j2; j++, kj++) { for (i = i1, ki = 0; i < i2; i++, ki++) RPIX2D (ft, i, j) = RPIX2D (&zpsf, ki, kj); } if ((status = fft2d (ft))) return (status); /* Now build "object" FT (central 11 X 11 portion). No need to normalize ! */ if ((status = AllocCmplxArray (fto, 2 * iso->nx, 2 * iso->ny))) return (status); wsize = 6; i1 = iso->nx - wsize; j1 = iso->ny - wsize; i2 = iso->nx + wsize; j2 = iso->ny + wsize; for (j = j1, kj = iso->ny / 2 - wsize; j <= j2; j++, kj++) { for (i = i1, ki = iso->nx / 2 - wsize; i <= i2; i++, ki++) RPIX2D (fto, i, j) = RPIX2D (&zpsf, ki, kj); } if ((status = fft2d (fto))) return (status); FreeCmplxArray (&ziso); FreeCmplxArray (&zpsf); return (STIS_OK); }