Example #1
0
    def fit_patches(self, data, dq, parms, clip, psfs, noise_models):
        """
        Fit the data given the psf_model
        """
        flags = np.zeros_like(data, dtype=np.int)
        fit_vars = np.zeros_like(data)
        fit_masks = np.ones_like(data, dtype=np.bool)
        for i in range(data.shape[0]):
            fp, fv, ind = self.fit_single_patch(data[i], dq[i], psfs[i],
                                                noise_models[i])
            if i == 0:
                fit_parms = np.zeros(data.shape[0], fp.shape[1])

            if clip:
                for j in range(parms.clip_iter):

                    # define model and clip variance
                    scaled_psf, bkg = self.construct_model_parts(fp[None, :], psfs)
                    model = scaled_psf + bkg
                    clip_var = parms.floor + parms.gain * np.abs(model)
                    clip_var += parms.q * scaled_psf ** 2.
                    
                    # sigma clip
                    chi = np.zeros_like(data)
                    chi[ind] = np.abs(data[ind] - model[ind]) / np.sqrt(clip_var[ind])
                    condition = chi - parms.clip_tol
                    condition = (condition > 0).reshape(parms.patch_shape)

                    # redefine mask, grow and add to dq mask.
                    ind = 1 - ind.reshape(parms.patch_shape)
                    idx = grow_mask(condition)
                    flags[i] = ind.copy()
                    flags[i][idx] = 3
                    flags[i][condition] = 2
                    ind = np.ravel((ind == 0) & (idx == 0))

                    # refit
                    fp, fv, ind = self.fit_single_patch(data[i], dq[i], psfs[i],
                                                        noise_models[i], ind=ind)

            fit_vars[i] = fv
            fit_masks[i] = ind
            fit_parms[i] = fp

        return fit_parms, fit_vars, fit_masks
Example #2
0
def fit_single_patch(data, psf, dq, parms, var=None):
    """
    Fit a single patch, return the scale for the psf plus any
    background parameters.  Takes in flattened arrays for
    data and psf.
    """
    gain = parms.gain
    floor = parms.floor
    clip_parms = parms.clip_parms
    background = parms.background

    if var == None:
        var = np.ones_like(data)

    if background is None:
        A = np.atleast_2d(psf).T
    elif background == 'constant':
        A = np.vstack((psf, np.ones_like(psf))).T
    elif background == 'linear':
        N = np.sqrt(psf.size).astype(np.int)
        x, y = np.meshgrid(range(N), range(N))
        A = np.vstack((psf, np.ones_like(psf),
                       x.ravel(), y.ravel())).T
    else:
        assert False, 'Background model not supported: %s' % background

    ind = dq == 0

    # fit the data using least squares
    rh = np.dot(A[ind, :].T, data[ind] / var[ind])
    try:
        lh = np.linalg.inv(np.dot(A[ind, :].T, A[ind, :] / var[ind, None]))
        fit_parms = np.dot(lh, rh)
    except:
        fit_parms = np.zeros(A.shape[1])

    bkg = make_background(data, fit_parms, background)

    # sigma clip if desired
    if (clip_parms is not None) & (np.any(fit_parms != 0)):
        Niter = clip_parms[0]
        assert Niter == 1, 'Multiple rounds of clipping not supported.'
        tol = clip_parms[1]
        for i in range(Niter):

            # define model and noise
            scaled_psf = psf * fit_parms[0]
            model = scaled_psf + bkg
            if parms.plot_data:
                parms.old_bkg = bkg
                parms.old_model = model
            model = model[ind]
            scaled_psf = scaled_psf[ind]
            var = floor + gain * np.abs(model) + (parms.q * scaled_psf) ** 2.

            # sigma clip
            chi = np.zeros_like(data)
            chi[ind] = np.abs(data[ind] - model) / np.sqrt(var)
            condition = chi - tol
            condition = (condition > 0).reshape(parms.patch_shape)
            
            # redefine mask, grow and add to dq mask.
            ind = 1 - ind.reshape(parms.patch_shape)
            idx = grow_mask(condition)
            if parms.plot_data:
                parms.flags = ind.copy()
                parms.flags[idx] = 3
                parms.flags[condition] = 2
            ind = np.ravel((ind == 0) & (idx == 0))

            # refit
            rh = np.dot(A[ind, :].T, data[ind])
            try:
                lh = np.linalg.inv(np.dot(A[ind, :].T, A[ind, :]))
                fit_parms = np.dot(lh, rh)
            except:
                fit_parms = np.zeros(A.shape[1])
            bkg = make_background(data, fit_parms, background)

    fit_vars = np.diagonal(lh)

    return fit_parms, fit_vars, bkg, ind
Example #3
0
def fig1(small=1.e-6):
    """
    Figure showing examples of data patches
    """
    Nexamples = 16
    rows = 4
    cols = 4
    rsize = 4
    csize = 4
    shrink = 1.
    ws, hs = 0.0, 0.2
    fs = 24

    # load data and dq
    f = pf.open('../data/region/f160w_25_457_557_457_557_pixels.fits')
    d = f[0].data
    f.close()
    f = pf.open('../data/region/f160w_25_457_557_457_557_dq.fits')
    dq = f[0].data
    f.close()

    # toss data where dq is nonzero in center
    center_pixel = (d.shape[1] - 1 ) / 2
    ind = dq[:, center_pixel] == 0
    d = d[ind]
    dq = dq[ind]

    # sort by maxima
    mxs = d[:, center_pixel]
    ind = np.argsort(mxs)
    mxs = mxs[ind]
    d = d[ind]
    dq = dq[ind]

    # get 7 other random patches
    ind = [0, d.shape[0] - 1]
    count = 0
    while True:
        new = np.random.randint(d.shape[0])
        if new in ind:
            continue
        else:
            ind.append(new)
        if len(ind) == Nexamples:
            break

    # sort and reshape to 2D
    ind = np.array(ind)
    data = d[ind]
    dq = dq[ind]
    mxs = data[:, center_pixel]
    ind = np.argsort(mxs)
    patch_side_size = np.sqrt(data.shape[1]) # assumes square patches
    dq = dq[ind].reshape(Nexamples, patch_side_size, patch_side_size)
    data = data[ind].reshape(Nexamples, patch_side_size, patch_side_size)

    # the figure
    pl.gray()
    f = pl.figure(figsize=(rows * rsize, cols * csize))
    pl.subplots_adjust(wspace=ws, hspace=hs)
    
    axes = [None] * cols
    for i in range(Nexamples):

        # patch pixels with dq != 0
        bad_pix = np.where(dq[i] != 0)
        for j in range(bad_pix[0].size):
            ind = np.zeros_like(dq[i])
            ind[bad_pix[0][j], bad_pix[1][j]] = 1
            idx = grow_mask(ind)
            fix = np.median(data[i][idx])
            data[i][bad_pix[0][j], bad_pix[1][j]] = fix

        mn = data[i].min()
        mx = data[i].max()
        kwargs = {'interpolation':'nearest', 'origin':'lower',
                  'norm':LogNorm(vmin=mn, vmax=mx)}

        ax = pl.subplot(rows, cols, i + 1)
        pl.imshow(data[i], **kwargs)
        ax.set_xticks([])
        ax.set_yticks([])
        pl.title('[%0.1f, %0.0f]' % (mn, mx), fontsize=fs)

    f.savefig('../plots/paper/fig1.png', bbox_inches='tight')
    pl.close(f)