示例#1
0
def numerical_image_gradients(theta0, delta, scene=None, stamp=None):

    dI_dp = []
    for i, (p, dp) in enumerate(zip(theta0, delta)):
        theta = theta0.copy()
        imlo, _ = make_image(theta, scene, stamp)
        theta[i] += dp
        imhi, _ = make_image(theta, scene, stamp)
        dI_dp.append((imhi - imlo) / (dp))

    return np.array(dI_dp)
示例#2
0
def test_image_gradients(ptrue, delta, scene=None, stamp=None):
    delta = np.ones_like(ptrue) * 1e-6
    #numerical
    grad_num = numerical_image_gradients(ptrue, delta, scene, stamp)
    image, grad = make_image(ptrue, scene, stamp)
    fig, axes = pl.subplots(len(ptrue), 3, sharex=True, sharey=True)
    for i in range(len(ptrue)):
        g = grad[i, :].reshape(stamp.nx, stamp.ny)
        c = axes[i, 0].imshow(grad_num[i, :, :].T, origin='lower')
        fig.colorbar(c, ax=axes[i, 0])
        c = axes[i, 1].imshow(g.T, origin='lower')
        fig.colorbar(c, ax=axes[i, 1])
        c = axes[i, 2].imshow((grad_num[i, :, :] - g).T, origin='lower')
        fig.colorbar(c, ax=axes[i, 2])

    axes[0, 0].set_title('Numerical')
    axes[0, 1].set_title('Analytic')
    axes[0, 2].set_title('N - A')
示例#3
0
def setup_scene(galaxy=False,
                fudge=1.0,
                fwhm=1.0,
                offset=0.0,
                size=(30, 30),
                add_noise=False):

    stamp = make_stamp(size, fwhm, offset=offset)

    # --- Get a Source and Scene -----
    if galaxy:
        source = Galaxy()
        source.ngauss = 1
        source.radii = np.arange(source.ngauss) * 0.5 + 1.0
        source.q = 0.5
        source.pa = np.deg2rad(30.)
        theta = [100., 10., 10., 0.5, np.deg2rad(10.)]
        label = ['$\psi$', '$x$', '$y$', '$q$', '$\\varphi$']
        bounds = [(0, 1e4), (0., 30), (0, 30), (0, 1), (0, np.pi / 2)]
    else:
        source = Star()
        theta = [100., 10., 10.]
        label = ['$\psi$', '$x$', '$y$']
        bounds = [(-1e6, 1e6), (-1e5, 1e5), (-1e5, 1e5)]

    scene = Scene(galaxy=galaxy)
    scene.sources = [source]

    # --- Generate mock  and add to stamp ---
    ptrue = np.array(theta) * fudge
    true_image, partials = make_image(ptrue, scene, stamp)
    stamp.pixel_values = true_image.copy()
    err = stamp.pixel_values.max() * 1e-2
    #err = np.sqrt(stamp.pixel_values.flatten())
    stamp.ierr = np.ones(stamp.npix) / err

    if add_noise:
        noise = np.random.normal(0, err, size=(stamp.nx, stamp.ny))
        stamp.pixel_values += noise

    return scene, stamp, ptrue, label
示例#4
0
def setup_scene(psfname='', size=(100, 100), fudge=1.0, add_noise=False):

    # --- Get a postage stamp ----
    stamp = make_stamp(size, psfname=psfname)

    # --- get the Scene ---
    scene = Scene(galaxy=False)
    sources = [Star()]
    scene.sources = sources

    # --- Get the mock image ----
    label = ['flux', 'x', 'y']
    theta = np.array([100., stamp.nx / 2., stamp.ny / 2.])
    ptrue = theta * fudge
    stamp.pixel_values = make_image(ptrue, scene, stamp)[0]
    err = stamp.pixel_values.max() * 1e-2
    #err = np.sqrt(stamp.pixel_values.flatten())
    stamp.ierr = np.ones(stamp.npix) / err

    if add_noise:
        noise = np.random.normal(0, err, size=(stamp.nx, stamp.ny))
        stamp.pixel_values += noise

    return scene, stamp, ptrue, label
