Esempio n. 1
0
def test_autocorrelate():
    """Test that auto-correlation works the same as convolution with the mirror image of itself.

    (See the Signal processing Section of http://en.wikipedia.org/wiki/Autocorrelation)
    """
    import time
    t1 = time.time()
    # Use a function that is NOT two-fold rotationally symmetric, e.g. two different flux Gaussians
    myGauss1 = galsim.SBGaussian(sigma=3., flux=4)
    myGauss1.applyShift(-0.2, -0.4)
    myGauss2 = (galsim.SBGaussian(sigma=6., flux=1.3))
    myGauss2.applyShift(0.3, 0.3)
    mySBP1 = galsim.SBAdd([myGauss1, myGauss2])
    mySBP2 = galsim.SBAdd([myGauss1, myGauss2])
    # Here we rotate by 180 degrees to create mirror image
    mySBP2.applyRotation(180. * galsim.degrees)
    myConv = galsim.SBConvolve([mySBP1, mySBP2])
    myImg1 = galsim.ImageF(80, 80, scale=0.7)
    myConv.draw(myImg1.view())
    myAutoCorr = galsim.SBAutoCorrelate(mySBP1)
    myImg2 = galsim.ImageF(80, 80, scale=0.7)
    myAutoCorr.draw(myImg2.view())
    printval(myImg1, myImg2)
    np.testing.assert_array_almost_equal(
        myImg1.array,
        myImg2.array,
        4,
        err_msg=
        "Asymmetric sum of Gaussians convolved with mirror of self disagrees with "
        + "SBAutoCorrelate result")

    # Repeat with the GSObject version of this:
    obj1 = galsim.Gaussian(sigma=3., flux=4)
    obj1.applyShift(-0.2, -0.4)
    obj2 = galsim.Gaussian(sigma=6., flux=1.3)
    obj2.applyShift(0.3, 0.3)
    add1 = galsim.Add(obj1, obj2)
    add2 = (galsim.Add(obj1, obj2)).createRotated(180. * galsim.degrees)
    conv = galsim.Convolve([add1, add2])
    conv.draw(myImg1)
    corr = galsim.AutoCorrelate(add1)
    corr.draw(myImg2)
    printval(myImg1, myImg2)
    np.testing.assert_array_almost_equal(
        myImg1.array,
        myImg2.array,
        4,
        err_msg=
        "Asymmetric sum of Gaussians convolved with mirror of self disagrees with "
        + "AutoCorrelate result")

    # Test photon shooting.
    do_shoot(corr, myImg2, "AutoCorrelate")

    t2 = time.time()
    print 'time for %s = %.2f' % (funcname(), t2 - t1)
