def test__centre_light_profile_on_grid_coordinate__peak_flux_is_correct_index( ): image_grid = grids.RegularGrid.from_shape_and_pixel_scale(shape=(5, 5), pixel_scale=1.0) sersic = lp.SphericalSersic(centre=(2.0, -2.0)) image_1d = sersic.intensities_from_grid(grid=image_grid) image_2d = image_grid.array_2d_from_array_1d(array_1d=image_1d) assert image_1d.argmax() == 0 assert np.unravel_index(image_2d.argmax(), image_2d.shape) == (0, 0) sersic = lp.SphericalSersic(centre=(2.0, 2.0)) image_1d = sersic.intensities_from_grid(grid=image_grid) image_2d = image_grid.array_2d_from_array_1d(array_1d=image_1d) assert image_1d.argmax() == 4 assert np.unravel_index(image_2d.argmax(), image_2d.shape) == (0, 4) sersic = lp.SphericalSersic(centre=(-2.0, -2.0)) image_1d = sersic.intensities_from_grid(grid=image_grid) image_2d = image_grid.array_2d_from_array_1d(array_1d=image_1d) assert image_1d.argmax() == 20 assert np.unravel_index(image_2d.argmax(), image_2d.shape) == (4, 0) sersic = lp.SphericalSersic(centre=(-2.0, 2.0)) image_1d = sersic.intensities_from_grid(grid=image_grid) image_2d = image_grid.array_2d_from_array_1d(array_1d=image_1d) assert image_1d.argmax() == 24 assert np.unravel_index(image_2d.argmax(), image_2d.shape) == (4, 4)
def test__within_circle__spherical_sersic_2__compare_to_grid(self): sersic = lp.SphericalSersic(intensity=3.0, effective_radius=2.0, sersic_index=2.0) integral_radius = 1.0 luminosity_tot = 0.0 xs = np.linspace(-1.5, 1.5, 40) ys = np.linspace(-1.5, 1.5, 40) edge = xs[1] - xs[0] area = edge**2 for x in xs: for y in ys: eta = math.sqrt(x**2 + y**2) if eta < integral_radius: luminosity_tot += sersic.intensities_from_grid_radii( eta) * area intensity_integral = sersic.luminosity_within_circle( radius=integral_radius) assert luminosity_tot == pytest.approx(intensity_integral, 0.02)
def pipeline(): lens_mass = mp.SphericalIsothermal(centre=(0.0, 0.0), einstein_radius=1.6) lens_subhalo = mp.SphericalIsothermal(centre=(1.0, 1.0), einstein_radius=0.0) source_light = lp.SphericalSersic(centre=(0.0, 0.0), intensity=1.0, effective_radius=0.5, sersic_index=1.0) lens_galaxy = galaxy.Galaxy(mass=lens_mass, subhalo=lens_subhalo) source_galaxy = galaxy.Galaxy(light=source_light) tools.reset_paths(test_name=test_name, output_path=output_path) tools.simulate_integration_image(test_name=test_name, pixel_scale=0.1, lens_galaxies=[lens_galaxy], source_galaxies=[source_galaxy], target_signal_to_noise=30.0) ccd_data = ccd.load_ccd_data_from_fits( image_path=path + '/data/' + test_name + '/image.fits', psf_path=path + '/data/' + test_name + '/psf.fits', noise_map_path=path + '/data/' + test_name + '/noise_map.fits', pixel_scale=0.1) pipeline = make_pipeline(test_name=test_name) result = pipeline.run(data=ccd_data) print(dir(result))
def test__within_circle__multiplies_by_conversion_factor(self): sersic = lp.SphericalSersic(intensity=3.0, effective_radius=2.0, sersic_index=1.0) integral_radius = 5.5 # Use gamma function for analytic computation of the intensity within a radius=0.5 x = sersic.sersic_constant * (integral_radius / sersic.effective_radius )**(1.0 / sersic.sersic_index) intensity_analytic = sersic.intensity * sersic.effective_radius**2 * 2 * math.pi * sersic.sersic_index * ( math.e**sersic.sersic_constant / (sersic.sersic_constant** (2 * sersic.sersic_index))) * scipy.special.gamma( 2 * sersic.sersic_index) * scipy.special.gammainc( 2 * sersic.sersic_index, x) intensity_integral = sersic.luminosity_within_circle( radius=integral_radius, conversion_factor=3.0) assert 3.0 * intensity_analytic == pytest.approx( intensity_integral, 1e-3)
def test__no_mass_profile__returns_none(self): gal = g.Galaxy(redshift=0.5, light=lp.SphericalSersic()) assert gal.mass_within_circle(radius=1.0, conversion_factor=1.0) == None assert gal.mass_within_ellipse(major_axis=1.0, conversion_factor=1.0) == None
def test__same_as_above__but_grid_is_padded_to_7x7_for_simulation(): data_grids = grids.GridStack.grid_stack_for_simulation(shape=(5, 5), pixel_scale=1.0, psf_shape=(3, 3)) sersic = lp.SphericalSersic(centre=(2.0, -2.0)) image_1d = sersic.intensities_from_grid(grid=data_grids.regular) assert image_1d.argmax() == 8 image_2d = data_grids.regular.array_2d_from_array_1d( padded_array_1d=image_1d) assert np.unravel_index(image_2d.argmax(), image_2d.shape) == (0, 0) image_2d = data_grids.regular.map_to_2d_keep_padded( padded_array_1d=image_1d) assert np.unravel_index(image_2d.argmax(), image_2d.shape) == (1, 1) sersic = lp.SphericalSersic(centre=(2.0, 2.0)) image_1d = sersic.intensities_from_grid(grid=data_grids.regular) assert image_1d.argmax() == 12 image_2d = data_grids.regular.array_2d_from_array_1d( padded_array_1d=image_1d) assert np.unravel_index(image_2d.argmax(), image_2d.shape) == (0, 4) image_2d = data_grids.regular.map_to_2d_keep_padded( padded_array_1d=image_1d) assert np.unravel_index(image_2d.argmax(), image_2d.shape) == (1, 5) sersic = lp.SphericalSersic(centre=(-2.0, -2.0)) image_1d = sersic.intensities_from_grid(grid=data_grids.regular) assert image_1d.argmax() == 36 image_2d = data_grids.regular.array_2d_from_array_1d( padded_array_1d=image_1d) assert np.unravel_index(image_2d.argmax(), image_2d.shape) == (4, 0) image_2d = data_grids.regular.map_to_2d_keep_padded( padded_array_1d=image_1d) assert np.unravel_index(image_2d.argmax(), image_2d.shape) == (5, 1) sersic = lp.SphericalSersic(centre=(-2.0, 2.0)) image_1d = sersic.intensities_from_grid(grid=data_grids.regular) assert image_1d.argmax() == 40 image_2d = data_grids.regular.array_2d_from_array_1d( padded_array_1d=image_1d) assert np.unravel_index(image_2d.argmax(), image_2d.shape) == (4, 4) image_2d = data_grids.regular.map_to_2d_keep_padded( padded_array_1d=image_1d) assert np.unravel_index(image_2d.argmax(), image_2d.shape) == (5, 5)
def test__spherical_and_elliptical_match(self): elliptical = lp.EllipticalSersic(axis_ratio=1.0, phi=0.0, intensity=3.0, effective_radius=2.0, sersic_index=2.0) spherical = lp.SphericalSersic(intensity=3.0, effective_radius=2.0, sersic_index=2.0) assert (elliptical.intensities_from_grid(grid) == spherical.intensities_from_grid(grid)).all()
def simulate_image_with_offset_centre_psf(): from autolens.data.array import grids from autolens.model.galaxy import galaxy as g from autolens.lens import ray_tracing psf = im.PSF.simulate_as_gaussian(shape=(21, 21), sigma=0.05, pixel_scale=0.1, centre=(0.1, 0.1)) image_plane_grids = grids.GridStack.grid_stack_for_simulation( shape=(100, 100), pixel_scale=0.1, psf_shape=(21, 21)) lens_galaxy = g.Galaxy(light=lp.SphericalSersic(centre=(0.0, 0.0), intensity=0.3, effective_radius=1.0, sersic_index=2.0), mass=mp.SphericalIsothermal(centre=(0.0, 0.0), einstein_radius=1.2)) source_galaxy = g.Galaxy(light=lp.SphericalSersic(centre=(0.0, 0.0), intensity=0.2, effective_radius=1.0, sersic_index=1.5)) tracer = ray_tracing.TracerImageSourcePlanes( lens_galaxies=[lens_galaxy], source_galaxies=[source_galaxy], image_plane_grid_stack=[image_plane_grids]) return im.CCDData.simulate(array=tracer.image_plane_image_for_simulation, pixel_scale=0.1, exposure_time=300.0, psf=psf, background_sky_level=0.1, add_noise=True)
def test__galaxy_data_intensities(self, image, mask): galaxy_data = gd.GalaxyData(image=image, noise_map=2.0 * np.ones((4, 4)), pixel_scale=3.0) galaxy_fit_data = gd.GalaxyFitData(galaxy_data=galaxy_data, mask=mask, sub_grid_size=2, use_intensities=True) assert galaxy_fit_data.pixel_scale == 3.0 assert (galaxy_fit_data.image == np.ones((4, 4))).all() assert (galaxy_fit_data.noise_map == 2.0 * np.ones((4, 4))).all() assert (galaxy_fit_data.mask == np.array([[True, True, True, True], [True, False, False, True], [True, False, False, True], [True, True, True, True]])).all() assert (galaxy_fit_data.image_1d == np.ones(4)).all() assert (galaxy_fit_data.noise_map_1d == 2.0 * np.ones(4)).all() assert (galaxy_fit_data.mask_1d == np.array( [False, False, False, False])).all() galaxy = MockGalaxy(value=1, shape=4) intensities = galaxy_fit_data.profile_quantity_from_galaxy_and_sub_grid( galaxies=[galaxy], sub_grid=galaxy_fit_data.grid_stack.sub) assert (intensities == np.array([1.0, 1.0, 1.0, 1.0])).all() galaxy = g.Galaxy(light=lp.SphericalSersic(intensity=1.0)) intensities_gal = galaxy.intensities_from_grid( grid=galaxy_fit_data.grid_stack.sub) intensities_gal = galaxy_fit_data.grid_stack.sub.sub_data_to_regular_data( sub_array=intensities_gal) intensities_gd = galaxy_fit_data.profile_quantity_from_galaxy_and_sub_grid( galaxies=[galaxy], sub_grid=galaxy_fit_data.grid_stack.sub) assert (intensities_gal == intensities_gd).all()
def simulate_lens_with_light_profile(): from autolens.data.array import grids from autolens.model.galaxy import galaxy as g from autolens.lens import ray_tracing psf = ccd.PSF.simulate_as_gaussian(shape=(11, 11), sigma=0.05, pixel_scale=0.05) image_plane_grid_stack = grids.GridStack.grid_stack_for_simulation( shape=(180, 180), pixel_scale=0.05, psf_shape=(11, 11)) lens_galaxy = g.Galaxy(light=lp.SphericalSersic(centre=(0.0, 0.0), intensity=0.2, effective_radius=0.8, sersic_index=4.0), mass=mp.EllipticalIsothermal(centre=(0.0, 0.0), axis_ratio=0.8, phi=135.0, einstein_radius=1.6)) source_galaxy = g.Galaxy(light=lp.EllipticalSersic(centre=(0.1, 0.1), axis_ratio=0.8, phi=90.0, intensity=0.2, effective_radius=0.3, sersic_index=1.0)) tracer = ray_tracing.TracerImageSourcePlanes( lens_galaxies=[lens_galaxy], source_galaxies=[source_galaxy], image_plane_grid_stack=image_plane_grid_stack) return ccd.CCDData.simulate(array=tracer.image_plane_image_for_simulation, pixel_scale=0.05, exposure_time=300.0, psf=psf, background_sky_level=0.1, add_noise=True)
def test__within_circle__spherical_dev_vaucouleurs__compare_to_analytic( self): sersic = lp.SphericalSersic(intensity=3.0, effective_radius=2.0, sersic_index=4.0) integral_radius = 0.5 # Use gamma function for analytic computation of the intensity within a radius=0.5 x = sersic.sersic_constant * ( (integral_radius / sersic.effective_radius) **(1.0 / sersic.sersic_index)) intensity_analytic = sersic.intensity * sersic.effective_radius ** 2 * 2 * math.pi * sersic.sersic_index * \ ((math.e ** sersic.sersic_constant) / ( sersic.sersic_constant ** (2 * sersic.sersic_index))) * \ scipy.special.gamma(2 * sersic.sersic_index) * scipy.special.gammainc( 2 * sersic.sersic_index, x) intensity_integral = sersic.luminosity_within_circle(radius=0.5) assert intensity_analytic == pytest.approx(intensity_integral, 1e-3)
# same way. Therefore, when determining their lensed images, we can sum the lensed images of each galaxy's light-profiles. # So, lets do it - lets use the 'plane' module in AutoLens to create a strong lensing system like the one pictured # above. For simplicity, we'll assume 1 lens galaxy and 1 source galaxy. # As always, we need grids, where our grids are the coordinates we'll 'trace' from the image-plane to the source-plane # in the lensing configuration above. Our grid-stack is therefore no longer just a 'grid-stack', but the grid-stack # representing our image-plane coordinates. Thus, lets name as such. image_plane_grid_stack = grids.GridStack.from_shape_pixel_scale_and_sub_grid_size(shape=(100, 100), pixel_scale=0.05, sub_grid_size=2) # Whereas before we called our galaxy's things like 'galaxy_with_light_profile', lets now refer to them by their role # in lensing, e.g. 'lens_galaxy' and 'source_galaxy'. mass_profile = mass_profiles.SphericalIsothermal(centre=(0.0, 0.0), einstein_radius=1.6) lens_galaxy = galaxy.Galaxy(mass=mass_profile) light_profile = light_profiles.SphericalSersic(centre=(0.0, 0.0), intensity=1.0, effective_radius=1.0, sersic_index=1.0) source_galaxy = galaxy.Galaxy(light=light_profile) # Lets setup our image-plane. This plane takes the lens galaxy we made above and the grid-stack of # image-plane coordinates. image_plane = plane.Plane(galaxies=[lens_galaxy], grid_stack=image_plane_grid_stack) # Up to now, we've kept our galaxies and grids separate, and passed the grid to a galaxy object to compute # its quantities (e.g. to compute light-profile intensities, we'd write galaxy.intensities_from_grid(grid=grid)). # # Plane's combine the galaxies and grids into one object, thus once we've setup a plane there is no longer any need # have to pass it a grid to compute its quantities. Furthermore, once these quantities are in a plane, they are # automatically mapped back to their original 2D grid-arrays. print('deflection-angles of planes regular-grid pixel 1:') print(image_plane.deflections_y[0,0]) print(image_plane.deflections_x[0,0])
phi=45.0), shear=mp.ExternalShear(magnitude=0.05, phi=90.0), redshift=0.5) source_galaxy = g.Galaxy(light=lp.EllipticalSersic(centre=(0.1, 0.1), axis_ratio=0.8, phi=60.0, intensity=1.0, effective_radius=1.0, sersic_index=2.5), redshift=1.0) # Setup our line-of-sight (los) galaxies using Spherical Sersic profiles for their light and Singular # Isothermal Sphere (SIS) profiles. We'll use 3 galaxies, but you can add more if desired. los_0 = g.Galaxy(light=lp.SphericalSersic(centre=(4.0, 4.0), intensity=0.30, effective_radius=0.3, sersic_index=2.0), mass=mp.SphericalIsothermal(centre=(4.0, 4.0), einstein_radius=0.02), redshift=0.25) los_1 = g.Galaxy(light=lp.SphericalSersic(centre=(3.6, -5.3), intensity=0.20, effective_radius=0.6, sersic_index=1.5), mass=mp.SphericalIsothermal(centre=(3.6, -5.3), einstein_radius=0.04), redshift=0.75) los_2 = g.Galaxy(light=lp.SphericalSersic(centre=(-3.1, -2.4), intensity=0.35, effective_radius=0.4, sersic_index=2.5),
exposure_time=300.0, psf=psf, background_sky_level=0.1, add_noise=True) # When fitting such an image, we now want to include the lens's light in the analysis. thus, we should update our # mask to be circular, and include the central regions of the image. ccd_data = simulate_lens_with_light_profile() mask = msk.Mask.circular(shape=ccd_data.shape, pixel_scale=ccd_data.pixel_scale, radius_arcsec=2.5) # As I said above, performing this fit is the same as usual, we just give the lens galaxy a light profile. lens_galaxy = g.Galaxy(light=lp.SphericalSersic(centre=(0.0, 0.0), intensity=0.2, effective_radius=0.8, sersic_index=4.0), mass=mp.EllipticalIsothermal(centre=(0.0, 0.0), axis_ratio=0.8, phi=135.0, einstein_radius=1.6)) # These are all the usual things we do when setting up a fit. source_galaxy = g.Galaxy(pixelization=pix.Rectangular(shape=(40, 40)), regularization=reg.Constant(coefficients=(1.0, ))) lens_data = ld.LensData(ccd_data=ccd_data, mask=mask) tracer = ray_tracing.TracerImageSourcePlanes( lens_galaxies=[lens_galaxy], source_galaxies=[source_galaxy], image_plane_grid_stack=lens_data.grid_stack,
# We can do the exact same with galaxies, to again compute the galaxy's image. galaxy_intensities = galaxy_with_light_profile.intensities_from_grid(grid=grid_stack.regular) print('intensity of regular-grid pixel 1:') print(galaxy_intensities[0]) print('intensity of regular-grid pixel 2:') print(galaxy_intensities[1]) print('intensity of regular-grid pixel 3:') print(galaxy_intensities[2]) print('etc.') # A galaxy plotter allows us to the plot the image, just like the profile plotters did for a light # profile (again, mapping the 1D image to 2D). galaxy_plotters.plot_intensities(galaxy=galaxy_with_light_profile, grid=grid_stack.regular) # We can pass galaxies as many profiles as we like. Lets create a galaxy with three light profiles. light_profile_1 = light_profiles.SphericalSersic(centre=(0.0, 0.0), intensity=1.0, effective_radius=1.0, sersic_index=2.5) light_profile_2 = light_profiles.SphericalSersic(centre=(1.0, 1.0), intensity=1.0, effective_radius=2.0, sersic_index=3.0) light_profile_3 = light_profiles.SphericalSersic(centre=(1.0, -1.0), intensity=1.0, effective_radius=2.0, sersic_index=2.0) galaxy_with_3_light_profiles = galaxy.Galaxy(light_1=light_profile_1, light_2=light_profile_2, light_3=light_profile_3) # We can print the galaxy to confirm it possesses the Sersic light-profiles above. print(galaxy_with_3_light_profiles) # If we plot the galaxy, we see 3 blobs of light! galaxy_plotters.plot_intensities(galaxy=galaxy_with_3_light_profiles, grid=grid_stack.regular) # We can also plot each individual light profile using the 'subplot' galaxy plotter. galaxy_plotters.plot_intensities_subplot(galaxy=galaxy_with_3_light_profiles, grid=grid_stack.regular) # Mass profiles interact with Galaxy objects in the exact same way as light profiles. # Lets create a galaxy with three SIS mass profiles.
mass_profile = lp.EllipticalSersic(centre=(0.0, 0.0), axis_ratio=0.8, phi=45.0, intensity=1.0, effective_radius=1.0, sersic_index=2.5) start = time.time() mass_profile.intensities_from_grid(grid=lens_data.grid_stack.sub) diff = time.time() - start print("EllipticalSersic time = {}".format(diff)) ### SphericalSersic ### mass_profile = lp.SphericalSersic(centre=(0.0, 0.0), intensity=1.0, effective_radius=1.0, sersic_index=2.5) start = time.time() mass_profile.intensities_from_grid(grid=lens_data.grid_stack.sub) diff = time.time() - start print("SphericalSersic time = {}".format(diff)) ### EllipticalCoreSersic ### mass_profile = lp.EllipticalCoreSersic(centre=(0.0, 0.0), axis_ratio=0.8, phi=45.0, intensity=1.0, effective_radius=1.0, sersic_index=2.5,
sub_grid_size=4) print(image_plane_grid_stack.regular.shape) print(image_plane_grid_stack.sub.shape) # Every regular-pixel is sub-gridded by 4x4, so the sub-grid has x16 more coordinates. # Next, lets setup a lens galaxy. In the previous tutorial, we set up each profile one line at a time. This made # code long and cumbersome to read. This time we'll setup easy galaxy using one block of code. # To help us, we've imported the 'light_profiles' and 'mass_profiles' modules as 'lp' and 'mp', and the # 'galaxy' module as 'g'. # We'll also give the lens galaxy some attributes we didn't in the last tutorial: # 1) A light-profile, meaning its light will appear in the image-plane image. # 2) An external shear, which accounts for the deflection of light due to line-of-sight structures. # 3) A redshift, which the tracer will use to convert arc second coordinates to kpc. lens_galaxy = g.Galaxy(light=lp.SphericalSersic(centre=(0.0, 0.0), intensity=2.0, effective_radius=0.5, sersic_index=2.5), mass=mp.EllipticalIsothermal(centre=(0.0, 0.0), axis_ratio=0.8, phi=90.0, einstein_radius=1.6), shear=mp.ExternalShear(magnitude=0.05, phi=45.0), redshift=0.5) print(lens_galaxy) # Lets also create a small satellite galaxy nearby the lens galaxy and at the same redshift. lens_satellite = g.Galaxy(light=lp.SphericalDevVaucouleurs(centre=(1.0, 0.0), intensity=2.0, effective_radius=0.2), mass=mp.SphericalIsothermal(centre=(1.0, 0.0), einstein_radius=0.4), redshift=0.5) print(lens_satellite) # Lets have a quick look at the appearance of our lens galaxy and its satellite galaxy_plotters.plot_intensities(galaxy=lens_galaxy, grid=image_plane_grid_stack.regular, title='Lens Galaxy') galaxy_plotters.plot_intensities(galaxy=lens_satellite, grid=image_plane_grid_stack.regular, title='Lens Satellite')
def make_galaxy(): return g.Galaxy(light=lp.SphericalSersic(intensity=1.0), mass=mp.SphericalIsothermal(einstein_radius=1.0))