示例#5
0
    stamp = make_stamp(size, psfname=psfname)
    # make the pixels tiny
    #stamp.distortion = np.eye(2) * 8.0
    oversample = 8
    stamp.psf.covariances *= oversample**2
    #stamp.psf.covariances[:, 0, 0] /= oversample
    #stamp.psf.covariances[:, 1, 1] /= oversample
    stamp.psf.means *= oversample
    stamp.crpix = np.array([stamp.nx / 2., stamp.ny / 2.])
    stamp.crval = np.zeros(2)

    T = -1.0 * np.eye(2)
    stamp.psf.covariances = np.matmul(T, np.matmul(stamp.psf.covariances, T.T))
    stamp.psf.means = np.matmul(stamp.psf.means, T)

    # --- get the Scene ---
    scene = Scene()
    sources = [Star()]
    scene.sources = sources

    # --- Get the mock image ----
    label = ['flux', 'x', 'y']
    theta = np.array([100., 0.0, 0.0])
    ptrue = theta
    stamp.pixel_values = make_image(ptrue, scene, stamp)[0]

    fig, ax = pl.subplots()
    ax.imshow(stamp.pixel_values.T, origin='lower')

    pl.show()
示例#6
0
def fit_source(ra=53.115325, dec=-27.803518, imname='', psfname=None,
               stamp_size=(100, 100), use_grad=True,
               err_expand=1.0, jitter=0.0, gain=np.inf):
    """
    """
    # --- Build the postage stamp ----
    stamp = make_stamp(imname, (ra, dec), stamp_size,
                       psfname=psfname, center_type='celestial')
    stamp.snr = stamp.pixel_values * stamp.ierr
    stamp.ierr = stamp.ierr.flatten() / err_expand
    counts = stamp.pixel_values.flatten() - stamp.pixel_values.min()
    stamp.ierr = 1.0 / np.sqrt(1/stamp.ierr**2 + jitter**2 + counts/gain)

    # override the WCS so coordinates are in pixels
    # The scale matrix D
    stamp.scale = np.eye(2)
    # The sky coordinates of the reference pixel
    stamp.crval = np.zeros([2])
    # The pixel coordinates of the reference pixel
    stamp.crpix = np.zeros([2])

    # Rotate the PSF by 180 degrees
    T = -1.0 * np.eye(2)
    stamp.psf.covariances = np.matmul(T, np.matmul(stamp.psf.covariances, T.T))
    stamp.psf.means = np.matmul(stamp.psf.means, T)

    # --- get the Scene ---
    scene = Scene(galaxy=False)
    sources = [Star()]
    scene.sources = sources

    # ---- Optimization ------
    if use_grad:
        nll = argfix(negative_lnlike_stamp, scene=scene, stamp=stamp)
    else:
        nll = argfix(negative_lnlike_nograd, scene=scene, stamp=stamp)
    if False:
        nll = argfix(chi_vector, scene=scene, stamp=stamp)
        method = 'lm'
        use_grad = False
        
    if True:
        def callback(x):
            #nf += 1
            print(x, nll(x))
        callback = None

        # Initial and bounds
        p0 = np.array([stamp.pixel_values.sum(), stamp.nx/2, stamp.ny/2])
        p0 += np.random.normal(0., [0.1 * p0[0], 0.5, 0.5])
        bounds = [(1, 1e4), (0., stamp_size[0]), (0, stamp_size[1])]
        bounds = None
        
        # Optimize
        from scipy.optimize import minimize
        lbfgsb_opt = {'ftol': 1e-20, 'gtol': 1e-12, 'disp':True, 'iprint': -1, 'maxcor': 20}
        result = minimize(nll, p0, jac=use_grad, bounds=None, callback=callback,
                          options=lbfgsb_opt)

        # plot results
        resid, partials = make_image(result.x, scene, stamp)
        dim = stamp.pixel_values
        mim = resid
        chi = (dim - mim) * stamp.ierr.reshape(stamp.nx, stamp.ny)
        
        fig, axes = pl.subplots(1, 4, sharex=True, sharey=True, figsize=(14.75, 3.25))
        images = [dim, mim, dim-mim, chi]
        labels = ['Data', 'Model', 'Data-Model', '$\chi$']
        for k, ax in enumerate(axes):
            c = ax.imshow(images[k].T, origin='lower')
            pl.colorbar(c, ax=ax)
            ax.set_title(labels[k])

        return result, (fig, axes), nll(result.x), stamp, scene
