def _get_gals(self, mode, dx, dy): # mode = self['Mode'] #Cen = galsim.Gaussian(half_light_radius=self['Cen']['hlr'],flux=self['Cen']['Flux']) #Neigh = galsim.Exponential(half_light_radius=self['Neigh']['hlr'],flux=self['Neigh']['Flux']) n = rng.uniform(low=0.5, high=4) Cen = galsim.Sersic(n, half_light_radius=self['Cen']['hlr'], flux=self['Cen']['Flux']) n = rng.uniform(low=0.5, high=4) Neigh = galsim.Sersic(n, half_light_radius=self['Neigh']['hlr'], flux=self['Neigh']['Flux']) Cen = Cen.shear(g1=np.random.normal(scale=0.02), g2=np.random.normal(scale=0.02)) Neigh = Neigh.shear(g1=np.random.normal(scale=0.02), g2=np.random.normal(scale=0.02)) #cen position if self['Cen']['Pos'] == 'Fixed': dx1, dy1 = self['Cen']['dx'], self['Cen']['dy'] elif self['Cen']['Pos'] == 'Rand_Circle': r = self['Cen']['r'] theta = 2. * np.pi * np.random.random() dx1, dy1 = r * np.cos(theta), r * np.sin(theta) #neigh position if self['Neigh']['Pos'] == 'Fixed': dx2, dy2 = self['Neigh']['dx'], self['Neigh']['dy'] elif self['Neigh']['Pos'] == 'Rand_circle': r = self['Neigh']['r'] theta = 2. * np.pi * np.random.random() dx2, dy2 = r * np.cos(theta), r * np.sin(theta) dx1 += np.random.uniform(low=-0.5, high=0.5) dy1 += np.random.uniform(low=-0.5, high=0.5) dx2 += np.random.uniform(low=-0.5, high=0.5) dy2 += np.random.uniform(low=-0.5, high=0.5) #Cen = Cen.shift(dx=dx1, dy=dy1) #Neigh = Neigh.shift(dx=dx2, dy=dy2) if mode == 'scarlet' or mode == 'minimof': Cen = Cen.shift(dx=dx1, dy=dy1) Neigh = Neigh.shift(dx=dx2, dy=dy2) gals = [Cen, Neigh] objs = galsim.Add(gals) elif mode == 'control': Cen = Cen.shift(dx=dx, dy=dy) gals = [Cen] objs = galsim.Add(gals) dx1, dy1 = dx, dy shear1, shear2 = self['Shear']['Shear1'], self['Shear']['Shear2'] #objs = objs.shear(g1=shear1, g2=shear2) return objs, dx1, dy1, dx2, dy2
def test_add_flux_scaling(): """Test flux scaling for Add. """ import time t1 = time.time() # decimal point to go to for parameter value comparisons param_decimal = 12 # init with Gaussian and Exponential only (should be ok given last tests) obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5), galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)]) obj *= 2. np.testing.assert_almost_equal( obj.getFlux(), test_flux * 2., decimal=param_decimal, err_msg="Flux param inconsistent after __imul__.") obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5), galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)]) obj /= 2. np.testing.assert_almost_equal( obj.getFlux(), test_flux / 2., decimal=param_decimal, err_msg="Flux param inconsistent after __idiv__.") obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5), galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)]) obj2 = obj * 2. # First test that original obj is unharmed... (also tests that .copy() is working) np.testing.assert_almost_equal( obj.getFlux(), test_flux, decimal=param_decimal, err_msg="Flux param inconsistent after __rmul__ (original).") # Then test new obj2 flux np.testing.assert_almost_equal( obj2.getFlux(), test_flux * 2., decimal=param_decimal, err_msg="Flux param inconsistent after __rmul__ (result).") obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5), galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)]) obj2 = 2. * obj # First test that original obj is unharmed... (also tests that .copy() is working) np.testing.assert_almost_equal( obj.getFlux(), test_flux, decimal=param_decimal, err_msg="Flux param inconsistent after __mul__ (original).") # Then test new obj2 flux np.testing.assert_almost_equal( obj2.getFlux(), test_flux * 2., decimal=param_decimal, err_msg="Flux param inconsistent after __mul__ (result).") obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5), galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)]) obj2 = obj / 2. # First test that original obj is unharmed... (also tests that .copy() is working) np.testing.assert_almost_equal( obj.getFlux(), test_flux, decimal=param_decimal, err_msg="Flux param inconsistent after __div__ (original).") # Then test new obj2 flux np.testing.assert_almost_equal( obj2.getFlux(), test_flux / 2., decimal=param_decimal, err_msg="Flux param inconsistent after __div__ (result).") t2 = time.time() print 'time for %s = %.2f'%(funcname(),t2-t1)
def test_autocorrelate(): """Test that auto-correlation works the same as convolution with the mirror image of itself. (See the Signal processing Section of http://en.wikipedia.org/wiki/Autocorrelation) """ import time t1 = time.time() # Use a function that is NOT two-fold rotationally symmetric, e.g. two different flux Gaussians myGauss1 = galsim.SBGaussian(sigma=3., flux=4) myGauss1.applyShift(-0.2, -0.4) myGauss2 = (galsim.SBGaussian(sigma=6., flux=1.3)) myGauss2.applyShift(0.3, 0.3) mySBP1 = galsim.SBAdd([myGauss1, myGauss2]) mySBP2 = galsim.SBAdd([myGauss1, myGauss2]) # Here we rotate by 180 degrees to create mirror image mySBP2.applyRotation(180. * galsim.degrees) myConv = galsim.SBConvolve([mySBP1, mySBP2]) myImg1 = galsim.ImageF(80, 80, scale=0.7) myConv.draw(myImg1.view()) myAutoCorr = galsim.SBAutoCorrelate(mySBP1) myImg2 = galsim.ImageF(80, 80, scale=0.7) myAutoCorr.draw(myImg2.view()) printval(myImg1, myImg2) np.testing.assert_array_almost_equal( myImg1.array, myImg2.array, 4, err_msg= "Asymmetric sum of Gaussians convolved with mirror of self disagrees with " + "SBAutoCorrelate result") # Repeat with the GSObject version of this: obj1 = galsim.Gaussian(sigma=3., flux=4) obj1.applyShift(-0.2, -0.4) obj2 = galsim.Gaussian(sigma=6., flux=1.3) obj2.applyShift(0.3, 0.3) add1 = galsim.Add(obj1, obj2) add2 = (galsim.Add(obj1, obj2)).createRotated(180. * galsim.degrees) conv = galsim.Convolve([add1, add2]) conv.draw(myImg1) corr = galsim.AutoCorrelate(add1) corr.draw(myImg2) printval(myImg1, myImg2) np.testing.assert_array_almost_equal( myImg1.array, myImg2.array, 4, err_msg= "Asymmetric sum of Gaussians convolved with mirror of self disagrees with " + "AutoCorrelate result") # Test photon shooting. do_shoot(corr, myImg2, "AutoCorrelate") t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
def test_add_flux_scaling(): """Test flux scaling for Add. """ # decimal point to go to for parameter value comparisons param_decimal = 12 test_flux = 17.9 test_sigma = 1.8 test_scale = 1.9 # init with Gaussian and Exponential only (should be ok given last tests) obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5), galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)]) obj *= 2. np.testing.assert_almost_equal( obj.flux, test_flux * 2., decimal=param_decimal, err_msg="Flux param inconsistent after __imul__.") obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5), galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)]) obj /= 2. np.testing.assert_almost_equal( obj.flux, test_flux / 2., decimal=param_decimal, err_msg="Flux param inconsistent after __idiv__.") obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5), galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)]) obj2 = obj * 2. # First test that original obj is unharmed... np.testing.assert_almost_equal( obj.flux, test_flux, decimal=param_decimal, err_msg="Flux param inconsistent after __rmul__ (original).") # Then test new obj2 flux np.testing.assert_almost_equal( obj2.flux, test_flux * 2., decimal=param_decimal, err_msg="Flux param inconsistent after __rmul__ (result).") obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5), galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)]) obj2 = 2. * obj # First test that original obj is unharmed... np.testing.assert_almost_equal( obj.flux, test_flux, decimal=param_decimal, err_msg="Flux param inconsistent after __mul__ (original).") # Then test new obj2 flux np.testing.assert_almost_equal( obj2.flux, test_flux * 2., decimal=param_decimal, err_msg="Flux param inconsistent after __mul__ (result).") obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5), galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)]) obj2 = obj / 2. # First test that original obj is unharmed... np.testing.assert_almost_equal( obj.flux, test_flux, decimal=param_decimal, err_msg="Flux param inconsistent after __div__ (original).") # Then test new obj2 flux np.testing.assert_almost_equal( obj2.flux, test_flux / 2., decimal=param_decimal, err_msg="Flux param inconsistent after __div__ (result).")
def _get_band_obj(self, Cen, Neigh, cen_sed, neigh_sed): mode = self['Mode'] if mode == 'scarlet' or mode == 'mof': Cen = Cen * cen_sed Neigh = Neigh * neigh_sed gals = [Cen, Neigh] objs = galsim.Add(gals) elif mode == 'control': Cen = Cen * cen_sed gals = [Cen] objs = galsim.Add(gals) return objs
def _get_gals(self): mode = self['Mode'] rng = self.rng Cen = self._get_cen_model() Neigh = self._get_nbr_model() #cen position if self['Cen']['Pos'] == 'Fixed': dx1, dy1 = self['Cen']['dx'], self['Cen']['dy'] elif self['Cen']['Pos'] == 'Rand_Circle': r = self['Cen']['r'] theta = 2. * np.pi * np.random.random() dx1, dy1 = r * np.cos(theta), r * np.sin(theta) #neigh position if self['Neigh']['Pos'] == 'Fixed': dx2, dy2 = self['Neigh']['dx'], self['Neigh']['dy'] elif self['Neigh']['Pos'] == 'Rand_circle': r = self['Neigh']['r'] theta = 2. * np.pi * np.random.random() dx2, dy2 = r * np.cos(theta), r * np.sin(theta) dx1 += np.random.uniform(low=-0.5, high=0.5) dy1 += np.random.uniform(low=-0.5, high=0.5) dx2 += np.random.uniform(low=-0.5, high=0.5) dy2 += np.random.uniform(low=-0.5, high=0.5) Cen = Cen.shift(dx=dx1, dy=dy1) Neigh = Neigh.shift(dx=dx2, dy=dy2) if mode == 'scarlet' or mode == 'mof': gals = [Cen, Neigh] objs = galsim.Add(gals) elif mode == 'control': gals = [Cen] objs = galsim.Add(gals) shear_spec = self['Shear'] shear1, shear2 = shear_spec['Shear1'], shear_spec['Shear2'] objs = objs.shear(g1=shear1, g2=shear2) if 'Extra_Shear' in shear_spec: if 'shear+' in shear_spec['Extra_Shear']: objs = objs.shear(g1=shear_spec['Extra_Shear']['shear+'], g2=0.0) elif 'shear-' in shear_spec['Extra_Shear']: objs = objs.shear(g1=shear_spec['Extra_Shear']['shear-'], g2=0.0) return objs, dx1, dy1, dx2, dy2
def main(): for profile, exactGal, nComponents, maxRadius in PROFILES: exactGal.applyShear(e1=E1, e2=E2) psf = galsim.Gaussian(sigma=PSF_SIGMA) exactObj = galsim.Convolve([exactGal, psf]) exactImage = exactObj.draw(dx=1.0) exactImage.write(profile + "-exact.fits") amplitudes, variances = lsst.shapelet.tractor.loadParameters( profile, nComponents, maxRadius) componentGals = [] for n, (amplitude, variance) in enumerate(zip(amplitudes, variances)): componentGal = galsim.Gaussian(flux=amplitude, sigma=GALAXY_RADIUS * variance**0.5) componentGal.applyShear(e1=E1, e2=E2) componentGals.append(componentGal) if MAKE_COMPONENT_IMAGES: componentObj = galsim.Convolve([componentGal, psf]) componentImage = galsim.ImageD(exactImage.bounds) componentObj.draw(componentImage, dx=1.0) componentImage.write("%s-approx-%0d.fits" % (profile, n)) approxGal = galsim.Add(componentGals) approxObj = galsim.Convolve([approxGal, psf]) approxImage = galsim.ImageD(exactImage.bounds) approxObj.draw(approxImage, dx=1.0) approxImage.write(profile + "-approx.fits") f1 = galsim.Add([ makeGaussian(flux=0.600000, e1=0.09090909, e2=0.36363636, sigma=2.25810086), makeGaussian(flux=0.400000, e1=-0.11111111, e2=-0.11111111, sigma=2.98130750), ]) f2 = galsim.Add([ makeGaussian(flux=0.350000, e1=-0.26315789, e2=-0.21052632, sigma=2.99069756), makeGaussian(flux=0.650000, e1=-0.12500000, e2=0.12500000, sigma=2.80606626), ]) f3 = galsim.Convolve([f1, f2]) image = galsim.ImageD(galsim.BoundsI(-20, 20, -20, 20)) f3.draw(image, dx=1.0) image.write("gaussians.fits")
def test_autocorrelate(): """Test that auto-correlation works the same as convolution with the mirror image of itself. (See the Signal processing Section of http://en.wikipedia.org/wiki/Autocorrelation) """ dx = 0.7 myImg1 = galsim.ImageF(80, 80, scale=dx) myImg1.setCenter(0, 0) myImg2 = galsim.ImageF(80, 80, scale=dx) myImg2.setCenter(0, 0) # Use a function that is NOT two-fold rotationally symmetric, e.g. two different flux Gaussians obj1 = galsim.Gaussian(sigma=3., flux=4).shift(-0.2, -0.4) obj2 = galsim.Gaussian(sigma=6., flux=1.3).shift(0.3, 0.3) add1 = galsim.Add(obj1, obj2) # Here we rotate by 180 degrees to create mirror image add2 = (galsim.Add(obj1, obj2)).rotate(180. * galsim.degrees) conv = galsim.Convolve([add1, add2]) conv.drawImage(myImg1, method='no_pixel') corr = galsim.AutoCorrelate(add1) corr.drawImage(myImg2, method='no_pixel') printval(myImg1, myImg2) np.testing.assert_array_almost_equal( myImg1.array, myImg2.array, 4, err_msg= "Asymmetric sum of Gaussians convolved with mirror of self disagrees with " + "AutoCorrelate result") check_basic(conv, "AutoCorrelate") # Test photon shooting. do_shoot(corr, myImg2, "AutoCorrelate") # Check picklability do_pickle(corr, lambda x: x.drawImage(method='no_pixel')) do_pickle(corr) # Should raise an exception for invalid arguments assert_raises(TypeError, galsim.AutoCorrelate) assert_raises(TypeError, galsim.AutoCorrelate, myImg1) assert_raises(TypeError, galsim.AutoCorrelate, [obj1]) assert_raises(TypeError, galsim.AutoCorrelate, obj1, obj2) assert_raises(TypeError, galsim.AutoCorrelate, obj1, realspace=False) assert_raises(TypeError, galsim.AutoCorrelation) assert_raises(TypeError, galsim.AutoCorrelation, myImg1) assert_raises(TypeError, galsim.AutoCorrelation, [obj1]) assert_raises(TypeError, galsim.AutoCorrelation, obj1, obj2) assert_raises(TypeError, galsim.AutoCorrelation, obj1, realspace=False)
def _BuildAdd(config, key, base, ignore, gsparams, logger): """@brief Build a Sum object. """ req = {'items': list} opt = {'flux': float} # Only Check, not Get. We need to handle items a bit differently, since it's a list. galsim.config.CheckAllParams(config, key, req=req, opt=opt, ignore=ignore) gsobjects = [] items = config['items'] if not isinstance(items, list): raise AttributeError("items entry for config.%s entry is not a list." % type) safe = True for i in range(len(items)): gsobject, safe1 = BuildGSObject(items, i, base, gsparams, logger) # Skip items with flux=0 if 'flux' in items[i] and galsim.config.value.GetCurrentValue( items[i], 'flux') == 0.: if logger: logger.debug('obj %d: Not including component with flux == 0', base['obj_num']) continue safe = safe and safe1 gsobjects.append(gsobject) if len(gsobjects) == 0: raise ValueError("No valid items for %s" % key) elif len(gsobjects) == 1: gsobject = gsobjects[0] else: # Special: if the last item in a Sum doesn't specify a flux, we scale it # to bring the total flux up to 1. if ('flux' not in items[-1]) and all('flux' in item for item in items[0:-1]): sum = 0 for item in items[0:-1]: sum += galsim.config.value.GetCurrentValue(item, 'flux') f = 1. - sum if (f < 0): import warnings warnings.warn( "Automatically scaling the last item in Sum to make the total flux\n" + "equal 1 requires the last item to have negative flux = %f" % f) gsobjects[-1] = gsobjects[-1].withFlux(f) if gsparams: gsparams = galsim.GSParams(**gsparams) else: gsparams = None gsobject = galsim.Add(gsobjects, gsparams=gsparams) if 'flux' in config: flux, safe1 = galsim.config.ParseValue(config, 'flux', base, float) if logger: logger.debug('obj %d: flux == %f', base['obj_num'], flux) gsobject = gsobject.withFlux(flux) safe = safe and safe1 return gsobject, safe
def _generate_bd( hlr, flux, vary=False, rng=None, max_bulge_shift_frac=0.1, # fraction of hlr max_bulge_rot=np.pi / 4, ): if vary: bulge_frac = _generate_bulge_frac(rng) else: bulge_frac = 0.5 disk_frac = (1.0 - bulge_frac) bulge = DeVaucouleurs(half_light_radius=hlr, flux=flux * bulge_frac) disk = Exponential(half_light_radius=hlr, flux=flux * disk_frac) if vary: bulge = _shift_bulge(rng, bulge, hlr, max_bulge_shift_frac) if vary: g1disk, g2disk = _generate_g1g2(rng) g1bulge, g2bulge = g1disk, g2disk if vary: g1bulge, g2bulge = _rotate_bulge(rng, max_bulge_rot, g1bulge, g2bulge) bulge = bulge.shear(g1=g1bulge, g2=g2bulge) disk = disk.shear(g1=g1disk, g2=g2disk) return galsim.Add(bulge, disk)
def create_source(self, fractions, half_light_radius, minor_major_axis_ratio, position_angle): """Create a model for the on-sky profile of a single source. Size and shape parameter values for any component that is not present (because its fraction is zero) are ignored. Parameters ---------- fractions : array Array of length 2 giving the disk and bulge fractions, respectively, which must be in the range [0,1] (but this is not checked). If their sum is less than one, the remainder is modeled as a point-like component. half_light_radius : array Array of length 2 giving the disk and bulge half-light radii in arcseconds, respectively. minor_major_axis_ratio : array Array of length 2 giving the dimensionless on-sky ellipse minor / major axis ratio for the disk and bulge components, respectively. position_angle : array Array of length 2 giving the position angle in degrees of the on-sky disk and bluge ellipses, respectively. Angles are measured counter clockwise relative to the +x axis. Returns ------- galsim.GSObject A object representing the sum of all requested components with its total flux normalized to one. """ # This is a no-op but still required to define the namespace. import galsim components = [] if fractions[0] > 0: # Disk component components.append( galsim.Exponential( flux=fractions[0], half_light_radius=half_light_radius[0]).shear( q=minor_major_axis_ratio[0], beta=position_angle[0] * galsim.degrees)) if fractions[1] > 0: components.append( galsim.DeVaucouleurs( flux=fractions[1], half_light_radius=half_light_radius[1]).shear( q=minor_major_axis_ratio[1], beta=position_angle[1] * galsim.degrees)) star_fraction = 1 - fractions.sum() if star_fraction > 0: # Model a point-like source with a tiny (0.001 arcsec) Gaussian. # TODO: sigma should be in arcsec here, not microns! components.append( galsim.Gaussian(flux=star_fraction, sigma=1e-3 * self.image.scale)) # Combine the components and transform to focal-plane microns. return galsim.Add(components, gsparams=self.gsparams)
def createSource(self, galaxyIndex, shifted=False, lensed=False): """ Returns a GalSim model of the source for the specified galaxy index with optional centroid shifts and weak lensing distortion. """ params = self.getTruthCatalog()[galaxyIndex] # Create the bulge component. bulge = galsim.Sersic(flux=params['bulge_flux'], half_light_radius=params['bulge_hlr'], n=params['bulge_n'], gsparams=Observation.getGSParams()) bulge.applyShear(q=params['bulge_q'], beta=params['bulge_beta_radians'] * galsim.radians) # Is there a disk component? if params['disk_flux'] > 0: disk = galsim.Exponential(flux=params['disk_flux'], half_light_radius=params['disk_hlr'], gsparams=Observation.getGSParams()) disk.applyShear(q=params['disk_q'], beta=params['disk_beta_radians'] * galsim.radians) source = galsim.Add(bulge, disk) else: source = bulge # Apply optional lensing. if lensed: source = source.lens(g1=params['g1'], g2=params['g2'], mu=params['mu']) # Apply optional centroid shift. if shifted: source = source.shift(dx=params['xshift'] * self.pixelScale, dy=params['yshift'] * self.pixelScale) return source
def whiten(self, profiles, image, config, base, logger): """ Whiten the noise on the stamp according to the existing noise in all the profiles. """ total = galsim.Add(profiles) return super(BlendBuilder, self).whiten(total, image, config, base, logger)
def _BuildAdd(config, base, ignore, gsparams, logger): """@brief Build a Sum object. """ req = {'items': list} opt = {'flux': float} # Only Check, not Get. We need to handle items a bit differently, since it's a list. galsim.config.CheckAllParams(config, req=req, opt=opt, ignore=ignore) gsobjects = [] items = config['items'] if not isinstance(items, list): raise AttributeError("items entry for type=Add is not a list.") safe = True for i in range(len(items)): gsobject, safe1 = BuildGSObject(items, i, base, gsparams, logger) # Skip items with flux=0 if 'flux' in items[i] and galsim.config.GetCurrentValue( 'flux', items[i], float, base) == 0.: logger.debug('obj %d: Not including component with flux == 0', base.get('obj_num', 0)) continue safe = safe and safe1 gsobjects.append(gsobject) if len(gsobjects) == 0: raise ValueError("No valid items for type=Add") elif len(gsobjects) == 1: gsobject = gsobjects[0] else: # Special: if the last item in a Sum doesn't specify a flux, we scale it # to bring the total flux up to 1. if ('flux' not in items[-1]) and all('flux' in item for item in items[0:-1]): sum_flux = 0 for item in items[0:-1]: sum_flux += galsim.config.GetCurrentValue( 'flux', item, float, base) f = 1. - sum_flux if (f < 0): logger.warning( "Warning: Automatic flux for the last item in Sum (to make the total flux=1) " "resulted in negative flux = %f for that item" % f) logger.debug( 'obj %d: Rescaling final object in sum to have flux = %f', base.get('obj_num', 0), f) gsobjects[-1] = gsobjects[-1].withFlux(f) if gsparams: gsparams = galsim.GSParams(**gsparams) else: gsparams = None gsobject = galsim.Add(gsobjects, gsparams=gsparams) if 'flux' in config: flux, safe1 = galsim.config.ParseValue(config, 'flux', base, float) logger.debug('obj %d: flux == %f', base.get('obj_num', 0), flux) gsobject = gsobject.withFlux(flux) safe = safe and safe1 return gsobject, safe
def _generate_bdk( hlr, flux, vary=False, rng=None, gsrng=None, knots_hlr_frac=0.25, max_knots_disk_frac=0.1, # fraction of disk light max_bulge_shift_frac=0.1, # fraction of hlr max_bulge_rot=np.pi / 4, ): if vary: bulge_frac = _generate_bulge_frac(rng) else: bulge_frac = 0.5 all_disk_frac = (1.0 - bulge_frac) knots_hlr = knots_hlr_frac * hlr if vary: knots_sub_frac = _generate_knots_sub_frac(rng, max_knots_disk_frac) else: knots_sub_frac = max_knots_disk_frac disk_frac = (1 - knots_sub_frac) * all_disk_frac knots_frac = knots_sub_frac * all_disk_frac bulge = DeVaucouleurs(half_light_radius=hlr, flux=flux * bulge_frac) disk = Exponential(half_light_radius=hlr, flux=flux * disk_frac) if gsrng is None: # fixed galaxy, so fix the rng gsrng = galsim.BaseDeviate(123) knots = galsim.RandomKnots( npoints=10, half_light_radius=knots_hlr, flux=flux * knots_frac, rng=gsrng, ) if vary: bulge = _shift_bulge(rng, bulge, hlr, max_bulge_shift_frac) if vary: g1disk, g2disk = _generate_g1g2(rng) g1bulge, g2bulge = g1disk, g2disk if vary: g1bulge, g2bulge = _rotate_bulge(rng, max_bulge_rot, g1bulge, g2bulge) bulge = bulge.shear(g1=g1bulge, g2=g2bulge) disk = disk.shear(g1=g1disk, g2=g2disk) knots = knots.shear(g1=g1disk, g2=g2disk) return galsim.Add(bulge, disk, knots)
def test_autocorrelate(): """Test that auto-correlation works the same as convolution with the mirror image of itself. (See the Signal processing Section of http://en.wikipedia.org/wiki/Autocorrelation) """ import time t1 = time.time() dx = 0.7 myImg1 = galsim.ImageF(80, 80, scale=dx) myImg1.setCenter(0, 0) myImg2 = galsim.ImageF(80, 80, scale=dx) myImg2.setCenter(0, 0) # Use a function that is NOT two-fold rotationally symmetric, e.g. two different flux Gaussians obj1 = galsim.Gaussian(sigma=3., flux=4).shift(-0.2, -0.4) obj2 = galsim.Gaussian(sigma=6., flux=1.3).shift(0.3, 0.3) add1 = galsim.Add(obj1, obj2) # Here we rotate by 180 degrees to create mirror image add2 = (galsim.Add(obj1, obj2)).rotate(180. * galsim.degrees) conv = galsim.Convolve([add1, add2]) conv.drawImage(myImg1, method='no_pixel') corr = galsim.AutoCorrelate(add1) corr.drawImage(myImg2, method='no_pixel') printval(myImg1, myImg2) np.testing.assert_array_almost_equal( myImg1.array, myImg2.array, 4, err_msg= "Asymmetric sum of Gaussians convolved with mirror of self disagrees with " + "AutoCorrelate result") # Test photon shooting. do_shoot(corr, myImg2, "AutoCorrelate") # Check picklability do_pickle(corr.SBProfile, lambda x: (repr(x.getObj()), x.isRealSpace(), x.getGSParams())) do_pickle(corr, lambda x: x.drawImage(method='no_pixel')) do_pickle(corr) do_pickle(corr.SBProfile) t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
def make_image(self, iobj, band=0, obsnum=0, include_nbrs=False): """ make an image for the given band and observation number including nbrs is causing some trouble, probably due to the object being way off the stamp (why does it work for the fitter?) """ import galsim res = self.get_result() pars = res['pars'] obs = self.list_of_obs[iobj][band][obsnum] meta = obs.meta psf_meta = obs.psf.meta band_pars = self.get_object_band_pars( pars, iobj, band, ) central_model = self._make_fully_shifted_model(band_pars, obs) if include_nbrs: maxrad = self._get_maxrad(obs) nbr_models = self._get_nbr_models( iobj, pars, meta, band, maxrad, obs, ) else: nbr_models = [] if len(nbr_models) > 0: all_models = [central_model] + nbr_models total_model = galsim.Add( all_models, gsparams=self._gsp, ) else: total_model = central_model total_model = galsim.Convolve( total_model, psf_meta['ii'], gsparams=self._gsp, ) image = meta['model'].copy() self._do_draw(obs, total_model, image) return image.array
def make_bdf(half_light_radius=None, flux=None, fracdev=None, trunc=0.0, gsparams=None): """ a bulge+disk maker for equal hlr for bulge and disk Parameters ---------- half_light_radius: float hlr flux: float Total flux in the profile fracdev: float fraction of light in the bulge """ import galsim assert half_light_radius is not None, 'send half_light_ratio' assert flux is not None, 'send flux' assert fracdev is not None, 'send fracdev' if trunc > 0: flux_untruncated = True else: flux_untruncated = False """ bulge = galsim.DeVaucouleurs( half_light_radius=half_light_radius, flux=fracdev, flux_untruncated=flux_untruncated , trunc=trunc, gsparams=gsparams, ) """ bulge = galsim.Sersic( n=2, half_light_radius=half_light_radius, flux=fracdev, flux_untruncated=flux_untruncated, trunc=trunc, gsparams=gsparams, ) disk = galsim.Exponential( half_light_radius=half_light_radius, flux=(1 - fracdev), gsparams=gsparams, ) return galsim.Add( bulge, disk, gsparams=gsparams, ).withFlux(flux)
def star2gs(self, index, gsparams): # Convert from dict to actual GsParams object # TODO: Currently fails if gsparams isn't passed! if gsparams: gsp = galsim.GSParams(**gsparams) else: gsp = None # List of individual band GSObjects gsobjects = [] # Iterate over all desired bands for band in self.bands: if self.data_version == 'y3v02': # Needed for all mag calculations gmag = self.catalog['g_Corr'][index] # Grab current band magnitude if band == 'g': mag = gmag elif band == 'r': mag = gmag - self.catalog['gr_Corr'][index] elif band == 'i': mag = gmag - self.catalog['gr_Corr'][index] - self.catalog[ 'ri_Corr'][index] elif band == 'z': mag = gmag - self.catalog['gr_Corr'][index] - self.catalog['ri_Corr'][index] \ - self.catalog['iz_Corr'][index] else: raise ValueError( 'Band {} is not an allowed band input '.format(band) + 'for data_version of {}!'.format(self.data_version)) # Now convert to flux flux = np.power(10.0, 0.4 * (self.zeropoint - mag)) # (star cats calibrated at zp=30) # NOTE: Will just use `scale_flux` parameter in galsim config for now # flux_factor = ... # Stars are treated as a delta function, to be convolved w/ set PSF star = galsim.DeltaFunction(flux) else: # Should already be checked by this point, but just to be safe: raise ValueError( 'There is no implementation for `star2gs` for data_version ' + 'of {}'.format(self.data_version)) # Add galaxy in given band to list gsobjects.append(star) # NOTE: If multiple bands were passed, the fluxes are simply added together. gs_star = galsim.Add(gsobjects) return gs_star
def test_gsparams(): """Test withGSParams with some non-default gsparams """ obj1 = galsim.Exponential(half_light_radius=1.7) obj2 = galsim.Pixel(scale=0.2) gsp = galsim.GSParams(folding_threshold=1.e-4, maxk_threshold=1.e-4, maximum_fft_size=1.e4) gsp2 = galsim.GSParams(folding_threshold=1.e-2, maxk_threshold=1.e-2) sum = galsim.Sum(obj1, obj2) sum1 = sum.withGSParams(gsp) assert sum.gsparams == galsim.GSParams() assert sum1.gsparams == gsp assert sum1.obj_list[0].gsparams == gsp assert sum1.obj_list[1].gsparams == gsp sum2 = galsim.Sum(obj1.withGSParams(gsp), obj2.withGSParams(gsp)) sum3 = galsim.Sum(galsim.Exponential(half_light_radius=1.7, gsparams=gsp), galsim.Pixel(scale=0.2)) sum4 = galsim.Add(obj1, obj2, gsparams=gsp) assert sum != sum1 assert sum1 == sum2 assert sum1 == sum3 assert sum1 == sum4 print('stepk = ', sum.stepk, sum1.stepk) assert sum1.stepk < sum.stepk print('maxk = ', sum.maxk, sum1.maxk) assert sum1.maxk > sum.maxk sum5 = galsim.Add(obj1, obj2, gsparams=gsp, propagate_gsparams=False) assert sum5 != sum4 assert sum5.gsparams == gsp assert sum5.obj_list[0].gsparams == galsim.GSParams() assert sum5.obj_list[1].gsparams == galsim.GSParams() sum6 = sum5.withGSParams(gsp2) assert sum6 != sum5 assert sum6.gsparams == gsp2 assert sum6.obj_list[0].gsparams == galsim.GSParams() assert sum6.obj_list[1].gsparams == galsim.GSParams()
def make_galsim_object(self, gsparams=None): ''' Make a galsim representation for the gaussian mixture. NOTE: The only difference from Erin's original code is the type checking and passing of gsparams. This is especially useful for increasing fft sizes. ''' # Accept optional gsparams for GSObject construction if gsparams and (type(gsparams) is not galsim._galsim.GSParams): if type(gsparams) is dict: # Convert to actual gsparams object gsparams = galsim.GSParams(**gsparams) else: raise TypeError( 'Only `dict` and `galsim.GSParam` types allowed for' 'gsparams; input has {} type.'.format(type(gsparams))) data = self._get_gmix_data() row, col = self.get_cen() gsobjects = [] for i in xrange(len(self)): flux = data['p'][i] T = data['irr'][i] + data['icc'][i] # assert(T!=0.0) if T == 0: # TODO: Explore this issue more! T is being stored as nonzero - # what is causing this? continue e1 = (data['icc'][i] - data['irr'][i]) / T e2 = 2.0 * data['irc'][i] / T rowshift = data['row'][i] - row colshift = data['col'][i] - col g1, g2 = ngmix.shape.e1e2_to_g1g2(e1, e2) Tround = ngmix.moments.get_Tround(T, g1, g2) sigma_round = np.sqrt(Tround / 2.0) gsobj = galsim.Gaussian(flux=flux, sigma=sigma_round, gsparams=gsparams) gsobj = gsobj.shear(g1=g1, g2=g2) gsobj = gsobj.shift(colshift, rowshift) gsobjects.append(gsobj) gs_obj = galsim.Add(gsobjects) return gs_obj
def _get_bd_model(self, spec): rng = self.rng flux = spec['Flux'] fracdev = rng.uniform(low=0.0, high=1.0) bulge_flux = fracdev * flux disk_flux = (1.0 - fracdev) * flux disk_hlr = spec['hlr'] if 'bulge_size_factor' in spec: frange = spec['bulge_size_factor']['range'] bulge_hlr = disk_hlr * rng.uniform( low=frange[0], high=frange[1], ) else: bulge_hlr = disk_hlr if 'knots' in spec: disk_flux, knot_flux = self._split_flux_with_knots(spec, disk_flux) disk = galsim.Exponential( half_light_radius=disk_hlr, flux=disk_flux, ) bulge = galsim.DeVaucouleurs( half_light_radius=bulge_hlr, flux=bulge_flux, ) if 'knots' in spec: knots = self._get_knots(spec, disk_hlr, knot_flux) disk = galsim.Add([disk, knots]) disk = self._add_ellipticity(disk, spec) bulge = self._add_ellipticity(bulge, spec) return galsim.Add([disk, bulge])
def doubleSersic(xcen1, ycen1, flux1, reff1, nser1, q1, pa1, xcen2, ycen2, flux2, reff2, nser2, q2, pa2, nx, ny, psf=None, scale=1.0, exptime=1.0, trunc=0, max_fft=None): """Generate image for double Sersic component.""" ser = galsim.Add([ galsim.Sersic( n=nser1, half_light_radius=reff1, flux=(flux1 * exptime), trunc=trunc).shear(q=q1, beta=(0.0 * galsim.degrees)).rotate( (90.0 - pa1) * galsim.degrees).shift((xcen1 - (nx / 2.0)), (ycen1 - (ny / 2.0))), galsim.Sersic( n=nser2, half_light_radius=reff2, flux=(flux2 * exptime), trunc=trunc).shear(q=q2, beta=(0.0 * galsim.degrees)).rotate( (90.0 - pa2) * galsim.degrees).shift((xcen2 - (nx / 2.0)), (ycen2 - (ny / 2.0))) ]) if psf is not None: if max_fft is not None: gsparams = galsim.GSParams(maximum_fft_size=max_fft) return (galsim.Convolve([ser, psf], gsparams=gsparams).drawImage( nx=nx, ny=ny, method='no_pixel', scale=scale)).array else: return (galsim.Convolve([ser, psf]).drawImage(nx=nx, ny=ny, method='no_pixel', scale=scale)).array else: return (ser.drawImage(nx=nx, ny=ny, method='no_pixel', scale=scale)).array
def __init__(self, identifier, redshift, ab_magnitude, ri_color, cosmic_shear_g1, cosmic_shear_g2, dx_arcsecs, dy_arcsecs, beta_radians, disk_flux, disk_hlr_arcsecs, disk_q, bulge_flux, bulge_hlr_arcsecs, bulge_q, agn_flux): self.identifier = identifier self.redshift = redshift self.ab_magnitude = ab_magnitude self.ri_color = ri_color self.dx_arcsecs = dx_arcsecs self.dy_arcsecs = dy_arcsecs self.cosmic_shear_g1 = cosmic_shear_g1 self.cosmic_shear_g2 = cosmic_shear_g2 components = [] # Initialize second-moments tensor. Note that we can only add the tensors for the # n = 1,4 components, as we do below, since they have the same centroid. self.second_moments = np.zeros((2, 2)) total_flux = disk_flux + bulge_flux + agn_flux self.disk_fraction = disk_flux / total_flux self.bulge_fraction = bulge_flux / total_flux if disk_flux > 0: disk = galsim.Exponential( flux=disk_flux, half_light_radius=disk_hlr_arcsecs).shear( q=disk_q, beta=beta_radians * galsim.radians) components.append(disk) self.second_moments += self.disk_fraction * sersic_second_moments( n=1, hlr=disk_hlr_arcsecs, q=disk_q, beta=beta_radians) if bulge_flux > 0: bulge = galsim.DeVaucouleurs( flux=bulge_flux, half_light_radius=bulge_hlr_arcsecs).shear( q=bulge_q, beta=beta_radians * galsim.radians) components.append(bulge) self.second_moments += self.bulge_fraction * sersic_second_moments( n=1, hlr=bulge_hlr_arcsecs, q=bulge_q, beta=beta_radians) # GalSim does not currently provide a "delta-function" component to model the AGN # so we use a very narrow Gaussian. See this GalSim issue for details: # https://github.com/GalSim-developers/GalSim/issues/533 if agn_flux > 0: agn = galsim.Gaussian(flux=agn_flux, sigma=1e-8) components.append(agn) # Combine the components into our final profile. self.profile = galsim.Add(components) # Apply transforms to build the final model. self.model = self.get_transformed_model() # Shear the second moments, if necessary. if self.cosmic_shear_g1 != 0 or self.cosmic_shear_g2 != 0: self.second_moments = sheared_second_moments( self.second_moments, self.cosmic_shear_g1, self.cosmic_shear_g2)
def _get_images(self): """ get images without noise for each band """ import galsim gmodels = [] rmodels = [] imodels = [] odlist = [] for i in range(self['objects']['nobj']): band_models, odata = self._get_convolved_models() gmodels.append(band_models[0]) rmodels.append(band_models[1]) imodels.append(band_models[2]) odlist.append(odata) band_models = [ galsim.Add(gmodels), galsim.Add(rmodels), galsim.Add(imodels), ] iconf = self['image'] ny, nx = [iconf['dim_pixels']] * 2 band_images = [] for model in band_models: image = model.drawImage( nx=nx, ny=ny, scale=iconf['pixel_scale'], ).array band_images.append(image) obj_data = eu.numpy_util.combine_arrlist(odlist) return band_images, obj_data
def galSimAdd(galObjList, size=0, scale=1.0, method="auto", returnArr=False): """ Just add a list of GSObjs together using GalSim Make sure all elements in the input list are GSObjs """ if len(galObjList) < 2: raise Exception("Should be more than one GSObjs to add !") outObj = galsim.Add(galObjList) if returnArr: outArr = galSimDrawImage(outObj, size=size, scale=scale, method=method) return outArr else: return outObj
def _BuildAdd(config, key, base, ignore, gsparams): """@brief Build an Add object """ req = {'items': list} opt = {'flux': float} # Only Check, not Get. We need to handle items a bit differently, since it's a list. galsim.config.CheckAllParams(config, key, req=req, opt=opt, ignore=ignore) gsobjects = [] items = config['items'] if not isinstance(items, list): raise AttributeError("items entry for config.%s entry is not a list." % type) safe = True for i in range(len(items)): gsobject, safe1 = BuildGSObject(items, i, base, gsparams) safe = safe and safe1 gsobjects.append(gsobject) #print 'After built component items for ',type,' safe = ',safe # Special: if the last item in a Sum doesn't specify a flux, we scale it # to bring the total flux up to 1. if ('flux' not in items[-1]) and all('flux' in item for item in items[0:-1]): sum = 0 for item in items[0:-1]: sum += galsim.config.value.GetCurrentValue(item, 'flux') #print 'sum = ',sum f = 1. - sum #print 'f = ',f if (f < 0): import warnings warnings.warn( "Automatically scaling the last item in Sum to make the total flux\n" + "equal 1 requires the last item to have negative flux = %f" % f) gsobjects[-1].setFlux(f) if gsparams: gsparams = galsim.GSParams(**gsparams) else: gsparams = None gsobject = galsim.Add(gsobjects, gsparams=gsparams) if 'flux' in config: flux, safe1 = galsim.config.ParseValue(config, 'flux', base, float) #print 'flux = ',flux gsobject.setFlux(flux) safe = safe and safe1 return gsobject, safe
def add_lumps(self, n_regions, frac_gal_flux=0.05, frac_r_e=1.0, **kwargs): flux = self.gal.flux * frac_gal_flux r_e = self.pars.r_e.to('arcsec') * frac_r_e PA = self.pars.PA.value ell = self.pars.ell n = self.pars.n lumps = HIIRegions( n_regions=n_regions, flux=flux, PA=PA, r_e=r_e, ell=ell, sersic_n=n, **kwargs) self.gal = self.gal.withFlux(self.gal.flux * (1-frac_gal_flux)) self.gal = galsim.Add([self.gal, lumps]) self._original_gal = self.gal
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 render_galaxy( self, galaxy_params: Tensor, psf: galsim.GSObject, slen: int, offset: Optional[Tensor] = None, ) -> Tensor: assert offset is None or offset.shape == (2, ) if isinstance(galaxy_params, Tensor): galaxy_params = galaxy_params.cpu().detach() total_flux, disk_frac, beta_radians, disk_q, a_d, bulge_q, a_b = galaxy_params bulge_frac = 1 - disk_frac disk_flux = total_flux * disk_frac bulge_flux = total_flux * bulge_frac components = [] if disk_flux > 0: b_d = a_d * disk_q disk_hlr_arcsecs = np.sqrt(a_d * b_d) disk = galsim.Exponential( flux=disk_flux, half_light_radius=disk_hlr_arcsecs).shear( q=disk_q, beta=beta_radians * galsim.radians, ) components.append(disk) if bulge_flux > 0: b_b = bulge_q * a_b bulge_hlr_arcsecs = np.sqrt(a_b * b_b) bulge = galsim.DeVaucouleurs( flux=bulge_flux, half_light_radius=bulge_hlr_arcsecs).shear( q=bulge_q, beta=beta_radians * galsim.radians) components.append(bulge) galaxy = galsim.Add(components) gal_conv = galsim.Convolution(galaxy, psf) offset = offset if offset is None else offset.numpy() image = gal_conv.drawImage(nx=slen, ny=slen, method="auto", scale=self.pixel_scale, offset=offset) return torch.from_numpy(image.array).reshape(1, slen, slen)