def get_HST_im_noise(images, SNRs, row, rng): [gal_im_v, gal_im_i] = images flux = np.array([gal_im_v.array.sum(), gal_im_i.array.sum()]) xi_v = galsim.getCOSMOSNoise(file_name='data/acs_V_unrot_sci_cf.fits', rng=rng) xi_i = galsim.getCOSMOSNoise(file_name='data/acs_I_unrot_sci_cf.fits', rng=rng) var_v = gal_im_v.addNoiseSNR(xi_v, snr=SNRs[0], preserve_flux=True) var_i = gal_im_i.addNoiseSNR(xi_i, snr=SNRs[1], preserve_flux=True) xi_v = galsim.getCOSMOSNoise(file_name='data/acs_V_unrot_sci_cf.fits', variance=var_v, rng=rng) xi_i = galsim.getCOSMOSNoise(file_name='data/acs_I_unrot_sci_cf.fits', variance=var_i, rng=rng) # Compute sn_ellip_gauss res_v = galsim.hsm.FindAdaptiveMom(gal_im_v, strict=False) res_i = galsim.hsm.FindAdaptiveMom(gal_im_i, strict=False) if (res_v.error_message != "") or (res_v.error_message != ""): print "HSM failed" else: aperture_noise_v = np.sqrt(var_v * 2 * np.pi * (res_v.moments_sigma**2)) / 1 aperture_noise_i = np.sqrt(var_i * 2 * np.pi * (res_i.moments_sigma**2)) / 1 sn_ellip_gauss_v = res_v.moments_amp / aperture_noise_v sn_ellip_gauss_i = res_i.moments_amp / aperture_noise_i row['sn_ellip_gauss'] = np.array([sn_ellip_gauss_v, sn_ellip_gauss_i]) row['noise_var'] = np.array([var_v, var_i]) row['flux'] = flux row['input_SNR'] = SNRs return [gal_im_v, gal_im_i], [xi_v, xi_i]
def get_CRG_basic(gal, in_p, true_SED=True, noise_variance=np.array([1e-39, 1e-39])): """Comptes CRG for input galaxy. @param gal galsim object of the galaxy to create CRG. in_p Input parametrs used to draw galaxy. This must contain the bulge, disk and composite SEDs. tru_SED If true then also return CRG with true SED as input noise_variance variance of HST noise to be added to the CRG input galaxy image in V and I bands """ hst_param = Eu_Args(scale=0.03, psf_sig_o=0.071, psf_w_o=806) PSF = get_gaussian_PSF(hst_param) con = galsim.Convolve([gal, PSF]) # get bandpass V_band = get_HST_Bandpass('F606W') I_band = get_HST_Bandpass('F814W') path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data/') xi_v = galsim.getCOSMOSNoise(file_name=path + 'acs_V_unrot_sci_cf.fits', variance=noise_variance[0]) xi_i = galsim.getCOSMOSNoise(file_name=path + 'acs_I_unrot_sci_cf.fits', variance=noise_variance[1]) psf_v = get_eff_psf(PSF, in_p.c_SED, V_band) psf_i = get_eff_psf(PSF, in_p.c_SED, I_band) eff_PSFs = [psf_v, psf_i] gal_im_v = con.drawImage(V_band, nx=350, ny=350, scale=0.03) gal_im_i = con.drawImage(I_band, nx=350, ny=350, scale=0.03) gal_im_v.addNoise(xi_v) gal_im_i.addNoise(xi_i) # Polynomial SEDs images = [gal_im_v, gal_im_i] bands = [V_band, I_band] crg1 = galsim.ChromaticRealGalaxy.makeFromImages(images=images, bands=bands, xis=[xi_v, xi_i], PSFs=eff_PSFs) if true_SED: seds = [in_p.b_SED, in_p.d_SED] crg2 = galsim.ChromaticRealGalaxy.makeFromImages(images=images, bands=bands, xis=[xi_v, xi_i], PSFs=eff_PSFs, SEDs=seds) return crg1, crg2 else: return crg1
def process(self, cache, ifield): self.log.info('begining for field %04d' % (ifield)) outFname = os.path.join(self.config.outDir, 'noi%04d.fits' % (ifield)) if os.path.exists(outFname): self.log.info('Already have the outcome') return self.log.info('simulating noise for field %s' % (ifield)) ngrid = 64 nx = 100 ny = nx scale = 0.168 variance = 0.01 ud = galsim.UniformDeviate(ifield * 10000 + 1) # setup the galaxy image and the noise image noi_image = galsim.ImageF(nx * ngrid, ny * ngrid, scale=scale) noi_image.setOrigin(0, 0) corNoise = galsim.getCOSMOSNoise(file_name='./corPre/correlation.fits',\ rng=ud,cosmos_scale=scale,variance=variance) corNoise.applyTo(noi_image) pyfits.writeto(outFname, noi_image.array) return
def test_whiten(): """Test the options in config to whiten images """ real_gal_dir = os.path.join('..','examples','data') real_gal_cat = 'real_galaxy_catalog_23.5_example.fits' config = { 'image' : { 'type' : 'Single', 'random_seed' : 1234, 'pixel_scale' : 0.05, }, 'stamp' : { 'type' : 'Basic', 'size' : 32, }, 'gal' : { 'type' : 'RealGalaxy', 'index' : 79, 'flux' : 100, }, 'psf' : { # This is really slow if we don't convolve by a PSF. 'type' : 'Gaussian', 'sigma' : 0.05 }, 'input' : { 'real_catalog' : { 'dir' : real_gal_dir , 'file_name' : real_gal_cat } } } # First build by hand (no whitening yet) rng = galsim.BaseDeviate(1234 + 1) rgc = galsim.RealGalaxyCatalog(os.path.join(real_gal_dir, real_gal_cat)) gal = galsim.RealGalaxy(rgc, index=79, flux=100, rng=rng) psf = galsim.Gaussian(sigma=0.05) final = galsim.Convolve(gal,psf) im1a = final.drawImage(nx=32, ny=32, scale=0.05) # Compare to what config builds galsim.config.ProcessInput(config) im1b, cv1b = galsim.config.BuildStamp(config, do_noise=False) np.testing.assert_equal(cv1b, 0.) np.testing.assert_equal(im1b.array, im1a.array) # Now add whitening, but no noise yet. cv1a = final.noise.whitenImage(im1a) print('From whiten, current_var = ',cv1a) galsim.config.RemoveCurrent(config) config['image']['noise'] = { 'whiten' : True, } im1c, cv1c = galsim.config.BuildStamp(config, do_noise=False) print('From BuildStamp, current_var = ',cv1c) np.testing.assert_equal(cv1c, cv1a) np.testing.assert_equal(im1c.array, im1a.array) rng1 = rng.duplicate() # Save current state of rng # 1. Gaussian noise ##### config['image']['noise'] = { 'type' : 'Gaussian', 'variance' : 50, 'whiten' : True, } galsim.config.RemoveCurrent(config) im2a = im1a.copy() im2a.addNoise(galsim.GaussianNoise(sigma=math.sqrt(50-cv1a), rng=rng)) im2b, cv2b = galsim.config.BuildStamp(config) np.testing.assert_almost_equal(cv2b, 50) np.testing.assert_almost_equal(im2b.array, im2a.array, decimal=5) # If whitening already added too much noise, raise an exception config['image']['noise']['variance'] = 1.e-5 try: np.testing.assert_raises(RuntimeError, galsim.config.BuildStamp,config) except ImportError: pass # 2. Poisson noise ##### config['image']['noise'] = { 'type' : 'Poisson', 'sky_level_pixel' : 50, 'whiten' : True, } galsim.config.RemoveCurrent(config) im3a = im1a.copy() sky = 50 - cv1a rng.reset(rng1.duplicate()) im3a.addNoise(galsim.PoissonNoise(sky_level=sky, rng=rng)) im3b, cv3b = galsim.config.BuildStamp(config) np.testing.assert_almost_equal(cv3b, 50, decimal=5) np.testing.assert_almost_equal(im3b.array, im3a.array, decimal=5) # It's more complicated if the sky is quoted per arcsec and the wcs is not uniform. config2 = galsim.config.CopyConfig(config) galsim.config.RemoveCurrent(config2) config2['image']['sky_level'] = 100 config2['image']['wcs'] = { 'type' : 'UVFunction', 'ufunc' : '0.05*x + 0.001*x**2', 'vfunc' : '0.05*y + 0.001*y**2', } del config2['image']['pixel_scale'] del config2['wcs'] config2['image']['noise']['symmetrize'] = 4 # Also switch to symmetrize, just to mix it up. del config2['image']['noise']['whiten'] rng.reset(1234+1) # Start fresh, since redoing the whitening/symmetrizing wcs = galsim.UVFunction(ufunc='0.05*x + 0.001*x**2', vfunc='0.05*y + 0.001*y**2') im3c = galsim.Image(32,32, wcs=wcs) im3c = final.drawImage(im3c) cv3c = final.noise.symmetrizeImage(im3c,4) sky = galsim.Image(im3c.bounds, wcs=wcs) wcs.makeSkyImage(sky, 100) mean_sky = np.mean(sky.array) im3c += sky extra_sky = 50 - cv3c im3c.addNoise(galsim.PoissonNoise(sky_level=extra_sky, rng=rng)) im3d, cv3d = galsim.config.BuildStamp(config2) np.testing.assert_almost_equal(cv3d, 50 + mean_sky, decimal=4) np.testing.assert_almost_equal(im3d.array, im3c.array, decimal=5) config['image']['noise']['sky_level_pixel'] = 1.e-5 try: np.testing.assert_raises(RuntimeError, galsim.config.BuildStamp,config) except ImportError: pass # 3. CCDNoise ##### config['image']['noise'] = { 'type' : 'CCD', 'sky_level_pixel' : 25, 'read_noise' : 5, 'gain' : 1, 'whiten' : True, } galsim.config.RemoveCurrent(config) im4a = im1a.copy() rn = math.sqrt(25-cv1a) rng.reset(rng1.duplicate()) im4a.addNoise(galsim.CCDNoise(sky_level=25, read_noise=rn, gain=1, rng=rng)) im4b, cv4b = galsim.config.BuildStamp(config) np.testing.assert_almost_equal(cv4b, 50, decimal=5) np.testing.assert_almost_equal(im4b.array, im4a.array, decimal=5) # Repeat with gain != 1 config['image']['noise']['gain'] = 3.7 galsim.config.RemoveCurrent(config) im5a = im1a.copy() rn = math.sqrt(25-cv1a * 3.7**2) rng.reset(rng1.duplicate()) im5a.addNoise(galsim.CCDNoise(sky_level=25, read_noise=rn, gain=3.7, rng=rng)) im5b, cv5b = galsim.config.BuildStamp(config) np.testing.assert_almost_equal(cv5b, 50, decimal=5) np.testing.assert_almost_equal(im5b.array, im5a.array, decimal=5) # And again with a non-trivial sky image galsim.config.RemoveCurrent(config2) config2['image']['noise'] = config['image']['noise'] config2['image']['noise']['symmetrize'] = 4 del config2['image']['noise']['whiten'] rng.reset(1234+1) im5c = galsim.Image(32,32, wcs=wcs) im5c = final.drawImage(im5c) cv5c = final.noise.symmetrizeImage(im5c, 4) sky = galsim.Image(im5c.bounds, wcs=wcs) wcs.makeSkyImage(sky, 100) mean_sky = np.mean(sky.array) im5c += sky rn = math.sqrt(25-cv5c * 3.7**2) im5c.addNoise(galsim.CCDNoise(sky_level=25, read_noise=rn, gain=3.7, rng=rng)) im5d, cv5d = galsim.config.BuildStamp(config2) np.testing.assert_almost_equal(cv5d, 50 + mean_sky, decimal=4) np.testing.assert_almost_equal(im5d.array, im5c.array, decimal=5) config['image']['noise']['sky_level_pixel'] = 1.e-5 config['image']['noise']['read_noise'] = 0 try: np.testing.assert_raises(RuntimeError, galsim.config.BuildStamp,config) except ImportError: pass # 4. COSMOSNoise ##### file_name = os.path.join(galsim.meta_data.share_dir,'acs_I_unrot_sci_20_cf.fits') config['image']['noise'] = { 'type' : 'COSMOS', 'file_name' : file_name, 'variance' : 50, 'whiten' : True, } galsim.config.RemoveCurrent(config) im6a = im1a.copy() rng.reset(rng1.duplicate()) noise = galsim.getCOSMOSNoise(file_name=file_name, variance=50, rng=rng) noise -= galsim.UncorrelatedNoise(cv1a, rng=rng, wcs=noise.wcs) im6a.addNoise(noise) im6b, cv6b = galsim.config.BuildStamp(config) np.testing.assert_almost_equal(cv6b, 50, decimal=5) np.testing.assert_almost_equal(im6b.array, im6a.array, decimal=5) config['image']['noise']['variance'] = 1.e-5 del config['_current_cn_tag'] try: np.testing.assert_raises(RuntimeError, galsim.config.BuildStamp,config) except ImportError: pass
def check_crg_noise(n_sed, n_im, n_trial, tol): print("Checking CRG noise for") print("n_sed = {}".format(n_sed)) print("n_im = {}".format(n_im)) print("n_trial = {}".format(n_trial)) print("Constructing chromatic PSFs") in_PSF = galsim.ChromaticAiry(lam=700., diam=2.4) out_PSF = galsim.ChromaticAiry(lam=700., diam=0.6) print("Constructing filters and SEDs") waves = np.arange(550.0, 900.1, 10.0) visband = galsim.Bandpass(galsim.LookupTable(waves, np.ones_like(waves), interpolant='linear'), wave_type='nm') split_points = np.linspace(550.0, 900.0, n_im + 1, endpoint=True) bands = [ visband.truncate(blue_limit=blim, red_limit=rlim) for blim, rlim in zip(split_points[:-1], split_points[1:]) ] maxk = max([ out_PSF.evaluateAtWavelength(waves[0]).maxk, out_PSF.evaluateAtWavelength(waves[-1]).maxk ]) SEDs = [ galsim.SED(galsim.LookupTable(waves, waves**i, interpolant='linear'), flux_type='fphotons', wave_type='nm').withFlux(1.0, visband) for i in range(n_sed) ] print("Constructing input noise correlation functions") rng = galsim.BaseDeviate(57721) in_xis = [ galsim.getCOSMOSNoise(cosmos_scale=0.03, rng=rng).dilate(1 + i * 0.05).rotate( 5 * i * galsim.degrees) for i in range(n_im) ] print("Creating noise images") img_sets = [] for i in range(n_trial): imgs = [] for xi in in_xis: img = galsim.Image(128, 128, scale=0.03) img.addNoise(xi) imgs.append(img) img_sets.append(imgs) print("Constructing `ChromaticRealGalaxy`s") crgs = [] for imgs in img_sets: crgs.append( galsim.ChromaticRealGalaxy.makeFromImages(imgs, bands, in_PSF, in_xis, SEDs=SEDs, maxk=maxk)) print("Convolving by output PSF") objs = [galsim.Convolve(crg, out_PSF) for crg in crgs] with assert_raises(galsim.GalSimError): noise = objs[0].noise # Invalid before drawImage is called print("Drawing through output filter") out_imgs = [ obj.drawImage(visband, nx=30, ny=30, scale=0.1) for obj in objs ] noise = objs[0].noise print("Measuring images' correlation functions") xi_obs = galsim.correlatednoise.CorrelatedNoise(out_imgs[0]) for img in out_imgs[1:]: xi_obs += galsim.correlatednoise.CorrelatedNoise(img) xi_obs /= n_trial xi_obs_img = galsim.Image(30, 30, scale=0.1) xi_obs.drawImage(xi_obs_img) noise_img = galsim.Image(30, 30, scale=0.1) noise.drawImage(noise_img) print("Predicted/Observed variance:", noise.getVariance() / xi_obs.getVariance()) print("Predicted/Observed xlag-1 covariance:", noise_img.array[14, 15] / xi_obs_img.array[14, 15]) print("Predicted/Observed ylag-1 covariance:", noise_img.array[15, 14] / xi_obs_img.array[15, 14]) # Just test that the covariances for nearest neighbor pixels are accurate. np.testing.assert_allclose(noise_img.array[14:17, 14:17], xi_obs_img.array[14:17, 14:17], rtol=0, atol=noise.getVariance() * tol)
def get_CRG(cat, rng, row): """Create CRG for a given input parametrs form catsim. Bulge + Disk galaxy is created, convolved with HST PSF, drawn in HST V and I bands for 1 second exposure. Correlated noise (from AEGIS images) is added to each image. SNR in a gaussian elliptical aperture is computed. cgr1: The galaxy +psf images + noise correlation function is provided as input to CRG with default polynomial SEDs. crg2: same as crg1 except, the input galaxy images are padded with noise. This enables us to to draw the CRG image larger than the input image, and not have boundary edges. crg3: same as crg2 except the SEDS of bulge and disk are provided as input to CRG. @cat catsim row containig catsim galaxy parametrs. @rng random number generator. @row astropy table to save measurents. """ # HST scale scale = 0.03 area = 4.437 * 10000 # np.pi * (2.4 * 100 / 2.)**2 v_exptime = 1 # 2260 i_exptime = 1 # 2100 psf_sig = 0.06 nx, ny = get_npix(cat, scale, psf_sig) print "Number of HST pixels:", nx, ny b_r, b_g = a_b2re_e(cat['a_b'], cat['b_b']) d_r, d_g = a_b2re_e(cat['a_d'], cat['b_d']) b_s = galsim.Shear(g=b_g, beta=cat['pa_bulge'] * galsim.degrees) d_s = galsim.Shear(g=d_g, beta=cat['pa_disk'] * galsim.degrees) input_p = cg_fn.Eu_Args(scale=scale, redshift=cat['redshift'], disk_n=cat['bulge_n'], bulge_n=cat['disk_n'], disk_HLR=d_r, bulge_HLR=b_r, bulge_e=[b_s.e1, b_s.e2], disk_e=[d_s.e1, d_s.e2], psf_sig_o=0.071, psf_w_o=806, bulge_frac=0.5) input_p.T_flux = 2 gal, PSF, con, seds = get_gal(input_p, cat, get_seds=True) # get bandpass V = cg_fn.get_HST_Bandpass('F606W') I = cg_fn.get_HST_Bandpass('F814W') c_sed = seds[0] + seds[1] temp_d = seds[1] * cat['fluxnorm_disk'] temp_b = seds[0] * cat['fluxnorm_bulge'] b_sed_mag = [temp_b.calculateMagnitude(V), temp_b.calculateMagnitude(I)] d_sed_mag = [temp_d.calculateMagnitude(V), temp_d.calculateMagnitude(I)] row['b_mag'] = b_sed_mag row['d_mag'] = d_sed_mag gal_im_v = con.drawImage(V, nx=nx, ny=ny, scale=scale, area=area, exptime=v_exptime) gal_im_i = con.drawImage(I, nx=nx, ny=ny, scale=scale, area=area, exptime=i_exptime) flux = np.array([gal_im_v.array.sum(), gal_im_i.array.sum()]) snr_num = np.array([np.sum(gal_im_v.array**2), np.sum(gal_im_i.array**2)]) # correlated noise to add to image noise_v = galsim.getCOSMOSNoise(file_name='data/acs_V_unrot_sci_cf.fits', rng=rng) noise_i = galsim.getCOSMOSNoise(file_name='data/acs_I_unrot_sci_cf.fits', rng=rng) # Add noise gal_im_v.addNoise(noise_v) gal_im_i.addNoise(noise_i) var_v = noise_v.getVariance() var_i = noise_i.getVariance() var = np.array([var_v, var_i]) # Compute sn_ellip_gauss try: res_v = galsim.hsm.FindAdaptiveMom(gal_im_v) res_i = galsim.hsm.FindAdaptiveMom(gal_im_i) aperture_noise_v = np.sqrt(var_v * 2 * np.pi * (res_v.moments_sigma**2)) aperture_noise_i = np.sqrt(var_i * 2 * np.pi * (res_i.moments_sigma**2)) sn_ellip_gauss_v = res_v.moments_amp / aperture_noise_v sn_ellip_gauss_i = res_i.moments_amp / aperture_noise_i except: sn_ellip_gauss_v = -10 sn_ellip_gauss_i = -10 row['HST_sn_ellip_gauss'] = np.array([sn_ellip_gauss_v, sn_ellip_gauss_i]) row['HST_noise_var'] = var row['HST_flux'] = flux row['HST_SNR'] = np.sqrt(snr_num / var) # covariance function for CRG input xi_v = galsim.getCOSMOSNoise(file_name='data/acs_V_unrot_sci_cf.fits', variance=var_v, rng=rng) xi_i = galsim.getCOSMOSNoise(file_name='data/acs_I_unrot_sci_cf.fits', variance=var_i, rng=rng) psf_v = cg_fn.get_eff_psf(PSF, c_sed, V) psf_i = cg_fn.get_eff_psf(PSF, c_sed, I) eff_PSFs = [psf_v, psf_i] print "Creating CRG with noise padding" cg_size = int( max(cat['BulgeHalfLightRadius'], cat['DiskHalfLightRadius'], 2 * psf_sig) * 12) print "pad size", cg_size intp_gal_v = galsim.InterpolatedImage(gal_im_v, noise_pad=noise_v, noise_pad_size=cg_size) gal_im_v_pad = intp_gal_v._pad_image intp_gal_i = galsim.InterpolatedImage(gal_im_i, noise_pad=noise_i, noise_pad_size=cg_size) gal_im_i_pad = intp_gal_i._pad_image print "CRG input im shape ", gal_im_v_pad.array.shape[0] * scale # Polynomial SEDs images = [gal_im_v_pad, gal_im_i_pad] crg1 = galsim.ChromaticRealGalaxy.makeFromImages(images=images, bands=[V, I], xis=[xi_v, xi_i], PSFs=eff_PSFs) return crg1
import numpy as np import galsim import matplotlib.pyplot as plt # For information on where to download the .pkl file below, see the python script # `devel/external/hst/make_cosmos_cfimage.py` NOISEIMFILE = "acs_I_unrot_sci_20_noisearrays.pkl" # Input pickled list filename CFIMFILE_SUB = "acs_I_unrot_sci_20_cf_subtracted.fits" # Output image of correlation function (sub) CFIMFILE_UNS = "acs_I_unrot_sci_20_cf_unsubtracted.fits" # Output image of correlation function RSEED = 12334566 ud = galsim.UniformDeviate(RSEED) # Case 1: subtract_mean=True; Case 2: subtract_mean=False cn1 = galsim.getCOSMOSNoise(ud, CFIMFILE_SUB, dx_cosmos=1.) cn2 = galsim.getCOSMOSNoise(ud, CFIMFILE_UNS, dx_cosmos=1.) testim1 = galsim.ImageD(7, 7) testim2 = galsim.ImageD(7, 7) var1 = 0. var2 = 0. noisearrays = cPickle.load(open(NOISEIMFILE, 'rb')) for noisearray, i in zip(noisearrays, range(len(noisearrays))): noise1 = galsim.ImageViewD((noisearray.copy()).astype(np.float64), scale=1.) noise2 = galsim.ImageViewD((noisearray.copy()).astype(np.float64), scale=1.) cn1.applyWhiteningTo(noise1) cn2.applyWhiteningTo(noise2) var1 += noise1.array.var() var2 += noise2.array.var()
import numpy as np import galsim # Use a deterministic random number generator so we don't fail tests because of rare flukes # in the random numbers. rseed=12345 smallim_size = 16 # size of image when we test correlated noise properties using small inputs largeim_size = 12 * smallim_size # ditto, but when we need a larger image if __name__ == "__main__": t1 = time.time() gd = galsim.GaussianDeviate(rseed) dx_cosmos=0.03 # Non-unity, non-default value to be used below cn = galsim.getCOSMOSNoise(rng=gd, dx_cosmos=dx_cosmos) cn.setVariance(1000.) # Again chosen to be non-unity # Define a PSF with which to convolve the noise field, one WITHOUT 2-fold rotational symmetry # (see test_autocorrelate in test_SBProfile.py for more info as to why this is relevant) # Make a relatively realistic mockup of a GREAT3 target image lam_over_diam_cosmos = (814.e-9 / 2.4) * (180. / np.pi) * 3600. # ~lamda/D in arcsec lam_over_diam_ground = lam_over_diam_cosmos * 2.4 / 4. # Generic 4m at same lambda psf_cosmos = galsim.Convolve([ galsim.Airy(lam_over_diam=lam_over_diam_cosmos, obscuration=0.4), galsim.Pixel(0.05)]) psf_ground = galsim.Convolve([ galsim.Kolmogorov(fwhm=0.8), galsim.Pixel(0.18), galsim.OpticalPSF(lam_over_diam=lam_over_diam_ground, coma2=0.4, defocus=-0.6)]) psf_shera = galsim.Convolve([ psf_ground, (galsim.Deconvolve(psf_cosmos)).createSheared(g1=0.03, g2=-0.01)]) # Then define the convolved cosmos correlated noise model conv_cn = cn.copy()
def test_CRG_noise(args): """Test noise propagation in ChromaticRealGalaxy """ t0 = time.time() print("Constructing chromatic PSFs") in_PSF = galsim.ChromaticAiry(lam=700., diam=2.4) out_PSF = galsim.ChromaticAiry(lam=700., diam=1.2) print("Constructing filters and SEDs") waves = np.arange(550.0, 900.1, 10.0) visband = galsim.Bandpass(galsim.LookupTable(waves, np.ones_like(waves), interpolant='linear'), wave_type='nm') split_points = np.linspace(550.0, 900.0, args.Nim + 1, endpoint=True) bands = [ visband.truncate(blue_limit=blim, red_limit=rlim) for blim, rlim in zip(split_points[:-1], split_points[1:]) ] maxk = max([ out_PSF.evaluateAtWavelength(waves[0]).maxK(), out_PSF.evaluateAtWavelength(waves[-1]).maxK() ]) SEDs = [ galsim.SED(galsim.LookupTable(waves, waves**i, interpolant='linear'), flux_type='fphotons', wave_type='nm').withFlux(1.0, visband) for i in range(args.NSED) ] print("Constructing input noise correlation functions") rng = galsim.BaseDeviate(args.seed) in_xis = [ galsim.getCOSMOSNoise(cosmos_scale=args.in_scale, rng=rng).dilate(1 + i * 0.05).rotate( 5 * i * galsim.degrees) for i in range(args.Nim) ] print("Creating noise images") img_sets = [] for i in range(args.Ntrial): imgs = [] for j, xi in enumerate(in_xis): img = galsim.Image(args.in_Nx, args.in_Nx, scale=args.in_scale) img.addNoise(xi) imgs.append(img) img_sets.append(imgs) print("Constructing `ChromaticRealGalaxy`s") crgs = [] with ProgressBar(len(img_sets)) as bar: for imgs in img_sets: crgs.append( galsim.ChromaticRealGalaxy.makeFromImages(imgs, bands, in_PSF, in_xis, SEDs=SEDs, maxk=maxk)) bar.update() print("Convolving by output PSF") objs = [galsim.Convolve(crg, out_PSF) for crg in crgs] print("Drawing through output filter") out_imgs = [ obj.drawImage(visband, nx=args.out_Nx, ny=args.out_Nx, scale=args.out_scale, iimult=args.iimult) for obj in objs ] noise = objs[0].noise print("Measuring images' correlation functions") xi_obs = galsim.correlatednoise.CorrelatedNoise(out_imgs[0]) for img in out_imgs[1:]: xi_obs += galsim.correlatednoise.CorrelatedNoise(img) xi_obs /= args.Ntrial xi_obs_img = galsim.Image(args.out_Nx, args.out_Nx, scale=args.out_scale) xi_obs.drawImage(xi_obs_img) print("Observed image variance: ", xi_obs.getVariance()) print("Predicted image variance: ", noise.getVariance()) print("Predicted/Observed variance:", noise.getVariance() / xi_obs.getVariance()) print("Took {} seconds".format(time.time() - t0)) if args.plot: import matplotlib.pyplot as plt out_array = (np.arange(args.out_Nx) - args.out_Nx / 2) * args.out_scale out_extent = [ -args.out_Nx * args.out_scale / 2, args.out_Nx * args.out_scale / 2, -args.out_Nx * args.out_scale / 2, args.out_Nx * args.out_scale / 2 ] fig = plt.figure(figsize=(5, 5)) # Sample image ax = fig.add_subplot(111) ax.imshow(out_imgs[0].array, extent=out_extent) ax.set_title("sample output image") ax.set_xlabel("x") ax.set_ylabel("y") # ax.colorbar() fig.show() # 2D correlation functions fig = plt.figure(figsize=(10, 10)) ax1 = fig.add_subplot(221) noise_img = galsim.Image(args.out_Nx, args.out_Nx, scale=args.out_scale) noise.drawImage(noise_img) ax1.imshow(np.log10(np.abs(noise_img.array)), extent=out_extent) ax1.set_title("predicted covariance function") ax1.set_xlabel(r"$\Delta x$") ax1.set_ylabel(r"$\Delta y$") ax2 = fig.add_subplot(222) ax2.imshow(np.log10(np.abs(xi_obs_img.array)), extent=out_extent) ax2.set_title("observed covariance function") ax2.set_xlabel(r"$\Delta x$") ax2.set_ylabel(r"$\Delta y$") # 1D slide through correlation functions ax3 = fig.add_subplot(223) ax3.plot(out_array, noise_img.array[args.out_Nx / 2, :], label="prediction", color='red') ax3.plot(out_array, xi_obs_img.array[args.out_Nx / 2, :], label="observation", color='blue') ax3.legend(loc='best') ax3.set_xlabel(r"$\Delta x$") ax3.set_ylabel(r"$\xi$") ax4 = fig.add_subplot(224) ax4.plot(out_array, noise_img.array[args.out_Nx / 2, :], label="prediction", color='red') ax4.plot(out_array, xi_obs_img.array[args.out_Nx / 2, :], label="observation", color='blue') ax4.plot(out_array, -noise_img.array[args.out_Nx / 2, :], ls=':', color='red') ax4.plot(out_array, -xi_obs_img.array[args.out_Nx / 2, :], ls=':', color='blue') ax4.legend(loc='best') ax4.set_yscale('log') ax4.set_xlabel(r"$\Delta x$") ax4.set_ylabel(r"$\xi$") plt.tight_layout() plt.show()
def test_convolve_cosmos(): """Test that a COSMOS noise field convolved with a ground based PSF-style kernel matches the output of the correlated noise model modified with the convolveWith method. """ t1 = time.time() gd = galsim.GaussianDeviate(rseed) dx_cosmos=0.03 # Non-unity, non-default value to be used below cn = galsim.getCOSMOSNoise( gd, '../examples/data/acs_I_unrot_sci_20_cf.fits', dx_cosmos=dx_cosmos) cn.setVariance(300.) # Again chosen to be non-unity and so as to produce ~unity output variance # Define a PSF with which to convolve the noise field, one WITHOUT 2-fold rotational symmetry # (see test_autocorrelate in test_SBProfile.py for more info as to why this is relevant) # Make a relatively realistic mockup of a GREAT3 target image lam_over_diam_cosmos = (814.e-9 / 2.4) * (180. / np.pi) * 3600. # ~lamda/D in arcsec lam_over_diam_ground = lam_over_diam_cosmos * 2.4 / 4. # Generic 4m at same lambda psf_cosmos = galsim.Convolve([ galsim.Airy(lam_over_diam=lam_over_diam_cosmos, obscuration=0.4), galsim.Pixel(0.05)]) psf_ground = galsim.Convolve([ galsim.Kolmogorov(fwhm=0.8), galsim.Pixel(0.18), galsim.OpticalPSF(lam_over_diam=lam_over_diam_ground, coma2=0.4, defocus=-0.6)]) psf_shera = galsim.Convolve([ psf_ground, (galsim.Deconvolve(psf_cosmos)).createSheared(g1=0.03, g2=-0.01)]) # Then define the convolved cosmos correlated noise model conv_cn = cn.copy() conv_cn.convolveWith(psf_shera) # Then draw the correlation function for this correlated noise as the reference refim = galsim.ImageD(smallim_size, smallim_size) conv_cn.draw(refim, dx=0.18) # Now start the test... # First we generate a COSMOS noise field (cosimage), read it into an InterpolatedImage and # then convolve it with psf, making sure we pad the edges interp=galsim.Linear(tol=1.e-4) # interpolation kernel to use in making convimages # Number of tests needs to be a little larger to beat down noise here, but see the script # in devel/external/test_cf/test_cf_convolution_detailed.py cosimage_padded = galsim.ImageD( (2 * smallim_size) * 6 + 256, # Note 6 here since 0.18 = 6 * 0.03 (2 * smallim_size) * 6 + 256, # large image to beat down noise + padding scale = dx_cosmos) # Use COSMOS pixel scale cosimage_padded.addNoise(cn) # Add cosmos noise # Put this noise into a GSObject and then convolve imobj_padded = galsim.InterpolatedImage( cosimage_padded, calculate_stepk=False, calculate_maxk=False, normalization='sb', dx=dx_cosmos, x_interpolant=interp) cimobj_padded = galsim.Convolve(imobj_padded, psf_shera) # We draw, calculate a correlation function for the resulting field, and repeat to get an # average over nsum_test trials convimage = galsim.ImageD(2 * smallim_size, 2 * smallim_size) cimobj_padded.draw(convimage, dx=0.18, normalization='sb') cn_test = galsim.CorrelatedNoise( gd, convimage, dx=0.18, correct_periodicity=True, subtract_mean=False) testim = galsim.ImageD(smallim_size, smallim_size) cn_test.draw(testim, dx=0.18) # Start some lists to store image info conv_list = [convimage.array.copy()] # Don't forget Python reference/assignment semantics, we # zero convimage and write over it later! mnsq_list = [np.mean(convimage.array**2)] var_list = [convimage.array.var()] #nsum_test = 500 - uncomment this line to pass test below at 2dp for i in range(nsum_test - 1): cosimage_padded.setZero() cosimage_padded.addNoise(cn) imobj_padded = galsim.InterpolatedImage( cosimage_padded, calculate_stepk=False, calculate_maxk=False, normalization='sb', dx=dx_cosmos, x_interpolant=interp) cimobj_padded = galsim.Convolve(imobj_padded, psf_shera) convimage.setZero() # See above # Draw convolved image into convimage cimobj_padded.draw(convimage, dx=0.18, normalization='sb') conv_list.append(convimage.array.copy()) # See above mnsq_list.append(np.mean(convimage.array**2)) var_list.append(convimage.array.var()) cn_test = galsim.CorrelatedNoise( gd, convimage, dx=0.18, correct_periodicity=True, subtract_mean=False) cn_test.draw(testim, dx=0.18, add_to_image=True) del imobj_padded del cimobj_padded del cn_test mnsq_individual = sum(mnsq_list) / float(nsum_test) var_individual = sum(var_list) / float(nsum_test) mnsq_individual = sum(mnsq_list) / float(nsum_test) testim /= float(nsum_test) # Take average CF of trials conv_array = np.asarray(conv_list) mnsq_all = np.mean(conv_array**2) var_all = conv_array.var() print "Mean square estimate from avg. of individual field mean squares = "+str(mnsq_individual) print "Mean square estimate from all fields = "+str(mnsq_all) print "Ratio of mean squares = %e" % (mnsq_individual / mnsq_all) print "Variance estimate from avg. of individual field variances = "+str(var_individual) print "Variance estimate from all fields = "+str(var_all) print "Ratio of variances = %e" % (var_individual / var_all) print "Zero lag CF from avg. of individual field CFs = "+str(testim.array[8, 8]) print "Zero lag CF in reference case = "+str(refim.array[8, 8]) print "Ratio of zero lag CFs = %e" % (testim.array[8, 8] / refim.array[8, 8]) print "Printing analysis of central 4x4 of CF:" # Show ratios etc in central 4x4 where CF is definitely non-zero print 'mean diff = ',np.mean(testim.array[4:12, 4:12] - refim.array[4:12, 4:12]) print 'var diff = ',np.var(testim.array[4:12, 4:12] - refim.array[4:12, 4:12]) print 'min diff = ',np.min(testim.array[4:12, 4:12] - refim.array[4:12, 4:12]) print 'max diff = ',np.max(testim.array[4:12, 4:12] - refim.array[4:12, 4:12]) print 'mean ratio = %e' % np.mean(testim.array[4:12, 4:12] / refim.array[4:12, 4:12]) print 'var ratio = ',np.var(testim.array[4:12, 4:12] / refim.array[4:12, 4:12]) print 'min ratio = %e' % np.min(testim.array[4:12, 4:12] / refim.array[4:12, 4:12]) print 'max ratio = %e' % np.max(testim.array[4:12, 4:12] / refim.array[4:12, 4:12]) # Test (this is a crude regression test at best, for a much more precise test of this behaviour # see devel/external/test_cf/test_cf_convolution_detailed.py) np.testing.assert_array_almost_equal( testim.array, refim.array, decimal=1,#decimal_approx, - if you want to pass at 2dp, make # nsum_test=500 above, takes ~100s on a fast laptop err_msg="Convolved COSMOS noise fields do not match the convolved correlated noise model.") t2 = time.time() print 'time for %s = %.2f'%(funcname(), t2 - t1)
import numpy as np import galsim # Use a deterministic random number generator so we don't fail tests because of rare flukes # in the random numbers. rseed=12345 smallim_size = 16 # size of image when we test correlated noise properties using small inputs largeim_size = 12 * smallim_size # ditto, but when we need a larger image if __name__ == "__main__": t1 = time.time() gd = galsim.GaussianDeviate(rseed) dx_cosmos=0.03 # Non-unity, non-default value to be used below cn = galsim.getCOSMOSNoise( gd, '../../../examples/data/acs_I_unrot_sci_20_cf.fits', dx_cosmos=dx_cosmos) cn.setVariance(1000.) # Again chosen to be non-unity # Define a PSF with which to convolve the noise field, one WITHOUT 2-fold rotational symmetry # (see test_autocorrelate in test_SBProfile.py for more info as to why this is relevant) # Make a relatively realistic mockup of a GREAT3 target image lam_over_diam_cosmos = (814.e-9 / 2.4) * (180. / np.pi) * 3600. # ~lamda/D in arcsec lam_over_diam_ground = lam_over_diam_cosmos * 2.4 / 4. # Generic 4m at same lambda psf_cosmos = galsim.Convolve([ galsim.Airy(lam_over_diam=lam_over_diam_cosmos, obscuration=0.4), galsim.Pixel(0.05)]) psf_ground = galsim.Convolve([ galsim.Kolmogorov(fwhm=0.8), galsim.Pixel(0.18), galsim.OpticalPSF(lam_over_diam=lam_over_diam_ground, coma2=0.4, defocus=-0.6)]) psf_shera = galsim.Convolve([ psf_ground, (galsim.Deconvolve(psf_cosmos)).createSheared(g1=0.03, g2=-0.01)]) # Then define the convolved cosmos correlated noise model conv_cn = cn.copy()
def draw_galaxies( data_dir=None, generative_model='https://raw.githubusercontent.com/EiffL/GalSim-Hub/master/modules/generative_model.tar.gz', batch_size=1024, n_batches=None, pool_size=12): """ This function will draw in postage stamps a sample of galaxies using both the real COSMOS galaxy catalog and a given generative model, it outputs """ cosmos_cat = galsim.COSMOSCatalog(dir=data_dir) cosmos_noise = galsim.getCOSMOSNoise() # Generating galaxies from the model by batch gal_model = GenerativeGalaxyModel(generative_model) sims_stamps = [] cosmos_stamps = [] param_stamps = [] idents = [] if n_batches is None: n_batches = len(cosmos_cat.orig_index) // batch_size # Process galaxies by batches for i in range(n_batches): inds = np.arange(i * batch_size, (i + 1) * batch_size) print("Batch %d" % i) # Generate uncovolved light profiles sim_galaxies = gal_model.sample( cat=cosmos_cat.param_cat[cosmos_cat.orig_index[inds]]) indices = [(j, k) for j, k in enumerate(inds)] # Draw galaxies on postage stamps engine = partial(_draw_galaxies, cosmos_cat=cosmos_cat, sim_galaxies=sim_galaxies, cosmos_noise=cosmos_noise) if pool_size is None: res = [] for ind in indices: res.append(engine(ind)) else: with Pool(pool_size) as p: res = p.map(engine, indices) # Extract the postage stamps into separate lists, discarding the ones # that failed for k, im_sims, im_cosmos, im_param, flag in res: if flag: sims_stamps.append(im_sims) cosmos_stamps.append(im_cosmos) param_stamps.append(im_param) idents.append( cosmos_cat.param_cat[cosmos_cat.orig_index[k]]['IDENT']) # Puts all images into one big table table = Table([ np.array(idents), np.stack(cosmos_stamps), np.stack(sims_stamps), np.stack(param_stamps) ], names=['IDENT', 'real', 'mock', 'param']) # Merge with the cosmos catalog data for convenience table = join(cosmos_cat.param_cat, table, keys=['IDENT']) return table
def test_CRG(args): """Predict an LSST or Euclid image given HST images of a galaxy with color gradients.""" t0 = time.time() print("Constructing chromatic PSFs") in_PSF = galsim.ChromaticAiry(lam=700, diam=2.4) if args.lsst_psf: out_PSF = galsim.ChromaticAtmosphere(galsim.Kolmogorov(fwhm=0.6), 500.0, zenith_angle=0*galsim.degrees, parallactic_angle=0.0*galsim.degrees) else: out_PSF = galsim.ChromaticAiry(lam=700, diam=1.2) # Euclid-like print("Constructing filters and SEDs") waves = np.arange(550.0, 900.1, 10.0) visband = galsim.Bandpass(galsim.LookupTable(waves, np.ones_like(waves), interpolant='linear'), wave_type='nm') split_points = np.linspace(550.0, 900.0, args.Nim+1, endpoint=True) bands = [visband.truncate(blue_limit=blim, red_limit=rlim) for blim, rlim in zip(split_points[:-1], split_points[1:])] outband = visband.truncate(blue_limit=args.out_blim, red_limit=args.out_rlim) maxk = max([out_PSF.evaluateAtWavelength(waves[0]).maxK(), out_PSF.evaluateAtWavelength(waves[-1]).maxK()]) SEDs = [galsim.SED(galsim.LookupTable(waves, waves**i, interpolant='linear'), wave_type='nm', flux_type='fphotons').withFlux(1.0, visband) for i in range(args.NSED)] print("Construction input noise correlation functions") rng = galsim.BaseDeviate(args.seed) in_xis = [galsim.getCOSMOSNoise(cosmos_scale=args.in_scale, rng=rng) .dilate(1 + i * 0.05) .rotate(30 * i * galsim.degrees) for i in range(args.Nim)] print("Constructing galaxy") components = [galsim.Gaussian(half_light_radius=0.3).shear(e1=0.1)] for i in range(1, args.Nim): components.append( galsim.Gaussian(half_light_radius=0.3+0.1*np.cos(i)) .shear(e=0.4+np.cos(i)*0.4, beta=i*galsim.radians) .shift(0.4*i, -0.4*i) ) gal = galsim.Add([c*s for c, s in zip(components, SEDs)]) gal = gal.shift(-gal.centroid(visband)) in_prof = galsim.Convolve(gal, in_PSF) out_prof = galsim.Convolve(gal, out_PSF) print("Drawing input images") in_Nx = args.in_Nx in_Ny = args.in_Ny if args.in_Ny is not None else in_Nx in_imgs = [in_prof.drawImage(band, nx=in_Nx, ny=in_Ny, scale=args.in_scale) for band in bands] [img.addNoiseSNR(xi, args.SNR, preserve_flux=True) for xi, img in zip(in_xis, in_imgs)] print("Drawing true output image") out_img = out_prof.drawImage(outband, nx=args.out_Nx, ny=args.out_Nx, scale=args.out_scale) # Now "deconvolve" the chromatic HST PSF while asserting the correct SEDs. print("Constructing ChromaticRealGalaxy") crg = galsim.ChromaticRealGalaxy.makeFromImages( in_imgs, bands, in_PSF, in_xis, SEDs=SEDs, maxk=maxk) # crg should be effectively the same thing as gal now. Let's test. crg_prof = galsim.Convolve(crg, out_PSF) crg_img = crg_prof.drawImage(outband, nx=args.out_Nx, ny=args.out_Nx, scale=args.out_scale) print("Max comparison:", out_img.array.max(), crg_img.array.max()) print("Sum comparison:", out_img.array.sum(), crg_img.array.sum()) print("Took {} seconds".format(time.time()-t0)) if args.plot: import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec in_extent = [-in_Nx*args.in_scale/2, in_Nx*args.in_scale/2, -in_Ny*args.in_scale/2, in_Ny*args.in_scale/2] out_extent = [-args.out_Nx*args.out_scale/2, args.out_Nx*args.out_scale/2, -args.out_Nx*args.out_scale/2, args.out_Nx*args.out_scale/2] fig = plt.figure(figsize=(10, 5)) outer_grid = gridspec.GridSpec(2, 1) # Input images inner_grid = gridspec.GridSpecFromSubplotSpec(1, args.Nim, outer_grid[0]) for i, img in enumerate(in_imgs): ax = plt.Subplot(fig, inner_grid[i]) im = ax.imshow(img.array, extent=in_extent, cmap='viridis') ax.set_title("band[{}] input".format(i)) # ax.set_xticks([]) # ax.set_yticks([]) fig.add_subplot(ax) plt.colorbar(im) inner_grid = gridspec.GridSpecFromSubplotSpec(1, 3, outer_grid[1]) # Output image, truth, and residual ax = plt.Subplot(fig, inner_grid[0]) ax.set_title("True output") im = ax.imshow(out_img.array, extent=out_extent, cmap='viridis') # ax.set_xticks([]) # ax.set_yticks([]) fig.add_subplot(ax) plt.colorbar(im) ax = plt.Subplot(fig, inner_grid[1]) ax.set_title("Reconstructed output") # ax.set_xticks([]) # ax.set_yticks([]) im = ax.imshow(crg_img.array, extent=out_extent, cmap='viridis') fig.add_subplot(ax) plt.colorbar(im) ax = plt.Subplot(fig, inner_grid[2]) ax.set_title("Residual") ax.set_xticks([]) ax.set_yticks([]) resid = crg_img.array - out_img.array vmin, vmax = np.percentile(resid, [5.0, 95.0]) v = np.max([np.abs(vmin), np.abs(vmax)]) im = ax.imshow(resid, extent=out_extent, cmap='seismic', vmin=-v, vmax=v) fig.add_subplot(ax) plt.colorbar(im) plt.tight_layout() plt.show()
def test_CRG_noise(args): """Test noise propagation in ChromaticRealGalaxy """ t0 = time.time() print("Constructing chromatic PSFs") in_PSF = galsim.ChromaticAiry(lam=700., diam=2.4) out_PSF = galsim.ChromaticAiry(lam=700., diam=1.2) print("Constructing filters and SEDs") waves = np.arange(550.0, 900.1, 10.0) visband = galsim.Bandpass(galsim.LookupTable(waves, np.ones_like(waves), interpolant='linear'), wave_type='nm') split_points = np.linspace(550.0, 900.0, args.Nim+1, endpoint=True) bands = [visband.truncate(blue_limit=blim, red_limit=rlim) for blim, rlim in zip(split_points[:-1], split_points[1:])] maxk = max([out_PSF.evaluateAtWavelength(waves[0]).maxK(), out_PSF.evaluateAtWavelength(waves[-1]).maxK()]) SEDs = [galsim.SED(galsim.LookupTable(waves, waves**i, interpolant='linear'), flux_type='fphotons', wave_type='nm').withFlux(1.0, visband) for i in range(args.NSED)] print("Constructing input noise correlation functions") rng = galsim.BaseDeviate(args.seed) in_xis = [galsim.getCOSMOSNoise(cosmos_scale=args.in_scale, rng=rng) .dilate(1 + i * 0.05) .rotate(5 * i * galsim.degrees) for i in range(args.Nim)] print("Creating noise images") img_sets = [] for i in range(args.Ntrial): imgs = [] for j, xi in enumerate(in_xis): img = galsim.Image(args.in_Nx, args.in_Nx, scale=args.in_scale) img.addNoise(xi) imgs.append(img) img_sets.append(imgs) print("Constructing `ChromaticRealGalaxy`s") crgs = [] with ProgressBar(len(img_sets)) as bar: for imgs in img_sets: crgs.append(galsim.ChromaticRealGalaxy.makeFromImages( imgs, bands, in_PSF, in_xis, SEDs=SEDs, maxk=maxk)) bar.update() print("Convolving by output PSF") objs = [galsim.Convolve(crg, out_PSF) for crg in crgs] print("Drawing through output filter") out_imgs = [obj.drawImage(visband, nx=args.out_Nx, ny=args.out_Nx, scale=args.out_scale, iimult=args.iimult) for obj in objs] noise = objs[0].noise print("Measuring images' correlation functions") xi_obs = galsim.correlatednoise.CorrelatedNoise(out_imgs[0]) for img in out_imgs[1:]: xi_obs += galsim.correlatednoise.CorrelatedNoise(img) xi_obs /= args.Ntrial xi_obs_img = galsim.Image(args.out_Nx, args.out_Nx, scale=args.out_scale) xi_obs.drawImage(xi_obs_img) print("Observed image variance: ", xi_obs.getVariance()) print("Predicted image variance: ", noise.getVariance()) print("Predicted/Observed variance:", noise.getVariance()/xi_obs.getVariance()) print("Took {} seconds".format(time.time()-t0)) if args.plot: import matplotlib.pyplot as plt out_array = (np.arange(args.out_Nx) - args.out_Nx/2) * args.out_scale out_extent = [-args.out_Nx*args.out_scale/2, args.out_Nx*args.out_scale/2, -args.out_Nx*args.out_scale/2, args.out_Nx*args.out_scale/2] fig = plt.figure(figsize=(5, 5)) # Sample image ax = fig.add_subplot(111) ax.imshow(out_imgs[0].array, extent=out_extent) ax.set_title("sample output image") ax.set_xlabel("x") ax.set_ylabel("y") # ax.colorbar() fig.show() # 2D correlation functions fig = plt.figure(figsize=(10, 10)) ax1 = fig.add_subplot(221) noise_img = galsim.Image(args.out_Nx, args.out_Nx, scale=args.out_scale) noise.drawImage(noise_img) ax1.imshow(np.log10(np.abs(noise_img.array)), extent=out_extent) ax1.set_title("predicted covariance function") ax1.set_xlabel(r"$\Delta x$") ax1.set_ylabel(r"$\Delta y$") ax2 = fig.add_subplot(222) ax2.imshow(np.log10(np.abs(xi_obs_img.array)), extent=out_extent) ax2.set_title("observed covariance function") ax2.set_xlabel(r"$\Delta x$") ax2.set_ylabel(r"$\Delta y$") # 1D slide through correlation functions ax3 = fig.add_subplot(223) ax3.plot(out_array, noise_img.array[args.out_Nx/2, :], label="prediction", color='red') ax3.plot(out_array, xi_obs_img.array[args.out_Nx/2, :], label="observation", color='blue') ax3.legend(loc='best') ax3.set_xlabel(r"$\Delta x$") ax3.set_ylabel(r"$\xi$") ax4 = fig.add_subplot(224) ax4.plot(out_array, noise_img.array[args.out_Nx/2, :], label="prediction", color='red') ax4.plot(out_array, xi_obs_img.array[args.out_Nx/2, :], label="observation", color='blue') ax4.plot(out_array, -noise_img.array[args.out_Nx/2, :], ls=':', color='red') ax4.plot(out_array, -xi_obs_img.array[args.out_Nx/2, :], ls=':', color='blue') ax4.legend(loc='best') ax4.set_yscale('log') ax4.set_xlabel(r"$\Delta x$") ax4.set_ylabel(r"$\xi$") plt.tight_layout() plt.show()
def check_crg_noise(n_sed, n_im, n_trial, tol): print("Checking CRG noise for") print("n_sed = {}".format(n_sed)) print("n_im = {}".format(n_im)) print("n_trial = {}".format(n_trial)) print("Constructing chromatic PSFs") in_PSF = galsim.ChromaticAiry(lam=700., diam=2.4) out_PSF = galsim.ChromaticAiry(lam=700., diam=0.6) print("Constructing filters and SEDs") waves = np.arange(550.0, 900.1, 10.0) visband = galsim.Bandpass(galsim.LookupTable(waves, np.ones_like(waves), interpolant='linear'), wave_type='nm') split_points = np.linspace(550.0, 900.0, n_im+1, endpoint=True) bands = [visband.truncate(blue_limit=blim, red_limit=rlim) for blim, rlim in zip(split_points[:-1], split_points[1:])] maxk = max([out_PSF.evaluateAtWavelength(waves[0]).maxk, out_PSF.evaluateAtWavelength(waves[-1]).maxk]) SEDs = [galsim.SED(galsim.LookupTable(waves, waves**i, interpolant='linear'), flux_type='fphotons', wave_type='nm').withFlux(1.0, visband) for i in range(n_sed)] print("Constructing input noise correlation functions") rng = galsim.BaseDeviate(57721) in_xis = [galsim.getCOSMOSNoise(cosmos_scale=0.03, rng=rng) .dilate(1 + i * 0.05) .rotate(5 * i * galsim.degrees) for i in range(n_im)] print("Creating noise images") img_sets = [] for i in range(n_trial): imgs = [] for xi in in_xis: img = galsim.Image(128, 128, scale=0.03) img.addNoise(xi) imgs.append(img) img_sets.append(imgs) print("Constructing `ChromaticRealGalaxy`s") crgs = [] for imgs in img_sets: crgs.append(galsim.ChromaticRealGalaxy.makeFromImages( imgs, bands, in_PSF, in_xis, SEDs=SEDs, maxk=maxk)) print("Convolving by output PSF") objs = [galsim.Convolve(crg, out_PSF) for crg in crgs] with assert_raises(galsim.GalSimError): noise = objs[0].noise # Invalid before drawImage is called print("Drawing through output filter") out_imgs = [obj.drawImage(visband, nx=30, ny=30, scale=0.1) for obj in objs] noise = objs[0].noise print("Measuring images' correlation functions") xi_obs = galsim.correlatednoise.CorrelatedNoise(out_imgs[0]) for img in out_imgs[1:]: xi_obs += galsim.correlatednoise.CorrelatedNoise(img) xi_obs /= n_trial xi_obs_img = galsim.Image(30, 30, scale=0.1) xi_obs.drawImage(xi_obs_img) noise_img = galsim.Image(30, 30, scale=0.1) noise.drawImage(noise_img) print("Predicted/Observed variance:", noise.getVariance()/xi_obs.getVariance()) print("Predicted/Observed xlag-1 covariance:", noise_img.array[14, 15]/xi_obs_img.array[14, 15]) print("Predicted/Observed ylag-1 covariance:", noise_img.array[15, 14]/xi_obs_img.array[15, 14]) # Just test that the covariances for nearest neighbor pixels are accurate. np.testing.assert_allclose( noise_img.array[14:17, 14:17], xi_obs_img.array[14:17, 14:17], rtol=0, atol=noise.getVariance()*tol)
import galsim # Use a deterministic random number generator so we don't fail tests because of rare flukes # in the random numbers. rseed = 12345 smallim_size = 16 # size of image when we test correlated noise properties using small inputs largeim_size = 12 * smallim_size # ditto, but when we need a larger image if __name__ == "__main__": t1 = time.time() gd = galsim.GaussianDeviate(rseed) dx_cosmos = 0.03 # Non-unity, non-default value to be used below cn = galsim.getCOSMOSNoise( gd, '../../../examples/data/acs_I_unrot_sci_20_cf.fits', dx_cosmos=dx_cosmos) cn.setVariance(1000.) # Again chosen to be non-unity # Define a PSF with which to convolve the noise field, one WITHOUT 2-fold rotational symmetry # (see test_autocorrelate in test_SBProfile.py for more info as to why this is relevant) # Make a relatively realistic mockup of a GREAT3 target image lam_over_diam_cosmos = (814.e-9 / 2.4) * (180. / np.pi) * 3600. # ~lamda/D in arcsec lam_over_diam_ground = lam_over_diam_cosmos * 2.4 / 4. # Generic 4m at same lambda psf_cosmos = galsim.Convolve([ galsim.Airy(lam_over_diam=lam_over_diam_cosmos, obscuration=0.4), galsim.Pixel(0.05) ]) psf_ground = galsim.Convolve([ galsim.Kolmogorov(fwhm=0.8), galsim.Pixel(0.18),
import numpy as np import galsim # Use a deterministic random number generator so we don't fail tests because of rare flukes # in the random numbers. rseed = 12345 smallim_size = 16 # size of image when we test correlated noise properties using small inputs largeim_size = 12 * smallim_size # ditto, but when we need a larger image if __name__ == "__main__": t1 = time.time() gd = galsim.GaussianDeviate(rseed) dx_cosmos = 0.03 # Non-unity, non-default value to be used below cn = galsim.getCOSMOSNoise(rng=gd, dx_cosmos=dx_cosmos) cn.setVariance(1000.) # Again chosen to be non-unity # Define a PSF with which to convolve the noise field, one WITHOUT 2-fold rotational symmetry # (see test_autocorrelate in test_SBProfile.py for more info as to why this is relevant) # Make a relatively realistic mockup of a GREAT3 target image lam_over_diam_cosmos = (814.e-9 / 2.4) * (180. / np.pi) * 3600. # ~lamda/D in arcsec lam_over_diam_ground = lam_over_diam_cosmos * 2.4 / 4. # Generic 4m at same lambda psf_cosmos = galsim.Convolve([ galsim.Airy(lam_over_diam=lam_over_diam_cosmos, obscuration=0.4), galsim.Pixel(0.05) ]) psf_ground = galsim.Convolve([ galsim.Kolmogorov(fwhm=0.8), galsim.Pixel(0.18), galsim.OpticalPSF(lam_over_diam=lam_over_diam_ground,
def test_cosmos_and_whitening(): """Test that noise generated by an HST COSMOS correlated noise is correct and correctly whitened. Includes test for a magnified, sheared, and rotated version of the COSMOS noise, and tests convolution with a ground-based PSF. """ t1 = time.time() gd = galsim.GaussianDeviate(rseed) dx_cosmos = 7.5 # Use some non-default, non-unity value of COSMOS pixel spacing ccn = galsim.getCOSMOSNoise( gd, '../examples/data/acs_I_unrot_sci_20_cf.fits', dx_cosmos=dx_cosmos) # large image to beat down noise outimage = galsim.ImageD(3 * largeim_size, 3 * largeim_size, scale=dx_cosmos) outimage.addNoise(ccn) # Add the COSMOS noise # Then estimate correlation function from generated noise cntest_correlated = galsim.CorrelatedNoise(ccn.getRNG(), outimage) # Check basic correlation function values of the 3x3 pixel region around (0,0) pos = galsim.PositionD(0., 0.) cf00 = ccn._profile.xValue(pos) cftest00 = cntest_correlated._profile.xValue(pos) # Test variances first np.testing.assert_almost_equal( cftest00 / cf00, 1., decimal=decimal_approx, err_msg="Noise field generated with COSMOS CorrelatedNoise does not approximately match "+ "input variance") # Then test (1, 0), (0, 1), (1,-1) and (1,1) values for xpos, ypos in zip((dx_cosmos, 0., dx_cosmos, dx_cosmos), (0., dx_cosmos, -dx_cosmos, dx_cosmos)): pos = galsim.PositionD(xpos, ypos) cf = ccn._profile.xValue(pos) cftest = cntest_correlated._profile.xValue(pos) np.testing.assert_almost_equal( cftest / cftest00, cf / cf00, decimal=decimal_approx, err_msg="Noise field generated with COSMOS CorrelatedNoise does not have "+ "approximately matching interpixel covariances") # Now whiten the noise field, and check that its variance and covariances are as expected # (non-zero distance correlations ~ 0!) whitened_variance = ccn.applyWhiteningTo(outimage) cntest_whitened = galsim.CorrelatedNoise(ccn.getRNG(), outimage) # Get the correlation function cftest00 = cntest_whitened._profile.xValue(galsim.PositionD(0., 0.)) # Test variances first np.testing.assert_almost_equal( cftest00 / whitened_variance, 1., decimal=decimal_approx, err_msg="Noise field generated by whitening COSMOS CorrelatedNoise does not approximately "+ "match theoretical variance") # Then test (1, 0), (0, 1), (1,-1) and (1,1) values for xpos, ypos in zip((dx_cosmos, 0., dx_cosmos, dx_cosmos), (0., dx_cosmos, -dx_cosmos, dx_cosmos)): pos = galsim.PositionD(xpos, ypos) cftest = cntest_whitened._profile.xValue(pos) np.testing.assert_almost_equal( cftest / cftest00, 0., decimal=decimal_approx, err_msg="Noise field generated by whitening COSMOS CorrelatedNoise does not have "+ "approximately zero interpixel covariances") # Now test whitening but having first expanded and sheared the COSMOS noise correlation ccn_transformed = ccn.createSheared(g1=-0.03, g2=0.07) ccn_transformed.applyRotation(313. * galsim.degrees) ccn_transformed.applyExpansion(3.9) outimage.setZero() outimage.addNoise(ccn_transformed) wht_variance = ccn_transformed.applyWhiteningTo(outimage) # Whiten noise correlation cntest_whitened = galsim.CorrelatedNoise(ccn.getRNG(), outimage) # Get the correlation function cftest00 = cntest_whitened._profile.xValue(galsim.PositionD(0., 0.)) # Test variances first np.testing.assert_almost_equal( cftest00 / wht_variance, 1., decimal=decimal_approx, err_msg="Noise field generated by whitening rotated, sheared, magnified COSMOS "+ "CorrelatedNoise does not approximately match theoretical variance") # Then test (1, 0), (0, 1), (1,-1) and (1,1) values for xpos, ypos in zip((dx_cosmos, 0., dx_cosmos, dx_cosmos), (0., dx_cosmos, -dx_cosmos, dx_cosmos)): pos = galsim.PositionD(xpos, ypos) cftest = cntest_whitened._profile.xValue(pos) np.testing.assert_almost_equal( cftest / cftest00, 0., decimal=decimal_approx, err_msg="Noise field generated by whitening rotated, sheared, magnified COSMOS "+ "CorrelatedNoise does not have approximately zero interpixel covariances") # Then convolve with a ground-based PSF and pixel, generate some more correlated noise # and whiten it dx_ground = dx_cosmos * 9. # simulates a 0.03 arcsec * 9 = 0.27 arcsec pitch ground image psf_ground = galsim.Moffat(beta=3., fwhm=2.5*dx_ground) # FWHM=0.675 arcsec seeing pix_ground = galsim.Pixel(dx_ground) ccn_convolved = ccn_transformed.copy() # Convolve the correlated noise field with each of the psf, pix ccn_convolved.convolveWith(galsim.Convolve([psf_ground, pix_ground])) # Reset the outimage, and set its pixel scale to now be the ground-based resolution outimage.setZero() outimage.scale = dx_ground # Add correlated noise outimage.addNoise(ccn_convolved) # Then whiten wht_variance = ccn_convolved.applyWhiteningTo(outimage) # Then test cntest_whitened = galsim.CorrelatedNoise(ccn.getRNG(), outimage) # Get the correlation function cftest00 = cntest_whitened._profile.xValue(galsim.PositionD(0., 0.)) # Test variances first np.testing.assert_almost_equal( cftest00 / wht_variance, 1., decimal=decimal_approx, err_msg="Noise field generated by whitening rotated, sheared, magnified, convolved COSMOS "+ "CorrelatedNoise does not approximately match theoretical variance") # Then test (1, 0), (0, 1), (1,-1) and (1,1) values for xpos, ypos in zip((dx_ground, 0., dx_ground, dx_ground), (0., dx_ground, -dx_ground, dx_ground)): pos = galsim.PositionD(xpos, ypos) cftest = cntest_whitened._profile.xValue(pos) np.testing.assert_almost_equal( cftest / cftest00, 0., decimal=decimal_approx, err_msg="Noise field generated by whitening rotated, sheared, magnified, convolved "+ "COSMOS CorrelatedNoise does not have approximately zero interpixel covariances") t2 = time.time() print 'time for %s = %.2f'%(funcname(), t2 - t1)
def test_CRG(args): """Predict an LSST or Euclid image given HST images of a galaxy with color gradients.""" t0 = time.time() print("Constructing chromatic PSFs") in_PSF = galsim.ChromaticAiry(lam=700, diam=2.4) if args.lsst_psf: out_PSF = galsim.ChromaticAtmosphere(galsim.Kolmogorov(fwhm=0.6), 500.0, zenith_angle=0 * galsim.degrees, parallactic_angle=0.0 * galsim.degrees) else: out_PSF = galsim.ChromaticAiry(lam=700, diam=1.2) # Euclid-like print("Constructing filters and SEDs") waves = np.arange(550.0, 900.1, 10.0) visband = galsim.Bandpass(galsim.LookupTable(waves, np.ones_like(waves), interpolant='linear'), wave_type='nm') split_points = np.linspace(550.0, 900.0, args.Nim + 1, endpoint=True) bands = [ visband.truncate(blue_limit=blim, red_limit=rlim) for blim, rlim in zip(split_points[:-1], split_points[1:]) ] outband = visband.truncate(blue_limit=args.out_blim, red_limit=args.out_rlim) maxk = max([ out_PSF.evaluateAtWavelength(waves[0]).maxK(), out_PSF.evaluateAtWavelength(waves[-1]).maxK() ]) SEDs = [ galsim.SED(galsim.LookupTable(waves, waves**i, interpolant='linear'), wave_type='nm', flux_type='fphotons').withFlux(1.0, visband) for i in range(args.NSED) ] print("Construction input noise correlation functions") rng = galsim.BaseDeviate(args.seed) in_xis = [ galsim.getCOSMOSNoise(cosmos_scale=args.in_scale, rng=rng).dilate(1 + i * 0.05).rotate( 30 * i * galsim.degrees) for i in range(args.Nim) ] print("Constructing galaxy") components = [galsim.Gaussian(half_light_radius=0.3).shear(e1=0.1)] for i in range(1, args.Nim): components.append( galsim.Gaussian(half_light_radius=0.3 + 0.1 * np.cos(i)).shear( e=0.4 + np.cos(i) * 0.4, beta=i * galsim.radians).shift(0.4 * i, -0.4 * i)) gal = galsim.Add([c * s for c, s in zip(components, SEDs)]) gal = gal.shift(-gal.centroid(visband)) in_prof = galsim.Convolve(gal, in_PSF) out_prof = galsim.Convolve(gal, out_PSF) print("Drawing input images") in_Nx = args.in_Nx in_Ny = args.in_Ny if args.in_Ny is not None else in_Nx in_imgs = [ in_prof.drawImage(band, nx=in_Nx, ny=in_Ny, scale=args.in_scale) for band in bands ] [ img.addNoiseSNR(xi, args.SNR, preserve_flux=True) for xi, img in zip(in_xis, in_imgs) ] print("Drawing true output image") out_img = out_prof.drawImage(outband, nx=args.out_Nx, ny=args.out_Nx, scale=args.out_scale) # Now "deconvolve" the chromatic HST PSF while asserting the correct SEDs. print("Constructing ChromaticRealGalaxy") crg = galsim.ChromaticRealGalaxy.makeFromImages(in_imgs, bands, in_PSF, in_xis, SEDs=SEDs, maxk=maxk) # crg should be effectively the same thing as gal now. Let's test. crg_prof = galsim.Convolve(crg, out_PSF) crg_img = crg_prof.drawImage(outband, nx=args.out_Nx, ny=args.out_Nx, scale=args.out_scale) print("Max comparison:", out_img.array.max(), crg_img.array.max()) print("Sum comparison:", out_img.array.sum(), crg_img.array.sum()) print("Took {} seconds".format(time.time() - t0)) if args.plot: import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec in_extent = [ -in_Nx * args.in_scale / 2, in_Nx * args.in_scale / 2, -in_Ny * args.in_scale / 2, in_Ny * args.in_scale / 2 ] out_extent = [ -args.out_Nx * args.out_scale / 2, args.out_Nx * args.out_scale / 2, -args.out_Nx * args.out_scale / 2, args.out_Nx * args.out_scale / 2 ] fig = plt.figure(figsize=(10, 5)) outer_grid = gridspec.GridSpec(2, 1) # Input images inner_grid = gridspec.GridSpecFromSubplotSpec(1, args.Nim, outer_grid[0]) for i, img in enumerate(in_imgs): ax = plt.Subplot(fig, inner_grid[i]) im = ax.imshow(img.array, extent=in_extent, cmap='viridis') ax.set_title("band[{}] input".format(i)) # ax.set_xticks([]) # ax.set_yticks([]) fig.add_subplot(ax) plt.colorbar(im) inner_grid = gridspec.GridSpecFromSubplotSpec(1, 3, outer_grid[1]) # Output image, truth, and residual ax = plt.Subplot(fig, inner_grid[0]) ax.set_title("True output") im = ax.imshow(out_img.array, extent=out_extent, cmap='viridis') # ax.set_xticks([]) # ax.set_yticks([]) fig.add_subplot(ax) plt.colorbar(im) ax = plt.Subplot(fig, inner_grid[1]) ax.set_title("Reconstructed output") # ax.set_xticks([]) # ax.set_yticks([]) im = ax.imshow(crg_img.array, extent=out_extent, cmap='viridis') fig.add_subplot(ax) plt.colorbar(im) ax = plt.Subplot(fig, inner_grid[2]) ax.set_title("Residual") ax.set_xticks([]) ax.set_yticks([]) resid = crg_img.array - out_img.array vmin, vmax = np.percentile(resid, [5.0, 95.0]) v = np.max([np.abs(vmin), np.abs(vmax)]) im = ax.imshow(resid, extent=out_extent, cmap='seismic', vmin=-v, vmax=v) fig.add_subplot(ax) plt.colorbar(im) plt.tight_layout() plt.show()