def test_fourier_sqrt(): """Test that the FourierSqrt operator is the inverse of auto-convolution. """ 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) # Test trivial case, where we could (but don't) analytically collapse the # chain of SBProfiles by recognizing that FourierSqrt is the inverse of # AutoConvolve. psf = galsim.Moffat(beta=3.8, fwhm=1.3, flux=5) psf.drawImage(myImg1, method='no_pixel') sqrt1 = galsim.FourierSqrt(psf) psf2 = galsim.AutoConvolve(sqrt1) np.testing.assert_almost_equal(psf.stepK(), psf2.stepK()) psf2.drawImage(myImg2, method='no_pixel') printval(myImg1, myImg2) np.testing.assert_array_almost_equal( myImg1.array, myImg2.array, 4, err_msg="Moffat sqrt convolved with self disagrees with original") # Test non-trivial case where we compare (in Fourier space) sqrt(a*a + b*b + 2*a*b) against (a + b) a = galsim.Moffat(beta=3.8, fwhm=1.3, flux=5) a.shift(dx=0.5, dy=-0.3) # need nonzero centroid to test centroid() b = galsim.Moffat(beta=2.5, fwhm=1.6, flux=3) check = galsim.Sum([a, b]) sqrt = galsim.FourierSqrt( galsim.Sum([ galsim.AutoConvolve(a), galsim.AutoConvolve(b), 2 * galsim.Convolve([a, b]) ])) np.testing.assert_almost_equal(check.stepK(), sqrt.stepK()) check.drawImage(myImg1, method='no_pixel') sqrt.drawImage(myImg2, method='no_pixel') np.testing.assert_almost_equal(check.centroid().x, sqrt.centroid().x) np.testing.assert_almost_equal(check.centroid().y, sqrt.centroid().y) np.testing.assert_almost_equal(check.getFlux(), sqrt.getFlux()) printval(myImg1, myImg2) np.testing.assert_array_almost_equal( myImg1.array, myImg2.array, 4, err_msg="Fourier square root of expanded square disagrees with original" ) # Check picklability do_pickle(sqrt1.SBProfile, lambda x: (repr(x.getObj()), x.getGSParams())) do_pickle(sqrt1, lambda x: x.drawImage(method='no_pixel')) do_pickle(sqrt1) do_pickle(sqrt1.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_fourier_sqrt(): """Test that the FourierSqrt operator is the inverse of auto-convolution. """ 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) # Test trivial case, where we could (but don't) analytically collapse the # chain of profiles by recognizing that FourierSqrt is the inverse of # AutoConvolve. psf = galsim.Moffat(beta=3.8, fwhm=1.3, flux=5) psf.drawImage(myImg1, method='no_pixel') sqrt1 = galsim.FourierSqrt(psf) psf2 = galsim.AutoConvolve(sqrt1) np.testing.assert_almost_equal(psf.stepk, psf2.stepk) psf2.drawImage(myImg2, method='no_pixel') printval(myImg1, myImg2) np.testing.assert_array_almost_equal( myImg1.array, myImg2.array, 4, err_msg="Moffat sqrt convolved with self disagrees with original") check_basic(sqrt1, "FourierSqrt", do_x=False) # Test non-trivial case where we compare (in Fourier space) sqrt(a*a + b*b + 2*a*b) against (a + b) a = galsim.Moffat(beta=3.8, fwhm=1.3, flux=5) a.shift(dx=0.5, dy=-0.3) # need nonzero centroid to test b = galsim.Moffat(beta=2.5, fwhm=1.6, flux=3) check = galsim.Sum([a, b]) sqrt = galsim.FourierSqrt( galsim.Sum([ galsim.AutoConvolve(a), galsim.AutoConvolve(b), 2 * galsim.Convolve([a, b]) ])) np.testing.assert_almost_equal(check.stepk, sqrt.stepk) check.drawImage(myImg1, method='no_pixel') sqrt.drawImage(myImg2, method='no_pixel') np.testing.assert_almost_equal(check.centroid.x, sqrt.centroid.x) np.testing.assert_almost_equal(check.centroid.y, sqrt.centroid.y) np.testing.assert_almost_equal(check.flux, sqrt.flux) np.testing.assert_almost_equal(check.xValue(check.centroid), check.max_sb) print('check.max_sb = ', check.max_sb) print('sqrt.max_sb = ', sqrt.max_sb) # This isn't super accurate... np.testing.assert_allclose(check.max_sb, sqrt.max_sb, rtol=0.1) printval(myImg1, myImg2) np.testing.assert_array_almost_equal( myImg1.array, myImg2.array, 4, err_msg="Fourier square root of expanded square disagrees with original" ) # Check picklability do_pickle(sqrt1, lambda x: x.drawImage(method='no_pixel')) do_pickle(sqrt1) # Should raise an exception for invalid arguments assert_raises(TypeError, galsim.FourierSqrt) assert_raises(TypeError, galsim.FourierSqrt, myImg1) assert_raises(TypeError, galsim.FourierSqrt, [psf]) assert_raises(TypeError, galsim.FourierSqrt, psf, psf) assert_raises(TypeError, galsim.FourierSqrt, psf, real_space=False) assert_raises(TypeError, galsim.FourierSqrtProfile) assert_raises(TypeError, galsim.FourierSqrtProfile, myImg1) assert_raises(TypeError, galsim.FourierSqrtProfile, [psf]) assert_raises(TypeError, galsim.FourierSqrtProfile, psf, psf) assert_raises(TypeError, galsim.FourierSqrtProfile, psf, real_space=False) assert_raises(NotImplementedError, sqrt1.xValue, galsim.PositionD(0, 0)) assert_raises(NotImplementedError, sqrt1.drawReal, myImg1) assert_raises(NotImplementedError, sqrt1.shoot, 1)
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)