Ejemplo n.º 1
0
def test_fail():
    # Some vv noisy images that result in errors in the fit to check the error reporting.

    scale = 1.3
    g1 = 0.33
    g2 = -0.27
    flux = 15
    noise = 2.
    seed = 1234

    psf = galsim.Moffat(half_light_radius=1.0, beta=2.5, trunc=3.0)
    psf = psf.dilate(scale).shear(g1=g1, g2=g2).withFlux(flux)
    image = psf.drawImage(nx=64, ny=64, scale=0.3)

    weight = image.copy()
    weight.fill(1 / noise**2)
    noisy_image = image.copy()
    rng = galsim.BaseDeviate(seed)
    noisy_image.addNoise(galsim.GaussianNoise(sigma=noise, rng=rng))

    star1 = piff.Star(piff.StarData(image, image.true_center, weight), None)
    star2 = piff.Star(piff.StarData(noisy_image, image.true_center, weight),
                      None)

    model1 = piff.Moffat(fastfit=True, beta=2.5)
    with np.testing.assert_raises(RuntimeError):
        model1.initialize(star2)
    with np.testing.assert_raises(RuntimeError):
        model1.fit(star2)
    star3 = model1.initialize(star1)
    star3 = model1.fit(star3)
    star3 = piff.Star(star2.data, star3.fit)
    with np.testing.assert_raises(RuntimeError):
        model1.fit(star3)

    # This is contrived to hit the fit failure for the reference.
    # I'm not sure what realistic use case would actually hit it, but at least it's
    # theoretically possible to fail there.
    model2 = piff.GSObjectModel(galsim.InterpolatedImage(noisy_image),
                                fastfit=True)
    with np.testing.assert_raises(RuntimeError):
        model2.initialize(star1)

    model3 = piff.Moffat(fastfit=False,
                         beta=2.5,
                         scipy_kwargs={'max_nfev': 10})
    with np.testing.assert_raises(RuntimeError):
        model3.initialize(star2)
    with np.testing.assert_raises(RuntimeError):
        model3.fit(star2).fit
    star3 = model3.initialize(star1)
    star3 = model3.fit(star3)
    star3 = piff.Star(star2.data, star3.fit)
    with np.testing.assert_raises(RuntimeError):
        model3.fit(star3)
Ejemplo n.º 2
0
def test_var():
    """Check that the variance estimate in params_var is sane.
    """
    # Here is the true PSF
    scale = 1.3
    g1 = 0.23
    g2 = -0.17
    du = 0.1
    dv = 0.4
    flux = 500
    wcs = galsim.JacobianWCS(0.26, 0.05, -0.08, -0.29)
    noise = 0.2

    gsobjs = [
        galsim.Gaussian(sigma=1.0),
        galsim.Kolmogorov(half_light_radius=1.0),
        galsim.Moffat(half_light_radius=1.0, beta=3.0),
        galsim.Moffat(half_light_radius=1.0, beta=2.5, trunc=3.0)
    ]

    # Mix of centered = True/False,
    #        fastfit = True/False,
    #        include_pixel = True/False
    models = [
        piff.Gaussian(fastfit=False, include_pixel=False, centered=False),
        piff.Kolmogorov(fastfit=True, include_pixel=True, centered=False),
        piff.Moffat(fastfit=False, beta=4.8, include_pixel=True,
                    centered=True),
        piff.Moffat(fastfit=True,
                    beta=2.5,
                    trunc=3.0,
                    include_pixel=False,
                    centered=True)
    ]

    names = ['Gaussian', 'Kolmogorov', 'Moffat3', 'Moffat2.5']

    for gsobj, model, name in zip(gsobjs, models, names):
        print()
        print("gsobj = ", gsobj)
        print()
        psf = gsobj.dilate(scale).shear(g1=g1, g2=g2).shift(du,
                                                            dv).withFlux(flux)
        image = psf.drawImage(nx=64, ny=64, wcs=wcs, method='no_pixel')
        weight = image.copy()
        weight.fill(1 / noise**2)
        # Save this one without noise.

        image1 = image.copy()
        image1.addNoise(galsim.GaussianNoise(sigma=noise))

        # Make a StarData instance for this image
        stardata = piff.StarData(image, image.true_center, weight)
        star = piff.Star(stardata, None)
        star = model.initialize(star)
        fit = model.fit(star).fit

        file_name = 'input/test_%s_var.npz' % name
        print(file_name)

        if not os.path.isfile(file_name):
            num_runs = 1000
            all_params = []
            for i in range(num_runs):
                image1 = image.copy()
                image1.addNoise(galsim.GaussianNoise(sigma=noise))
                sd = piff.StarData(image1, image1.true_center, weight)
                s = piff.Star(sd, None)
                try:
                    s = model.initialize(s)
                    s = model.fit(s)
                except RuntimeError as e:  # Occasionally hsm fails.
                    print('Caught ', e)
                    continue
                print(s.fit.params)
                all_params.append(s.fit.params)
            var = np.var(all_params, axis=0)
            np.savez(file_name, var=var)
        var = np.load(file_name)['var']
        print('params = ', fit.params)
        print('empirical var = ', var)
        print('piff estimate = ', fit.params_var)
        print('ratio = ', fit.params_var / var)
        print('max ratio = ', np.max(fit.params_var / var))
        print('min ratio = ', np.min(fit.params_var / var))
        print('mean ratio = ', np.mean(fit.params_var / var))
        # Note: The fastfit=False estimates are better -- typically better than 10%
        #       The fastfit=True estimates are much rougher.  Especially size.  Need rtol=0.3.
        np.testing.assert_allclose(fit.params_var, var, rtol=0.3)
