def test_ne(): """ Check that inequality works as expected.""" gsp = galsim.GSParams(maxk_threshold=5.1e-3, folding_threshold=1.1e-3) objs = [galsim.Shapelet(1., 2), galsim.Shapelet(1., 3), galsim.Shapelet(2., 2), galsim.Shapelet(1., 2, bvec=[1, 0, 0, 0.2, 0.3, -0.1]), galsim.Shapelet(1., 2, gsparams=gsp)] all_obj_diff(objs)
def test_ne(): import time t1 = time.time() gsp = galsim.GSParams(maxk_threshold=5.1e-3, folding_threshold=1.1e-3) objs = [ galsim.Shapelet(1., 2), galsim.Shapelet(1., 3), galsim.Shapelet(2., 2), galsim.Shapelet(1., 2, bvec=[1, 0, 0, 0.2, 0.3, -0.1]), galsim.Shapelet(1., 2, gsparams=gsp) ] all_obj_diff(objs) t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
def test_shapelet_gaussian(): """Test that the simplest Shapelet profile is equivalent to a Gaussian """ ftypes = [np.float32, np.float64] scale = 0.2 test_flux = 23. # First, a Shapelet with only b_00 = 1 should be identically a Gaussian im1 = galsim.ImageF(64,64, scale=scale) im2 = galsim.ImageF(64,64, scale=scale) for sigma in [1., 0.6, 2.4]: gauss = galsim.Gaussian(flux=test_flux, sigma=sigma) gauss.drawImage(im1, method='no_pixel') for order in [0, 2, 8]: bvec = np.zeros(galsim.Shapelet.size(order)) bvec[0] = test_flux shapelet = galsim.Shapelet(sigma=sigma, order=order, bvec=bvec) shapelet.drawImage(im2, method='no_pixel') printval(im2,im1) np.testing.assert_array_almost_equal( im1.array, im2.array, 5, err_msg="Shapelet with (only) b00=1 disagrees with Gaussian result" "for flux=%f, sigma=%f, order=%d"%(test_flux,sigma,order)) np.testing.assert_almost_equal( gauss.max_sb, shapelet.max_sb, 5, err_msg="Shapelet max_sb did not match Gaussian max_sb") np.testing.assert_almost_equal( gauss.flux, shapelet.flux, 5, err_msg="Shapelet flux did not match Gaussian flux")
def test_shapelet_gaussian(): """Test that the simplest Shapelet profile is equivalent to a Gaussian """ import time t1 = time.time() ftypes = [np.float32, np.float64] scale = 0.2 test_flux = 23. # First, a Shapelet with only b_00 = 1 should be identically a Gaussian im1 = galsim.ImageF(64, 64, scale=scale) im2 = galsim.ImageF(64, 64, scale=scale) for sigma in [1., 0.6, 2.4]: gauss = galsim.Gaussian(flux=test_flux, sigma=sigma) gauss.draw(im1) for order in [0, 2, 8]: bvec = np.zeros(galsim.LVectorSize(order)) bvec[0] = test_flux shapelet = galsim.Shapelet(sigma=sigma, order=order, bvec=bvec) shapelet.draw(im2) printval(im2, im1) np.testing.assert_array_almost_equal( im1.array, im2.array, 5, err_msg= "Shapelet with (only) b00=1 disagrees with Gaussian result" "for flux=%f, sigma=%f, order=%d" % (test_flux, sigma, order)) t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
def getPSF(self, pos, gsparams=None): """Returns the PSF at position pos @param pos The position in pixel units for which to build the PSF. @param gsparams (Optional) A GSParams instance to pass to the constructed GSObject. @returns a galsim.Shapelet instance. """ if not self.bounds.includes(pos): raise IndexError("position in DES_Shapelet.getPSF is out of bounds") import numpy Px = self._definePxy(pos.x,self.bounds.xmin,self.bounds.xmax) Py = self._definePxy(pos.y,self.bounds.ymin,self.bounds.ymax) order = self.fit_order P = numpy.array([ Px[n-q] * Py[q] for n in range(order+1) for q in range(n+1) ]) assert len(P) == self.fit_size # Note: This is equivalent to: # # P = numpy.empty(self.fit_size) # k = 0 # for n in range(self.fit_order+1): # for q in range(n+1): # P[k] = Px[n-q] * Py[q] # k = k+1 b1 = numpy.dot(P,self.interp_matrix) b = numpy.dot(b1,self.rot_matrix) assert len(b) == self.psf_size b += self.ave_psf ret = galsim.Shapelet(self.sigma, self.psf_order, b, gsparams=gsparams) return ret
def test_shapelet_properties(): """Test some specific numbers for a particular Shapelet profile. """ # A semi-random particular vector of coefficients. sigma = 1.8 order = 4 bvec = [ 1.3, # n = 0 0.02, 0.03, # n = 1 0.23, -0.19, 0.08, # n = 2 0.01, 0.02, 0.04, -0.03, # n = 3 -0.09, 0.07, -0.11, -0.08, 0.11 ] # n = 4 shapelet = galsim.Shapelet(sigma=sigma, order=order, bvec=bvec) check_basic(shapelet, "Shapelet", approx_maxsb=True) # Check flux flux = bvec[0] + bvec[5] + bvec[14] np.testing.assert_almost_equal(shapelet.getFlux(), flux, 10) # The maxSB is not very accurate for Shapelet, but in this case it is still ok (matching # xValue(0,0), which isn't actually the maximum) to 2 digits. np.testing.assert_almost_equal( shapelet.xValue(0, 0), shapelet.maxSB(), 2, err_msg="Shapelet maxSB did not match maximum pixel value") # Check centroid cen = galsim.PositionD( bvec[1], -bvec[2]) + np.sqrt(2.) * galsim.PositionD(bvec[8], -bvec[9]) cen *= 2. * sigma / flux np.testing.assert_almost_equal(shapelet.centroid().x, cen.x, 10) np.testing.assert_almost_equal(shapelet.centroid().y, cen.y, 10) # Check Fourier properties np.testing.assert_almost_equal(shapelet.maxK(), 4.61738371186, 10) np.testing.assert_almost_equal(shapelet.stepK(), 0.195133742529, 10) # Check image values in real and Fourier space zero = galsim.PositionD(0., 0.) np.testing.assert_almost_equal(shapelet.kValue(zero), flux + 0j, 10) np.testing.assert_almost_equal(shapelet.xValue(zero), 0.0653321217013, 10) # Check picklability do_pickle(shapelet) do_pickle(shapelet.SBProfile) do_pickle(shapelet.SBProfile.getBVec())
def BuildDES_Shapelet(config, key, base, ignore, gsparams, logger): """@brief Build a RealGalaxy type GSObject from user input. """ opt = {'flux': float, 'num': int} kwargs, safe = galsim.config.GetAllParams(config, key, base, opt=opt, ignore=ignore) if 'des_shapelet' not in base: raise ValueError( "No DES_Shapelet instance available for building type = DES_Shapelet" ) num = kwargs.get('num', 0) if num < 0: raise ValueError( "Invalid num < 0 supplied for DES_Shapelet: num = %d" % num) if num >= len(base['des_shapelet']): raise ValueError( "Invalid num supplied for DES_Shapelet (too large): num = %d" % num) des_shapelet = base['des_shapelet'][num] if 'image_pos' not in base: raise ValueError( "DES_Shapelet requested, but no image_pos defined in base.") image_pos = base['image_pos'] # Convert gsparams from a dict to an actual GSParams object if gsparams: gsparams = galsim.GSParams(**gsparams) else: gsparams = None if des_shapelet.getBounds().includes(image_pos): #psf = des_shapelet.getPSF(image_pos, gsparams) # Because of serialization issues, the above call doesn't work. So we need to # repeat the internals of getPSF here. b = des_shapelet.getB(image_pos) sigma = des_shapelet.getSigma() order = des_shapelet.getOrder() psf = galsim.Shapelet(sigma, order, b, gsparams=gsparams) else: message = 'Position ' + str( image_pos) + ' not in interpolation bounds: ' message += str(des_shapelet.getBounds()) raise galsim.config.gsobject.SkipThisObject(message) if 'flux' in kwargs: psf = psf.withFlux(kwargs['flux']) # The second item here is "safe", a boolean that declares whether the returned value is # safe to save and use again for later objects. In this case, we wouldn't want to do # that, since they will be at different positions, so the interpolated PSF will be different. return psf, False
def getPSF(self, image_pos, gsparams=None): """Returns the PSF at position image_pos @param image_pos The position in pixel units for which to build the PSF. @param gsparams (Optional) A GSParams instance to pass to the constructed GSObject. @returns the PSF as a galsim.Shapelet instance """ return galsim.Shapelet(self.sigma, self.psf_order, self.getB(image_pos), gsparams=gsparams)
def BuildDES_Shapelet(config, base, ignore, gsparams, logger): """Build a GSObject representing the shapelet model at the correct location in the image in a config-processing context. This is used as object type ``DES_Shapelet`` in a config file. It requires the use of the ``des_shapelet`` input field. """ des_shapelet = galsim.config.GetInputObj('des_shapelet', config, base, 'DES_Shapelet') opt = {'flux': float, 'num': int, 'image_pos': galsim.PositionD} params, safe = galsim.config.GetAllParams(config, base, opt=opt, ignore=ignore) if 'image_pos' in params: image_pos = params['image_pos'] elif 'image_pos' in base: image_pos = base['image_pos'] else: raise galsim.GalSimConfigError( "DES_Shapelet requested, but no image_pos defined in base.") # Convert gsparams from a dict to an actual GSParams object if gsparams: gsparams = galsim.GSParams(**gsparams) else: gsparams = None if des_shapelet.getBounds().includes(image_pos): #psf = des_shapelet.getPSF(image_pos, gsparams) # Because of serialization issues, the above call doesn't work. So we need to # repeat the internals of getPSF here. b = des_shapelet.getB(image_pos) sigma = des_shapelet.getSigma() order = des_shapelet.getOrder() psf = galsim.Shapelet(sigma, order, b, gsparams=gsparams).transform(-1, 0, 0, 1) else: message = 'Position ' + str( image_pos) + ' not in interpolation bounds: ' message += str(des_shapelet.getBounds()) raise galsim.config.gsobject.SkipThisObject(message) if 'flux' in params: psf = psf.withFlux(params['flux']) # The second item here is "safe", a boolean that declares whether the returned value is # safe to save and use again for later objects. In this case, we wouldn't want to do # that, since they will be at different positions, so the interpolated PSF will be different. return psf, False
def test_shapelet_properties(): """Test some specific numbers for a particular Shapelet profile. """ import time t1 = time.time() # A semi-random particular vector of coefficients. sigma = 1.8 order = 4 bvec = [ 1.3, # n = 0 0.02, 0.03, # n = 1 0.23, -0.19, 0.08, # n = 2 0.01, 0.02, 0.04, -0.03, # n = 3 -0.09, 0.07, -0.11, -0.08, 0.11 ] # n = 4 shapelet = galsim.Shapelet(sigma=sigma, order=order, bvec=bvec) # Check flux flux = bvec[0] + bvec[5] + bvec[14] np.testing.assert_almost_equal(shapelet.getFlux(), flux, 10) # Check centroid cen = galsim.PositionD( bvec[1], -bvec[2]) + np.sqrt(2.) * galsim.PositionD(bvec[8], -bvec[9]) cen *= 2. * sigma / flux np.testing.assert_almost_equal(shapelet.centroid().x, cen.x, 10) np.testing.assert_almost_equal(shapelet.centroid().y, cen.y, 10) # Check Fourier properties np.testing.assert_almost_equal(shapelet.maxK(), 4.61738371186, 10) np.testing.assert_almost_equal(shapelet.stepK(), 0.195133742529, 10) # Check image values in real and Fourier space zero = galsim.PositionD(0., 0.) np.testing.assert_almost_equal(shapelet.kValue(zero), flux + 0j, 10) np.testing.assert_almost_equal(shapelet.xValue(zero), 0.0653321217013, 10) # Check picklability do_pickle(shapelet) t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
def getPSF(self, image_pos, gsparams=None): """Returns the PSF at position image_pos @param image_pos The position in pixel units for which to build the PSF. @param gsparams (Optional) A GSParams instance to pass to the constructed GSObject. @returns the PSF as a galsim.Shapelet instance """ psf = galsim.Shapelet(self.sigma, self.psf_order, self.getB(image_pos), gsparams=gsparams) # The fitpsf files were built with respect to (u,v) = (ra,dec). The GalSim convention is # to use sky coordinates with u = -ra. So we need to flip the profile across the v axis # to take u -> -u. psf = psf.transform(-1,0,0,1) return psf
def test_shapelet_drawImage(): """Test some measured properties of a drawn shapelet against the supposed true values """ ftypes = [np.float32, np.float64] scale = 0.2 test_flux = 23. im = galsim.ImageF(129,129, scale=scale) for sigma in [1., 0.3, 2.4]: for order in [0, 2, 8]: bvec = np.zeros(galsim.Shapelet.size(order)) bvec[0] = 1. # N,m = 0,0 k = 0 for n in range(1,order+1): k += n+1 if n%2 == 0: # even n bvec[k] = 0.23/(n*n) # N,m = n,0 or p,q = n/2,n/2 if n >= 2: bvec[k-2] = 0.14/n # N,m = n,2 real part bvec[k-1] = -0.08/n # N,m = n,2 imag part else: # odd n if n >= 1: bvec[k-1] = -0.08/n**3.2 # N,m = n,1 real part bvec[k] = 0.05/n**2.1 # N,m = n,1 imag part if n >= 3: bvec[k-3] = 0.31/n**4.2 # N,m = n,3 real part bvec[k-2] = -0.18/n**3.9 # N,m = n,3 imag part print('shapelet vector = ',bvec) shapelet = galsim.Shapelet(sigma=sigma, order=order, bvec=bvec) gsp = galsim.GSParams(xvalue_accuracy=1.e-8, kvalue_accuracy=1.e-8) shapelet2 = galsim.Shapelet(sigma=sigma, order=order, bvec=bvec, gsparams=gsp) assert shapelet2 != shapelet assert shapelet2 == shapelet.withGSParams(gsp) assert shapelet2 == shapelet.withGSParams(xvalue_accuracy=1.e-8, kvalue_accuracy=1.e-8) check_basic(shapelet, "Shapelet", approx_maxsb=True) # Test normalization (This is normally part of do_shoot. When we eventually # implement photon shooting, we should go back to the normal do_shoot call, # and remove this section.) shapelet = shapelet.withFlux(test_flux) shapelet.drawImage(im) flux = im.array.sum() print('im.sum = ',flux,' cf. ',test_flux) np.testing.assert_almost_equal(flux / test_flux, 1., 4, err_msg="Flux normalization for Shapelet disagrees with expected result") np.testing.assert_allclose( im.array.max(), shapelet.max_sb * im.scale**2, rtol=0.1, err_msg="Shapelet max_sb did not match maximum pixel") # Test centroid # Note: this only works if the image has odd sizes. If they are even, then # setCenter doesn't actually set the center to the true center of the image # (since it falls between pixels). im.setCenter(0,0) x,y = np.meshgrid(np.arange(im.array.shape[0]).astype(float) + im.xmin, np.arange(im.array.shape[1]).astype(float) + im.ymin) x *= scale y *= scale flux = im.array.sum() mx = (x*im.array).sum() / flux my = (y*im.array).sum() / flux conv = galsim.Convolve([shapelet, galsim.Pixel(scale)]) print('centroid = ',mx,my,' cf. ',conv.centroid) np.testing.assert_almost_equal(mx, shapelet.centroid.x, 3, err_msg="Measured centroid (x) for Shapelet disagrees with expected result") np.testing.assert_almost_equal(my, shapelet.centroid.y, 3, err_msg="Measured centroid (y) for Shapelet disagrees with expected result")
def test_shapelet_adjustments(): """Test that adjusting the Shapelet profile in various ways does the right thing """ import time t1 = time.time() ftypes = [np.float32, np.float64] nx = 128 ny = 128 scale = 0.2 im = galsim.ImageF(nx, ny, scale=scale) sigma = 1.8 order = 6 bvec = [ 1.3, # n = 0 0.02, 0.03, # n = 1 0.23, -0.19, 0.08, # n = 2 0.01, 0.02, 0.04, -0.03, # n = 3 -0.09, 0.07, -0.11, -0.08, 0.11, # n = 4 -0.03, -0.02, -0.08, 0.01, -0.06, -0.03, # n = 5 0.06, -0.02, 0.00, -0.05, -0.04, 0.01, 0.09 ] # n = 6 ref_shapelet = galsim.Shapelet(sigma=sigma, order=order, bvec=bvec) ref_im = galsim.ImageF(nx, ny) ref_shapelet.draw(ref_im, scale=scale) # Test setSigma shapelet = galsim.Shapelet(sigma=1., order=order, bvec=bvec) shapelet.setSigma(sigma) shapelet.draw(im) np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet set with setSigma disagrees with reference Shapelet") # Test setBVec shapelet = galsim.Shapelet(sigma=sigma, order=order) shapelet.setBVec(bvec) shapelet.draw(im) np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet set with setBVec disagrees with reference Shapelet") # Test setOrder shapelet = galsim.Shapelet(sigma=sigma, order=2) shapelet.setOrder(order) shapelet.setBVec(bvec) shapelet.draw(im) np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet set with setOrder disagrees with reference Shapelet") # Test that changing the order preserves the values to the extent possible. shapelet = galsim.Shapelet(sigma=sigma, order=order, bvec=bvec) shapelet.setOrder(10) np.testing.assert_array_equal( shapelet.getBVec()[0:28], bvec, err_msg="Shapelet setOrder to larger doesn't preserve existing values." ) np.testing.assert_array_equal( shapelet.getBVec()[28:66], np.zeros(66 - 28), err_msg="Shapelet setOrder to larger doesn't fill with zeros.") shapelet.setOrder(6) np.testing.assert_array_equal( shapelet.getBVec(), bvec, err_msg= "Shapelet setOrder back to original from larger doesn't preserve existing values." ) shapelet.setOrder(3) np.testing.assert_array_equal( shapelet.getBVec()[0:10], bvec[0:10], err_msg="Shapelet setOrder to smaller doesn't preserve existing values." ) shapelet.setOrder(6) np.testing.assert_array_equal( shapelet.getBVec()[0:10], bvec[0:10], err_msg= "Shapelet setOrder back to original from smaller doesn't preserve existing values." ) shapelet.setOrder(6) np.testing.assert_array_equal( shapelet.getBVec()[10:28], np.zeros(28 - 10), err_msg= "Shapelet setOrder back to original from smaller doesn't fill with zeros." ) # Test that setting a Shapelet with setNM gives the right profile shapelet = galsim.Shapelet(sigma=sigma, order=order) i = 0 for n in range(order + 1): for m in range(n, -1, -2): if m == 0: shapelet.setNM(n, m, bvec[i]) i = i + 1 else: shapelet.setNM(n, m, bvec[i], bvec[i + 1]) i = i + 2 shapelet.draw(im) np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet set with setNM disagrees with reference Shapelet") # Test that setting a Shapelet with setPQ gives the right profile shapelet = galsim.Shapelet(sigma=sigma, order=order) i = 0 for n in range(order + 1): for m in range(n, -1, -2): p = (n + m) / 2 q = (n - m) / 2 if m == 0: shapelet.setPQ(p, q, bvec[i]) i = i + 1 else: shapelet.setPQ(p, q, bvec[i], bvec[i + 1]) i = i + 2 shapelet.draw(im) np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet set with setPQ disagrees with reference Shapelet") # Test that the Shapelet setFlux does the same thing as the GSObject setFlux gsref_shapelet = galsim.GSObject( ref_shapelet) # Make it opaque to the Shapelet versions gsref_shapelet.setFlux(23.) gsref_shapelet.draw(ref_im) shapelet = galsim.Shapelet(sigma=sigma, order=order, bvec=bvec) shapelet.setFlux(23.) shapelet.draw(im) np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet setFlux disagrees with GSObject setFlux") # Test that the Shapelet scaleFlux does the same thing as the GSObject scaleFlux gsref_shapelet.scaleFlux(0.23) gsref_shapelet.draw(ref_im) shapelet.scaleFlux(0.23) shapelet.draw(im) np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet setFlux disagrees with SObject scaleFlux") # Test that the Shapelet applyRotation does the same thing as the GSObject applyRotation gsref_shapelet.applyRotation(23. * galsim.degrees) gsref_shapelet.draw(ref_im) shapelet.applyRotation(23. * galsim.degrees) shapelet.draw(im) np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet applyRotation disagrees with GSObject applyRotation") # Test that the Shapelet applyDilation does the same thing as the GSObject applyDilation gsref_shapelet.applyDilation(1.3) gsref_shapelet.draw(ref_im) shapelet.applyDilation(1.3) shapelet.draw(im) np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet applyDilation disagrees with GSObject applyDilation") # Test that the Shapelet applyMagnification does the same thing as the GSObject # applyMagnification gsref_shapelet.applyMagnification(0.8) gsref_shapelet.draw(ref_im) shapelet.applyMagnification(0.8) shapelet.draw(im) np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg= "Shapelet applyMagnification disagrees with GSObject applyMagnification" ) # Test that applyLensing works on Shapelet gsref_shapelet.applyLensing(-0.05, 0.15, 1.1) gsref_shapelet.draw(ref_im) shapelet.applyLensing(-0.05, 0.15, 1.1) shapelet.draw(im) np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet applyLensing disagrees with GSObject applyLensing") t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
def test_shapelet_draw(): """Test some measured properties of a drawn shapelet against the supposed true values """ import time t1 = time.time() ftypes = [np.float32, np.float64] scale = 0.2 test_flux = 23. pix = galsim.Pixel(scale) im = galsim.ImageF(129, 129, scale=scale) for sigma in [1., 0.3, 2.4]: for order in [0, 2, 8]: shapelet = galsim.Shapelet(sigma=sigma, order=order) shapelet.setNM(0, 0, 1.) for n in range(1, order + 1): if n % 2 == 0: # even n #shapelet.setNM(n,0,0.23/(n*n)) shapelet.setPQ( n / 2, n / 2, 0.23 / (n * n)) # same thing. Just test setPQ syntax. if n >= 2: shapelet.setNM(n, 2, 0.14 / n, -0.08 / n) else: # odd n if n >= 1: shapelet.setNM(n, 1, -0.08 / n**3.2, 0.05 / n**2.1) if n >= 3: shapelet.setNM(n, 3, 0.31 / n**4.2, -0.18 / n**3.9) #print 'shapelet vector = ',shapelet.getBVec() # Test normalization (This is normally part of do_shoot. When we eventually # implement photon shooting, we should go back to the normal do_shoot call, # and remove this section.) shapelet.setFlux(test_flux) # Need to convolve with a pixel if we want the flux to come out right. conv = galsim.Convolve([pix, shapelet]) conv.draw(im, normalization="surface brightness") flux = im.array.sum() print 'img.sum = ', flux, ' cf. ', test_flux / (scale * scale) np.testing.assert_almost_equal( flux * scale * scale / test_flux, 1., 4, err_msg="Surface brightness normalization for Shapelet " "disagrees with expected result") conv.draw(im, normalization="flux") flux = im.array.sum() print 'im.sum = ', flux, ' cf. ', test_flux np.testing.assert_almost_equal( flux / test_flux, 1., 4, err_msg= "Flux normalization for Shapelet disagrees with expected result" ) # Test centroid # Note: this only works if the image has odd sizes. If they are even, then # setCenter doesn't actually set the center to the true center of the image # (since it falls between pixels). im.setCenter(0, 0) x, y = np.meshgrid( np.arange(im.array.shape[0]).astype(float) + im.getXMin(), np.arange(im.array.shape[1]).astype(float) + im.getYMin()) x *= scale y *= scale flux = im.array.sum() mx = (x * im.array).sum() / flux my = (y * im.array).sum() / flux print 'centroid = ', mx, my, ' cf. ', conv.centroid() np.testing.assert_almost_equal( mx, shapelet.centroid().x, 3, err_msg= "Measured centroid (x) for Shapelet disagrees with expected result" ) np.testing.assert_almost_equal( my, shapelet.centroid().y, 3, err_msg= "Measured centroid (y) for Shapelet disagrees with expected result" ) t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
def test_shapelet_adjustments(): """Test that adjusting the Shapelet profile in various ways does the right thing """ ftypes = [np.float32, np.float64] nx = 128 ny = 128 scale = 0.2 im = galsim.ImageF(nx,ny, scale=scale) sigma = 1.8 order = 6 bvec = [1.3, # n = 0 0.02, 0.03, # n = 1 0.23, -0.19, 0.08, # n = 2 0.01, 0.02, 0.04, -0.03, # n = 3 -0.09, 0.07, -0.11, -0.08, 0.11, # n = 4 -0.03, -0.02, -0.08, 0.01, -0.06, -0.03, # n = 5 0.06, -0.02, 0.00, -0.05, -0.04, 0.01, 0.09 ] # n = 6 ref_shapelet = galsim.Shapelet(sigma=sigma, order=order, bvec=bvec) ref_im = galsim.ImageF(nx,ny) ref_shapelet.drawImage(ref_im, scale=scale) # Test PQ and NM access np.testing.assert_equal(ref_shapelet.getPQ(0,0), (bvec[0],0)) np.testing.assert_equal(ref_shapelet.getPQ(1,1), (bvec[5],0)) np.testing.assert_equal(ref_shapelet.getPQ(1,2), (bvec[8],-bvec[9])) np.testing.assert_equal(ref_shapelet.getPQ(3,2), (bvec[19],bvec[20])) np.testing.assert_equal(ref_shapelet.getNM(0,0), (bvec[0],0)) np.testing.assert_equal(ref_shapelet.getNM(2,0), (bvec[5],0)) np.testing.assert_equal(ref_shapelet.getNM(3,-1), (bvec[8],-bvec[9])) np.testing.assert_equal(ref_shapelet.getNM(5,1), (bvec[19],bvec[20])) # Test that the Shapelet withFlux does the same thing as the GSObject withFlux # Make it opaque to the Shapelet versions alt_shapelet = ref_shapelet + 0. * galsim.Gaussian(sigma=1) alt_shapelet.withFlux(23.).drawImage(ref_im, method='no_pixel') shapelet = galsim.Shapelet(sigma=sigma, order=order, bvec=bvec) shapelet.withFlux(23.).drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet withFlux disagrees with GSObject withFlux") # Test that scaling the Shapelet flux does the same thing as the GSObject scaling (alt_shapelet * 0.23).drawImage(ref_im, method='no_pixel') (shapelet * 0.23).drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet *= 0.23 disagrees with GSObject *= 0.23") # Test that the Shapelet rotate does the same thing as the GSObject rotate alt_shapelet.rotate(23. * galsim.degrees).drawImage(ref_im, method='no_pixel') shapelet.rotate(23. * galsim.degrees).drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet rotate disagrees with GSObject rotate") # Test that the Shapelet dilate does the same thing as the GSObject dilate alt_shapelet.dilate(1.3).drawImage(ref_im, method='no_pixel') shapelet.dilate(1.3).drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet dilate disagrees with GSObject dilate") # Test that the Shapelet expand does the same thing as the GSObject expand alt_shapelet.expand(1.7).drawImage(ref_im, method='no_pixel') shapelet.expand(1.7).drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet expand disagrees with GSObject expand") # Test that the Shapelet magnify does the same thing as the GSObject magnify alt_shapelet.magnify(0.8).drawImage(ref_im, method='no_pixel') shapelet.magnify(0.8).drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet magnify disagrees with GSObject magnify") # Test that lens works on Shapelet alt_shapelet.lens(-0.05, 0.15, 1.1).drawImage(ref_im, method='no_pixel') shapelet.lens(-0.05, 0.15, 1.1).drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet lens disagrees with GSObject lens")
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_dep_shapelet(): """Test the deprecated methods in galsim/deprecated/shapelet.py """ np.testing.assert_almost_equal(check_dep(galsim.LVectorSize, 12), galsim.ShapeletSize(12)) # The next bit is from the old test_shapelet_adjustments() test ftypes = [np.float32, np.float64] nx = 128 ny = 128 scale = 0.2 im = galsim.ImageF(nx, ny, scale=scale) sigma = 1.8 order = 6 bvec = [ 1.3, # n = 0 0.02, 0.03, # n = 1 0.23, -0.19, 0.08, # n = 2 0.01, 0.02, 0.04, -0.03, # n = 3 -0.09, 0.07, -0.11, -0.08, 0.11, # n = 4 -0.03, -0.02, -0.08, 0.01, -0.06, -0.03, # n = 5 0.06, -0.02, 0.00, -0.05, -0.04, 0.01, 0.09 ] # n = 6 ref_shapelet = galsim.Shapelet(sigma=sigma, order=order, bvec=bvec) ref_im = galsim.ImageF(nx, ny) ref_shapelet.drawImage(ref_im, scale=scale, method='no_pixel') # test setsigma shapelet = galsim.Shapelet(sigma=1., order=order, bvec=bvec) check_dep(shapelet.setSigma, sigma) shapelet.drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet set with setSigma disagrees with reference Shapelet") # Test setBVec shapelet = galsim.Shapelet(sigma=sigma, order=order) check_dep(shapelet.setBVec, bvec) shapelet.drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet set with setBVec disagrees with reference Shapelet") # Test setOrder shapelet = galsim.Shapelet(sigma=sigma, order=2) check_dep(shapelet.setOrder, order) check_dep(shapelet.setBVec, bvec) shapelet.drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet set with setOrder disagrees with reference Shapelet") # Test that changing the order preserves the values to the extent possible. shapelet = galsim.Shapelet(sigma=sigma, order=order, bvec=bvec) check_dep(shapelet.setOrder, 10) np.testing.assert_array_equal( shapelet.getBVec()[0:28], bvec, err_msg="Shapelet setOrder to larger doesn't preserve existing values." ) np.testing.assert_array_equal( shapelet.getBVec()[28:66], np.zeros(66 - 28), err_msg="Shapelet setOrder to larger doesn't fill with zeros.") check_dep(shapelet.setOrder, 6) np.testing.assert_array_equal( shapelet.getBVec(), bvec, err_msg= "Shapelet setOrder back to original from larger doesn't preserve existing values." ) check_dep(shapelet.setOrder, 3) np.testing.assert_array_equal( shapelet.getBVec()[0:10], bvec[0:10], err_msg="Shapelet setOrder to smaller doesn't preserve existing values." ) check_dep(shapelet.setOrder, 6) np.testing.assert_array_equal( shapelet.getBVec()[0:10], bvec[0:10], err_msg= "Shapelet setOrder back to original from smaller doesn't preserve existing values." ) check_dep(shapelet.setOrder, 6) np.testing.assert_array_equal( shapelet.getBVec()[10:28], np.zeros(28 - 10), err_msg= "Shapelet setOrder back to original from smaller doesn't fill with zeros." ) # Test that setting a Shapelet with setNM gives the right profile shapelet = galsim.Shapelet(sigma=sigma, order=order) i = 0 for n in range(order + 1): for m in range(n, -1, -2): if m == 0: check_dep(shapelet.setNM, n, m, bvec[i]) i = i + 1 else: check_dep(shapelet.setNM, n, m, bvec[i], bvec[i + 1]) i = i + 2 shapelet.drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet set with setNM disagrees with reference Shapelet") # Test that setting a Shapelet with setPQ gives the right profile shapelet = galsim.Shapelet(sigma=sigma, order=order) i = 0 for n in range(order + 1): for m in range(n, -1, -2): p = (n + m) // 2 q = (n - m) // 2 if m == 0: check_dep(shapelet.setPQ, p, q, bvec[i]) i = i + 1 else: check_dep(shapelet.setPQ, p, q, bvec[i], bvec[i + 1]) i = i + 2 shapelet.drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet set with setPQ disagrees with reference Shapelet") # Check fitImage s1 = galsim.Shapelet(sigma=sigma, order=10) check_dep(s1.fitImage, image=im) s2 = galsim.FitShapelet(sigma=sigma, order=10, image=im) np.testing.assert_array_almost_equal(s1.getBVec(), s2.getBVec())
def test_shapelet_fit(): """Test fitting a Shapelet decomposition of an image """ import time t1 = time.time() for norm in ['f', 'sb']: # We fit a shapelet approximation of a distorted Moffat profile: flux = 20 psf = galsim.Moffat(beta=3.4, half_light_radius=1.2, flux=flux) psf.applyShear(g1=0.11, g2=0.07) psf.applyShift(0.03, 0.04) scale = 0.2 pixel = galsim.Pixel(scale) conv = galsim.Convolve([psf, pixel]) im1 = conv.draw(scale=scale, normalization=norm) sigma = 1.2 # Match half-light-radius as a decent first approximation. shapelet = galsim.Shapelet(sigma=sigma, order=10) shapelet.fitImage(im1, normalization=norm) #print 'fitted shapelet coefficients = ',shapelet.getBVec() # Check flux print 'flux = ', shapelet.getFlux(), ' cf. ', flux np.testing.assert_almost_equal( shapelet.getFlux() / flux, 1., 1, err_msg="Fitted shapelet has the wrong flux") # Test centroid print 'centroid = ', shapelet.centroid(), ' cf. ', conv.centroid() np.testing.assert_almost_equal( shapelet.centroid().x, conv.centroid().x, 2, err_msg="Fitted shapelet has the wrong centroid (x)") np.testing.assert_almost_equal( shapelet.centroid().y, conv.centroid().y, 2, err_msg="Fitted shapelet has the wrong centroid (y)") # Test drawing image from shapelet im2 = im1.copy() shapelet.draw(im2, normalization=norm) # Check that images are close to the same: print 'norm(diff) = ', np.sum((im1.array - im2.array)**2) print 'norm(im) = ', np.sum(im1.array**2) assert np.sum( (im1.array - im2.array)**2) < 1.e-3 * np.sum(im1.array**2) # Remeasure -- should now be very close to the same. shapelet2 = shapelet.copy() shapelet2.fitImage(im2, normalization=norm) np.testing.assert_equal( shapelet.getSigma(), shapelet2.getSigma(), err_msg="Second fitted shapelet has the wrong sigma") np.testing.assert_equal( shapelet.getOrder(), shapelet2.getOrder(), err_msg="Second fitted shapelet has the wrong order") np.testing.assert_almost_equal( shapelet.getBVec(), shapelet2.getBVec(), 6, err_msg="Second fitted shapelet coefficients do not match original" ) t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
def test_shapelet_drawImage(): """Test some measured properties of a drawn shapelet against the supposed true values """ import time t1 = time.time() ftypes = [np.float32, np.float64] scale = 0.2 test_flux = 23. im = galsim.ImageF(129,129, scale=scale) for sigma in [1., 0.3, 2.4]: for order in [0, 2, 8]: bvec = np.zeros(galsim.ShapeletSize(order)) bvec[0] = 1. # N,m = 0,0 k = 0 for n in range(1,order+1): k += n+1 if n%2 == 0: # even n bvec[k] = 0.23/(n*n) # N,m = n,0 or p,q = n/2,n/2 if n >= 2: bvec[k-2] = 0.14/n # N,m = n,2 real part bvec[k-1] = -0.08/n # N,m = n,2 imag part else: # odd n if n >= 1: bvec[k-1] = -0.08/n**3.2 # N,m = n,1 real part bvec[k] = 0.05/n**2.1 # N,m = n,1 imag part if n >= 3: bvec[k-3] = 0.31/n**4.2 # N,m = n,3 real part bvec[k-2] = -0.18/n**3.9 # N,m = n,3 imag part print 'shapelet vector = ',bvec shapelet = galsim.Shapelet(sigma=sigma, order=order, bvec=bvec) # Test normalization (This is normally part of do_shoot. When we eventually # implement photon shooting, we should go back to the normal do_shoot call, # and remove this section.) shapelet = shapelet.withFlux(test_flux) shapelet.drawImage(im) flux = im.array.sum() print 'im.sum = ',flux,' cf. ',test_flux np.testing.assert_almost_equal(flux / test_flux, 1., 4, err_msg="Flux normalization for Shapelet disagrees with expected result") # Test centroid # Note: this only works if the image has odd sizes. If they are even, then # setCenter doesn't actually set the center to the true center of the image # (since it falls between pixels). im.setCenter(0,0) x,y = np.meshgrid(np.arange(im.array.shape[0]).astype(float) + im.getXMin(), np.arange(im.array.shape[1]).astype(float) + im.getYMin()) x *= scale y *= scale flux = im.array.sum() mx = (x*im.array).sum() / flux my = (y*im.array).sum() / flux conv = galsim.Convolve([shapelet, galsim.Pixel(scale)]) print 'centroid = ',mx,my,' cf. ',conv.centroid() np.testing.assert_almost_equal(mx, shapelet.centroid().x, 3, err_msg="Measured centroid (x) for Shapelet disagrees with expected result") np.testing.assert_almost_equal(my, shapelet.centroid().y, 3, err_msg="Measured centroid (y) for Shapelet disagrees with expected result") t2 = time.time() print 'time for %s = %.2f'%(funcname(),t2-t1)
def test_shapelet_adjustments(): """Test that adjusting the Shapelet profile in various ways does the right thing """ import time t1 = time.time() ftypes = [np.float32, np.float64] nx = 128 ny = 128 scale = 0.2 im = galsim.ImageF(nx,ny, scale=scale) sigma = 1.8 order = 6 bvec = [1.3, # n = 0 0.02, 0.03, # n = 1 0.23, -0.19, 0.08, # n = 2 0.01, 0.02, 0.04, -0.03, # n = 3 -0.09, 0.07, -0.11, -0.08, 0.11, # n = 4 -0.03, -0.02, -0.08, 0.01, -0.06, -0.03, # n = 5 0.06, -0.02, 0.00, -0.05, -0.04, 0.01, 0.09 ] # n = 6 ref_shapelet = galsim.Shapelet(sigma=sigma, order=order, bvec=bvec) ref_im = galsim.ImageF(nx,ny) ref_shapelet.drawImage(ref_im, scale=scale) # Test that the Shapelet withFlux does the same thing as the GSObject withFlux gsref_shapelet = galsim.GSObject(ref_shapelet) # Make it opaque to the Shapelet versions gsref_shapelet.withFlux(23.).drawImage(ref_im, method='no_pixel') shapelet = galsim.Shapelet(sigma=sigma, order=order, bvec=bvec) shapelet.withFlux(23.).drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet withFlux disagrees with GSObject withFlux") # Test that scaling the Shapelet flux does the same thing as the GSObject scaling gsref_shapelet *= 0.23 gsref_shapelet.drawImage(ref_im, method='no_pixel') shapelet *= 0.23 shapelet.drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet *= 0.23 disagrees with GSObject *= 0.23") # Test that the Shapelet rotate does the same thing as the GSObject rotate gsref_shapelet.rotate(23. * galsim.degrees).drawImage(ref_im, method='no_pixel') shapelet.rotate(23. * galsim.degrees).drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet rotate disagrees with GSObject rotate") # Test that the Shapelet dilate does the same thing as the GSObject dilate gsref_shapelet.dilate(1.3).drawImage(ref_im, method='no_pixel') shapelet.dilate(1.3).drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet dilate disagrees with GSObject dilate") # Test that the Shapelet magnify does the same thing as the GSObject magnify gsref_shapelet.magnify(0.8).drawImage(ref_im, method='no_pixel') shapelet.magnify(0.8).drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet magnify disagrees with GSObject magnify") # Test that lens works on Shapelet gsref_shapelet.lens(-0.05, 0.15, 1.1).drawImage(ref_im, method='no_pixel') shapelet.lens(-0.05, 0.15, 1.1).drawImage(im, method='no_pixel') np.testing.assert_array_almost_equal( im.array, ref_im.array, 6, err_msg="Shapelet lens disagrees with GSObject lens") t2 = time.time() print 'time for %s = %.2f'%(funcname(),t2-t1)