Choose the Simple Stellar Population library
We provide a set of Simple Stellar Population libraries, already formatted for usage by galapy
functions and classes.
We can print a list of available libraries by calling
[1]:
from galapy.CompositeStellarPopulation import print_ssp_libs
print_ssp_libs()
Available SSP formats
---------------------
* bc03.stelib.chab.extrap;
* bc03.stelib.chab;
* bc03.basel.chab;
* bc03.basel.chab.refined;
* parsec22.NTL.refined;
* parsec22.NT;
* parsec22.NTL;
* parsec22.NT.refined;
with the naming convention: author.method[.imf.filling_schema]
family: An achronym for the authors of the SSP library
method: if present, shows which method was used to compute the SSP
imf: if present shows the initial mass function used to compute the SSP
filling_schema: all the SSPs’ wavelength domain has been extended to span from \(1\ \mathring{A}\) to \(10^{10}\ \mathring{A}\). This code provides the strategy used (not present = filled with zeros,
extrap
= extrapolated linearly in the logarithm,refined
= thinner lambda grid obtained by linearly-interpolating theextend
equivalent)
They are divided into two main families providing different features each. The details are reported in the following sections.
Note that the different families are divided in flavours all of which have different properties. The main property that regulates the impact on the sampling performances is the size of the wavelength grid: the smaller the fastest.
Look around:
We can load a SSP table by invoking the dedicated function:
[2]:
from galapy.CompositeStellarPopulation import load_SSP_table
which returns a tuple with
the wavelength grid
the age grid
the metallicity grid
the table itself
[3]:
l, t, Z, L = load_SSP_table('bc03.basel.chab')
Our tables are stored as flattened, contiguous objects, mainly for internal usage.
[4]:
L.shape, l.size*t.size*Z.size
[4]:
((3438981,), 3438981)
We can reshape them into a 3D matrix by calling the dedicated function:
[5]:
from galapy.CompositeStellarPopulation import reshape_SSP_table
this function takes two arguments:
the
L
tablea shape tuple consisting of 3 elements: the wavelength grid size, the age grid size and the metallicity grid size
[6]:
L = reshape_SSP_table( L, shape=(l.size, t.size, Z.size) )
L.shape
[6]:
(2223, 221, 7)
Bruzual & Charlot 2003: bc03
the classic and popular Bruzual & Charlot (2003) in its updated version (v2016). This library provides the continuum luminosity from SSPs for a set of different IMFs, at varying wavelength, age and metallicity.
bc03
SSP tables only include stellar emission (atmospheres) thus, if the user wants to also model further emission components due to stars, these have to be computed separately. Namely it is required to build the synchrotron and nebular free-free contributions separately (seegalapy.Synchrotron
andgalapy.NebularFreeFree
).
General to all the libraries in the family:
size |
values |
|
---|---|---|
Time grid |
221 |
irregularly distributed values in the interval \(0 < \tau < 2\times10^{10}\ \text{years}\) |
Metallicity grid |
7 |
|
Specific to the different flavours:
basel.chab
: lower resolution wavelength grid (\(N_\lambda < 3000\)), with Chabrier IMFstelib.chab
: higher resolution wavelength grid (\(N_\lambda > 7000\)), with Chabrier IMF
flavour |
Wavelength grid |
Description |
---|---|---|
|
2223 |
Extended from the original work to span from \(1 \mathring{A}\) to \(10^{10}\mathring{A}\), the filling method is zeros padding |
|
2837 |
Same as above but the density of wavelength grid points has been increased to have at least 128 values per-each order of magnitude |
|
7325 |
Same as |
|
7325 |
Same as above but instead of zeros padding, the padding values have been extrapolated linearly in log-space from the last two grid points in the original table |
Tips
the SSP libraries of choice for comparison with other works (as these tables are present in most of the other SED fitting tools)
highly tested and verified
the
stelib
flavour includes the tables with the highest wavelength resolution from those included in the default database.the
stelib.*.extrap
flavour introduces extrapolation at long and short wavelength instead of padding with zeros the table.flavours marked
refined
should be used when computing the transmitted band flux in photometric systems including bands from the submm/mm bands and longer (lower frequency).
Plot single SSPs
It might be useful to visualise the different SSPs before choosing which one best suits someones needs
[7]:
from galapy.analysis.plot import plt
(the plt
module in galapy.analysis.plot
is just a matplotlib.pyplot
where some tweaking of the default layout has been applied)
Load the two stelib
flavours, to show the difference between the default zeros-padding and the extrapolated library:
[8]:
l, t, Z, Lbc03zerosp = load_SSP_table('bc03.stelib.chab')
Lbc03zerosp = reshape_SSP_table( Lbc03zerosp, shape=(l.size, t.size, Z.size) )
*_, Lbc03extrap = load_SSP_table('bc03.stelib.chab.extrap')
Lbc03extrap = reshape_SSP_table( Lbc03extrap, shape=(l.size, t.size, Z.size) )
(since the wavelength, age and metallicity grids are all the same for the two cases, we store them just from the first table)
We select some different ages from the table picking some indices and check the value from the age-grid t
[9]:
tidx = [1, 100, 150, 200]
iz = 3
print( f'Metallicity: {Z[iz]}')
print( 'Ages:')
for it in tidx :
print( f'{t[it]:.2e} years' )
Metallicity: 0.008
Ages:
1.00e+05 years
3.70e+07 years
2.60e+09 years
1.50e+10 years
And finally, we plot in 4 different panels the four different ages. Note how the tails of the emissions are different (solid blue line VS dashed green line)
[10]:
fig, axs = plt.subplots(2,2, figsize=(14,8), sharex=True, sharey=True,
gridspec_kw={'hspace':0.0, 'wspace':0.0},
tight_layout=True)
for ii, it in enumerate(tidx) :
jj = int(ii/2)
kk = int(ii%2)
if jj != 0 :
axs[jj,kk].set_xlabel('$\\lambda\\ [\\AA]$')
if kk == 0 :
axs[jj,kk].set_ylabel('$L_\\lambda\\ [L_\\odot\\;\\AA^{-1}]$')
axs[jj,kk].set_xscale('log')
axs[jj,kk].set_yscale('log')
axs[jj,kk].set_xlim(2.*10**0,10**10)
axs[jj,kk].plot(l, Lbc03zerosp[:,it,3], label='zeros padding')
axs[jj,kk].plot(l, Lbc03extrap[:,it,3], ls='--', label='extrapolated')
if ii == 3 :
axs[jj,kk].legend()

