Pre-calculated tables & interpolation
Profile tables
For convenience (and to save computation time!), profiles over a range of radii have been computed for the following set of Sérsic indices n
and flattening (or “stretching,” if prolate) invq
:
n_arr = np.arange(0.5, 8.1, 0.1)
invq_arr = np.array([1., 2., 3., 4., 5., 6., 7., 8., 10., 20., 100.,
1.11, 1.25, 1.43, 1.67, 2.5, 3.33, 0.5, 0.67])
These tables can be loaded as follows.
[1]:
import os
import deprojected_sersic_models as deproj_sersic
table_dir = os.getenv('DEPROJECTED_SERSIC_MODELS_DATADIR')
table = deproj_sersic.io.read_profile_table(n=1.0, invq=5.0, path=table_dir)
By default, if path
is not specified, then the system variable DEPROJECTED_SERSIC_MODELS_DATADIR
(e.g., as set in your .bashrc
file) is used.
The tables contain a range of profiles and constants, which are accessed as table['key']
.
Table key |
Description |
Units |
Type |
---|---|---|---|
|
Radius |
\(\mathrm{kpc}\) |
array |
|
Circular velocity |
\(\mathrm{km/s}\) |
array |
|
Enclosed 3D mass |
\(M_{\odot}\) |
array |
|
Mass density |
\(M_{\odot}/\mathrm{kpc}^3\) |
array |
|
Slope of log mass density |
array |
|
|
Enclosed 3D mass in spheroid |
\(M_{\odot}\) |
array |
|
Sérsic index |
const |
|
|
Intrinsic axis ratio |
const |
|
|
Flattening \(1/q\) |
const |
|
|
Total mass |
\(M_{\odot}\) |
const |
|
2D effective radius |
\(\mathrm{kpc}\) |
const |
|
Enclosed 3D mass at \(R_{\mathrm{eff}}\) |
\(M_{\odot}\) |
const |
|
Enclosed 3D mass in spheroid at \(R_{\mathrm{eff}}\) |
\(M_{\odot}\) |
const |
|
Circular velocity at \(R_{\mathrm{eff}}\) |
\(\mathrm{km/s}\) |
const |
|
Total virial coefficient at \(R_{\mathrm{eff}}\) |
const |
|
|
3D virial coefficient at \(R_{\mathrm{eff}}\) |
const |
|
|
3D spherical half mass radius |
\(\mathrm{kpc}\) |
const |
These profiles can be scaled or interpolated to match different total masses or effective radii.
The pre-computed table distribution are sampled from logarithmically in \(R\), ranging from 0.01 to 100 kpc, but also includes the profile values at \(R=0\).
Interpolation functions
Interpolation functions are provided in deprojected_sersic_models
to aid in such scaling / interpolation calculations.
These functions can be used with or without pre-loaded tables.
Interpolating using loaded/computed tables
The loaded table can be passed to these functions as shown below.
[2]:
import numpy as np
total_mass = 1.e11
Reff = 5.
n = 1.0
invq = 5.0
R = np.arange(0., 30.1, 0.1)
vcirc = deproj_sersic.interpolate_sersic_profile_VC(R=R, total_mass=total_mass, Reff=Reff,
n=n, invq=invq, table=table)
menc = deproj_sersic.interpolate_sersic_profile_menc(R=R, total_mass=total_mass, Reff=Reff,
n=n, invq=invq, table=table)
rho = deproj_sersic.interpolate_sersic_profile_rho(R=R, total_mass=total_mass, Reff=Reff,
n=n, invq=invq, table=table)
dlnrho_dlnR = deproj_sersic.interpolate_sersic_profile_dlnrho_dlnR(R=R, Reff=Reff, n=n,
invq=invq, table=table)
For comparison with the original table (now in linear space):
[3]:
import matplotlib.pyplot as plt
%matplotlib inline
%config InlineBackend.figure_format = 'svg' # Tutorial plot configuration
# Make pseudo table bundle, for plotting
table_gather = {'R': R, 'vcirc': vcirc, 'menc3D_sph': menc, 'rho': rho,
'dlnrho_dlnR': dlnrho_dlnR, 'n': n, 'invq': invq, 'q': 1./invq,
'total_mass': total_mass, 'Reff': Reff }
plot_kwargs = [{'color':'grey', 'ls':':', 'marker':'+', 'ms':5, 'label':'Table'},
{'lw': 2., 'label':'Interp+scale'}]
deproj_sersic.plot.plot_profiles([table, table_gather],
prof_names=['v_circ', 'enclosed_mass', 'density', 'dlnrho_dlnR'],
rlim=[R.min(), R.max()], rlog = [False, False, True, False],
plot_kwargs=plot_kwargs)
Interpolating without loaded tables
The deprojected_sersic_models
interpolation functions can also be used directly, without separately loading the pre-computed tables.
The following example shows the syntax for this case.
[4]:
total_mass = 1.e11
Reff = 5.0
n = 1.0
R = np.arange(0., 30.1, 0.1)
invq_arr = [1., 2.5, 3.33, 5., 10.]
vcs, mencs, rhos, dlnrho_dlnRs = [], [], [], []
for invq in invq_arr:
vc = deproj_sersic.interpolate_sersic_profile_VC(R=R, total_mass=total_mass, Reff=Reff,
n=n, invq=invq, path=table_dir)
menc = deproj_sersic.interpolate_sersic_profile_menc(R=R, total_mass=total_mass, Reff=Reff,
n=n, invq=invq, path=table_dir)
rho = deproj_sersic.interpolate_sersic_profile_rho(R=R, total_mass=total_mass, Reff=Reff,
n=n, invq=invq, path=table_dir)
dlnrho_dlnR = deproj_sersic.interpolate_sersic_profile_dlnrho_dlnR(R=R, Reff=Reff, n=n,
invq=invq, path=table_dir)
vcs.append(vc)
mencs.append(menc)
rhos.append(rho)
dlnrho_dlnRs.append(dlnrho_dlnR)
[5]:
# Make pseudo table bundles, for plotting
tables = []
plot_kwargs = []
for invq, vc, menc, rho, dlnrho_dlnR in zip(invq_arr, vcs, mencs, rhos, dlnrho_dlnRs):
table_gather = {'R': R, 'vcirc': vc, 'menc3D_sph': menc, 'rho': rho,
'dlnrho_dlnR': dlnrho_dlnR, 'n': n, 'invq': invq, 'q': 1./invq,
'total_mass': total_mass, 'Reff': Reff }
tables.append(table_gather)
plot_kwargs.append({'label': 'q={:0.2f}'.format(1./invq)})
fig_kwargs = {'legend_title': 'Intrinic axis ratio'}
deproj_sersic.plot.plot_profiles(tables,
prof_names=['v_circ', 'enclosed_mass', 'density', 'dlnrho_dlnR'],
rlog = [False, False, True, False],
plot_kwargs=plot_kwargs, fig_kwargs=fig_kwargs)
“Nearest” interpolation
Finally, the “nearest” versions of the interpolation functions can also be used to find the closest value of n
and invq
that have been pre-computed, and use those tables for interpolation.
[6]:
total_mass = 1.e11
Reff = 5.0
n = 0.975
invq_arr = 4.75
R = np.arange(0., 30.1, 0.1)
vc = deproj_sersic.interpolate_sersic_profile_VC_nearest(R=R, total_mass=total_mass, Reff=Reff,
n=n, invq=invq, path=table_dir)
menc = deproj_sersic.interpolate_sersic_profile_menc_nearest(R=R, total_mass=total_mass, Reff=Reff,
n=n, invq=invq, path=table_dir)
rho = deproj_sersic.interpolate_sersic_profile_rho_nearest(R=R, total_mass=total_mass, Reff=Reff,
n=n, invq=invq, path=table_dir)
dlnrho_dlnrho_dlnRdlnr = deproj_sersic.interpolate_sersic_profile_dlnrho_dlnR_nearest(R=R, Reff=Reff, n=n,
invq=invq, path=table_dir)
Interpolate all table profiles
There are cases where it is convenient to interpolate the entire set of profiles for a table. The function interpolate_entire_table
enables this calculation (see also interpolate_entire_table_nearest
).
[7]:
total_mass = 1.e11
Reff = 5.0
n = 1.0
invq = 5.0
R = np.arange(0., 30.1, 0.1)
table_interp = deproj_sersic.interpolate_entire_table(R=R, total_mass=total_mass, Reff=Reff,
n=n, invq=invq, path=table_dir)
[8]:
deproj_sersic.plot.plot_profiles([table, table_interp],
ylog=[False, False, True, False, True, False],
rlog=False, rlim=[0.,30.])
Alternatively, the pre-loaded table can be used directly.
[9]:
table = deproj_sersic.io.read_profile_table(n=n, invq=invq, path=table_dir)
table_interp2 = deproj_sersic.interpolate_entire_table(R=R, total_mass=total_mass,
Reff=Reff, table=table)