Esempio n. 2
0
    def __init__(self,
                 real_galaxy_catalog,
                 index=None,
                 id=None,
                 random=False,
                 rng=None,
                 x_interpolant=None,
                 k_interpolant=None,
                 flux=None,
                 pad_factor=0,
                 noise_pad=False,
                 pad_image=None,
                 use_cache=True,
                 gsparams=None):

        import pyfits
        import numpy as np

        # Code block below will be for galaxy selection; not all are currently implemented.  Each
        # option must return an index within the real_galaxy_catalog.
        if index is not None:
            if id is not None or random is True:
                raise AttributeError(
                    'Too many methods for selecting a galaxy!')
            use_index = index
        elif id is not None:
            if random is True:
                raise AttributeError(
                    'Too many methods for selecting a galaxy!')
            use_index = real_galaxy_catalog._get_index_for_id(id)
        elif random is True:
            if rng is None:
                uniform_deviate = galsim.UniformDeviate()
            elif isinstance(rng, galsim.BaseDeviate):
                uniform_deviate = galsim.UniformDeviate(rng)
            else:
                raise TypeError(
                    "The rng provided to RealGalaxy constructor is not a BaseDeviate"
                )
            use_index = int(real_galaxy_catalog.nobjects * uniform_deviate())
        else:
            raise AttributeError('No method specified for selecting a galaxy!')

        # read in the galaxy, PSF images; for now, rely on pyfits to make I/O errors. Should
        # consider exporting this code into fits.py in some function that takes a filename and HDU,
        # and returns an ImageView

        gal_image = real_galaxy_catalog.getGal(use_index)
        PSF_image = real_galaxy_catalog.getPSF(use_index)

        # choose proper interpolant
        if x_interpolant is None:
            lan5 = galsim.Lanczos(5, conserve_flux=True, tol=1.e-4)
            self.x_interpolant = galsim.InterpolantXY(lan5)
        else:
            self.x_interpolant = galsim.utilities.convert_interpolant_to_2d(
                x_interpolant)
        if k_interpolant is None:
            self.k_interpolant = galsim.InterpolantXY(
                galsim.Quintic(tol=1.e-4))
        else:
            self.k_interpolant = galsim.utilities.convert_interpolant_to_2d(
                k_interpolant)

        # read in data about galaxy from FITS binary table; store as normal attributes of RealGalaxy

        # save any other relevant information as instance attributes
        self.catalog_file = real_galaxy_catalog.file_name
        self.index = use_index
        self.pixel_scale = float(real_galaxy_catalog.pixel_scale[use_index])

        # handle padding by an image
        specify_size = False
        padded_size = gal_image.getPaddedSize(pad_factor)
        if pad_image is not None:
            specify_size = True
            if isinstance(pad_image, str):
                pad_image = galsim.fits.read(pad_image)
            if (not isinstance(pad_image, galsim.BaseImageF)
                    and not isinstance(pad_image, galsim.BaseImageD)):
                raise ValueError(
                    "Supplied pad_image is not one of the allowed types!")
            # If an image was supplied directly or from a file, check its size:
            #    Cannot use if too small.
            #    Use to define the final image size otherwise.
            deltax = ((1 + pad_image.getXMax() - pad_image.getXMin()) -
                      (1 + gal_image.getXMax() - gal_image.getXMin()))
            deltay = ((1 + pad_image.getYMax() - pad_image.getYMin()) -
                      (1 + gal_image.getYMax() - gal_image.getYMin()))
            if deltax < 0 or deltay < 0:
                raise RuntimeError("Image supplied for padding is too small!")
            if pad_factor != 1. and pad_factor != 0.:
                import warnings
                msg = "Warning: ignoring specified pad_factor because user also specified\n"
                msg += "         an image to use directly for the padding."
                warnings.warn(msg)
        else:
            if isinstance(gal_image, galsim.BaseImageF):
                pad_image = galsim.ImageF(padded_size, padded_size)
            if isinstance(gal_image, galsim.BaseImageD):
                pad_image = galsim.ImageD(padded_size, padded_size)

        # Set up the GaussianDeviate if not provided one, or check that the user-provided one
        # is of a valid type.  Note if random was selected, we can use that uniform_deviate safely.
        if random is True:
            gaussian_deviate = galsim.GaussianDeviate(uniform_deviate)
        else:
            if rng is None:
                gaussian_deviate = galsim.GaussianDeviate()
            elif isinstance(rng, galsim.BaseDeviate):
                # Even if it's already a GaussianDeviate, we still want to make a new Gaussian
                # deviate that would generate the same sequence, because later we change the sigma
                # and we don't want to change it for the original one that was passed in.  So don't
                # distinguish between GaussianDeviate and the other BaseDeviates here.
                gaussian_deviate = galsim.GaussianDeviate(rng)
            else:
                raise TypeError(
                    "rng provided to RealGalaxy constructor is not a BaseDeviate"
                )

        # handle noise-padding options
        try:
            noise_pad = galsim.config.value._GetBoolValue(noise_pad, '')
        except:
            pass
        if noise_pad:
            self.pad_variance = float(real_galaxy_catalog.variance[use_index])

            # Check, is it "True" or something else?  If True, we use Gaussian uncorrelated noise
            # using the stored variance in the catalog.  Otherwise, if it's a CorrelatedNoise we use
            # it directly; if it's an Image of some sort we use it to make a CorrelatedNoise; if
            # it's a string, we read in the image from file and make a CorrelatedNoise.
            if type(noise_pad) is not bool:
                if isinstance(noise_pad,
                              galsim.correlatednoise._BaseCorrelatedNoise):
                    cn = noise_pad.copy()
                    if rng:  # Let user supplied RNG take precedence over that in user CN
                        cn.setRNG(gaussian_deviate)
                    # This small patch may have different overall variance, so rescale while
                    # preserving the correlation structure by default
                    cn.setVariance(self.pad_variance)
                elif (isinstance(noise_pad, galsim.BaseImageF)
                      or isinstance(noise_pad, galsim.BaseImageD)):
                    cn = galsim.CorrelatedNoise(gaussian_deviate, noise_pad)
                elif use_cache and noise_pad in RealGalaxy._cache_noise_pad:
                    cn = RealGalaxy._cache_noise_pad[noise_pad]
                    # Make sure that we are using the desired RNG by resetting that in this cached
                    # CorrelatedNoise instance
                    if rng:
                        cn.setRNG(gaussian_deviate)
                    # This small patch may have different overall variance, so rescale while
                    # preserving the correlation structure
                    cn.setVariance(self.pad_variance)
                elif isinstance(noise_pad, str):
                    tmp_img = galsim.fits.read(noise_pad)
                    cn = galsim.CorrelatedNoise(gaussian_deviate, tmp_img)
                    if use_cache:
                        RealGalaxy._cache_noise_pad[noise_pad] = cn
                    # This small patch may have different overall variance, so rescale while
                    # preserving the correlation structure
                    cn.setVariance(self.pad_variance)
                else:
                    raise RuntimeError(
                        "noise_pad must be either a bool, CorrelatedNoise, Image, "
                        + "or a filename for reading in an Image")

            # Set the GaussianDeviate sigma
            gaussian_deviate.setSigma(np.sqrt(self.pad_variance))

            # populate padding image with noise field
            if type(noise_pad) is bool:
                pad_image.addNoise(galsim.DeviateNoise(gaussian_deviate))
            else:
                pad_image.addNoise(cn)
        else:
            self.pad_variance = 0.

        # Now we have to check: was the padding determined using pad_factor?  Or by passing in an
        # image for padding?  Treat these cases differently:
        # (1) If the former, then we can simply have the C++ handle the padding process.
        # (2) If the latter, then we have to do the padding ourselves, and pass the resulting image
        # to the C++ with pad_factor explicitly set to 1.
        if specify_size is False:
            # Make the SBInterpolatedImage out of the image.
            self.original_image = galsim.SBInterpolatedImage(
                gal_image,
                xInterp=self.x_interpolant,
                kInterp=self.k_interpolant,
                dx=self.pixel_scale,
                pad_factor=pad_factor,
                pad_image=pad_image,
                gsparams=gsparams)
        else:
            # Leave the original image as-is.  Instead, we shift around the image to be used for
            # padding.  Find out how much x and y margin there should be on lower end:
            x_marg = int(np.round(0.5 * deltax))
            y_marg = int(np.round(0.5 * deltay))
            # Now reset the pad_image to contain the original image in an even way
            pad_image = pad_image.view()
            pad_image.setScale(self.pixel_scale)
            pad_image.setOrigin(gal_image.getXMin() - x_marg,
                                gal_image.getYMin() - y_marg)
            # Set the central values of pad_image to be equal to the input image
            pad_image[gal_image.bounds] = gal_image
            self.original_image = galsim.SBInterpolatedImage(
                pad_image,
                xInterp=self.x_interpolant,
                kInterp=self.k_interpolant,
                dx=self.pixel_scale,
                pad_factor=1.,
                gsparams=gsparams)

        # also make the original PSF image, with far less fanfare: we don't need to pad with
        # anything interesting.
        self.original_PSF = galsim.SBInterpolatedImage(
            PSF_image,
            xInterp=self.x_interpolant,
            kInterp=self.k_interpolant,
            dx=self.pixel_scale,
            gsparams=gsparams)

        # recalculate Fourier-space attributes rather than using overly-conservative defaults
        self.original_image.calculateStepK()
        self.original_image.calculateMaxK()
        self.original_PSF.calculateStepK()
        self.original_PSF.calculateMaxK()

        if flux != None:
            self.original_image.setFlux(flux)
            self.original_image.__class__ = galsim.SBTransform  # correctly reflect SBProfile change
        self.original_PSF.setFlux(1.0)
        self.original_PSF.__class__ = galsim.SBTransform  # correctly reflect SBProfile change

        # Calculate the PSF "deconvolution" kernel
        psf_inv = galsim.SBDeconvolve(self.original_PSF, gsparams=gsparams)
        # Initialize the SBProfile attribute
        GSObject.__init__(
            self,
            galsim.SBConvolve([self.original_image, psf_inv],
                              gsparams=gsparams))