Ejemplo n.º 3
0
def test_direct():
    """ Simple test for directly instantiated Gaussian, Kolmogorov, and Moffat without going through
    GSObjectModel explicitly.
    """
    # Here is the true PSF
    scale = 1.3
    g1 = 0.23
    g2 = -0.17
    du = 0.1
    dv = 0.4

    gsobjs = [
        galsim.Gaussian(sigma=1.0),
        galsim.Kolmogorov(half_light_radius=1.0),
        galsim.Moffat(half_light_radius=1.0, beta=3.0),
        galsim.Moffat(half_light_radius=1.0, beta=2.5, trunc=3.0)
    ]

    models = [
        piff.Gaussian(fastfit=True, include_pixel=False),
        piff.Kolmogorov(fastfit=True, include_pixel=False),
        piff.Moffat(fastfit=True, beta=3.0, include_pixel=False),
        piff.Moffat(fastfit=True, beta=2.5, trunc=3.0, include_pixel=False)
    ]

    for gsobj, model in zip(gsobjs, models):
        print()
        print("gsobj = ", gsobj)
        print()
        psf = gsobj.dilate(scale).shear(g1=g1, g2=g2).shift(du, dv)

        # Draw the PSF onto an image.  Let's go ahead and give it a non-trivial WCS.
        wcs = galsim.JacobianWCS(0.26, 0.05, -0.08, -0.29)
        image = galsim.Image(64, 64, wcs=wcs)

        # This is only going to come out right if we (unphysically) don't convolve by the pixel.
        psf.drawImage(image, method='no_pixel')

        # Make a StarData instance for this image
        stardata = piff.StarData(image, image.true_center)
        star = piff.Star(stardata, None)
        star = model.initialize(star)

        # First try fastfit.
        print('Fast fit')
        fit = model.fit(star).fit

        print('True scale = ', scale, ', model scale = ', fit.params[0])
        print('True g1 = ', g1, ', model g1 = ', fit.params[1])
        print('True g2 = ', g2, ', model g2 = ', fit.params[2])
        print('True du = ', du, ', model du = ', fit.center[0])
        print('True dv = ', dv, ', model dv = ', fit.center[1])

        # This test is fairly accurate, since we didn't add any noise and didn't convolve by
        # the pixel, so the image is very accurately a sheared GSObject.
        # These tests are more strict above.  The truncated Moffat included here but not there
        # doesn't work quite as well.
        np.testing.assert_allclose(fit.params[0], scale, rtol=1e-4)
        np.testing.assert_allclose(fit.params[1], g1, rtol=0, atol=1e-5)
        np.testing.assert_allclose(fit.params[2], g2, rtol=0, atol=1e-5)
        np.testing.assert_allclose(fit.center[0], du, rtol=0, atol=1e-5)
        np.testing.assert_allclose(fit.center[1], dv, rtol=0, atol=1e-5)

        # Also need to test ability to serialize
        outfile = os.path.join('output', 'gsobject_direct_test.fits')
        with fitsio.FITS(outfile, 'rw', clobber=True) as f:
            model.write(f, 'psf_model')
        with fitsio.FITS(outfile, 'r') as f:
            roundtrip_model = piff.GSObjectModel.read(f, 'psf_model')
        assert model.__dict__ == roundtrip_model.__dict__

    # repeat with fastfit=False

    models = [
        piff.Gaussian(fastfit=False, include_pixel=False),
        piff.Kolmogorov(fastfit=False, include_pixel=False),
        piff.Moffat(fastfit=False, beta=3.0, include_pixel=False),
        piff.Moffat(fastfit=False, beta=2.5, trunc=3.0, include_pixel=False)
    ]

    for gsobj, model in zip(gsobjs, models):
        print()
        print("gsobj = ", gsobj)
        print()
        psf = gsobj.dilate(scale).shear(g1=g1, g2=g2).shift(du, dv)

        # Draw the PSF onto an image.  Let's go ahead and give it a non-trivial WCS.
        wcs = galsim.JacobianWCS(0.26, 0.05, -0.08, -0.29)
        image = galsim.Image(64, 64, wcs=wcs)

        # This is only going to come out right if we (unphysically) don't convolve by the pixel.
        psf.drawImage(image, method='no_pixel')

        # Make a StarData instance for this image
        stardata = piff.StarData(image, image.true_center)
        star = piff.Star(stardata, None)
        star = model.initialize(star)

        print('Slow fit')
        fit = model.fit(star).fit

        print('True scale = ', scale, ', model scale = ', fit.params[0])
        print('True g1 = ', g1, ', model g1 = ', fit.params[1])
        print('True g2 = ', g2, ', model g2 = ', fit.params[2])
        print('True du = ', du, ', model du = ', fit.center[0])
        print('True dv = ', dv, ', model dv = ', fit.center[1])

        # This test is fairly accurate, since we didn't add any noise and didn't convolve by
        # the pixel, so the image is very accurately a sheared GSObject.
        np.testing.assert_allclose(fit.params[0], scale, rtol=1e-5)
        np.testing.assert_allclose(fit.params[1], g1, rtol=0, atol=1e-5)
        np.testing.assert_allclose(fit.params[2], g2, rtol=0, atol=1e-5)
        np.testing.assert_allclose(fit.center[0], du, rtol=0, atol=1e-5)
        np.testing.assert_allclose(fit.center[1], dv, rtol=0, atol=1e-5)

        # Also need to test ability to serialize
        outfile = os.path.join('output', 'gsobject_direct_test.fits')
        with fitsio.FITS(outfile, 'rw', clobber=True) as f:
            model.write(f, 'psf_model')
        with fitsio.FITS(outfile, 'r') as f:
            roundtrip_model = piff.GSObjectModel.read(f, 'psf_model')
        assert model.__dict__ == roundtrip_model.__dict__