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)
def mockCoadd(self, variances, fwhms, psfs): weights = 1.0 / variances weights /= weights.sum() coadd_variance = 1.0 / (1.0 / variances).sum() coadd_psf = galsim.FourierSqrt( galsim.Sum([ galsim.AutoCorrelate(psf) * weight for psf, weight in zip(psfs, weights) ])) return coadd_variance, coadd_psf
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) """ dx = 0.7 myImg1 = galsim.ImageF(80, 80, scale=dx) myImg1.setCenter(0, 0) myImg2 = galsim.ImageF(80, 80, scale=dx) myImg2.setCenter(0, 0) # Use a function that is NOT two-fold rotationally symmetric, e.g. two different flux Gaussians obj1 = galsim.Gaussian(sigma=3., flux=4).shift(-0.2, -0.4) obj2 = galsim.Gaussian(sigma=6., flux=1.3).shift(0.3, 0.3) add1 = galsim.Add(obj1, obj2) # Here we rotate by 180 degrees to create mirror image add2 = (galsim.Add(obj1, obj2)).rotate(180. * galsim.degrees) conv = galsim.Convolve([add1, add2]) conv.drawImage(myImg1, method='no_pixel') corr = galsim.AutoCorrelate(add1) corr.drawImage(myImg2, method='no_pixel') 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") check_basic(conv, "AutoCorrelate") # Test photon shooting. do_shoot(corr, myImg2, "AutoCorrelate") # Check picklability do_pickle(corr, lambda x: x.drawImage(method='no_pixel')) do_pickle(corr) # Should raise an exception for invalid arguments assert_raises(TypeError, galsim.AutoCorrelate) assert_raises(TypeError, galsim.AutoCorrelate, myImg1) assert_raises(TypeError, galsim.AutoCorrelate, [obj1]) assert_raises(TypeError, galsim.AutoCorrelate, obj1, obj2) assert_raises(TypeError, galsim.AutoCorrelate, obj1, realspace=False) assert_raises(TypeError, galsim.AutoCorrelation) assert_raises(TypeError, galsim.AutoCorrelation, myImg1) assert_raises(TypeError, galsim.AutoCorrelation, [obj1]) assert_raises(TypeError, galsim.AutoCorrelation, obj1, obj2) assert_raises(TypeError, galsim.AutoCorrelation, obj1, realspace=False)
def convolveWith(self, gsobject, gsparams=None): """Convolve the correlated noise model with an input GSObject. The resulting correlated noise model will then give a statistical description of the noise field that would result from convolving noise generated according to the initial correlated noise with a kernel represented by `gsobject` (e.g. a PSF). The practical purpose of this method is that it allows us to model what is happening to noise in the images from Hubble Space Telescope that we use for simulating PSF convolved galaxies with the galsim.RealGalaxy class. This modifies the representation of the correlation function, but leaves the random number generator unchanged. Examples -------- The following command simply applies a galsim.Moffat PSF with slope parameter `beta`=3. and FWHM=0.7: >>> correlated_noise.convolveWith(galsim.Moffat(beta=3., fwhm=0.7)) Often we will want to convolve with more than one function. For example, if we wanted to simulate how a noise field would look if convolved with a ground-based PSF (such as the Moffat above) and then rendered onto a new (typically larger) pixel grid, the following example command demonstrates the syntax: >>> correlated_noise.convolveWith( ... galsim.Convolve([galsim.Deconvolve(galsim.Pixel(0.03)), ... galsim.Pixel(0.2), galsim.Moffat(3., fwhm=0.7), Note, we also deconvolve by the original pixel, which should be the pixel size of the image from which the `correlated_noise` was made. This command above is functionally equivalent to >>> correlated_noise.convolveWith(galsim.Deconvolve(galsim.Pixel(0.03))) >>> correlated_noise.convolveWith(galsim.Pixel(0.2)) >>> correlated_noise.convolveWith(galsim.Moffat(beta=3., fwhm=0.7)) as is demanded for a linear operation such as convolution. @param gsobject A galsim.GSObject or derived class instance representing the function with which the user wants to convolve the correlated noise model. @param gsparams You may also specify a gsparams argument. See the docstring for GSObject for more information about this option. """ self._profile = galsim.Convolve( [self._profile, galsim.AutoCorrelate(gsobject)], gsparams=gsparams)
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() dx = 0.7 myImg1 = galsim.ImageF(80, 80, scale=dx) myImg1.setCenter(0, 0) myImg2 = galsim.ImageF(80, 80, scale=dx) myImg2.setCenter(0, 0) # Use a function that is NOT two-fold rotationally symmetric, e.g. two different flux Gaussians obj1 = galsim.Gaussian(sigma=3., flux=4).shift(-0.2, -0.4) obj2 = galsim.Gaussian(sigma=6., flux=1.3).shift(0.3, 0.3) add1 = galsim.Add(obj1, obj2) # Here we rotate by 180 degrees to create mirror image add2 = (galsim.Add(obj1, obj2)).rotate(180. * galsim.degrees) conv = galsim.Convolve([add1, add2]) conv.drawImage(myImg1, method='no_pixel') corr = galsim.AutoCorrelate(add1) corr.drawImage(myImg2, method='no_pixel') 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") # Check picklability do_pickle(corr.SBProfile, lambda x: (repr(x.getObj()), x.isRealSpace(), x.getGSParams())) do_pickle(corr, lambda x: x.drawImage(method='no_pixel')) do_pickle(corr) do_pickle(corr.SBProfile) t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
def test_autoconvolve(): """Test that auto-convolution works the same as convolution with itself. """ dx = 0.4 myImg1 = galsim.ImageF(80, 80, scale=dx) myImg1.setCenter(0, 0) myImg2 = galsim.ImageF(80, 80, scale=dx) myImg2.setCenter(0, 0) psf = galsim.Moffat(beta=3.8, fwhm=1.3, flux=5) conv = galsim.Convolve([psf, psf]) conv.drawImage(myImg1, method='no_pixel') conv2 = galsim.AutoConvolve(psf) conv2.drawImage(myImg2, method='no_pixel') 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.drawImage(myImg1, method='no_pixel') 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.drawImage(myImg1, method='no_pixel') np.testing.assert_array_almost_equal( myImg1.array, myImg2.array, 4, err_msg= "Using AutoConvolve with GSParams() disagrees with expected result") check_basic(conv, "AutoConvolve(Moffat)") cen = galsim.PositionD(0, 0) np.testing.assert_equal(conv2.centroid, cen) np.testing.assert_almost_equal(conv2.flux, psf.flux**2) np.testing.assert_array_less(conv2.xValue(cen), conv2.max_sb) # Check picklability do_pickle(conv2, lambda x: x.drawImage(method='no_pixel')) do_pickle(conv2) # Test photon shooting. do_shoot(conv2, myImg2, "AutoConvolve(Moffat)") # For a symmetric profile, AutoCorrelate is the same thing: conv2 = galsim.AutoCorrelate(psf) conv2.drawImage(myImg2, method='no_pixel') 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.drawImage(myImg1, method='no_pixel') 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.drawImage(myImg1, method='no_pixel') np.testing.assert_array_almost_equal( myImg1.array, myImg2.array, 4, err_msg= "Using AutoCorrelate with GSParams() disagrees with expected result") cen = galsim.PositionD(0, 0) np.testing.assert_equal(conv2.centroid, cen) np.testing.assert_almost_equal(conv2.flux, psf.flux**2) np.testing.assert_array_less(conv2.xValue(cen), conv2.max_sb) # Also check AutoConvolve with an asymmetric profile. # (AutoCorrelate with this profile is done below...) obj1 = galsim.Gaussian(sigma=3., flux=4).shift(-0.2, -0.4) obj2 = galsim.Gaussian(sigma=6., flux=1.3).shift(0.3, 0.3) add = galsim.Add(obj1, obj2) conv = galsim.Convolve([add, add]) conv.drawImage(myImg1, method='no_pixel') autoconv = galsim.AutoConvolve(add) autoconv.drawImage(myImg2, method='no_pixel') 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") cen = 2. * add.centroid np.testing.assert_equal(autoconv.centroid, cen) np.testing.assert_almost_equal(autoconv.flux, add.flux**2) np.testing.assert_array_less(autoconv.xValue(cen), autoconv.max_sb) check_basic(autoconv, "AutoConvolve(asym)") # Should raise an exception for invalid arguments assert_raises(TypeError, galsim.AutoConvolve) assert_raises(TypeError, galsim.AutoConvolve, myImg1) assert_raises(TypeError, galsim.AutoConvolve, [psf]) assert_raises(TypeError, galsim.AutoConvolve, psf, psf) assert_raises(TypeError, galsim.AutoConvolve, psf, realspace=False) assert_raises(TypeError, galsim.AutoConvolution) assert_raises(TypeError, galsim.AutoConvolution, myImg1) assert_raises(TypeError, galsim.AutoConvolution, [psf]) assert_raises(TypeError, galsim.AutoConvolution, psf, psf) assert_raises(TypeError, galsim.AutoConvolution, psf, realspace=False)
def test_realspace_convolve(): """Test the real-space convolution of a Moffat and a Box profile against a known result. """ dx = 0.2 # 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=dx) img.setCenter(0, 0) # Code was formerly: # psf = galsim.Moffat(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.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(scale=dx, flux=1.) conv = galsim.Convolve([psf, pixel], real_space=True) conv.drawImage(img, scale=dx, method="sb", 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.drawImage(img, scale=dx, method="sb", 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.drawImage(img, scale=dx, method="sb", 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.drawImage(img, scale=dx, method="sb", 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.drawImage(img, scale=dx, method="sb", 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") check_basic(conv, "Truncated Moffat*Box", approx_maxsb=True) # Test kvalues do_kvalue(conv, img, "Truncated Moffat*Box") # Check picklability do_pickle(conv, lambda x: x.drawImage(method='sb')) do_pickle(conv) # Check some warnings that should be raised # More than 2 with only hard edges gives a warning either way. (Different warnings though.) assert_warns(galsim.GalSimWarning, galsim.Convolve, [psf, psf, pixel]) assert_warns(galsim.GalSimWarning, galsim.Convolve, [psf, psf, pixel], real_space=False) assert_warns(galsim.GalSimWarning, galsim.Convolve, [psf, psf, pixel], real_space=True) # 2 with hard edges gives a warning if we ask it not to use real_space assert_warns(galsim.GalSimWarning, galsim.Convolve, [psf, pixel], real_space=False) # >2 of any kind give a warning if we ask it to use real_space g = galsim.Gaussian(sigma=2) assert_warns(galsim.GalSimWarning, galsim.Convolve, [g, g, g], real_space=True) # non-analytic profiles cannot do real_space d = galsim.Deconvolve(galsim.Gaussian(sigma=2)) assert_warns(galsim.GalSimWarning, galsim.Convolve, [g, d], real_space=True) assert_raises(TypeError, galsim.Convolve, [g, d], real_space='true') # Repeat some of the above for AutoConvolve and AutoCorrelate conv = galsim.AutoConvolve(psf, real_space=True) check_basic(conv, "AutoConvolve Truncated Moffat", approx_maxsb=True) do_kvalue(conv, img, "AutoConvolve Truncated Moffat") do_pickle(conv) conv = galsim.AutoCorrelate(psf, real_space=True) check_basic(conv, "AutoCorrelate Truncated Moffat", approx_maxsb=True) do_kvalue(conv, img, "AutoCorrelate Truncated Moffat") do_pickle(conv) assert_warns(galsim.GalSimWarning, galsim.AutoConvolve, psf, real_space=False) assert_warns(galsim.GalSimWarning, galsim.AutoConvolve, d, real_space=True) assert_warns(galsim.GalSimWarning, galsim.AutoCorrelate, psf, real_space=False) assert_warns(galsim.GalSimWarning, galsim.AutoCorrelate, d, real_space=True) assert_raises(TypeError, galsim.AutoConvolve, d, real_space='true') assert_raises(TypeError, galsim.AutoCorrelate, d, real_space='true')
def test_gsparams(): """Test withGSParams with some non-default gsparams """ obj1 = galsim.Exponential(half_light_radius=1.7) obj2 = galsim.Pixel(scale=0.2) gsp = galsim.GSParams(folding_threshold=1.e-4, maxk_threshold=1.e-4, maximum_fft_size=1.e4) gsp2 = galsim.GSParams(folding_threshold=1.e-2, maxk_threshold=1.e-2) # Convolve conv = galsim.Convolve(obj1, obj2) conv1 = conv.withGSParams(gsp) assert conv.gsparams == galsim.GSParams() assert conv1.gsparams == gsp assert conv1.obj_list[0].gsparams == gsp assert conv1.obj_list[1].gsparams == gsp conv2 = galsim.Convolve(obj1.withGSParams(gsp), obj2.withGSParams(gsp)) conv3 = galsim.Convolve( galsim.Exponential(half_light_radius=1.7, gsparams=gsp), galsim.Pixel(scale=0.2)) conv4 = galsim.Convolve(obj1, obj2, gsparams=gsp) assert conv != conv1 assert conv1 == conv2 assert conv1 == conv3 assert conv1 == conv4 print('stepk = ', conv.stepk, conv1.stepk) assert conv1.stepk < conv.stepk print('maxk = ', conv.maxk, conv1.maxk) assert conv1.maxk > conv.maxk conv5 = galsim.Convolve(obj1, obj2, gsparams=gsp, propagate_gsparams=False) assert conv5 != conv4 assert conv5.gsparams == gsp assert conv5.obj_list[0].gsparams == galsim.GSParams() assert conv5.obj_list[1].gsparams == galsim.GSParams() conv6 = conv5.withGSParams(gsp2) assert conv6 != conv5 assert conv6.gsparams == gsp2 assert conv6.obj_list[0].gsparams == galsim.GSParams() assert conv6.obj_list[1].gsparams == galsim.GSParams() # AutoConvolve conv = galsim.AutoConvolve(obj1) conv1 = conv.withGSParams(gsp) assert conv.gsparams == galsim.GSParams() assert conv1.gsparams == gsp assert conv1.orig_obj.gsparams == gsp conv2 = galsim.AutoConvolve(obj1.withGSParams(gsp)) conv3 = galsim.AutoConvolve(obj1, gsparams=gsp) assert conv != conv1 assert conv1 == conv2 assert conv1 == conv3 print('stepk = ', conv.stepk, conv1.stepk) assert conv1.stepk < conv.stepk print('maxk = ', conv.maxk, conv1.maxk) assert conv1.maxk > conv.maxk conv4 = galsim.AutoConvolve(obj1, gsparams=gsp, propagate_gsparams=False) assert conv4 != conv3 assert conv4.gsparams == gsp assert conv4.orig_obj.gsparams == galsim.GSParams() conv5 = conv4.withGSParams(gsp2) assert conv5 != conv4 assert conv5.gsparams == gsp2 assert conv5.orig_obj.gsparams == galsim.GSParams() # AutoCorrelate conv = galsim.AutoCorrelate(obj1) conv1 = conv.withGSParams(gsp) assert conv.gsparams == galsim.GSParams() assert conv1.gsparams == gsp assert conv1.orig_obj.gsparams == gsp conv2 = galsim.AutoCorrelate(obj1.withGSParams(gsp)) conv3 = galsim.AutoCorrelate(obj1, gsparams=gsp) assert conv != conv1 assert conv1 == conv2 assert conv1 == conv3 print('stepk = ', conv.stepk, conv1.stepk) assert conv1.stepk < conv.stepk print('maxk = ', conv.maxk, conv1.maxk) assert conv1.maxk > conv.maxk conv4 = galsim.AutoCorrelate(obj1, gsparams=gsp, propagate_gsparams=False) assert conv4 != conv3 assert conv4.gsparams == gsp assert conv4.orig_obj.gsparams == galsim.GSParams() conv5 = conv4.withGSParams(gsp2) assert conv5 != conv4 assert conv5.gsparams == gsp2 assert conv5.orig_obj.gsparams == galsim.GSParams() # Deconvolve conv = galsim.Convolve(obj1, galsim.Deconvolve(obj2)) conv1 = conv.withGSParams(gsp) assert conv.gsparams == galsim.GSParams() assert conv1.gsparams == gsp assert conv1.obj_list[0].gsparams == gsp assert conv1.obj_list[1].gsparams == gsp assert conv1.obj_list[1].orig_obj.gsparams == gsp conv2 = galsim.Convolve(obj1, galsim.Deconvolve(obj2.withGSParams(gsp))) conv3 = galsim.Convolve(obj1.withGSParams(gsp), galsim.Deconvolve(obj2)) conv4 = galsim.Convolve(obj1, galsim.Deconvolve(obj2, gsparams=gsp)) assert conv != conv1 assert conv1 == conv2 assert conv1 == conv3 assert conv1 == conv4 print('stepk = ', conv.stepk, conv1.stepk) assert conv1.stepk < conv.stepk print('maxk = ', conv.maxk, conv1.maxk) assert conv1.maxk > conv.maxk conv5 = galsim.Convolve( obj1, galsim.Deconvolve(obj2, gsparams=gsp, propagate_gsparams=False)) assert conv5 != conv4 assert conv5.gsparams == gsp assert conv5.obj_list[0].gsparams == gsp assert conv5.obj_list[1].gsparams == gsp assert conv5.obj_list[1].orig_obj.gsparams == galsim.GSParams() conv6 = conv5.withGSParams(gsp2) assert conv6 != conv5 assert conv6.gsparams == gsp2 assert conv6.obj_list[0].gsparams == gsp2 assert conv6.obj_list[1].gsparams == gsp2 assert conv6.obj_list[1].orig_obj.gsparams == galsim.GSParams() # FourierSqrt conv = galsim.Convolve(obj1, galsim.FourierSqrt(obj2)) conv1 = conv.withGSParams(gsp) assert conv.gsparams == galsim.GSParams() assert conv1.gsparams == gsp assert conv1.obj_list[0].gsparams == gsp assert conv1.obj_list[1].gsparams == gsp assert conv1.obj_list[1].orig_obj.gsparams == gsp conv2 = galsim.Convolve(obj1, galsim.FourierSqrt(obj2.withGSParams(gsp))) conv3 = galsim.Convolve(obj1.withGSParams(gsp), galsim.FourierSqrt(obj2)) conv4 = galsim.Convolve(obj1, galsim.FourierSqrt(obj2, gsparams=gsp)) assert conv != conv1 assert conv1 == conv2 assert conv1 == conv3 assert conv1 == conv4 print('stepk = ', conv.stepk, conv1.stepk) assert conv1.stepk < conv.stepk print('maxk = ', conv.maxk, conv1.maxk) assert conv1.maxk > conv.maxk conv5 = galsim.Convolve( obj1, galsim.FourierSqrt(obj2, gsparams=gsp, propagate_gsparams=False)) assert conv5 != conv4 assert conv5.gsparams == gsp assert conv5.obj_list[0].gsparams == gsp assert conv5.obj_list[1].gsparams == gsp assert conv5.obj_list[1].orig_obj.gsparams == galsim.GSParams() conv6 = conv5.withGSParams(gsp2) assert conv6 != conv5 assert conv6.gsparams == gsp2 assert conv6.obj_list[0].gsparams == gsp2 assert conv6.obj_list[1].gsparams == gsp2 assert conv6.obj_list[1].orig_obj.gsparams == galsim.GSParams()
def test_autoconvolve(): """Test that auto-convolution works the same as convolution with itself. """ import time t1 = time.time() dx = 0.4 myImg1 = galsim.ImageF(80,80, scale=dx) myImg1.setCenter(0,0) myImg2 = galsim.ImageF(80,80, scale=dx) myImg2.setCenter(0,0) psf = galsim.Moffat(beta=3.8, fwhm=1.3, flux=5) conv = galsim.Convolve([psf,psf]) conv.drawImage(myImg1, method='no_pixel') conv2 = galsim.AutoConvolve(psf) conv2.drawImage(myImg2, method='no_pixel') 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.drawImage(myImg1, method='no_pixel') 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.drawImage(myImg1, method='no_pixel') 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.drawImage(myImg2, method='no_pixel') 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.drawImage(myImg1, method='no_pixel') 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.drawImage(myImg1, method='no_pixel') 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).shift(-0.2, -0.4) obj2 = galsim.Gaussian(sigma=6., flux=1.3).shift(0.3, 0.3) add = galsim.Add(obj1, obj2) conv = galsim.Convolve([add, add]) conv.drawImage(myImg1, method='no_pixel') corr = galsim.AutoConvolve(add) corr.drawImage(myImg2, method='no_pixel') 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") # Check picklability do_pickle(conv2.SBProfile, lambda x: (repr(x.getObj()), x.isRealSpace(), x.getGSParams())) do_pickle(conv2, lambda x: x.drawImage(method='no_pixel')) do_pickle(conv2) do_pickle(conv2.SBProfile) t2 = time.time() print 'time for %s = %.2f'%(funcname(),t2-t1)
def test_flip(): """Test several ways to flip a profile """ # The Shapelet profile has the advantage of being fast and not circularly symmetric, so # it is a good test of the actual code for doing the flips (in SBTransform). # But since the bug Rachel reported in #645 was actually in SBInterpolatedImage # (one calculation implicitly assumed dx > 0), it seems worthwhile to run through all the # classes to make sure we hit everything with negative steps for dx and dy. prof_list = [ galsim.Shapelet(sigma=0.17, order=2, bvec=[1.7, 0.01,0.03, 0.29, 0.33, -0.18]), ] if __name__ == "__main__": image_dir = './real_comparison_images' catalog_file = 'test_catalog.fits' rgc = galsim.RealGalaxyCatalog(catalog_file, dir=image_dir) # Some of these are slow, so only do the Shapelet test as part of the normal unit tests. prof_list += [ galsim.Airy(lam_over_diam=0.17, flux=1.7), galsim.Airy(lam_over_diam=0.17, obscuration=0.2, flux=1.7), # Box gets rendered with real-space convolution. The default accuracy isn't quite # enough to get the flip to match at 6 decimal places. galsim.Box(0.17, 0.23, flux=1.7, gsparams=galsim.GSParams(realspace_relerr=1.e-6)), # Without being convolved by anything with a reasonable k cutoff, this needs # a very large fft. galsim.DeVaucouleurs(half_light_radius=0.17, flux=1.7), # I don't really understand why this needs a lower maxk_threshold to work, but # without it, the k-space tests fail. galsim.Exponential(scale_radius=0.17, flux=1.7, gsparams=galsim.GSParams(maxk_threshold=1.e-4)), galsim.Gaussian(sigma=0.17, flux=1.7), galsim.Kolmogorov(fwhm=0.17, flux=1.7), galsim.Moffat(beta=2.5, fwhm=0.17, flux=1.7), galsim.Moffat(beta=2.5, fwhm=0.17, flux=1.7, trunc=0.82), galsim.OpticalPSF(lam_over_diam=0.17, obscuration=0.2, nstruts=6, coma1=0.2, coma2=0.5, defocus=-0.1, flux=1.7), # Like with Box, we need to increase the real-space convolution accuracy. # This time lowering both relerr and abserr. galsim.Pixel(0.23, flux=1.7, gsparams=galsim.GSParams(realspace_relerr=1.e-6, realspace_abserr=1.e-8)), # Note: RealGalaxy should not be rendered directly because of the deconvolution. # Here we convolve it by a Gaussian that is slightly larger than the original PSF. galsim.Convolve([ galsim.RealGalaxy(rgc, index=0, flux=1.7), # "Real" RealGalaxy galsim.Gaussian(sigma=0.08) ]), galsim.Convolve([ galsim.RealGalaxy(rgc, index=1, flux=1.7), # "Fake" RealGalaxy galsim.Gaussian(sigma=0.08) ]), # (cf. test_real.py) galsim.Spergel(nu=-0.19, half_light_radius=0.17, flux=1.7), galsim.Spergel(nu=0., half_light_radius=0.17, flux=1.7), galsim.Spergel(nu=0.8, half_light_radius=0.17, flux=1.7), galsim.Sersic(n=2.3, half_light_radius=0.17, flux=1.7), galsim.Sersic(n=2.3, half_light_radius=0.17, flux=1.7, trunc=0.82), # The shifts here caught a bug in how SBTransform handled the recentering. # Two of the shifts (0.125 and 0.375) lead back to 0.0 happening on an integer # index, which now works correctly. galsim.Sum([ galsim.Gaussian(sigma=0.17, flux=1.7).shift(-0.2,0.125), galsim.Exponential(scale_radius=0.23, flux=3.1).shift(0.375,0.23)]), galsim.TopHat(0.23, flux=1.7), # Box and Pixel use real-space convolution. Convolve with a Gaussian to get fft. galsim.Convolve([ galsim.Box(0.17, 0.23, flux=1.7).shift(-0.2,0.1), galsim.Gaussian(sigma=0.09) ]), galsim.Convolve([ galsim.TopHat(0.17, flux=1.7).shift(-0.275,0.125), galsim.Gaussian(sigma=0.09) ]), # Test something really crazy with several layers worth of transformations galsim.Convolve([ galsim.Sum([ galsim.Gaussian(sigma=0.17, flux=1.7).shear(g1=0.1,g2=0.2).shift(2,3), galsim.Kolmogorov(fwhm=0.33, flux=3.9).transform(0.31,0.19,-0.23,0.33) * 88., galsim.Box(0.11, 0.44, flux=4).rotate(33 * galsim.degrees) / 1.9 ]).shift(-0.3,1), galsim.AutoConvolve(galsim.TopHat(0.5).shear(g1=0.3,g2=0)).rotate(3*galsim.degrees), (galsim.AutoCorrelate(galsim.Box(0.2, 0.3)) * 11).shift(3,2).shift(2,-3) * 0.31 ]).shift(0,0).transform(0,-1,-1,0).shift(-1,1) ] s = galsim.Shear(g1=0.11, g2=-0.21) s1 = galsim.Shear(g1=0.11, g2=0.21) # Appropriate for the flips around x and y axes s2 = galsim.Shear(g1=-0.11, g2=-0.21) # Appropriate for the flip around x=y # Also use shears with just a g1 to get dx != dy, but dxy, dyx = 0. q = galsim.Shear(g1=0.11, g2=0.) q1 = galsim.Shear(g1=0.11, g2=0.) # Appropriate for the flips around x and y axes q2 = galsim.Shear(g1=-0.11, g2=0.) # Appropriate for the flip around x=y decimal=6 # Oddly, these aren't as precise as I would have expected. # Even when we only go to this many digits of accuracy, the Exponential needed # a lower than default value for maxk_threshold. im = galsim.ImageD(16,16, scale=0.05) for prof in prof_list: print('prof = ',prof) # Not all profiles are expected to have a max_sb value close to the maximum pixel value, # so mark the ones where we don't want to require this to be true. close_maxsb = True name = str(prof) if ('DeVauc' in name or 'Sersic' in name or 'Spergel' in name or 'Optical' in name or 'shift' in name): close_maxsb = False # Make sure we hit all 4 fill functions. # image_x uses fillXValue with izero, jzero # image_x1 uses fillXValue with izero, jzero, and unequal dx,dy # image_x2 uses fillXValue with dxy, dyx # image_k uses fillKValue with izero, jzero # image_k1 uses fillKValue with izero, jzero, and unequal dx,dy # image_k2 uses fillKValue with dxy, dyx image_x = prof.drawImage(image=im.copy(), method='no_pixel') image_x1 = prof.shear(q).drawImage(image=im.copy(), method='no_pixel') image_x2 = prof.shear(s).drawImage(image=im.copy(), method='no_pixel') image_k = prof.drawImage(image=im.copy()) image_k1 = prof.shear(q).drawImage(image=im.copy()) image_k2 = prof.shear(s).drawImage(image=im.copy()) if close_maxsb: np.testing.assert_allclose( image_x.array.max(), prof.max_sb*im.scale**2, rtol=0.2, err_msg="max_sb did not match maximum pixel value") np.testing.assert_allclose( image_x1.array.max(), prof.shear(q).max_sb*im.scale**2, rtol=0.2, err_msg="max_sb did not match maximum pixel value") np.testing.assert_allclose( image_x2.array.max(), prof.shear(s).max_sb*im.scale**2, rtol=0.2, err_msg="max_sb did not match maximum pixel value") # Flip around y axis (i.e. x -> -x) flip1 = prof.transform(-1, 0, 0, 1) image2_x = flip1.drawImage(image=im.copy(), method='no_pixel') np.testing.assert_array_almost_equal( image_x.array, image2_x.array[:,::-1], decimal=decimal, err_msg="Flipping image around y-axis failed x test") image2_x1 = flip1.shear(q1).drawImage(image=im.copy(), method='no_pixel') np.testing.assert_array_almost_equal( image_x1.array, image2_x1.array[:,::-1], decimal=decimal, err_msg="Flipping image around y-axis failed x1 test") image2_x2 = flip1.shear(s1).drawImage(image=im.copy(), method='no_pixel') np.testing.assert_array_almost_equal( image_x2.array, image2_x2.array[:,::-1], decimal=decimal, err_msg="Flipping image around y-axis failed x2 test") image2_k = flip1.drawImage(image=im.copy()) np.testing.assert_array_almost_equal( image_k.array, image2_k.array[:,::-1], decimal=decimal, err_msg="Flipping image around y-axis failed k test") image2_k1 = flip1.shear(q1).drawImage(image=im.copy()) np.testing.assert_array_almost_equal( image_k1.array, image2_k1.array[:,::-1], decimal=decimal, err_msg="Flipping image around y-axis failed k1 test") image2_k2 = flip1.shear(s1).drawImage(image=im.copy()) np.testing.assert_array_almost_equal( image_k2.array, image2_k2.array[:,::-1], decimal=decimal, err_msg="Flipping image around y-axis failed k2 test") if close_maxsb: np.testing.assert_allclose( image2_x.array.max(), flip1.max_sb*im.scale**2, rtol=0.2, err_msg="max_sb did not match maximum pixel value") np.testing.assert_allclose( image2_x1.array.max(), flip1.shear(q).max_sb*im.scale**2, rtol=0.2, err_msg="max_sb did not match maximum pixel value") np.testing.assert_allclose( image2_x2.array.max(), flip1.shear(s).max_sb*im.scale**2, rtol=0.2, err_msg="max_sb did not match maximum pixel value") # Flip around x axis (i.e. y -> -y) flip2 = prof.transform(1, 0, 0, -1) image2_x = flip2.drawImage(image=im.copy(), method='no_pixel') np.testing.assert_array_almost_equal( image_x.array, image2_x.array[::-1,:], decimal=decimal, err_msg="Flipping image around x-axis failed x test") image2_x1 = flip2.shear(q1).drawImage(image=im.copy(), method='no_pixel') np.testing.assert_array_almost_equal( image_x1.array, image2_x1.array[::-1,:], decimal=decimal, err_msg="Flipping image around x-axis failed x1 test") image2_x2 = flip2.shear(s1).drawImage(image=im.copy(), method='no_pixel') np.testing.assert_array_almost_equal( image_x2.array, image2_x2.array[::-1,:], decimal=decimal, err_msg="Flipping image around x-axis failed x2 test") image2_k = flip2.drawImage(image=im.copy()) np.testing.assert_array_almost_equal( image_k.array, image2_k.array[::-1,:], decimal=decimal, err_msg="Flipping image around x-axis failed k test") image2_k1 = flip2.shear(q1).drawImage(image=im.copy()) np.testing.assert_array_almost_equal( image_k1.array, image2_k1.array[::-1,:], decimal=decimal, err_msg="Flipping image around x-axis failed k1 test") image2_k2 = flip2.shear(s1).drawImage(image=im.copy()) np.testing.assert_array_almost_equal( image_k2.array, image2_k2.array[::-1,:], decimal=decimal, err_msg="Flipping image around x-axis failed k2 test") if close_maxsb: np.testing.assert_allclose( image2_x.array.max(), flip2.max_sb*im.scale**2, rtol=0.2, err_msg="max_sb did not match maximum pixel value") np.testing.assert_allclose( image2_x1.array.max(), flip2.shear(q).max_sb*im.scale**2, rtol=0.2, err_msg="max_sb did not match maximum pixel value") np.testing.assert_allclose( image2_x2.array.max(), flip2.shear(s).max_sb*im.scale**2, rtol=0.2, err_msg="max_sb did not match maximum pixel value") # Flip around x=y (i.e. y -> x, x -> y) flip3 = prof.transform(0, 1, 1, 0) image2_x = flip3.drawImage(image=im.copy(), method='no_pixel') np.testing.assert_array_almost_equal( image_x.array, np.transpose(image2_x.array), decimal=decimal, err_msg="Flipping image around x=y failed x test") image2_x1 = flip3.shear(q2).drawImage(image=im.copy(), method='no_pixel') np.testing.assert_array_almost_equal( image_x1.array, np.transpose(image2_x1.array), decimal=decimal, err_msg="Flipping image around x=y failed x1 test") image2_x2 = flip3.shear(s2).drawImage(image=im.copy(), method='no_pixel') np.testing.assert_array_almost_equal( image_x2.array, np.transpose(image2_x2.array), decimal=decimal, err_msg="Flipping image around x=y failed x2 test") image2_k = flip3.drawImage(image=im.copy()) np.testing.assert_array_almost_equal( image_k.array, np.transpose(image2_k.array), decimal=decimal, err_msg="Flipping image around x=y failed k test") image2_k1 = flip3.shear(q2).drawImage(image=im.copy()) np.testing.assert_array_almost_equal( image_k1.array, np.transpose(image2_k1.array), decimal=decimal, err_msg="Flipping image around x=y failed k1 test") image2_k2 = flip3.shear(s2).drawImage(image=im.copy()) np.testing.assert_array_almost_equal( image_k2.array, np.transpose(image2_k2.array), decimal=decimal, err_msg="Flipping image around x=y failed k2 test") if close_maxsb: np.testing.assert_allclose( image2_x.array.max(), flip3.max_sb*im.scale**2, rtol=0.2, err_msg="max_sb did not match maximum pixel value") np.testing.assert_allclose( image2_x1.array.max(), flip3.shear(q).max_sb*im.scale**2, rtol=0.2, err_msg="max_sb did not match maximum pixel value") np.testing.assert_allclose( image2_x2.array.max(), flip3.shear(s).max_sb*im.scale**2, rtol=0.2, err_msg="max_sb did not match maximum pixel value") do_pickle(prof, lambda x: x.drawImage(image=im.copy(), method='no_pixel')) do_pickle(flip1, lambda x: x.drawImage(image=im.copy(), method='no_pixel')) do_pickle(flip2, lambda x: x.drawImage(image=im.copy(), method='no_pixel')) do_pickle(flip3, lambda x: x.drawImage(image=im.copy(), method='no_pixel')) do_pickle(prof) do_pickle(flip1) do_pickle(flip2) do_pickle(flip3)
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)