Esempio n. 3
0
def test_autoconvolve():
    """Test that auto-convolution works the same as convolution with itself.
    """
    import time
    t1 = time.time()

    mySBP = galsim.SBMoffat(beta=3.8, fwhm=1.3, flux=5)
    myConv = galsim.SBConvolve([mySBP, mySBP])
    myImg1 = galsim.ImageF(80, 80, scale=0.4)
    myConv.draw(myImg1.view())
    myAutoConv = galsim.SBAutoConvolve(mySBP)
    myImg2 = galsim.ImageF(80, 80, scale=0.4)
    myAutoConv.draw(myImg2.view())
    printval(myImg1, myImg2)
    np.testing.assert_array_almost_equal(
        myImg1.array,
        myImg2.array,
        4,
        err_msg=
        "Moffat convolved with self disagrees with SBAutoConvolve result")

    # Repeat with the GSObject version of this:
    psf = galsim.Moffat(beta=3.8, fwhm=1.3, flux=5)
    conv = galsim.Convolve([psf, psf])
    conv.draw(myImg1)
    conv2 = galsim.AutoConvolve(psf)
    conv2.draw(myImg2)
    printval(myImg1, myImg2)
    np.testing.assert_array_almost_equal(
        myImg1.array,
        myImg2.array,
        4,
        err_msg="Moffat convolved with self disagrees with AutoConvolve result"
    )

    # Check with default_params
    conv = galsim.AutoConvolve(psf, gsparams=default_params)
    conv.draw(myImg1)
    np.testing.assert_array_almost_equal(
        myImg1.array,
        myImg2.array,
        4,
        err_msg=
        "Using AutoConvolve with default_params disagrees with expected result"
    )
    conv = galsim.AutoConvolve(psf, gsparams=galsim.GSParams())
    conv.draw(myImg1)
    np.testing.assert_array_almost_equal(
        myImg1.array,
        myImg2.array,
        4,
        err_msg=
        "Using AutoConvolve with GSParams() disagrees with expected result")

    # For a symmetric profile, AutoCorrelate is the same thing:
    conv2 = galsim.AutoCorrelate(psf)
    conv2.draw(myImg2)
    printval(myImg1, myImg2)
    np.testing.assert_array_almost_equal(
        myImg1.array,
        myImg2.array,
        4,
        err_msg="Moffat convolved with self disagrees with AutoCorrelate result"
    )

    # And check AutoCorrelate with gsparams:
    conv2 = galsim.AutoCorrelate(psf, gsparams=default_params)
    conv2.draw(myImg1)
    np.testing.assert_array_almost_equal(
        myImg1.array,
        myImg2.array,
        4,
        err_msg=
        "Using AutoCorrelate with default_params disagrees with expected result"
    )
    conv2 = galsim.AutoCorrelate(psf, gsparams=galsim.GSParams())
    conv2.draw(myImg1)
    np.testing.assert_array_almost_equal(
        myImg1.array,
        myImg2.array,
        4,
        err_msg=
        "Using AutoCorrelate with GSParams() disagrees with expected result")

    # Test photon shooting.
    do_shoot(conv2, myImg2, "AutoConvolve(Moffat)")

    # Also check AutoConvolve with an asymmetric profile.
    # (AutoCorrelate with this profile is done below...)
    obj1 = galsim.Gaussian(sigma=3., flux=4)
    obj1.applyShift(-0.2, -0.4)
    obj2 = galsim.Gaussian(sigma=6., flux=1.3)
    obj2.applyShift(0.3, 0.3)
    add = galsim.Add(obj1, obj2)
    conv = galsim.Convolve([add, add])
    conv.draw(myImg1)
    corr = galsim.AutoConvolve(add)
    corr.draw(myImg2)
    printval(myImg1, myImg2)
    np.testing.assert_array_almost_equal(
        myImg1.array,
        myImg2.array,
        4,
        err_msg=
        "Asymmetric sum of Gaussians convolved with self disagrees with " +
        "AutoConvolve result")

    t2 = time.time()
    print 'time for %s = %.2f' % (funcname(), t2 - t1)