PARSEC22: parsec22
Produced with the PARSEC code (Bressan et al., 2012; Chen et al., 2014; Chen et al., 2015) for a Chabrier IMF and varying ages and metallicities, including emission from dusty AGB stars Bressan et al., 1998.
These libraries come in two flavours, the first one with continuum emission only and the second also including nebular emission. In the former, besides continuum stellar emission, non-thermal synchrotron emission from core-collapse supernovae is also included in each SSP spectrum (see, e.g., Vega et al., 2008). In the latter, on top of the stellar continuum and non-thermal synchrotron, nebular emission is also included, with both free-free continuum and nebular emission (see, e.g., Maya et al., 2004), calculated with CLOUDY.
We highlight that, using the PARSEC22 SSP libraries come with the advantage of reducing the total amount of computations the code has to perform for getting to a final equivalent SED. Namely, using our custom SSP libraries avoids the need to compute separately the radio stellar emissions. Furthermore, nebular line emission is currently only available with the PARSEC22 SSP libraries.}
General to all the libraries in the family:
size |
values |
|
---|---|---|
Time grid |
146 |
irregularly distributed values in the interval \(0 < \tau < 1.4\times10^{10}\ \text{years}\) |
Metallicity grid |
7 |
|
Specific to the different flavours:
NT
: stellar atmospheres + Non-Thermal emission (i.e. Super-Nova Synchrotron)NTL
: stellar atmospheres + Non-Thermal emission (i.e. Super-Nova Synchrotron) + Nebular emission (i.e. Bremstrhalung + Emission Lines)
flavour |
Wavelength grid |
Description |
---|---|---|
|
1562 |
See above, spanning from \(1\mathring{A}\) to \(10^{10}\mathring{A}\), the missing parts are padded with zeros |
|
2189 |
Same as above but the density of wavelength grid points has been increased to have at least 128 values per-each order of magnitude in the wavelength grid |
|
1562 |
Same as |
|
2189 |
Same as |
Tips
the
parsec22
family is our default, it is the most updated and has been developed with a resolution largely sufficient for most of the applications.currently, using
parsec22.NTL
libraries is the only method to account for the nebular contribution both in terms ofenergy balance
line emission
flavours marked
refined
should be used when computing the transmitted band flux in photometric systems including bands from the submm/mm bands and longer (lower frequency).
Some plots
Let’s check the difference between the NT
and NTL
flavours:
[11]:
l, t, Z, Lp22nt = load_SSP_table('parsec22.NT')
Lp22nt = reshape_SSP_table( Lp22nt, shape=(l.size, t.size, Z.size) )
*_, Lp22ntl = load_SSP_table('parsec22.NTL')
Lp22ntl = reshape_SSP_table( Lp22ntl, shape=(l.size, t.size, Z.size) )
(since the wavelength, age and metallicity grids are all the same for the two cases, we store them just from the first table)
We select some different ages from the table picking some indices and check the value from the age-grid t
[12]:
tidx = [1, 25, 75, 125]
iz = 3
print( f'Metallicity: {Z[iz]}')
print( 'Ages:')
for it in tidx :
print( f'{t[it]:.2e} years' )
Metallicity: 0.004
Ages:
1.00e+05 years
3.80e+06 years
5.00e+07 years
4.00e+09 years
And finally, we plot in 4 different panels the four different ages. Note how the difference is evident just at the youngest ages (solid blue line VS dashed green line in the two upper plots)
[13]:
fig, axs = plt.subplots(2,2, figsize=(14,8), sharex=True, sharey=True,
gridspec_kw={'hspace':0.0, 'wspace':0.0},
tight_layout=True)
for ii, it in enumerate(tidx) :
jj = int(ii/2)
kk = int(ii%2)
if jj != 0 :
axs[jj,kk].set_xlabel('$\\lambda\\ [\\AA]$')
if kk == 0 :
axs[jj,kk].set_ylabel('$L_\\lambda\\ [L_\\odot\\;\\AA^{-1}]$')
axs[jj,kk].set_xscale('log')
axs[jj,kk].set_yscale('log')
axs[jj,kk].set_xlim(2.*10**0,10**10)
axs[jj,kk].plot(l, Lp22nt[:,it,3], label='non-thermal')
axs[jj,kk].plot(l, Lp22ntl[:,it,3], ls='--', label='non-thermal + nebular')
if ii == 3 :
axs[jj,kk].legend()
