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_pixel(): """Test various ways to build a Pixel """ config = { 'gal1' : { 'type' : 'Pixel' , 'scale' : 2 }, 'gal2' : { 'type' : 'Pixel' , 'scale' : 1.7, 'flux' : 100 }, 'gal3' : { 'type' : 'Box' , 'width' : 2, 'height' : 2.1, 'flux' : 1.e6, 'ellip' : { 'type' : 'QBeta' , 'q' : 0.6, 'beta' : 0.39 * galsim.radians } }, 'gal4' : { 'type' : 'Box' , 'width' : 1, 'height' : 1.2, 'flux' : 50, 'dilate' : 3, 'ellip' : galsim.Shear(e1=0.3), 'rotate' : 12 * galsim.degrees, 'magnify' : 1.03, 'shear' : galsim.Shear(g1=0.03, g2=-0.05), 'shift' : { 'type' : 'XY', 'x' : 0.7, 'y' : -1.2 } }, } gal1a = galsim.config.BuildGSObject(config, 'gal1')[0] gal1b = galsim.Pixel(scale = 2) gsobject_compare(gal1a, gal1b) gal2a = galsim.config.BuildGSObject(config, 'gal2')[0] gal2b = galsim.Pixel(scale = 1.7, flux = 100) gsobject_compare(gal2a, gal2b) # The config stuff emits a warning about the rectangular pixel. # We suppress that here, since we're doing it on purpose. import warnings with warnings.catch_warnings(): warnings.simplefilter("ignore") gal3a = galsim.config.BuildGSObject(config, 'gal3')[0] gal3b = galsim.Box(width = 2, height = 2.1, flux = 1.e6) gal3b = gal3b.shear(q = 0.6, beta = 0.39 * galsim.radians) # Drawing sheared Pixel without convolution doesn't work, so we need to # do the extra convolution by a Gaussian here gsobject_compare(gal3a, gal3b, conv=galsim.Gaussian(0.1)) gal4a = galsim.config.BuildGSObject(config, 'gal4')[0] gal4b = galsim.Box(width = 1, height = 1.2, flux = 50) gal4b = gal4b.dilate(3).shear(e1 = 0.3).rotate(12 * galsim.degrees).magnify(1.03) gal4b = gal4b.shear(g1 = 0.03, g2 = -0.05).shift(dx = 0.7, dy = -1.2) gsobject_compare(gal4a, gal4b, conv=galsim.Gaussian(0.1))
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_box(): """Test the generation of a specific box profile against a known result. """ savedImg = galsim.fits.read(os.path.join(imgdir, "box_1.fits")) myImg = galsim.ImageF(savedImg.bounds, scale=0.2) myImg.setCenter(0,0) test_flux = 1.8 pixel = galsim.Pixel(scale=1, flux=1) pixel.drawImage(myImg, method="sb", use_true_center=False) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 5, err_msg="Using GSObject Pixel disagrees with expected result") np.testing.assert_array_equal( pixel.scale, 1, err_msg="Pixel scale returned wrong value") # Check with default_params pixel = galsim.Pixel(scale=1, flux=1, gsparams=default_params) pixel.drawImage(myImg, method="sb", use_true_center=False) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 5, err_msg="Using GSObject Pixel with default_params disagrees with expected result") pixel = galsim.Pixel(scale=1, flux=1, gsparams=galsim.GSParams()) pixel.drawImage(myImg, method="sb", use_true_center=False) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 5, err_msg="Using GSObject Pixel with GSParams() disagrees with expected result") # Use non-unity values. pixel = galsim.Pixel(flux=1.7, scale=2.3) # Test photon shooting. do_shoot(pixel,myImg,"Pixel") # Check picklability do_pickle(pixel, lambda x: x.drawImage(method='no_pixel')) do_pickle(pixel) do_pickle(galsim.Pixel(1)) # Check that non-square Box profiles work correctly scale = 0.2939 # Use a strange scale here to make sure that the centers of the pixels # never fall on the box edge, otherwise it gets a bit weird to know what # the correct SB value is for that pixel. im = galsim.ImageF(16,16, scale=scale) gsp = galsim.GSParams(maximum_fft_size = 30000) for (width,height) in [ (3,2), (1.7, 2.7), (2.2222, 3.1415) ]: box = galsim.Box(width=width, height=height, flux=test_flux, gsparams=gsp) check_basic(box, "Box with width,height = %f,%f"%(width,height)) do_shoot(box,im,"Box with width,height = %f,%f"%(width,height)) if __name__ == '__main__': # These are slow because they require a pretty huge fft. # So only do them if running as main. do_kvalue(box,im,"Box with width,height = %f,%f"%(width,height)) cen = galsim.PositionD(0, 0) np.testing.assert_equal(box.centroid, cen) np.testing.assert_almost_equal(box.kValue(cen), (1+0j) * test_flux) np.testing.assert_almost_equal(box.flux, test_flux) np.testing.assert_almost_equal(box.xValue(cen), box.max_sb) np.testing.assert_almost_equal(box.xValue(width/2.-0.001, height/2.-0.001), box.max_sb) np.testing.assert_almost_equal(box.xValue(width/2.-0.001, height/2.+0.001), 0.) np.testing.assert_almost_equal(box.xValue(width/2.+0.001, height/2.-0.001), 0.) np.testing.assert_almost_equal(box.xValue(width/2.+0.001, height/2.+0.001), 0.) np.testing.assert_array_equal( box.width, width, err_msg="Box width returned wrong value") np.testing.assert_array_equal( box.height, height, err_msg="Box height returned wrong value") # Check picklability do_pickle(box, lambda x: x.drawImage(method='no_pixel')) do_pickle(box) do_pickle(galsim.Box(1,1)) # Check sheared boxes the same way box = galsim.Box(width=3, height=2, flux=test_flux, gsparams=gsp) box = box.shear(galsim.Shear(g1=0.2, g2=-0.3)) check_basic(box, "Sheared Box", approx_maxsb=True) do_shoot(box,im, "Sheared Box") if __name__ == '__main__': do_kvalue(box,im, "Sheared Box") do_pickle(box, lambda x: x.drawImage(method='no_pixel')) do_pickle(box) cen = galsim.PositionD(0, 0) np.testing.assert_equal(box.centroid, cen) np.testing.assert_almost_equal(box.kValue(cen), (1+0j) * test_flux) np.testing.assert_almost_equal(box.flux, test_flux) np.testing.assert_almost_equal(box.xValue(cen), box.max_sb) # This is also a profile that may be convolved using real space convolution, so test that. if __name__ == '__main__': conv = galsim.Convolve(box, galsim.Pixel(scale=scale), real_space=True) check_basic(conv, "Sheared Box convolved with pixel in real space", approx_maxsb=True, scale=0.2) do_kvalue(conv,im, "Sheared Box convolved with pixel in real space") do_pickle(conv, lambda x: x.xValue(0.123,-0.456)) do_pickle(conv)