Esempio n. 4
0
def test_realspace_shearconvolve():
    """Test the real-space convolution of a sheared Gaussian and a Box SBProfile against a 
       known result.
    """
    import time
    t1 = time.time()
    psf = galsim.SBGaussian(flux=1, sigma=1)
    e1 = 0.04
    e2 = 0.0
    myShear = galsim.Shear(e1=e1, e2=e2)
    psf.applyShear(myShear._shear)
    pix = galsim.SBBox(xw=0.2, yw=0.2, flux=1.)
    conv = galsim.SBConvolve([psf, pix], real_space=True)
    saved_img = galsim.fits.read(
        os.path.join(imgdir, "gauss_smallshear_convolve_box.fits"))
    img = galsim.ImageF(saved_img.bounds, scale=0.2)
    conv.draw(img.view())
    printval(img, saved_img)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Sheared Gaussian convolved with Box SBProfile disagrees with expected result"
    )

    # Repeat with the GSObject version of this:
    psf = galsim.Gaussian(flux=1, sigma=1)
    psf.applyShear(e1=e1, e2=e2)
    pixel = galsim.Pixel(xw=0.2, yw=0.2, flux=1.)
    conv = galsim.Convolve([psf, pixel], real_space=True)
    conv.draw(img,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Using GSObject Convolve([psf,pixel]) disagrees with expected result")

    # Check with default_params
    conv = galsim.Convolve([psf, pixel],
                           real_space=True,
                           gsparams=default_params)
    conv.draw(img,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Using GSObject Convolve([psf,pixel]) with default_params disagrees with "
        "expected result")
    conv = galsim.Convolve([psf, pixel],
                           real_space=True,
                           gsparams=galsim.GSParams())
    conv.draw(img,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Using GSObject Convolve([psf,pixel]) with GSParams() disagrees with "
        "expected result")

    # Other ways to do the convolution:
    conv = galsim.Convolve(psf, pixel, real_space=True)
    conv.draw(img,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Using GSObject Convolve(psf,pixel) disagrees with expected result")

    # The real-space convolution algorithm is not (trivially) independent of the order of
    # the two things being convolved.  So check the opposite order.
    conv = galsim.Convolve([pixel, psf], real_space=True)
    conv.draw(img,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Using GSObject Convolve([pixel,psf]) disagrees with expected result")

    t2 = time.time()
    print 'time for %s = %.2f' % (funcname(), t2 - t1)
Esempio n. 5
0
def test_convolve():
    """Test the convolution of a Moffat and a Box SBProfile against a known result.
    """
    import time
    t1 = time.time()
    # Code was formerly:
    # mySBP = galsim.SBMoffat(beta=1.5, truncationFWHM=4, flux=1, half_light_radius=1)
    #
    # ...but this is no longer quite so simple since we changed the handling of trunc to be in
    # physical units.  However, the same profile can be constructed using
    # fwhm=1.0927449310213702,
    # as calculated by interval bisection in devutils/external/calculate_moffat_radii.py
    fwhm_backwards_compatible = 1.0927449310213702
    mySBP = galsim.SBMoffat(beta=1.5,
                            fwhm=fwhm_backwards_compatible,
                            trunc=4 * fwhm_backwards_compatible,
                            flux=1)
    mySBP2 = galsim.SBBox(xw=0.2, yw=0.2, flux=1.)
    myConv = galsim.SBConvolve([mySBP, mySBP2])
    # Using an exact Maple calculation for the comparison.  Only accurate to 4 decimal places.
    savedImg = galsim.fits.read(os.path.join(imgdir, "moffat_pixel.fits"))
    myImg = galsim.ImageF(savedImg.bounds, scale=0.2)
    myConv.draw(myImg.view())
    printval(myImg, savedImg)

    np.testing.assert_array_almost_equal(
        myImg.array,
        savedImg.array,
        4,
        err_msg=
        "Moffat convolved with Box SBProfile disagrees with expected result")

    # Repeat with the GSObject version of this:
    psf = galsim.Moffat(beta=1.5,
                        fwhm=fwhm_backwards_compatible,
                        trunc=4 * fwhm_backwards_compatible,
                        flux=1)
    pixel = galsim.Pixel(xw=0.2, yw=0.2, flux=1.)
    # Note: Since both of these have hard edges, GalSim wants to do this with real_space=True.
    # Here we are intentionally tesing the Fourier convolution, so we want to suppress the
    # warning that GalSim emits.
    import warnings
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        # We'll do the real space convolution below
        conv = galsim.Convolve([psf, pixel], real_space=False)
        conv.draw(myImg,
                  dx=0.2,
                  normalization="surface brightness",
                  use_true_center=False)
        np.testing.assert_array_almost_equal(
            myImg.array,
            savedImg.array,
            4,
            err_msg=
            "Using GSObject Convolve([psf,pixel]) disagrees with expected result"
        )

        # Other ways to do the convolution:
        conv = galsim.Convolve(psf, pixel, real_space=False)
        conv.draw(myImg,
                  dx=0.2,
                  normalization="surface brightness",
                  use_true_center=False)
        np.testing.assert_array_almost_equal(
            myImg.array,
            savedImg.array,
            4,
            err_msg=
            "Using GSObject Convolve(psf,pixel) disagrees with expected result"
        )

        # Check with default_params
        conv = galsim.Convolve([psf, pixel],
                               real_space=False,
                               gsparams=default_params)
        conv.draw(myImg,
                  dx=0.2,
                  normalization="surface brightness",
                  use_true_center=False)
        np.testing.assert_array_almost_equal(
            myImg.array,
            savedImg.array,
            4,
            err_msg=
            "Using GSObject Convolve([psf,pixel]) with default_params disagrees with"
            "expected result")
        conv = galsim.Convolve([psf, pixel],
                               real_space=False,
                               gsparams=galsim.GSParams())
        conv.draw(myImg,
                  dx=0.2,
                  normalization="surface brightness",
                  use_true_center=False)
        np.testing.assert_array_almost_equal(
            myImg.array,
            savedImg.array,
            4,
            err_msg=
            "Using GSObject Convolve([psf,pixel]) with GSParams() disagrees with"
            "expected result")

    # Test photon shooting.
    do_shoot(conv, myImg, "Moffat * Pixel")

    t2 = time.time()
    print 'time for %s = %.2f' % (funcname(), t2 - t1)
Esempio n. 6
0
def test_realspace_distorted_convolve():
    """
    The same as above, but both the Moffat and the Box are sheared, rotated and shifted
    to stress test the code that deals with this for real-space convolutions that wouldn't
    be tested otherwise.
    """
    import time
    t1 = time.time()
    fwhm_backwards_compatible = 1.0927449310213702
    psf = galsim.SBMoffat(beta=1.5,
                          half_light_radius=1,
                          trunc=4 * fwhm_backwards_compatible,
                          flux=1)
    #psf = galsim.SBMoffat(beta=1.5, fwhm=fwhm_backwards_compatible,
    #trunc=4*fwhm_backwards_compatible, flux=1)
    psf.applyShear(galsim.Shear(g1=0.11, g2=0.17)._shear)
    psf.applyRotation(13 * galsim.degrees)
    pixel = galsim.SBBox(xw=0.2, yw=0.2, flux=1.)
    pixel.applyShear(galsim.Shear(g1=0.2, g2=0.0)._shear)
    pixel.applyRotation(80 * galsim.degrees)
    pixel.applyShift(0.13, 0.27)
    conv = galsim.SBConvolve([psf, pixel], real_space=True)

    # Note: Using an image created from Maple "exact" calculations.
    saved_img = galsim.fits.read(
        os.path.join(imgdir, "moffat_pixel_distorted.fits"))
    img = galsim.ImageF(saved_img.bounds, scale=0.2)
    conv.draw(img.view())
    printval(img, saved_img)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "distorted Moffat convolved with distorted Box disagrees with expected result"
    )

    # Repeat with the GSObject version of this:
    psf = galsim.Moffat(beta=1.5,
                        half_light_radius=1,
                        trunc=4 * fwhm_backwards_compatible,
                        flux=1)
    #psf = galsim.Moffat(beta=1.5, fwhm=fwhm_backwards_compatible,
    #trunc=4*fwhm_backwards_compatible, flux=1)
    psf.applyShear(g1=0.11, g2=0.17)
    psf.applyRotation(13 * galsim.degrees)
    pixel = galsim.Pixel(xw=0.2, yw=0.2, flux=1.)
    pixel.applyShear(g1=0.2, g2=0.0)
    pixel.applyRotation(80 * galsim.degrees)
    pixel.applyShift(0.13, 0.27)
    # NB: real-space is chosen automatically
    conv = galsim.Convolve([psf, pixel])
    conv.draw(img,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Using Convolve([psf,pixel]) (distorted) disagrees with expected result"
    )

    # Check with default_params
    conv = galsim.Convolve([psf, pixel], gsparams=default_params)
    conv.draw(img,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Using Convolve([psf,pixel]) (distorted) with default_params disagrees with "
        "expected result")
    conv = galsim.Convolve([psf, pixel], gsparams=galsim.GSParams())
    conv.draw(img,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Using Convolve([psf,pixel]) (distorted) with GSParams() disagrees with "
        "expected result")

    # Other ways to do the convolution:
    conv = galsim.Convolve(psf, pixel)
    conv.draw(img,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Using Convolve(psf,pixel) (distorted) disagrees with expected result")

    # The real-space convolution algorithm is not (trivially) independent of the order of
    # the two things being convolved.  So check the opposite order.
    conv = galsim.Convolve([pixel, psf])
    conv.draw(img,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Using Convolve([pixel,psf]) (distorted) disagrees with expected result"
    )

    t2 = time.time()
    print 'time for %s = %.2f' % (funcname(), t2 - t1)
Esempio n. 7
0
def test_realspace_convolve():
    """Test the real-space convolution of a Moffat and a Box SBProfile against a known result.
    """
    import time
    t1 = time.time()
    # Code was formerly:
    # mySBP = galsim.SBMoffat(beta=1.5, truncationFWHM=4, flux=1, half_light_radius=1)
    #
    # ...but this is no longer quite so simple since we changed the handling of trunc to be in
    # physical units.  However, the same profile can be constructed using
    # fwhm=1.0927449310213702,
    # as calculated by interval bisection in devutils/external/calculate_moffat_radii.py
    fwhm_backwards_compatible = 1.0927449310213702
    #psf = galsim.SBMoffat(beta=1.5, fwhm=fwhm_backwards_compatible,
    #trunc=4*fwhm_backwards_compatible, flux=1)
    psf = galsim.SBMoffat(beta=1.5,
                          half_light_radius=1,
                          trunc=4 * fwhm_backwards_compatible,
                          flux=1)
    pixel = galsim.SBBox(xw=0.2, yw=0.2, flux=1.)
    conv = galsim.SBConvolve([psf, pixel], real_space=True)
    # Note: Using an image created from Maple "exact" calculations.
    saved_img = galsim.fits.read(os.path.join(imgdir, "moffat_pixel.fits"))
    img = galsim.ImageF(saved_img.bounds, scale=0.2)
    conv.draw(img.view())
    printval(img, saved_img)
    arg = abs(saved_img.array - img.array).argmax()
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Moffat convolved with Box SBProfile disagrees with expected result")

    # Repeat with the GSObject version of this:
    psf = galsim.Moffat(beta=1.5,
                        half_light_radius=1,
                        trunc=4 * fwhm_backwards_compatible,
                        flux=1)
    #psf = galsim.Moffat(beta=1.5, fwhm=fwhm_backwards_compatible,
    #trunc=4*fwhm_backwards_compatible, flux=1)
    pixel = galsim.Pixel(xw=0.2, yw=0.2, flux=1.)
    conv = galsim.Convolve([psf, pixel], real_space=True)
    conv.draw(img,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Using GSObject Convolve([psf,pixel]) disagrees with expected result")

    # Check with default_params
    conv = galsim.Convolve([psf, pixel],
                           real_space=True,
                           gsparams=default_params)
    conv.draw(img,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Using GSObject Convolve([psf,pixel]) with default_params disagrees with "
        "expected result")
    conv = galsim.Convolve([psf, pixel],
                           real_space=True,
                           gsparams=galsim.GSParams())
    conv.draw(img,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Using GSObject Convolve([psf,pixel]) with GSParams() disagrees with "
        "expected result")

    # Other ways to do the convolution:
    conv = galsim.Convolve(psf, pixel, real_space=True)
    conv.draw(img,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Using GSObject Convolve(psf,pixel) disagrees with expected result")

    # The real-space convolution algorithm is not (trivially) independent of the order of
    # the two things being convolved.  So check the opposite order.
    conv = galsim.Convolve([pixel, psf], real_space=True)
    conv.draw(img,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        img.array,
        saved_img.array,
        5,
        err_msg=
        "Using GSObject Convolve([pixel,psf]) disagrees with expected result")

    # Test kvalues
    do_kvalue(conv, "Truncated Moffat convolved with Box")

    t2 = time.time()
    print 'time for %s = %.2f' % (funcname(), t2 - t1)
Esempio n. 8
0
def test_shearconvolve():
    """Test the convolution of a sheared Gaussian and a Box SBProfile against a known result.
    """
    import time
    t1 = time.time()
    e1 = 0.04
    e2 = 0.0
    myShear = galsim.Shear(e1=e1, e2=e2)
    # test at SBProfile level using applyShear
    mySBP = galsim.SBGaussian(flux=1, sigma=1)
    mySBP.applyShear(myShear._shear)
    mySBP2 = galsim.SBBox(xw=0.2, yw=0.2, flux=1.)
    myConv = galsim.SBConvolve([mySBP, mySBP2])
    savedImg = galsim.fits.read(
        os.path.join(imgdir, "gauss_smallshear_convolve_box.fits"))
    myImg = galsim.ImageF(savedImg.bounds, scale=0.2)
    myConv.draw(myImg.view())
    printval(myImg, savedImg)
    np.testing.assert_array_almost_equal(
        myImg.array,
        savedImg.array,
        5,
        err_msg=
        "Sheared Gaussian convolved with Box SBProfile disagrees with expected result"
    )

    # Repeat with the GSObject version of this:
    psf = galsim.Gaussian(flux=1, sigma=1)
    psf2 = psf.createSheared(e1=e1, e2=e2)
    psf.applyShear(e1=e1, e2=e2)
    pixel = galsim.Pixel(xw=0.2, yw=0.2, flux=1.)
    conv = galsim.Convolve([psf, pixel])
    conv.draw(myImg,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        myImg.array,
        savedImg.array,
        5,
        err_msg=
        "Using GSObject Convolve([psf,pixel]) disagrees with expected result")
    conv2 = galsim.Convolve([psf2, pixel])
    conv2.draw(myImg,
               dx=0.2,
               normalization="surface brightness",
               use_true_center=False)
    np.testing.assert_array_almost_equal(
        myImg.array,
        savedImg.array,
        5,
        err_msg=
        "Using GSObject Convolve([psf,pixel]) disagrees with expected result")

    # Check with default_params
    conv = galsim.Convolve([psf, pixel], gsparams=default_params)
    conv.draw(myImg,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        myImg.array,
        savedImg.array,
        5,
        err_msg=
        "Using GSObject Convolve([psf,pixel]) with default_params disagrees with "
        "expected result")
    conv = galsim.Convolve([psf, pixel], gsparams=galsim.GSParams())
    conv.draw(myImg,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        myImg.array,
        savedImg.array,
        5,
        err_msg=
        "Using GSObject Convolve([psf,pixel]) with GSParams() disagrees with "
        "expected result")

    # Other ways to do the convolution:
    conv = galsim.Convolve(psf, pixel)
    conv.draw(myImg,
              dx=0.2,
              normalization="surface brightness",
              use_true_center=False)
    np.testing.assert_array_almost_equal(
        myImg.array,
        savedImg.array,
        5,
        err_msg=
        "Using GSObject Convolve(psf,pixel) disagrees with expected result")

    # Test photon shooting.
    do_shoot(conv, myImg, "sheared Gaussian * Pixel")

    t2 = time.time()
    print 'time for %s = %.2f' % (funcname(), t2 - t1)
Esempio n. 9
0
    def __init__(self, *args, **kwargs):

        # First check for number of arguments != 0
        if len(args) == 0:
            # No arguments. Could initialize with an empty list but draw then segfaults. Raise an
            # exception instead.
            raise ValueError("Convolve must be initialized with at least one GSObject.")
        elif len(args) == 1:
            if isinstance(args[0], GSObject):
                SBList = [args[0].SBProfile]
            elif isinstance(args[0], list):
                SBList=[]
                for obj in args[0]:
                    if isinstance(obj, GSObject):
                        SBList.append(obj.SBProfile)
                    else:
                        raise TypeError("Input list must contain only GSObjects.")
            else:
                raise TypeError("Single input argument must be a GSObject or list of them.")
        elif len(args) >= 2:
            # >= 2 arguments.  Convert to a list of SBProfiles
            SBList = []
            for obj in args:
                if isinstance(obj, GSObject):
                    SBList.append(obj.SBProfile)
                else:
                    raise TypeError("Input args must contain only GSObjects.")

        # Having built the list of SBProfiles or thrown exceptions if necessary, see now whether
        # to perform real space convolution...

        # Check kwargs
        # real_space can be True or False (default if omitted is None), which specifies whether to 
        # do the convolution as an integral in real space rather than as a product in fourier 
        # space.  If the parameter is omitted (or explicitly given as None I guess), then
        # we will usually do the fourier method.  However, if there are 2 components _and_ both of 
        # them have hard edges, then we use real-space convolution.
        real_space = kwargs.pop("real_space", None)

        gsparams = kwargs.pop("gsparams", None)

        # Make sure there is nothing left in the dict.
        if kwargs:
            raise TypeError(
                "Convolve constructor got unexpected keyword argument(s): %s"%kwargs.keys())


        # If 1 argument, check if it is a list:
        if len(args) == 1 and isinstance(args[0], list):
            args = args[0]

        hard_edge = True
        for obj in args:
            if not obj.hasHardEdges():
                hard_edge = False

        if real_space is None:
            # Figure out if it makes more sense to use real-space convolution.
            if len(args) == 2:
                real_space = hard_edge
            elif len(args) == 1:
                real_space = obj.isAnalyticX()
            else:
                real_space = False
        
        # Warn if doing DFT convolution for objects with hard edges.
        if not real_space and hard_edge:
            import warnings
            if len(args) == 2:
                msg = """
                Doing convolution of 2 objects, both with hard edges.
                This might be more accurate and/or faster using real_space=True"""
            else:
                msg = """
                Doing convolution where all objects have hard edges.
                There might be some inaccuracies due to ringing in k-space."""
            warnings.warn(msg)

        if real_space:
            # Can't do real space if nobj > 2
            if len(args) > 2:
                import warnings
                msg = """
                Real-space convolution of more than 2 objects is not implemented.
                Switching to DFT method."""
                warnings.warn(msg)
                real_space = False

            # Also can't do real space if any object is not analytic, so check for that.
            else:
                for obj in args:
                    if not obj.isAnalyticX():
                        import warnings
                        msg = """
                        A component to be convolved is not analytic in real space.
                        Cannot use real space convolution.
                        Switching to DFT method."""
                        warnings.warn(msg)
                        real_space = False
                        break

        # Then finally initialize the SBProfile using the objects' SBProfiles in SBList
        GSObject.__init__(self, galsim.SBConvolve(SBList, real_space=real_space,
                                                  gsparams=gsparams))
Esempio n. 10
0
                desq = de1 * de1 + de2 * de2
                if desq > 0.:
                    de = np.sqrt(desq)
                    dg = math.tanh(0.5 * math.atanh(de))
                    dg1 = de1 * (dg / de)
                    dg2 = de2 * (dg / de)
                else:
                    dg1 = 0.0
                    dg2 = 0.0
                disk.applyShear(g1=dg1, g2=dg2)

                # Rescale fluxes and add: use the overloaded multiplication and addition operators
                galaxy = bt * bulge + (1.0 - bt) * disk

                # Convolve with PSF, and draw image
                convGalaxy = galsim.SBConvolve([PSF, galaxy.SBProfile])
                convGalaxyImg = convGalaxy.draw(dx=pixelScale)

                # More noise realizations?
                for invsnind in range(len(invSN)):
                    print "Beginning inverse S/N of ", invSN[invsnind]
                    if invSN[invsnind] > 0.0:
                        # Choose Gaussian sigma per pixel based on GREAT08-style S/N definition
                        gaussSig = invSN[invsnind] * np.sqrt(
                            np.sum(convGalaxyImg.array**(2.0)))

                        # Add noise the appropriate number of times, and write each one to file
                        for iRealization in range(nRealization[invsnind]):
                            tmpImg = convGalaxyImg.copy()
                            tmpImg.addNoise(
                                galsim.GaussianDeviate(rng,