def _get_one_gal(self, gal_g1=0.05, gal_g2=-0.03, psf_fwhm=0.65, psf_g1=-0.01, psf_g2=0.01, img_shape=(51,51), img_pixel_scale=0.186, sigma_noise=None, snr=None, rng=None): """Create one object """ # This allow crontrol of random over parallel processes galsim_rng = galsim.UniformDeviate(int(rng.rand()*100000)) error = 1 while error: try: gal, g = self._create_sersic(gal_g1, gal_g2) psf = self._create_psf(psf_g1, psf_g2, psf_fwhm) obj = galsim.Convolve(gal, psf) obj_galimg = obj.drawImage(nx=img_shape[0], ny=img_shape[1], scale= img_pixel_scale) psf_galimg = psf.drawImage(nx=img_shape[0], ny=img_shape[1], scale= img_pixel_scale) if sigma_noise != None: obj_galimg.addNoise(galsim.GaussianNoise(sigma=sigma_noise, rng=galsim_rng)) elif snr != None: obj_galimg.addNoiseSNR(noise=galsim.GaussianNoise(sigma=0.01, rng=galsim_rng), snr=snr) error = 0 except: print('error') error = 1 return obj_galimg.array, psf_galimg.array, g
def measurement_function(profile, true_e1=0, true_e2=0, true_s=0, e1_vec=[], e2_vec=[], size_vec=[], e1_inter_vec=[], e2_inter_vec=[], size_inter_vec=[], noise=None, string=''): true_size = true_s print " " print "n: ", n logger.info(string) im = galsim.Image(base_size, base_size) gal = profile image = gal.drawImage(image=im, scale=pixel_scale / n, method='no_pixel') logger.info("Image shape, before interleave: (%g, %g)", image.array.shape[0], image.array.shape[1]) if not noise == None: read_noise = galsim.GaussianNoise(sigma=noise / (n**2)) image.addNoise(read_noise) results = image.FindAdaptiveMom(hsmparams=new_params) e1_vec.append((results.observed_shape.e1 - true_e1)) e2_vec.append((results.observed_shape.e2 - true_e2)) size_vec.append(results.moments_sigma - true_size) ## Interleave the profiles im_list = [] offsets_list = [] #create list of images to interleave-no effect for j in xrange(n): for i in xrange(n): im = galsim.Image(base_size, base_size) offset = galsim.PositionD(-(i + 0.5) / n + 0.5, -(j + 0.5) / n + 0.5) offsets_list.append(offset) print "Offset: ", offset gal.drawImage(image=im, scale=pixel_scale, offset=offset, method='no_pixel') im_list.append(im) image = galsim.utilities.interleaveImages(im_list=im_list, N=(n, n), offsets=offsets_list) print "Image shape, after interleave: ", image.array.shape if not noise == None: read_noise = galsim.GaussianNoise(sigma=noise) image.addNoise(read_noise) results = image.FindAdaptiveMom(hsmparams=new_params) e1_inter_vec.append(np.abs(results.observed_shape.e1 - e)) e2_inter_vec.append(np.abs(results.observed_shape.e2 - e)) size_inter_vec.append(results.moments_sigma - gal_sigma)
def measurement_function(profile, e1_inter_vec=[], e2_inter_vec=[], size_inter_vec=[], noise=None, string='', type='nl'): beta0 = 3.566e-7 ### First, measure moments *without* NL applied, at given flux image = profile.drawImage(image=galsim.Image(base_size, base_size), scale=pixel_scale / n, method='no_pixel') if not noise == None: read_noise = galsim.GaussianNoise(sigma=noise / (n**2)) image.addNoise(read_noise) results = image.FindAdaptiveMom(hsmparams=new_params) ref_e1 = results.observed_shape.e1 ref_e2 = results.observed_shape.e2 ref_s = results.moments_sigma ## Interleave the profiles im_list = [] offsets_list = [] #create list of images to interleave-no effect for j in xrange(n): for i in xrange(n): im = galsim.Image(base_size, base_size) offset = galsim.PositionD(-(i + 0.5) / n + 0.5, -(j + 0.5) / n + 0.5) offsets_list.append(offset) print "Offset: ", offset profile.drawImage(image=im, scale=pixel_scale, offset=offset, method='no_pixel') if type == 'bf': #cd = PowerLawCD(5, 5.e-7, 5.e-7, 1.5e-7, 1.5e-7, 2.5e-7, 2.5e-7, 1.3) cd = BaseCDModel(aL, aR, aB, aT) im = cd.applyForward(im) elif type == 'nl': im.applyNonlinearity(f, beta0) else: print "wrong type: 'bf' or 'nl' " sys.exit(1) im_list.append(im) image = galsim.utilities.interleaveImages(im_list=im_list, N=(n, n), offsets=offsets_list) print "Image shape, after interleave: ", image.array.shape if not noise == None: read_noise = galsim.GaussianNoise(sigma=noise) image.addNoise(read_noise) results = image.FindAdaptiveMom(hsmparams=new_params) e1_inter_vec.append(results.observed_shape.e1 - ref_e1) e2_inter_vec.append(results.observed_shape.e2 - ref_e2) size_inter_vec.append((results.moments_sigma - ref_s) / ref_s)
def simulate_shear(constants, redshift, nbins, noise_sd=0.0, seed=0): """Takes cosmological parameters, generates a shear map, and adds noise. Inputs: constants: Constants, object for cosmological constants redshift: float, the redshift value for the sample nbins: int, the number of bins for the correlation function noise_sd: float, the standard deviation for IID Gaussian noise. seed: integer, seed for the RNG; if 0 it uses a randomly chosen seed. Returns: A pair of shear spectrum grids. """ grid_nx = 100 # length of grid in one dimension (degrees) theta = 10.0 # grid spacing dtheta = theta / grid_nx # wavenumbers at which to evaluate power spectra ell = np.logspace(-2.0, 4.0, num=50) nicaea_obj = constants.nicaea_object() psObs_nicaea = nicaea_obj.convergencePowerSpectrum(ell=ell, z=redshift) psObs_tabulated = galsim.LookupTable(ell, psObs_nicaea, interpolant='linear') ps_galsim = galsim.PowerSpectrum(psObs_tabulated, delta2=False, units=galsim.radians) grid_deviate = galsim.BaseDeviate(seed) g1, g2, kappa = ps_galsim.buildGrid(grid_spacing=dtheta, ngrid=grid_nx, rng=grid_deviate, units='degrees', kmin_factor=2, kmax_factor=2, get_convergence=True) g1_r, g2_r, _ = galsim.lensing_ps.theoryToObserved(g1, g2, kappa) rng = galsim.GaussianDeviate(seed=seed) g1_noise_grid = galsim.ImageD(grid_nx, grid_nx) g2_noise_grid = galsim.ImageD(grid_nx, grid_nx) g1_noise_grid.addNoise(galsim.GaussianNoise(rng=rng, sigma=noise_sd)) g2_noise_grid.addNoise(galsim.GaussianNoise(rng=rng, sigma=noise_sd)) g1_noisy = np.add(g1_r, g1_noise_grid.array) g2_noisy = np.add(g2_r, g2_noise_grid.array) min_sep = dtheta max_sep = grid_nx * np.sqrt(2) * dtheta grid_range = dtheta * np.arange(grid_nx) x, y = np.meshgrid(grid_range, grid_range) stats = run_treecorr(x, y, g1, g2, min_sep, max_sep, nbins=nbins) return g1_noisy, g2_noisy, stats
def gs_noise_generator(stamp_size=50, variance=5, pixel_scale=.2, interp_factor=2, padding_factor=1): """ Generate a noise k space image using GalSim. Args: stamp_size: in pixels variance: noise variance pixel_scale: in arcsec/pixel interp_factor: interpolation factor for k space padding_factor: padding wrap factor Returns: A complex64 numpy array. """ noise = galsim.GaussianNoise().withVariance(variance) noise_image = galsim.Image(stamp_size, stamp_size, scale=pixel_scale) noise.applyTo(noise_image) noise_image = galsim.InterpolatedImage(noise_image) Nk = stamp_size * padding_factor * interp_factor from galsim.bounds import _BoundsI bounds = _BoundsI(-Nk // 2, Nk // 2 - 1, -Nk // 2, Nk // 2 - 1) imnos = noise_image.drawKImage(bounds=bounds, scale=2. * np.pi / (stamp_size * padding_factor * pixel_scale), recenter=False) return imnos.array.astype('complex64')
def make_data(gsobject, scale, g1, g2, u0, v0, flux, noise=0., pix_scale=1., fpu=0., fpv=0., nside=32, nom_u0=0., nom_v0=0., rng=None, include_pixel=True): """Make a Star instance filled with a Kolmogorov profile :param gsobject The fiducial gsobject profile to use. :param scale: The scale to apply to the gsobject. :param g1, g2: The shear to apply to the gsobject. :param u0, v0: The sub-pixel offset to apply. :param flux: The flux of the star :param noise: RMS Gaussian noise to be added to each pixel [default: 0] :param pix_scale: pixel size in "wcs" units [default: 1.] :param fpu,fpv: position of this cutout in some larger focal plane [default: 0,0] :param nside: The size of the array [default: 32] :param nom_u0, nom_v0: The nominal u0,v0 in the StarData [default: 0,0] :param rng: If adding noise, the galsim deviate to use for the random numbers [default: None] :param include_pixel: Include integration over pixel. [default: True] """ k = gsobject.withFlux(flux).dilate(scale).shear(g1=g1, g2=g2).shift(u0, v0) if noise == 0.: var = 0.1 else: var = noise star = piff.Star.makeTarget(x=nside/2+nom_u0/pix_scale, y=nside/2+nom_v0/pix_scale, u=fpu, v=fpv, scale=pix_scale, stamp_size=nside) star.image.setOrigin(0,0) method = 'auto' if include_pixel else 'no_pixel' k.drawImage(star.image, method=method, offset=galsim.PositionD(nom_u0/pix_scale, nom_v0/pix_scale), use_true_center=False) star.data.weight = star.image.copy() star.weight.fill(1./var/var) if noise != 0: gn = galsim.GaussianNoise(sigma=noise, rng=rng) star.image.addNoise(gn) return star
def test_fluxconservation(): """Test flux conservation of charge deflection model for galaxy and flat image. """ galflux = 3.e4 galsigma = 3. noise = 10. shiftcoeff = 1.e-7 alpha = 0.3 size = 50 # Define a consistent rng for repeatability urng = galsim.UniformDeviate(rseed) gal = galsim.Gaussian(flux=galflux, sigma=galsigma) image = gal.drawImage(scale=1., dtype=np.float64) image.addNoise(galsim.GaussianNoise(sigma=noise, rng=urng)) flat = galsim.Image(size, size, dtype=np.float64, init_value=1.) cd = PowerLawCD(2, shiftcoeff, 0.94 * shiftcoeff, shiftcoeff / 2.4, shiftcoeff / 5., shiftcoeff / 3.7, shiftcoeff / 1.8, alpha) imagecd = cd.applyForward(image) flatcd = cd.applyForward(flat) # Then test np.testing.assert_almost_equal( image.array.sum(), imagecd.array.sum(), 13 - int(np.log10(galflux)), "Galaxy image flux is not left invariant by charge deflection") np.testing.assert_almost_equal( flat.array.sum(), flatcd.array.sum(), 13 - int(np.log10(galflux)), "Flat image flux is not left invariant by charge deflection") # Check picklability do_pickle(cd, lambda x: x.applyForward(image)) do_pickle(cd)
def buildNoisePadImage(self, noise_pad_size, noise_pad, rng): """A helper function that builds the `pad_image` from the given `noise_pad` specification. """ # Make it with the same dtype as the image pad_image = galsim.Image(noise_pad_size, noise_pad_size, dtype=self.image.dtype) # Figure out what kind of noise to apply to the image if isinstance(noise_pad, float): noise = galsim.GaussianNoise(rng, sigma=np.sqrt(noise_pad)) elif isinstance(noise_pad, galsim.correlatednoise._BaseCorrelatedNoise): noise = noise_pad.copy(rng=rng) elif isinstance(noise_pad, galsim.Image): noise = galsim.CorrelatedNoise(noise_pad, rng) elif self.use_cache and noise_pad in InterpolatedImage._cache_noise_pad: noise = InterpolatedImage._cache_noise_pad[noise_pad] if rng: # Make sure that we are using a specified RNG by resetting that in this cached # CorrelatedNoise instance, otherwise preserve the cached RNG noise = noise.copy(rng=rng) elif isinstance(noise_pad, str): noise = galsim.CorrelatedNoise(galsim.fits.read(noise_pad), rng) if self.use_cache: InterpolatedImage._cache_noise_pad[noise_pad] = noise else: raise ValueError( "Input noise_pad must be a float/int, a CorrelatedNoise, Image, or filename " + "containing an image to use to make a CorrelatedNoise!") # Add the noise pad_image.addNoise(noise) return pad_image
def make_star(hlr, g1, g2, u0, v0, flux, noise=0., du=1., fpu=0., fpv=0., nside=32, nom_u0=0., nom_v0=0., rng=None): """Make a Star instance filled with a Kolmogorov profile :param hlr: The half_light_radius of the Kolmogorov. :param g1, g2: Shear applied to profile. :param u0, v0: The sub-pixel offset to apply. :param flux: The flux of the star :param noise: RMS Gaussian noise to be added to each pixel [default: 0] :param du: pixel size in "wcs" units [default: 1.] :param fpu,fpv: position of this cutout in some larger focal plane [default: 0,0] :param nside: The size of the array [default: 32] :param nom_u0, nom_v0: The nominal u0,v0 in the StarData [default: 0,0] :param rng: If adding noise, the galsim deviate to use for the random numbers [default: None] """ k = galsim.Kolmogorov(half_light_radius=hlr, flux=flux).shear(g1=g1, g2=g2).shift(u0,v0) if noise == 0.: var = 0.1 else: var = noise star = piff.Star.makeTarget(x=nside/2+nom_u0/du, y=nside/2+nom_v0/du, u=fpu*du, v=fpv*du, scale=du, stamp_size=nside) star.image.setOrigin(0,0) k.drawImage(star.image, method='no_pixel', offset=galsim.PositionD(nom_u0/du,nom_v0/du), use_true_center=False) star.data.weight = star.image.copy() star.weight.fill(1./var/var) if noise != 0: gn = galsim.GaussianNoise(sigma=noise, rng=rng) star.image.addNoise(gn) return star
def addNoise(self, config, base, im, rng, current_var, draw_method, logger): # Read the noise variance var = self.getNoiseVariance(config, base) ret = var # save for the return value # If we already have some variance in the image (from whitening), then we subtract this much # from sigma**2. if current_var: logger.debug( 'image %d, obj %d: Target variance is %f, current variance is %f', base.get('image_num', 0), base.get('obj_num', 0), var, current_var) if var < current_var: raise galsim.GalSimConfigError( "Whitening already added more noise than the requested Gaussian noise." ) var -= current_var # Now apply the noise. import math sigma = math.sqrt(var) im.addNoise(galsim.GaussianNoise(rng, sigma=sigma)) logger.debug('image %d, obj %d: Added Gaussian noise with var = %f', base.get('image_num', 0), base.get('obj_num', 0), var) return ret
def draw(self, profile, mag, noise=False): img = galsim.ImageD(self.stamp_size, self.stamp_size, scale=self.pixel_scale) profile = profile.withFlux(self.flux(mag)) profile.drawImage(image=img) if noise: gd = galsim.GaussianNoise(bd, sigma=self.sigma_sky) img.addNoise(gd) return img
def draw(self, profile, mag, noise=False): img = galsim.ImageD(self.stamp_size, self.stamp_size, scale=self.pixel_scale) flux = self.s0 * 10**(-0.4*(mag - 24.0)) * self.exptime profile = profile.withFlux(flux) profile.drawImage(image=img) if noise: gd = galsim.GaussianNoise(bd, sigma=self.sigma_sky) img.addNoise(gd) return img
def test_gaussian(): """Test the Gaussian noise builder """ scale = 0.3 sigma = 17.3 config = { 'image' : { 'type' : 'Single', 'random_seed' : 1234, 'pixel_scale' : scale, 'size' : 32, 'noise' : { 'type' : 'Gaussian', 'sigma' : sigma, } }, 'gal' : { 'type' : 'Gaussian', 'sigma' : 1.1, 'flux' : 100, }, } # First build by hand rng = galsim.BaseDeviate(1234 + 1) gal = galsim.Gaussian(sigma=1.1, flux=100) im1a = gal.drawImage(nx=32, ny=32, scale=scale) var = sigma**2 im1a.addNoise(galsim.GaussianNoise(rng, sigma)) # Compare to what config builds im1b = galsim.config.BuildImage(config) np.testing.assert_equal(im1b.array, im1a.array) # Check noise variance var = sigma**2 var1 = galsim.config.CalculateNoiseVariance(config) np.testing.assert_equal(var1, var) var2 = galsim.Image(3,3) galsim.config.AddNoiseVariance(config, var2) np.testing.assert_almost_equal(var2.array, var) # Check include_obj_var=True, which shouldn't do anything different in this case var3 = galsim.Image(32,32) galsim.config.AddNoiseVariance(config, var3, include_obj_var=True) np.testing.assert_almost_equal(var3.array, var) # Gaussian noise can also be given the variance directly, rather than sigma galsim.config.RemoveCurrent(config) del config['image']['noise']['sigma'] del config['image']['noise']['_get'] config['image']['noise']['variance'] = var im1c = galsim.config.BuildImage(config) np.testing.assert_equal(im1c.array, im1a.array)
def allDetectorEffects(img, rng=None, exptime=None): """ This utility applies all sources of noise and detector effects for WFIRST that are implemented in GalSim. In terms of noise, this includes the Poisson noise due to the signal (sky + background), dark current, and read noise. The detector effects that are included are reciprocity failure, quantization, nonlinearity, and interpixel capacitance. It also includes the necessary factors of gain. In short, the user should be able to pass in an Image with all sources of signal (background plus astronomical objects), and the Image will be modified to include all subsequent steps in the image generation process for WFIRST that are implemented in GalSim. @param img The Image to be modified. @param rng An optional galsim.BaseDeviate to use for the addition of noise. If None, a new one will be initialized. [default: None] @param exptime The exposure time, in seconds. If None, then the WFIRST default exposure time will be used. [default: None] """ # Deal appropriately with passed-in RNG, exposure time. if rng is None: rng = galsim.BaseDeviate() elif not isinstance(rng, galsim.BaseDeviate): raise TypeError( "The rng provided to RealGalaxy constructor is not a BaseDeviate") if exptime is None: exptime = galsim.wfirst.exptime # Add Poisson noise. poisson_noise = galsim.PoissonNoise(rng) img.addNoise(poisson_noise) # Reciprocity failure (use WFIRST routine, with the supplied exposure time). addReciprocityFailure(img, exptime=exptime) # Quantize. img.quantize() # Dark current (use exposure time). dark_current = galsim.wfirst.dark_current * exptime dark_noise = galsim.DeviateNoise(galsim.PoissonDeviate(rng, dark_current)) img.addNoise(dark_noise) # Nonlinearity (use WFIRST routine). applyNonlinearity(img) # IPC (use WFIRST routine). applyIPC(img) # Read noise. read_noise = galsim.GaussianNoise(rng, sigma=galsim.wfirst.read_noise) img.addNoise(read_noise) # Gain. img /= galsim.wfirst.gain # Quantize. img.quantize()
def test_fail(): # Some vv noisy images that result in errors in the fit to check the error reporting. scale = 1.3 g1 = 0.33 g2 = -0.27 flux = 15 noise = 2. seed = 1234 psf = galsim.Moffat(half_light_radius=1.0, beta=2.5, trunc=3.0) psf = psf.dilate(scale).shear(g1=g1, g2=g2).withFlux(flux) image = psf.drawImage(nx=64, ny=64, scale=0.3) weight = image.copy() weight.fill(1 / noise**2) noisy_image = image.copy() rng = galsim.BaseDeviate(seed) noisy_image.addNoise(galsim.GaussianNoise(sigma=noise, rng=rng)) star1 = piff.Star(piff.StarData(image, image.true_center, weight), None) star2 = piff.Star(piff.StarData(noisy_image, image.true_center, weight), None) model1 = piff.Moffat(fastfit=True, beta=2.5) with np.testing.assert_raises(RuntimeError): model1.initialize(star2) with np.testing.assert_raises(RuntimeError): model1.fit(star2) star3 = model1.initialize(star1) star3 = model1.fit(star3) star3 = piff.Star(star2.data, star3.fit) with np.testing.assert_raises(RuntimeError): model1.fit(star3) # This is contrived to hit the fit failure for the reference. # I'm not sure what realistic use case would actually hit it, but at least it's # theoretically possible to fail there. model2 = piff.GSObjectModel(galsim.InterpolatedImage(noisy_image), fastfit=True) with np.testing.assert_raises(RuntimeError): model2.initialize(star1) model3 = piff.Moffat(fastfit=False, beta=2.5, scipy_kwargs={'max_nfev': 10}) with np.testing.assert_raises(RuntimeError): model3.initialize(star2) with np.testing.assert_raises(RuntimeError): model3.fit(star2).fit star3 = model3.initialize(star1) star3 = model3.fit(star3) star3 = piff.Star(star2.data, star3.fit) with np.testing.assert_raises(RuntimeError): model3.fit(star3)
def sample(args, do_series=False): """ Generate MCMC (emcee) samples from arguments specified in args. @param series Boolean controlling whether or not to use series approx. @returns post-sampling emcee sampler object. """ # 3 random number generators to seed bd = galsim.BaseDeviate(args.image_seed) # for GalSim rstate = np.random.mtrand.RandomState(args.sample_seed + args.jmax).get_state() # for emcee np.random.seed(args.sample_seed + args.jmax) # for numpy functions called outside of emcee nwalkers = args.nwalkers nsteps = args.nsteps ndim = 6 p_initial = [args.x0, args.y0, args.HLR, args.flux, args.e1, args.e2] # x0, y0, HLR, flux, e1, e2 p_std = [0.01, 0.01, 0.01, args.flux * 0.01, 0.01, 0.01] x0, y0, HLR, flux, e1, e2 = p_initial psf = galsim.Moffat(beta=3, fwhm=args.PSF_FWHM) gal = galsim.Spergel(nu=args.nu, half_light_radius=args.HLR, flux=args.flux) gal = gal.shear(e1=args.e1, e2=args.e2) gal = gal.shift(args.x0, args.y0) final = galsim.Convolve(gal, psf) target_image = final.drawImage(nx=args.nx, ny=args.ny, scale=args.scale) noise = galsim.GaussianNoise(rng=bd) if args.noisy_image: noisevar = target_image.addNoiseSNR(noise, args.SNR, preserve_flux=True) else: dummy_image = target_image.copy() noisevar = dummy_image.addNoiseSNR(noise, args.SNR, preserve_flux=True) p0 = np.empty((nwalkers, ndim), dtype=float) todo = np.ones(nwalkers, dtype=bool) lnp_args = [target_image, noisevar, args, do_series] while len(todo) > 0: p0[todo] = [ p_initial + p_std * np.random.normal(size=ndim) for i in range(len(todo)) ] todo = np.nonzero([not np.isfinite(lnprob(p, *lnp_args)) for p in p0])[0] sampler = emcee.EnsembleSampler(nwalkers, ndim, lnprob, args=lnp_args) sampler.run_mcmc(p0, nsteps, rstate0=rstate) return sampler
def test_addnoisesnr(): """Test that addNoiseSNR is behaving sensibly. """ # Rather than reproducing the S/N calculation in addNoiseSNR(), we'll just check for # self-consistency of the behavior with / without flux preservation. # Begin by making some object that we draw into an Image. gal_sigma = 3.7 pix_scale = 0.6 test_snr = 73. gauss = galsim.Gaussian(sigma=gal_sigma) im = gauss.drawImage(scale=pix_scale, dtype=np.float64) # Now make the noise object to use. # Use a default-constructed rng (i.e. rng=None) since we had initially had trouble # with that. And use the duplicate feature to get a second copy of this rng. gn = galsim.GaussianNoise() rng2 = gn.rng.duplicate() # Try addNoiseSNR with preserve_flux=True, so the RNG needs a different variance. # Check what variance was added for this SNR, and that the RNG still has its original variance # after this call. var_out = im.addNoiseSNR(gn, test_snr, preserve_flux=True) assert gn.getVariance() == 1.0 max_val = im.array.max() # Now apply addNoiseSNR to another (clean) image with preserve_flux=False, so we use the noise # variance in the original RNG, i.e., 1. Check that the returned variance is 1, and that the # value of the maximum pixel (presumably the peak of the galaxy light profile) is scaled as we # expect for this SNR. im2 = gauss.drawImage(scale=pix_scale, dtype=np.float64) gn2 = galsim.GaussianNoise(rng=rng2) var_out2 = im2.addNoiseSNR(gn2, test_snr, preserve_flux=False) assert var_out2 == 1.0 expect_max_val2 = max_val * np.sqrt(var_out2 / var_out) np.testing.assert_almost_equal( im2.array.max(), expect_max_val2, decimal=8, err_msg= 'addNoiseSNR with preserve_flux = True and False give inconsistent results' )
def add_noise(star, rng, noise_var=0.1): noise = galsim.GaussianNoise(sigma=np.sqrt(noise_var), rng=rng) noisy_image = star.image.copy() noisy_image.addNoise(noise) weight = star.weight.copy() weight.fill(1. / noise_var) noisy_star = piff.Star.makeTarget(x=0, y=0, image=noisy_image, weight=weight) return noisy_star
def setup(): """Build an input image and catalog used by a few tests below. """ wcs = galsim.TanWCS( galsim.AffineTransform(0.26, 0.05, -0.08, -0.24, galsim.PositionD(1024, 1024)), #galsim.AffineTransform(0.26, 0., 0., 0.26, galsim.PositionD(1024,1024)), galsim.CelestialCoord(5 * galsim.arcmin, -25 * galsim.degrees)) # Make the image (copied from test_single_image in test_simple.py) image = galsim.Image(2048, 2048, wcs=wcs) # Where to put the stars. x_list = [ 123.12, 345.98, 567.25, 1094.94, 924.15, 1532.74, 1743.11, 888.39, 1033.29, 1409.31 ] y_list = [ 345.43, 567.45, 1094.32, 924.29, 1532.92, 1743.83, 888.83, 1033.19, 1409.20, 123.11 ] # Draw a Gaussian PSF at each location on the image. sigma = 1.3 g1 = 0.23 g2 = -0.17 du = 0.09 # in arcsec dv = -0.07 flux = 123.45 psf = galsim.Gaussian(sigma=sigma).shear(g1=g1, g2=g2).shift(du, dv) * flux for x, y in zip(x_list, y_list): bounds = galsim.BoundsI(int(x - 31), int(x + 32), int(y - 31), int(y + 32)) offset = galsim.PositionD(x - int(x) - 0.5, y - int(y) - 0.5) psf.drawImage(image=image[bounds], method='no_pixel', offset=offset) image.addNoise( galsim.GaussianNoise(rng=galsim.BaseDeviate(1234), sigma=1e-6)) # Write out the image to a file image_file = os.path.join('output', 'test_stats_image.fits') image.write(image_file) # Write out the catalog to a file dtype = [('x', 'f8'), ('y', 'f8')] data = np.empty(len(x_list), dtype=dtype) data['x'] = x_list data['y'] = y_list cat_file = os.path.join('output', 'test_stats_cat.fits') fitsio.write(cat_file, data, clobber=True)
def draw_images(galaxies_psf, band, img_size, filter_name, sky_level_pixel, rng_shear=None, real_or_param='param'): ''' Return single galaxy noiseless images as well as the blended noisy one Parameters: ---------- galaxies_psf: PSF to add on the image band: filter number in which the image is drawn img_size: size of the drawn image filter_name: name of the filter sky_level_pixel: sky level pixel for noise realization real_or_param: the galaxy generation use real image or parametric model ''' # Create image in r bandpass filter to do the peak detection blend_img = galsim.ImageF(img_size, img_size, scale=pixel_scale[band]) images = [] for j, gal in enumerate(galaxies_psf): temp_img = galsim.ImageF(img_size, img_size, scale=pixel_scale[band]) # Parametric image if real_or_param == 'param': gal.drawImage(filters[filter_name], image=temp_img) # Real image elif real_or_param == "real": gal.drawImage(image=temp_img) images.append(temp_img) blend_img += temp_img # add noise if rng_shear is None: poissonian_noise = galsim.PoissonNoise(rng, sky_level=sky_level_pixel) blend_img.addNoise(poissonian_noise) #blend_img = np.array(blend_img.array.data) else: poissonian_noise = galsim.GaussianNoise( rng=rng_shear, sigma=np.sqrt(sky_level_pixel) ) #PoissonNoise(rng_shear, sky_level=sky_level_pixel) blend_img.addNoise(poissonian_noise) #np.random.seed(rng_shear) #rng = np.random.RandomState(rng_shear) #blend_img = rng.poisson(np.array(blend_img.array.data)+sky_level_pixel).astype(float) - sky_level_pixel return images, blend_img
def _set_gaussian_rng(self): """ Set the random number generator used to create the points We are approximating the random walk to have infinite number of steps, which is just a gaussian """ # gaussian step size in each dimension for a random walk with infinite # number steps self._sigma_step = self._half_light_radius/2.3548200450309493*2 self._gauss_rng = galsim.GaussianNoise( self._rng, sigma=self._sigma_step, )
def test_dep_noise(): """Test the deprecated methods in galsim/deprecated/noise.py """ import time t1 = time.time() rng = galsim.BaseDeviate(123) gn = galsim.GaussianNoise(rng=rng, sigma=0.3) rng2 = galsim.BaseDeviate(999) check_dep(gn.setRNG, rng2) assert gn.rng is rng2 check_dep(gn.setVariance, 1.7) np.testing.assert_almost_equal(gn.getVariance(), 1.7) check_dep(gn.scaleVariance, 1.9) np.testing.assert_almost_equal(gn.getVariance(), 1.7 * 1.9) check_dep(gn.setSigma, 2.3) np.testing.assert_almost_equal(gn.getSigma(), 2.3) pn = galsim.PoissonNoise(rng=rng, sky_level=0.3) check_dep(pn.setSkyLevel, 2.3) np.testing.assert_almost_equal(pn.getSkyLevel(), 2.3) cn = galsim.CCDNoise(rng=rng, gain=1.7, read_noise=0.5, sky_level=0.3) np.testing.assert_almost_equal(cn.getSkyLevel(), 0.3) np.testing.assert_almost_equal(cn.getGain(), 1.7) np.testing.assert_almost_equal(cn.getReadNoise(), 0.5) check_dep(cn.setSkyLevel, 2.3) np.testing.assert_almost_equal(cn.getSkyLevel(), 2.3) np.testing.assert_almost_equal(cn.getGain(), 1.7) np.testing.assert_almost_equal(cn.getReadNoise(), 0.5) check_dep(cn.setGain, 0.9) np.testing.assert_almost_equal(cn.getSkyLevel(), 2.3) np.testing.assert_almost_equal(cn.getGain(), 0.9) np.testing.assert_almost_equal(cn.getReadNoise(), 0.5) check_dep(cn.setReadNoise, 11) np.testing.assert_almost_equal(cn.getSkyLevel(), 2.3) np.testing.assert_almost_equal(cn.getGain(), 0.9) np.testing.assert_almost_equal(cn.getReadNoise(), 11) t2 = time.time() print 'time for %s = %.2f'%(funcname(),t2-t1)
def single_sersic_galaxy(gal_params, size=[60, 60], psf_rh=3.0, psf_beta=None, psf_custom=None, add_noise=None, band='r', pixel_scale=0.168, pixel_unit=False): """ Generate single Sersic galaxy """ import galsim # Define sersic galaxy gal = galsim.Sersic(gal_params['sersic_n'], half_light_radius=gal_params['gal_rh'], flux=gal_params['gal_flux']) # Shear the galaxy by some value. gal_shape = galsim.Shear(q=gal_params['gal_q'], beta=gal_params['gal_beta'] * galsim.degrees) gal = gal.shear(gal_shape) # Define the PSF profile if psf_custom is not None: psf = galsim.InterpolatedImage( galsim.Image(psf_custom, dtype=float, scale=0.168)) elif psf_rh < 0: raise ValueError('PSF half-light radius (`psf_rh`) must be positive!') elif psf_beta is not None: psf = ggalsim.Moffat(beta=psf_beta, flux=1., half_light_radius=psf_rh) else: psf = galsim.Gaussian(sigma=psf_rh, flux=1.) # Convolve galaxy with PSF final = galsim.Convolve([gal, psf]) # Draw the image with a particular pixel scale. if pixel_unit: image = final.drawImage(scale=pixel_scale, nx=size[1], ny=size[0]) else: image = final.drawImage(scale=pixel_scale, nx=size[1] // pixel_scale, ny=size[0] // pixel_scale) # Add noise if want if add_noise is not None: #assert isinstance(add_noise, float) or isinstance(add_noise, int), '`add_noise` must be float!' noise = galsim.GaussianNoise(sigma=add_noise) image.addNoise(noise) return image
def test_moments_fail(): # If the weight is 0 everywhere, HSM will fail. _, noisy_stars = makeStars(nstar=1, beta=5.) star = noisy_stars[0] star.data.weight *= 0. with np.testing.assert_raises(galsim.GalSimHSMError): calculate_moments(star) # If it's just really noisy, then HSM will return an error flag, which Piff turns into a # RuntimeError _, noisy_stars = makeStars(nstar=1, beta=5.) star = noisy_stars[0] rng = galsim.BaseDeviate(1234) star.data.image.addNoise(galsim.GaussianNoise(sigma=2.e7, rng=rng)) with np.testing.assert_raises(RuntimeError): calculate_moments(star)
def render_stamp(self, gal_orig, g1, g2, theta, xshift, yshift, mu, mirror): # transform gal = gal_orig.copy() gal.applyDilation(self.args.size_rescale) gal.applyRotation(theta * galsim.radians) gal = gal if not mirror else gal.transform(-1.0, 0.0, 0.0, 1.0) gal.applyLensing(g1=g1, g2=g2, mu=mu) # convolve psf = galsim.Gaussian(fwhm=self.args.gaussian_psf_fwhm) pixel = galsim.Pixel(scale=self.args.pixel_scale) final = galsim.Convolve([psf, pixel, gal]) # render at subpixel translation offset = galsim.PositionD(xshift, yshift) bbox = galsim.BoundsI(0, self.args.stamp_full_sz - 1, 0, self.args.stamp_full_sz - 1) galaxy_image = galsim.ImageF(self.args.stamp_full_sz, self.args.stamp_full_sz, scale=self.args.pixel_scale) galaxy_image.setOrigin(0, 0) stamp = galaxy_image.subImage(bbox) final.draw(stamp, normalization='flux', scale=self.args.pixel_scale, offset=offset) # whiten current_var = -1.0 additional_var = self.args.noise_std**2 if self.args.noise_whiten: current_var = final.noise.whitenImage(stamp) additional_var = self.args.noise_std**2 - current_var if additional_var < 0.0 and self.args.noise_whiten_can_fail: # pre-whitening failed return None, None, None, None # add noise if additional_var > 0.0: new_noise = galsim.GaussianNoise(self.rng, sigma=additional_var**0.5) new_noise.applyTo(stamp) return stamp, gal, current_var, additional_var
def generate_sample(args): """Generate one valid sample and write it to the destination arrays. """ i, flux, bulge_n, bulge_re, g1, g2, psf_re, noise = args with counter.get_lock(): # Increment the global iteration counter counter.value += 1 # Initialize the random number generators random.seed(random_seed + counter.value) rng = galsim.BaseDeviate(random_seed + counter.value + 1) gal = galsim.Sersic(bulge_n, half_light_radius=bulge_re) gal = gal.withFlux(flux) gal = gal.shear(g1=g1, g2=g2) psf = galsim.Moffat(beta=psf_beta, flux=1.0, fwhm=psf_re) final = galsim.Convolve([psf, gal]) image = galsim.ImageF(image_size, image_size, scale=pixel_scale) final.drawImage(image=image) # signal to noise ratio snr = np.sqrt((image.array**2).sum()) / noise image_nonoise = copy.deepcopy(image.array) image.addNoise(galsim.PoissonNoise(rng, sky_level=0.0)) # noise map for bkgr gaussian noise image.addNoise(galsim.GaussianNoise(rng, sigma=noise)) # Optionally: generate a PSF image if i == 0: psf_image = galsim.ImageF(image_size, image_size, scale=pixel_scale) psf.drawImage(image=psf_image) data["psf_img"][i] = psf_image.array data["img"][i] = image.array # final noised image data["img_nonoise"][i] = image_nonoise # noiseless image data["gal_flux"][i] = flux data["bulge_re"][i] = bulge_re data["bulge_n"][i] = bulge_n data["psf_r"][i] = psf_re data["snr"][i] = snr data["sigma"][i] = noise data["g_1"][i] = g1 data["g_2"][i] = g2
def test_forwardbackward(): """Test invariance (to first order) under forward-backward transformation. """ import time t1 = time.time() galflux = 3000. galsigma = 3. noise = 1. shiftcoeff = 1.e-7 alpha = 0.3 size = 50 gal = galsim.Gaussian(flux=galflux, sigma=galsigma) maxflux = gal.xValue(0, 0) image = gal.drawImage(scale=1., dtype=np.float64) cimage = galsim.Image(image.getBounds(), dtype=np.float64) # used for normalization later, we expect residual to be of this order cimage.fill(1.e-3) cimage = cimage + image cimage = cimage * maxflux * maxflux * shiftcoeff * shiftcoeff # Define a consistent rng for repeatability urng = galsim.UniformDeviate(rseed) image.addNoise(galsim.GaussianNoise(sigma=noise, rng=urng)) cd = PowerLawCD(2, shiftcoeff * 0.0234, shiftcoeff * 0.05234, shiftcoeff * 0.01312, shiftcoeff * 0.00823, shiftcoeff * 0.07216, shiftcoeff * 0.01934, alpha) imagecd = cd.applyForward(image) imagecddc = cd.applyBackward(imagecd) # residual after forward-backward should be of order a^2 q qmax^2 imageres = (imagecddc - image) / cimage maxres = imageres.array.max() minres = imageres.array.min() assert maxres < 10, ( "maximum positive residual of forward-backward transformation is too large" ) assert minres > -10, ( "maximum negative residual of forward-backward transformation is too large" ) t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
def _generate_noise_from_rootps(rng, rootps): """Utility function for generating a NumPy array containing a Gaussian random noise field with a user-specified power spectrum also supplied as a NumPy array. @param rng galsim.BaseDeviate instance to provide the random number generation @param rootps a NumPy array containing the square root of the discrete Power Spectrum ordered in two dimensions according to the usual DFT pattern (see np.fft.fftfreq) @return A NumPy array (contiguous) of the same shape as rootps, filled with the noise field. """ # I believe it is cheaper to make two random vectors than to make a single one (for a phase) # and then apply cos(), sin() to it... gaussvec_real = galsim.ImageD(rootps.shape[1], rootps.shape[0]) # Remember NumPy is [y, x] gaussvec_imag = galsim.ImageD(rootps.shape[1], rootps.shape[0]) gn = galsim.GaussianNoise(rng, sigma=1.) # Quicker to create anew each time than to save it and # then check if its rng needs to be changed or not. gaussvec_real.addNoise(gn) gaussvec_imag.addNoise(gn) noise_array = np.fft.ifft2((gaussvec_real.array + gaussvec_imag.array * 1j) * rootps) return np.ascontiguousarray(noise_array.real)
def add_noise(self, rng, gal_stamp): #self.make_stamp() sigma = wfirst.read_noise read_noise = galsim.GaussianNoise(rng, sigma=sigma) im, sky_stamp = self.add_background(gal_stamp, thermal_backgrounds=None, filter_='H158', phot=False) #im.addNoise(read_noise) gal_stamp = self.add_poisson_noise(rng, im, sky_image=sky_stamp, phot=False) #sky_image = add_poisson_noise(rng, sky_image, sky_image=sky_image, phot=False) gal_stamp -= sky_stamp return gal_stamp, sky_stamp
def ring_test_single_gal(Args, gal, chr_PSF, noise_sigma=None): """ Ring test to measure shape of galaxy. @param Args Class with the following attributes: Args.npix Number of pixels across postage stamp image Args.scale Pixel scale of postage stamp image Args.n_ring Number of intrinsic ellipticity pairs around ring. Args.shear_est Method to use to estimate shape. Args.sig_w For S13 method, the width (sigma) of the Gaussian weight funcion. @return Multiplicate bias estimate. """ star = galsim.Gaussian(half_light_radius=1e-9) * Args.c_SED con = galsim.Convolve(chr_PSF, star) PSF_img = con.drawImage(Args.bp, nx=Args.npix, ny=Args.npix, scale=Args.scale) n = len(Args.rt_g) ghat = np.zeros([n, 2]) random_seed = 141508 rng = galsim.BaseDeviate(random_seed) for i, g in enumerate(Args.rt_g): gsum = [] betas = np.linspace(0.0, 360.0, 2 * Args.n_ring, endpoint=False) / 2. for beta in betas: gal1 = gal.rotate(beta * galsim.degrees).shear(g1=g[0], g2=g[1]) obj = galsim.Convolve(gal1, chr_PSF) img = obj.drawImage(bandpass=Args.bp, nx=Args.npix, ny=Args.npix, scale=Args.scale) if noise_sigma: gaussian_noise = galsim.GaussianNoise(rng, noise_sigma) img.addNoise(gaussian_noise) result = estimate_shape(Args, img, PSF_img, Args.shear_est) if result is "Fail": return "Fail" del gal1, obj, img gsum.append([result.g1, result.g2]) gmean = np.mean(np.array(gsum), axis=0) ghat[i] = [gmean[0], gmean[1]] return ghat.T