Example #1
0
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);
}
Example #2
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);
}