More General Star Formation Histories and Spectral Synthesis¶
By default, ARES does not perform spectral synthesis. For example, in More Realistic Galaxy Populations, the luminosity of galaxies is determined using a fixed conversion factor between \(1600\unicode{x212B}\) luminosity and star formation rate (SFR). The proper way to do this is to sum the luminosity from stars of all ages. In practice, the constant conversion factor works well for rest UV studies, since the rest UV depends largely on massive, short-lived stars. However, for non-trivial star formation histories (SFHs), or predictions at longer wavelengths, performing spectral synthesis in details is a must.
To enable a more general treatment of galaxy growth histories, including the proper synthesis of their spectra, we must use the GalaxyEnsemble
object, which supercedes the GalaxyCohort
object. We describe this object in more detail below.
Setting up a GalaxyEnsemble
object¶
We can build a new population object by modifying just a few parameters relative to the “base” double power-law SFE approach taken in Mirocha, Furlanetto, & Sun (2017):
# Extract base set of parameters using a double power-law SFE
pars = ares.util.ParameterBundle('mirocha2017:base').pars_by_pop(0, 1)
# Add modifications necessary to handle generalizations
pars['pop_sfr_model'] = 'ensemble'
pars['pop_aging'] = True
pars['pop_ssp'] = True
The pop_sfr_model
setting ensures that the correct model is used, while pop_aging
and pop_ssp
force ARES to properly track the impact of aging on the spectra of galaxies, by treating star formation at each timestep as a “simple stellar population,” i.e., a burst, which ages passively from that point onward.
For illustrative purposes, let’s build two model galaxies: one with an exponentially rising (but noisy) SFH, and another that is identical for the first 900 Myr of evolution, but then is suddenly switched off:
tarr = np.arange(50, 1001, 1.) # array of times in Myr
# Exponentially-rising SFH with log-normal scatter
sfh1 = np.exp(tarr / 200.)
sfh1 *= np.random.lognormal(size=tarr.size, sigma=0.5)
sfh1 = np.atleast_2d(sfh1)
# For contrast, compare to same SFH that is nulled for last 50 Myr
sfh2 = sfh1.copy()
sfh2[:,tarr > 950] = 0.0
# Plot histories for sanity check
pl.figure(1)
pl.plot(tarr, sfh1[0], color='k')
pl.plot(tarr, sfh2[0], color='b')
pl.xlabel(r'$t / \mathrm{Myr}$')
pl.ylabel(r'SFR')
Note
We’ve made the SFH arrays 2-D because in general we can perform spectral synthesis on an entire population of galaxies all at once. The first dimension of the SFH arrays corresponds to galaxy ID number.
Now, to pass these histories to ARES directly and bypass all the usual SFH-generating machinery, use the pop_histories
parameter:
pars1['pop_histories'] = {'t': tarr, 'sfh': sfh1, 'nh': np.ones_like(sfh1)}
pars2['pop_histories'] = {'t': tarr, 'sfh': sfh2, 'nh': np.ones_like(sfh2)}
Note that we’ve added nh
as well, the number density of halos. In this example, since we’re treating individual galaxies, this is set to unity. However, in general, one can treat the evolution of galaxies in halo mass bins, in which case nh
may be set to the number density of the DM parent halos of these galaxies.
Now, create a few GalaxyPopulation
instances:
pop1 = ares.populations.GalaxyPopulation(**pars1)
pop2 = ares.populations.GalaxyPopulation(**pars2)
All the spectral synthesis machinery lives in ares.util.SpectralSynthesis
, which is initialized as an attribute synth
belonging to each GalaxyEnsemble
instance. So, to plot the spectra of our two idealized galaxies at \(t=1\) Gyr, we can do:
# Just look at the rest UV for now.
waves = np.arange(800, 3000, 10)
# Generate spectra in rest frame
spec1 = pop1.synth.Spectrum(sfh=sfh1[0], waves=waves, tarr=tarr, tobs=1000)
spec2 = pop2.synth.Spectrum(sfh=sfh2[0], waves=waves, tarr=tarr, tobs=1000)
# Plot
pl.semilogy(waves, spec1, color='k')
pl.semilogy(waves, spec2, color='b')
pl.xlabel(r'$\lambda / \AA$')
pl.ylabel(r'$f_{\nu}$')
Note
These spectra correspond to the BPASS v1.0 models, since that is the
default in the mirocha2017
parameter bundle. You can switch to starburst99 by setting pop_sed='leitherer1999'
. You can also change the stellar metallicity via the pop_Z
parameter. If you have a model for metal enrichment, that is possible to supply as well.
There are many options for outputting photometry in addition to / instead of rest spectra. Contact me if you’re interested in these features as they are not yet documented.
Using the GalaxyEnsemble
from within ARES¶
In practice, you may want to leverage the features of the GalaxyEnsemble
object from within an ARES simulation, e.g., the 21-cm signal, metagalactic gackground, or while modeling a population of galaxies and comparing to observed UV luminosity functions or stellar mass functions.
Once again, contact me if you’re interested in these features as they are not yet documented.