def _get_object(self): hlr, flux = self._get_hlr_flux() disk_hlr = hlr if self.g_pdf is None: disk_g1, disk_g2 = 0.0, 0.0 else: disk_g1, disk_g2 = self.g_pdf.sample2d() all_obj = {} if 'bulge' in self['pdfs']: hlr_fac, fracdev, gfac, bulge_offset = self._get_bulge_stats() bulge_hlr = disk_hlr * hlr_fac bulge_g1, bulge_g2 = gfac * disk_g1, gfac * disk_g2 disk_flux = (1 - fracdev) * flux bulge_flux = fracdev * flux bulge = galsim.DeVaucouleurs( half_light_radius=bulge_hlr, flux=bulge_flux, ).shear( g1=bulge_g1, g2=bulge_g2, ).shift( dx=bulge_offset[1], dy=bulge_offset[0], ) all_obj['bulge'] = bulge else: disk_flux = flux disk = galsim.Exponential( half_light_radius=disk_hlr, flux=disk_flux, ).shear( g1=disk_g1, g2=disk_g2, ) all_obj['disk'] = disk if 'knots' in self['pdfs']: nknots, knots_flux = self._get_knots_stats(disk_flux) knots = galsim.RandomWalk( npoints=nknots, half_light_radius=disk_hlr, flux=knots_flux, ).shear(g1=disk_g1, g2=disk_g2) all_obj['knots'] = knots obj_cen1, obj_cen2 = self.position_pdf.sample() all_obj['cen'] = np.array([obj_cen1, obj_cen2]) return all_obj
def _get_knots(self, spec, hlr, knot_flux): return galsim.RandomWalk( npoints=spec['knots']['num'], half_light_radius=hlr, flux=knot_flux, rng=self.galsim_rng, )
def test_randwalk_defaults(): """ Create a random walk galaxy and test that the getters work for default inputs """ # try constructing with mostly defaults npoints=100 hlr = 8.0 rng = galsim.BaseDeviate(1234) rw=galsim.RandomWalk(npoints, hlr, rng=rng) assert rw.npoints==npoints,"expected npoints==%d, got %d" % (npoints, rw.npoints) assert rw.input_half_light_radius==hlr,\ "expected hlr==%g, got %g" % (hlr, rw.input_half_light_radius) g=rw.gaussians ngauss=len(g) assert ngauss == npoints,"expected %d gaussians, got %d" % (npoints, ngauss) pts=rw.points assert pts.shape == (npoints,2),"expected (%d,2) shape for points, got %s" % (npoints, pts.shape) # Run some basic tests of correctness psf = galsim.Gaussian(sigma=0.8) conv = galsim.Convolve(rw, psf) check_basic(conv, "RandomWalk") im = galsim.ImageD(64,64, scale=0.5) do_shoot(conv, im, "RandomWalk") do_kvalue(conv, im, "RandomWalk") do_pickle(rw) do_pickle(conv)
def test_randwalk_defaults(): """ Create a random walk galaxy and test that the getters work for default inputs """ # try constructing with mostly defaults npoints = 100 hlr = 8.0 rw = galsim.RandomWalk(npoints, hlr) assert rw.npoints == npoints, "expected npoints==%d, got %d" % (npoints, rw.npoints) assert rw.input_half_light_radius==hlr,\ "expected hlr==%g, got %g" % (hlr, rw.input_half_light_radius) g = rw.gaussians ngauss = len(g) assert ngauss == npoints, "expected %d gaussians, got %d" % (npoints, ngauss) pts = rw.points assert pts.shape == ( npoints, 2), "expected (%d,2) shape for points, got %s" % (npoints, pts.shape)
def test_randwalk_valid_inputs(): """ Create a random walk galaxy and test that the getters work for valid non-default inputs """ # try constructing with mostly defaults npoints = 100 hlr = 8.0 flux = 3.5 seed = 35 rng = galsim.UniformDeviate(seed) rw = galsim.RandomWalk(npoints, hlr, flux=flux, rng=rng) assert rw.npoints == npoints, "expected npoints==%d, got %d" % (npoints, rw.npoints) assert rw.input_half_light_radius==hlr,\ "expected hlr==%g, got %g" % (hlr, rw.input_half_light_radius) assert rw.flux==flux,\ "expected flux==%g, got %g" % (flux, rw.flux) g = rw.gaussians ngauss = len(g) assert ngauss == npoints == npoints, "expected %d gaussians, got %d" % ( npoints, ngauss) pts = rw.points assert pts.shape == ( npoints, 2), "expected (%d,2) shape for points, got %s" % (npoints, pts.shape)
def test_randwalk_repr(): """ test the repr and str work, and that a new object can be created using eval """ npoints = 100 hlr = 8.0 flux = 1 rw = galsim.RandomWalk(npoints, hlr, flux=flux) # just make sure str() works, don't require eval to give # a consistent object back st = str(rw) # require eval(repr(rw)) to give a consistent object back new_rw = eval(repr(rw)) assert new_rw.npoints == rw.npoints,\ "expected npoints=%d got %d" % (rw.npoints,new_rw.npoints) mess = "expected input_half_light_radius=%.16g got %.16g" assert new_rw.input_half_light_radius == rw.input_half_light_radius,\ mess % (rw.input_half_light_radius,new_rw.input_half_light_radius) assert new_rw.flux == rw.flux,\ "expected flux=%.16g got %.16g" % (rw.flux,new_rw.flux)
def test_randwalk_hlr(): """ Create a random walk galaxy and test that the half light radius is consistent with the requested value Note for DeV profile we don't test npoints=3 because it fails """ # for checking accuracy, we need expected standard deviation of # the result interp_npts = np.array( [6, 7, 8, 9, 10, 15, 20, 30, 50, 75, 100, 150, 200, 500, 1000]) interp_hlr = np.array([ 7.511, 7.597, 7.647, 7.68, 7.727, 7.827, 7.884, 7.936, 7.974, 8.0, 8.015, 8.019, 8.031, 8.027, 8.043 ]) / 8.0 interp_std = np.array([ 2.043, 2.029, 1.828, 1.817, 1.67, 1.443, 1.235, 1.017, 0.8046, 0.6628, 0.5727, 0.4703, 0.4047, 0.255, 0.1851 ]) / 8.0 hlr = 8.0 # test these npoints npt_vals = [3, 10, 30, 60, 100, 1000] # should be within 5 sigma nstd = 5 # number of trials ntrial_vals = [100] * len(npt_vals) profs = [ galsim.Gaussian(half_light_radius=hlr), galsim.Exponential(half_light_radius=hlr), galsim.DeVaucouleurs(half_light_radius=hlr), ] for prof in profs: for ipts, npoints in enumerate(npt_vals): # DeV profile will fail for npoints==3 if isinstance(prof, galsim.DeVaucouleurs) and npoints == 3: continue ntrial = ntrial_vals[ipts] hlr_calc = np.zeros(ntrial) for i in range(ntrial): #rw=galsim.RandomWalk(npoints, hlr) rw = galsim.RandomWalk(npoints, profile=prof) hlr_calc[i] = rw.calculateHLR() mn = hlr_calc.mean() std_check = np.interp(npoints, interp_npts, interp_std * hlr) mess = "hlr for npoints: %d outside of expected range" % npoints assert abs(mn - hlr) < nstd * std_check, mess
def test_randwalk_defaults(): """ Create a random walk galaxy and test that the getters work for default inputs """ # try constructing with mostly defaults npoints = 100 hlr = 8.0 rng = galsim.BaseDeviate(1234) rw = galsim.RandomWalk(npoints, half_light_radius=hlr, rng=rng) assert rw.npoints == npoints, "expected npoints==%d, got %d" % (npoints, rw.npoints) assert rw.input_half_light_radius==hlr,\ "expected hlr==%g, got %g" % (hlr, rw.input_half_light_radius) nobj = len(rw.points) assert nobj == npoints, "expected %d objects, got %d" % (npoints, nobj) pts = rw.points assert pts.shape == ( npoints, 2), "expected (%d,2) shape for points, got %s" % (npoints, pts.shape) np.testing.assert_almost_equal(rw.centroid.x, np.mean(pts[:, 0])) np.testing.assert_almost_equal(rw.centroid.y, np.mean(pts[:, 1])) gsp = galsim.GSParams(xvalue_accuracy=1.e-8, kvalue_accuracy=1.e-8) rw2 = galsim.RandomWalk(npoints, half_light_radius=hlr, rng=rng, gsparams=gsp) assert rw2 != rw assert rw2 == rw.withGSParams(gsp) # Run some basic tests of correctness psf = galsim.Gaussian(sigma=0.8) conv = galsim.Convolve(rw, psf) check_basic(conv, "RandomWalk") im = galsim.ImageD(64, 64, scale=0.5) do_shoot(conv, im, "RandomWalk") do_kvalue(conv, im, "RandomWalk") do_pickle(rw) do_pickle(conv)
def test_randwalk_config(): """ test we get the same object using a configuration and the explicit constructor """ hlr = 2.0 flux = np.pi gal_config1 = { 'type': 'RandomWalk', 'npoints': 100, 'half_light_radius': hlr, 'flux': flux, } gal_config2 = { 'type': 'RandomWalk', 'npoints': 150, 'profile': { 'type': 'Exponential', 'half_light_radius': hlr, 'flux': flux, } } for gal_config in (gal_config1, gal_config2): config = { 'gal': gal_config, 'rng': galsim.BaseDeviate(31415), } rwc = galsim.config.BuildGSObject(config, 'gal')[0] print(repr(rwc._profile)) rw = galsim.RandomWalk( gal_config['npoints'], half_light_radius=hlr, flux=flux, ) assert rw.npoints==rwc.npoints,\ "expected npoints==%d, got %d" % (rw.npoints, rwc.npoints) assert rw.input_half_light_radius==rwc.input_half_light_radius,\ "expected hlr==%g, got %g" % (rw.input_half_light_radius, rw.input_half_light_radius) nobj = len(rw.points) nobjc = len(rwc.points) assert nobj == nobjc, "expected %d objects, got %d" % (nobj, nobjc) pts = rw.points ptsc = rwc.points assert (pts.shape == ptsc.shape),\ "expected %s shape for points, got %s" % (pts.shape,ptsc.shape)
def test_randwalk_valid_inputs(): """ Create a random walk galaxy and test that the getters work for valid non-default inputs """ # try constructing with mostly defaults npoints = 100 hlr = 8.0 flux = 3.5 seed = 35 rng = galsim.UniformDeviate(seed) args = (npoints, ) kw1 = {'half_light_radius': hlr, 'flux': flux, 'rng': rng} prof = galsim.Exponential(half_light_radius=hlr, flux=flux) kw2 = {'profile': prof, 'rng': rng} # version of profile with a transformation prof = galsim.Exponential(half_light_radius=hlr, flux=flux) prof = prof.shear(g1=-0.05, g2=0.025) kw3 = {'profile': prof, 'rng': rng} for kw in (kw1, kw2, kw3): rw = galsim.RandomWalk(*args, **kw) assert rw.npoints == npoints, "expected npoints==%d, got %d" % ( npoints, rw.npoints) assert rw.flux==flux,\ "expected flux==%g, got %g" % (flux, rw.flux) if kw is not kw3: # only test if not a transformation object assert rw.input_half_light_radius==hlr,\ "expected hlr==%g, got %g" % (hlr, rw.input_half_light_radius) pts = rw.points nobj = len(pts) assert nobj == npoints == npoints, "expected %d objects, got %d" % ( npoints, nobj) pts = rw.points assert pts.shape == (npoints, 2), "expected (%d,2) shape for points, got %s" % ( npoints, pts.shape)
def add_point_sources(self, n_points, frac_gal_flux=0.05, frac_r_e=1.0, total_flux=None, point_fwhm=None): r_e = self.pars.r_e.to('arcsec').value * frac_r_e flux = total_flux if total_flux else self.gal.flux * frac_gal_flux points = galsim.RandomWalk(n_points, half_light_radius=r_e, flux=flux) points = points.shear(q=self.pars.b_a, beta=(0.0 * galsim.degrees)) points = points.rotate( self.pars.PA.to('degree').value * galsim.degrees) if total_flux is None: self.gal = self.gal.withFlux(self.gal.flux * (1-frac_gal_flux)) if point_fwhm is not None: point_psf = galsim.Gaussian( flux=1.0, fwhm=point_fwhm.to('arcsec').value) points = galsim.Convolve([points, point_psf]) self.gal = galsim.Add([self.gal, points]) self._original_gal = self.gal
def test_randwalk_hlr(): """ Create a random walk galaxy and test that the half light radius is consistent with the requested value """ # for checking accuracy, we need expected standard deviation of # the result interp_npts = np.array( [6, 7, 8, 9, 10, 15, 20, 30, 50, 75, 100, 150, 200, 500, 1000]) interp_hlr = np.array([ 7.511, 7.597, 7.647, 7.68, 7.727, 7.827, 7.884, 7.936, 7.974, 8.0, 8.015, 8.019, 8.031, 8.027, 8.043 ]) / 8.0 interp_std = np.array([ 2.043, 2.029, 1.828, 1.817, 1.67, 1.443, 1.235, 1.017, 0.8046, 0.6628, 0.5727, 0.4703, 0.4047, 0.255, 0.1851 ]) / 8.0 hlr = 8.0 # test these npoints npt_vals = [3, 10, 30, 60, 100, 1000] # should be within 4 sigma nstd = 4 # number of trials ntrial_vals = [100] * len(npt_vals) for ipts, npoints in enumerate(npt_vals): ntrial = ntrial_vals[ipts] hlr_calc = np.zeros(ntrial) for i in range(ntrial): rw = galsim.RandomWalk(npoints, hlr) hlr_calc[i] = rw.calculateHLR() mn = hlr_calc.mean() std_check = np.interp(npoints, interp_npts, interp_std * hlr) mess = "hlr for npoints: %d outside of expected range" % npoints assert abs(mn - hlr) < nstd * std_check, mess
def test_randwalk_config(): """ test we get the same object using a configuration and the explicit constructor """ gal_config = { 'type': 'RandomWalk', 'npoints': 100, 'half_light_radius': 2.0, 'flux': np.pi, } config = { 'gal': gal_config, 'rng': galsim.BaseDeviate(31415), } rwc = galsim.config.BuildGSObject(config, 'gal')[0] rw = galsim.RandomWalk( gal_config['npoints'], gal_config['half_light_radius'], flux=gal_config['flux'], ) assert rw.npoints==rwc.npoints,\ "expected npoints==%d, got %d" % (rw.npoints, rwc.npoints) assert rw.input_half_light_radius==rwc.input_half_light_radius,\ "expected hlr==%g, got %g" % (rw.input_half_light_radius, rw.input_half_light_radius) ng = len(rw.gaussians) ngc = len(rwc.gaussians) assert ng == ngc, "expected %d gaussians, got %d" % (ng, ngc) pts = rw.points ptsc = rwc.points assert (pts.shape == ptsc.shape),\ "expected %s shape for points, got %s" % (pts.shape,ptsc.shape)
def drawRandomWalk(self, gsObject, psf=None): """ Draw the image of a RandomWalk light profile. In orider to allow for reproducibility, the specific realisation of the random walk is seeded by the object unique identifier, if provided. @param [in] gsObject is an instantiation of the GalSimCelestialObject class carrying information about the object whose image is to be drawn @param [in] psf PSF to use for the convolution. If None, then use self.PSF. """ if psf is None: psf = self.PSF # Seeds the random walk with the object id if available if gsObject.uniqueId is None: rng = None else: rng = galsim.BaseDeviate(int(gsObject.uniqueId)) # Create the RandomWalk profile centeredObj = galsim.RandomWalk(npoints=int(gsObject.npoints), half_light_radius=float(gsObject.halfLightRadiusArcsec), rng=rng) # Apply intrinsic ellipticity to the profile centeredObj = centeredObj.shear(q=gsObject.minorAxisRadians/gsObject.majorAxisRadians, beta=(0.5*np.pi+gsObject.positionAngleRadians)*galsim.radians) # Apply weak lensing distortion. centeredObj = centeredObj.lens(gsObject.g1, gsObject.g2, gsObject.mu) # Apply the PSF. if psf is not None: centeredObj = psf.applyPSF(xPupil=gsObject.xPupilArcsec, yPupil=gsObject.yPupilArcsec, obj=centeredObj) return centeredObj
def main(argv): """ Make a fits image cube using parameters from an input catalog - The number of images in the cube matches the number of rows in the catalog. - Each image size is computed automatically by GalSim based on the Nyquist size. - Only galaxies. No stars. - PSF is Moffat - Each galaxy is bulge plus disk: deVaucouleurs + Exponential. - A fraction of the disk flux is placed into point sources, which can model knots of star formation. - The catalog's columns are: 0 PSF beta (Moffat exponent) 1 PSF FWHM 2 PSF e1 3 PSF e2 4 PSF trunc 5 Disc half-light-radius 6 Disc e1 7 Disc e2 8 Bulge half-light-radius 9 Bulge e1 10 Bulge e2 11 Galaxy dx (the two components have same center) 12 Galaxy dy - Applied shear is the same for each galaxy - Noise is Poisson using a nominal sky value of 1.e6 """ logging.basicConfig(format="%(message)s", level=logging.INFO, stream=sys.stdout) logger = logging.getLogger("demo4") # Define some parameters we'll use below and make directories if needed. cat_file_name = os.path.join('input', 'galsim_default_input.asc') if not os.path.isdir('output'): os.mkdir('output') multi_file_name = os.path.join('output', 'multi.fits') random_seed = 8241573 sky_level = 1.e6 # ADU / arcsec^2 pixel_scale = 1.0 # arcsec / pixel (size units in input catalog are pixels) gal_flux = 1.e6 # arbitrary choice, makes nice (not too) noisy images gal_g1 = -0.009 # gal_g2 = 0.011 # # the fraction of flux in each component # 40% is in the bulge, 60% in a disk. 70% of that disk light is placed # into point sources distributed as a random walk bulge_frac = 0.4 disk_frac = 0.6 knot_frac = 0.42 smooth_disk_frac = 0.18 # number of knots of star formation. To simulate a nice irregular (all the # flux is in knots) we find ~100 is a minimum number needed, but we will # just use 10 here to make the demo run fast. n_knots = 10 xsize = 64 # pixels ysize = 64 # pixels logger.info('Starting demo script 4 using:') logger.info(' - parameters taken from catalog %r', cat_file_name) logger.info(' - Moffat PSF (parameters from catalog)') logger.info(' - pixel scale = %.2f', pixel_scale) logger.info(' - Bulge + Disc galaxies (parameters from catalog)') logger.info(' - 100 Point sources, distributed as random walk') logger.info(' - Applied gravitational shear = (%.3f,%.3f)', gal_g1, gal_g2) logger.info(' - Poisson noise (sky level = %.1e).', sky_level) # Read in the input catalog cat = galsim.Catalog(cat_file_name) # save a list of the galaxy images in the "images" list variable: images = [] for k in range(cat.nobjects): # Initialize the (pseudo-)random number generator that we will be using below. # Use a different random seed for each object to get different noise realizations. # Using sequential random seeds here is safer than it sounds. We use Mersenne Twister # random number generators that are designed to be used with this kind of seeding. # However, to be extra safe, we actually initialize one random number generator with this # seed, generate and throw away two random values with that, and then use the next value # to seed a completely different Mersenne Twister RNG. The result is that successive # RNGs created this way produce very independent random number streams. rng = galsim.BaseDeviate(random_seed + k + 1) # Take the Moffat beta from the first column (called 0) of the input catalog: # Note: cat.get(k,col) returns a string. To get the value as a float, use either # cat.getFloat(k,col) or float(cat.get(k,col)) beta = cat.getFloat(k, 0) # A Moffat's size may be either scale_radius, fwhm, or half_light_radius. # Here we use fwhm, taking from the catalog as well. fwhm = cat.getFloat(k, 1) # A Moffat profile may be truncated if desired # The units for this are expected to be arcsec (or specifically -- whatever units # you are using for all the size values as defined by the pixel_scale). trunc = cat.getFloat(k, 4) # Note: You may omit the flux, since the default is flux=1. psf = galsim.Moffat(beta=beta, fwhm=fwhm, trunc=trunc) # Take the (e1, e2) shape parameters from the catalog as well. psf = psf.shear(e1=cat.getFloat(k, 2), e2=cat.getFloat(k, 3)) # Galaxy is a bulge + disk(+knots) with parameters taken from the catalog: # put some fraction of the disk light into knots of star formation disk_hlr = cat.getFloat(k, 5) disk_e1 = cat.getFloat(k, 6) disk_e2 = cat.getFloat(k, 7) bulge_hlr = cat.getFloat(k, 8) bulge_e1 = cat.getFloat(k, 9) bulge_e2 = cat.getFloat(k, 10) smooth_disk = galsim.Exponential(flux=smooth_disk_frac, half_light_radius=disk_hlr) knots = galsim.RandomWalk(n_knots, half_light_radius=disk_hlr, flux=knot_frac, rng=rng) disk = galsim.Add([smooth_disk, knots]) disk = disk.shear(e1=disk_e1, e2=disk_e2) # the rest of the light goes into the bulge bulge = galsim.DeVaucouleurs(flux=bulge_frac, half_light_radius=bulge_hlr) bulge = bulge.shear(e1=bulge_e1, e2=bulge_e2) # The flux of an Add object is the sum of the component fluxes. # Note that in demo3.py, a similar addition was performed by the binary operator "+". gal = galsim.Add([disk, bulge]) # This flux may be overridden by withFlux. The relative fluxes of the components # remains the same, but the total flux is set to gal_flux. gal = gal.withFlux(gal_flux) gal = gal.shear(g1=gal_g1, g2=gal_g2) # The center of the object is normally placed at the center of the postage stamp image. # You can change that with shift: gal = gal.shift(dx=cat.getFloat(k, 11), dy=cat.getFloat(k, 12)) final = galsim.Convolve([psf, gal]) # Draw the profile image = galsim.ImageF(xsize, ysize) final.drawImage(image, scale=pixel_scale) # Add Poisson noise to the image: image.addNoise(galsim.PoissonNoise(rng, sky_level * pixel_scale**2)) logger.info('Drew image for object at row %d in the input catalog' % k) # Add the image to our list of images images.append(image) # Now write the images to a multi-extension fits file. Each image will be in its own HDU. galsim.fits.writeMulti(images, multi_file_name) logger.info('Images written to multi-extension fits file %r', multi_file_name)
def test_randwalk_invalid_inputs(): """ Create a random walk galaxy and test that the the correct exceptions are raised for invalid inputs """ npoints = 100 hlr = 8.0 flux = 1.0 # try sending wrong type for npoints with assert_raises(GalSimValueError): galsim.RandomWalk('blah', half_light_radius=1, flux=3) # try sending neither profile or hlr with assert_raises(GalSimIncompatibleValuesError): galsim.RandomWalk(npoints) # try with rng wrong type with assert_raises(TypeError): galsim.RandomWalk(npoints, half_light_radius=hlr, rng=37) # wrong type for profile with assert_raises(GalSimIncompatibleValuesError): galsim.RandomWalk(npoints, profile=3.5) # wrong type for npoints npoints_bad = [35] with assert_raises(TypeError): galsim.RandomWalk(npoints_bad, half_light_radius=hlr) # wrong type for hlr with assert_raises(GalSimRangeError): galsim.RandomWalk(npoints, half_light_radius=-1.5) # wrong type for flux with assert_raises(TypeError): galsim.RandomWalk(npoints, flux=[3.5], half_light_radius=hlr) # sending flux with a profile prof = galsim.Exponential(half_light_radius=hlr, flux=2.0) with assert_raises(GalSimIncompatibleValuesError): galsim.RandomWalk(npoints, flux=flux, profile=prof) # sending hlr with a profile with assert_raises(GalSimIncompatibleValuesError): galsim.RandomWalk(npoints, half_light_radius=3, profile=prof) # bad value for npoints npoints_bad = -35 with assert_raises(GalSimRangeError): galsim.RandomWalk(npoints_bad, half_light_radius=hlr) # bad value for hlr with assert_raises(GalSimRangeError): galsim.RandomWalk(npoints, half_light_radius=-1.5) # negative flux with assert_raises(GalSimRangeError): galsim.RandomWalk(npoints, flux=-35.0, half_light_radius=hlr)
def test_randwalk_invalid_inputs(): """ Create a random walk galaxy and test that the the correct exceptions are raised for invalid inputs """ # try with rng wrong type npoints = 100 hlr = 8.0 rng = 37 args = (npoints, hlr) kwargs = {'rng': rng} with assert_raises(TypeError): galsim.RandomWalk(*args, **kwargs) # try sending wrong type for npoints npoints = [35] hlr = 8.0 args = (npoints, hlr) with assert_raises(TypeError): galsim.RandomWalk(*args) # try sending wrong type for hlr npoints = 100 hlr = [1.5] args = (npoints, hlr) with assert_raises(TypeError): galsim.RandomWalk(*args) # try sending wrong type for flux npoints = 100 hlr = 8.0 flux = [3.5] args = (npoints, hlr) kwargs = {'flux': flux} with assert_raises(TypeError): galsim.RandomWalk(*args, **kwargs) # send bad value for npoints npoints = -35 hlr = 8.0 args = (npoints, hlr) with assert_raises(ValueError): galsim.RandomWalk(*args) # try sending bad value for hlr npoints = 100 hlr = -1.5 args = (npoints, hlr) with assert_raises(ValueError): galsim.RandomWalk(*args) # try sending wrong type for flux npoints = 100 hlr = 8.0 flux = -35.0 args = (npoints, hlr) kwargs = {'flux': flux} with assert_raises(ValueError): galsim.RandomWalk(*args, **kwargs)
def test(ntrial=1, dim=2000, show=False): import galsim import biggles import images rng = np.random.RandomState() nobj_per = 4 nknots = 100 knot_flux_frac = 0.001 nknots_low, nknots_high = 1, 100 nband = 3 noises = [0.0005, 0.001, 0.0015] scale = 0.263 psf = galsim.Gaussian(fwhm=0.9) dims = 64, 64 flux_low, flux_high = 0.5, 1.5 r50_low, r50_high = 0.1, 2.0 fracdev_low, fracdev_high = 0.001, 0.99 bulge_colors = np.array([0.5, 1.0, 1.5]) disk_colors = np.array([1.25, 1.0, 0.75]) knots_colors = np.array([1.5, 1.0, 0.5]) sigma = dims[0]/2.0/4.0*scale maxrad = dims[0]/2.0/2.0 * scale tm0 = time.time() nobj_meas = 0 for trial in range(ntrial): print("trial: %d/%d" % (trial+1, ntrial)) all_band_obj = [] for i in range(nobj_per): nknots = int(rng.uniform(low=nknots_low, high=nknots_high)) r50 = rng.uniform(low=r50_low, high=r50_high) flux = rng.uniform(low=flux_low, high=flux_high) dx, dy = rng.normal(scale=sigma, size=2).clip( min=-maxrad, max=maxrad, ) g1d, g2d = rng.normal(scale=0.2, size=2).clip(max=0.5) g1b = 0.5*g1d+rng.normal(scale=0.02) g2b = 0.5*g2d+rng.normal(scale=0.02) fracdev = rng.uniform(low=fracdev_low, high=fracdev_high) flux_bulge = fracdev*flux flux_disk = (1-fracdev)*flux flux_knots = nknots*knot_flux_frac*flux_disk print("fracdev:", fracdev, "nknots:", nknots) bulge_obj = galsim.DeVaucouleurs( half_light_radius=r50 ).shear(g1=g1b, g2=g2b) disk_obj = galsim.Exponential( half_light_radius=r50 ).shear(g1=g1d, g2=g2d) knots_obj = galsim.RandomWalk( npoints=nknots, profile=disk_obj, ) # .shear(g1=g1d, g2=g2d) band_objs = [] for band in range(nband): band_disk = disk_obj.withFlux(flux_disk*disk_colors[band]) band_bulge = bulge_obj.withFlux(flux_bulge*bulge_colors[band]) band_knots = knots_obj.withFlux(flux_knots*knots_colors[band]) obj = galsim.Sum(band_disk, band_bulge, band_knots).shift( dx=dx, dy=dy, ) obj = galsim.Convolve(obj, psf) band_objs.append(obj) all_band_obj.append(band_objs) jacob = ngmix.DiagonalJacobian( row=0, col=0, scale=scale, ) wcs = jacob.get_galsim_wcs() psfim = psf.drawImage(wcs=wcs).array psf_obs = get_psf_obs(psfim, jacob) dlist = [] for band in range(nband): band_objects = [o[band] for o in all_band_obj] obj = galsim.Sum(band_objects) im = obj.drawImage(nx=dims[1], ny=dims[0], wcs=wcs).array im = obj.drawImage(nx=dims[1], ny=dims[0], scale=scale).array im += rng.normal(scale=noises[band], size=im.shape) wt = im*0 + 1.0/noises[band]**2 dlist.append( dict( image=im, weight=wt, wcs=wcs, ) ) mer = MEDSifier(dlist) mg = mer.get_meds(0) mr = mer.get_meds(1) mi = mer.get_meds(2) nobj = mg.size print(" found", nobj, "objects") nobj_meas += nobj list_of_obs = [] for i in range(nobj): gobslist = mg.get_obslist(i, weight_type='uberseg') robslist = mr.get_obslist(i, weight_type='uberseg') iobslist = mi.get_obslist(i, weight_type='uberseg') mbo = ngmix.MultiBandObsList() mbo.append(gobslist) mbo.append(robslist) mbo.append(iobslist) list_of_obs.append(mbo) for mbo in list_of_obs: for obslist in mbo: for obs in obslist: obs.set_psf(psf_obs) prior = moflib.get_mof_prior(list_of_obs, "bdf", rng) mof_fitter = moflib.MOFStamps( list_of_obs, "bdf", prior=prior, ) band = 2 guess = moflib.get_stamp_guesses(list_of_obs, band, "bdf", rng) mof_fitter.go(guess) if show: # corrected images tab = biggles.Table(1, 2) rgb = images.get_color_image( dlist[2]['image'].transpose(), dlist[1]['image'].transpose(), dlist[0]['image'].transpose(), nonlinear=0.1, ) rgb *= 1.0/rgb.max() tab[0, 0] = images.view_mosaic( [rgb, mer.seg, mer.detim], titles=['image', 'seg', 'detim'], show=False, # dims=[dim, dim], ) imlist = [] for iobj, mobs in enumerate(list_of_obs): cmobs = mof_fitter.make_corrected_obs(iobj) gim = images.make_combined_mosaic( [mobs[0][0].image, cmobs[0][0].image], ) rim = images.make_combined_mosaic( [mobs[1][0].image, cmobs[1][0].image], ) iim = images.make_combined_mosaic( [mobs[2][0].image, cmobs[2][0].image], ) rgb = images.get_color_image( iim.transpose(), rim.transpose(), gim.transpose(), nonlinear=0.1, ) rgb *= 1.0/rgb.max() imlist.append(rgb) plt = images.view_mosaic(imlist, show=False) tab[0, 1] = plt tab.show(width=dim*2, height=dim) if ntrial > 1: if 'q' == input("hit a key: "): return total_time = time.time()-tm0 print("time per group:", total_time/ntrial) print("time per object:", total_time/nobj_meas)