def test_spergel_shoot(): """Test Spergel with photon shooting. Particularly the flux of the final image. """ rng = galsim.BaseDeviate(1234) obj = galsim.Spergel(nu=0, half_light_radius=3.5, 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.Spergel(nu=3.2, half_light_radius=3.5, 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.Spergel(nu=-0.6, half_light_radius=3.5, 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_spergel_05(): """Test the equivalence of Spergel with nu=0.5 and Exponential """ # cf test_exponential() re = 1.0 r0 = re / 1.67839 # The real value of re/r0 = 1.6783469900166605 hlr_r0 = 1.6783469900166605 savedImg = galsim.fits.read(os.path.join(imgdir, "exp_1.fits")) dx = 0.2 myImg = galsim.ImageF(savedImg.bounds, scale=dx) spergel = galsim.Spergel(nu=0.5, flux=1., half_light_radius=r0 * hlr_r0) spergel.drawImage(myImg, method="sb", use_true_center=False) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 5, err_msg= "Using Spergel nu=0.5 disagrees with expected result for Exponential") check_basic(spergel, "nu=0.5 Spergel") do_kvalue(spergel, myImg, "nu=0.5 Spergel") # cf test_exponential_properties() test_flux = 17.9 test_scale = 1.8 spergel = galsim.Spergel(nu=0.5, flux=test_flux, half_light_radius=test_scale * hlr_r0) cen = galsim.PositionD(0, 0) np.testing.assert_equal(spergel.centroid, cen) np.testing.assert_almost_equal(spergel.kValue(cen), (1 + 0j) * test_flux) np.testing.assert_almost_equal(spergel.flux, test_flux) import math np.testing.assert_almost_equal(spergel.xValue(cen), 1. / (2. * math.pi) * test_flux / test_scale**2, decimal=5) np.testing.assert_almost_equal(spergel.xValue(cen), spergel.max_sb) # Also test some random values other than the center: expon = galsim.Exponential(flux=test_flux, scale_radius=test_scale) for (x, y) in [(0.1, 0.2), (-0.5, 0.4), (0, 0.9), (1.2, 0.1), (2, 2)]: pos = galsim.PositionD(x, y) np.testing.assert_almost_equal(spergel.xValue(pos), expon.xValue(pos), decimal=5) np.testing.assert_almost_equal(spergel.kValue(pos), expon.kValue(pos), decimal=5)
def sample(args, do_series=False): """ Generate MCMC (emcee) samples from arguments specified in args. @param series Boolean controlling whether or not to use series approx. @returns post-sampling emcee sampler object. """ # 3 random number generators to seed bd = galsim.BaseDeviate(args.image_seed) # for GalSim rstate = np.random.mtrand.RandomState(args.sample_seed + args.jmax).get_state() # for emcee np.random.seed(args.sample_seed + args.jmax) # for numpy functions called outside of emcee nwalkers = args.nwalkers nsteps = args.nsteps ndim = 6 p_initial = [args.x0, args.y0, args.HLR, args.flux, args.e1, args.e2] # x0, y0, HLR, flux, e1, e2 p_std = [0.01, 0.01, 0.01, args.flux * 0.01, 0.01, 0.01] x0, y0, HLR, flux, e1, e2 = p_initial psf = galsim.Moffat(beta=3, fwhm=args.PSF_FWHM) gal = galsim.Spergel(nu=args.nu, half_light_radius=args.HLR, flux=args.flux) gal = gal.shear(e1=args.e1, e2=args.e2) gal = gal.shift(args.x0, args.y0) final = galsim.Convolve(gal, psf) target_image = final.drawImage(nx=args.nx, ny=args.ny, scale=args.scale) noise = galsim.GaussianNoise(rng=bd) if args.noisy_image: noisevar = target_image.addNoiseSNR(noise, args.SNR, preserve_flux=True) else: dummy_image = target_image.copy() noisevar = dummy_image.addNoiseSNR(noise, args.SNR, preserve_flux=True) p0 = np.empty((nwalkers, ndim), dtype=float) todo = np.ones(nwalkers, dtype=bool) lnp_args = [target_image, noisevar, args, do_series] while len(todo) > 0: p0[todo] = [ p_initial + p_std * np.random.normal(size=ndim) for i in range(len(todo)) ] todo = np.nonzero([not np.isfinite(lnprob(p, *lnp_args)) for p in p0])[0] sampler = emcee.EnsembleSampler(nwalkers, ndim, lnprob, args=lnp_args) sampler.run_mcmc(p0, nsteps, rstate0=rstate) return sampler
def test_spergel_properties(): """Test some basic properties of the Spergel profile. """ test_flux = 17.9 spergel = galsim.Spergel(nu=0.0, flux=test_flux, scale_radius=1.0) # Check that we are centered on (0, 0) cen = galsim.PositionD(0, 0) np.testing.assert_equal(spergel.centroid, cen) # # Check Fourier properties np.testing.assert_almost_equal(spergel.kValue(cen), (1 + 0j) * test_flux) maxk = spergel.maxk assert spergel.kValue( maxk, 0).real / test_flux <= galsim.GSParams().maxk_threshold np.testing.assert_almost_equal(spergel.flux, test_flux) np.testing.assert_almost_equal(spergel.xValue(cen), spergel.max_sb) # Check input flux vs output flux for inFlux in np.logspace(-2, 2, 10): spergel = galsim.Spergel(nu=0.0, flux=inFlux, scale_radius=1.0) outFlux = spergel.flux np.testing.assert_almost_equal(outFlux, inFlux) np.testing.assert_almost_equal(spergel.xValue(cen), spergel.max_sb)
def test_spergel_flux_scaling(): """Test flux scaling for Spergel. """ # decimal point to go to for parameter value comparisons param_decimal = 12 test_flux = 17.9 test_spergel_nu = [-0.85, -0.5, 0.0, 0.85, 4.0] test_hlr = 1.8 # loop through spergel nu for test_nu in test_spergel_nu: # init with hlr and flux only (should be ok given last tests) init_obj = galsim.Spergel(test_nu, half_light_radius=test_hlr, flux=test_flux) obj2 = init_obj * 2. np.testing.assert_almost_equal( init_obj.flux, test_flux, decimal=param_decimal, err_msg="Flux param inconsistent after __rmul__ (original).") np.testing.assert_almost_equal( obj2.flux, test_flux * 2., decimal=param_decimal, err_msg="Flux param inconsistent after __rmul__ (result).") obj2 = 2. * init_obj np.testing.assert_almost_equal( init_obj.flux, test_flux, decimal=param_decimal, err_msg="Flux param inconsistent after __mul__ (original).") np.testing.assert_almost_equal( obj2.flux, test_flux * 2., decimal=param_decimal, err_msg="Flux param inconsistent after __mul__ (result).") obj2 = init_obj / 2. np.testing.assert_almost_equal( init_obj.flux, test_flux, decimal=param_decimal, err_msg="Flux param inconsistent after __div__ (original).") np.testing.assert_almost_equal( obj2.flux, test_flux / 2., decimal=param_decimal, err_msg="Flux param inconsistent after __div__ (result).")
def draw_spergel(params, image=None, gsparams=None, dtype=None): """Draw a Spergel profile in k-space onto the given image params = [ half_light_radius, flux, e1, e2, x0, y0 ] image is optional, but if provided will be used as is. """ nu = 0.5 gal = galsim.Spergel(nu, params[0], flux=params[1], gsparams=gsparams) gal = gal._shear(galsim._Shear(params[2] + 1j * params[3])) gal = gal._shift(galsim.PositionD(params[4], params[5])) if image is None: image = gal.drawKImage(dtype=dtype, nx=256, ny=256) else: image = gal._drawKImage(image) return image
def make_round_model(self, pars): """ make the galsim Spergel model """ import galsim r50 = pars[4] nu = pars[5] flux = pars[6] # generic RuntimeError thrown try: gal = galsim.Spergel(nu, half_light_radius=r50, flux=flux,) except RuntimeError as err: raise GMixRangeError(str(err)) return gal
def getimage(p, args, do_series): x0, y0, HLR, flux, e1, e2 = p psf = galsim.Moffat(beta=3, fwhm=args.PSF_FWHM) if do_series: gal = galsim.SpergelSeries(nu=args.nu, jmax=args.jmax, half_light_radius=HLR, flux=flux) else: gal = galsim.Spergel(nu=args.nu, half_light_radius=HLR, flux=flux) gal = gal.shear(e1=e1, e2=e2) gal = gal.shift(x0, y0) final = galsim.Convolve(gal, psf) if do_series: img = final.drawImage(nx=args.nx, ny=args.ny, scale=args.scale, iimult=args.iimult) else: img = final.drawImage(nx=args.nx, ny=args.ny, scale=args.scale) return img
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) # Spergel. Params include nu, half_light_radius, scale_radius, flux, and gsparams. # The following should all test unequal: gals = [ galsim.Spergel(nu=0.0, half_light_radius=1.0), galsim.Spergel(nu=0.1, half_light_radius=1.0), galsim.Spergel(nu=0.0, half_light_radius=1.1), galsim.Spergel(nu=0.0, scale_radius=1.0), galsim.Spergel(nu=0.0, half_light_radius=1.0, flux=1.1), galsim.Spergel(nu=0.0, half_light_radius=1.0, gsparams=gsp) ] all_obj_diff(gals)
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_spergel(): """Test the generation of a specific Spergel profile against a known result. """ test_spergel_nu = [-0.85, -0.5, 0.0, 0.85, 4.0] mathica_enclosed_fluxes = [ 3.06256e-2, 9.99995e-6, 6.06443e-10, 2.94117e-11, 6.25011e-12 ] mathica_enclosing_radii = [ 2.3973e-17, 1.00001e-5, 1.69047e-3, 5.83138e-3, 1.26492e-2 ] for nu, enclosed_flux, enclosing_radius in zip(test_spergel_nu, mathica_enclosed_fluxes, mathica_enclosing_radii): filename = "spergel_nu{0:.2f}.fits".format(nu) savedImg = galsim.fits.read(os.path.join(imgdir, filename)) savedImg.setCenter(0, 0) dx = 0.2 myImg = galsim.ImageF(savedImg.bounds, scale=dx) myImg.setCenter(0, 0) spergel = galsim.Spergel(nu=nu, half_light_radius=1.0) # Reference images were made with old centering, # which is equivalent to use_true_center=False. myImg = spergel.drawImage(myImg, scale=dx, method="sb", use_true_center=False) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 5, err_msg="Using GSObject Spergel disagrees with expected result") gsp = galsim.GSParams(xvalue_accuracy=1.e-8, kvalue_accuracy=1.e-8) spergel2 = galsim.Spergel(nu=nu, half_light_radius=1.0, gsparams=gsp) assert spergel2 != spergel assert spergel2 == spergel.withGSParams(gsp) # nu < 0 has inf for xValue(0,0), so the x tests fail for them. check_basic(spergel, "Spergel with nu=%f" % nu, do_x=(nu > 0)) # Only nu >= -0.3 give reasonably sized FFTs, # and small nu method='phot' is super slow. if nu >= -0.3: test_im = galsim.Image(16, 16, scale=dx) do_kvalue(spergel, test_im, "Spergel(nu={0:1}) ".format(nu)) # Test photon shooting. # Convolve with a small gaussian to smooth out the central peak. spergel2 = galsim.Convolve(spergel, galsim.Gaussian(sigma=0.3)) do_shoot(spergel2, myImg, "Spergel") # Test integrated flux routines against Mathematica spergel = galsim.Spergel(nu=nu, scale_radius=1.0) np.testing.assert_almost_equal( spergel.calculateFluxRadius(1.e-5) / enclosing_radius, 1.0, 4, err_msg="Calculated incorrect Spergel(nu={0}) flux-enclosing-radius." .format(nu)) np.testing.assert_almost_equal( spergel.calculateIntegratedFlux(1.e-5) / enclosed_flux, 1.0, 4, err_msg="Calculated incorrect Spergel(nu={0}) enclosed flux.". format(nu)) # Use non-unity values. spergel = galsim.Spergel(nu=0.37, flux=1.7, half_light_radius=2.3) check_basic(spergel, "Spergel") # Check picklability do_pickle(spergel, lambda x: x.drawImage(method='no_pixel')) do_pickle(spergel) do_pickle(galsim.Spergel(0, 1)) # Should raise an exception if both scale_radius and half_light_radius are provided. assert_raises(TypeError, galsim.Spergel, nu=0, scale_radius=3, half_light_radius=1) assert_raises(TypeError, galsim.Spergel, nu=0) assert_raises(TypeError, galsim.Spergel, scale_radius=3) # Allowed range = [-0.85, 4.0] assert_raises(ValueError, galsim.Spergel, nu=-0.9) assert_raises(ValueError, galsim.Spergel, nu=4.1)
def test_spergel_radii(): """Test initialization of Spergel with different types of radius specification. """ import math test_spergel_nu = [-0.85, -0.5, 0.0, 0.85, 4.0] test_spergel_scale = [20.0, 1.0, 1.0, 0.5, 0.5] test_hlr = 1.8 for nu, scale in zip(test_spergel_nu, test_spergel_scale): test_gal = galsim.Spergel(nu=nu, half_light_radius=test_hlr, flux=1.) # Check that the returned half-light radius is correct print('test_hlr = ', test_hlr) print('test_gal hlr, sr = ', test_gal.half_light_radius, test_gal.scale_radius) np.testing.assert_almost_equal( test_gal.half_light_radius, test_hlr, decimal=5, err_msg="Error in returned HLR for Spergel HLR constructor, nu=%.1f" % nu) # Check that the returned flux is correct print('test_gal.flux = ', test_gal.flux) np.testing.assert_almost_equal( test_gal.flux, 1., decimal=5, err_msg= "Error in returned Flux for Spergel HLR constructor, nu=%.1f" % nu) # (test half-light radii) print('flux = ', test_gal.flux) print('hlr = ', test_gal.half_light_radius) print('scale = ', test_gal.scale_radius) got_hlr = test_gal.half_light_radius got_flux = test_gal.flux # nu = -0.85 is too difficult to numerically integrate if nu > -0.85: hlr_sum = radial_integrate(test_gal, 0., got_hlr) print('hlr_sum = ', hlr_sum) np.testing.assert_almost_equal( hlr_sum, 0.5 * got_flux, decimal=4, err_msg= "Error in Spergel half-light radius constructor, nu=%.1f" % nu) # Test constructor using scale radius (test scale radius) test_gal = galsim.Spergel(nu=nu, scale_radius=scale, flux=1.) # Check that the returned scale radius is correct print('test_scale = ', scale) print('test_gal hlr, sr = ', test_gal.half_light_radius, test_gal.scale_radius) np.testing.assert_almost_equal( test_gal.scale_radius, scale, decimal=5, err_msg="Error in returned SR for Sersic SR constructor, nu=%.1f" % nu) # Check that the returned flux is correct print('test_gal.flux = ', test_gal.flux) np.testing.assert_almost_equal( test_gal.flux, 1., decimal=5, err_msg= "Error in returned Flux for Spergel HLR constructor, nu=%.1f" % nu) # (test half-light radius) got_hlr = test_gal.half_light_radius got_flux = test_gal.flux # nu = -0.85 is too difficult to numerically integrate if nu > -0.85: hlr_sum = radial_integrate(test_gal, 0., got_hlr) print('hlr_sum = ', hlr_sum) np.testing.assert_almost_equal( hlr_sum, 0.5 * got_flux, decimal=4, err_msg="Error in HLR for scale_radius constructed Spergel") # Check that the getters don't work after modifying the original. test_gal_shear = test_gal.shear(g1=0.3, g2=0.1) assert_raises(AttributeError, getattr, test_gal_shear, "nu") assert_raises(AttributeError, getattr, test_gal_shear, "half_light_radius") assert_raises(AttributeError, getattr, test_gal_shear, "scale_radius")