def test_ne(): """Test base.py GSObjects for not-equals.""" # Define some universal gsps gsp = galsim.GSParams(maxk_threshold=1.1e-3, folding_threshold=5.1e-3) # Pixel. Params include scale, flux, gsparams. # gsparams. # The following should all test unequal: gals = [galsim.Pixel(scale=1.0), galsim.Pixel(scale=1.1), galsim.Pixel(scale=1.0, flux=1.1), galsim.Pixel(scale=1.0, gsparams=gsp)] all_obj_diff(gals) # Box. Params include width, height, flux, gsparams. # gsparams. # The following should all test unequal: gals = [galsim.Box(width=1.0, height=1.0), galsim.Box(width=1.1, height=1.0), galsim.Box(width=1.0, height=1.1), galsim.Box(width=1.0, height=1.0, flux=1.1), galsim.Box(width=1.0, height=1.0, gsparams=gsp)] all_obj_diff(gals) # TopHat. Params include radius, flux, gsparams. # gsparams. # The following should all test unequal: gals = [galsim.TopHat(radius=1.0), galsim.TopHat(radius=1.1), galsim.TopHat(radius=1.0, flux=1.1), galsim.TopHat(radius=1.0, gsparams=gsp)] all_obj_diff(gals)
def test_box_shoot(): """Test Box with photon shooting. Particularly the flux of the final image. """ rng = galsim.BaseDeviate(1234) obj = galsim.Box(width=1.3, height=2.4, flux=1.e4) im = galsim.Image(100,100, scale=1) im.setCenter(0,0) added_flux, photons = obj.drawPhot(im, poisson_flux=False, rng=rng) print('obj.flux = ',obj.flux) print('added_flux = ',added_flux) print('photon fluxes = ',photons.flux.min(),'..',photons.flux.max()) print('image flux = ',im.array.sum()) assert np.isclose(added_flux, obj.flux) assert np.isclose(im.array.sum(), obj.flux) obj = galsim.Pixel(scale=9.3, flux=1.e4) added_flux, photons = obj.drawPhot(im, poisson_flux=False, rng=rng) print('obj.flux = ',obj.flux) print('added_flux = ',added_flux) print('photon fluxes = ',photons.flux.min(),'..',photons.flux.max()) print('image flux = ',im.array.sum()) assert np.isclose(added_flux, obj.flux) assert np.isclose(im.array.sum(), obj.flux) obj = galsim.TopHat(radius=4.7, flux=1.e4) added_flux, photons = obj.drawPhot(im, poisson_flux=False, rng=rng) print('obj.flux = ',obj.flux) print('added_flux = ',added_flux) print('photon fluxes = ',photons.flux.min(),'..',photons.flux.max()) print('image flux = ',im.array.sum()) assert np.isclose(added_flux, obj.flux) assert np.isclose(im.array.sum(), obj.flux)
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_tophat(): """Test the generation of a specific tophat profile against a known result. """ savedImg = galsim.fits.read(os.path.join(imgdir, "tophat_101.fits")) myImg = galsim.ImageF(savedImg.bounds, scale=0.2) myImg.setCenter(0,0) test_flux = 1.8 # There are numerical issues with using radius = 1, since many points are right on the edge # of the circle. e.g. (+-1,0), (0,+-1), (+-0.6,+-0.8), (+-0.8,+-0.6). And in practice, some # of these end up getting drawn and not others, which means it's not a good choice for a unit # test since it wouldn't be any less correct for a different subset of these points to be # drawn. Using r = 1.01 solves this problem and makes the result symmetric. tophat = galsim.TopHat(radius=1.01, flux=1) tophat.drawImage(myImg, method="sb", use_true_center=False) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 5, err_msg="Using GSObject TopHat disagrees with expected result") np.testing.assert_array_equal( tophat.radius, 1.01, err_msg="TopHat radius returned wrong value") # Check with default_params tophat = galsim.TopHat(radius=1.01, flux=1, gsparams=default_params) tophat.drawImage(myImg, method="sb", use_true_center=False) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 5, err_msg="Using GSObject TopHat with default_params disagrees with expected result") tophat = galsim.TopHat(radius=1.01, flux=1, gsparams=galsim.GSParams()) tophat.drawImage(myImg, method="sb", use_true_center=False) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 5, err_msg="Using GSObject TopHat with GSParams() disagrees with expected result") # Use non-unity values. tophat = galsim.TopHat(flux=1.7, radius=2.3) # Test photon shooting. do_shoot(tophat,myImg,"TopHat") # Test shoot and kvalue scale = 0.2939 im = galsim.ImageF(16,16, scale=scale) # The choices of radius here are fairly specific. If the edge of the circle comes too close # to the center of one of the pixels, then the test will fail, since the Fourier draw method # will blur the edge a bit and give some flux to that pixel. for radius in [ 1.2, 0.93, 2.11 ]: tophat = galsim.TopHat(radius=radius, flux=test_flux) check_basic(tophat, "TopHat with radius = %f"%radius) do_shoot(tophat,im,"TopHat with radius = %f"%radius) do_kvalue(tophat,im,"TopHat with radius = %f"%radius) # This is also a profile that may be convolved using real space convolution, so test that. conv = galsim.Convolve(tophat, galsim.Pixel(scale=scale), real_space=True) check_basic(conv, "TopHat convolved with pixel in real space", approx_maxsb=True, scale=0.2) do_kvalue(conv,im, "TopHat convolved with pixel in real space") cen = galsim.PositionD(0, 0) np.testing.assert_equal(tophat.centroid, cen) np.testing.assert_almost_equal(tophat.kValue(cen), (1+0j) * test_flux) np.testing.assert_almost_equal(tophat.flux, test_flux) np.testing.assert_almost_equal(tophat.xValue(cen), tophat.max_sb) np.testing.assert_almost_equal(tophat.xValue(radius-0.001, 0.), tophat.max_sb) np.testing.assert_almost_equal(tophat.xValue(0., radius-0.001), tophat.max_sb) np.testing.assert_almost_equal(tophat.xValue(radius+0.001, 0.), 0.) np.testing.assert_almost_equal(tophat.xValue(0., radius+0.001), 0.) # Check picklability do_pickle(tophat, lambda x: x.drawImage(method='no_pixel')) do_pickle(tophat) do_pickle(galsim.TopHat(1)) # Check sheared tophat the same way tophat = galsim.TopHat(radius=1.2, flux=test_flux) # Again, the test is very sensitive to the choice of shear here. Most values fail because # some pixel center gets too close to the resulting ellipse for the fourier draw to match # the real-space draw at the required accuracy. tophat = tophat.shear(galsim.Shear(g1=0.15, g2=-0.33)) check_basic(tophat, "Sheared TopHat") do_shoot(tophat,im, "Sheared TopHat") do_kvalue(tophat,im, "Sheared TopHat") cen = galsim.PositionD(0, 0) np.testing.assert_equal(tophat.centroid, cen) np.testing.assert_almost_equal(tophat.kValue(cen), (1+0j) * test_flux) np.testing.assert_almost_equal(tophat.flux, test_flux) np.testing.assert_almost_equal(tophat.xValue(cen), tophat.max_sb) # Check picklability do_pickle(tophat, lambda x: x.drawImage(method='no_pixel')) do_pickle(tophat) # Check real-space convolution of the sheared tophat. conv = galsim.Convolve(tophat, galsim.Pixel(scale=scale), real_space=True) check_basic(conv, "Sheared TopHat convolved with pixel in real space", approx_maxsb=True, scale=0.2) do_kvalue(conv,im, "Sheared TopHat convolved with pixel in real space")