示例#7
0
    if add_noise:
        noise = np.random.normal(0, err, size=(stamp.nx, stamp.ny))
        stamp.pixel_values += noise

    return scene, stamp, ptrue, label


if __name__ == "__main__":

    # Get a scene and a stamp at some parameters
    scene, stamp, ptrue, label = setup_scene(galaxy=True,
                                             fwhm=2.0,
                                             fudge=1.25,
                                             add_noise=True)
    true_image, partials = make_image(ptrue, scene, stamp)

    # Set up likelihoods
    nll = argfix(negative_lnlike_stamp, scene=scene, stamp=stamp)
    nll_nograd = argfix(negative_lnlike_nograd, scene=scene, stamp=stamp)

    # --- Chi2 on a grid ------
    # needs to be debugged
    if False:
        mux = np.linspace(47, 53., 100)
        muy = np.linspace(47, 53., 100)
        flux = np.linspace(3000, 5000., 10)
        chi2 = np.zeros([len(mux), len(muy), len(flux)])

        for i, x in enumerate(mux):
            for j, y in enumerate(muy):
示例#8
0
if __name__ == "__main__":

    # --- Get a postage stamp ----
    psfname = os.path.join(paths.psfmixture, 'f090_ng6_em_random.p')
    scene, stamp, ptrue, label = setup_scene(size=(50, 50),
                                             psfname=psfname,
                                             add_noise=True)

    nll = argfix(negative_lnlike_stamp, scene=scene, stamp=stamp)
    nll_nograd = argfix(negative_lnlike_nograd, scene=scene, stamp=stamp)

    # --- Plot a model and gradients thereof ---
    if False:
        theta_init = ptrue * 1.05
        image_init, partials_init = make_image(theta_init, scene, stamp)
        fig, axes = pl.subplots(3, 2, sharex=True, sharey=True)
        ax = axes.flat[0]
        i = ax.imshow(stamp.pixel_values.T, origin='lower')
        ax.text(0.1, 0.9, 'Mock Data', transform=ax.transAxes)
        ax = axes.flat[1]
        i = ax.imshow(image_init.T, origin='lower')
        ax.text(0.1, 0.9, 'Initial Model', transform=ax.transAxes)
        for i, ddtheta in enumerate(partials_init[scene.free_inds, :]):
            ax = axes.flat[i + 2]
            ax.imshow(ddtheta.reshape(stamp.nx, stamp.ny).T, origin='lower')
            ax.text(0.1,
                    0.9,
                    '$\partial I/\partial {}$'.format(label[i]),
                    transform=ax.transAxes)
        pl.show()
示例#9
0
    scene.sources = sources
    label = ['flux', 'x', 'y']

    nll = argfix(negative_lnlike_stamp, scene=scene, stamp=stamp)
    nll_nograd = argfix(negative_lnlike_nograd, scene=scene, stamp=stamp)

    # --- Initialize ---
    theta_init = np.array([stamp.pixel_values.sum() * 1.0, ra_init, dec_init])
    if inpixels:
        world = np.array([ra_init, dec_init, 0])
        hdr = fits.getheader(imname)
        ast = apy_wcs.WCS(hdr)
        center = ast.wcs_world2pix(world[None, :], 0)[0, :2] - stamp.lo
        theta_init = np.array(
            [stamp.pixel_values.sum() * 0.5, center[0], center[1]])
    image_init, partials = make_image(theta_init, scene, stamp)

    # --- Plot initial value ---
    if True:
        fig, axes = pl.subplots(3, 2, sharex=True, sharey=True)
        ax = axes.flat[0]
        i = ax.imshow(stamp.pixel_values.T, origin='lower')
        ax.text(0.1, 0.9, 'Sim. Data', transform=ax.transAxes)
        ax = axes.flat[1]
        i = ax.imshow(image_init.T, origin='lower')
        ax.text(0.1, 0.9, 'Initial Model', transform=ax.transAxes)
        for i, ddtheta in enumerate(partials):
            ax = axes.flat[i + 2]
            ax.imshow(ddtheta.reshape(stamp.nx, stamp.ny).T, origin='lower')
            ax.text(0.1,
                    0.9,