In [9]:
# imports
import numpy as np
from astropy import constants as const
from astropy.cosmology import Planck15
from astropy import units as u
from linetools.analysis.absline import photo_cross
from linetools.spectra import io as lsio
from linetools.spectra.xspectrum1d import XSpectrum1D
from linetools.spectra import utils as lspecu
from pyigm.fN.fnmodel import FNModel
from pyigm.fN import tau_eff
from pyigm.abssys.utils import hi_model
from pyigm.abssys.lls import LLSSystem
from bokeh.io import output_notebook, show, output_file
from bokeh.plotting import figure
from bokeh.models import Range1d
output_notebook()
In [42]:
# For presentation
pwdth = 600
phght = 400
# For laptop
#pwdth = 800
#phght = 600
In [8]:
a = 1/137.036 # Fine-structure constant
bohr = 5.2917721067 * 1e-9 * u.cm
coeff = 2**9 * np.pi**2 / 3 * a * bohr**2
IH = const.Ryd.to('erg', equivalencies=u.spectral())
In [9]:
def f(eta):
num = np.exp(-4*eta*np.arctan(1./eta))
denom = 1 - np.exp(-2*np.pi*eta)
#
return num/denom
In [10]:
energy = IH * np.linspace(1.0002,6.,100)
In [11]:
eta = np.sqrt(IH/ (energy-IH))
sig_phot= coeff * (IH/energy)**4 * f(eta.value)
sig_phot[0]
Out[11]:
In [12]:
# Bokeh plot
pexact = figure(plot_width=pwdth, plot_height=phght, title="Photoionization cross-section")
# Cumul
pexact.line((energy/IH).value, sig_phot.value, color='blue', line_width=2)
# Axes
pexact.xaxis.axis_label = "Energy (Ryd)"
pexact.yaxis.axis_label = "sigma_phot (cm^2)"
#pexact.set(y_range=Range1d(0,1.1))
show(pexact)
In [13]:
energy = IH * np.linspace(1.0002,20.,100)
#
eta = np.sqrt(IH/ (energy-IH))
sig_phot= coeff * (IH/energy)**4 * f(eta.value)
In [14]:
lgsig = np.log(sig_phot.value)
lge = np.log(energy.value)
In [15]:
dlnsig = lgsig - np.roll(lgsig,1)
dlnsig[0] = dlnsig[1]
#
dlne = lge - np.roll(lge,1)
dlne[0] = dlne[1]
In [16]:
# Power-law
# Bokeh plot
pplaw = figure(plot_width=600, plot_height=400, title="Power-law Dependence of sigma")
# Cumul
pplaw.line((energy/IH).value, dlnsig/dlne, color='blue', line_width=2)
# Axes
pplaw.xaxis.axis_label = "Energy (Ryd)"
pplaw.yaxis.axis_label = "dln(sigma)/dln(nu)"
#pexact.set(y_range=Range1d(0,1.1))
show(pplaw)
In [17]:
verner_phot = photo_cross(1,1, energy.to('eV'))
verner_phot[0]
Out[17]:
In [18]:
# Bokeh plot
pverner = figure(plot_width=600, plot_height=400, title="Approxiate Photoionization Cross-section")
# Cumul
pverner.line((energy/IH).value, np.log10(sig_phot.value), color='blue', line_width=2)
pverner.line((energy/IH).value, np.log10(verner_phot.value), color='green', line_width=2)
# Axes
pverner.xaxis.axis_label = "Energy (Ryd)"
pverner.yaxis.axis_label = "log10 [sigma_phot (cm^2)]"
#pexact.set(y_range=Range1d(0,1.1))
show(pverner)
In [19]:
verner_phot = photo_cross(1,1, IH.to('eV'))
np.log10(1./verner_phot.value)
Out[19]:
In [2]:
lls = LLSSystem((0.,0.), 3.5, None, NHI=17.2)
lls
Out[2]:
In [3]:
#### Spectrum
wave = np.arange(3600., 5000., 0.1)*u.AA
spec = XSpectrum1D.from_tuple((wave, np.ones_like(wave)))
spec
Out[3]:
In [37]:
### HI model -- Lyman series lines only
lyman, lines = hi_model(lls, spec)
In [41]:
# Bokeh plot
plyman = figure(plot_width=600, plot_height=400, title="Idealized LLS (Lyman series only)")
# Spectrum
plyman.line(lyman.wavelength.value, lyman.flux.value, color='blue', line_width=2)
# Axes
plyman.xaxis.axis_label = "Wavelength (Ang)"
plyman.yaxis.axis_label = "Normalized flux"
plyman.x_range=Range1d(4100,4250)
show(plyman)
In [4]:
### HI model -- Lyman series lines only
full_model, lines = hi_model(lls, spec, add_lls=True)
In [5]:
# Bokeh plot
plls = figure(plot_width=600, plot_height=400, title="Idealized LLS")
# Spectrum
plls.line(full_model.wavelength.value, full_model.flux.value, color='green', line_width=2)
# Axes
plls.xaxis.axis_label = "Wavelength (Ang)"
plls.yaxis.axis_label = "Normalized flux"
plls.x_range=Range1d(4000,4250)
show(plls)
In [7]:
4107./4.5
Out[7]:
In [7]:
# Read
j0529_uvb = lsio.readspec('../Data/J0529-3526_uvb.fits')
j0529_vis = lsio.readspec('../Data/J0529-3526_vis.fits')
In [10]:
# Splice
j0529 = lspecu.splice_two(j0529_uvb,j0529_vis)
In [13]:
# Bokeh plot
pj0529 = figure(plot_width=800, plot_height=600, title="LLS in J0529-3526")
# Cumul
pj0529.line(j0529.wavelength.value, j0529.flux.value, color='black', line_width=2)
# Axes
pj0529.xaxis.axis_label = "Observed Wavelength (Ang)"
pj0529.yaxis.axis_label = "Relative Flux"
pj0529.x_range=Range1d(4200,7000)
pj0529.y_range=Range1d(0., 1.8e-16)
show(pj0529)
In [46]:
# Plot with linetools GUI
from linetools.guis import xspecgui
xspecgui.main(j0529)
In [34]:
def calc_lz(z):
lz = 1.62 * ((1+z)/(1 + 3.23))**(1.83)
return lz
In [35]:
z=3.5
lz = calc_lz(z)
lz
Out[35]:
In [36]:
Dz1 = 1./lz
Dz1
Out[36]:
In [37]:
def calc_Drp(z,Dz):
num = const.c.to('cm/s') * Dz
denom = Planck15.H(z) * (1+z)
return (num/denom).to('Mpc')
In [38]:
Drp = calc_Drp(z,Dz1)
Drp
Out[38]:
In [39]:
def calc_dXdz(z):
num = (1+z)**2 * Planck15.H0
denom = Planck15.H(z)
return (num/denom).value
In [44]:
zval = np.linspace(0., 5, 100)
dXdz = calc_dXdz(zval)
In [45]:
# Bokeh plot
pdX = figure(plot_width=pwdth, plot_height=phght, title="dX/dz")
# Cumul
pdX.line(zval, dXdz, color='blue', line_width=2)
# Axes
pdX.xaxis.axis_label = "z"
pdX.yaxis.axis_label = "dX/dz"
pdX.y_range=Range1d(0,5)#, y_range=Range1d(0., 1.8e-16))
show(pdX)
In [46]:
calc_dXdz(2.8)
Out[46]:
In [31]:
# simple power-law integration
lz_tau2 = 10**9.13 * 10**(17.5*(-0.52)) / 0.52
lz_tau2
Out[31]:
In [32]:
calc_lz(2.8) # Ribaudo+11
Out[32]:
In [47]:
# Setup
zem = 3.5
z912 = 3
In [48]:
fnmodel = FNModel.default_model()
fnmodel.zmnx = (0.5,4) # extend default range
In [49]:
# Calculate
zval, teff_LL = tau_eff.lyman_limit(fnmodel, z912, zem)
In [50]:
# Bokeh plot
ptLL = figure(plot_width=pwdth, plot_height=phght, title="Effective Opacity")
# Cumul
ptLL.line(zval, teff_LL, color='blue', line_width=2)
# Axes
ptLL.xaxis.axis_label = "z"
ptLL.yaxis.axis_label = "teff_LL"
ptLL.y_range=Range1d(0,2)#, y_range=Range1d(0., 1.8e-16))
show(ptLL)
In [51]:
logNHI = np.linspace(12., 22, 100)
Nval = 10**logNHI
dlogN = logNHI[1]-logNHI[0]
# f(N)
log_fnX = fnmodel.evaluate(logNHI, 3.)
# Per logN
intgrnd = 10.**(log_fnX.flatten()) * 10**logNHI * (1-np.exp(-1*Nval*6.33e-18))
In [52]:
# Bokeh plot
pdtLL = figure(plot_width=600, plot_height=400, title="Differential Effective Opacity")
# Cumul
pdtLL.line(logNHI, intgrnd, color='green', line_width=2)
# Axes
pdtLL.xaxis.axis_label = "log NHI"
pdtLL.yaxis.axis_label = "d teff_LL / dlogN (Relative)"
pdtLL.y_range=Range1d(0,0.1)#, y_range=Range1d(0., 1.8e-16))
show(pdtLL)
In [ ]: