def __mul__(self, other): if isinstance(other, galsim.GSObject): return galsim.Chromatic(other, self) # SEDs can be multiplied by scalars or functions (callables) wave_factor = 1.0 + self.redshift wave_type = 'nm' flux_type = 'fphotons' if hasattr(other, '__call__'): spec = lambda w: self._rest_photons(w) * other(w * wave_factor) elif isinstance(self._spec, galsim.LookupTable): # If other is not a function, then there is no loss of accuracy by applying the # factor directly to the LookupTable, if that's what we are using. # Make sure to keep the same properties about the table, flux_type, wave_type. if self.wave_factor == 10.0: wave_type = 'Angstroms' flux_type = self.flux_type x = self._spec.getArgs() f = [ val * other for val in self._spec.getVals() ] spec = galsim.LookupTable(x, f, x_log=self._spec.x_log, f_log=self._spec.f_log, interpolant=self._spec.interpolant) else: spec = lambda w: self._rest_photons(w) * other return SED(spec, flux_type=flux_type, wave_type=wave_type, redshift=self.redshift, _wave_list=self.wave_list, _blue_limit=self.blue_limit, _red_limit=self.red_limit)
def __mul__(self, other): if isinstance(other, galsim.GSObject): return galsim.Chromatic(other, self) # SEDs can be multiplied by scalars or functions (callables) ret = self.copy() if hasattr(other, '__call__'): wave_factor = 1.0 + self.redshift ret._rest_photons = lambda w: self._rest_photons(w) * other(w * wave_factor) else: ret._rest_photons = lambda w: self._rest_photons(w) * other return ret
def compare_image_integrators(): import galsim.integ import time pixel_scale = 0.2 stamp_size = 128 gal = galsim.Chromatic(galsim.Gaussian(half_light_radius=0.5), disk_SED) PSF_500 = galsim.Gaussian(half_light_radius=PSF_hlr) PSF = galsim.ChromaticAtmosphere(PSF_500, 500.0, zenith_angle) final = galsim.Convolve([gal, PSF]) image = galsim.ImageD(stamp_size, stamp_size, scale=pixel_scale) # truth flux x = np.union1d(disk_SED.wave_list, bandpass.wave_list) x = x[(x <= bandpass.red_limit) & (x >= bandpass.blue_limit)] target = np.trapz(disk_SED(x) * bandpass(x), x) print('target') print(' {:14.11f}'.format(target)) t1 = time.time() print('midpoint') for N in [10, 30, 100, 300, 1000, 3000]: image = final.drawImage(bandpass, image=image, integrator=galsim.integ.ContinuousIntegrator( rule=galsim.integ.midpt, N=N)) mom = silentgetmoments(image) outstring = ' {:4d} {:14.11f} {:14.11f} {:14.11f} {:14.11f} {:14.11f} {:14.11f} {:14.11f}' print( outstring.format(N, image.array.sum(), image.array.sum() - target, *mom)) t2 = time.time() print('time for midpoint = %.2f' % (t2 - t1)) print('trapezoidal') for N in [10, 30, 100, 300, 1000, 3000]: image = final.drawImage(bandpass, image=image, integrator=galsim.integ.ContinuousIntegrator( rule=np.trapz, N=N)) mom = silentgetmoments(image) outstring = ' {:4d} {:14.11f} {:14.11f} {:14.11f} {:14.11f} {:14.11f} {:14.11f} {:14.11f}' print( outstring.format(N, image.array.sum(), image.array.sum() - target, *mom)) t3 = time.time() print('time for trapezoidal = %.2f' % (t3 - t2))
def main(argv): # Where to find and output data path, filename = os.path.split(__file__) datapath = os.path.abspath(os.path.join(path, "data/")) outpath = os.path.abspath(os.path.join(path, "output/")) # In non-script code, use getLogger(__name__) at module scope instead. logging.basicConfig(format="%(message)s", level=logging.INFO, stream=sys.stdout) logger = logging.getLogger("demo12") # initialize (pseudo-)random number generator random_seed = 1234567 rng = galsim.BaseDeviate(random_seed) # read in SEDs SED_names = ['CWW_E_ext', 'CWW_Sbc_ext', 'CWW_Scd_ext', 'CWW_Im_ext'] SEDs = {} for SED_name in SED_names: SED_filename = os.path.join(galsim.meta_data.share_dir, '{0}.sed'.format(SED_name)) # Here we create some galsim.SED objects to hold star or galaxy spectra. The most # convenient way to create realistic spectra is to read them in from a two-column ASCII # file, where the first column is wavelength and the second column is flux. Wavelengths in # the example SED files are in Angstroms, flux in flambda. We use a set of files that are # distributed with GalSim in the share/ directory. SED = galsim.SED(SED_filename, wave_type='Ang', flux_type='flambda') # The normalization of SEDs affects how many photons are eventually drawn into an image. # One way to control this normalization is to specify the flux density in photons per nm # at a particular wavelength. For example, here we normalize such that the photon density # is 1 photon per nm at 500 nm. SEDs[SED_name] = SED.withFluxDensity(target_flux_density=1.0, wavelength=500) logger.debug('Successfully read in SEDs') # read in the LSST filters filter_names = 'ugrizy' filters = {} for filter_name in filter_names: filter_filename = os.path.join(datapath, 'LSST_{0}.dat'.format(filter_name)) # Here we create some galsim.Bandpass objects to represent the filters we're observing # through. These include the entire imaging system throughput including the atmosphere, # reflective and refractive optics, filters, and the CCD quantum efficiency. These are # also conveniently read in from two-column ASCII files where the first column is # wavelength and the second column is dimensionless throughput. The example filter files # units of nanometers for the wavelength type, so we specify that using the required # `wave_type` argument. filters[filter_name] = galsim.Bandpass(filter_filename, wave_type='nm') # For speed, we can thin out the wavelength sampling of the filter a bit. # In the following line, `rel_err` specifies the relative error when integrating over just # the filter (however, this is not necessarily the relative error when integrating over the # filter times an SED). filters[filter_name] = filters[filter_name].thin(rel_err=1e-4) logger.debug('Read in filters') pixel_scale = 0.2 # arcseconds #----------------------------------------------------------------------------------------------- # Part A: chromatic de Vaucouleurs galaxy # Here we create a chromatic version of a de Vaucouleurs profile using the Chromatic class. # This class lets one create chromatic versions of any galsim GSObject class. The first # argument is the GSObject instance to be chromaticized, and the second argument is the # profile's SED. logger.info('') logger.info('Starting part A: chromatic De Vaucouleurs galaxy') redshift = 0.8 mono_gal = galsim.DeVaucouleurs(half_light_radius=0.5) SED = SEDs['CWW_E_ext'].atRedshift(redshift) gal = galsim.Chromatic(mono_gal, SED) # You can still shear, shift, and dilate the resulting chromatic object. gal = gal.shear(g1=0.5, g2=0.3).dilate(1.05).shift((0.0, 0.1)) logger.debug('Created Chromatic') # convolve with PSF to make final profile PSF = galsim.Moffat(fwhm=0.6, beta=2.5) final = galsim.Convolve([gal, PSF]) logger.debug('Created final profile') # draw profile through LSST filters gaussian_noise = galsim.GaussianNoise(rng, sigma=0.1) for filter_name, filter_ in filters.iteritems(): img = galsim.ImageF(64, 64, scale=pixel_scale) final.drawImage(filter_, image=img) img.addNoise(gaussian_noise) logger.debug('Created {0}-band image'.format(filter_name)) out_filename = os.path.join(outpath, 'demo12a_{0}.fits'.format(filter_name)) galsim.fits.write(img, out_filename) logger.debug('Wrote {0}-band image to disk'.format(filter_name)) logger.info('Added flux for {0}-band image: {1}'.format( filter_name, img.added_flux)) logger.info( 'You can display the output in ds9 with a command line that looks something like:' ) logger.info( 'ds9 output/demo12a_*.fits -match scale -zoom 2 -match frame image &') #----------------------------------------------------------------------------------------------- # Part B: chromatic bulge+disk galaxy logger.info('') logger.info('Starting part B: chromatic bulge+disk galaxy') redshift = 0.8 # make a bulge ... mono_bulge = galsim.DeVaucouleurs(half_light_radius=0.5) bulge_SED = SEDs['CWW_E_ext'].atRedshift(redshift) # The `*` operator can be used as a shortcut for creating a chromatic version of a GSObject: bulge = mono_bulge * bulge_SED bulge = bulge.shear(g1=0.12, g2=0.07) logger.debug('Created bulge component') # ... and a disk ... mono_disk = galsim.Exponential(half_light_radius=2.0) disk_SED = SEDs['CWW_Im_ext'].atRedshift(redshift) disk = mono_disk * disk_SED disk = disk.shear(g1=0.4, g2=0.2) logger.debug('Created disk component') # ... and then combine them. bdgal = 1.1 * ( 0.8 * bulge + 4 * disk ) # you can add and multiply ChromaticObjects just like GSObjects bdfinal = galsim.Convolve([bdgal, PSF]) # Note that at this stage, our galaxy is chromatic but our PSF is still achromatic. Part C) # below will dive into chromatic PSFs. logger.debug('Created bulge+disk galaxy final profile') # draw profile through LSST filters gaussian_noise = galsim.GaussianNoise(rng, sigma=0.02) for filter_name, filter_ in filters.iteritems(): img = galsim.ImageF(64, 64, scale=pixel_scale) bdfinal.drawImage(filter_, image=img) img.addNoise(gaussian_noise) logger.debug('Created {0}-band image'.format(filter_name)) out_filename = os.path.join(outpath, 'demo12b_{0}.fits'.format(filter_name)) galsim.fits.write(img, out_filename) logger.debug('Wrote {0}-band image to disk'.format(filter_name)) logger.info('Added flux for {0}-band image: {1}'.format( filter_name, img.added_flux)) logger.info( 'You can display the output in ds9 with a command line that looks something like:' ) logger.info( 'ds9 -rgb -blue -scale limits -0.2 0.8 output/demo12b_r.fits -green -scale limits' + ' -0.25 1.0 output/demo12b_i.fits -red -scale limits -0.25 1.0 output/demo12b_z.fits' + ' -zoom 2 &') #----------------------------------------------------------------------------------------------- # Part C: chromatic PSF logger.info('') logger.info('Starting part C: chromatic PSF') redshift = 0.0 mono_gal = galsim.Exponential(half_light_radius=0.5) SED = SEDs['CWW_Im_ext'].atRedshift(redshift) # Here's another way to set the normalization of the SED. If we want 50 counts to be drawn # when observing an object with this SED through the LSST g-band filter, for instance, then we # can do: SED = SED.withFlux(50.0, filters['g']) # The flux drawn through other bands, which sample different parts of the SED and have different # throughputs, will, of course, be different. gal = mono_gal * SED gal = gal.shear(g1=0.5, g2=0.3) logger.debug('Created `Chromatic` galaxy') # For a ground-based PSF, two chromatic effects are introduced by the atmosphere: # (i) differential chromatic refraction (DCR), and (ii) wavelength-dependent seeing. # # DCR shifts the position of the PSF as a function of wavelength. Blue light is shifted # toward the zenith slightly more than red light. # # Kolmogorov turbulence in the atmosphere leads to a seeing size (e.g., FWHM) that scales with # wavelength to the (-0.2) power. # # The ChromaticAtmosphere function will attach both of these effects to a fiducial PSF at # some fiducial wavelength. # First we define a monochromatic PSF to be the fiducial PSF. PSF_500 = galsim.Moffat(beta=2.5, fwhm=0.5) # Then we use ChromaticAtmosphere to manipulate this fiducial PSF as a function of wavelength. # ChromaticAtmosphere also needs to know the wavelength of the fiducial PSF, and the location # and orientation of the object with respect to the zenith. This final piece of information # can be specified in several ways (see the ChromaticAtmosphere docstring for all of them). # Here are a couple ways: let's pretend our object is located near M101 on the sky, we observe # it 1 hour before it transits and we're observing from Mauna Kea. ra = galsim.HMS_Angle("14:03:13") # hours : minutes : seconds dec = galsim.DMS_Angle("54:20:57") # degrees : minutes : seconds m101 = galsim.CelestialCoord(ra, dec) latitude = 19.8207 * galsim.degrees # latitude of Mauna Kea HA = -1.0 * galsim.hours # Hour angle = one hour before transit # Then we can compute the zenith angle and parallactic angle (which is is the position angle # of the zenith measured from North through East) of this object: za, pa = galsim.dcr.zenith_parallactic_angles(m101, HA=HA, latitude=latitude) # And then finally, create the chromatic PSF PSF = galsim.ChromaticAtmosphere(PSF_500, 500.0, zenith_angle=za, parallactic_angle=pa) # We could have also just passed `m101`, `latitude` and `HA` to ChromaticAtmosphere directly: PSF = galsim.ChromaticAtmosphere(PSF_500, 500.0, obj_coord=m101, latitude=latitude, HA=HA) # and proceed like normal. # convolve with galaxy to create final profile final = galsim.Convolve([gal, PSF]) logger.debug('Created chromatic PSF finale profile') # Draw profile through LSST filters gaussian_noise = galsim.GaussianNoise(rng, sigma=0.03) for filter_name, filter_ in filters.iteritems(): img = galsim.ImageF(64, 64, scale=pixel_scale) final.drawImage(filter_, image=img) img.addNoise(gaussian_noise) logger.debug('Created {0}-band image'.format(filter_name)) out_filename = os.path.join(outpath, 'demo12c_{0}.fits'.format(filter_name)) galsim.fits.write(img, out_filename) logger.debug('Wrote {0}-band image to disk'.format(filter_name)) logger.info('Added flux for {0}-band image: {1}'.format( filter_name, img.added_flux)) logger.info( 'You can display the output in ds9 with a command line that looks something like:' ) logger.info( 'ds9 output/demo12c_*.fits -match scale -zoom 2 -match frame image -blink &' )
def main(argv): cat_file_name = 'real_galaxy_catalog_example.fits' dir = 'data' # Make output directory if not already present. if not os.path.isdir('output'): os.mkdir('output') cube_file_name = os.path.join('output', 'cube_real.fits') psf_file_name = os.path.join('output', 'psf_real.fits') random_seed = 1512413 sky_level = 1.e6 # ADU / arcsec^2 pixel_scale = 0.16 # arcsec gal_flux = 1.e5 # arbitrary choice, makes nice (not too) noisy images psf_inner_fwhm = 0.1 # arcsec psf_outer_fwhm = 0.6 # arcsec psf_inner_fraction = 0.8 # fraction of total PSF flux in the inner Gaussian psf_outer_fraction = 0.2 # fraction of total PSF flux in the inner Gaussian redshift = 0.05 ngal = 30 # SED ----------------------------------------------------- path, filename = os.path.split(__file__) datapath = os.path.abspath(os.path.join(path, "data/")) outpath = os.path.abspath(os.path.join(path, "output/")) random_seed = 1234567 rng = galsim.BaseDeviate(random_seed) # read in SEDs SED_names = ['CWW_E_ext', 'CWW_Sbc_ext', 'CWW_Scd_ext', 'CWW_Im_ext'] SEDs = {} for SED_name in SED_names: SED_filename = os.path.join(datapath, '{0}.sed'.format(SED_name)) SED = galsim.SED(SED_filename, wave_type='Ang') SEDs[SED_name] = SED.withFluxDensity(target_flux_density=1.0, wavelength=500) filter_names = 'gri' filters = {} for filter_name in filter_names: filter_filename = os.path.join(datapath, 'LSST_{0}.dat'.format(filter_name)) filters[filter_name] = galsim.Bandpass(filter_filename) filters[filter_name] = filters[filter_name].thin(rel_err=1e-4) #-------------------------------------------------------------------- real_galaxy_catalog = galsim.RealGalaxyCatalog(cat_file_name, dir=dir) psf = galsim.Gaussian(fwhm=psf_inner_fwhm, flux=psf_inner_fraction) # Draw the PSF with no noise. psf_image = psf.drawImage(scale=pixel_scale) # write to file psf_image.write(psf_file_name) # Build the images for k in range(ngal): # Initialize the random number generator we will be using. rng = galsim.UniformDeviate(random_seed + k) gal = galsim.RealGalaxy(real_galaxy_catalog, index=k) # Set the flux #gal = gal.withFlux(gal_flux) SED = SEDs['CWW_E_ext'].atRedshift(redshift) #SED = SEDs['CWW_Sbc_ext'].atRedshift(redshift) galcol = galsim.Chromatic(gal, SED) final = galsim.Convolve([galcol, psf]) dx = rng() - 0.5 dy = rng() - 0.5 # Draw the profile galcol = galsim.Chromatic(final, SED) for filter_name, filter_ in filters.iteritems(): img = galsim.ImageF(78, 78, scale=pixel_scale) final.drawImage(filter_, image=img) out_filename = os.path.join( outpath, 'realcolor_{0}_{1}.fits'.format(filter_name, str(k))) galsim.fits.write(img, out_filename)
frac = np.random.rand() bulge_frac = frac bulge = galsim.DeVaucouleurs(half_light_radius=dev_radius * scale) bulge = bulge.shear(e1=dev_e2, e2=dev_e2) flux = flux_pl.sample() gal = frac * bulge + (1 - frac) * disk redshift = np.random.rand() * max_redshift sed = np.random.choice(template_seds, 1)[0].atRedshift(redshift) #normalize flux according to specified filter sed = sed.withFlux(flux, filters[args.filter_norm]) mgal = galsim.Chromatic(gal, sed) cgal = galsim.Convolve([mgal, psf]) gtrue.rad = frac * dev_radius + (1 - frac) * exp_radius gtrue.sed = sed gtrue.redshift = redshift true_x.append(gtrue.x) true_y.append(gtrue.y) for filter_name, filter_ in filters.items(): tmp = cgal.drawImage(filter_, image=images[filter_name], add_to_image=True, offset=(offsetx, offsety))
def chromatic_galaxy(theta): gal_type,half_radius,pixel_scale,skyvar,redshift,e1,e2,indx =theta # where to find and output data path,filename = os.path.split(__file__) datapath = os.path.abspath(os.path.join(path,"data/")) outpath = os.path.abspath(os.path.join(path,"output/")) # In non-script code, use getLogger(__name__) at module scope instead logging.basicConfig(format="%(message)s",level=logging.INFO,stream=sys.stdout) logger = logging.getLogger("colored_images") # Initialize (pseudo-) random number generator random_seed = 1234567 rng = galsim.BaseDeviate(random_seed) # read in SEDs SED_names = ['CWW_E_ext','CWW_Sbc_ext','CWW_Scd_ext','CWW_Im_ext'] SEDs = {} for SED_name in SED_names: SED_filename = os.path.join(datapath,'{1}.sed'.format(SED_name)) SED = galsim.SED(SED_filename,wave_type='Ang') SEDs[SED_name] = SED.withFluxDensity(target_flux_density=1.0,wavelength=500) logger.debug('Successfully read in SEDs') filter_names = 'ugrizy' filters = {} for filter_name in filter_names: filter_filename = os.path.join(datapath,'LSST_{0}.dat'.format(filter_name)) filters[filter_name] = galsim.Bandpass(filter_filename) filters[filter_name] = filters[filter_name].thin(rel_err=1e-4) logger.debug('Read in filters') PSF = galsim.Moffat(fwhm=0.6,beta=2.5) #------------------------------------------------------------- # Part A: Chromatic de Vaucouleurs galaxy if gal_type == 'deVoucauleurs': logger.info('') logger.info('Starting part A: chromatic de Vaucouleurs galaxy') mono_gal = galsim.DeVaucouleurs(half_light_radius=half_radius) plt.imshow(mono_gal.drawImage(64,64).array) plt.show() SED = SEDs['CWW_E_ext'].atRedshift(redshift) gal = galsim.Chromatic(mono_gal,SED) gal = gal.shear(g1=0.5,g2=0.3).dilate(1.05).shift((1.0,2.1)) logger.debug('Created Chromatic') final = galsim.Convolve([gal,PSF]) logger.debug('Created final profile') gaussian_noise = galsim.GaussianNoise(rng,sigma=skyvar) for filter_name,filter_ in filters.iteritems(): img = galsim.ImageF(64,64,scale=pixel_scale) final.drawImage(filter_,image=img) #plt.imshow(final.drawImage(64,64).array) #plt.show() #img.addNoise(gaussian_noise) logger.debug('Created {0}-band image'.format(filter_name)) out_filename = os.path.join(outpath,'demo12a_{0}_{1}.fits'.format(filter_name,str(indx))) galsim.fits.write(img,out_filename) logger.debug('Wrote {0}-band image to disk'.format(filter_name)) logger.info('Added flux for {0}-band image:{1}'.format(filter_name,img.added_flux)) #----------------------------------------------------------------------- # PART B: chromatic bulge_disk galaxy if gal_type == 'diskbulge': logger.info('') logger.info('Starting part B: chromatic bulge_disk galaxy') mono_bulge = galsim.DeVaucouleurs(half_light_radius=0.05) bulge_SED = SEDs['CWW_E_ext'].atRedshift(redshift) bulge = mono_bulge * bulge_SED bulge = bulge.shear(g1=0.05,g2=0.07) logger.debug('Created bulge component') mono_disk = galsim.Exponential(half_light_radius=1.0) disk_SED = SEDs['CWW_Im_ext'].atRedshift(redshift) disk = mono_disk*disk_SED disk = disk.shear(g1=e1,g2=e2) logger.debug('Created disk component') bdgal = 1.1*(0.8*bulge+4.0*disk) bdfinal = galsim.Convolve([bdgal,PSF]) logger.debug('Created bulge+disk galaxy final profile') gaussian_noise = galsim.GaussianNoise(rng,sigma=skyvar) for filter_name,filter_ in filters.iteritems(): img = galsim.ImageF(64,64,scale=pixel_scale) bdfinal.drawImage(filter_,image=img) #img.addNoise(gaussian_noise) logger.debug('Created {0}-band image'.format(filter_name)) out_filename = os.path.join(outpath,'demo12b_{0}_{1}.fits'.format(filter_name,str(indx))) galsim.fits.write(img,out_filename) logger.debug('Wrote {0}-band image to disk'.format(filter_name)) logger.info('Added flux for {0}-band image:{1}'.format(filter_name,img.added_flux)) # PART C: chromatic real galaxy if gal_type == 'real': logger.info('') logger.info('Starting part B: chromatic bulge_disk galaxy') cubeimg = pf.getdata('cube_real.fits') idx = np.random.randint(low=0,high=99) imarr = cubeimg[idx,:,:] nx1,nx2 = np.shape(imarr) img = galsim.ImageF(nx1,nx2,scale=pixel_scale) bulge_SED = SEDs['CWW_E_ext'].atRedshift(redshift) bulge = mono_bulge * bulge_SED bulge = bulge.shear(g1=0.05,g2=0.07) logger.debug('Created bulge component') mono_disk = galsim.Exponential(half_light_radius=1.0) disk_SED = SEDs['CWW_Im_ext'].atRedshift(redshift) disk = mono_disk*disk_SED disk = disk.shear(g1=e1,g2=e2) logger.debug('Created disk component') bdgal = 1.1*(0.8*bulge+4.0*disk) bdfinal = galsim.Convolve([bdgal,PSF]) logger.debug('Created bulge+disk galaxy final profile') gaussian_noise = galsim.GaussianNoise(rng,sigma=skyvar) for filter_name,filter_ in filters.iteritems(): img = galsim.ImageF(64,64,scale=pixel_scale) bdfinal.drawImage(filter_,image=img) img.addNoise(gaussian_noise) logger.debug('Created {0}-band image'.format(filter_name)) out_filename = os.path.join(outpath,'demo12b_{0}_{1}.fits'.format(filter_name,str(indx))) galsim.fits.write(img,out_filename) logger.debug('Wrote {0}-band image to disk'.format(filter_name)) logger.info('Added flux for {0}-band image:{1}'.format(filter_name,img.added_flux))
frac = np.random.rand() bulge_frac = frac bulge = galsim.DeVaucouleurs(half_light_radius=dev_radius*scale) bulge = bulge.shear(e1=dev_e2, e2=dev_e2) flux = flux_pl.sample() gal = frac*bulge + (1-frac)*disk redshift = np.random.rand()*max_redshift sed = np.random.choice(templates_galaxy,1)[0].atRedshift(redshift) #normalize flux according to specified filter sed = sed.withFlux(flux, filters[args.filter_norm]) mgal = galsim.Chromatic(gal, sed) cgal = galsim.Convolve([mgal, psf]) gtrue.rad = frac*dev_radius+(1-frac)*exp_radius gtrue.sed = sed gtrue.redshift = redshift gtrue.is_star = False else: delta = galsim.Gaussian(sigma=1e-9) gtrue.rad = 0 sed = np.random.choice(templates_star,1)[0] gtrue.sed = sed gtrue.redshift = 0 gtrue.is_star = True