Spectral Data Cubes from a Parametric Galaxy¶
In this example we show how to create a spectral data cube from a parametric galaxy. For this we’ll generate a disk and a bulge morphology and make spectral data cubes for each individual component before combining them.
[1]:
import matplotlib.pyplot as plt
import numpy as np
from unyt import Msun, Myr, angstrom, degree, kpc
from synthesizer.emission_models import IntrinsicEmission
from synthesizer.grid import Grid
from synthesizer.imaging import SpectralCube
from synthesizer.parametric import SFH, Stars, ZDist
from synthesizer.parametric.galaxy import Galaxy
from synthesizer.parametric.morphology import Sersic2D
plt.rcParams["font.family"] = "DeJavu Serif"
plt.rcParams["font.serif"] = ["Times New Roman"]
# Set the seed
np.random.seed(42)
# Define the grid
grid_name = "test_grid"
grid_dir = "../../../tests/test_grid/"
grid = Grid(
grid_name, grid_dir=grid_dir, new_lam=np.logspace(2, 5, 600) * angstrom
)
# Define the SFH and metallicity distribution
metal_dist = ZDist.Normal(mean=0.015, sigma=0.005)
sfh = SFH.Constant(max_age=200 * Myr)
# Define the morphology using a simple effective radius and slope
morph = Sersic2D(
r_eff=1 * kpc,
sersic_index=1.0,
ellipticity=0,
theta=0 * degree,
)
# Create the Stars object
stars = Stars(
grid.log10age,
grid.metallicity,
sf_hist=sfh,
metal_dist=metal_dist,
morphology=morph,
initial_mass=10**9.0 * Msun,
)
# Initialise a parametric Galaxy for the bulge
bulge = Galaxy(stars, redshift=3)
# Define the SFH and metallicity distribution
metal_dist = ZDist.Normal(mean=0.01, sigma=0.005)
sfh = SFH.Constant(max_age=100 * Myr)
# Define the morphology using a simple effective radius and slope
morph = Sersic2D(
r_eff=5 * kpc,
sersic_index=1.0,
ellipticity=0.4,
theta=1 * degree,
)
# Create the Stars object
stars = Stars(
grid.log10age,
grid.metallicity,
sf_hist=sfh,
metal_dist=metal_dist,
morphology=morph,
initial_mass=10**9.5 * Msun,
)
# Initialise a parametric Galaxy for the disk
disk = Galaxy(stars, redshift=3)
Before we can generate a spectral data cube, we first need to generate spectra for each component.
[2]:
model = IntrinsicEmission(grid, fesc=0.1)
bulge_sed = bulge.stars.get_spectra(model)
disk_sed = disk.stars.get_spectra(model)
Spectral Data Cube Creation¶
We now have most of the ingredients we need to generate a spectral data cube from our galaxy. We only require parameters describing the wavelength array of our spectral data cube, its resolution, and the field of view (FOV):
[3]:
# Define the width of the image
width = 30 * kpc
# Define image resolution (here we arbitrarily set it to 100 pixels
# along an axis)
resolution = width / 200
# Define the wavelength array
lam = np.linspace(10**3, 10**4.5, 1000)
print(
"Data cube spatial width is %.2f kpc with a %.2f kpc spaxel resolution"
% (width.value, resolution.value)
)
Data cube spatial width is 30.00 kpc with a 0.15 kpc spaxel resolution
Finally, we create the individual spectral cubes, and then add them together to get the final combined galaxy spectral data cube.
To make the spectral cubes we have to pass the Sed
objects we made, the quantity we want to populate the spectral cube with, and the density grid defined by each morphology. The possible quantities are "lnu"
, "luminosity"
or "llam"
for rest frame luminosities, or "fnu"
, "flam"
or "flux"
for fluxes (the latter 3 require get_fnu
or get_fnu0
to have been called). We will make a cube populated with "flux"
.
[4]:
# Get the data cubes
bulge_cube = SpectralCube(resolution=resolution, lam=lam, fov=width)
disk_cube = SpectralCube(resolution=resolution, lam=lam, fov=width)
# And get the cube itself
bulge_cube.get_data_cube_smoothed(
bulge_sed,
quantity="lnu",
density_grid=bulge.stars.morphology.get_density_grid(
bulge_cube.resolution, bulge_cube.npix
),
)
disk_cube.get_data_cube_smoothed(
disk_sed,
quantity="lnu",
density_grid=disk.stars.morphology.get_density_grid(
disk_cube.resolution, disk_cube.npix
),
)
# Combine each individual component
cube = bulge_cube + disk_cube
Now we have our parametric spectral data cube, cube
. We can see what we’ve made by making an animation.
[5]:
# Animate the data cube
ani = cube.animate_data_cube(fps=240, show=True)
Galaxy helper method¶
If you don’t want to use the low level SpectralCube
object we also include a helper method on a galaxy.
[6]:
bulge_cube = bulge.get_data_cube(
resolution, width, lam, stellar_spectra="intrinsic", quantity="luminosity"
)
disk_cube = disk.get_data_cube(
resolution, width, lam, stellar_spectra="intrinsic", quantity="luminosity"
)
cube = bulge_cube + disk_cube